claudemesh-cli 1.34.18 → 1.35.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 +343 -231
- package/dist/entrypoints/cli.js.map +6 -5
- package/dist/entrypoints/mcp.js +2 -2
- package/dist/entrypoints/mcp.js.map +2 -2
- 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.35.1", env;
|
|
108
108
|
var init_urls = __esm(() => {
|
|
109
109
|
URLS = {
|
|
110
110
|
BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
|
|
@@ -4337,6 +4337,76 @@ var init_session_hello_sig = __esm(() => {
|
|
|
4337
4337
|
DEFAULT_ATTESTATION_TTL_MS = 12 * 60 * 60 * 1000;
|
|
4338
4338
|
});
|
|
4339
4339
|
|
|
4340
|
+
// src/services/session/keypair-store.ts
|
|
4341
|
+
var exports_keypair_store = {};
|
|
4342
|
+
__export(exports_keypair_store, {
|
|
4343
|
+
sessionsDir: () => sessionsDir,
|
|
4344
|
+
loadOrCreateSessionKeypair: () => loadOrCreateSessionKeypair
|
|
4345
|
+
});
|
|
4346
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
4347
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync7 } from "node:fs";
|
|
4348
|
+
import { homedir as homedir5 } from "node:os";
|
|
4349
|
+
import { join as join5 } from "node:path";
|
|
4350
|
+
function sessionsDir() {
|
|
4351
|
+
return process.env.CLAUDEMESH_SESSIONS_DIR || join5(homedir5(), ".claudemesh", "sessions");
|
|
4352
|
+
}
|
|
4353
|
+
function keyFilePath(meshSlug, sessionId) {
|
|
4354
|
+
return join5(sessionsDir(), meshSlug, `${sessionId}.json`);
|
|
4355
|
+
}
|
|
4356
|
+
function readValidKeypair(file) {
|
|
4357
|
+
try {
|
|
4358
|
+
if (!existsSync8(file))
|
|
4359
|
+
return null;
|
|
4360
|
+
const parsed = JSON.parse(readFileSync7(file, "utf8"));
|
|
4361
|
+
if (parsed && typeof parsed.publicKey === "string" && /^[0-9a-f]{64}$/.test(parsed.publicKey) && typeof parsed.secretKey === "string" && /^[0-9a-f]{128}$/.test(parsed.secretKey)) {
|
|
4362
|
+
return { publicKey: parsed.publicKey, secretKey: parsed.secretKey };
|
|
4363
|
+
}
|
|
4364
|
+
} catch {}
|
|
4365
|
+
return null;
|
|
4366
|
+
}
|
|
4367
|
+
async function loadOrCreateSessionKeypair(meshSlug, sessionId) {
|
|
4368
|
+
if (!SLUG_RE.test(meshSlug) || !UUID_RE.test(sessionId)) {
|
|
4369
|
+
return generateKeypair3();
|
|
4370
|
+
}
|
|
4371
|
+
const file = keyFilePath(meshSlug, sessionId);
|
|
4372
|
+
const existing = readValidKeypair(file);
|
|
4373
|
+
if (existing)
|
|
4374
|
+
return existing;
|
|
4375
|
+
const kp = await generateKeypair3();
|
|
4376
|
+
try {
|
|
4377
|
+
mkdirSync4(join5(sessionsDir(), meshSlug), { recursive: true, mode: 448 });
|
|
4378
|
+
const stored = {
|
|
4379
|
+
version: 1,
|
|
4380
|
+
meshSlug,
|
|
4381
|
+
sessionId,
|
|
4382
|
+
publicKey: kp.publicKey,
|
|
4383
|
+
secretKey: kp.secretKey,
|
|
4384
|
+
createdAt: new Date().toISOString()
|
|
4385
|
+
};
|
|
4386
|
+
const tmp = `${file}.${randomBytes6(6).toString("hex")}.tmp`;
|
|
4387
|
+
writeFileSync7(tmp, JSON.stringify(stored), { mode: 384 });
|
|
4388
|
+
try {
|
|
4389
|
+
if (existsSync8(file)) {
|
|
4390
|
+
const won = readValidKeypair(file);
|
|
4391
|
+
if (won) {
|
|
4392
|
+
try {
|
|
4393
|
+
rmSync(tmp, { force: true });
|
|
4394
|
+
} catch {}
|
|
4395
|
+
return won;
|
|
4396
|
+
}
|
|
4397
|
+
}
|
|
4398
|
+
renameSync2(tmp, file);
|
|
4399
|
+
} catch {}
|
|
4400
|
+
} catch {}
|
|
4401
|
+
return kp;
|
|
4402
|
+
}
|
|
4403
|
+
var UUID_RE, SLUG_RE;
|
|
4404
|
+
var init_keypair_store = __esm(() => {
|
|
4405
|
+
init_facade7();
|
|
4406
|
+
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4407
|
+
SLUG_RE = /^[a-z0-9._-]+$/i;
|
|
4408
|
+
});
|
|
4409
|
+
|
|
4340
4410
|
// src/commands/launch.ts
|
|
4341
4411
|
var exports_launch = {};
|
|
4342
4412
|
__export(exports_launch, {
|
|
@@ -4344,10 +4414,33 @@ __export(exports_launch, {
|
|
|
4344
4414
|
});
|
|
4345
4415
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
4346
4416
|
import { randomUUID } from "node:crypto";
|
|
4347
|
-
import { mkdtempSync, writeFileSync as
|
|
4348
|
-
import { tmpdir, hostname as hostname2, homedir as
|
|
4349
|
-
import { join as
|
|
4417
|
+
import { mkdtempSync, writeFileSync as writeFileSync8, rmSync as rmSync2, readdirSync, statSync as statSync2, existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
|
|
4418
|
+
import { tmpdir, hostname as hostname2, homedir as homedir6 } from "node:os";
|
|
4419
|
+
import { join as join6 } from "node:path";
|
|
4350
4420
|
import { createInterface as createInterface4 } from "node:readline";
|
|
4421
|
+
function resolveLatestSessionUuid(cwd) {
|
|
4422
|
+
try {
|
|
4423
|
+
const slug = cwd.replace(/\//g, "-");
|
|
4424
|
+
const dir = join6(homedir6(), ".claude", "projects", slug);
|
|
4425
|
+
if (!existsSync9(dir))
|
|
4426
|
+
return;
|
|
4427
|
+
const uuidRe = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
|
|
4428
|
+
let newest = null;
|
|
4429
|
+
for (const entry of readdirSync(dir)) {
|
|
4430
|
+
const m = uuidRe.exec(entry);
|
|
4431
|
+
if (!m)
|
|
4432
|
+
continue;
|
|
4433
|
+
try {
|
|
4434
|
+
const mtime = statSync2(join6(dir, entry)).mtimeMs;
|
|
4435
|
+
if (!newest || mtime > newest.mtime)
|
|
4436
|
+
newest = { id: m[1], mtime };
|
|
4437
|
+
} catch {}
|
|
4438
|
+
}
|
|
4439
|
+
return newest?.id;
|
|
4440
|
+
} catch {
|
|
4441
|
+
return;
|
|
4442
|
+
}
|
|
4443
|
+
}
|
|
4351
4444
|
async function ensureDaemonRunning(meshSlug, quiet) {
|
|
4352
4445
|
const { ensureDaemonReady: ensureDaemonReady2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
4353
4446
|
if (!quiet)
|
|
@@ -4743,17 +4836,17 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4743
4836
|
for (const entry of readdirSync(tmpBase)) {
|
|
4744
4837
|
if (!entry.startsWith("claudemesh-"))
|
|
4745
4838
|
continue;
|
|
4746
|
-
const full =
|
|
4839
|
+
const full = join6(tmpBase, entry);
|
|
4747
4840
|
const age = Date.now() - statSync2(full).mtimeMs;
|
|
4748
4841
|
if (age > 3600000)
|
|
4749
|
-
|
|
4842
|
+
rmSync2(full, { recursive: true, force: true });
|
|
4750
4843
|
}
|
|
4751
4844
|
} catch {}
|
|
4752
4845
|
await ensureDaemonRunning(mesh.slug, args.quiet);
|
|
4753
4846
|
try {
|
|
4754
|
-
const claudeConfigPath =
|
|
4755
|
-
if (
|
|
4756
|
-
const claudeConfig = JSON.parse(
|
|
4847
|
+
const claudeConfigPath = join6(homedir6(), ".claude.json");
|
|
4848
|
+
if (existsSync9(claudeConfigPath)) {
|
|
4849
|
+
const claudeConfig = JSON.parse(readFileSync8(claudeConfigPath, "utf-8"));
|
|
4757
4850
|
const mcpServers = claudeConfig.mcpServers ?? {};
|
|
4758
4851
|
let cleaned = 0;
|
|
4759
4852
|
for (const key of Object.keys(mcpServers)) {
|
|
@@ -4771,7 +4864,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4771
4864
|
}
|
|
4772
4865
|
if (cleaned > 0) {
|
|
4773
4866
|
claudeConfig.mcpServers = mcpServers;
|
|
4774
|
-
|
|
4867
|
+
writeFileSync8(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
|
|
4775
4868
|
`, "utf-8");
|
|
4776
4869
|
}
|
|
4777
4870
|
}
|
|
@@ -4788,7 +4881,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4788
4881
|
console.log(" (Could not fetch service catalog — mesh services won't be natively available)");
|
|
4789
4882
|
}
|
|
4790
4883
|
}
|
|
4791
|
-
const tmpDir = mkdtempSync(
|
|
4884
|
+
const tmpDir = mkdtempSync(join6(tmpdir(), "claudemesh-"));
|
|
4792
4885
|
const sessionConfig = {
|
|
4793
4886
|
version: 1,
|
|
4794
4887
|
meshes: [mesh],
|
|
@@ -4797,10 +4890,18 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4797
4890
|
...parsedGroups.length > 0 ? { groups: parsedGroups } : {},
|
|
4798
4891
|
messageMode
|
|
4799
4892
|
};
|
|
4800
|
-
|
|
4801
|
-
`, "utf-8");
|
|
4893
|
+
writeFileSync8(join6(tmpDir, "config.json"), JSON.stringify(sessionConfig, null, 2) + `
|
|
4894
|
+
`, { encoding: "utf-8", mode: 384 });
|
|
4802
4895
|
const isResume = args.resume !== null || args.continueSession;
|
|
4803
|
-
|
|
4896
|
+
let claudeSessionId;
|
|
4897
|
+
if (args.resume) {
|
|
4898
|
+
claudeSessionId = args.resume;
|
|
4899
|
+
} else if (args.continueSession) {
|
|
4900
|
+
claudeSessionId = resolveLatestSessionUuid(process.cwd());
|
|
4901
|
+
} else {
|
|
4902
|
+
claudeSessionId = randomUUID();
|
|
4903
|
+
}
|
|
4904
|
+
const passSessionIdFlag = !isResume;
|
|
4804
4905
|
let sessionTokenFilePath = null;
|
|
4805
4906
|
let sessionTokenForCleanup = null;
|
|
4806
4907
|
try {
|
|
@@ -4812,7 +4913,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4812
4913
|
try {
|
|
4813
4914
|
const { generateKeypair: generateKeypair4 } = await Promise.resolve().then(() => (init_facade7(), exports_facade4));
|
|
4814
4915
|
const { signParentAttestation: signParentAttestation2 } = await Promise.resolve().then(() => (init_session_hello_sig(), exports_session_hello_sig));
|
|
4815
|
-
const sessionKp = await generateKeypair4();
|
|
4916
|
+
const sessionKp = claudeSessionId ? await (await Promise.resolve().then(() => (init_keypair_store(), exports_keypair_store))).loadOrCreateSessionKeypair(mesh.slug, claudeSessionId) : await generateKeypair4();
|
|
4816
4917
|
const att = await signParentAttestation2({
|
|
4817
4918
|
parentMemberPubkey: mesh.pubkey,
|
|
4818
4919
|
parentSecretKey: mesh.secretKey,
|
|
@@ -4858,10 +4959,10 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4858
4959
|
}
|
|
4859
4960
|
const meshMcpEntries = [];
|
|
4860
4961
|
if (serviceCatalog.length > 0) {
|
|
4861
|
-
const claudeConfigPath =
|
|
4962
|
+
const claudeConfigPath = join6(homedir6(), ".claude.json");
|
|
4862
4963
|
let claudeConfig = {};
|
|
4863
4964
|
try {
|
|
4864
|
-
claudeConfig = JSON.parse(
|
|
4965
|
+
claudeConfig = JSON.parse(readFileSync8(claudeConfigPath, "utf-8"));
|
|
4865
4966
|
} catch {
|
|
4866
4967
|
claudeConfig = {};
|
|
4867
4968
|
}
|
|
@@ -4888,7 +4989,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4888
4989
|
meshMcpEntries.push({ key: entryKey, entry });
|
|
4889
4990
|
}
|
|
4890
4991
|
claudeConfig.mcpServers = mcpServers;
|
|
4891
|
-
|
|
4992
|
+
writeFileSync8(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
|
|
4892
4993
|
`, "utf-8");
|
|
4893
4994
|
if (!args.quiet && meshMcpEntries.length > 0) {
|
|
4894
4995
|
console.log(` ${meshMcpEntries.length} mesh service(s) registered as native MCPs:`);
|
|
@@ -4912,7 +5013,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4912
5013
|
const claudeArgs = [
|
|
4913
5014
|
"--dangerously-load-development-channels",
|
|
4914
5015
|
"server:claudemesh",
|
|
4915
|
-
...claudeSessionId ? ["--session-id", claudeSessionId] : [],
|
|
5016
|
+
...passSessionIdFlag && claudeSessionId ? ["--session-id", claudeSessionId] : [],
|
|
4916
5017
|
...args.resume ? ["--resume", args.resume] : [],
|
|
4917
5018
|
...args.continueSession ? ["--continue"] : [],
|
|
4918
5019
|
...args.skipPermConfirm ? ["--dangerously-skip-permissions"] : [],
|
|
@@ -4923,12 +5024,12 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4923
5024
|
let claudeBin = "claude";
|
|
4924
5025
|
if (!isWindows2) {
|
|
4925
5026
|
const candidates = [
|
|
4926
|
-
|
|
5027
|
+
join6(homedir6(), ".local", "bin", "claude"),
|
|
4927
5028
|
"/usr/local/bin/claude",
|
|
4928
|
-
|
|
5029
|
+
join6(homedir6(), ".claude", "bin", "claude")
|
|
4929
5030
|
];
|
|
4930
5031
|
for (const c of candidates) {
|
|
4931
|
-
if (
|
|
5032
|
+
if (existsSync9(c)) {
|
|
4932
5033
|
claudeBin = c;
|
|
4933
5034
|
break;
|
|
4934
5035
|
}
|
|
@@ -4937,19 +5038,19 @@ async function runLaunch(flags, rawArgs) {
|
|
|
4937
5038
|
const cleanup = () => {
|
|
4938
5039
|
if (meshMcpEntries.length > 0) {
|
|
4939
5040
|
try {
|
|
4940
|
-
const claudeConfigPath =
|
|
4941
|
-
const claudeConfig = JSON.parse(
|
|
5041
|
+
const claudeConfigPath = join6(homedir6(), ".claude.json");
|
|
5042
|
+
const claudeConfig = JSON.parse(readFileSync8(claudeConfigPath, "utf-8"));
|
|
4942
5043
|
const mcpServers = claudeConfig.mcpServers ?? {};
|
|
4943
5044
|
for (const { key } of meshMcpEntries) {
|
|
4944
5045
|
delete mcpServers[key];
|
|
4945
5046
|
}
|
|
4946
5047
|
claudeConfig.mcpServers = mcpServers;
|
|
4947
|
-
|
|
5048
|
+
writeFileSync8(claudeConfigPath, JSON.stringify(claudeConfig, null, 2) + `
|
|
4948
5049
|
`, "utf-8");
|
|
4949
5050
|
} catch {}
|
|
4950
5051
|
}
|
|
4951
5052
|
try {
|
|
4952
|
-
|
|
5053
|
+
rmSync2(tmpDir, { recursive: true, force: true });
|
|
4953
5054
|
} catch {}
|
|
4954
5055
|
};
|
|
4955
5056
|
process.on("exit", cleanup);
|
|
@@ -5642,9 +5743,9 @@ __export(exports_join, {
|
|
|
5642
5743
|
runJoin: () => runJoin
|
|
5643
5744
|
});
|
|
5644
5745
|
import sodium3 from "libsodium-wrappers";
|
|
5645
|
-
import { writeFileSync as
|
|
5646
|
-
import { join as
|
|
5647
|
-
import { homedir as
|
|
5746
|
+
import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "node:fs";
|
|
5747
|
+
import { join as join7, dirname as dirname3 } from "node:path";
|
|
5748
|
+
import { homedir as homedir7, hostname as hostname3 } from "node:os";
|
|
5648
5749
|
function deriveAppBaseUrl() {
|
|
5649
5750
|
const override = process.env.CLAUDEMESH_APP_URL;
|
|
5650
5751
|
if (override)
|
|
@@ -5763,11 +5864,11 @@ async function runJoin(args) {
|
|
|
5763
5864
|
joinedAt: new Date().toISOString()
|
|
5764
5865
|
});
|
|
5765
5866
|
writeConfig(config);
|
|
5766
|
-
const configDir = env.CLAUDEMESH_CONFIG_DIR ??
|
|
5767
|
-
const inviteFile =
|
|
5867
|
+
const configDir = env.CLAUDEMESH_CONFIG_DIR ?? join7(homedir7(), ".claudemesh");
|
|
5868
|
+
const inviteFile = join7(configDir, `invite-${payload.mesh_slug}.txt`);
|
|
5768
5869
|
try {
|
|
5769
|
-
|
|
5770
|
-
|
|
5870
|
+
mkdirSync5(dirname3(inviteFile), { recursive: true });
|
|
5871
|
+
writeFileSync9(inviteFile, link, "utf-8");
|
|
5771
5872
|
} catch {}
|
|
5772
5873
|
console.log("");
|
|
5773
5874
|
console.log(`✓ Joined "${payload.mesh_slug}" as ${displayName}${enroll.alreadyMember ? " (already a member — re-enrolled with same pubkey)" : ""}`);
|
|
@@ -6013,7 +6114,7 @@ async function rename(oldSlug, newSlug) {
|
|
|
6013
6114
|
console.error(` ${icons.cross} Usage: ${bold("claudemesh rename")} <old-slug> <new-slug>`);
|
|
6014
6115
|
return EXIT.INVALID_ARGS;
|
|
6015
6116
|
}
|
|
6016
|
-
if (!
|
|
6117
|
+
if (!SLUG_RE2.test(newSlug)) {
|
|
6017
6118
|
console.error(` ${icons.cross} Invalid slug: must be 2-32 chars, lowercase alnum + hyphens, start with alnum`);
|
|
6018
6119
|
return EXIT.INVALID_ARGS;
|
|
6019
6120
|
}
|
|
@@ -6064,7 +6165,7 @@ async function rename(oldSlug, newSlug) {
|
|
|
6064
6165
|
return EXIT.INTERNAL_ERROR;
|
|
6065
6166
|
}
|
|
6066
6167
|
}
|
|
6067
|
-
var
|
|
6168
|
+
var SLUG_RE2;
|
|
6068
6169
|
var init_rename2 = __esm(() => {
|
|
6069
6170
|
init_facade10();
|
|
6070
6171
|
init_facade6();
|
|
@@ -6072,7 +6173,7 @@ var init_rename2 = __esm(() => {
|
|
|
6072
6173
|
init_facade();
|
|
6073
6174
|
init_styles();
|
|
6074
6175
|
init_exit_codes();
|
|
6075
|
-
|
|
6176
|
+
SLUG_RE2 = /^[a-z0-9][a-z0-9-]{1,31}$/;
|
|
6076
6177
|
});
|
|
6077
6178
|
|
|
6078
6179
|
// src/services/clipboard/read.ts
|
|
@@ -9272,12 +9373,12 @@ var init_whoami = __esm(() => {
|
|
|
9272
9373
|
});
|
|
9273
9374
|
|
|
9274
9375
|
// src/daemon/lock.ts
|
|
9275
|
-
import { existsSync as
|
|
9376
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync9, unlinkSync as unlinkSync3, writeFileSync as writeFileSync10 } from "node:fs";
|
|
9276
9377
|
import { dirname as dirname4 } from "node:path";
|
|
9277
9378
|
function acquireSingletonLock() {
|
|
9278
|
-
|
|
9279
|
-
if (
|
|
9280
|
-
const raw =
|
|
9379
|
+
mkdirSync6(dirname4(DAEMON_PATHS.PID_FILE), { recursive: true, mode: 448 });
|
|
9380
|
+
if (existsSync10(DAEMON_PATHS.PID_FILE)) {
|
|
9381
|
+
const raw = readFileSync9(DAEMON_PATHS.PID_FILE, "utf8").trim();
|
|
9281
9382
|
const oldPid = Number.parseInt(raw, 10);
|
|
9282
9383
|
if (Number.isFinite(oldPid) && oldPid > 0 && isProcessAlive(oldPid)) {
|
|
9283
9384
|
return { result: "already-running", pid: oldPid };
|
|
@@ -9285,22 +9386,22 @@ function acquireSingletonLock() {
|
|
|
9285
9386
|
try {
|
|
9286
9387
|
unlinkSync3(DAEMON_PATHS.PID_FILE);
|
|
9287
9388
|
} catch {}
|
|
9288
|
-
|
|
9389
|
+
writeFileSync10(DAEMON_PATHS.PID_FILE, String(process.pid), { mode: 384 });
|
|
9289
9390
|
return { result: "stale", pid: process.pid };
|
|
9290
9391
|
}
|
|
9291
|
-
|
|
9392
|
+
writeFileSync10(DAEMON_PATHS.PID_FILE, String(process.pid), { mode: 384 });
|
|
9292
9393
|
return { result: "acquired", pid: process.pid };
|
|
9293
9394
|
}
|
|
9294
9395
|
function releaseSingletonLock() {
|
|
9295
9396
|
try {
|
|
9296
|
-
const raw =
|
|
9397
|
+
const raw = readFileSync9(DAEMON_PATHS.PID_FILE, "utf8").trim();
|
|
9297
9398
|
if (Number.parseInt(raw, 10) === process.pid)
|
|
9298
9399
|
unlinkSync3(DAEMON_PATHS.PID_FILE);
|
|
9299
9400
|
} catch {}
|
|
9300
9401
|
}
|
|
9301
9402
|
function readRunningPid() {
|
|
9302
9403
|
try {
|
|
9303
|
-
const raw =
|
|
9404
|
+
const raw = readFileSync9(DAEMON_PATHS.PID_FILE, "utf8").trim();
|
|
9304
9405
|
const pid = Number.parseInt(raw, 10);
|
|
9305
9406
|
if (Number.isFinite(pid) && pid > 0 && isProcessAlive(pid))
|
|
9306
9407
|
return pid;
|
|
@@ -9990,7 +10091,7 @@ var init_session_registry = __esm(() => {
|
|
|
9990
10091
|
|
|
9991
10092
|
// src/daemon/ipc/server.ts
|
|
9992
10093
|
import { createServer as createServer2 } from "node:http";
|
|
9993
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
10094
|
+
import { chmodSync as chmodSync3, existsSync as existsSync11, unlinkSync as unlinkSync4 } from "node:fs";
|
|
9994
10095
|
import { timingSafeEqual } from "node:crypto";
|
|
9995
10096
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
9996
10097
|
function startIpcServer(opts) {
|
|
@@ -10006,7 +10107,7 @@ function startIpcServer(opts) {
|
|
|
10006
10107
|
meshConfigs: opts.meshConfigs,
|
|
10007
10108
|
onPendingInserted: opts.onPendingInserted
|
|
10008
10109
|
});
|
|
10009
|
-
if (
|
|
10110
|
+
if (existsSync11(DAEMON_PATHS.SOCK_FILE)) {
|
|
10010
10111
|
try {
|
|
10011
10112
|
unlinkSync4(DAEMON_PATHS.SOCK_FILE);
|
|
10012
10113
|
} catch {}
|
|
@@ -10833,16 +10934,16 @@ function parseSendRequest(body, idempotencyHeader) {
|
|
|
10833
10934
|
}
|
|
10834
10935
|
async function resolveAndEncrypt(req, broker, meshSecretKey, meshSlug) {
|
|
10835
10936
|
const { encryptDirect: encryptDirect2 } = await Promise.resolve().then(() => (init_box(), exports_box));
|
|
10836
|
-
const { randomBytes:
|
|
10937
|
+
const { randomBytes: randomBytes7 } = await import("node:crypto");
|
|
10837
10938
|
const to = req.to.trim();
|
|
10838
10939
|
if (to.startsWith("#") && /^#[0-9a-z_-]{20,}$/i.test(to)) {
|
|
10839
10940
|
const ciphertext = Buffer.from(req.message, "utf8").toString("base64");
|
|
10840
|
-
const nonce =
|
|
10941
|
+
const nonce = randomBytes7(24).toString("base64");
|
|
10841
10942
|
return { target_spec: to, ciphertext, nonce, mesh: meshSlug ?? "" };
|
|
10842
10943
|
}
|
|
10843
10944
|
if (to.startsWith("@") || to === "*") {
|
|
10844
10945
|
const ciphertext = Buffer.from(req.message, "utf8").toString("base64");
|
|
10845
|
-
const nonce =
|
|
10946
|
+
const nonce = randomBytes7(24).toString("base64");
|
|
10846
10947
|
return { target_spec: to, ciphertext, nonce, mesh: meshSlug ?? "" };
|
|
10847
10948
|
}
|
|
10848
10949
|
if (/^[0-9a-f]{64}$/i.test(to)) {
|
|
@@ -11863,8 +11964,8 @@ function bufferToHex(b) {
|
|
|
11863
11964
|
return s;
|
|
11864
11965
|
}
|
|
11865
11966
|
async function randomNonce2() {
|
|
11866
|
-
const { randomBytes:
|
|
11867
|
-
return
|
|
11967
|
+
const { randomBytes: randomBytes7 } = await import("node:crypto");
|
|
11968
|
+
return randomBytes7(24).toString("base64");
|
|
11868
11969
|
}
|
|
11869
11970
|
function defaultLog4(level, msg, meta) {
|
|
11870
11971
|
const line = JSON.stringify({ level, msg, ...meta, ts: new Date().toISOString() });
|
|
@@ -12039,13 +12140,13 @@ __export(exports_identity, {
|
|
|
12039
12140
|
__resetHostIdCacheForTests: () => __resetHostIdCacheForTests,
|
|
12040
12141
|
__computeV1FingerprintForTests: () => __computeV1FingerprintForTests
|
|
12041
12142
|
});
|
|
12042
|
-
import { existsSync as
|
|
12043
|
-
import { join as
|
|
12143
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "node:fs";
|
|
12144
|
+
import { join as join8 } from "node:path";
|
|
12044
12145
|
import { createHash as createHash2 } from "node:crypto";
|
|
12045
12146
|
import { execFileSync } from "node:child_process";
|
|
12046
12147
|
import { networkInterfaces } from "node:os";
|
|
12047
12148
|
function path() {
|
|
12048
|
-
return
|
|
12149
|
+
return join8(DAEMON_PATHS.DAEMON_DIR, FILE_NAME);
|
|
12049
12150
|
}
|
|
12050
12151
|
function computeCurrentFingerprint() {
|
|
12051
12152
|
const host_id = readHostIdV2() ?? "";
|
|
@@ -12060,13 +12161,13 @@ function computeCurrentFingerprint() {
|
|
|
12060
12161
|
}
|
|
12061
12162
|
function checkFingerprint() {
|
|
12062
12163
|
const current = computeCurrentFingerprint();
|
|
12063
|
-
if (!
|
|
12064
|
-
|
|
12164
|
+
if (!existsSync12(path())) {
|
|
12165
|
+
writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
|
|
12065
12166
|
return { result: "first_run", current };
|
|
12066
12167
|
}
|
|
12067
12168
|
let stored;
|
|
12068
12169
|
try {
|
|
12069
|
-
stored = JSON.parse(
|
|
12170
|
+
stored = JSON.parse(readFileSync10(path(), "utf8"));
|
|
12070
12171
|
} catch {
|
|
12071
12172
|
return { result: "unavailable", current };
|
|
12072
12173
|
}
|
|
@@ -12074,7 +12175,7 @@ function checkFingerprint() {
|
|
|
12074
12175
|
if (stored.fingerprint === current.fingerprint)
|
|
12075
12176
|
return { result: "match", current, stored };
|
|
12076
12177
|
if (stored.host_id && stored.host_id === current.host_id) {
|
|
12077
|
-
|
|
12178
|
+
writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
|
|
12078
12179
|
return { result: "match", current, stored };
|
|
12079
12180
|
}
|
|
12080
12181
|
return { result: "mismatch", current, stored };
|
|
@@ -12082,7 +12183,7 @@ function checkFingerprint() {
|
|
|
12082
12183
|
if (stored.schema_version === 1) {
|
|
12083
12184
|
const v1 = computeCurrentFingerprintV1();
|
|
12084
12185
|
if (stored.fingerprint === v1.fingerprint) {
|
|
12085
|
-
|
|
12186
|
+
writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
|
|
12086
12187
|
return { result: "match", current, stored };
|
|
12087
12188
|
}
|
|
12088
12189
|
return { result: "mismatch", current, stored };
|
|
@@ -12091,7 +12192,7 @@ function checkFingerprint() {
|
|
|
12091
12192
|
}
|
|
12092
12193
|
function acceptCurrentHost() {
|
|
12093
12194
|
const current = computeCurrentFingerprint();
|
|
12094
|
-
|
|
12195
|
+
writeFileSync11(path(), JSON.stringify(current, null, 2), { mode: 384 });
|
|
12095
12196
|
return current;
|
|
12096
12197
|
}
|
|
12097
12198
|
function fingerprintV2(host_id, stable_mac) {
|
|
@@ -12141,7 +12242,7 @@ function readHostIdV1() {
|
|
|
12141
12242
|
if (process.platform === "linux") {
|
|
12142
12243
|
for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
12143
12244
|
try {
|
|
12144
|
-
const raw =
|
|
12245
|
+
const raw = readFileSync10(p, "utf8").trim();
|
|
12145
12246
|
if (raw)
|
|
12146
12247
|
return `linux:${raw}`;
|
|
12147
12248
|
} catch {}
|
|
@@ -12187,7 +12288,7 @@ function readHostIdV2Uncached() {
|
|
|
12187
12288
|
if (process.platform === "linux") {
|
|
12188
12289
|
for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
12189
12290
|
try {
|
|
12190
|
-
const raw =
|
|
12291
|
+
const raw = readFileSync10(p, "utf8").trim();
|
|
12191
12292
|
if (raw)
|
|
12192
12293
|
return `linux:${raw}`;
|
|
12193
12294
|
} catch {}
|
|
@@ -12230,23 +12331,23 @@ var init_identity = __esm(() => {
|
|
|
12230
12331
|
});
|
|
12231
12332
|
|
|
12232
12333
|
// src/daemon/run.ts
|
|
12233
|
-
import { existsSync as
|
|
12334
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11 } from "node:fs";
|
|
12234
12335
|
function detectContainer() {
|
|
12235
12336
|
if (process.env.KUBERNETES_SERVICE_HOST)
|
|
12236
12337
|
return true;
|
|
12237
12338
|
if (process.env.CONTAINER === "1")
|
|
12238
12339
|
return true;
|
|
12239
12340
|
try {
|
|
12240
|
-
if (
|
|
12341
|
+
if (existsSync13("/.dockerenv"))
|
|
12241
12342
|
return true;
|
|
12242
|
-
const cg =
|
|
12343
|
+
const cg = readFileSync11("/proc/1/cgroup", "utf8");
|
|
12243
12344
|
if (/(docker|kubepods|containerd)/.test(cg))
|
|
12244
12345
|
return true;
|
|
12245
12346
|
} catch {}
|
|
12246
12347
|
return false;
|
|
12247
12348
|
}
|
|
12248
12349
|
async function runDaemon(opts = {}) {
|
|
12249
|
-
|
|
12350
|
+
mkdirSync7(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
|
|
12250
12351
|
const lock = acquireSingletonLock();
|
|
12251
12352
|
if (lock.result === "already-running") {
|
|
12252
12353
|
process.stderr.write(`daemon already running (pid ${lock.pid})
|
|
@@ -12389,6 +12490,17 @@ async function runDaemon(opts = {}) {
|
|
|
12389
12490
|
}
|
|
12390
12491
|
prior.close().catch(() => {});
|
|
12391
12492
|
}
|
|
12493
|
+
const priorByPubkey = sessionBrokersByPubkey.get(info.presence.sessionPubkey);
|
|
12494
|
+
if (priorByPubkey && priorByPubkey !== prior) {
|
|
12495
|
+
for (const [tok, c] of sessionBrokers) {
|
|
12496
|
+
if (c === priorByPubkey) {
|
|
12497
|
+
sessionBrokers.delete(tok);
|
|
12498
|
+
break;
|
|
12499
|
+
}
|
|
12500
|
+
}
|
|
12501
|
+
sessionBrokersByPubkey.delete(info.presence.sessionPubkey);
|
|
12502
|
+
priorByPubkey.close().catch(() => {});
|
|
12503
|
+
}
|
|
12392
12504
|
const sessionSecretKeyHex = info.presence.sessionSecretKey;
|
|
12393
12505
|
const sessionPubkeyHex = info.presence.sessionPubkey;
|
|
12394
12506
|
const client = new SessionBrokerClient({
|
|
@@ -12525,10 +12637,10 @@ __export(exports_service_install, {
|
|
|
12525
12637
|
installService: () => installService,
|
|
12526
12638
|
detectPlatform: () => detectPlatform
|
|
12527
12639
|
});
|
|
12528
|
-
import { existsSync as
|
|
12640
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, readFileSync as readFileSync12 } from "node:fs";
|
|
12529
12641
|
import { execSync as execSync2 } from "node:child_process";
|
|
12530
|
-
import { homedir as
|
|
12531
|
-
import { join as
|
|
12642
|
+
import { homedir as homedir8 } from "node:os";
|
|
12643
|
+
import { join as join9, dirname as dirname5 } from "node:path";
|
|
12532
12644
|
function detectPlatform() {
|
|
12533
12645
|
if (process.platform === "darwin")
|
|
12534
12646
|
return "darwin";
|
|
@@ -12546,10 +12658,10 @@ function installService(args) {
|
|
|
12546
12658
|
if (isCi() && !args.allowCi) {
|
|
12547
12659
|
throw new Error("Refusing to install persistent service in CI; pass --allow-ci-persistent to override.");
|
|
12548
12660
|
}
|
|
12549
|
-
if (!
|
|
12661
|
+
if (!existsSync14(args.binaryPath)) {
|
|
12550
12662
|
throw new Error(`binary not found at ${args.binaryPath}`);
|
|
12551
12663
|
}
|
|
12552
|
-
|
|
12664
|
+
mkdirSync8(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
|
|
12553
12665
|
if (platform5 === "darwin")
|
|
12554
12666
|
return installDarwin(args);
|
|
12555
12667
|
return installLinux(args);
|
|
@@ -12562,7 +12674,7 @@ function uninstallService() {
|
|
|
12562
12674
|
try {
|
|
12563
12675
|
execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
|
|
12564
12676
|
} catch {}
|
|
12565
|
-
if (
|
|
12677
|
+
if (existsSync14(p)) {
|
|
12566
12678
|
unlinkSync5(p);
|
|
12567
12679
|
removed.push(p);
|
|
12568
12680
|
}
|
|
@@ -12571,7 +12683,7 @@ function uninstallService() {
|
|
|
12571
12683
|
try {
|
|
12572
12684
|
execSync2(`systemctl --user disable --now ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
|
|
12573
12685
|
} catch {}
|
|
12574
|
-
if (
|
|
12686
|
+
if (existsSync14(p)) {
|
|
12575
12687
|
unlinkSync5(p);
|
|
12576
12688
|
removed.push(p);
|
|
12577
12689
|
}
|
|
@@ -12579,11 +12691,11 @@ function uninstallService() {
|
|
|
12579
12691
|
return { platform: platform5, removed };
|
|
12580
12692
|
}
|
|
12581
12693
|
function darwinPlistPath() {
|
|
12582
|
-
return
|
|
12694
|
+
return join9(homedir8(), "Library", "LaunchAgents", `${SERVICE_LABEL2}.plist`);
|
|
12583
12695
|
}
|
|
12584
12696
|
function installDarwin(args) {
|
|
12585
12697
|
const plist = darwinPlistPath();
|
|
12586
|
-
|
|
12698
|
+
mkdirSync8(dirname5(plist), { recursive: true });
|
|
12587
12699
|
const log2 = DAEMON_PATHS.LOG_FILE;
|
|
12588
12700
|
const nodeBin = process.execPath;
|
|
12589
12701
|
const meshArgs = [
|
|
@@ -12615,25 +12727,25 @@ function installDarwin(args) {
|
|
|
12615
12727
|
<key>StandardErrorPath</key>
|
|
12616
12728
|
<string>${escapeXml(log2)}</string>
|
|
12617
12729
|
<key>WorkingDirectory</key>
|
|
12618
|
-
<string>${escapeXml(
|
|
12730
|
+
<string>${escapeXml(homedir8())}</string>
|
|
12619
12731
|
<key>EnvironmentVariables</key>
|
|
12620
12732
|
<dict>
|
|
12621
12733
|
<key>HOME</key>
|
|
12622
|
-
<string>${escapeXml(
|
|
12734
|
+
<string>${escapeXml(homedir8())}</string>
|
|
12623
12735
|
<key>PATH</key>
|
|
12624
12736
|
<string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
12625
12737
|
</dict>
|
|
12626
12738
|
</dict>
|
|
12627
12739
|
</plist>
|
|
12628
12740
|
`;
|
|
12629
|
-
|
|
12741
|
+
writeFileSync12(plist, xml, { mode: 420 });
|
|
12630
12742
|
try {
|
|
12631
12743
|
execSync2(`launchctl bootout gui/$(id -u)/${SERVICE_LABEL2}`, { stdio: "ignore" });
|
|
12632
12744
|
} catch {}
|
|
12633
12745
|
try {
|
|
12634
12746
|
const pidPath = DAEMON_PATHS.PID_FILE;
|
|
12635
|
-
if (
|
|
12636
|
-
const pid = parseInt(
|
|
12747
|
+
if (existsSync14(pidPath)) {
|
|
12748
|
+
const pid = parseInt(readFileSync12(pidPath, "utf8").trim(), 10);
|
|
12637
12749
|
if (Number.isFinite(pid) && pid > 0) {
|
|
12638
12750
|
try {
|
|
12639
12751
|
process.kill(pid, "SIGTERM");
|
|
@@ -12648,11 +12760,11 @@ function installDarwin(args) {
|
|
|
12648
12760
|
};
|
|
12649
12761
|
}
|
|
12650
12762
|
function linuxUnitPath() {
|
|
12651
|
-
return
|
|
12763
|
+
return join9(homedir8(), ".config", "systemd", "user", SYSTEMD_UNIT2);
|
|
12652
12764
|
}
|
|
12653
12765
|
function installLinux(args) {
|
|
12654
12766
|
const unit = linuxUnitPath();
|
|
12655
|
-
|
|
12767
|
+
mkdirSync8(dirname5(unit), { recursive: true });
|
|
12656
12768
|
const nodeBin = process.execPath;
|
|
12657
12769
|
const execArgs = [
|
|
12658
12770
|
"daemon",
|
|
@@ -12678,14 +12790,14 @@ Environment=PATH=/usr/local/bin:/usr/bin:/bin
|
|
|
12678
12790
|
[Install]
|
|
12679
12791
|
WantedBy=default.target
|
|
12680
12792
|
`;
|
|
12681
|
-
|
|
12793
|
+
writeFileSync12(unit, content, { mode: 420 });
|
|
12682
12794
|
try {
|
|
12683
12795
|
execSync2(`systemctl --user stop ${SYSTEMD_UNIT2}`, { stdio: "ignore" });
|
|
12684
12796
|
} catch {}
|
|
12685
12797
|
try {
|
|
12686
12798
|
const pidPath = DAEMON_PATHS.PID_FILE;
|
|
12687
|
-
if (
|
|
12688
|
-
const pid = parseInt(
|
|
12799
|
+
if (existsSync14(pidPath)) {
|
|
12800
|
+
const pid = parseInt(readFileSync12(pidPath, "utf8").trim(), 10);
|
|
12689
12801
|
if (Number.isFinite(pid) && pid > 0) {
|
|
12690
12802
|
try {
|
|
12691
12803
|
process.kill(pid, "SIGTERM");
|
|
@@ -12712,10 +12824,10 @@ function readInstalledUnit() {
|
|
|
12712
12824
|
if (!platform5)
|
|
12713
12825
|
return { platform: null, path: null, content: null };
|
|
12714
12826
|
const path2 = platform5 === "darwin" ? darwinPlistPath() : linuxUnitPath();
|
|
12715
|
-
if (!
|
|
12827
|
+
if (!existsSync14(path2))
|
|
12716
12828
|
return { platform: platform5, path: null, content: null };
|
|
12717
12829
|
try {
|
|
12718
|
-
return { platform: platform5, path: path2, content:
|
|
12830
|
+
return { platform: platform5, path: path2, content: readFileSync12(path2, "utf8") };
|
|
12719
12831
|
} catch {
|
|
12720
12832
|
return { platform: platform5, path: path2, content: null };
|
|
12721
12833
|
}
|
|
@@ -12731,8 +12843,8 @@ __export(exports_daemon, {
|
|
|
12731
12843
|
runDaemonCommand: () => runDaemonCommand
|
|
12732
12844
|
});
|
|
12733
12845
|
import { spawn } from "node:child_process";
|
|
12734
|
-
import { existsSync as
|
|
12735
|
-
import { join as
|
|
12846
|
+
import { existsSync as existsSync15, openSync as openSync3, mkdirSync as mkdirSync9 } from "node:fs";
|
|
12847
|
+
import { join as join10 } from "node:path";
|
|
12736
12848
|
async function runDaemonCommand(sub, opts, rest = []) {
|
|
12737
12849
|
switch (sub) {
|
|
12738
12850
|
case undefined:
|
|
@@ -13054,8 +13166,8 @@ async function runStop(opts) {
|
|
|
13054
13166
|
return 1;
|
|
13055
13167
|
}
|
|
13056
13168
|
async function spawnDetachedDaemon(opts) {
|
|
13057
|
-
|
|
13058
|
-
const logPath =
|
|
13169
|
+
mkdirSync9(DAEMON_PATHS.DAEMON_DIR, { recursive: true, mode: 448 });
|
|
13170
|
+
const logPath = join10(DAEMON_PATHS.DAEMON_DIR, "daemon.log");
|
|
13059
13171
|
const binary = process.argv[1] ?? "claudemesh";
|
|
13060
13172
|
const args = ["daemon", "up", "--foreground"];
|
|
13061
13173
|
if (opts.noTcp)
|
|
@@ -13073,7 +13185,7 @@ async function spawnDetachedDaemon(opts) {
|
|
|
13073
13185
|
const sockPath = DAEMON_PATHS.SOCK_FILE;
|
|
13074
13186
|
const startedAt = Date.now();
|
|
13075
13187
|
while (Date.now() - startedAt < 3000) {
|
|
13076
|
-
if (
|
|
13188
|
+
if (existsSync15(sockPath)) {
|
|
13077
13189
|
if (opts.json) {
|
|
13078
13190
|
process.stdout.write(JSON.stringify({ ok: true, detached: true, pid: child.pid, log: logPath }) + `
|
|
13079
13191
|
`);
|
|
@@ -13118,19 +13230,19 @@ __export(exports_install, {
|
|
|
13118
13230
|
import {
|
|
13119
13231
|
chmodSync as chmodSync4,
|
|
13120
13232
|
copyFileSync,
|
|
13121
|
-
existsSync as
|
|
13122
|
-
mkdirSync as
|
|
13123
|
-
readFileSync as
|
|
13124
|
-
writeFileSync as
|
|
13233
|
+
existsSync as existsSync16,
|
|
13234
|
+
mkdirSync as mkdirSync10,
|
|
13235
|
+
readFileSync as readFileSync13,
|
|
13236
|
+
writeFileSync as writeFileSync13
|
|
13125
13237
|
} from "node:fs";
|
|
13126
|
-
import { homedir as
|
|
13127
|
-
import { dirname as dirname6, join as
|
|
13238
|
+
import { homedir as homedir9, platform as platform5 } from "node:os";
|
|
13239
|
+
import { dirname as dirname6, join as join11, resolve } from "node:path";
|
|
13128
13240
|
import { fileURLToPath } from "node:url";
|
|
13129
13241
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
13130
13242
|
function readClaudeConfig() {
|
|
13131
|
-
if (!
|
|
13243
|
+
if (!existsSync16(CLAUDE_CONFIG))
|
|
13132
13244
|
return {};
|
|
13133
|
-
const text =
|
|
13245
|
+
const text = readFileSync13(CLAUDE_CONFIG, "utf-8").trim();
|
|
13134
13246
|
if (!text)
|
|
13135
13247
|
return {};
|
|
13136
13248
|
try {
|
|
@@ -13140,12 +13252,12 @@ function readClaudeConfig() {
|
|
|
13140
13252
|
}
|
|
13141
13253
|
}
|
|
13142
13254
|
function backupClaudeConfig() {
|
|
13143
|
-
if (!
|
|
13255
|
+
if (!existsSync16(CLAUDE_CONFIG))
|
|
13144
13256
|
return;
|
|
13145
|
-
const backupDir =
|
|
13146
|
-
|
|
13257
|
+
const backupDir = join11(dirname6(CLAUDE_CONFIG), ".claude", "backups");
|
|
13258
|
+
mkdirSync10(backupDir, { recursive: true });
|
|
13147
13259
|
const ts = Date.now();
|
|
13148
|
-
const dest =
|
|
13260
|
+
const dest = join11(backupDir, `.claude.json.pre-claudemesh.${ts}`);
|
|
13149
13261
|
copyFileSync(CLAUDE_CONFIG, dest);
|
|
13150
13262
|
}
|
|
13151
13263
|
function patchMcpServer(entry) {
|
|
@@ -13169,7 +13281,7 @@ function patchMcpServer(entry) {
|
|
|
13169
13281
|
return action;
|
|
13170
13282
|
}
|
|
13171
13283
|
function removeMcpServer() {
|
|
13172
|
-
if (!
|
|
13284
|
+
if (!existsSync16(CLAUDE_CONFIG))
|
|
13173
13285
|
return false;
|
|
13174
13286
|
backupClaudeConfig();
|
|
13175
13287
|
const cfg = readClaudeConfig();
|
|
@@ -13182,8 +13294,8 @@ function removeMcpServer() {
|
|
|
13182
13294
|
return true;
|
|
13183
13295
|
}
|
|
13184
13296
|
function flushClaudeConfig(obj) {
|
|
13185
|
-
|
|
13186
|
-
|
|
13297
|
+
mkdirSync10(dirname6(CLAUDE_CONFIG), { recursive: true });
|
|
13298
|
+
writeFileSync13(CLAUDE_CONFIG, JSON.stringify(obj, null, 2) + `
|
|
13187
13299
|
`, "utf-8");
|
|
13188
13300
|
try {
|
|
13189
13301
|
chmodSync4(CLAUDE_CONFIG, 384);
|
|
@@ -13205,8 +13317,8 @@ function resolveEntry() {
|
|
|
13205
13317
|
function resolveBundledSkillsDir() {
|
|
13206
13318
|
const here = fileURLToPath(import.meta.url);
|
|
13207
13319
|
const pkgRoot = resolve(dirname6(here), "..", "..");
|
|
13208
|
-
const skillsDir =
|
|
13209
|
-
if (
|
|
13320
|
+
const skillsDir = join11(pkgRoot, "skills");
|
|
13321
|
+
if (existsSync16(skillsDir))
|
|
13210
13322
|
return skillsDir;
|
|
13211
13323
|
return null;
|
|
13212
13324
|
}
|
|
@@ -13219,13 +13331,13 @@ function installSkills() {
|
|
|
13219
13331
|
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
13220
13332
|
if (!entry.isDirectory())
|
|
13221
13333
|
continue;
|
|
13222
|
-
const srcDir =
|
|
13223
|
-
const dstDir =
|
|
13224
|
-
|
|
13334
|
+
const srcDir = join11(src, entry.name);
|
|
13335
|
+
const dstDir = join11(CLAUDE_SKILLS_ROOT, entry.name);
|
|
13336
|
+
mkdirSync10(dstDir, { recursive: true });
|
|
13225
13337
|
for (const file of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
13226
13338
|
if (!file.isFile())
|
|
13227
13339
|
continue;
|
|
13228
|
-
copyFileSync(
|
|
13340
|
+
copyFileSync(join11(srcDir, file.name), join11(dstDir, file.name));
|
|
13229
13341
|
}
|
|
13230
13342
|
installed.push(entry.name);
|
|
13231
13343
|
}
|
|
@@ -13240,8 +13352,8 @@ function uninstallSkills() {
|
|
|
13240
13352
|
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
13241
13353
|
if (!entry.isDirectory())
|
|
13242
13354
|
continue;
|
|
13243
|
-
const dstDir =
|
|
13244
|
-
if (
|
|
13355
|
+
const dstDir = join11(CLAUDE_SKILLS_ROOT, entry.name);
|
|
13356
|
+
if (existsSync16(dstDir)) {
|
|
13245
13357
|
try {
|
|
13246
13358
|
fs.rmSync(dstDir, { recursive: true, force: true });
|
|
13247
13359
|
removed.push(entry.name);
|
|
@@ -13266,9 +13378,9 @@ function entriesEqual(a, b) {
|
|
|
13266
13378
|
return a.command === b.command && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
|
|
13267
13379
|
}
|
|
13268
13380
|
function readClaudeSettings() {
|
|
13269
|
-
if (!
|
|
13381
|
+
if (!existsSync16(CLAUDE_SETTINGS))
|
|
13270
13382
|
return {};
|
|
13271
|
-
const text =
|
|
13383
|
+
const text = readFileSync13(CLAUDE_SETTINGS, "utf-8").trim();
|
|
13272
13384
|
if (!text)
|
|
13273
13385
|
return {};
|
|
13274
13386
|
try {
|
|
@@ -13278,8 +13390,8 @@ function readClaudeSettings() {
|
|
|
13278
13390
|
}
|
|
13279
13391
|
}
|
|
13280
13392
|
function writeClaudeSettings(obj) {
|
|
13281
|
-
|
|
13282
|
-
|
|
13393
|
+
mkdirSync10(dirname6(CLAUDE_SETTINGS), { recursive: true });
|
|
13394
|
+
writeFileSync13(CLAUDE_SETTINGS, JSON.stringify(obj, null, 2) + `
|
|
13283
13395
|
`, "utf-8");
|
|
13284
13396
|
}
|
|
13285
13397
|
function installAllowedTools() {
|
|
@@ -13293,7 +13405,7 @@ function installAllowedTools() {
|
|
|
13293
13405
|
return { added: toAdd, unchanged: CLAUDEMESH_TOOLS.length - toAdd.length };
|
|
13294
13406
|
}
|
|
13295
13407
|
function uninstallAllowedTools() {
|
|
13296
|
-
if (!
|
|
13408
|
+
if (!existsSync16(CLAUDE_SETTINGS))
|
|
13297
13409
|
return 0;
|
|
13298
13410
|
const settings = readClaudeSettings();
|
|
13299
13411
|
const existing = settings.allowedTools ?? [];
|
|
@@ -13328,7 +13440,7 @@ function installHooks() {
|
|
|
13328
13440
|
return { added, unchanged };
|
|
13329
13441
|
}
|
|
13330
13442
|
function uninstallHooks() {
|
|
13331
|
-
if (!
|
|
13443
|
+
if (!existsSync16(CLAUDE_SETTINGS))
|
|
13332
13444
|
return 0;
|
|
13333
13445
|
const settings = readClaudeSettings();
|
|
13334
13446
|
const hooks2 = settings.hooks;
|
|
@@ -13378,7 +13490,7 @@ async function runInstall(args = []) {
|
|
|
13378
13490
|
render.err("`bun` is not on PATH.", "Install Bun first: https://bun.com");
|
|
13379
13491
|
process.exit(1);
|
|
13380
13492
|
}
|
|
13381
|
-
if (!
|
|
13493
|
+
if (!existsSync16(entry)) {
|
|
13382
13494
|
render.err(`MCP entry not found at ${entry}`);
|
|
13383
13495
|
process.exit(1);
|
|
13384
13496
|
}
|
|
@@ -13429,7 +13541,7 @@ async function runInstall(args = []) {
|
|
|
13429
13541
|
const installed = installSkills();
|
|
13430
13542
|
if (installed.length > 0) {
|
|
13431
13543
|
render.ok(`Claude skill${installed.length === 1 ? "" : "s"} installed`, installed.join(", "));
|
|
13432
|
-
render.info(dim(` ${
|
|
13544
|
+
render.info(dim(` ${join11(CLAUDE_SKILLS_ROOT, installed[0])}/SKILL.md`));
|
|
13433
13545
|
}
|
|
13434
13546
|
} catch (e) {
|
|
13435
13547
|
render.warn(`skill install failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -13592,9 +13704,9 @@ var init_install = __esm(() => {
|
|
|
13592
13704
|
init_facade();
|
|
13593
13705
|
init_render();
|
|
13594
13706
|
init_styles();
|
|
13595
|
-
CLAUDE_CONFIG =
|
|
13596
|
-
CLAUDE_SETTINGS =
|
|
13597
|
-
CLAUDE_SKILLS_ROOT =
|
|
13707
|
+
CLAUDE_CONFIG = join11(homedir9(), ".claude.json");
|
|
13708
|
+
CLAUDE_SETTINGS = join11(homedir9(), ".claude", "settings.json");
|
|
13709
|
+
CLAUDE_SKILLS_ROOT = join11(homedir9(), ".claude", "skills");
|
|
13598
13710
|
CLAUDEMESH_TOOLS = [
|
|
13599
13711
|
"mcp__claudemesh__cancel_scheduled",
|
|
13600
13712
|
"mcp__claudemesh__check_messages",
|
|
@@ -13649,35 +13761,35 @@ var exports_uninstall = {};
|
|
|
13649
13761
|
__export(exports_uninstall, {
|
|
13650
13762
|
uninstall: () => uninstall
|
|
13651
13763
|
});
|
|
13652
|
-
import { readFileSync as
|
|
13653
|
-
import { join as
|
|
13654
|
-
import { homedir as
|
|
13764
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync14, existsSync as existsSync17, rmSync as rmSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
13765
|
+
import { join as join12, dirname as dirname7 } from "node:path";
|
|
13766
|
+
import { homedir as homedir10 } from "node:os";
|
|
13655
13767
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
13656
13768
|
function bundledSkillsDir() {
|
|
13657
13769
|
const here = fileURLToPath2(import.meta.url);
|
|
13658
|
-
const pkgRoot =
|
|
13659
|
-
const skillsDir =
|
|
13660
|
-
return
|
|
13770
|
+
const pkgRoot = join12(dirname7(here), "..", "..");
|
|
13771
|
+
const skillsDir = join12(pkgRoot, "skills");
|
|
13772
|
+
return existsSync17(skillsDir) ? skillsDir : null;
|
|
13661
13773
|
}
|
|
13662
13774
|
async function uninstall() {
|
|
13663
13775
|
let removed = 0;
|
|
13664
|
-
if (
|
|
13776
|
+
if (existsSync17(PATHS.CLAUDE_JSON)) {
|
|
13665
13777
|
try {
|
|
13666
|
-
const raw =
|
|
13778
|
+
const raw = readFileSync14(PATHS.CLAUDE_JSON, "utf-8");
|
|
13667
13779
|
const config = JSON.parse(raw);
|
|
13668
13780
|
const servers = config.mcpServers;
|
|
13669
13781
|
if (servers && "claudemesh" in servers) {
|
|
13670
13782
|
delete servers.claudemesh;
|
|
13671
|
-
|
|
13783
|
+
writeFileSync14(PATHS.CLAUDE_JSON, JSON.stringify(config, null, 2) + `
|
|
13672
13784
|
`, "utf-8");
|
|
13673
13785
|
render.ok("removed MCP server", dim("~/.claude.json"));
|
|
13674
13786
|
removed++;
|
|
13675
13787
|
}
|
|
13676
13788
|
} catch {}
|
|
13677
13789
|
}
|
|
13678
|
-
if (
|
|
13790
|
+
if (existsSync17(PATHS.CLAUDE_SETTINGS)) {
|
|
13679
13791
|
try {
|
|
13680
|
-
const raw =
|
|
13792
|
+
const raw = readFileSync14(PATHS.CLAUDE_SETTINGS, "utf-8");
|
|
13681
13793
|
const config = JSON.parse(raw);
|
|
13682
13794
|
const hooks2 = config.hooks;
|
|
13683
13795
|
if (hooks2) {
|
|
@@ -13698,7 +13810,7 @@ async function uninstall() {
|
|
|
13698
13810
|
}
|
|
13699
13811
|
}
|
|
13700
13812
|
if (removedHooks > 0) {
|
|
13701
|
-
|
|
13813
|
+
writeFileSync14(PATHS.CLAUDE_SETTINGS, JSON.stringify(config, null, 2) + `
|
|
13702
13814
|
`, "utf-8");
|
|
13703
13815
|
render.ok(`removed ${removedHooks} claudemesh hook${removedHooks === 1 ? "" : "s"}`, dim("settings.json"));
|
|
13704
13816
|
removed++;
|
|
@@ -13713,10 +13825,10 @@ async function uninstall() {
|
|
|
13713
13825
|
for (const entry of readdirSync2(src, { withFileTypes: true })) {
|
|
13714
13826
|
if (!entry.isDirectory())
|
|
13715
13827
|
continue;
|
|
13716
|
-
const dst =
|
|
13717
|
-
if (
|
|
13828
|
+
const dst = join12(CLAUDE_SKILLS_ROOT2, entry.name);
|
|
13829
|
+
if (existsSync17(dst)) {
|
|
13718
13830
|
try {
|
|
13719
|
-
|
|
13831
|
+
rmSync3(dst, { recursive: true, force: true });
|
|
13720
13832
|
removedSkills.push(entry.name);
|
|
13721
13833
|
} catch {}
|
|
13722
13834
|
}
|
|
@@ -13738,7 +13850,7 @@ var init_uninstall = __esm(() => {
|
|
|
13738
13850
|
init_render();
|
|
13739
13851
|
init_styles();
|
|
13740
13852
|
init_exit_codes();
|
|
13741
|
-
CLAUDE_SKILLS_ROOT2 =
|
|
13853
|
+
CLAUDE_SKILLS_ROOT2 = join12(homedir10(), ".claude", "skills");
|
|
13742
13854
|
});
|
|
13743
13855
|
|
|
13744
13856
|
// src/commands/doctor.ts
|
|
@@ -13746,9 +13858,9 @@ var exports_doctor = {};
|
|
|
13746
13858
|
__export(exports_doctor, {
|
|
13747
13859
|
runDoctor: () => runDoctor
|
|
13748
13860
|
});
|
|
13749
|
-
import { existsSync as
|
|
13750
|
-
import { homedir as
|
|
13751
|
-
import { join as
|
|
13861
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
|
|
13862
|
+
import { homedir as homedir11, platform as platform6 } from "node:os";
|
|
13863
|
+
import { join as join13 } from "node:path";
|
|
13752
13864
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
13753
13865
|
function checkNode() {
|
|
13754
13866
|
const major = Number(process.versions.node.split(".")[0]);
|
|
@@ -13772,8 +13884,8 @@ function checkClaudeOnPath() {
|
|
|
13772
13884
|
};
|
|
13773
13885
|
}
|
|
13774
13886
|
function checkMcpRegistered() {
|
|
13775
|
-
const claudeConfig =
|
|
13776
|
-
if (!
|
|
13887
|
+
const claudeConfig = join13(homedir11(), ".claude.json");
|
|
13888
|
+
if (!existsSync18(claudeConfig)) {
|
|
13777
13889
|
return {
|
|
13778
13890
|
name: "claudemesh MCP registered in ~/.claude.json",
|
|
13779
13891
|
pass: false,
|
|
@@ -13781,7 +13893,7 @@ function checkMcpRegistered() {
|
|
|
13781
13893
|
};
|
|
13782
13894
|
}
|
|
13783
13895
|
try {
|
|
13784
|
-
const cfg = JSON.parse(
|
|
13896
|
+
const cfg = JSON.parse(readFileSync15(claudeConfig, "utf-8"));
|
|
13785
13897
|
const registered = Boolean(cfg.mcpServers?.["claudemesh"]);
|
|
13786
13898
|
return {
|
|
13787
13899
|
name: "claudemesh MCP registered in ~/.claude.json",
|
|
@@ -13798,8 +13910,8 @@ function checkMcpRegistered() {
|
|
|
13798
13910
|
}
|
|
13799
13911
|
}
|
|
13800
13912
|
function checkHooksRegistered() {
|
|
13801
|
-
const settings =
|
|
13802
|
-
if (!
|
|
13913
|
+
const settings = join13(homedir11(), ".claude", "settings.json");
|
|
13914
|
+
if (!existsSync18(settings)) {
|
|
13803
13915
|
return {
|
|
13804
13916
|
name: "Status hooks registered in ~/.claude/settings.json",
|
|
13805
13917
|
pass: false,
|
|
@@ -13807,7 +13919,7 @@ function checkHooksRegistered() {
|
|
|
13807
13919
|
};
|
|
13808
13920
|
}
|
|
13809
13921
|
try {
|
|
13810
|
-
const raw =
|
|
13922
|
+
const raw = readFileSync15(settings, "utf-8");
|
|
13811
13923
|
const has = raw.includes("claudemesh hook ");
|
|
13812
13924
|
return {
|
|
13813
13925
|
name: "Status hooks registered in ~/.claude/settings.json",
|
|
@@ -13824,7 +13936,7 @@ function checkHooksRegistered() {
|
|
|
13824
13936
|
}
|
|
13825
13937
|
function checkConfigFile() {
|
|
13826
13938
|
const path2 = getConfigPath();
|
|
13827
|
-
if (!
|
|
13939
|
+
if (!existsSync18(path2)) {
|
|
13828
13940
|
return {
|
|
13829
13941
|
name: "~/.claudemesh/config.json exists and parses",
|
|
13830
13942
|
pass: true,
|
|
@@ -14007,7 +14119,7 @@ var exports_status = {};
|
|
|
14007
14119
|
__export(exports_status, {
|
|
14008
14120
|
runStatus: () => runStatus2
|
|
14009
14121
|
});
|
|
14010
|
-
import { statSync as statSync4, existsSync as
|
|
14122
|
+
import { statSync as statSync4, existsSync as existsSync19 } from "node:fs";
|
|
14011
14123
|
import WebSocket3 from "ws";
|
|
14012
14124
|
async function probeBroker(url, timeoutMs = 4000) {
|
|
14013
14125
|
return new Promise((resolve2) => {
|
|
@@ -14037,7 +14149,7 @@ async function runStatus2() {
|
|
|
14037
14149
|
render.section(`status (v${VERSION})`);
|
|
14038
14150
|
const configPath = getConfigPath();
|
|
14039
14151
|
let configPermsNote = "missing";
|
|
14040
|
-
if (
|
|
14152
|
+
if (existsSync19(configPath)) {
|
|
14041
14153
|
const mode = (statSync4(configPath).mode & 511).toString(8).padStart(4, "0");
|
|
14042
14154
|
configPermsNote = mode === "0600" ? `${mode}` : `${mode} — expected 0600`;
|
|
14043
14155
|
}
|
|
@@ -14183,13 +14295,13 @@ var init_check_claude_binary = __esm(() => {
|
|
|
14183
14295
|
});
|
|
14184
14296
|
|
|
14185
14297
|
// src/services/health/check-mcp-registered.ts
|
|
14186
|
-
import { existsSync as
|
|
14298
|
+
import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
|
|
14187
14299
|
function checkMcpRegistered2() {
|
|
14188
14300
|
try {
|
|
14189
|
-
if (!
|
|
14301
|
+
if (!existsSync20(PATHS.CLAUDE_JSON)) {
|
|
14190
14302
|
return { name: "mcp-registered", ok: false, message: "~/.claude.json not found" };
|
|
14191
14303
|
}
|
|
14192
|
-
const raw =
|
|
14304
|
+
const raw = readFileSync16(PATHS.CLAUDE_JSON, "utf-8");
|
|
14193
14305
|
const config = JSON.parse(raw);
|
|
14194
14306
|
if (config.mcpServers && "claudemesh" in config.mcpServers) {
|
|
14195
14307
|
return { name: "mcp-registered", ok: true, message: "MCP server registered" };
|
|
@@ -14204,13 +14316,13 @@ var init_check_mcp_registered = __esm(() => {
|
|
|
14204
14316
|
});
|
|
14205
14317
|
|
|
14206
14318
|
// src/services/health/check-hooks-registered.ts
|
|
14207
|
-
import { existsSync as
|
|
14319
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17 } from "node:fs";
|
|
14208
14320
|
function checkHooksRegistered2() {
|
|
14209
14321
|
try {
|
|
14210
|
-
if (!
|
|
14322
|
+
if (!existsSync21(PATHS.CLAUDE_SETTINGS)) {
|
|
14211
14323
|
return { name: "hooks-registered", ok: false, message: "~/.claude/settings.json not found" };
|
|
14212
14324
|
}
|
|
14213
|
-
const raw =
|
|
14325
|
+
const raw = readFileSync17(PATHS.CLAUDE_SETTINGS, "utf-8");
|
|
14214
14326
|
const config = JSON.parse(raw);
|
|
14215
14327
|
if (config.hooks) {
|
|
14216
14328
|
return { name: "hooks-registered", ok: true, message: "Hooks configured" };
|
|
@@ -14225,10 +14337,10 @@ var init_check_hooks_registered = __esm(() => {
|
|
|
14225
14337
|
});
|
|
14226
14338
|
|
|
14227
14339
|
// src/services/health/check-config-perms.ts
|
|
14228
|
-
import { existsSync as
|
|
14340
|
+
import { existsSync as existsSync22, statSync as statSync5 } from "node:fs";
|
|
14229
14341
|
function checkConfigPerms() {
|
|
14230
14342
|
const configFile = PATHS.CONFIG_FILE;
|
|
14231
|
-
if (!
|
|
14343
|
+
if (!existsSync22(configFile)) {
|
|
14232
14344
|
return { name: "config-perms", ok: true, message: "No config file yet (first run)" };
|
|
14233
14345
|
}
|
|
14234
14346
|
try {
|
|
@@ -14246,13 +14358,13 @@ var init_check_config_perms = __esm(() => {
|
|
|
14246
14358
|
});
|
|
14247
14359
|
|
|
14248
14360
|
// src/services/health/check-keypairs-valid.ts
|
|
14249
|
-
import { existsSync as
|
|
14361
|
+
import { existsSync as existsSync23, readFileSync as readFileSync18 } from "node:fs";
|
|
14250
14362
|
function checkKeypairsValid() {
|
|
14251
|
-
if (!
|
|
14363
|
+
if (!existsSync23(PATHS.CONFIG_FILE)) {
|
|
14252
14364
|
return { name: "keypairs-valid", ok: true, message: "No config (first run)" };
|
|
14253
14365
|
}
|
|
14254
14366
|
try {
|
|
14255
|
-
const raw =
|
|
14367
|
+
const raw = readFileSync18(PATHS.CONFIG_FILE, "utf-8");
|
|
14256
14368
|
const config = JSON.parse(raw);
|
|
14257
14369
|
const meshes = config.meshes ?? [];
|
|
14258
14370
|
if (meshes.length === 0) {
|
|
@@ -14732,19 +14844,19 @@ var exports_url_handler = {};
|
|
|
14732
14844
|
__export(exports_url_handler, {
|
|
14733
14845
|
runUrlHandler: () => runUrlHandler
|
|
14734
14846
|
});
|
|
14735
|
-
import { platform as platform7, homedir as
|
|
14736
|
-
import { existsSync as
|
|
14737
|
-
import { join as
|
|
14847
|
+
import { platform as platform7, homedir as homedir12 } from "node:os";
|
|
14848
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync11, writeFileSync as writeFileSync15, rmSync as rmSync4, chmodSync as chmodSync5 } from "node:fs";
|
|
14849
|
+
import { join as join14 } from "node:path";
|
|
14738
14850
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
14739
14851
|
function resolveClaudemeshBin() {
|
|
14740
14852
|
return process.argv[1] ?? "claudemesh";
|
|
14741
14853
|
}
|
|
14742
14854
|
function installDarwin2() {
|
|
14743
14855
|
const binPath = resolveClaudemeshBin();
|
|
14744
|
-
const appDir =
|
|
14745
|
-
const contents =
|
|
14746
|
-
const macOS =
|
|
14747
|
-
|
|
14856
|
+
const appDir = join14(homedir12(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
|
|
14857
|
+
const contents = join14(appDir, "Contents");
|
|
14858
|
+
const macOS = join14(contents, "MacOS");
|
|
14859
|
+
mkdirSync11(macOS, { recursive: true });
|
|
14748
14860
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
14749
14861
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
14750
14862
|
<plist version="1.0">
|
|
@@ -14767,7 +14879,7 @@ function installDarwin2() {
|
|
|
14767
14879
|
</array>
|
|
14768
14880
|
</dict>
|
|
14769
14881
|
</plist>`;
|
|
14770
|
-
|
|
14882
|
+
writeFileSync15(join14(contents, "Info.plist"), plist);
|
|
14771
14883
|
const shim = `#!/bin/sh
|
|
14772
14884
|
URL="$1"
|
|
14773
14885
|
CODE=\${URL#claudemesh://}
|
|
@@ -14781,8 +14893,8 @@ tell application "Terminal"
|
|
|
14781
14893
|
end tell
|
|
14782
14894
|
EOF
|
|
14783
14895
|
`;
|
|
14784
|
-
const shimPath =
|
|
14785
|
-
|
|
14896
|
+
const shimPath = join14(macOS, "open-url");
|
|
14897
|
+
writeFileSync15(shimPath, shim);
|
|
14786
14898
|
chmodSync5(shimPath, 493);
|
|
14787
14899
|
const lsreg = spawnSync5("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister", ["-f", appDir], { encoding: "utf-8" });
|
|
14788
14900
|
if (lsreg.status !== 0) {
|
|
@@ -14793,8 +14905,8 @@ EOF
|
|
|
14793
14905
|
}
|
|
14794
14906
|
function installLinux2() {
|
|
14795
14907
|
const binPath = resolveClaudemeshBin();
|
|
14796
|
-
const appsDir =
|
|
14797
|
-
|
|
14908
|
+
const appsDir = join14(homedir12(), ".local", "share", "applications");
|
|
14909
|
+
mkdirSync11(appsDir, { recursive: true });
|
|
14798
14910
|
const desktop = `[Desktop Entry]
|
|
14799
14911
|
Type=Application
|
|
14800
14912
|
Name=Claudemesh
|
|
@@ -14805,8 +14917,8 @@ Terminal=true
|
|
|
14805
14917
|
MimeType=x-scheme-handler/claudemesh;
|
|
14806
14918
|
NoDisplay=true
|
|
14807
14919
|
`;
|
|
14808
|
-
const desktopPath =
|
|
14809
|
-
|
|
14920
|
+
const desktopPath = join14(appsDir, "claudemesh.desktop");
|
|
14921
|
+
writeFileSync15(desktopPath, desktop);
|
|
14810
14922
|
const xdg1 = spawnSync5("xdg-mime", ["default", "claudemesh.desktop", "x-scheme-handler/claudemesh"], { encoding: "utf-8" });
|
|
14811
14923
|
if (xdg1.status !== 0) {
|
|
14812
14924
|
render.warn("xdg-mime not available — skipped mime default registration");
|
|
@@ -14828,8 +14940,8 @@ function installWindows() {
|
|
|
14828
14940
|
`[HKEY_CURRENT_USER\\Software\\Classes\\claudemesh\\shell\\open\\command]`,
|
|
14829
14941
|
`@="\\"${binPath.replace(/\\/g, "\\\\")}\\" \\"%1\\""`
|
|
14830
14942
|
];
|
|
14831
|
-
const regPath =
|
|
14832
|
-
|
|
14943
|
+
const regPath = join14(homedir12(), "claudemesh-handler.reg");
|
|
14944
|
+
writeFileSync15(regPath, lines.join(`\r
|
|
14833
14945
|
`));
|
|
14834
14946
|
const res = spawnSync5("reg.exe", ["import", regPath], { encoding: "utf-8" });
|
|
14835
14947
|
if (res.status !== 0) {
|
|
@@ -14840,16 +14952,16 @@ function installWindows() {
|
|
|
14840
14952
|
return EXIT.SUCCESS;
|
|
14841
14953
|
}
|
|
14842
14954
|
function uninstallDarwin() {
|
|
14843
|
-
const appDir =
|
|
14844
|
-
if (
|
|
14845
|
-
|
|
14955
|
+
const appDir = join14(homedir12(), "Library", "Application Support", "claudemesh", "ClaudemeshHandler.app");
|
|
14956
|
+
if (existsSync24(appDir))
|
|
14957
|
+
rmSync4(appDir, { recursive: true, force: true });
|
|
14846
14958
|
render.ok("removed claudemesh:// handler on macOS");
|
|
14847
14959
|
return EXIT.SUCCESS;
|
|
14848
14960
|
}
|
|
14849
14961
|
function uninstallLinux() {
|
|
14850
|
-
const desktopPath =
|
|
14851
|
-
if (
|
|
14852
|
-
|
|
14962
|
+
const desktopPath = join14(homedir12(), ".local", "share", "applications", "claudemesh.desktop");
|
|
14963
|
+
if (existsSync24(desktopPath))
|
|
14964
|
+
rmSync4(desktopPath, { force: true });
|
|
14853
14965
|
render.ok("removed claudemesh:// handler on Linux");
|
|
14854
14966
|
return EXIT.SUCCESS;
|
|
14855
14967
|
}
|
|
@@ -14893,9 +15005,9 @@ var exports_status_line = {};
|
|
|
14893
15005
|
__export(exports_status_line, {
|
|
14894
15006
|
runStatusLine: () => runStatusLine
|
|
14895
15007
|
});
|
|
14896
|
-
import { existsSync as
|
|
14897
|
-
import { join as
|
|
14898
|
-
import { homedir as
|
|
15008
|
+
import { existsSync as existsSync25, readFileSync as readFileSync19 } from "node:fs";
|
|
15009
|
+
import { join as join15 } from "node:path";
|
|
15010
|
+
import { homedir as homedir13 } from "node:os";
|
|
14899
15011
|
async function runStatusLine() {
|
|
14900
15012
|
try {
|
|
14901
15013
|
const config = readConfig();
|
|
@@ -14903,11 +15015,11 @@ async function runStatusLine() {
|
|
|
14903
15015
|
process.stdout.write("◇ claudemesh (not joined)");
|
|
14904
15016
|
return EXIT.SUCCESS;
|
|
14905
15017
|
}
|
|
14906
|
-
const cachePath =
|
|
15018
|
+
const cachePath = join15(homedir13(), ".claudemesh", "peer-cache.json");
|
|
14907
15019
|
let cache = {};
|
|
14908
|
-
if (
|
|
15020
|
+
if (existsSync25(cachePath)) {
|
|
14909
15021
|
try {
|
|
14910
|
-
cache = JSON.parse(
|
|
15022
|
+
cache = JSON.parse(readFileSync19(cachePath, "utf-8"));
|
|
14911
15023
|
} catch {}
|
|
14912
15024
|
}
|
|
14913
15025
|
const pick = config.meshes[0];
|
|
@@ -14938,7 +15050,7 @@ __export(exports_backup, {
|
|
|
14938
15050
|
runRestore: () => runRestore,
|
|
14939
15051
|
runBackup: () => runBackup
|
|
14940
15052
|
});
|
|
14941
|
-
import { readFileSync as
|
|
15053
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, existsSync as existsSync26 } from "node:fs";
|
|
14942
15054
|
import { createInterface as createInterface11 } from "node:readline";
|
|
14943
15055
|
function readHidden(prompt5) {
|
|
14944
15056
|
return new Promise((resolve2) => {
|
|
@@ -14980,11 +15092,11 @@ async function deriveKey(pass, salt, s) {
|
|
|
14980
15092
|
}
|
|
14981
15093
|
async function runBackup(outPath) {
|
|
14982
15094
|
const configPath = getConfigPath();
|
|
14983
|
-
if (!
|
|
15095
|
+
if (!existsSync26(configPath)) {
|
|
14984
15096
|
console.error(" No config found — nothing to back up. Join a mesh first.");
|
|
14985
15097
|
return EXIT.NOT_FOUND;
|
|
14986
15098
|
}
|
|
14987
|
-
const plaintext =
|
|
15099
|
+
const plaintext = readFileSync20(configPath);
|
|
14988
15100
|
const pass = await readHidden(" Passphrase (min 12 chars): ");
|
|
14989
15101
|
if (pass.length < 12) {
|
|
14990
15102
|
console.error(" ✗ Passphrase too short.");
|
|
@@ -15002,7 +15114,7 @@ async function runBackup(outPath) {
|
|
|
15002
15114
|
const ciphertext = Buffer.from(s.crypto_aead_xchacha20poly1305_ietf_encrypt(plaintext, null, null, nonce, key));
|
|
15003
15115
|
const blob = Buffer.concat([MAGIC, salt, nonce, ciphertext]);
|
|
15004
15116
|
const file = outPath ?? `claudemesh-backup-${new Date().toISOString().replace(/[:.]/g, "-")}.cmb`;
|
|
15005
|
-
|
|
15117
|
+
writeFileSync16(file, blob, { mode: 384 });
|
|
15006
15118
|
console.log(`
|
|
15007
15119
|
✓ Backup saved: ${file}`);
|
|
15008
15120
|
console.log(` Size: ${blob.length} bytes. Guard the passphrase — there is no recovery.
|
|
@@ -15014,11 +15126,11 @@ async function runRestore(inPath) {
|
|
|
15014
15126
|
console.error(" Usage: claudemesh restore <backup-file>");
|
|
15015
15127
|
return EXIT.INVALID_ARGS;
|
|
15016
15128
|
}
|
|
15017
|
-
if (!
|
|
15129
|
+
if (!existsSync26(inPath)) {
|
|
15018
15130
|
console.error(` ✗ File not found: ${inPath}`);
|
|
15019
15131
|
return EXIT.NOT_FOUND;
|
|
15020
15132
|
}
|
|
15021
|
-
const blob =
|
|
15133
|
+
const blob = readFileSync20(inPath);
|
|
15022
15134
|
if (blob.length < 4 + 16 + 24 + 17 || !blob.subarray(0, 4).equals(MAGIC)) {
|
|
15023
15135
|
console.error(" ✗ Not a claudemesh backup file (bad magic).");
|
|
15024
15136
|
return EXIT.INVALID_ARGS;
|
|
@@ -15037,12 +15149,12 @@ async function runRestore(inPath) {
|
|
|
15037
15149
|
return EXIT.INTERNAL_ERROR;
|
|
15038
15150
|
}
|
|
15039
15151
|
const configPath = getConfigPath();
|
|
15040
|
-
if (
|
|
15152
|
+
if (existsSync26(configPath)) {
|
|
15041
15153
|
const backupOld = `${configPath}.before-restore.${Date.now()}`;
|
|
15042
|
-
|
|
15154
|
+
writeFileSync16(backupOld, readFileSync20(configPath), { mode: 384 });
|
|
15043
15155
|
console.log(` ↻ Existing config saved to ${backupOld}`);
|
|
15044
15156
|
}
|
|
15045
|
-
|
|
15157
|
+
writeFileSync16(configPath, Buffer.from(plaintext), { mode: 384 });
|
|
15046
15158
|
console.log(`
|
|
15047
15159
|
✓ Config restored to ${configPath}`);
|
|
15048
15160
|
console.log(" Run `claudemesh list` to verify your meshes.\n");
|
|
@@ -15062,8 +15174,8 @@ __export(exports_upgrade, {
|
|
|
15062
15174
|
runUpgrade: () => runUpgrade
|
|
15063
15175
|
});
|
|
15064
15176
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
15065
|
-
import { existsSync as
|
|
15066
|
-
import { dirname as dirname8, join as
|
|
15177
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
15178
|
+
import { dirname as dirname8, join as join16, resolve as resolve2 } from "node:path";
|
|
15067
15179
|
async function latestVersion() {
|
|
15068
15180
|
try {
|
|
15069
15181
|
const res = await fetch(URLS.NPM_REGISTRY, { signal: AbortSignal.timeout(8000) });
|
|
@@ -15076,15 +15188,15 @@ async function latestVersion() {
|
|
|
15076
15188
|
}
|
|
15077
15189
|
}
|
|
15078
15190
|
function findNpm() {
|
|
15079
|
-
const portable =
|
|
15080
|
-
if (
|
|
15081
|
-
return { npm: portable, prefix:
|
|
15191
|
+
const portable = join16(process.env.HOME ?? "", ".claudemesh", "node", "bin", "npm");
|
|
15192
|
+
if (existsSync27(portable)) {
|
|
15193
|
+
return { npm: portable, prefix: join16(process.env.HOME ?? "", ".claudemesh") };
|
|
15082
15194
|
}
|
|
15083
15195
|
let cur = resolve2(process.argv[1] ?? ".");
|
|
15084
15196
|
for (let i = 0;i < 6; i++) {
|
|
15085
15197
|
cur = dirname8(cur);
|
|
15086
|
-
const candidate =
|
|
15087
|
-
if (
|
|
15198
|
+
const candidate = join16(cur, "bin", "npm");
|
|
15199
|
+
if (existsSync27(candidate))
|
|
15088
15200
|
return { npm: candidate };
|
|
15089
15201
|
}
|
|
15090
15202
|
return { npm: "npm" };
|
|
@@ -15146,9 +15258,9 @@ __export(exports_grants, {
|
|
|
15146
15258
|
runBlock: () => runBlock,
|
|
15147
15259
|
isAllowed: () => isAllowed
|
|
15148
15260
|
});
|
|
15149
|
-
import { existsSync as
|
|
15150
|
-
import { homedir as
|
|
15151
|
-
import { join as
|
|
15261
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
|
|
15262
|
+
import { homedir as homedir14 } from "node:os";
|
|
15263
|
+
import { join as join17 } from "node:path";
|
|
15152
15264
|
async function syncToBroker(meshSlug, grants) {
|
|
15153
15265
|
const auth = getStoredToken();
|
|
15154
15266
|
if (!auth)
|
|
@@ -15166,19 +15278,19 @@ async function syncToBroker(meshSlug, grants) {
|
|
|
15166
15278
|
}
|
|
15167
15279
|
}
|
|
15168
15280
|
function readGrants() {
|
|
15169
|
-
if (!
|
|
15281
|
+
if (!existsSync28(GRANT_FILE))
|
|
15170
15282
|
return {};
|
|
15171
15283
|
try {
|
|
15172
|
-
return JSON.parse(
|
|
15284
|
+
return JSON.parse(readFileSync21(GRANT_FILE, "utf-8"));
|
|
15173
15285
|
} catch {
|
|
15174
15286
|
return {};
|
|
15175
15287
|
}
|
|
15176
15288
|
}
|
|
15177
15289
|
function writeGrants(g) {
|
|
15178
|
-
const dir =
|
|
15179
|
-
if (!
|
|
15180
|
-
|
|
15181
|
-
|
|
15290
|
+
const dir = join17(homedir14(), ".claudemesh");
|
|
15291
|
+
if (!existsSync28(dir))
|
|
15292
|
+
mkdirSync12(dir, { recursive: true });
|
|
15293
|
+
writeFileSync17(GRANT_FILE, JSON.stringify(g, null, 2), { mode: 384 });
|
|
15182
15294
|
}
|
|
15183
15295
|
function resolveCaps(input) {
|
|
15184
15296
|
if (input.includes("all"))
|
|
@@ -15334,7 +15446,7 @@ var init_grants = __esm(() => {
|
|
|
15334
15446
|
BROKER_HTTP7 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
|
|
15335
15447
|
ALL_CAPS = ["read", "dm", "broadcast", "state-read", "state-write", "file-read"];
|
|
15336
15448
|
DEFAULT_CAPS = ["read", "dm", "broadcast", "state-read"];
|
|
15337
|
-
GRANT_FILE =
|
|
15449
|
+
GRANT_FILE = join17(homedir14(), ".claudemesh", "grants.json");
|
|
15338
15450
|
});
|
|
15339
15451
|
|
|
15340
15452
|
// src/commands/profile.ts
|
|
@@ -17055,7 +17167,7 @@ __export(exports_file, {
|
|
|
17055
17167
|
});
|
|
17056
17168
|
import { hostname as osHostname2 } from "node:os";
|
|
17057
17169
|
import { resolve as resolvePath, basename, dirname as dirname9 } from "node:path";
|
|
17058
|
-
import { statSync as statSync7, existsSync as
|
|
17170
|
+
import { statSync as statSync7, existsSync as existsSync29, writeFileSync as writeFileSync18, mkdirSync as mkdirSync13 } from "node:fs";
|
|
17059
17171
|
function emitJson2(data) {
|
|
17060
17172
|
console.log(JSON.stringify(data, null, 2));
|
|
17061
17173
|
}
|
|
@@ -17072,7 +17184,7 @@ async function runFileShare(filePath, opts) {
|
|
|
17072
17184
|
return EXIT.INVALID_ARGS;
|
|
17073
17185
|
}
|
|
17074
17186
|
const absPath = resolvePath(filePath);
|
|
17075
|
-
if (!
|
|
17187
|
+
if (!existsSync29(absPath)) {
|
|
17076
17188
|
render.err(`File not found: ${absPath}`);
|
|
17077
17189
|
return EXIT.INVALID_ARGS;
|
|
17078
17190
|
}
|
|
@@ -17151,8 +17263,8 @@ async function runFileGet(fileId, opts) {
|
|
|
17151
17263
|
}
|
|
17152
17264
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
17153
17265
|
const outPath = opts.out ? resolvePath(opts.out) : resolvePath(process.cwd(), meta.name);
|
|
17154
|
-
|
|
17155
|
-
|
|
17266
|
+
mkdirSync13(dirname9(outPath), { recursive: true });
|
|
17267
|
+
writeFileSync18(outPath, buf);
|
|
17156
17268
|
if (opts.json) {
|
|
17157
17269
|
emitJson2({ fileId, name: meta.name, savedTo: outPath, sizeBytes: buf.length });
|
|
17158
17270
|
} else {
|
|
@@ -17762,7 +17874,7 @@ __export(exports_bridge, {
|
|
|
17762
17874
|
runBridge: () => runBridge,
|
|
17763
17875
|
bridgeConfigTemplate: () => bridgeConfigTemplate
|
|
17764
17876
|
});
|
|
17765
|
-
import { readFileSync as
|
|
17877
|
+
import { readFileSync as readFileSync22, existsSync as existsSync30 } from "node:fs";
|
|
17766
17878
|
function parseConfig(text) {
|
|
17767
17879
|
const trimmed = text.trim();
|
|
17768
17880
|
if (trimmed.startsWith("{"))
|
|
@@ -17806,13 +17918,13 @@ async function runBridge(configPath) {
|
|
|
17806
17918
|
render.err("Usage: claudemesh bridge run <config.yaml>");
|
|
17807
17919
|
return EXIT.INVALID_ARGS;
|
|
17808
17920
|
}
|
|
17809
|
-
if (!
|
|
17921
|
+
if (!existsSync30(configPath)) {
|
|
17810
17922
|
render.err(`config file not found: ${configPath}`);
|
|
17811
17923
|
return EXIT.NOT_FOUND;
|
|
17812
17924
|
}
|
|
17813
17925
|
let cfg;
|
|
17814
17926
|
try {
|
|
17815
|
-
cfg = parseConfig(
|
|
17927
|
+
cfg = parseConfig(readFileSync22(configPath, "utf-8"));
|
|
17816
17928
|
} catch (e) {
|
|
17817
17929
|
render.err(`failed to parse ${configPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
17818
17930
|
return EXIT.INVALID_ARGS;
|
|
@@ -18786,12 +18898,12 @@ import {
|
|
|
18786
18898
|
ListResourcesRequestSchema,
|
|
18787
18899
|
ReadResourceRequestSchema
|
|
18788
18900
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
18789
|
-
import { existsSync as
|
|
18901
|
+
import { existsSync as existsSync31, appendFileSync as appendFileSync2 } from "node:fs";
|
|
18790
18902
|
import { request as httpRequest2 } from "node:http";
|
|
18791
|
-
import { join as
|
|
18903
|
+
import { join as join18 } from "node:path";
|
|
18792
18904
|
async function daemonReady() {
|
|
18793
18905
|
for (let i = 0;i < DAEMON_BOOT_RETRIES; i++) {
|
|
18794
|
-
if (
|
|
18906
|
+
if (existsSync31(DAEMON_PATHS.SOCK_FILE))
|
|
18795
18907
|
return true;
|
|
18796
18908
|
await new Promise((r) => setTimeout(r, DAEMON_BOOT_RETRY_MS));
|
|
18797
18909
|
}
|
|
@@ -19065,7 +19177,7 @@ ${mf.allowed_tools.map((t) => ` - ${t}`).join(`
|
|
|
19065
19177
|
return { contents: [{ uri, mimeType: "text/markdown", text: fm.join(`
|
|
19066
19178
|
`) + skill.instructions }] };
|
|
19067
19179
|
});
|
|
19068
|
-
const mcpLogPath =
|
|
19180
|
+
const mcpLogPath = join18(DAEMON_PATHS.DAEMON_DIR, `mcp-${process.pid}.log`);
|
|
19069
19181
|
const mcpLog = (msg, meta) => {
|
|
19070
19182
|
const line = JSON.stringify({ ts: new Date().toISOString(), pid: process.pid, msg, ...meta }) + `
|
|
19071
19183
|
`;
|
|
@@ -21392,4 +21504,4 @@ main().catch((err) => {
|
|
|
21392
21504
|
process.exit(EXIT.INTERNAL_ERROR);
|
|
21393
21505
|
});
|
|
21394
21506
|
|
|
21395
|
-
//# debugId=
|
|
21507
|
+
//# debugId=A7ECB4BF81F2B4CE64756E2164756E21
|