From a70c5fd1243015f95ea91de3fc2a79419e475c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Guti=C3=A9rrez?= <35082514+alezmad@users.noreply.github.com> Date: Mon, 6 Apr 2026 17:27:00 +0100 Subject: [PATCH] =?UTF-8?q?feat(cli):=20v0.5.5=20=E2=80=94=20ping=5Fmesh?= =?UTF-8?q?=20diagnostic=20tool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sends test messages to self through the full pipeline per priority and measures round-trip timing. Reports send→ack and send→receive latency. Detects broker priority gating (status=working holds next/low). Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/cli/package.json | 2 +- apps/cli/src/mcp/server.ts | 52 ++++++++++++++++++++++++++++++++++++++ apps/cli/src/mcp/tools.ts | 17 +++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/apps/cli/package.json b/apps/cli/package.json index 4e947c6..77a038e 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,6 +1,6 @@ { "name": "claudemesh-cli", - "version": "0.5.4", + "version": "0.5.5", "description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.", "keywords": [ "claude-code", diff --git a/apps/cli/src/mcp/server.ts b/apps/cli/src/mcp/server.ts index 8db5c38..74e7d62 100644 --- a/apps/cli/src/mcp/server.ts +++ b/apps/cli/src/mcp/server.ts @@ -707,6 +707,58 @@ Your message mode is "${messageMode}". return text(lines.join("\n")); } + case "ping_mesh": { + const { priorities: pingPriorities } = (args ?? {}) as { priorities?: string[] }; + const toTest = (pingPriorities ?? ["now", "next"]) as Priority[]; + const client = allClients()[0]; + if (!client) return text("ping_mesh: not connected", true); + const results: string[] = []; + + for (const prio of toTest) { + const sendTime = Date.now(); + const pingId = `ping-${sendTime}-${prio}`; + // Send to self (broadcast) — should bounce back through the broker + const sendResult = await client.send("*", `__ping__${pingId}`, prio); + const ackTime = Date.now(); + + if (!sendResult.ok) { + results.push(`[${prio}] SEND FAILED: ${sendResult.error}`); + continue; + } + + // Wait up to 10s for the ping to arrive in pushBuffer + let received = false; + let receiveTime = 0; + for (let i = 0; i < 100; i++) { + await new Promise(r => setTimeout(r, 100)); + const buffer = client.pushHistory; + const match = buffer.find(m => + m.plaintext?.includes(pingId) || false + ); + if (match) { + received = true; + receiveTime = Date.now(); + break; + } + } + + if (received) { + results.push( + `[${prio}] OK — send→ack: ${ackTime - sendTime}ms, send→receive: ${receiveTime - sendTime}ms` + ); + } else { + // Check peer status + const peers = await client.listPeers(); + const selfStatus = peers.find(p => p.displayName === myName)?.status ?? "unknown"; + results.push( + `[${prio}] NOT RECEIVED in 10s (your status: ${selfStatus}${selfStatus === "working" ? " — broker holds next/low" : ""})` + ); + } + } + + return text(`Ping results:\n${results.join("\n")}`); + } + default: return text(`Unknown tool: ${name}`, true); } diff --git a/apps/cli/src/mcp/tools.ts b/apps/cli/src/mcp/tools.ts index 77113ff..e78e8ed 100644 --- a/apps/cli/src/mcp/tools.ts +++ b/apps/cli/src/mcp/tools.ts @@ -555,4 +555,21 @@ export const TOOLS: Tool[] = [ "Get a complete overview of the mesh: peers, groups, state, memory, files, tasks, streams, tables. Call on session start for full situational awareness.", inputSchema: { type: "object", properties: {} }, }, + + // --- Diagnostics --- + { + name: "ping_mesh", + description: + "Send test messages through the full pipeline and measure round-trip timing per priority. Diagnoses push delivery issues.", + inputSchema: { + type: "object", + properties: { + priorities: { + type: "array", + items: { type: "string", enum: ["now", "next", "low"] }, + description: "Priorities to test (default: [\"now\", \"next\"])", + }, + }, + }, + }, ];