claudemesh-cli 1.30.2 → 1.31.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 +202 -55
- package/dist/entrypoints/cli.js.map +10 -9
- package/dist/entrypoints/mcp.js +2 -2
- package/dist/entrypoints/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/entrypoints/cli.js
CHANGED
|
@@ -104,7 +104,7 @@ __export(exports_urls, {
|
|
|
104
104
|
VERSION: () => VERSION,
|
|
105
105
|
URLS: () => URLS
|
|
106
106
|
});
|
|
107
|
-
var URLS, VERSION = "1.
|
|
107
|
+
var URLS, VERSION = "1.31.1", env;
|
|
108
108
|
var init_urls = __esm(() => {
|
|
109
109
|
URLS = {
|
|
110
110
|
BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
|
|
@@ -3780,6 +3780,7 @@ __export(exports_lifecycle, {
|
|
|
3780
3780
|
_resetDaemonReadyCache: () => _resetDaemonReadyCache
|
|
3781
3781
|
});
|
|
3782
3782
|
import { existsSync as existsSync6, readFileSync as readFileSync6, statSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
3783
|
+
import { homedir as homedir3 } from "node:os";
|
|
3783
3784
|
import { join as join4 } from "node:path";
|
|
3784
3785
|
async function ensureDaemonReady(opts = {}) {
|
|
3785
3786
|
if (lastResultThisProcess && (lastResultThisProcess.state === "up" || lastResultThisProcess.state === "started")) {
|
|
@@ -3800,6 +3801,19 @@ async function runEnsureDaemon(opts) {
|
|
|
3800
3801
|
const probe = await probeDaemon();
|
|
3801
3802
|
if (probe === "up")
|
|
3802
3803
|
return { state: "up", durationMs: Date.now() - t0 };
|
|
3804
|
+
if (isServiceManaged()) {
|
|
3805
|
+
if (probe === "stale")
|
|
3806
|
+
cleanupStaleFiles();
|
|
3807
|
+
const polled = await pollForSocket(SERVICE_BUDGET_MS);
|
|
3808
|
+
if (polled.ok)
|
|
3809
|
+
return { state: "up", durationMs: Date.now() - t0 };
|
|
3810
|
+
const tool = process.platform === "darwin" ? `launchctl print gui/$(id -u)/${SERVICE_LABEL}` : `systemctl --user status ${SYSTEMD_UNIT}`;
|
|
3811
|
+
return {
|
|
3812
|
+
state: "service-not-ready",
|
|
3813
|
+
durationMs: Date.now() - t0,
|
|
3814
|
+
reason: `service-managed daemon not responding within ${SERVICE_BUDGET_MS}ms (run \`${tool}\`)`
|
|
3815
|
+
};
|
|
3816
|
+
}
|
|
3803
3817
|
if (probe === "stale")
|
|
3804
3818
|
cleanupStaleFiles();
|
|
3805
3819
|
if (opts.noAutoSpawn) {
|
|
@@ -3819,6 +3833,15 @@ async function runEnsureDaemon(opts) {
|
|
|
3819
3833
|
markSpawnFailure();
|
|
3820
3834
|
return { state: "spawn-failed", durationMs: Date.now() - t0, reason: spawnRes.reason };
|
|
3821
3835
|
}
|
|
3836
|
+
function isServiceManaged() {
|
|
3837
|
+
if (process.platform === "darwin") {
|
|
3838
|
+
return existsSync6(join4(homedir3(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`));
|
|
3839
|
+
}
|
|
3840
|
+
if (process.platform === "linux") {
|
|
3841
|
+
return existsSync6(join4(homedir3(), ".config", "systemd", "user", SYSTEMD_UNIT));
|
|
3842
|
+
}
|
|
3843
|
+
return false;
|
|
3844
|
+
}
|
|
3822
3845
|
async function probeDaemon() {
|
|
3823
3846
|
if (!existsSync6(DAEMON_PATHS.SOCK_FILE))
|
|
3824
3847
|
return "absent";
|
|
@@ -3936,7 +3959,7 @@ async function resolveCliBinary() {
|
|
|
3936
3959
|
}
|
|
3937
3960
|
return argv1;
|
|
3938
3961
|
}
|
|
3939
|
-
var SPAWN_LOCK_FILE = () => join4(DAEMON_PATHS.DAEMON_DIR, ".spawn.lock"), SPAWN_FAIL_FILE = () => join4(DAEMON_PATHS.DAEMON_DIR, ".spawn-failure"), SPAWN_FAIL_TTL_MS = 30000, PROBE_TIMEOUT_MS =
|
|
3962
|
+
var SPAWN_LOCK_FILE = () => join4(DAEMON_PATHS.DAEMON_DIR, ".spawn.lock"), SPAWN_FAIL_FILE = () => join4(DAEMON_PATHS.DAEMON_DIR, ".spawn-failure"), SPAWN_FAIL_TTL_MS = 30000, PROBE_TIMEOUT_MS = 2500, SERVICE_BUDGET_MS = 8000, lastResultThisProcess = null, SERVICE_LABEL = "com.claudemesh.daemon", SYSTEMD_UNIT = "claudemesh-daemon.service";
|
|
3940
3963
|
var init_lifecycle = __esm(() => {
|
|
3941
3964
|
init_client3();
|
|
3942
3965
|
init_paths2();
|
|
@@ -3982,7 +4005,7 @@ __export(exports_launch, {
|
|
|
3982
4005
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
3983
4006
|
import { randomUUID } from "node:crypto";
|
|
3984
4007
|
import { mkdtempSync, writeFileSync as writeFileSync7, rmSync, readdirSync, statSync as statSync2, existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
3985
|
-
import { tmpdir, hostname as hostname2, homedir as
|
|
4008
|
+
import { tmpdir, hostname as hostname2, homedir as homedir4 } from "node:os";
|
|
3986
4009
|
import { join as join5 } from "node:path";
|
|
3987
4010
|
import { createInterface as createInterface4 } from "node:readline";
|
|
3988
4011
|
async function ensureDaemonRunning(meshSlug, quiet) {
|
|
@@ -4329,7 +4352,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4329
4352
|
} catch {}
|
|
4330
4353
|
await ensureDaemonRunning(mesh.slug, args.quiet);
|
|
4331
4354
|
try {
|
|
4332
|
-
const claudeConfigPath = join5(
|
|
4355
|
+
const claudeConfigPath = join5(homedir4(), ".claude.json");
|
|
4333
4356
|
if (existsSync7(claudeConfigPath)) {
|
|
4334
4357
|
const claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
|
|
4335
4358
|
const mcpServers = claudeConfig.mcpServers ?? {};
|
|
@@ -4435,7 +4458,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4435
4458
|
}
|
|
4436
4459
|
const meshMcpEntries = [];
|
|
4437
4460
|
if (serviceCatalog.length > 0) {
|
|
4438
|
-
const claudeConfigPath = join5(
|
|
4461
|
+
const claudeConfigPath = join5(homedir4(), ".claude.json");
|
|
4439
4462
|
let claudeConfig = {};
|
|
4440
4463
|
try {
|
|
4441
4464
|
claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
|
|
@@ -4500,9 +4523,9 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4500
4523
|
let claudeBin = "claude";
|
|
4501
4524
|
if (!isWindows2) {
|
|
4502
4525
|
const candidates = [
|
|
4503
|
-
join5(
|
|
4526
|
+
join5(homedir4(), ".local", "bin", "claude"),
|
|
4504
4527
|
"/usr/local/bin/claude",
|
|
4505
|
-
join5(
|
|
4528
|
+
join5(homedir4(), ".claude", "bin", "claude")
|
|
4506
4529
|
];
|
|
4507
4530
|
for (const c of candidates) {
|
|
4508
4531
|
if (existsSync7(c)) {
|
|
@@ -4514,7 +4537,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4514
4537
|
const cleanup = () => {
|
|
4515
4538
|
if (meshMcpEntries.length > 0) {
|
|
4516
4539
|
try {
|
|
4517
|
-
const claudeConfigPath = join5(
|
|
4540
|
+
const claudeConfigPath = join5(homedir4(), ".claude.json");
|
|
4518
4541
|
const claudeConfig = JSON.parse(readFileSync7(claudeConfigPath, "utf-8"));
|
|
4519
4542
|
const mcpServers = claudeConfig.mcpServers ?? {};
|
|
4520
4543
|
for (const { key } of meshMcpEntries) {
|
|
@@ -5221,7 +5244,7 @@ __export(exports_join, {
|
|
|
5221
5244
|
import sodium3 from "libsodium-wrappers";
|
|
5222
5245
|
import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync4 } from "node:fs";
|
|
5223
5246
|
import { join as join6, dirname as dirname3 } from "node:path";
|
|
5224
|
-
import { homedir as
|
|
5247
|
+
import { homedir as homedir5, hostname as hostname3 } from "node:os";
|
|
5225
5248
|
function deriveAppBaseUrl() {
|
|
5226
5249
|
const override = process.env.CLAUDEMESH_APP_URL;
|
|
5227
5250
|
if (override)
|
|
@@ -5340,7 +5363,7 @@ async function runJoin(args) {
|
|
|
5340
5363
|
joinedAt: new Date().toISOString()
|
|
5341
5364
|
});
|
|
5342
5365
|
writeConfig(config);
|
|
5343
|
-
const configDir = env.CLAUDEMESH_CONFIG_DIR ?? join6(
|
|
5366
|
+
const configDir = env.CLAUDEMESH_CONFIG_DIR ?? join6(homedir5(), ".claudemesh");
|
|
5344
5367
|
const inviteFile = join6(configDir, `invite-${payload.mesh_slug}.txt`);
|
|
5345
5368
|
try {
|
|
5346
5369
|
mkdirSync4(dirname3(inviteFile), { recursive: true });
|
|
@@ -7580,6 +7603,10 @@ function warnDaemonState(res, opts = {}) {
|
|
|
7580
7603
|
return true;
|
|
7581
7604
|
case "spawn-failed":
|
|
7582
7605
|
process.stderr.write(`${tag("warn")} daemon spawn failed${res.reason ? `: ${res.reason}` : ""} — using cold path ${hint("(check ~/.claudemesh/daemon/daemon.log)")}
|
|
7606
|
+
`);
|
|
7607
|
+
return true;
|
|
7608
|
+
case "service-not-ready":
|
|
7609
|
+
process.stderr.write(`${tag("warn")} ${res.reason ?? "service-managed daemon not responding"} — using cold path ${hint("(check ~/.claudemesh/daemon/daemon.log)")}
|
|
7583
7610
|
`);
|
|
7584
7611
|
return true;
|
|
7585
7612
|
}
|
|
@@ -9307,11 +9334,68 @@ function bindSseStream(res, bus) {
|
|
|
9307
9334
|
return cleanup;
|
|
9308
9335
|
}
|
|
9309
9336
|
|
|
9337
|
+
// src/daemon/process-info.ts
|
|
9338
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
9339
|
+
import { promisify } from "node:util";
|
|
9340
|
+
async function getProcessStartTime(pid) {
|
|
9341
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
9342
|
+
return null;
|
|
9343
|
+
try {
|
|
9344
|
+
const { stdout } = await execFileAsync("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
9345
|
+
encoding: "utf8",
|
|
9346
|
+
timeout: 1000
|
|
9347
|
+
});
|
|
9348
|
+
const out = stdout.trim();
|
|
9349
|
+
return out.length > 0 ? out : null;
|
|
9350
|
+
} catch {
|
|
9351
|
+
return null;
|
|
9352
|
+
}
|
|
9353
|
+
}
|
|
9354
|
+
async function getProcessStartTimes(pids) {
|
|
9355
|
+
const result = new Map;
|
|
9356
|
+
const valid = pids.filter((p) => Number.isFinite(p) && p > 0);
|
|
9357
|
+
if (valid.length === 0)
|
|
9358
|
+
return result;
|
|
9359
|
+
try {
|
|
9360
|
+
const { stdout } = await execFileAsync("ps", ["-o", "pid=,lstart=", "-p", valid.join(",")], { encoding: "utf8", timeout: 2000 });
|
|
9361
|
+
for (const raw of stdout.split(`
|
|
9362
|
+
`)) {
|
|
9363
|
+
const line = raw.trim();
|
|
9364
|
+
if (!line)
|
|
9365
|
+
continue;
|
|
9366
|
+
const m = /^(\d+)\s+(.+)$/.exec(line);
|
|
9367
|
+
if (!m)
|
|
9368
|
+
continue;
|
|
9369
|
+
const pid = Number.parseInt(m[1], 10);
|
|
9370
|
+
const lstart = m[2].trim();
|
|
9371
|
+
if (Number.isFinite(pid) && lstart.length > 0)
|
|
9372
|
+
result.set(pid, lstart);
|
|
9373
|
+
}
|
|
9374
|
+
} catch {}
|
|
9375
|
+
return result;
|
|
9376
|
+
}
|
|
9377
|
+
function isPidAlive(pid) {
|
|
9378
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
9379
|
+
return false;
|
|
9380
|
+
try {
|
|
9381
|
+
process.kill(pid, 0);
|
|
9382
|
+
return true;
|
|
9383
|
+
} catch {
|
|
9384
|
+
return false;
|
|
9385
|
+
}
|
|
9386
|
+
}
|
|
9387
|
+
var execFileAsync;
|
|
9388
|
+
var init_process_info = __esm(() => {
|
|
9389
|
+
execFileAsync = promisify(execFile2);
|
|
9390
|
+
});
|
|
9391
|
+
|
|
9310
9392
|
// src/daemon/session-registry.ts
|
|
9311
9393
|
function startReaper() {
|
|
9312
9394
|
if (reaperHandle)
|
|
9313
9395
|
return;
|
|
9314
|
-
reaperHandle = setInterval(
|
|
9396
|
+
reaperHandle = setInterval(() => {
|
|
9397
|
+
reapDead();
|
|
9398
|
+
}, REAPER_INTERVAL_MS).unref?.() ?? reaperHandle;
|
|
9315
9399
|
}
|
|
9316
9400
|
function setRegistryHooks(next) {
|
|
9317
9401
|
hooks.onRegister = next.onRegister;
|
|
@@ -9334,8 +9418,20 @@ function registerSession(info) {
|
|
|
9334
9418
|
try {
|
|
9335
9419
|
hooks.onRegister?.(stored);
|
|
9336
9420
|
} catch {}
|
|
9421
|
+
if (stored.startTime === undefined) {
|
|
9422
|
+
captureStartTimeAsync(info.token, info.pid);
|
|
9423
|
+
}
|
|
9337
9424
|
return stored;
|
|
9338
9425
|
}
|
|
9426
|
+
async function captureStartTimeAsync(token, pid) {
|
|
9427
|
+
const lstart = await getProcessStartTime(pid);
|
|
9428
|
+
if (lstart === null)
|
|
9429
|
+
return;
|
|
9430
|
+
const entry = byToken.get(token);
|
|
9431
|
+
if (!entry || entry.pid !== pid)
|
|
9432
|
+
return;
|
|
9433
|
+
entry.startTime = lstart;
|
|
9434
|
+
}
|
|
9339
9435
|
function deregisterByToken(token) {
|
|
9340
9436
|
const entry = byToken.get(token);
|
|
9341
9437
|
if (!entry)
|
|
@@ -9361,26 +9457,44 @@ function resolveToken(token) {
|
|
|
9361
9457
|
function listSessions() {
|
|
9362
9458
|
return [...byToken.values()];
|
|
9363
9459
|
}
|
|
9364
|
-
function reapDead() {
|
|
9460
|
+
async function reapDead() {
|
|
9461
|
+
const entries = [...byToken.entries()];
|
|
9365
9462
|
const dead = [];
|
|
9366
|
-
|
|
9463
|
+
const survivors = [];
|
|
9464
|
+
for (const [token, info] of entries) {
|
|
9367
9465
|
if (Date.now() - info.registeredAt > TTL_MS) {
|
|
9368
9466
|
dead.push(token);
|
|
9369
9467
|
continue;
|
|
9370
9468
|
}
|
|
9371
|
-
|
|
9372
|
-
process.kill(info.pid, 0);
|
|
9373
|
-
} catch {
|
|
9469
|
+
if (!isPidAlive(info.pid)) {
|
|
9374
9470
|
dead.push(token);
|
|
9471
|
+
continue;
|
|
9375
9472
|
}
|
|
9473
|
+
survivors.push([token, info]);
|
|
9474
|
+
}
|
|
9475
|
+
const guardedPids = survivors.filter(([, info]) => info.startTime !== undefined).map(([, info]) => info.pid);
|
|
9476
|
+
if (guardedPids.length > 0) {
|
|
9477
|
+
try {
|
|
9478
|
+
const live = await getProcessStartTimes(guardedPids);
|
|
9479
|
+
for (const [token, info] of survivors) {
|
|
9480
|
+
if (info.startTime === undefined)
|
|
9481
|
+
continue;
|
|
9482
|
+
const lstart = live.get(info.pid);
|
|
9483
|
+
if (lstart === undefined)
|
|
9484
|
+
continue;
|
|
9485
|
+
if (lstart !== info.startTime)
|
|
9486
|
+
dead.push(token);
|
|
9487
|
+
}
|
|
9488
|
+
} catch {}
|
|
9376
9489
|
}
|
|
9377
9490
|
for (const t of dead)
|
|
9378
9491
|
deregisterByToken(t);
|
|
9379
9492
|
}
|
|
9380
9493
|
var TTL_MS, REAPER_INTERVAL_MS, byToken, bySessionId, hooks, reaperHandle = null;
|
|
9381
9494
|
var init_session_registry = __esm(() => {
|
|
9495
|
+
init_process_info();
|
|
9382
9496
|
TTL_MS = 24 * 60 * 60 * 1000;
|
|
9383
|
-
REAPER_INTERVAL_MS =
|
|
9497
|
+
REAPER_INTERVAL_MS = 5 * 1000;
|
|
9384
9498
|
byToken = new Map;
|
|
9385
9499
|
bySessionId = new Map;
|
|
9386
9500
|
hooks = {};
|
|
@@ -9508,7 +9622,12 @@ function makeHandler(opts) {
|
|
|
9508
9622
|
return;
|
|
9509
9623
|
}
|
|
9510
9624
|
if (req.method === "GET" && url.pathname === "/v1/health") {
|
|
9511
|
-
|
|
9625
|
+
const brokers = {};
|
|
9626
|
+
if (opts.brokers) {
|
|
9627
|
+
for (const [slug, client] of opts.brokers)
|
|
9628
|
+
brokers[slug] = client.status;
|
|
9629
|
+
}
|
|
9630
|
+
respond(res, 200, { ok: true, pid: process.pid, brokers });
|
|
9512
9631
|
return;
|
|
9513
9632
|
}
|
|
9514
9633
|
if (req.method === "POST" && url.pathname === "/v1/sessions/register") {
|
|
@@ -11463,7 +11582,7 @@ __export(exports_service_install, {
|
|
|
11463
11582
|
});
|
|
11464
11583
|
import { existsSync as existsSync12, mkdirSync as mkdirSync7, writeFileSync as writeFileSync11, unlinkSync as unlinkSync5, readFileSync as readFileSync11 } from "node:fs";
|
|
11465
11584
|
import { execSync as execSync2 } from "node:child_process";
|
|
11466
|
-
import { homedir as
|
|
11585
|
+
import { homedir as homedir6 } from "node:os";
|
|
11467
11586
|
import { join as join8, dirname as dirname5 } from "node:path";
|
|
11468
11587
|
function detectPlatform() {
|
|
11469
11588
|
if (process.platform === "darwin")
|
|
@@ -11496,7 +11615,7 @@ function uninstallService() {
|
|
|
11496
11615
|
if (platform5 === "darwin") {
|
|
11497
11616
|
const p = darwinPlistPath();
|
|
11498
11617
|
try {
|
|
11499
|
-
execSync2(`launchctl bootout gui/$(id -u)/${
|
|
11618
|
+
execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
|
|
11500
11619
|
} catch {}
|
|
11501
11620
|
if (existsSync12(p)) {
|
|
11502
11621
|
unlinkSync5(p);
|
|
@@ -11505,7 +11624,7 @@ function uninstallService() {
|
|
|
11505
11624
|
} else if (platform5 === "linux") {
|
|
11506
11625
|
const p = linuxUnitPath();
|
|
11507
11626
|
try {
|
|
11508
|
-
execSync2(`systemctl --user disable --now ${
|
|
11627
|
+
execSync2(`systemctl --user disable --now ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
|
|
11509
11628
|
} catch {}
|
|
11510
11629
|
if (existsSync12(p)) {
|
|
11511
11630
|
unlinkSync5(p);
|
|
@@ -11515,7 +11634,7 @@ function uninstallService() {
|
|
|
11515
11634
|
return { platform: platform5, removed };
|
|
11516
11635
|
}
|
|
11517
11636
|
function darwinPlistPath() {
|
|
11518
|
-
return join8(
|
|
11637
|
+
return join8(homedir6(), "Library", "LaunchAgents", `${SERVICE_LABEL2}.plist`);
|
|
11519
11638
|
}
|
|
11520
11639
|
function installDarwin(args) {
|
|
11521
11640
|
const plist = darwinPlistPath();
|
|
@@ -11535,7 +11654,7 @@ function installDarwin(args) {
|
|
|
11535
11654
|
<plist version="1.0">
|
|
11536
11655
|
<dict>
|
|
11537
11656
|
<key>Label</key>
|
|
11538
|
-
<string>${
|
|
11657
|
+
<string>${SERVICE_LABEL2}</string>
|
|
11539
11658
|
<key>ProgramArguments</key>
|
|
11540
11659
|
<array>
|
|
11541
11660
|
<string>${escapeXml(nodeBin)}</string>
|
|
@@ -11550,11 +11669,11 @@ function installDarwin(args) {
|
|
|
11550
11669
|
<key>StandardErrorPath</key>
|
|
11551
11670
|
<string>${escapeXml(log2)}</string>
|
|
11552
11671
|
<key>WorkingDirectory</key>
|
|
11553
|
-
<string>${escapeXml(
|
|
11672
|
+
<string>${escapeXml(homedir6())}</string>
|
|
11554
11673
|
<key>EnvironmentVariables</key>
|
|
11555
11674
|
<dict>
|
|
11556
11675
|
<key>HOME</key>
|
|
11557
|
-
<string>${escapeXml(
|
|
11676
|
+
<string>${escapeXml(homedir6())}</string>
|
|
11558
11677
|
<key>PATH</key>
|
|
11559
11678
|
<string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
11560
11679
|
</dict>
|
|
@@ -11563,7 +11682,7 @@ function installDarwin(args) {
|
|
|
11563
11682
|
`;
|
|
11564
11683
|
writeFileSync11(plist, xml, { mode: 420 });
|
|
11565
11684
|
try {
|
|
11566
|
-
execSync2(`launchctl bootout gui/$(id -u)/${
|
|
11685
|
+
execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
|
|
11567
11686
|
} catch {}
|
|
11568
11687
|
try {
|
|
11569
11688
|
const pidPath = DAEMON_PATHS.PID_FILE;
|
|
@@ -11583,7 +11702,7 @@ function installDarwin(args) {
|
|
|
11583
11702
|
};
|
|
11584
11703
|
}
|
|
11585
11704
|
function linuxUnitPath() {
|
|
11586
|
-
return join8(
|
|
11705
|
+
return join8(homedir6(), ".config", "systemd", "user", SYSTEMD_UNIT2);
|
|
11587
11706
|
}
|
|
11588
11707
|
function installLinux(args) {
|
|
11589
11708
|
const unit = linuxUnitPath();
|
|
@@ -11614,7 +11733,7 @@ WantedBy=default.target
|
|
|
11614
11733
|
`;
|
|
11615
11734
|
writeFileSync11(unit, content, { mode: 420 });
|
|
11616
11735
|
try {
|
|
11617
|
-
execSync2(`systemctl --user stop ${
|
|
11736
|
+
execSync2(`systemctl --user stop ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
|
|
11618
11737
|
} catch {}
|
|
11619
11738
|
try {
|
|
11620
11739
|
const pidPath = DAEMON_PATHS.PID_FILE;
|
|
@@ -11630,7 +11749,7 @@ WantedBy=default.target
|
|
|
11630
11749
|
return {
|
|
11631
11750
|
platform: "linux",
|
|
11632
11751
|
unitPath: unit,
|
|
11633
|
-
bootCommand: `systemctl --user daemon-reload && systemctl --user enable --now ${
|
|
11752
|
+
bootCommand: `systemctl --user daemon-reload && systemctl --user enable --now ${SYSTEMD_UNIT2}`
|
|
11634
11753
|
};
|
|
11635
11754
|
}
|
|
11636
11755
|
function escapeXml(s) {
|
|
@@ -11654,7 +11773,7 @@ function readInstalledUnit() {
|
|
|
11654
11773
|
return { platform: platform5, path: path2, content: null };
|
|
11655
11774
|
}
|
|
11656
11775
|
}
|
|
11657
|
-
var
|
|
11776
|
+
var SERVICE_LABEL2 = "com.claudemesh.daemon", SYSTEMD_UNIT2 = "claudemesh-daemon.service";
|
|
11658
11777
|
var init_service_install = __esm(() => {
|
|
11659
11778
|
init_paths2();
|
|
11660
11779
|
});
|
|
@@ -11991,7 +12110,7 @@ import {
|
|
|
11991
12110
|
readFileSync as readFileSync12,
|
|
11992
12111
|
writeFileSync as writeFileSync12
|
|
11993
12112
|
} from "node:fs";
|
|
11994
|
-
import { homedir as
|
|
12113
|
+
import { homedir as homedir7, platform as platform5 } from "node:os";
|
|
11995
12114
|
import { dirname as dirname6, join as join9, resolve } from "node:path";
|
|
11996
12115
|
import { fileURLToPath } from "node:url";
|
|
11997
12116
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
@@ -12234,7 +12353,7 @@ function installStatusLine() {
|
|
|
12234
12353
|
writeClaudeSettings(settings);
|
|
12235
12354
|
return { installed: true };
|
|
12236
12355
|
}
|
|
12237
|
-
function runInstall(args = []) {
|
|
12356
|
+
async function runInstall(args = []) {
|
|
12238
12357
|
const skipHooks = args.includes("--no-hooks");
|
|
12239
12358
|
const skipSkill = args.includes("--no-skill");
|
|
12240
12359
|
const skipService = args.includes("--no-service");
|
|
@@ -12325,7 +12444,7 @@ function runInstall(args = []) {
|
|
|
12325
12444
|
} catch {}
|
|
12326
12445
|
if (!skipService && hasMeshes) {
|
|
12327
12446
|
try {
|
|
12328
|
-
installDaemonService(entry);
|
|
12447
|
+
await installDaemonService(entry);
|
|
12329
12448
|
} catch (e) {
|
|
12330
12449
|
render.warn(`daemon service install failed: ${e instanceof Error ? e.message : String(e)}`, "Run `claudemesh daemon install-service` to retry.");
|
|
12331
12450
|
}
|
|
@@ -12353,7 +12472,7 @@ function runInstall(args = []) {
|
|
|
12353
12472
|
render.info(dim(` claudemesh install --status-line # live peer count in Claude Code`));
|
|
12354
12473
|
render.info(dim(` claudemesh completions zsh # shell completions`));
|
|
12355
12474
|
}
|
|
12356
|
-
function installDaemonService(binaryEntry) {
|
|
12475
|
+
async function installDaemonService(binaryEntry) {
|
|
12357
12476
|
const {
|
|
12358
12477
|
installService: installService2,
|
|
12359
12478
|
detectPlatform: detectPlatform2
|
|
@@ -12385,7 +12504,35 @@ function installDaemonService(binaryEntry) {
|
|
|
12385
12504
|
render.ok("daemon started");
|
|
12386
12505
|
} catch (e) {
|
|
12387
12506
|
render.warn(`daemon service installed but failed to start: ${e instanceof Error ? e.message : String(e)}`, `Run manually: ${r.bootCommand}`);
|
|
12507
|
+
return;
|
|
12508
|
+
}
|
|
12509
|
+
await verifyBrokerConnectivity();
|
|
12510
|
+
}
|
|
12511
|
+
async function verifyBrokerConnectivity() {
|
|
12512
|
+
const VERIFY_BUDGET_MS = 15000;
|
|
12513
|
+
const POLL_INTERVAL_MS2 = 500;
|
|
12514
|
+
const { ipc: ipc2 } = await Promise.resolve().then(() => (init_client3(), exports_client));
|
|
12515
|
+
const start = Date.now();
|
|
12516
|
+
let lastBrokers = {};
|
|
12517
|
+
while (Date.now() - start < VERIFY_BUDGET_MS) {
|
|
12518
|
+
try {
|
|
12519
|
+
const res = await ipc2({
|
|
12520
|
+
path: "/v1/health",
|
|
12521
|
+
timeoutMs: 2000
|
|
12522
|
+
});
|
|
12523
|
+
lastBrokers = res.body?.brokers ?? {};
|
|
12524
|
+
const openMesh = Object.entries(lastBrokers).find(([, s]) => s === "open");
|
|
12525
|
+
if (openMesh) {
|
|
12526
|
+
const others = Object.entries(lastBrokers).filter(([slug]) => slug !== openMesh[0]);
|
|
12527
|
+
const tail = others.length > 0 ? `, ${others.length} other mesh${others.length === 1 ? "" : "es"} attaching` : "";
|
|
12528
|
+
render.ok(`broker connected (mesh=${openMesh[0]}${tail})`);
|
|
12529
|
+
return;
|
|
12530
|
+
}
|
|
12531
|
+
} catch {}
|
|
12532
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS2));
|
|
12388
12533
|
}
|
|
12534
|
+
const states = Object.keys(lastBrokers).length === 0 ? "no health response from daemon" : Object.entries(lastBrokers).map(([m, s]) => `${m}=${s}`).join(", ");
|
|
12535
|
+
render.warn(`broker did not reach open within ${Math.round(VERIFY_BUDGET_MS / 1000)}s (${states})`, "Check ~/.claudemesh/daemon/daemon.log for connect errors. Common causes: outbound :443 blocked, expired TLS, DNS resolution.");
|
|
12389
12536
|
}
|
|
12390
12537
|
function runUninstall() {
|
|
12391
12538
|
render.section("claudemesh uninstall");
|
|
@@ -12432,9 +12579,9 @@ var init_install = __esm(() => {
|
|
|
12432
12579
|
init_facade();
|
|
12433
12580
|
init_render();
|
|
12434
12581
|
init_styles();
|
|
12435
|
-
CLAUDE_CONFIG = join9(
|
|
12436
|
-
CLAUDE_SETTINGS = join9(
|
|
12437
|
-
CLAUDE_SKILLS_ROOT = join9(
|
|
12582
|
+
CLAUDE_CONFIG = join9(homedir7(), ".claude.json");
|
|
12583
|
+
CLAUDE_SETTINGS = join9(homedir7(), ".claude", "settings.json");
|
|
12584
|
+
CLAUDE_SKILLS_ROOT = join9(homedir7(), ".claude", "skills");
|
|
12438
12585
|
CLAUDEMESH_TOOLS = [
|
|
12439
12586
|
"mcp__claudemesh__cancel_scheduled",
|
|
12440
12587
|
"mcp__claudemesh__check_messages",
|
|
@@ -12491,7 +12638,7 @@ __export(exports_uninstall, {
|
|
|
12491
12638
|
});
|
|
12492
12639
|
import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync14, rmSync as rmSync2, readdirSync as readdirSync2 } from "node:fs";
|
|
12493
12640
|
import { join as join10, dirname as dirname7 } from "node:path";
|
|
12494
|
-
import { homedir as
|
|
12641
|
+
import { homedir as homedir8 } from "node:os";
|
|
12495
12642
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
12496
12643
|
function bundledSkillsDir() {
|
|
12497
12644
|
const here = fileURLToPath2(import.meta.url);
|
|
@@ -12578,7 +12725,7 @@ var init_uninstall = __esm(() => {
|
|
|
12578
12725
|
init_render();
|
|
12579
12726
|
init_styles();
|
|
12580
12727
|
init_exit_codes();
|
|
12581
|
-
CLAUDE_SKILLS_ROOT2 = join10(
|
|
12728
|
+
CLAUDE_SKILLS_ROOT2 = join10(homedir8(), ".claude", "skills");
|
|
12582
12729
|
});
|
|
12583
12730
|
|
|
12584
12731
|
// src/commands/doctor.ts
|
|
@@ -12587,7 +12734,7 @@ __export(exports_doctor, {
|
|
|
12587
12734
|
runDoctor: () => runDoctor
|
|
12588
12735
|
});
|
|
12589
12736
|
import { existsSync as existsSync15, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
|
|
12590
|
-
import { homedir as
|
|
12737
|
+
import { homedir as homedir9, platform as platform6 } from "node:os";
|
|
12591
12738
|
import { join as join11 } from "node:path";
|
|
12592
12739
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
12593
12740
|
function checkNode() {
|
|
@@ -12612,7 +12759,7 @@ function checkClaudeOnPath() {
|
|
|
12612
12759
|
};
|
|
12613
12760
|
}
|
|
12614
12761
|
function checkMcpRegistered() {
|
|
12615
|
-
const claudeConfig = join11(
|
|
12762
|
+
const claudeConfig = join11(homedir9(), ".claude.json");
|
|
12616
12763
|
if (!existsSync15(claudeConfig)) {
|
|
12617
12764
|
return {
|
|
12618
12765
|
name: "claudemesh MCP registered in ~/.claude.json",
|
|
@@ -12638,7 +12785,7 @@ function checkMcpRegistered() {
|
|
|
12638
12785
|
}
|
|
12639
12786
|
}
|
|
12640
12787
|
function checkHooksRegistered() {
|
|
12641
|
-
const settings = join11(
|
|
12788
|
+
const settings = join11(homedir9(), ".claude", "settings.json");
|
|
12642
12789
|
if (!existsSync15(settings)) {
|
|
12643
12790
|
return {
|
|
12644
12791
|
name: "Status hooks registered in ~/.claude/settings.json",
|
|
@@ -13572,7 +13719,7 @@ var exports_url_handler = {};
|
|
|
13572
13719
|
__export(exports_url_handler, {
|
|
13573
13720
|
runUrlHandler: () => runUrlHandler
|
|
13574
13721
|
});
|
|
13575
|
-
import { platform as platform7, homedir as
|
|
13722
|
+
import { platform as platform7, homedir as homedir10 } from "node:os";
|
|
13576
13723
|
import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync14, rmSync as rmSync3, chmodSync as chmodSync5 } from "node:fs";
|
|
13577
13724
|
import { join as join12 } from "node:path";
|
|
13578
13725
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
@@ -13581,7 +13728,7 @@ function resolveClaudemeshBin() {
|
|
|
13581
13728
|
}
|
|
13582
13729
|
function installDarwin2() {
|
|
13583
13730
|
const binPath = resolveClaudemeshBin();
|
|
13584
|
-
const appDir = join12(
|
|
13731
|
+
const appDir = join12(homedir10(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
|
|
13585
13732
|
const contents = join12(appDir, "Contents");
|
|
13586
13733
|
const macOS = join12(contents, "MacOS");
|
|
13587
13734
|
mkdirSync9(macOS, { recursive: true });
|
|
@@ -13633,7 +13780,7 @@ EOF
|
|
|
13633
13780
|
}
|
|
13634
13781
|
function installLinux2() {
|
|
13635
13782
|
const binPath = resolveClaudemeshBin();
|
|
13636
|
-
const appsDir = join12(
|
|
13783
|
+
const appsDir = join12(homedir10(), ".local", "share", "applications");
|
|
13637
13784
|
mkdirSync9(appsDir, { recursive: true });
|
|
13638
13785
|
const desktop = `[Desktop Entry]
|
|
13639
13786
|
Type=Application
|
|
@@ -13668,7 +13815,7 @@ function installWindows() {
|
|
|
13668
13815
|
`[HKEY_CURRENT_USER\\Software\\Classes\\claudemesh\\shell\\open\\command]`,
|
|
13669
13816
|
`@="\\"${binPath.replace(/\\/g, "\\\\")}\\" \\"%1\\""`
|
|
13670
13817
|
];
|
|
13671
|
-
const regPath = join12(
|
|
13818
|
+
const regPath = join12(homedir10(), "claudemesh-handler.reg");
|
|
13672
13819
|
writeFileSync14(regPath, lines.join(`\r
|
|
13673
13820
|
`));
|
|
13674
13821
|
const res = spawnSync5("reg.exe", ["import", regPath], { encoding: "utf-8" });
|
|
@@ -13680,14 +13827,14 @@ function installWindows() {
|
|
|
13680
13827
|
return EXIT.SUCCESS;
|
|
13681
13828
|
}
|
|
13682
13829
|
function uninstallDarwin() {
|
|
13683
|
-
const appDir = join12(
|
|
13830
|
+
const appDir = join12(homedir10(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
|
|
13684
13831
|
if (existsSync21(appDir))
|
|
13685
13832
|
rmSync3(appDir, { recursive: true, force: true });
|
|
13686
13833
|
render.ok("removed claudemesh:// handler on macOS");
|
|
13687
13834
|
return EXIT.SUCCESS;
|
|
13688
13835
|
}
|
|
13689
13836
|
function uninstallLinux() {
|
|
13690
|
-
const desktopPath = join12(
|
|
13837
|
+
const desktopPath = join12(homedir10(), ".local", "share", "applications", "claudemesh.desktop");
|
|
13691
13838
|
if (existsSync21(desktopPath))
|
|
13692
13839
|
rmSync3(desktopPath, { force: true });
|
|
13693
13840
|
render.ok("removed claudemesh:// handler on Linux");
|
|
@@ -13735,7 +13882,7 @@ __export(exports_status_line, {
|
|
|
13735
13882
|
});
|
|
13736
13883
|
import { existsSync as existsSync22, readFileSync as readFileSync18 } from "node:fs";
|
|
13737
13884
|
import { join as join13 } from "node:path";
|
|
13738
|
-
import { homedir as
|
|
13885
|
+
import { homedir as homedir11 } from "node:os";
|
|
13739
13886
|
async function runStatusLine() {
|
|
13740
13887
|
try {
|
|
13741
13888
|
const config = readConfig();
|
|
@@ -13743,7 +13890,7 @@ async function runStatusLine() {
|
|
|
13743
13890
|
process.stdout.write("◇ claudemesh (not joined)");
|
|
13744
13891
|
return EXIT.SUCCESS;
|
|
13745
13892
|
}
|
|
13746
|
-
const cachePath = join13(
|
|
13893
|
+
const cachePath = join13(homedir11(), ".claudemesh", "peer-cache.json");
|
|
13747
13894
|
let cache = {};
|
|
13748
13895
|
if (existsSync22(cachePath)) {
|
|
13749
13896
|
try {
|
|
@@ -13987,7 +14134,7 @@ __export(exports_grants, {
|
|
|
13987
14134
|
isAllowed: () => isAllowed
|
|
13988
14135
|
});
|
|
13989
14136
|
import { existsSync as existsSync25, mkdirSync as mkdirSync10, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
|
|
13990
|
-
import { homedir as
|
|
14137
|
+
import { homedir as homedir12 } from "node:os";
|
|
13991
14138
|
import { join as join15 } from "node:path";
|
|
13992
14139
|
async function syncToBroker(meshSlug, grants) {
|
|
13993
14140
|
const auth = getStoredToken();
|
|
@@ -14015,7 +14162,7 @@ function readGrants() {
|
|
|
14015
14162
|
}
|
|
14016
14163
|
}
|
|
14017
14164
|
function writeGrants(g) {
|
|
14018
|
-
const dir = join15(
|
|
14165
|
+
const dir = join15(homedir12(), ".claudemesh");
|
|
14019
14166
|
if (!existsSync25(dir))
|
|
14020
14167
|
mkdirSync10(dir, { recursive: true });
|
|
14021
14168
|
writeFileSync16(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
|
|
@@ -14174,7 +14321,7 @@ var init_grants = __esm(() => {
|
|
|
14174
14321
|
BROKER_HTTP7 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
|
|
14175
14322
|
ALL_CAPS = ["read", "dm", "broadcast", "state-read", "state-write", "file-read"];
|
|
14176
14323
|
DEFAULT_CAPS = ["read", "dm", "broadcast", "state-read"];
|
|
14177
|
-
GRANT_FILE = join15(
|
|
14324
|
+
GRANT_FILE = join15(homedir12(), ".claudemesh", "grants.json");
|
|
14178
14325
|
});
|
|
14179
14326
|
|
|
14180
14327
|
// src/commands/profile.ts
|
|
@@ -19213,7 +19360,7 @@ async function main() {
|
|
|
19213
19360
|
}
|
|
19214
19361
|
case "install": {
|
|
19215
19362
|
const { runInstall: runInstall2 } = await Promise.resolve().then(() => (init_install(), exports_install));
|
|
19216
|
-
runInstall2(positionals);
|
|
19363
|
+
await runInstall2(positionals);
|
|
19217
19364
|
break;
|
|
19218
19365
|
}
|
|
19219
19366
|
case "uninstall": {
|
|
@@ -19893,4 +20040,4 @@ main().catch((err) => {
|
|
|
19893
20040
|
process.exit(EXIT.INTERNAL_ERROR);
|
|
19894
20041
|
});
|
|
19895
20042
|
|
|
19896
|
-
//# debugId=
|
|
20043
|
+
//# debugId=59AFA8DBDD2CE8AD64756E2164756E21
|