claudemesh-cli 1.18.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/entrypoints/cli.js
CHANGED
|
@@ -88,7 +88,7 @@ __export(exports_urls, {
|
|
|
88
88
|
VERSION: () => VERSION,
|
|
89
89
|
URLS: () => URLS
|
|
90
90
|
});
|
|
91
|
-
var URLS, VERSION = "1.
|
|
91
|
+
var URLS, VERSION = "1.19.0", env;
|
|
92
92
|
var init_urls = __esm(() => {
|
|
93
93
|
URLS = {
|
|
94
94
|
BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
|
|
@@ -5135,6 +5135,14 @@ __export(exports_rename, {
|
|
|
5135
5135
|
rename: () => rename
|
|
5136
5136
|
});
|
|
5137
5137
|
async function rename(slug, newName) {
|
|
5138
|
+
const auth = getStoredToken();
|
|
5139
|
+
if (!auth) {
|
|
5140
|
+
console.error(` ${icons.cross} Renaming a mesh requires a claudemesh.com account session.`);
|
|
5141
|
+
console.error(` ${dim("Joining via invite signs you in to the mesh, not to a web account.")}`);
|
|
5142
|
+
console.error(` ${dim("Run")} ${bold("claudemesh login")} ${dim("first, then retry, or rename from the dashboard:")}`);
|
|
5143
|
+
console.error(` https://claudemesh.com/dashboard`);
|
|
5144
|
+
return EXIT.AUTH_FAILED;
|
|
5145
|
+
}
|
|
5138
5146
|
try {
|
|
5139
5147
|
await renameMesh2(slug, newName);
|
|
5140
5148
|
console.log(` ${green(icons.check)} Renamed "${slug}" to "${newName}"`);
|
|
@@ -5146,6 +5154,7 @@ async function rename(slug, newName) {
|
|
|
5146
5154
|
}
|
|
5147
5155
|
var init_rename2 = __esm(() => {
|
|
5148
5156
|
init_facade10();
|
|
5157
|
+
init_facade6();
|
|
5149
5158
|
init_styles();
|
|
5150
5159
|
init_exit_codes();
|
|
5151
5160
|
});
|
|
@@ -11578,12 +11587,30 @@ claudemesh webhook delete <name>
|
|
|
11578
11587
|
### \`file\` — shared mesh files
|
|
11579
11588
|
|
|
11580
11589
|
\`\`\`bash
|
|
11581
|
-
claudemesh file
|
|
11582
|
-
claudemesh file
|
|
11590
|
+
claudemesh file share <path> # upload to mesh (visible to all members)
|
|
11591
|
+
claudemesh file share <path> --to <peer> # share with one peer (same-host fast path if co-located)
|
|
11592
|
+
claudemesh file share <path> --to <peer> --message "see line 42"
|
|
11593
|
+
claudemesh file share <path> --upload # force network upload, skip same-host fast path
|
|
11594
|
+
claudemesh file get <file-id> # download by id (saves to ./<name>)
|
|
11595
|
+
claudemesh file get <file-id> --out /tmp/foo.bin # download to explicit path
|
|
11596
|
+
claudemesh file list [search-query] # browse mesh files
|
|
11597
|
+
claudemesh file status <file-id> # who has accessed
|
|
11583
11598
|
claudemesh file delete <file-id>
|
|
11584
|
-
# Upload + retrieval currently via MCP \`share_file\` / \`get_file\` (binary streams)
|
|
11585
11599
|
\`\`\`
|
|
11586
11600
|
|
|
11601
|
+
**Same-host fast path** (v0.6.0+): when \`--to <peer>\` resolves to a session
|
|
11602
|
+
running on the same hostname as you, \`claudemesh file share\` skips MinIO
|
|
11603
|
+
entirely and sends a DM with the absolute filepath. The receiver reads it
|
|
11604
|
+
directly off disk. No 50 MB cap, no upload latency, nothing in the bucket.
|
|
11605
|
+
Falls back to encrypted upload when the peer is remote, or always when
|
|
11606
|
+
\`--upload\` is set. Routes by session pubkey, so sibling sessions of the
|
|
11607
|
+
same member work without tripping the self-DM guard.
|
|
11608
|
+
|
|
11609
|
+
**Network upload cap**: 50 MB. Same-host fast path has no cap.
|
|
11610
|
+
|
|
11611
|
+
**\`--to\` accepts**: display name, member pubkey, session pubkey, or any
|
|
11612
|
+
≥8-char prefix of a pubkey. Prefer pubkey when multiple peers share a name.
|
|
11613
|
+
|
|
11587
11614
|
### \`mesh-mcp\` — call MCP servers other peers deployed to the mesh
|
|
11588
11615
|
|
|
11589
11616
|
\`\`\`bash
|
|
@@ -11729,6 +11756,129 @@ var init_skill = __esm(() => {
|
|
|
11729
11756
|
init_exit_codes();
|
|
11730
11757
|
});
|
|
11731
11758
|
|
|
11759
|
+
// src/commands/file.ts
|
|
11760
|
+
var exports_file = {};
|
|
11761
|
+
__export(exports_file, {
|
|
11762
|
+
runFileShare: () => runFileShare,
|
|
11763
|
+
runFileGet: () => runFileGet
|
|
11764
|
+
});
|
|
11765
|
+
import { hostname as osHostname } from "node:os";
|
|
11766
|
+
import { resolve as resolvePath, basename, dirname as dirname6 } from "node:path";
|
|
11767
|
+
import { statSync as statSync6, existsSync as existsSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync7 } from "node:fs";
|
|
11768
|
+
function emitJson2(data) {
|
|
11769
|
+
console.log(JSON.stringify(data, null, 2));
|
|
11770
|
+
}
|
|
11771
|
+
function formatSize(bytes) {
|
|
11772
|
+
if (bytes < 1024)
|
|
11773
|
+
return `${bytes} B`;
|
|
11774
|
+
if (bytes < 1024 * 1024)
|
|
11775
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
11776
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
11777
|
+
}
|
|
11778
|
+
async function runFileShare(filePath, opts) {
|
|
11779
|
+
if (!filePath) {
|
|
11780
|
+
render.err('Usage: claudemesh file share <path> [--to <peer>] [--tags a,b] [--message "..."] [--upload]');
|
|
11781
|
+
return EXIT.INVALID_ARGS;
|
|
11782
|
+
}
|
|
11783
|
+
const absPath = resolvePath(filePath);
|
|
11784
|
+
if (!existsSync20(absPath)) {
|
|
11785
|
+
render.err(`File not found: ${absPath}`);
|
|
11786
|
+
return EXIT.INVALID_ARGS;
|
|
11787
|
+
}
|
|
11788
|
+
const stat = statSync6(absPath);
|
|
11789
|
+
if (!stat.isFile()) {
|
|
11790
|
+
render.err(`Not a regular file: ${absPath}`);
|
|
11791
|
+
return EXIT.INVALID_ARGS;
|
|
11792
|
+
}
|
|
11793
|
+
const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
|
|
11794
|
+
return await withMesh({ meshSlug: opts.mesh ?? null }, async (client, mesh) => {
|
|
11795
|
+
if (opts.to && !opts.upload) {
|
|
11796
|
+
const peers = await client.listPeers();
|
|
11797
|
+
const myHost = osHostname();
|
|
11798
|
+
const target = peers.find((p) => {
|
|
11799
|
+
if (!p.hostname || p.hostname !== myHost)
|
|
11800
|
+
return false;
|
|
11801
|
+
return p.displayName === opts.to || p.memberPubkey === opts.to || p.pubkey === opts.to || typeof opts.to === "string" && opts.to.length >= 8 && p.pubkey.startsWith(opts.to);
|
|
11802
|
+
});
|
|
11803
|
+
if (target) {
|
|
11804
|
+
const note = opts.message ? `
|
|
11805
|
+
${opts.message}` : "";
|
|
11806
|
+
const body = `\uD83D\uDCCE file://${absPath} (${formatSize(stat.size)} · same host, no upload)${note}`;
|
|
11807
|
+
const result = await client.send(target.pubkey, body, "next");
|
|
11808
|
+
if (!result.ok) {
|
|
11809
|
+
render.err(`Send failed: ${result.error ?? "unknown"}`);
|
|
11810
|
+
return EXIT.NETWORK_ERROR;
|
|
11811
|
+
}
|
|
11812
|
+
if (opts.json) {
|
|
11813
|
+
emitJson2({ mode: "local", path: absPath, to: target.displayName, hostname: myHost, sizeBytes: stat.size });
|
|
11814
|
+
} else {
|
|
11815
|
+
render.ok(`shared ${bold(basename(absPath))} ${dim(`(${formatSize(stat.size)})`)} → ${green(target.displayName)} ${dim("[same host, no upload]")}`);
|
|
11816
|
+
}
|
|
11817
|
+
return EXIT.SUCCESS;
|
|
11818
|
+
}
|
|
11819
|
+
}
|
|
11820
|
+
const fileId = await client.uploadFile(absPath, mesh.meshId, mesh.memberId, {
|
|
11821
|
+
name: basename(absPath),
|
|
11822
|
+
tags,
|
|
11823
|
+
persistent: true,
|
|
11824
|
+
targetSpec: opts.to
|
|
11825
|
+
});
|
|
11826
|
+
if (opts.to) {
|
|
11827
|
+
const note = opts.message ? `
|
|
11828
|
+
${opts.message}` : "";
|
|
11829
|
+
const body = `\uD83D\uDCCE ${basename(absPath)} (${formatSize(stat.size)})
|
|
11830
|
+
claudemesh file get ${fileId}${note}`;
|
|
11831
|
+
await client.send(opts.to, body, "next");
|
|
11832
|
+
}
|
|
11833
|
+
if (opts.json) {
|
|
11834
|
+
emitJson2({ mode: "upload", fileId, name: basename(absPath), sizeBytes: stat.size, to: opts.to ?? null });
|
|
11835
|
+
} else {
|
|
11836
|
+
render.ok(`uploaded ${bold(basename(absPath))} ${dim(`(${formatSize(stat.size)})`)} ${dim("· id=" + fileId.slice(0, 12))}`);
|
|
11837
|
+
if (opts.to)
|
|
11838
|
+
render.info(dim(` notified ${opts.to}`));
|
|
11839
|
+
else
|
|
11840
|
+
render.info(dim(` retrieve: claudemesh file get ${fileId}`));
|
|
11841
|
+
}
|
|
11842
|
+
return EXIT.SUCCESS;
|
|
11843
|
+
});
|
|
11844
|
+
}
|
|
11845
|
+
async function runFileGet(fileId, opts) {
|
|
11846
|
+
if (!fileId) {
|
|
11847
|
+
render.err("Usage: claudemesh file get <file-id> [--out <path>]");
|
|
11848
|
+
return EXIT.INVALID_ARGS;
|
|
11849
|
+
}
|
|
11850
|
+
return await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
|
|
11851
|
+
const meta = await client.getFile(fileId);
|
|
11852
|
+
if (!meta) {
|
|
11853
|
+
render.err(`File not found or not accessible: ${fileId}`);
|
|
11854
|
+
return EXIT.NOT_FOUND;
|
|
11855
|
+
}
|
|
11856
|
+
const res = await fetch(meta.url, { signal: AbortSignal.timeout(60000) });
|
|
11857
|
+
if (!res.ok) {
|
|
11858
|
+
render.err(`Download failed: HTTP ${res.status}`);
|
|
11859
|
+
return EXIT.NETWORK_ERROR;
|
|
11860
|
+
}
|
|
11861
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
11862
|
+
const outPath = opts.out ? resolvePath(opts.out) : resolvePath(process.cwd(), meta.name);
|
|
11863
|
+
mkdirSync7(dirname6(outPath), { recursive: true });
|
|
11864
|
+
writeFileSync11(outPath, buf);
|
|
11865
|
+
if (opts.json) {
|
|
11866
|
+
emitJson2({ fileId, name: meta.name, savedTo: outPath, sizeBytes: buf.length });
|
|
11867
|
+
} else {
|
|
11868
|
+
render.ok(`saved ${bold(meta.name)} ${dim(`(${formatSize(buf.length)})`)} → ${dim(outPath)}`);
|
|
11869
|
+
}
|
|
11870
|
+
return EXIT.SUCCESS;
|
|
11871
|
+
});
|
|
11872
|
+
}
|
|
11873
|
+
var MAX_FILE_BYTES;
|
|
11874
|
+
var init_file = __esm(() => {
|
|
11875
|
+
init_connect();
|
|
11876
|
+
init_render();
|
|
11877
|
+
init_styles();
|
|
11878
|
+
init_exit_codes();
|
|
11879
|
+
MAX_FILE_BYTES = 50 * 1024 * 1024;
|
|
11880
|
+
});
|
|
11881
|
+
|
|
11732
11882
|
// ../../packages/sdk/dist/crypto.js
|
|
11733
11883
|
var require_crypto = __commonJS((exports) => {
|
|
11734
11884
|
var __importDefault = exports && exports.__importDefault || function(mod) {
|
|
@@ -12321,7 +12471,7 @@ __export(exports_bridge, {
|
|
|
12321
12471
|
runBridge: () => runBridge,
|
|
12322
12472
|
bridgeConfigTemplate: () => bridgeConfigTemplate
|
|
12323
12473
|
});
|
|
12324
|
-
import { readFileSync as readFileSync14, existsSync as
|
|
12474
|
+
import { readFileSync as readFileSync14, existsSync as existsSync21 } from "node:fs";
|
|
12325
12475
|
function parseConfig(text) {
|
|
12326
12476
|
const trimmed = text.trim();
|
|
12327
12477
|
if (trimmed.startsWith("{"))
|
|
@@ -12365,7 +12515,7 @@ async function runBridge(configPath) {
|
|
|
12365
12515
|
render.err("Usage: claudemesh bridge run <config.yaml>");
|
|
12366
12516
|
return EXIT.INVALID_ARGS;
|
|
12367
12517
|
}
|
|
12368
|
-
if (!
|
|
12518
|
+
if (!existsSync21(configPath)) {
|
|
12369
12519
|
render.err(`config file not found: ${configPath}`);
|
|
12370
12520
|
return EXIT.NOT_FOUND;
|
|
12371
12521
|
}
|
|
@@ -13342,7 +13492,7 @@ var init_definitions = __esm(() => {
|
|
|
13342
13492
|
|
|
13343
13493
|
// src/services/bridge/server.ts
|
|
13344
13494
|
import { createServer as createServer2 } from "node:net";
|
|
13345
|
-
import { mkdirSync as
|
|
13495
|
+
import { mkdirSync as mkdirSync8, unlinkSync as unlinkSync2, existsSync as existsSync22, chmodSync as chmodSync5 } from "node:fs";
|
|
13346
13496
|
async function resolveTarget2(client, to) {
|
|
13347
13497
|
if (to.startsWith("@") || to === "*" || /^[0-9a-f]{64}$/i.test(to)) {
|
|
13348
13498
|
return { ok: true, spec: to };
|
|
@@ -13456,10 +13606,10 @@ function handleConnection(socket, client) {
|
|
|
13456
13606
|
function startBridgeServer(client) {
|
|
13457
13607
|
const path = socketPath(client.meshSlug);
|
|
13458
13608
|
const dir = socketDir();
|
|
13459
|
-
if (!
|
|
13460
|
-
|
|
13609
|
+
if (!existsSync22(dir)) {
|
|
13610
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
13461
13611
|
}
|
|
13462
|
-
if (
|
|
13612
|
+
if (existsSync22(path)) {
|
|
13463
13613
|
try {
|
|
13464
13614
|
unlinkSync2(path);
|
|
13465
13615
|
} catch {}
|
|
@@ -13610,11 +13760,11 @@ If the channel meta contains \`subtype: reminder\`, this is a scheduled reminder
|
|
|
13610
13760
|
| remember(content, tags?) | Store persistent knowledge with optional tags. |
|
|
13611
13761
|
| recall(query) | Full-text search over mesh memory. |
|
|
13612
13762
|
| forget(id) | Soft-delete a memory entry. |
|
|
13613
|
-
|
|
|
13614
|
-
|
|
|
13615
|
-
|
|
|
13616
|
-
|
|
|
13617
|
-
|
|
|
13763
|
+
| claudemesh file share <path> [--to peer] [--tags a,b] | Share a file with the mesh, or DM it to a specific peer. Same-host fast path: when --to matches a peer on this machine, sends an absolute filepath instead of uploading (no MinIO round-trip). |
|
|
13764
|
+
| claudemesh file get <id> [--out path] | Download a shared file by id. |
|
|
13765
|
+
| claudemesh file list [query] | Find files shared in the mesh. |
|
|
13766
|
+
| claudemesh file status <id> | Check who has accessed a file. |
|
|
13767
|
+
| claudemesh file delete <id> | Remove a shared file from the mesh. |
|
|
13618
13768
|
| vector_store(collection, text, metadata?) | Store embedding in per-mesh Qdrant collection. |
|
|
13619
13769
|
| vector_search(collection, query, limit?) | Semantic search over stored embeddings. |
|
|
13620
13770
|
| vector_delete(collection, id) | Remove an embedding. |
|
|
@@ -14961,6 +15111,8 @@ Platform
|
|
|
14961
15111
|
claudemesh vault list|delete encrypted secrets
|
|
14962
15112
|
claudemesh watch list|remove URL change watchers
|
|
14963
15113
|
claudemesh webhook list|delete outbound HTTP triggers
|
|
15114
|
+
claudemesh file share <path> [--to peer] upload (or local-host fast path if --to matches)
|
|
15115
|
+
claudemesh file get <id> [--out path] download by id
|
|
14964
15116
|
claudemesh file list|status|delete shared mesh files
|
|
14965
15117
|
claudemesh mesh-mcp list|call|catalog deployed mesh-MCP servers
|
|
14966
15118
|
claudemesh clock set|pause|resume mesh logical clock
|
|
@@ -15633,7 +15785,19 @@ async function main() {
|
|
|
15633
15785
|
case "file": {
|
|
15634
15786
|
const sub = positionals[0];
|
|
15635
15787
|
const f = { mesh: flags.mesh, json: !!flags.json };
|
|
15636
|
-
if (sub === "
|
|
15788
|
+
if (sub === "share") {
|
|
15789
|
+
const { runFileShare: runFileShare2 } = await Promise.resolve().then(() => (init_file(), exports_file));
|
|
15790
|
+
process.exit(await runFileShare2(positionals[1] ?? "", {
|
|
15791
|
+
...f,
|
|
15792
|
+
to: flags.to,
|
|
15793
|
+
tags: flags.tags,
|
|
15794
|
+
message: flags.message,
|
|
15795
|
+
upload: !!flags.upload
|
|
15796
|
+
}));
|
|
15797
|
+
} else if (sub === "get") {
|
|
15798
|
+
const { runFileGet: runFileGet2 } = await Promise.resolve().then(() => (init_file(), exports_file));
|
|
15799
|
+
process.exit(await runFileGet2(positionals[1] ?? "", { ...f, out: flags.out }));
|
|
15800
|
+
} else if (sub === "list") {
|
|
15637
15801
|
const { runFileList: runFileList2 } = await Promise.resolve().then(() => (init_platform_actions(), exports_platform_actions));
|
|
15638
15802
|
process.exit(await runFileList2({ ...f, query: positionals[1] }));
|
|
15639
15803
|
} else if (sub === "status") {
|
|
@@ -15643,7 +15807,7 @@ async function main() {
|
|
|
15643
15807
|
const { runFileDelete: runFileDelete2 } = await Promise.resolve().then(() => (init_platform_actions(), exports_platform_actions));
|
|
15644
15808
|
process.exit(await runFileDelete2(positionals[1] ?? "", f));
|
|
15645
15809
|
} else {
|
|
15646
|
-
console.error("Usage: claudemesh file <list|status|delete>");
|
|
15810
|
+
console.error("Usage: claudemesh file <share|get|list|status|delete>");
|
|
15647
15811
|
process.exit(EXIT.INVALID_ARGS);
|
|
15648
15812
|
}
|
|
15649
15813
|
break;
|
|
@@ -15925,4 +16089,4 @@ main().catch((err) => {
|
|
|
15925
16089
|
process.exit(EXIT.INTERNAL_ERROR);
|
|
15926
16090
|
});
|
|
15927
16091
|
|
|
15928
|
-
//# debugId=
|
|
16092
|
+
//# debugId=4702C484C802D1AB64756E2164756E21
|