claudemesh-cli 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entrypoints/cli.js +651 -157
- package/dist/entrypoints/cli.js.map +13 -10
- package/dist/entrypoints/mcp.js +240 -37
- package/dist/entrypoints/mcp.js.map +6 -4
- package/package.json +2 -1
- package/skills/claudemesh/SKILL.md +235 -0
package/dist/entrypoints/cli.js
CHANGED
|
@@ -88,7 +88,7 @@ __export(exports_urls, {
|
|
|
88
88
|
VERSION: () => VERSION,
|
|
89
89
|
URLS: () => URLS
|
|
90
90
|
});
|
|
91
|
-
var URLS, VERSION = "1.1
|
|
91
|
+
var URLS, VERSION = "1.2.1", env;
|
|
92
92
|
var init_urls = __esm(() => {
|
|
93
93
|
URLS = {
|
|
94
94
|
BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
|
|
@@ -6392,11 +6392,136 @@ var init_ban = __esm(() => {
|
|
|
6392
6392
|
init_exit_codes();
|
|
6393
6393
|
});
|
|
6394
6394
|
|
|
6395
|
+
// src/services/bridge/protocol.ts
|
|
6396
|
+
import { homedir as homedir4 } from "node:os";
|
|
6397
|
+
import { join as join4 } from "node:path";
|
|
6398
|
+
function socketPath(meshSlug) {
|
|
6399
|
+
return join4(homedir4(), ".claudemesh", "sockets", `${meshSlug}.sock`);
|
|
6400
|
+
}
|
|
6401
|
+
function socketDir() {
|
|
6402
|
+
return join4(homedir4(), ".claudemesh", "sockets");
|
|
6403
|
+
}
|
|
6404
|
+
function frame(obj) {
|
|
6405
|
+
return JSON.stringify(obj) + `
|
|
6406
|
+
`;
|
|
6407
|
+
}
|
|
6408
|
+
|
|
6409
|
+
class LineParser {
|
|
6410
|
+
buf = "";
|
|
6411
|
+
feed(chunk) {
|
|
6412
|
+
this.buf += typeof chunk === "string" ? chunk : chunk.toString("utf-8");
|
|
6413
|
+
const lines = [];
|
|
6414
|
+
let nl = this.buf.indexOf(`
|
|
6415
|
+
`);
|
|
6416
|
+
while (nl !== -1) {
|
|
6417
|
+
lines.push(this.buf.slice(0, nl));
|
|
6418
|
+
this.buf = this.buf.slice(nl + 1);
|
|
6419
|
+
nl = this.buf.indexOf(`
|
|
6420
|
+
`);
|
|
6421
|
+
}
|
|
6422
|
+
return lines;
|
|
6423
|
+
}
|
|
6424
|
+
}
|
|
6425
|
+
var init_protocol = () => {};
|
|
6426
|
+
|
|
6427
|
+
// src/services/bridge/client.ts
|
|
6428
|
+
import { createConnection } from "node:net";
|
|
6429
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
6430
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
6431
|
+
async function tryBridge(meshSlug, verb, args = {}, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
6432
|
+
const path = socketPath(meshSlug);
|
|
6433
|
+
if (!existsSync5(path))
|
|
6434
|
+
return null;
|
|
6435
|
+
return new Promise((resolve) => {
|
|
6436
|
+
const id = randomUUID2();
|
|
6437
|
+
const req = { id, verb, args };
|
|
6438
|
+
const parser = new LineParser;
|
|
6439
|
+
let settled = false;
|
|
6440
|
+
const finish = (value) => {
|
|
6441
|
+
if (settled)
|
|
6442
|
+
return;
|
|
6443
|
+
settled = true;
|
|
6444
|
+
try {
|
|
6445
|
+
socket.destroy();
|
|
6446
|
+
} catch {}
|
|
6447
|
+
clearTimeout(timer);
|
|
6448
|
+
resolve(value);
|
|
6449
|
+
};
|
|
6450
|
+
const socket = createConnection({ path });
|
|
6451
|
+
const timer = setTimeout(() => {
|
|
6452
|
+
finish(null);
|
|
6453
|
+
}, timeoutMs);
|
|
6454
|
+
socket.on("connect", () => {
|
|
6455
|
+
try {
|
|
6456
|
+
socket.write(frame(req));
|
|
6457
|
+
} catch {
|
|
6458
|
+
finish(null);
|
|
6459
|
+
}
|
|
6460
|
+
});
|
|
6461
|
+
socket.on("data", (chunk) => {
|
|
6462
|
+
const lines = parser.feed(chunk);
|
|
6463
|
+
for (const line of lines) {
|
|
6464
|
+
if (!line.trim())
|
|
6465
|
+
continue;
|
|
6466
|
+
let res;
|
|
6467
|
+
try {
|
|
6468
|
+
res = JSON.parse(line);
|
|
6469
|
+
} catch {
|
|
6470
|
+
continue;
|
|
6471
|
+
}
|
|
6472
|
+
if (res.id !== id)
|
|
6473
|
+
continue;
|
|
6474
|
+
if (res.ok)
|
|
6475
|
+
finish({ ok: true, result: res.result });
|
|
6476
|
+
else
|
|
6477
|
+
finish({ ok: false, error: res.error });
|
|
6478
|
+
return;
|
|
6479
|
+
}
|
|
6480
|
+
});
|
|
6481
|
+
socket.on("error", (err) => {
|
|
6482
|
+
const code = err.code;
|
|
6483
|
+
if (code === "ECONNREFUSED" || code === "ENOENT" || code === "EPERM") {
|
|
6484
|
+
finish(null);
|
|
6485
|
+
} else {
|
|
6486
|
+
finish(null);
|
|
6487
|
+
}
|
|
6488
|
+
});
|
|
6489
|
+
socket.on("close", () => {
|
|
6490
|
+
finish(null);
|
|
6491
|
+
});
|
|
6492
|
+
});
|
|
6493
|
+
}
|
|
6494
|
+
var DEFAULT_TIMEOUT_MS = 5000;
|
|
6495
|
+
var init_client3 = __esm(() => {
|
|
6496
|
+
init_protocol();
|
|
6497
|
+
});
|
|
6498
|
+
|
|
6395
6499
|
// src/commands/peers.ts
|
|
6396
6500
|
var exports_peers = {};
|
|
6397
6501
|
__export(exports_peers, {
|
|
6398
6502
|
runPeers: () => runPeers
|
|
6399
6503
|
});
|
|
6504
|
+
function projectFields(record, fields) {
|
|
6505
|
+
const out = {};
|
|
6506
|
+
for (const f of fields) {
|
|
6507
|
+
const sourceKey = FIELD_ALIAS[f] ?? f;
|
|
6508
|
+
out[f] = record[sourceKey];
|
|
6509
|
+
}
|
|
6510
|
+
return out;
|
|
6511
|
+
}
|
|
6512
|
+
async function listPeersForMesh(slug) {
|
|
6513
|
+
const bridged = await tryBridge(slug, "peers");
|
|
6514
|
+
if (bridged && bridged.ok) {
|
|
6515
|
+
return bridged.result;
|
|
6516
|
+
}
|
|
6517
|
+
let result = [];
|
|
6518
|
+
await withMesh({ meshSlug: slug }, async (client) => {
|
|
6519
|
+
const all = await client.listPeers();
|
|
6520
|
+
const selfPubkey = client.getSessionPubkey();
|
|
6521
|
+
result = selfPubkey ? all.filter((p) => p.pubkey !== selfPubkey) : all;
|
|
6522
|
+
});
|
|
6523
|
+
return result;
|
|
6524
|
+
}
|
|
6400
6525
|
async function runPeers(flags) {
|
|
6401
6526
|
const config = readConfig();
|
|
6402
6527
|
const slugs = flags.mesh ? [flags.mesh] : config.meshes.map((m) => m.slug);
|
|
@@ -6405,55 +6530,59 @@ async function runPeers(flags) {
|
|
|
6405
6530
|
render.hint("claudemesh <invite-url> # join + launch");
|
|
6406
6531
|
process.exit(1);
|
|
6407
6532
|
}
|
|
6533
|
+
const fieldList = typeof flags.json === "string" && flags.json.length > 0 ? flags.json.split(",").map((s) => s.trim()).filter(Boolean) : null;
|
|
6534
|
+
const wantsJson = flags.json !== undefined && flags.json !== false;
|
|
6408
6535
|
const allJson = [];
|
|
6409
6536
|
for (const slug of slugs) {
|
|
6410
6537
|
try {
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
const
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
render.
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
}
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
render.info(
|
|
6439
|
-
|
|
6440
|
-
render.info(dim(` cwd: ${p.cwd}`));
|
|
6441
|
-
}
|
|
6442
|
-
});
|
|
6538
|
+
const peers = await listPeersForMesh(slug);
|
|
6539
|
+
if (wantsJson) {
|
|
6540
|
+
const projected = fieldList ? peers.map((p) => projectFields(p, fieldList)) : peers;
|
|
6541
|
+
allJson.push({ mesh: slug, peers: projected });
|
|
6542
|
+
continue;
|
|
6543
|
+
}
|
|
6544
|
+
render.section(`peers on ${slug} (${peers.length})`);
|
|
6545
|
+
if (peers.length === 0) {
|
|
6546
|
+
render.info(dim(" (no peers connected)"));
|
|
6547
|
+
continue;
|
|
6548
|
+
}
|
|
6549
|
+
for (const p of peers) {
|
|
6550
|
+
const groups = p.groups.length ? " [" + p.groups.map((g) => `@${g.name}${g.role ? `:${g.role}` : ""}`).join(", ") + "]" : "";
|
|
6551
|
+
const statusDot = p.status === "working" ? yellow("●") : green("●");
|
|
6552
|
+
const name = bold(p.displayName);
|
|
6553
|
+
const meta = [];
|
|
6554
|
+
if (p.peerType)
|
|
6555
|
+
meta.push(p.peerType);
|
|
6556
|
+
if (p.channel)
|
|
6557
|
+
meta.push(p.channel);
|
|
6558
|
+
if (p.model)
|
|
6559
|
+
meta.push(p.model);
|
|
6560
|
+
const metaStr = meta.length ? dim(` (${meta.join(", ")})`) : "";
|
|
6561
|
+
const summary = p.summary ? dim(` — ${p.summary}`) : "";
|
|
6562
|
+
const pubkeyTag = dim(` · ${p.pubkey.slice(0, 16)}…`);
|
|
6563
|
+
render.info(`${statusDot} ${name}${groups}${metaStr}${pubkeyTag}${summary}`);
|
|
6564
|
+
if (p.cwd)
|
|
6565
|
+
render.info(dim(` cwd: ${p.cwd}`));
|
|
6566
|
+
}
|
|
6443
6567
|
} catch (e) {
|
|
6444
6568
|
render.err(`${slug}: ${e instanceof Error ? e.message : String(e)}`);
|
|
6445
6569
|
}
|
|
6446
6570
|
}
|
|
6447
|
-
if (
|
|
6571
|
+
if (wantsJson) {
|
|
6448
6572
|
process.stdout.write(JSON.stringify(slugs.length === 1 ? allJson[0]?.peers : allJson, null, 2) + `
|
|
6449
6573
|
`);
|
|
6450
6574
|
}
|
|
6451
6575
|
}
|
|
6576
|
+
var FIELD_ALIAS;
|
|
6452
6577
|
var init_peers = __esm(() => {
|
|
6453
6578
|
init_connect();
|
|
6454
6579
|
init_facade();
|
|
6580
|
+
init_client3();
|
|
6455
6581
|
init_render();
|
|
6456
6582
|
init_styles();
|
|
6583
|
+
FIELD_ALIAS = {
|
|
6584
|
+
name: "displayName"
|
|
6585
|
+
};
|
|
6457
6586
|
});
|
|
6458
6587
|
|
|
6459
6588
|
// src/commands/send.ts
|
|
@@ -6462,7 +6591,33 @@ __export(exports_send, {
|
|
|
6462
6591
|
runSend: () => runSend
|
|
6463
6592
|
});
|
|
6464
6593
|
async function runSend(flags, to, message) {
|
|
6594
|
+
if (!to || !message) {
|
|
6595
|
+
render.err("Usage: claudemesh send <to> <message>");
|
|
6596
|
+
process.exit(1);
|
|
6597
|
+
}
|
|
6465
6598
|
const priority = flags.priority === "now" ? "now" : flags.priority === "low" ? "low" : "next";
|
|
6599
|
+
const config = readConfig();
|
|
6600
|
+
const meshSlug = flags.mesh ?? (config.meshes.length === 1 ? config.meshes[0].slug : null);
|
|
6601
|
+
if (meshSlug) {
|
|
6602
|
+
const bridged = await tryBridge(meshSlug, "send", { to, message, priority });
|
|
6603
|
+
if (bridged !== null) {
|
|
6604
|
+
if (bridged.ok) {
|
|
6605
|
+
const r = bridged.result;
|
|
6606
|
+
if (flags.json) {
|
|
6607
|
+
console.log(JSON.stringify({ ok: true, messageId: r.messageId, target: to }));
|
|
6608
|
+
} else {
|
|
6609
|
+
render.ok(`sent to ${to}`, r.messageId ? dim(r.messageId.slice(0, 8)) : undefined);
|
|
6610
|
+
}
|
|
6611
|
+
return;
|
|
6612
|
+
}
|
|
6613
|
+
if (flags.json) {
|
|
6614
|
+
console.log(JSON.stringify({ ok: false, error: bridged.error }));
|
|
6615
|
+
} else {
|
|
6616
|
+
render.err(`send failed: ${bridged.error}`);
|
|
6617
|
+
}
|
|
6618
|
+
process.exit(1);
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6466
6621
|
await withMesh({ meshSlug: flags.mesh ?? null }, async (client) => {
|
|
6467
6622
|
let targetSpec = to;
|
|
6468
6623
|
if (!to.startsWith("@") && to !== "*" && !/^[0-9a-f]{64}$/i.test(to)) {
|
|
@@ -6470,22 +6625,34 @@ async function runSend(flags, to, message) {
|
|
|
6470
6625
|
const match = peers.find((p) => p.displayName.toLowerCase() === to.toLowerCase());
|
|
6471
6626
|
if (!match) {
|
|
6472
6627
|
const names = peers.map((p) => p.displayName).join(", ");
|
|
6473
|
-
|
|
6628
|
+
render.err(`Peer "${to}" not found.`, `online: ${names || "(none)"}`);
|
|
6474
6629
|
process.exit(1);
|
|
6475
6630
|
}
|
|
6476
6631
|
targetSpec = match.pubkey;
|
|
6477
6632
|
}
|
|
6478
6633
|
const result = await client.send(targetSpec, message, priority);
|
|
6479
6634
|
if (result.ok) {
|
|
6480
|
-
|
|
6635
|
+
if (flags.json) {
|
|
6636
|
+
console.log(JSON.stringify({ ok: true, messageId: result.messageId, target: to }));
|
|
6637
|
+
} else {
|
|
6638
|
+
render.ok(`sent to ${to}`, result.messageId ? dim(result.messageId.slice(0, 8)) : undefined);
|
|
6639
|
+
}
|
|
6481
6640
|
} else {
|
|
6482
|
-
|
|
6641
|
+
if (flags.json) {
|
|
6642
|
+
console.log(JSON.stringify({ ok: false, error: result.error ?? "unknown" }));
|
|
6643
|
+
} else {
|
|
6644
|
+
render.err(`send failed: ${result.error ?? "unknown error"}`);
|
|
6645
|
+
}
|
|
6483
6646
|
process.exit(1);
|
|
6484
6647
|
}
|
|
6485
6648
|
});
|
|
6486
6649
|
}
|
|
6487
6650
|
var init_send = __esm(() => {
|
|
6488
6651
|
init_connect();
|
|
6652
|
+
init_facade();
|
|
6653
|
+
init_client3();
|
|
6654
|
+
init_render();
|
|
6655
|
+
init_styles();
|
|
6489
6656
|
});
|
|
6490
6657
|
|
|
6491
6658
|
// src/commands/inbox.ts
|
|
@@ -6731,20 +6898,40 @@ __export(exports_broker_actions, {
|
|
|
6731
6898
|
runForget: () => runForget,
|
|
6732
6899
|
runClock: () => runClock
|
|
6733
6900
|
});
|
|
6901
|
+
function unambiguousMesh(opts) {
|
|
6902
|
+
if (opts.mesh)
|
|
6903
|
+
return opts.mesh;
|
|
6904
|
+
const config = readConfig();
|
|
6905
|
+
return config.meshes.length === 1 ? config.meshes[0].slug : null;
|
|
6906
|
+
}
|
|
6734
6907
|
async function runStatusSet(state, opts) {
|
|
6735
6908
|
const valid = ["idle", "working", "dnd"];
|
|
6736
6909
|
if (!valid.includes(state)) {
|
|
6737
6910
|
render.err(`Invalid status: ${state}`, `must be one of: ${valid.join(", ")}`);
|
|
6738
6911
|
return EXIT.INVALID_ARGS;
|
|
6739
6912
|
}
|
|
6913
|
+
const meshSlug = unambiguousMesh(opts);
|
|
6914
|
+
if (meshSlug) {
|
|
6915
|
+
const bridged = await tryBridge(meshSlug, "status_set", { status: state });
|
|
6916
|
+
if (bridged !== null) {
|
|
6917
|
+
if (bridged.ok) {
|
|
6918
|
+
if (opts.json)
|
|
6919
|
+
console.log(JSON.stringify({ status: state }));
|
|
6920
|
+
else
|
|
6921
|
+
render.ok(`status set to ${bold(state)}`);
|
|
6922
|
+
return EXIT.SUCCESS;
|
|
6923
|
+
}
|
|
6924
|
+
render.err(bridged.error);
|
|
6925
|
+
return EXIT.INTERNAL_ERROR;
|
|
6926
|
+
}
|
|
6927
|
+
}
|
|
6740
6928
|
await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
|
|
6741
6929
|
await client.setStatus(state);
|
|
6742
6930
|
});
|
|
6743
|
-
if (opts.json)
|
|
6931
|
+
if (opts.json)
|
|
6744
6932
|
console.log(JSON.stringify({ status: state }));
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
render.ok(`status set to ${bold(state)}`);
|
|
6933
|
+
else
|
|
6934
|
+
render.ok(`status set to ${bold(state)}`);
|
|
6748
6935
|
return EXIT.SUCCESS;
|
|
6749
6936
|
}
|
|
6750
6937
|
async function runSummary(text, opts) {
|
|
@@ -6752,14 +6939,28 @@ async function runSummary(text, opts) {
|
|
|
6752
6939
|
render.err("Usage: claudemesh summary <text>");
|
|
6753
6940
|
return EXIT.INVALID_ARGS;
|
|
6754
6941
|
}
|
|
6942
|
+
const meshSlug = unambiguousMesh(opts);
|
|
6943
|
+
if (meshSlug) {
|
|
6944
|
+
const bridged = await tryBridge(meshSlug, "summary", { summary: text });
|
|
6945
|
+
if (bridged !== null) {
|
|
6946
|
+
if (bridged.ok) {
|
|
6947
|
+
if (opts.json)
|
|
6948
|
+
console.log(JSON.stringify({ summary: text }));
|
|
6949
|
+
else
|
|
6950
|
+
render.ok("summary set", dim(text));
|
|
6951
|
+
return EXIT.SUCCESS;
|
|
6952
|
+
}
|
|
6953
|
+
render.err(bridged.error);
|
|
6954
|
+
return EXIT.INTERNAL_ERROR;
|
|
6955
|
+
}
|
|
6956
|
+
}
|
|
6755
6957
|
await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
|
|
6756
6958
|
await client.setSummary(text);
|
|
6757
6959
|
});
|
|
6758
|
-
if (opts.json)
|
|
6960
|
+
if (opts.json)
|
|
6759
6961
|
console.log(JSON.stringify({ summary: text }));
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
render.ok("summary set", dim(text));
|
|
6962
|
+
else
|
|
6963
|
+
render.ok("summary set", dim(text));
|
|
6763
6964
|
return EXIT.SUCCESS;
|
|
6764
6965
|
}
|
|
6765
6966
|
async function runVisible(value, opts) {
|
|
@@ -6772,14 +6973,28 @@ async function runVisible(value, opts) {
|
|
|
6772
6973
|
render.err("Usage: claudemesh visible <true|false>");
|
|
6773
6974
|
return EXIT.INVALID_ARGS;
|
|
6774
6975
|
}
|
|
6976
|
+
const meshSlug = unambiguousMesh(opts);
|
|
6977
|
+
if (meshSlug) {
|
|
6978
|
+
const bridged = await tryBridge(meshSlug, "visible", { visible });
|
|
6979
|
+
if (bridged !== null) {
|
|
6980
|
+
if (bridged.ok) {
|
|
6981
|
+
if (opts.json)
|
|
6982
|
+
console.log(JSON.stringify({ visible }));
|
|
6983
|
+
else
|
|
6984
|
+
render.ok(visible ? "you are now visible to peers" : "you are now hidden", visible ? undefined : "direct messages still reach you");
|
|
6985
|
+
return EXIT.SUCCESS;
|
|
6986
|
+
}
|
|
6987
|
+
render.err(bridged.error);
|
|
6988
|
+
return EXIT.INTERNAL_ERROR;
|
|
6989
|
+
}
|
|
6990
|
+
}
|
|
6775
6991
|
await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
|
|
6776
6992
|
await client.setVisible(visible);
|
|
6777
6993
|
});
|
|
6778
|
-
if (opts.json)
|
|
6994
|
+
if (opts.json)
|
|
6779
6995
|
console.log(JSON.stringify({ visible }));
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
render.ok(visible ? "you are now visible to peers" : "you are now hidden", visible ? undefined : "direct messages still reach you");
|
|
6996
|
+
else
|
|
6997
|
+
render.ok(visible ? "you are now visible to peers" : "you are now hidden", visible ? undefined : "direct messages still reach you");
|
|
6783
6998
|
return EXIT.SUCCESS;
|
|
6784
6999
|
}
|
|
6785
7000
|
async function runGroupJoin(name, opts) {
|
|
@@ -6967,6 +7182,8 @@ async function runTaskComplete(id, result, opts) {
|
|
|
6967
7182
|
}
|
|
6968
7183
|
var init_broker_actions = __esm(() => {
|
|
6969
7184
|
init_connect();
|
|
7185
|
+
init_facade();
|
|
7186
|
+
init_client3();
|
|
6970
7187
|
init_render();
|
|
6971
7188
|
init_styles();
|
|
6972
7189
|
init_exit_codes();
|
|
@@ -7278,17 +7495,17 @@ __export(exports_install, {
|
|
|
7278
7495
|
import {
|
|
7279
7496
|
chmodSync as chmodSync3,
|
|
7280
7497
|
copyFileSync,
|
|
7281
|
-
existsSync as
|
|
7498
|
+
existsSync as existsSync6,
|
|
7282
7499
|
mkdirSync as mkdirSync3,
|
|
7283
7500
|
readFileSync as readFileSync4,
|
|
7284
7501
|
writeFileSync as writeFileSync5
|
|
7285
7502
|
} from "node:fs";
|
|
7286
|
-
import { homedir as
|
|
7287
|
-
import { dirname as dirname2, join as
|
|
7503
|
+
import { homedir as homedir5, platform as platform5 } from "node:os";
|
|
7504
|
+
import { dirname as dirname2, join as join5, resolve } from "node:path";
|
|
7288
7505
|
import { fileURLToPath } from "node:url";
|
|
7289
7506
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
7290
7507
|
function readClaudeConfig() {
|
|
7291
|
-
if (!
|
|
7508
|
+
if (!existsSync6(CLAUDE_CONFIG))
|
|
7292
7509
|
return {};
|
|
7293
7510
|
const text = readFileSync4(CLAUDE_CONFIG, "utf-8").trim();
|
|
7294
7511
|
if (!text)
|
|
@@ -7300,12 +7517,12 @@ function readClaudeConfig() {
|
|
|
7300
7517
|
}
|
|
7301
7518
|
}
|
|
7302
7519
|
function backupClaudeConfig() {
|
|
7303
|
-
if (!
|
|
7520
|
+
if (!existsSync6(CLAUDE_CONFIG))
|
|
7304
7521
|
return;
|
|
7305
|
-
const backupDir =
|
|
7522
|
+
const backupDir = join5(dirname2(CLAUDE_CONFIG), ".claude", "backups");
|
|
7306
7523
|
mkdirSync3(backupDir, { recursive: true });
|
|
7307
7524
|
const ts = Date.now();
|
|
7308
|
-
const dest =
|
|
7525
|
+
const dest = join5(backupDir, `.claude.json.pre-claudemesh.${ts}`);
|
|
7309
7526
|
copyFileSync(CLAUDE_CONFIG, dest);
|
|
7310
7527
|
}
|
|
7311
7528
|
function patchMcpServer(entry) {
|
|
@@ -7329,7 +7546,7 @@ function patchMcpServer(entry) {
|
|
|
7329
7546
|
return action;
|
|
7330
7547
|
}
|
|
7331
7548
|
function removeMcpServer() {
|
|
7332
|
-
if (!
|
|
7549
|
+
if (!existsSync6(CLAUDE_CONFIG))
|
|
7333
7550
|
return false;
|
|
7334
7551
|
backupClaudeConfig();
|
|
7335
7552
|
const cfg = readClaudeConfig();
|
|
@@ -7353,16 +7570,65 @@ function bunAvailable() {
|
|
|
7353
7570
|
const res = platform5() === "win32" ? spawnSync3("where", ["bun"]) : spawnSync3("sh", ["-c", "command -v bun"]);
|
|
7354
7571
|
return res.status === 0;
|
|
7355
7572
|
}
|
|
7573
|
+
function isBundledFile(p) {
|
|
7574
|
+
return /[/\\]dist[/\\]/.test(p);
|
|
7575
|
+
}
|
|
7356
7576
|
function resolveEntry() {
|
|
7357
7577
|
const here = fileURLToPath(import.meta.url);
|
|
7358
|
-
if (
|
|
7578
|
+
if (isBundledFile(here))
|
|
7359
7579
|
return here;
|
|
7360
|
-
}
|
|
7361
7580
|
return resolve(dirname2(here), "..", "index.ts");
|
|
7362
7581
|
}
|
|
7582
|
+
function resolveBundledSkillsDir() {
|
|
7583
|
+
const here = fileURLToPath(import.meta.url);
|
|
7584
|
+
const pkgRoot = resolve(dirname2(here), "..", "..");
|
|
7585
|
+
const skillsDir = join5(pkgRoot, "skills");
|
|
7586
|
+
if (existsSync6(skillsDir))
|
|
7587
|
+
return skillsDir;
|
|
7588
|
+
return null;
|
|
7589
|
+
}
|
|
7590
|
+
function installSkills() {
|
|
7591
|
+
const src = resolveBundledSkillsDir();
|
|
7592
|
+
if (!src)
|
|
7593
|
+
return [];
|
|
7594
|
+
const fs = __require("node:fs");
|
|
7595
|
+
const installed = [];
|
|
7596
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
7597
|
+
if (!entry.isDirectory())
|
|
7598
|
+
continue;
|
|
7599
|
+
const srcDir = join5(src, entry.name);
|
|
7600
|
+
const dstDir = join5(CLAUDE_SKILLS_ROOT, entry.name);
|
|
7601
|
+
mkdirSync3(dstDir, { recursive: true });
|
|
7602
|
+
for (const file of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
7603
|
+
if (!file.isFile())
|
|
7604
|
+
continue;
|
|
7605
|
+
copyFileSync(join5(srcDir, file.name), join5(dstDir, file.name));
|
|
7606
|
+
}
|
|
7607
|
+
installed.push(entry.name);
|
|
7608
|
+
}
|
|
7609
|
+
return installed;
|
|
7610
|
+
}
|
|
7611
|
+
function uninstallSkills() {
|
|
7612
|
+
const src = resolveBundledSkillsDir();
|
|
7613
|
+
if (!src)
|
|
7614
|
+
return [];
|
|
7615
|
+
const fs = __require("node:fs");
|
|
7616
|
+
const removed = [];
|
|
7617
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
7618
|
+
if (!entry.isDirectory())
|
|
7619
|
+
continue;
|
|
7620
|
+
const dstDir = join5(CLAUDE_SKILLS_ROOT, entry.name);
|
|
7621
|
+
if (existsSync6(dstDir)) {
|
|
7622
|
+
try {
|
|
7623
|
+
fs.rmSync(dstDir, { recursive: true, force: true });
|
|
7624
|
+
removed.push(entry.name);
|
|
7625
|
+
} catch {}
|
|
7626
|
+
}
|
|
7627
|
+
}
|
|
7628
|
+
return removed;
|
|
7629
|
+
}
|
|
7363
7630
|
function buildMcpEntry(entryPath) {
|
|
7364
|
-
|
|
7365
|
-
if (isBundled) {
|
|
7631
|
+
if (isBundledFile(entryPath)) {
|
|
7366
7632
|
return {
|
|
7367
7633
|
command: "claudemesh",
|
|
7368
7634
|
args: ["mcp"]
|
|
@@ -7377,7 +7643,7 @@ function entriesEqual(a, b) {
|
|
|
7377
7643
|
return a.command === b.command && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
|
|
7378
7644
|
}
|
|
7379
7645
|
function readClaudeSettings() {
|
|
7380
|
-
if (!
|
|
7646
|
+
if (!existsSync6(CLAUDE_SETTINGS))
|
|
7381
7647
|
return {};
|
|
7382
7648
|
const text = readFileSync4(CLAUDE_SETTINGS, "utf-8").trim();
|
|
7383
7649
|
if (!text)
|
|
@@ -7404,7 +7670,7 @@ function installAllowedTools() {
|
|
|
7404
7670
|
return { added: toAdd, unchanged: CLAUDEMESH_TOOLS.length - toAdd.length };
|
|
7405
7671
|
}
|
|
7406
7672
|
function uninstallAllowedTools() {
|
|
7407
|
-
if (!
|
|
7673
|
+
if (!existsSync6(CLAUDE_SETTINGS))
|
|
7408
7674
|
return 0;
|
|
7409
7675
|
const settings = readClaudeSettings();
|
|
7410
7676
|
const existing = settings.allowedTools ?? [];
|
|
@@ -7439,7 +7705,7 @@ function installHooks() {
|
|
|
7439
7705
|
return { added, unchanged };
|
|
7440
7706
|
}
|
|
7441
7707
|
function uninstallHooks() {
|
|
7442
|
-
if (!
|
|
7708
|
+
if (!existsSync6(CLAUDE_SETTINGS))
|
|
7443
7709
|
return 0;
|
|
7444
7710
|
const settings = readClaudeSettings();
|
|
7445
7711
|
const hooks = settings.hooks;
|
|
@@ -7479,15 +7745,16 @@ function installStatusLine() {
|
|
|
7479
7745
|
}
|
|
7480
7746
|
function runInstall(args = []) {
|
|
7481
7747
|
const skipHooks = args.includes("--no-hooks");
|
|
7748
|
+
const skipSkill = args.includes("--no-skill");
|
|
7482
7749
|
const wantStatusLine = args.includes("--status-line");
|
|
7483
7750
|
render.section("claudemesh install");
|
|
7484
7751
|
const entry = resolveEntry();
|
|
7485
|
-
const
|
|
7486
|
-
if (!
|
|
7752
|
+
const bundled = isBundledFile(entry);
|
|
7753
|
+
if (!bundled && !bunAvailable()) {
|
|
7487
7754
|
render.err("`bun` is not on PATH.", "Install Bun first: https://bun.com");
|
|
7488
7755
|
process.exit(1);
|
|
7489
7756
|
}
|
|
7490
|
-
if (!
|
|
7757
|
+
if (!existsSync6(entry)) {
|
|
7491
7758
|
render.err(`MCP entry not found at ${entry}`);
|
|
7492
7759
|
process.exit(1);
|
|
7493
7760
|
}
|
|
@@ -7533,6 +7800,19 @@ function runInstall(args = []) {
|
|
|
7533
7800
|
} else {
|
|
7534
7801
|
render.info(dim("· Hooks skipped (--no-hooks)"));
|
|
7535
7802
|
}
|
|
7803
|
+
if (!skipSkill) {
|
|
7804
|
+
try {
|
|
7805
|
+
const installed = installSkills();
|
|
7806
|
+
if (installed.length > 0) {
|
|
7807
|
+
render.ok(`Claude skill${installed.length === 1 ? "" : "s"} installed`, installed.join(", "));
|
|
7808
|
+
render.info(dim(` ${join5(CLAUDE_SKILLS_ROOT, installed[0])}/SKILL.md`));
|
|
7809
|
+
}
|
|
7810
|
+
} catch (e) {
|
|
7811
|
+
render.warn(`skill install failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
7812
|
+
}
|
|
7813
|
+
} else {
|
|
7814
|
+
render.info(dim("· Skill install skipped (--no-skill)"));
|
|
7815
|
+
}
|
|
7536
7816
|
if (wantStatusLine) {
|
|
7537
7817
|
try {
|
|
7538
7818
|
const { installed } = installStatusLine();
|
|
@@ -7595,16 +7875,27 @@ function runUninstall() {
|
|
|
7595
7875
|
} catch (e) {
|
|
7596
7876
|
render.warn(`hook removal failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
7597
7877
|
}
|
|
7878
|
+
try {
|
|
7879
|
+
const removed = uninstallSkills();
|
|
7880
|
+
if (removed.length > 0) {
|
|
7881
|
+
render.ok(`Skill${removed.length === 1 ? "" : "s"} removed`, removed.join(", "));
|
|
7882
|
+
} else {
|
|
7883
|
+
render.info(dim("· No claudemesh skills to remove"));
|
|
7884
|
+
}
|
|
7885
|
+
} catch (e) {
|
|
7886
|
+
render.warn(`skill removal failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
7887
|
+
}
|
|
7598
7888
|
render.blank();
|
|
7599
7889
|
render.info("Restart Claude Code to drop the MCP connection + hooks.");
|
|
7600
7890
|
}
|
|
7601
|
-
var MCP_NAME = "claudemesh", CLAUDE_CONFIG, CLAUDE_SETTINGS, HOOK_COMMAND_STOP = "claudemesh hook idle", HOOK_COMMAND_USER_PROMPT = "claudemesh hook working", HOOK_MARKER = "claudemesh hook ", CLAUDEMESH_TOOLS;
|
|
7891
|
+
var MCP_NAME = "claudemesh", CLAUDE_CONFIG, CLAUDE_SETTINGS, HOOK_COMMAND_STOP = "claudemesh hook idle", HOOK_COMMAND_USER_PROMPT = "claudemesh hook working", HOOK_MARKER = "claudemesh hook ", CLAUDE_SKILLS_ROOT, CLAUDEMESH_TOOLS;
|
|
7602
7892
|
var init_install = __esm(() => {
|
|
7603
7893
|
init_facade();
|
|
7604
7894
|
init_render();
|
|
7605
7895
|
init_styles();
|
|
7606
|
-
CLAUDE_CONFIG =
|
|
7607
|
-
CLAUDE_SETTINGS =
|
|
7896
|
+
CLAUDE_CONFIG = join5(homedir5(), ".claude.json");
|
|
7897
|
+
CLAUDE_SETTINGS = join5(homedir5(), ".claude", "settings.json");
|
|
7898
|
+
CLAUDE_SKILLS_ROOT = join5(homedir5(), ".claude", "skills");
|
|
7608
7899
|
CLAUDEMESH_TOOLS = [
|
|
7609
7900
|
"mcp__claudemesh__cancel_scheduled",
|
|
7610
7901
|
"mcp__claudemesh__check_messages",
|
|
@@ -7659,10 +7950,19 @@ var exports_uninstall = {};
|
|
|
7659
7950
|
__export(exports_uninstall, {
|
|
7660
7951
|
uninstall: () => uninstall
|
|
7661
7952
|
});
|
|
7662
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync6, existsSync as
|
|
7953
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync6, existsSync as existsSync7, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
|
|
7954
|
+
import { join as join6, dirname as dirname3 } from "node:path";
|
|
7955
|
+
import { homedir as homedir6 } from "node:os";
|
|
7956
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7957
|
+
function bundledSkillsDir() {
|
|
7958
|
+
const here = fileURLToPath2(import.meta.url);
|
|
7959
|
+
const pkgRoot = join6(dirname3(here), "..", "..");
|
|
7960
|
+
const skillsDir = join6(pkgRoot, "skills");
|
|
7961
|
+
return existsSync7(skillsDir) ? skillsDir : null;
|
|
7962
|
+
}
|
|
7663
7963
|
async function uninstall() {
|
|
7664
7964
|
let removed = 0;
|
|
7665
|
-
if (
|
|
7965
|
+
if (existsSync7(PATHS.CLAUDE_JSON)) {
|
|
7666
7966
|
try {
|
|
7667
7967
|
const raw = readFileSync5(PATHS.CLAUDE_JSON, "utf-8");
|
|
7668
7968
|
const config = JSON.parse(raw);
|
|
@@ -7676,7 +7976,7 @@ async function uninstall() {
|
|
|
7676
7976
|
}
|
|
7677
7977
|
} catch {}
|
|
7678
7978
|
}
|
|
7679
|
-
if (
|
|
7979
|
+
if (existsSync7(PATHS.CLAUDE_SETTINGS)) {
|
|
7680
7980
|
try {
|
|
7681
7981
|
const raw = readFileSync5(PATHS.CLAUDE_SETTINGS, "utf-8");
|
|
7682
7982
|
const config = JSON.parse(raw);
|
|
@@ -7707,16 +8007,39 @@ async function uninstall() {
|
|
|
7707
8007
|
}
|
|
7708
8008
|
} catch {}
|
|
7709
8009
|
}
|
|
8010
|
+
const src = bundledSkillsDir();
|
|
8011
|
+
if (src) {
|
|
8012
|
+
const removedSkills = [];
|
|
8013
|
+
try {
|
|
8014
|
+
for (const entry of readdirSync2(src, { withFileTypes: true })) {
|
|
8015
|
+
if (!entry.isDirectory())
|
|
8016
|
+
continue;
|
|
8017
|
+
const dst = join6(CLAUDE_SKILLS_ROOT2, entry.name);
|
|
8018
|
+
if (existsSync7(dst)) {
|
|
8019
|
+
try {
|
|
8020
|
+
rmSync2(dst, { recursive: true, force: true });
|
|
8021
|
+
removedSkills.push(entry.name);
|
|
8022
|
+
} catch {}
|
|
8023
|
+
}
|
|
8024
|
+
}
|
|
8025
|
+
if (removedSkills.length > 0) {
|
|
8026
|
+
render.ok(`removed Claude skill${removedSkills.length === 1 ? "" : "s"}`, removedSkills.join(", "));
|
|
8027
|
+
removed++;
|
|
8028
|
+
}
|
|
8029
|
+
} catch {}
|
|
8030
|
+
}
|
|
7710
8031
|
if (removed === 0) {
|
|
7711
8032
|
render.info(dim("Nothing to remove — claudemesh was not installed."));
|
|
7712
8033
|
}
|
|
7713
8034
|
return EXIT.SUCCESS;
|
|
7714
8035
|
}
|
|
8036
|
+
var CLAUDE_SKILLS_ROOT2;
|
|
7715
8037
|
var init_uninstall = __esm(() => {
|
|
7716
8038
|
init_paths();
|
|
7717
8039
|
init_render();
|
|
7718
8040
|
init_styles();
|
|
7719
8041
|
init_exit_codes();
|
|
8042
|
+
CLAUDE_SKILLS_ROOT2 = join6(homedir6(), ".claude", "skills");
|
|
7720
8043
|
});
|
|
7721
8044
|
|
|
7722
8045
|
// src/commands/doctor.ts
|
|
@@ -7724,9 +8047,9 @@ var exports_doctor = {};
|
|
|
7724
8047
|
__export(exports_doctor, {
|
|
7725
8048
|
runDoctor: () => runDoctor
|
|
7726
8049
|
});
|
|
7727
|
-
import { existsSync as
|
|
7728
|
-
import { homedir as
|
|
7729
|
-
import { join as
|
|
8050
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
|
|
8051
|
+
import { homedir as homedir7, platform as platform6 } from "node:os";
|
|
8052
|
+
import { join as join7 } from "node:path";
|
|
7730
8053
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
7731
8054
|
function checkNode() {
|
|
7732
8055
|
const major = Number(process.versions.node.split(".")[0]);
|
|
@@ -7750,8 +8073,8 @@ function checkClaudeOnPath() {
|
|
|
7750
8073
|
};
|
|
7751
8074
|
}
|
|
7752
8075
|
function checkMcpRegistered() {
|
|
7753
|
-
const claudeConfig =
|
|
7754
|
-
if (!
|
|
8076
|
+
const claudeConfig = join7(homedir7(), ".claude.json");
|
|
8077
|
+
if (!existsSync8(claudeConfig)) {
|
|
7755
8078
|
return {
|
|
7756
8079
|
name: "claudemesh MCP registered in ~/.claude.json",
|
|
7757
8080
|
pass: false,
|
|
@@ -7776,8 +8099,8 @@ function checkMcpRegistered() {
|
|
|
7776
8099
|
}
|
|
7777
8100
|
}
|
|
7778
8101
|
function checkHooksRegistered() {
|
|
7779
|
-
const settings =
|
|
7780
|
-
if (!
|
|
8102
|
+
const settings = join7(homedir7(), ".claude", "settings.json");
|
|
8103
|
+
if (!existsSync8(settings)) {
|
|
7781
8104
|
return {
|
|
7782
8105
|
name: "Status hooks registered in ~/.claude/settings.json",
|
|
7783
8106
|
pass: false,
|
|
@@ -7802,7 +8125,7 @@ function checkHooksRegistered() {
|
|
|
7802
8125
|
}
|
|
7803
8126
|
function checkConfigFile() {
|
|
7804
8127
|
const path = getConfigPath();
|
|
7805
|
-
if (!
|
|
8128
|
+
if (!existsSync8(path)) {
|
|
7806
8129
|
return {
|
|
7807
8130
|
name: "~/.claudemesh/config.json exists and parses",
|
|
7808
8131
|
pass: true,
|
|
@@ -7985,7 +8308,7 @@ var exports_status = {};
|
|
|
7985
8308
|
__export(exports_status, {
|
|
7986
8309
|
runStatus: () => runStatus
|
|
7987
8310
|
});
|
|
7988
|
-
import { statSync as statSync3, existsSync as
|
|
8311
|
+
import { statSync as statSync3, existsSync as existsSync9 } from "node:fs";
|
|
7989
8312
|
import WebSocket2 from "ws";
|
|
7990
8313
|
async function probeBroker(url, timeoutMs = 4000) {
|
|
7991
8314
|
return new Promise((resolve2) => {
|
|
@@ -8015,7 +8338,7 @@ async function runStatus() {
|
|
|
8015
8338
|
render.section(`status (v${VERSION})`);
|
|
8016
8339
|
const configPath = getConfigPath();
|
|
8017
8340
|
let configPermsNote = "missing";
|
|
8018
|
-
if (
|
|
8341
|
+
if (existsSync9(configPath)) {
|
|
8019
8342
|
const mode = (statSync3(configPath).mode & 511).toString(8).padStart(4, "0");
|
|
8020
8343
|
configPermsNote = mode === "0600" ? `${mode}` : `${mode} — expected 0600`;
|
|
8021
8344
|
}
|
|
@@ -8161,10 +8484,10 @@ var init_check_claude_binary = __esm(() => {
|
|
|
8161
8484
|
});
|
|
8162
8485
|
|
|
8163
8486
|
// src/services/health/check-mcp-registered.ts
|
|
8164
|
-
import { existsSync as
|
|
8487
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
|
|
8165
8488
|
function checkMcpRegistered2() {
|
|
8166
8489
|
try {
|
|
8167
|
-
if (!
|
|
8490
|
+
if (!existsSync10(PATHS.CLAUDE_JSON)) {
|
|
8168
8491
|
return { name: "mcp-registered", ok: false, message: "~/.claude.json not found" };
|
|
8169
8492
|
}
|
|
8170
8493
|
const raw = readFileSync7(PATHS.CLAUDE_JSON, "utf-8");
|
|
@@ -8182,10 +8505,10 @@ var init_check_mcp_registered = __esm(() => {
|
|
|
8182
8505
|
});
|
|
8183
8506
|
|
|
8184
8507
|
// src/services/health/check-hooks-registered.ts
|
|
8185
|
-
import { existsSync as
|
|
8508
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
|
|
8186
8509
|
function checkHooksRegistered2() {
|
|
8187
8510
|
try {
|
|
8188
|
-
if (!
|
|
8511
|
+
if (!existsSync11(PATHS.CLAUDE_SETTINGS)) {
|
|
8189
8512
|
return { name: "hooks-registered", ok: false, message: "~/.claude/settings.json not found" };
|
|
8190
8513
|
}
|
|
8191
8514
|
const raw = readFileSync8(PATHS.CLAUDE_SETTINGS, "utf-8");
|
|
@@ -8203,10 +8526,10 @@ var init_check_hooks_registered = __esm(() => {
|
|
|
8203
8526
|
});
|
|
8204
8527
|
|
|
8205
8528
|
// src/services/health/check-config-perms.ts
|
|
8206
|
-
import { existsSync as
|
|
8529
|
+
import { existsSync as existsSync12, statSync as statSync4 } from "node:fs";
|
|
8207
8530
|
function checkConfigPerms() {
|
|
8208
8531
|
const configFile = PATHS.CONFIG_FILE;
|
|
8209
|
-
if (!
|
|
8532
|
+
if (!existsSync12(configFile)) {
|
|
8210
8533
|
return { name: "config-perms", ok: true, message: "No config file yet (first run)" };
|
|
8211
8534
|
}
|
|
8212
8535
|
try {
|
|
@@ -8224,9 +8547,9 @@ var init_check_config_perms = __esm(() => {
|
|
|
8224
8547
|
});
|
|
8225
8548
|
|
|
8226
8549
|
// src/services/health/check-keypairs-valid.ts
|
|
8227
|
-
import { existsSync as
|
|
8550
|
+
import { existsSync as existsSync13, readFileSync as readFileSync9 } from "node:fs";
|
|
8228
8551
|
function checkKeypairsValid() {
|
|
8229
|
-
if (!
|
|
8552
|
+
if (!existsSync13(PATHS.CONFIG_FILE)) {
|
|
8230
8553
|
return { name: "keypairs-valid", ok: true, message: "No config (first run)" };
|
|
8231
8554
|
}
|
|
8232
8555
|
try {
|
|
@@ -8710,18 +9033,18 @@ var exports_url_handler = {};
|
|
|
8710
9033
|
__export(exports_url_handler, {
|
|
8711
9034
|
runUrlHandler: () => runUrlHandler
|
|
8712
9035
|
});
|
|
8713
|
-
import { platform as platform7, homedir as
|
|
8714
|
-
import { existsSync as
|
|
8715
|
-
import { join as
|
|
9036
|
+
import { platform as platform7, homedir as homedir8 } from "node:os";
|
|
9037
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync7, rmSync as rmSync3, chmodSync as chmodSync4 } from "node:fs";
|
|
9038
|
+
import { join as join8 } from "node:path";
|
|
8716
9039
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
8717
9040
|
function resolveClaudemeshBin() {
|
|
8718
9041
|
return process.argv[1] ?? "claudemesh";
|
|
8719
9042
|
}
|
|
8720
9043
|
function installDarwin() {
|
|
8721
9044
|
const binPath = resolveClaudemeshBin();
|
|
8722
|
-
const appDir =
|
|
8723
|
-
const contents =
|
|
8724
|
-
const macOS =
|
|
9045
|
+
const appDir = join8(homedir8(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
|
|
9046
|
+
const contents = join8(appDir, "Contents");
|
|
9047
|
+
const macOS = join8(contents, "MacOS");
|
|
8725
9048
|
mkdirSync4(macOS, { recursive: true });
|
|
8726
9049
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
8727
9050
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -8745,7 +9068,7 @@ function installDarwin() {
|
|
|
8745
9068
|
</array>
|
|
8746
9069
|
</dict>
|
|
8747
9070
|
</plist>`;
|
|
8748
|
-
writeFileSync7(
|
|
9071
|
+
writeFileSync7(join8(contents, "Info.plist"), plist);
|
|
8749
9072
|
const shim = `#!/bin/sh
|
|
8750
9073
|
URL="$1"
|
|
8751
9074
|
CODE=\${URL#claudemesh://}
|
|
@@ -8759,7 +9082,7 @@ tell application "Terminal"
|
|
|
8759
9082
|
end tell
|
|
8760
9083
|
EOF
|
|
8761
9084
|
`;
|
|
8762
|
-
const shimPath =
|
|
9085
|
+
const shimPath = join8(macOS, "open-url");
|
|
8763
9086
|
writeFileSync7(shimPath, shim);
|
|
8764
9087
|
chmodSync4(shimPath, 493);
|
|
8765
9088
|
const lsreg = spawnSync5("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister", ["-f", appDir], { encoding: "utf-8" });
|
|
@@ -8771,7 +9094,7 @@ EOF
|
|
|
8771
9094
|
}
|
|
8772
9095
|
function installLinux() {
|
|
8773
9096
|
const binPath = resolveClaudemeshBin();
|
|
8774
|
-
const appsDir =
|
|
9097
|
+
const appsDir = join8(homedir8(), ".local", "share", "applications");
|
|
8775
9098
|
mkdirSync4(appsDir, { recursive: true });
|
|
8776
9099
|
const desktop = `[Desktop Entry]
|
|
8777
9100
|
Type=Application
|
|
@@ -8783,7 +9106,7 @@ Terminal=true
|
|
|
8783
9106
|
MimeType=x-scheme-handler/claudemesh;
|
|
8784
9107
|
NoDisplay=true
|
|
8785
9108
|
`;
|
|
8786
|
-
const desktopPath =
|
|
9109
|
+
const desktopPath = join8(appsDir, "claudemesh.desktop");
|
|
8787
9110
|
writeFileSync7(desktopPath, desktop);
|
|
8788
9111
|
const xdg1 = spawnSync5("xdg-mime", ["default", "claudemesh.desktop", "x-scheme-handler/claudemesh"], { encoding: "utf-8" });
|
|
8789
9112
|
if (xdg1.status !== 0) {
|
|
@@ -8806,7 +9129,7 @@ function installWindows() {
|
|
|
8806
9129
|
`[HKEY_CURRENT_USER\\Software\\Classes\\claudemesh\\shell\\open\\command]`,
|
|
8807
9130
|
`@="\\"${binPath.replace(/\\/g, "\\\\")}\\" \\"%1\\""`
|
|
8808
9131
|
];
|
|
8809
|
-
const regPath =
|
|
9132
|
+
const regPath = join8(homedir8(), "claudemesh-handler.reg");
|
|
8810
9133
|
writeFileSync7(regPath, lines.join(`\r
|
|
8811
9134
|
`));
|
|
8812
9135
|
const res = spawnSync5("reg.exe", ["import", regPath], { encoding: "utf-8" });
|
|
@@ -8818,16 +9141,16 @@ function installWindows() {
|
|
|
8818
9141
|
return EXIT.SUCCESS;
|
|
8819
9142
|
}
|
|
8820
9143
|
function uninstallDarwin() {
|
|
8821
|
-
const appDir =
|
|
8822
|
-
if (
|
|
8823
|
-
|
|
9144
|
+
const appDir = join8(homedir8(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
|
|
9145
|
+
if (existsSync14(appDir))
|
|
9146
|
+
rmSync3(appDir, { recursive: true, force: true });
|
|
8824
9147
|
render.ok("removed claudemesh:// handler on macOS");
|
|
8825
9148
|
return EXIT.SUCCESS;
|
|
8826
9149
|
}
|
|
8827
9150
|
function uninstallLinux() {
|
|
8828
|
-
const desktopPath =
|
|
8829
|
-
if (
|
|
8830
|
-
|
|
9151
|
+
const desktopPath = join8(homedir8(), ".local", "share", "applications", "claudemesh.desktop");
|
|
9152
|
+
if (existsSync14(desktopPath))
|
|
9153
|
+
rmSync3(desktopPath, { force: true });
|
|
8831
9154
|
render.ok("removed claudemesh:// handler on Linux");
|
|
8832
9155
|
return EXIT.SUCCESS;
|
|
8833
9156
|
}
|
|
@@ -8871,9 +9194,9 @@ var exports_status_line = {};
|
|
|
8871
9194
|
__export(exports_status_line, {
|
|
8872
9195
|
runStatusLine: () => runStatusLine
|
|
8873
9196
|
});
|
|
8874
|
-
import { existsSync as
|
|
8875
|
-
import { join as
|
|
8876
|
-
import { homedir as
|
|
9197
|
+
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "node:fs";
|
|
9198
|
+
import { join as join9 } from "node:path";
|
|
9199
|
+
import { homedir as homedir9 } from "node:os";
|
|
8877
9200
|
async function runStatusLine() {
|
|
8878
9201
|
try {
|
|
8879
9202
|
const config = readConfig();
|
|
@@ -8881,9 +9204,9 @@ async function runStatusLine() {
|
|
|
8881
9204
|
process.stdout.write("◇ claudemesh (not joined)");
|
|
8882
9205
|
return EXIT.SUCCESS;
|
|
8883
9206
|
}
|
|
8884
|
-
const cachePath =
|
|
9207
|
+
const cachePath = join9(homedir9(), ".claudemesh", "peer-cache.json");
|
|
8885
9208
|
let cache = {};
|
|
8886
|
-
if (
|
|
9209
|
+
if (existsSync15(cachePath)) {
|
|
8887
9210
|
try {
|
|
8888
9211
|
cache = JSON.parse(readFileSync10(cachePath, "utf-8"));
|
|
8889
9212
|
} catch {}
|
|
@@ -8916,7 +9239,7 @@ __export(exports_backup, {
|
|
|
8916
9239
|
runRestore: () => runRestore,
|
|
8917
9240
|
runBackup: () => runBackup
|
|
8918
9241
|
});
|
|
8919
|
-
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, existsSync as
|
|
9242
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, existsSync as existsSync16 } from "node:fs";
|
|
8920
9243
|
import { createInterface as createInterface10 } from "node:readline";
|
|
8921
9244
|
function readHidden(prompt5) {
|
|
8922
9245
|
return new Promise((resolve2) => {
|
|
@@ -8958,7 +9281,7 @@ async function deriveKey(pass, salt, s) {
|
|
|
8958
9281
|
}
|
|
8959
9282
|
async function runBackup(outPath) {
|
|
8960
9283
|
const configPath = getConfigPath();
|
|
8961
|
-
if (!
|
|
9284
|
+
if (!existsSync16(configPath)) {
|
|
8962
9285
|
console.error(" No config found — nothing to back up. Join a mesh first.");
|
|
8963
9286
|
return EXIT.NOT_FOUND;
|
|
8964
9287
|
}
|
|
@@ -8992,7 +9315,7 @@ async function runRestore(inPath) {
|
|
|
8992
9315
|
console.error(" Usage: claudemesh restore <backup-file>");
|
|
8993
9316
|
return EXIT.INVALID_ARGS;
|
|
8994
9317
|
}
|
|
8995
|
-
if (!
|
|
9318
|
+
if (!existsSync16(inPath)) {
|
|
8996
9319
|
console.error(` ✗ File not found: ${inPath}`);
|
|
8997
9320
|
return EXIT.NOT_FOUND;
|
|
8998
9321
|
}
|
|
@@ -9015,7 +9338,7 @@ async function runRestore(inPath) {
|
|
|
9015
9338
|
return EXIT.INTERNAL_ERROR;
|
|
9016
9339
|
}
|
|
9017
9340
|
const configPath = getConfigPath();
|
|
9018
|
-
if (
|
|
9341
|
+
if (existsSync16(configPath)) {
|
|
9019
9342
|
const backupOld = `${configPath}.before-restore.${Date.now()}`;
|
|
9020
9343
|
writeFileSync8(backupOld, readFileSync11(configPath), { mode: 384 });
|
|
9021
9344
|
console.log(` ↻ Existing config saved to ${backupOld}`);
|
|
@@ -9040,8 +9363,8 @@ __export(exports_upgrade, {
|
|
|
9040
9363
|
runUpgrade: () => runUpgrade
|
|
9041
9364
|
});
|
|
9042
9365
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
9043
|
-
import { existsSync as
|
|
9044
|
-
import { dirname as
|
|
9366
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
9367
|
+
import { dirname as dirname4, join as join10, resolve as resolve2 } from "node:path";
|
|
9045
9368
|
async function latestVersion() {
|
|
9046
9369
|
try {
|
|
9047
9370
|
const res = await fetch(URLS.NPM_REGISTRY, { signal: AbortSignal.timeout(8000) });
|
|
@@ -9054,15 +9377,15 @@ async function latestVersion() {
|
|
|
9054
9377
|
}
|
|
9055
9378
|
}
|
|
9056
9379
|
function findNpm() {
|
|
9057
|
-
const portable =
|
|
9058
|
-
if (
|
|
9059
|
-
return { npm: portable, prefix:
|
|
9380
|
+
const portable = join10(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
|
|
9381
|
+
if (existsSync17(portable)) {
|
|
9382
|
+
return { npm: portable, prefix: join10(process.env.HOME ?? "", ".claudemesh") };
|
|
9060
9383
|
}
|
|
9061
9384
|
let cur = resolve2(process.argv[1] ?? ".");
|
|
9062
9385
|
for (let i = 0;i < 6; i++) {
|
|
9063
|
-
cur =
|
|
9064
|
-
const candidate =
|
|
9065
|
-
if (
|
|
9386
|
+
cur = dirname4(cur);
|
|
9387
|
+
const candidate = join10(cur, "bin", "npm");
|
|
9388
|
+
if (existsSync17(candidate))
|
|
9066
9389
|
return { npm: candidate };
|
|
9067
9390
|
}
|
|
9068
9391
|
return { npm: "npm" };
|
|
@@ -9124,9 +9447,9 @@ __export(exports_grants, {
|
|
|
9124
9447
|
runBlock: () => runBlock,
|
|
9125
9448
|
isAllowed: () => isAllowed
|
|
9126
9449
|
});
|
|
9127
|
-
import { existsSync as
|
|
9128
|
-
import { homedir as
|
|
9129
|
-
import { join as
|
|
9450
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
9451
|
+
import { homedir as homedir10 } from "node:os";
|
|
9452
|
+
import { join as join11 } from "node:path";
|
|
9130
9453
|
async function syncToBroker(meshSlug, grants) {
|
|
9131
9454
|
const auth = getStoredToken();
|
|
9132
9455
|
if (!auth)
|
|
@@ -9144,7 +9467,7 @@ async function syncToBroker(meshSlug, grants) {
|
|
|
9144
9467
|
}
|
|
9145
9468
|
}
|
|
9146
9469
|
function readGrants() {
|
|
9147
|
-
if (!
|
|
9470
|
+
if (!existsSync18(GRANT_FILE))
|
|
9148
9471
|
return {};
|
|
9149
9472
|
try {
|
|
9150
9473
|
return JSON.parse(readFileSync12(GRANT_FILE, "utf-8"));
|
|
@@ -9153,8 +9476,8 @@ function readGrants() {
|
|
|
9153
9476
|
}
|
|
9154
9477
|
}
|
|
9155
9478
|
function writeGrants(g) {
|
|
9156
|
-
const dir =
|
|
9157
|
-
if (!
|
|
9479
|
+
const dir = join11(homedir10(), ".claudemesh");
|
|
9480
|
+
if (!existsSync18(dir))
|
|
9158
9481
|
mkdirSync5(dir, { recursive: true });
|
|
9159
9482
|
writeFileSync9(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
|
|
9160
9483
|
}
|
|
@@ -9312,7 +9635,7 @@ var init_grants = __esm(() => {
|
|
|
9312
9635
|
BROKER_HTTP7 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
|
|
9313
9636
|
ALL_CAPS = ["read", "dm", "broadcast", "state-read", "state-write", "file-read"];
|
|
9314
9637
|
DEFAULT_CAPS = ["read", "dm", "broadcast", "state-read"];
|
|
9315
|
-
GRANT_FILE =
|
|
9638
|
+
GRANT_FILE = join11(homedir10(), ".claudemesh", "grants.json");
|
|
9316
9639
|
});
|
|
9317
9640
|
|
|
9318
9641
|
// src/mcp/tools/definitions.ts
|
|
@@ -10238,6 +10561,165 @@ var init_definitions = __esm(() => {
|
|
|
10238
10561
|
];
|
|
10239
10562
|
});
|
|
10240
10563
|
|
|
10564
|
+
// src/services/bridge/server.ts
|
|
10565
|
+
import { createServer as createServer2 } from "node:net";
|
|
10566
|
+
import { mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, existsSync as existsSync19, chmodSync as chmodSync5 } from "node:fs";
|
|
10567
|
+
async function resolveTarget2(client, to) {
|
|
10568
|
+
if (to.startsWith("@") || to === "*" || /^[0-9a-f]{64}$/i.test(to)) {
|
|
10569
|
+
return { ok: true, spec: to };
|
|
10570
|
+
}
|
|
10571
|
+
const peers = await client.listPeers();
|
|
10572
|
+
const match = peers.find((p) => p.displayName.toLowerCase() === to.toLowerCase());
|
|
10573
|
+
if (!match) {
|
|
10574
|
+
return {
|
|
10575
|
+
ok: false,
|
|
10576
|
+
error: `peer "${to}" not found. online: ${peers.map((p) => p.displayName).join(", ") || "(none)"}`
|
|
10577
|
+
};
|
|
10578
|
+
}
|
|
10579
|
+
return { ok: true, spec: match.pubkey };
|
|
10580
|
+
}
|
|
10581
|
+
async function dispatch(client, req) {
|
|
10582
|
+
const args = req.args ?? {};
|
|
10583
|
+
try {
|
|
10584
|
+
switch (req.verb) {
|
|
10585
|
+
case "ping": {
|
|
10586
|
+
const peers = await client.listPeers();
|
|
10587
|
+
return {
|
|
10588
|
+
id: req.id,
|
|
10589
|
+
ok: true,
|
|
10590
|
+
result: {
|
|
10591
|
+
mesh: client.meshSlug,
|
|
10592
|
+
ws_status: client.status,
|
|
10593
|
+
peers_online: peers.length,
|
|
10594
|
+
push_buffer: client.pushHistory.length
|
|
10595
|
+
}
|
|
10596
|
+
};
|
|
10597
|
+
}
|
|
10598
|
+
case "peers": {
|
|
10599
|
+
const peers = await client.listPeers();
|
|
10600
|
+
return { id: req.id, ok: true, result: peers };
|
|
10601
|
+
}
|
|
10602
|
+
case "send": {
|
|
10603
|
+
const to = String(args.to ?? "");
|
|
10604
|
+
const message = String(args.message ?? "");
|
|
10605
|
+
const priority = args.priority ?? "next";
|
|
10606
|
+
if (!to || !message) {
|
|
10607
|
+
return { id: req.id, ok: false, error: "send: `to` and `message` required" };
|
|
10608
|
+
}
|
|
10609
|
+
const resolved = await resolveTarget2(client, to);
|
|
10610
|
+
if (!resolved.ok)
|
|
10611
|
+
return { id: req.id, ok: false, error: resolved.error };
|
|
10612
|
+
const result = await client.send(resolved.spec, message, priority);
|
|
10613
|
+
if (!result.ok) {
|
|
10614
|
+
return { id: req.id, ok: false, error: result.error ?? "send failed" };
|
|
10615
|
+
}
|
|
10616
|
+
return {
|
|
10617
|
+
id: req.id,
|
|
10618
|
+
ok: true,
|
|
10619
|
+
result: { messageId: result.messageId, target: resolved.spec }
|
|
10620
|
+
};
|
|
10621
|
+
}
|
|
10622
|
+
case "summary": {
|
|
10623
|
+
const text = String(args.summary ?? "");
|
|
10624
|
+
if (!text)
|
|
10625
|
+
return { id: req.id, ok: false, error: "summary: `summary` required" };
|
|
10626
|
+
await client.setSummary(text);
|
|
10627
|
+
return { id: req.id, ok: true, result: { summary: text } };
|
|
10628
|
+
}
|
|
10629
|
+
case "status_set": {
|
|
10630
|
+
const state = String(args.status ?? "");
|
|
10631
|
+
if (!["idle", "working", "dnd"].includes(state)) {
|
|
10632
|
+
return { id: req.id, ok: false, error: "status_set: must be idle | working | dnd" };
|
|
10633
|
+
}
|
|
10634
|
+
await client.setStatus(state);
|
|
10635
|
+
return { id: req.id, ok: true, result: { status: state } };
|
|
10636
|
+
}
|
|
10637
|
+
case "visible": {
|
|
10638
|
+
const visible = Boolean(args.visible);
|
|
10639
|
+
await client.setVisible(visible);
|
|
10640
|
+
return { id: req.id, ok: true, result: { visible } };
|
|
10641
|
+
}
|
|
10642
|
+
default:
|
|
10643
|
+
return { id: req.id, ok: false, error: `unknown verb: ${req.verb}` };
|
|
10644
|
+
}
|
|
10645
|
+
} catch (err) {
|
|
10646
|
+
return {
|
|
10647
|
+
id: req.id,
|
|
10648
|
+
ok: false,
|
|
10649
|
+
error: err instanceof Error ? err.message : String(err)
|
|
10650
|
+
};
|
|
10651
|
+
}
|
|
10652
|
+
}
|
|
10653
|
+
function handleConnection(socket, client) {
|
|
10654
|
+
const parser = new LineParser;
|
|
10655
|
+
socket.on("data", (chunk) => {
|
|
10656
|
+
const lines = parser.feed(chunk);
|
|
10657
|
+
for (const line of lines) {
|
|
10658
|
+
if (!line.trim())
|
|
10659
|
+
continue;
|
|
10660
|
+
let req;
|
|
10661
|
+
try {
|
|
10662
|
+
req = JSON.parse(line);
|
|
10663
|
+
} catch {
|
|
10664
|
+
continue;
|
|
10665
|
+
}
|
|
10666
|
+
if (!req || typeof req !== "object" || !req.id || !req.verb)
|
|
10667
|
+
continue;
|
|
10668
|
+
dispatch(client, req).then((res) => {
|
|
10669
|
+
try {
|
|
10670
|
+
socket.write(frame(res));
|
|
10671
|
+
} catch {}
|
|
10672
|
+
});
|
|
10673
|
+
}
|
|
10674
|
+
});
|
|
10675
|
+
socket.on("error", () => {});
|
|
10676
|
+
}
|
|
10677
|
+
function startBridgeServer(client) {
|
|
10678
|
+
const path = socketPath(client.meshSlug);
|
|
10679
|
+
const dir = socketDir();
|
|
10680
|
+
if (!existsSync19(dir)) {
|
|
10681
|
+
mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
10682
|
+
}
|
|
10683
|
+
if (existsSync19(path)) {
|
|
10684
|
+
try {
|
|
10685
|
+
unlinkSync2(path);
|
|
10686
|
+
} catch {}
|
|
10687
|
+
}
|
|
10688
|
+
const server = createServer2((socket) => handleConnection(socket, client));
|
|
10689
|
+
try {
|
|
10690
|
+
server.listen(path);
|
|
10691
|
+
} catch (err) {
|
|
10692
|
+
process.stderr.write(`[claudemesh] bridge: failed to bind ${path}: ${String(err)}
|
|
10693
|
+
`);
|
|
10694
|
+
return null;
|
|
10695
|
+
}
|
|
10696
|
+
server.on("error", (err) => {
|
|
10697
|
+
process.stderr.write(`[claudemesh] bridge: ${String(err)}
|
|
10698
|
+
`);
|
|
10699
|
+
});
|
|
10700
|
+
try {
|
|
10701
|
+
chmodSync5(path, 384);
|
|
10702
|
+
} catch {}
|
|
10703
|
+
let stopped = false;
|
|
10704
|
+
return {
|
|
10705
|
+
path,
|
|
10706
|
+
stop() {
|
|
10707
|
+
if (stopped)
|
|
10708
|
+
return;
|
|
10709
|
+
stopped = true;
|
|
10710
|
+
try {
|
|
10711
|
+
server.close();
|
|
10712
|
+
} catch {}
|
|
10713
|
+
try {
|
|
10714
|
+
unlinkSync2(path);
|
|
10715
|
+
} catch {}
|
|
10716
|
+
}
|
|
10717
|
+
};
|
|
10718
|
+
}
|
|
10719
|
+
var init_server = __esm(() => {
|
|
10720
|
+
init_protocol();
|
|
10721
|
+
});
|
|
10722
|
+
|
|
10241
10723
|
// src/mcp/server.ts
|
|
10242
10724
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
10243
10725
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -10803,12 +11285,12 @@ ${peerLines.join(`
|
|
|
10803
11285
|
}
|
|
10804
11286
|
}
|
|
10805
11287
|
try {
|
|
10806
|
-
const { writeFileSync: writeFileSync10, mkdirSync:
|
|
11288
|
+
const { writeFileSync: writeFileSync10, mkdirSync: mkdirSync7, existsSync: existsSync20 } = await import("node:fs");
|
|
10807
11289
|
const { join: joinPath } = await import("node:path");
|
|
10808
|
-
const { homedir:
|
|
10809
|
-
const dir = joinPath(
|
|
10810
|
-
if (!
|
|
10811
|
-
|
|
11290
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
11291
|
+
const dir = joinPath(homedir11(), ".claudemesh");
|
|
11292
|
+
if (!existsSync20(dir))
|
|
11293
|
+
mkdirSync7(dir, { recursive: true });
|
|
10812
11294
|
writeFileSync10(joinPath(dir, "peer-cache.json"), JSON.stringify(statusCache));
|
|
10813
11295
|
} catch {}
|
|
10814
11296
|
return text(sections.join(`
|
|
@@ -11051,17 +11533,17 @@ ${lines.join(`
|
|
|
11051
11533
|
const { path: filePath, name: fileName, tags, to: fileTo } = args ?? {};
|
|
11052
11534
|
if (!filePath)
|
|
11053
11535
|
return text("share_file: `path` required", true);
|
|
11054
|
-
const { existsSync:
|
|
11055
|
-
if (!
|
|
11536
|
+
const { existsSync: existsSync20 } = await import("node:fs");
|
|
11537
|
+
if (!existsSync20(filePath))
|
|
11056
11538
|
return text(`share_file: file not found: ${filePath}`, true);
|
|
11057
11539
|
const client = allClients()[0];
|
|
11058
11540
|
if (!client)
|
|
11059
11541
|
return text("share_file: not connected", true);
|
|
11060
11542
|
if (fileTo) {
|
|
11061
11543
|
const { encryptFile: encryptFile2, sealKeyForPeer: sealKeyForPeer2 } = await Promise.resolve().then(() => (init_file_crypto(), exports_file_crypto));
|
|
11062
|
-
const { readFileSync: readFileSync13, writeFileSync: writeFileSync10, mkdtempSync: mkdtempSync2, unlinkSync:
|
|
11544
|
+
const { readFileSync: readFileSync13, writeFileSync: writeFileSync10, mkdtempSync: mkdtempSync2, unlinkSync: unlinkSync3, rmdirSync } = await import("node:fs");
|
|
11063
11545
|
const { tmpdir: tmpdir2 } = await import("node:os");
|
|
11064
|
-
const { join:
|
|
11546
|
+
const { join: join12, basename } = await import("node:path");
|
|
11065
11547
|
const peers = await client.listPeers();
|
|
11066
11548
|
const targetPeer = peers.find((p) => p.pubkey === fileTo || p.displayName === fileTo);
|
|
11067
11549
|
if (!targetPeer) {
|
|
@@ -11084,8 +11566,8 @@ ${lines.join(`
|
|
|
11084
11566
|
combined.set(ciphertext, nonceBytes.length);
|
|
11085
11567
|
const rawName = fileName ?? basename(filePath);
|
|
11086
11568
|
const baseName = basename(rawName).replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 255);
|
|
11087
|
-
const tmpDir = mkdtempSync2(
|
|
11088
|
-
const tmpPath =
|
|
11569
|
+
const tmpDir = mkdtempSync2(join12(tmpdir2(), "cm-"));
|
|
11570
|
+
const tmpPath = join12(tmpDir, baseName);
|
|
11089
11571
|
writeFileSync10(tmpPath, combined);
|
|
11090
11572
|
try {
|
|
11091
11573
|
const fileId = await client.uploadFile(tmpPath, client.meshId, client.meshSlug, {
|
|
@@ -11101,7 +11583,7 @@ ${lines.join(`
|
|
|
11101
11583
|
return text(`share_file: upload failed — ${e instanceof Error ? e.message : String(e)}`, true);
|
|
11102
11584
|
} finally {
|
|
11103
11585
|
try {
|
|
11104
|
-
|
|
11586
|
+
unlinkSync3(tmpPath);
|
|
11105
11587
|
} catch {}
|
|
11106
11588
|
try {
|
|
11107
11589
|
rmdirSync(tmpDir);
|
|
@@ -11161,9 +11643,9 @@ ${lines.join(`
|
|
|
11161
11643
|
const plaintext = await decryptFile2(ciphertext, nonce, kf);
|
|
11162
11644
|
if (!plaintext)
|
|
11163
11645
|
return text(genericErr, true);
|
|
11164
|
-
const { writeFileSync: writeFileSync11, mkdirSync:
|
|
11165
|
-
const { dirname:
|
|
11166
|
-
|
|
11646
|
+
const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync8 } = await import("node:fs");
|
|
11647
|
+
const { dirname: dirname6 } = await import("node:path");
|
|
11648
|
+
mkdirSync8(dirname6(save_to), { recursive: true });
|
|
11167
11649
|
writeFileSync11(save_to, plaintext);
|
|
11168
11650
|
return text(`Downloaded and decrypted: ${result.name} → ${save_to}`);
|
|
11169
11651
|
}
|
|
@@ -11174,9 +11656,9 @@ ${lines.join(`
|
|
|
11174
11656
|
}
|
|
11175
11657
|
if (!res.ok)
|
|
11176
11658
|
return text(`get_file: download failed (${res.status})`, true);
|
|
11177
|
-
const { writeFileSync: writeFileSync10, mkdirSync:
|
|
11178
|
-
const { dirname:
|
|
11179
|
-
|
|
11659
|
+
const { writeFileSync: writeFileSync10, mkdirSync: mkdirSync7 } = await import("node:fs");
|
|
11660
|
+
const { dirname: dirname5 } = await import("node:path");
|
|
11661
|
+
mkdirSync7(dirname5(save_to), { recursive: true });
|
|
11180
11662
|
writeFileSync10(save_to, Buffer.from(await res.arrayBuffer()));
|
|
11181
11663
|
return text(`Downloaded: ${result.name} → ${save_to}`);
|
|
11182
11664
|
}
|
|
@@ -11935,8 +12417,8 @@ ${lines.join(`
|
|
|
11935
12417
|
const entryType = vType ?? "env";
|
|
11936
12418
|
let plaintextBytes;
|
|
11937
12419
|
if (entryType === "file") {
|
|
11938
|
-
const { existsSync:
|
|
11939
|
-
if (!
|
|
12420
|
+
const { existsSync: existsSync20, readFileSync: readFileSync13 } = await import("node:fs");
|
|
12421
|
+
if (!existsSync20(value))
|
|
11940
12422
|
return text(`vault_set: file not found: ${value}`, true);
|
|
11941
12423
|
plaintextBytes = new Uint8Array(readFileSync13(value));
|
|
11942
12424
|
} else {
|
|
@@ -12195,8 +12677,14 @@ ${lines.join(`
|
|
|
12195
12677
|
});
|
|
12196
12678
|
const transport = new StdioServerTransport;
|
|
12197
12679
|
await server.connect(transport);
|
|
12680
|
+
const bridges = [];
|
|
12198
12681
|
startClients(config).then(() => {
|
|
12199
12682
|
wirePushHandlers().catch(() => {});
|
|
12683
|
+
for (const client of allClients()) {
|
|
12684
|
+
const bridge = startBridgeServer(client);
|
|
12685
|
+
if (bridge)
|
|
12686
|
+
bridges.push(bridge);
|
|
12687
|
+
}
|
|
12200
12688
|
}).catch(() => {
|
|
12201
12689
|
wirePushHandlers().catch(() => {});
|
|
12202
12690
|
});
|
|
@@ -12369,6 +12857,11 @@ ${lines.join(`
|
|
|
12369
12857
|
const keepalive = setInterval(() => {}, 1000);
|
|
12370
12858
|
const shutdown = () => {
|
|
12371
12859
|
clearInterval(keepalive);
|
|
12860
|
+
for (const b of bridges) {
|
|
12861
|
+
try {
|
|
12862
|
+
b.stop();
|
|
12863
|
+
} catch {}
|
|
12864
|
+
}
|
|
12372
12865
|
stopAll();
|
|
12373
12866
|
process.exit(0);
|
|
12374
12867
|
};
|
|
@@ -12490,10 +12983,11 @@ async function startServiceProxy(serviceName) {
|
|
|
12490
12983
|
process.on("SIGINT", shutdown);
|
|
12491
12984
|
}
|
|
12492
12985
|
var peerNameCache, peerNameCacheAge = 0, CACHE_TTL_MS = 30000, DEPRECATED_TOOL_HINTS, warnedTools;
|
|
12493
|
-
var
|
|
12986
|
+
var init_server2 = __esm(() => {
|
|
12494
12987
|
init_definitions();
|
|
12495
12988
|
init_facade();
|
|
12496
12989
|
init_facade8();
|
|
12990
|
+
init_server();
|
|
12497
12991
|
peerNameCache = new Map;
|
|
12498
12992
|
DEPRECATED_TOOL_HINTS = {
|
|
12499
12993
|
send_message: "claudemesh send <to> <msg> [--mesh X] [--priority Y]",
|
|
@@ -12537,7 +13031,7 @@ async function runMcp() {
|
|
|
12537
13031
|
process.exit(0);
|
|
12538
13032
|
}
|
|
12539
13033
|
var init_mcp = __esm(() => {
|
|
12540
|
-
|
|
13034
|
+
init_server2();
|
|
12541
13035
|
});
|
|
12542
13036
|
|
|
12543
13037
|
// src/commands/hook.ts
|
|
@@ -12993,12 +13487,12 @@ async function main() {
|
|
|
12993
13487
|
}
|
|
12994
13488
|
case "peers": {
|
|
12995
13489
|
const { runPeers: runPeers2 } = await Promise.resolve().then(() => (init_peers(), exports_peers));
|
|
12996
|
-
await runPeers2({ mesh: flags.mesh, json:
|
|
13490
|
+
await runPeers2({ mesh: flags.mesh, json: flags.json });
|
|
12997
13491
|
break;
|
|
12998
13492
|
}
|
|
12999
13493
|
case "send": {
|
|
13000
13494
|
const { runSend: runSend2 } = await Promise.resolve().then(() => (init_send(), exports_send));
|
|
13001
|
-
await runSend2({}, positionals[0] ?? "", positionals.slice(1).join(" "));
|
|
13495
|
+
await runSend2({ mesh: flags.mesh, priority: flags.priority, json: !!flags.json }, positionals[0] ?? "", positionals.slice(1).join(" "));
|
|
13002
13496
|
break;
|
|
13003
13497
|
}
|
|
13004
13498
|
case "inbox": {
|
|
@@ -13246,4 +13740,4 @@ main().catch((err) => {
|
|
|
13246
13740
|
process.exit(EXIT.INTERNAL_ERROR);
|
|
13247
13741
|
});
|
|
13248
13742
|
|
|
13249
|
-
//# debugId=
|
|
13743
|
+
//# debugId=E126BD4968D2FCDF64756E2164756E21
|