feat(cli): file share / file get + same-host fast path (v1.19.0)
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled

Two new CLI verbs for the file-sharing surface that already existed
on the broker (HTTP /upload + WS get_file/list_files) but was only
reachable through MCP-style docstrings referencing tools that do
not in fact exist:

  claudemesh file share <path> [--to peer] [--message "..."]
  claudemesh file get <id> [--out path]

Same-host fast path: when --to resolves to a session on the same
hostname, skip MinIO and DM the absolute filepath. The receiver
reads it off disk directly. No bucket roundtrip, no 50 MB cap.
Falls back to encrypted upload when the peer is remote or --upload
is set.

Routes the same-host DM by session pubkey, not displayName, so
sibling sessions of the same member do not trip the v0.5.1
self-DM guard.

Updates the bundled SKILL.md and the MCP server instructions to
reference the real CLI verbs instead of the fictional share_file()
/ get_file() tool calls.

Also: rename.ts now distinguishes mesh-membership from web-account
auth and points users at claudemesh login + the dashboard rather
than emitting a bare "Not signed in".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-05-03 14:05:24 +01:00
parent f9ed3fa286
commit 3a3d2a6c4c
7 changed files with 246 additions and 12 deletions

View File

@@ -159,6 +159,8 @@ Platform
claudemesh vault list|delete encrypted secrets
claudemesh watch list|remove URL change watchers
claudemesh webhook list|delete outbound HTTP triggers
claudemesh file share <path> [--to peer] upload (or local-host fast path if --to matches)
claudemesh file get <id> [--out path] download by id
claudemesh file list|status|delete shared mesh files
claudemesh mesh-mcp list|call|catalog deployed mesh-MCP servers
claudemesh clock set|pause|resume mesh logical clock
@@ -576,10 +578,24 @@ async function main(): Promise<void> {
case "file": {
const sub = positionals[0];
const f = { mesh: flags.mesh as string, json: !!flags.json };
if (sub === "list") { const { runFileList } = await import("~/commands/platform-actions.js"); process.exit(await runFileList({ ...f, query: positionals[1] })); }
if (sub === "share") {
const { runFileShare } = await import("~/commands/file.js");
process.exit(await runFileShare(positionals[1] ?? "", {
...f,
to: flags.to as string | undefined,
tags: flags.tags as string | undefined,
message: flags.message as string | undefined,
upload: !!flags.upload,
}));
}
else if (sub === "get") {
const { runFileGet } = await import("~/commands/file.js");
process.exit(await runFileGet(positionals[1] ?? "", { ...f, out: flags.out as string | undefined }));
}
else if (sub === "list") { const { runFileList } = await import("~/commands/platform-actions.js"); process.exit(await runFileList({ ...f, query: positionals[1] })); }
else if (sub === "status") { const { runFileStatus } = await import("~/commands/platform-actions.js"); process.exit(await runFileStatus(positionals[1] ?? "", f)); }
else if (sub === "delete") { const { runFileDelete } = await import("~/commands/platform-actions.js"); process.exit(await runFileDelete(positionals[1] ?? "", f)); }
else { console.error("Usage: claudemesh file <list|status|delete>"); process.exit(EXIT.INVALID_ARGS); }
else { console.error("Usage: claudemesh file <share|get|list|status|delete>"); process.exit(EXIT.INVALID_ARGS); }
break;
}
case "mesh-mcp": {