broker-client: full WS client with hello handshake + ack, auto-reconnect with exponential backoff (1s → 30s capped), in-memory outbound queue (max 100) during reconnect, 500-entry push buffer for check_messages. MCP tool integration: - send_message: "slug:target" prefix or single-mesh fast path - check_messages: drains push buffers across all clients - set_status: fans manual override across all connected meshes - set_summary: stubbed (broker protocol extension needed) - list_peers: stubbed — lists connected mesh slugs + statuses manager module holds Map<meshId, BrokerClient>, starts on MCP server boot for every joined mesh in ~/.claudemesh/config.json. new CLI command: seed-test-mesh injects a mesh row for dev testing. also fixes a broker-side hello race: handleHello sent hello_ack before the caller closure assigned presenceId, so clients sending right after the ack hit the no_hello check. Fix: return presenceId, caller sets closure var, THEN sends hello_ack. Queue drain is fire-and-forget now. round-trip verified: two clients, A→B, push received with correct senderPubkey + ciphertext. 44/44 broker tests still pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
/**
|
|
* `claudemesh seed-test-mesh` — dev-only helper for 15b testing.
|
|
*
|
|
* Writes a locally-valid JoinedMesh entry to ~/.claudemesh/config.json
|
|
* so the MCP server can connect to a locally-running broker without
|
|
* invite-link / crypto plumbing.
|
|
*
|
|
* Usage:
|
|
* claudemesh seed-test-mesh <broker-url> <mesh-id> <member-id> <pubkey> <slug>
|
|
*/
|
|
|
|
import { loadConfig, saveConfig } from "../state/config";
|
|
|
|
export function runSeedTestMesh(args: string[]): void {
|
|
const [brokerUrl, meshId, memberId, pubkey, slug] = args;
|
|
if (!brokerUrl || !meshId || !memberId || !pubkey || !slug) {
|
|
console.error(
|
|
"Usage: claudemesh seed-test-mesh <broker-ws-url> <mesh-id> <member-id> <pubkey> <slug>",
|
|
);
|
|
console.error("");
|
|
console.error(
|
|
'Example: claudemesh seed-test-mesh "ws://localhost:7900/ws" mesh-123 member-abc aaa..aaa smoke-test',
|
|
);
|
|
process.exit(1);
|
|
}
|
|
const config = loadConfig();
|
|
// Remove any prior entry with same slug (idempotent).
|
|
config.meshes = config.meshes.filter((m) => m.slug !== slug);
|
|
config.meshes.push({
|
|
meshId,
|
|
memberId,
|
|
slug,
|
|
name: `Test: ${slug}`,
|
|
pubkey,
|
|
secretKey: "dev-only-stub", // real keypair generated during join in Step 17
|
|
brokerUrl,
|
|
joinedAt: new Date().toISOString(),
|
|
});
|
|
saveConfig(config);
|
|
console.log(`Seeded mesh "${slug}" (${meshId}) into local config.`);
|
|
console.log(
|
|
`Run \`claudemesh mcp\` to connect, or register with Claude Code via \`claudemesh install\`.`,
|
|
);
|
|
}
|