remote-pi 0.4.1 → 0.4.3
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/daemon/rpc_child.d.ts +4 -1
- package/dist/daemon/rpc_child.js +14 -3
- package/dist/daemon/rpc_child.js.map +1 -1
- package/dist/daemon/supervisor.js +9 -1
- package/dist/daemon/supervisor.js.map +1 -1
- package/dist/index.js +75 -60
- package/dist/index.js.map +1 -1
- package/dist/mcp/mesh_server.js +170 -44
- package/dist/mcp/mesh_server.js.map +1 -1
- package/dist/session/address.d.ts +49 -0
- package/dist/session/address.js +58 -0
- package/dist/session/address.js.map +1 -0
- package/dist/session/broker.d.ts +18 -22
- package/dist/session/broker.js +10 -51
- package/dist/session/broker.js.map +1 -1
- package/dist/session/broker_remote.js +5 -5
- package/dist/session/broker_remote.js.map +1 -1
- package/dist/session/cwd_lock.js +11 -4
- package/dist/session/cwd_lock.js.map +1 -1
- package/dist/session/mesh_message.d.ts +20 -0
- package/dist/session/mesh_message.js +28 -0
- package/dist/session/mesh_message.js.map +1 -0
- package/dist/session/mesh_node.d.ts +11 -0
- package/dist/session/mesh_node.js +81 -2
- package/dist/session/mesh_node.js.map +1 -1
- package/dist/session/tools.js +17 -11
- package/dist/session/tools.js.map +1 -1
- package/package.json +1 -1
- package/skills/agent-network/SKILL.md +163 -280
- package/skills/claude-agent-network/SKILL.md +0 -239
package/dist/mcp/mesh_server.js
CHANGED
|
@@ -19,11 +19,18 @@ import { homedir } from "node:os";
|
|
|
19
19
|
import { join } from "node:path";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
import { MeshNode } from "../session/mesh_node.js";
|
|
22
|
-
import { loadLocalConfig, defaultAgentName } from "../session/local_config.js";
|
|
22
|
+
import { loadLocalConfig, defaultAgentName, localConfigExists } from "../session/local_config.js";
|
|
23
23
|
import { resolveRelayUrl } from "../config.js";
|
|
24
24
|
import { acquireCwdLock } from "../session/cwd_lock.js";
|
|
25
25
|
// ── Args / config ─────────────────────────────────────────────────────────────
|
|
26
26
|
const _argv = process.argv.slice(2);
|
|
27
|
+
// This agent's folder = the dir the `claude` session was launched in, which
|
|
28
|
+
// Claude sets as this subprocess's `process.cwd()`. We deliberately do NOT use
|
|
29
|
+
// CLAUDE_PROJECT_DIR: that's the git repo root, which would collapse every
|
|
30
|
+
// monorepo subproject (app/, relay/, …) into one identity + one lock. The
|
|
31
|
+
// `remote-pi claude` launcher therefore registers us WITHOUT a baked `--cwd`,
|
|
32
|
+
// so one shared local-scope entry self-identifies per session. `--cwd` and
|
|
33
|
+
// REMOTE_PI_MCP_CWD remain as explicit overrides (tests / manual launches).
|
|
27
34
|
let _cwd = process.env["REMOTE_PI_MCP_CWD"] ?? process.cwd();
|
|
28
35
|
let _nameOverride = process.env["REMOTE_PI_MCP_NAME"];
|
|
29
36
|
let _bridgeEnabled = true;
|
|
@@ -45,6 +52,25 @@ const AUDIT_PATH = join(homedir(), ".pi", "remote", "sessions", "local", "audit.
|
|
|
45
52
|
const inbox = [];
|
|
46
53
|
// ── Mesh node ─────────────────────────────────────────────────────────────────
|
|
47
54
|
const { url: relayUrl } = resolveRelayUrl();
|
|
55
|
+
// Diagnostics go to STDERR — stdout is the JSON-RPC channel, so writing there
|
|
56
|
+
// would corrupt the MCP protocol. Claude Code captures an MCP server's stderr
|
|
57
|
+
// into its mcp-logs, which is where these land for debugging.
|
|
58
|
+
function logErr(msg) {
|
|
59
|
+
process.stderr.write(`[remote-pi-mesh ${isoNow()}] ${msg}\n`);
|
|
60
|
+
}
|
|
61
|
+
// Survive stray async failures. This process runs background work (relay WS
|
|
62
|
+
// churn, UDS failover, the MCP SDK) whose errors previously had NO global
|
|
63
|
+
// handler — a single unhandled rejection or exception silently killed this
|
|
64
|
+
// stdio subprocess, and Claude surfaced the MCP as "disconnected" with no
|
|
65
|
+
// trace. None of that background work is fatal to serving tools over stdio, so
|
|
66
|
+
// log loudly and keep running instead of dying. (We intentionally do NOT
|
|
67
|
+
// process.exit here: the tools stay available even if the mesh is degraded.)
|
|
68
|
+
process.on("unhandledRejection", (reason) => {
|
|
69
|
+
logErr(`unhandledRejection: ${reason instanceof Error ? (reason.stack ?? reason.message) : String(reason)}`);
|
|
70
|
+
});
|
|
71
|
+
process.on("uncaughtException", (err) => {
|
|
72
|
+
logErr(`uncaughtException: ${err.stack ?? err.message}`);
|
|
73
|
+
});
|
|
48
74
|
const mesh = new MeshNode({
|
|
49
75
|
sockPath: BROKER_SOCK,
|
|
50
76
|
name: AGENT_NAME,
|
|
@@ -53,11 +79,16 @@ const mesh = new MeshNode({
|
|
|
53
79
|
// daemon already hosting the broker for this cwd). As a follower the
|
|
54
80
|
// bridge stays dormant and cross-PC rides the existing leader.
|
|
55
81
|
...(_bridgeEnabled ? { bridge: { relayUrl, cwd: _cwd } } : {}),
|
|
56
|
-
|
|
82
|
+
// Silent: stdout is the MCP JSON-RPC channel and stderr noise isn't wanted.
|
|
83
|
+
// Real failures still surface via the global handlers / fail-loud below.
|
|
84
|
+
log: () => { },
|
|
57
85
|
});
|
|
58
86
|
let meshReady = false;
|
|
87
|
+
// When the mesh isn't joined, this explains why (folder busy / connecting), so
|
|
88
|
+
// the tools return something actionable instead of a generic "not connected".
|
|
89
|
+
let degradedReason = "connecting to the mesh…";
|
|
59
90
|
// ── MCP server setup ──────────────────────────────────────────────────────────
|
|
60
|
-
const mcp = new McpServer({ name: "remote-pi-mesh", version: "0.
|
|
91
|
+
const mcp = new McpServer({ name: "remote-pi-mesh", version: "0.4.3" }, {
|
|
61
92
|
capabilities: { experimental: { "claude/channel": {} } },
|
|
62
93
|
instructions: [
|
|
63
94
|
`You are connected to the remote-pi agent mesh as "${AGENT_NAME}".`,
|
|
@@ -65,12 +96,12 @@ const mcp = new McpServer({ name: "remote-pi-mesh", version: "0.2.1" }, {
|
|
|
65
96
|
"Use list_peers to discover available agents.",
|
|
66
97
|
"Use agent_send to send messages — use the exact peer name returned by list_peers.",
|
|
67
98
|
'Use "broadcast" as the target to send to all peers at once.',
|
|
68
|
-
"Follow the
|
|
99
|
+
"Follow the agent-network protocol (in your system prompt) for the full details (ACK statuses, replies via re, cross-PC <pc>:<peer> addressing).",
|
|
69
100
|
].join("\n"),
|
|
70
101
|
});
|
|
71
102
|
function notReady() {
|
|
72
103
|
return {
|
|
73
|
-
content: [{ type: "text", text:
|
|
104
|
+
content: [{ type: "text", text: `Mesh not available yet — ${degradedReason}` }],
|
|
74
105
|
isError: true,
|
|
75
106
|
};
|
|
76
107
|
}
|
|
@@ -108,7 +139,16 @@ mcp.registerTool("agent_send", {
|
|
|
108
139
|
}
|
|
109
140
|
const ack = await mesh.sendWithAck(to, body, re ?? null);
|
|
110
141
|
const note = ack.status === "received" ? `Delivered to ${ack.target ?? to}` :
|
|
111
|
-
|
|
142
|
+
// plan/34 removed busy-drop: the current broker NEVER returns `busy`. So
|
|
143
|
+
// if we still see it, the broker LEADER in this mesh is an out-of-date
|
|
144
|
+
// process (e.g. a long-running Pi/agent that leads the local broker and
|
|
145
|
+
// predates the new build) — and that old code DROPPED this message. Be
|
|
146
|
+
// honest: this was NOT delivered. Fix = restart the leader agent.
|
|
147
|
+
ack.status === "busy" ?
|
|
148
|
+
`NOT delivered — "${to}" came back BUSY, which only happens when an ` +
|
|
149
|
+
`OUT-OF-DATE broker leader dropped the message (busy was removed in the ` +
|
|
150
|
+
`current version). Restart the agent that leads the local broker (the ` +
|
|
151
|
+
`oldest Pi/remote-pi process) so it picks up the new build, then resend.` :
|
|
112
152
|
ack.status === "denied" ? `${to} denied the message` :
|
|
113
153
|
`No ACK from ${to} (timeout) — peer may be offline`;
|
|
114
154
|
return {
|
|
@@ -134,25 +174,36 @@ mcp.registerTool("get_messages", {
|
|
|
134
174
|
function isoNow() {
|
|
135
175
|
return new Date().toISOString();
|
|
136
176
|
}
|
|
177
|
+
// Background lock+join state. The cwd lock enforces the per-folder singleton
|
|
178
|
+
// (at most one remote-pi agent — Pi OR Claude — per folder; a second peer with
|
|
179
|
+
// the same cwd-derived name would be a ghost).
|
|
180
|
+
//
|
|
181
|
+
// We retry only briefly — just enough to ride out a restart RACE (the previous
|
|
182
|
+
// MCP for this folder is still tearing down when Claude respawns us). After a
|
|
183
|
+
// short grace we FAIL LOUD (exit non-zero) rather than degrade forever: a
|
|
184
|
+
// silent connected-but-idle MCP hides the real problem (you launched claude in
|
|
185
|
+
// the wrong folder, or this folder already has a live agent — a duplicate
|
|
186
|
+
// session). Failing makes Claude show the MCP as errored so you actually see it.
|
|
187
|
+
const JOIN_RETRY_MS = 2_000;
|
|
188
|
+
const MAX_JOIN_ATTEMPTS = 4; // ~6–8s grace for a restart race, then fail loud
|
|
189
|
+
let _lock = null;
|
|
190
|
+
let _lockRetryTimer = null;
|
|
191
|
+
let _lockAttempt = 0;
|
|
192
|
+
let _joined = false;
|
|
193
|
+
let _shuttingDown = false;
|
|
137
194
|
async function main() {
|
|
138
|
-
// Per-cwd singleton — same kernel-enforced UDS lock the Pi extension's
|
|
139
|
-
// `/remote-pi` takes (see cwd_lock.ts). At most one remote-pi agent (Pi OR
|
|
140
|
-
// Claude) may own a folder. Without this, a second MCP in the same cwd joins
|
|
141
|
-
// the global broker under the same cwd-derived name and the broker
|
|
142
|
-
// disambiguates it to `Name#2` — an unresponsive ghost peer. We acquire the
|
|
143
|
-
// lock BEFORE touching the mesh and hard-fail if refused: the process exits
|
|
144
|
-
// before connecting the stdio transport, so Claude Code surfaces this MCP as
|
|
145
|
-
// failed (the session keeps working, just without mesh tools).
|
|
146
|
-
const lock = await acquireCwdLock(_cwd);
|
|
147
|
-
if (!lock.ok) {
|
|
148
|
-
process.stderr.write(`[remote-pi-mesh] folder already owned by another remote-pi agent ` +
|
|
149
|
-
`(lock: ${lock.lockPath}). Refusing to start a duplicate mesh peer.\n`);
|
|
150
|
-
process.exit(1);
|
|
151
|
-
}
|
|
152
195
|
// Subscribe BEFORE connecting so we don't miss early envelopes. The
|
|
153
196
|
// SessionPeer swallows broker ACKs / system events itself, so handlers
|
|
154
197
|
// only see real peer messages (and replies, which carry `re`).
|
|
155
198
|
mesh.onMessage((env) => {
|
|
199
|
+
// plan/34 (passive presence): broker control/system envelopes
|
|
200
|
+
// (`peer_joined` / `peer_left` / `list_peers_reply`) are presence signals,
|
|
201
|
+
// NOT agent messages. Never push them to the inbox or the claude/channel —
|
|
202
|
+
// otherwise a peer joining/leaving would wake this agent's turn. Discovery
|
|
203
|
+
// is pull-based via `list_peers`. (Real broker ACKs and `re` replies are
|
|
204
|
+
// already swallowed upstream by SessionPeer.)
|
|
205
|
+
if (env.from === "broker" || env.from.endsWith(":broker"))
|
|
206
|
+
return;
|
|
156
207
|
const msg = {
|
|
157
208
|
from: env.from,
|
|
158
209
|
body: env.body,
|
|
@@ -168,37 +219,112 @@ async function main() {
|
|
|
168
219
|
params: { content: `📨 Message from ${msg.from}:\n${JSON.stringify(msg.body, null, 2)}` },
|
|
169
220
|
}).catch(() => { });
|
|
170
221
|
});
|
|
222
|
+
// Connect the stdio transport FIRST and unconditionally, so Claude Code
|
|
223
|
+
// always sees this server as connected and the tools stay reachable — even
|
|
224
|
+
// before (or entirely without) a mesh join. The mesh join is layered on
|
|
225
|
+
// best-effort below; a busy folder no longer kills the MCP.
|
|
226
|
+
const transport = new StdioServerTransport();
|
|
227
|
+
transport.onclose = shutdown;
|
|
228
|
+
process.stdin.on("end", shutdown);
|
|
229
|
+
process.stdin.on("close", shutdown);
|
|
230
|
+
await mcp.connect(transport);
|
|
231
|
+
// Only join the mesh if this folder is an actual remote-pi agent — i.e. it
|
|
232
|
+
// has a local config (written by the `remote-pi claude` wizard) or an
|
|
233
|
+
// explicit name override. `-s local` MCP registrations are inherited by
|
|
234
|
+
// EVERY claude session in the git repo, so without this gate a plain claude
|
|
235
|
+
// opened in any subfolder would auto-grab that folder's lock and join as a
|
|
236
|
+
// stray agent — colliding with the real agent. No config ⇒ stay connected
|
|
237
|
+
// but idle (tools report why); don't lock, don't join, don't retry.
|
|
238
|
+
if (localConfigExists(_cwd) || _nameOverride !== undefined) {
|
|
239
|
+
// Kick off the lock+join in the background. Never awaited — the MCP is
|
|
240
|
+
// already serving; mesh availability arrives (and recovers) asynchronously.
|
|
241
|
+
void tryJoinMesh();
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
degradedReason =
|
|
245
|
+
`this folder is not a remote-pi agent (no config). Run "remote-pi claude" ` +
|
|
246
|
+
`here to make it one. Mesh tools are idle.`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/** Acquire the per-cwd lock, then join the mesh. Retries briefly to absorb a
|
|
250
|
+
* restart race; if the lock or join still fails after MAX_JOIN_ATTEMPTS, FAIL
|
|
251
|
+
* LOUD (exit) so the failure is visible instead of silently degrading. */
|
|
252
|
+
async function tryJoinMesh() {
|
|
253
|
+
if (_joined || _shuttingDown)
|
|
254
|
+
return;
|
|
255
|
+
const res = await acquireCwdLock(_cwd);
|
|
256
|
+
if (!res.ok) {
|
|
257
|
+
_lockAttempt++;
|
|
258
|
+
if (_lockAttempt >= MAX_JOIN_ATTEMPTS) {
|
|
259
|
+
_failLoud(`folder already served by another remote-pi agent (lock: ${res.lockPath})`);
|
|
260
|
+
}
|
|
261
|
+
degradedReason = `folder busy (lock ${res.lockPath}); attempt ${_lockAttempt}/${MAX_JOIN_ATTEMPTS}`;
|
|
262
|
+
_scheduleJoinRetry(JOIN_RETRY_MS);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
_lock = res;
|
|
171
266
|
try {
|
|
172
267
|
await mesh.connect();
|
|
173
268
|
meshReady = true;
|
|
269
|
+
_joined = true;
|
|
270
|
+
_lockAttempt = 0;
|
|
174
271
|
}
|
|
175
272
|
catch (e) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
// socket (and, when leader, a relay WS) open, so without this the process
|
|
180
|
-
// would linger forever after Claude exits — orphaning the mesh peer (it
|
|
181
|
-
// keeps showing "online" with nothing actually attached). We leave the
|
|
182
|
-
// mesh, then exit. Triggered by either the MCP transport closing or stdin
|
|
183
|
-
// hitting EOF (whichever the host does first).
|
|
184
|
-
let shuttingDown = false;
|
|
185
|
-
const shutdown = () => {
|
|
186
|
-
if (shuttingDown)
|
|
187
|
-
return;
|
|
188
|
-
shuttingDown = true;
|
|
273
|
+
// Got the lock but the broker join failed (e.g. socket churn). Release the
|
|
274
|
+
// lock so another contender isn't starved, then retry / fail loud.
|
|
275
|
+
_lockAttempt++;
|
|
189
276
|
try {
|
|
190
|
-
|
|
277
|
+
_lock.release();
|
|
191
278
|
}
|
|
192
|
-
catch { /*
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
279
|
+
catch { /* best-effort */ }
|
|
280
|
+
_lock = null;
|
|
281
|
+
if (_lockAttempt >= MAX_JOIN_ATTEMPTS) {
|
|
282
|
+
_failLoud(`mesh join failed: ${String(e)}`);
|
|
283
|
+
}
|
|
284
|
+
degradedReason = `mesh join failed (attempt ${_lockAttempt}/${MAX_JOIN_ATTEMPTS}): ${String(e)}`;
|
|
285
|
+
_scheduleJoinRetry(JOIN_RETRY_MS);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
function _scheduleJoinRetry(delayMs) {
|
|
289
|
+
if (_lockRetryTimer || _joined || _shuttingDown)
|
|
290
|
+
return;
|
|
291
|
+
const t = setTimeout(() => {
|
|
292
|
+
_lockRetryTimer = null;
|
|
293
|
+
void tryJoinMesh();
|
|
294
|
+
}, delayMs);
|
|
295
|
+
// Don't let the retry timer alone keep the process alive past stdin close.
|
|
296
|
+
t.unref?.();
|
|
297
|
+
_lockRetryTimer = t;
|
|
298
|
+
}
|
|
299
|
+
/** Exit non-zero with a loud, specific reason so Claude surfaces the MCP as
|
|
300
|
+
* errored (visible) instead of a silent connected-but-idle peer. */
|
|
301
|
+
function _failLoud(reason) {
|
|
302
|
+
logErr(`FATAL: ${reason}. Exiting so the failure is visible. cwd=${_cwd}. ` +
|
|
303
|
+
`Most likely you launched claude in the WRONG FOLDER, or this folder ` +
|
|
304
|
+
`already has a running remote-pi agent (a duplicate session). ` +
|
|
305
|
+
`Launch one agent per folder via "remote-pi claude" from the project dir.`);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
// Exit cleanly when Claude Code disconnects. The MeshNode keeps a UDS socket
|
|
309
|
+
// (and, when leader, a relay WS) open, so without this the process would linger
|
|
310
|
+
// after Claude exits — orphaning the mesh peer (it keeps showing "online" with
|
|
311
|
+
// nothing attached). We leave the mesh, then exit. Triggered by the MCP
|
|
312
|
+
// transport closing or stdin hitting EOF (whichever the host does first).
|
|
313
|
+
function shutdown() {
|
|
314
|
+
if (_shuttingDown)
|
|
315
|
+
return;
|
|
316
|
+
_shuttingDown = true;
|
|
317
|
+
if (_lockRetryTimer) {
|
|
318
|
+
clearTimeout(_lockRetryTimer);
|
|
319
|
+
_lockRetryTimer = null;
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
_lock?.release();
|
|
323
|
+
}
|
|
324
|
+
catch { /* OS frees the UDS lock on exit anyway */ }
|
|
325
|
+
void Promise.resolve(mesh.close())
|
|
326
|
+
.catch(() => { })
|
|
327
|
+
.finally(() => process.exit(0));
|
|
202
328
|
}
|
|
203
329
|
main().catch((err) => {
|
|
204
330
|
process.stderr.write(`[remote-pi-mesh] fatal: ${String(err)}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh_server.js","sourceRoot":"","sources":["../../src/mcp/mesh_server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,iFAAiF;AAEjF,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AAC7D,IAAI,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACtD,IAAI,cAAc,GAAG,IAAI,CAAC;AAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACtC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAE,CAAC;IAAC,CAAC;SAC5D,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAAC,aAAa,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAAC,CAAC;SAC1E,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;QAAC,cAAc,GAAG,KAAK,CAAC;IAAC,CAAC;AAClE,CAAC;AAED,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;AACnC,MAAM,UAAU,GAAG,aAAa,IAAI,IAAI,CAAC,UAAU,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC9E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AACzF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AAYxF,MAAM,KAAK,GAAkB,EAAE,CAAC;AAEhC,iFAAiF;AAEjF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;AAE5C,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC;IACxB,QAAQ,EAAE,WAAW;IACrB,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,UAAU;IACrB,yEAAyE;IACzE,qEAAqE;IACrE,+DAA+D;IAC/D,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,GAAG,EAAE,CAAC,IAAY,EAAQ,EAAE,GAA0C,CAAC;CACxE,CAAC,CAAC;AAEH,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,iFAAiF;AAEjF,MAAM,GAAG,GAAG,IAAI,SAAS,CACvB,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC5C;IACE,YAAY,EAAE,EAAE,YAAY,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE;IACxD,YAAY,EAAE;QACZ,qDAAqD,UAAU,IAAI;QACnE,+FAA+F;QAC/F,8CAA8C;QAC9C,mFAAmF;QACnF,6DAA6D;QAC7D,yHAAyH;KAC1H,CAAC,IAAI,CAAC,IAAI,CAAC;CACb,CACF,CAAC;AAEF,SAAS,QAAQ;IACf,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAC;QAC7G,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE;IAC7B,WAAW,EAAE,6DAA6D;IAC1E,WAAW,EAAE,EAAE;CAChB,EAAE,KAAK,IAAI,EAAE;IACZ,IAAI,CAAC,SAAS;QAAE,OAAO,QAAQ,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC;IAC5G,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sBAAsB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1G,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE;IAC7B,WAAW,EAAE,wEAAwE;IACrF,WAAW,EAAE;QACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2EAA2E,CAAC;QACpG,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QAC3D,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;KACtF;CACF,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE;IAC5B,IAAI,CAAC,SAAS;QAAE,OAAO,QAAQ,EAAE,CAAC;IAClC,IAAI,EAAE,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAClG,CAAC;IACD,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,WAAW,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;YACtC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;QAC1E,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;QACzD,MAAM,IAAI,GACR,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;YAChE,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,oDAAoD,CAAC,CAAC;gBACnF,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;oBACtD,eAAe,EAAE,kCAAkC,CAAC;QACtD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAChD,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;SACxD,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gBAAgB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACpG,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,YAAY,CAAC,cAAc,EAAE;IAC/B,WAAW,EAAE,mGAAmG;IAChH,WAAW,EAAE,EAAE;CAChB,EAAE,KAAK,IAAI,EAAE;IACZ,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IAC9F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3B,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CACvG,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5E,CAAC,CAAC,CAAC;AAEH,iFAAiF;AAEjF,SAAS,MAAM;IACb,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,uEAAuE;IACvE,2EAA2E;IAC3E,6EAA6E;IAC7E,mEAAmE;IACnE,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,+DAA+D;IAC/D,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mEAAmE;YACnE,UAAU,IAAI,CAAC,QAAQ,+CAA+C,CACvE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oEAAoE;IACpE,uEAAuE;IACvE,+DAA+D;IAC/D,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;QACrB,MAAM,GAAG,GAAgB;YACvB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,EAAE,EAAE,MAAM,EAAE;SACb,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,wEAAwE;QACxE,oFAAoF;QACpF,KAAK,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;YAC3B,MAAM,EAAE,8BAA8B;YACtC,MAAM,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,CAAC,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;SAC1F,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAA+D,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAED,sEAAsE;IACtE,0EAA0E;IAC1E,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,+CAA+C;IAC/C,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC;YAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,0CAA0C,CAAC,CAAC;QAC5E,KAAK,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;aAC/B,KAAK,CAAC,GAAG,EAAE,GAAqB,CAAC,CAAC;aAClC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,SAAS,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACpC,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"mesh_server.js","sourceRoot":"","sources":["../../src/mcp/mesh_server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mesh addressing for plan/35 (malha direta). An "agent" ≡ a cwd (cwd_lock
|
|
3
|
+
* guarantees at most one Pi per folder), so the folder *is* the address:
|
|
4
|
+
*
|
|
5
|
+
* - **local** → an absolute path on this machine. A local peer is reached by
|
|
6
|
+
* `POST`ing its inbox socket directly (see `apiSockPath`).
|
|
7
|
+
* - **remote** → `<label>:/path`, where `<label>` names a sibling machine
|
|
8
|
+
* (resolved to a pubkey via `mesh_versions`/siblings in Wave C) and `/path`
|
|
9
|
+
* is the folder on that machine. Routed cross-PC through the relay.
|
|
10
|
+
*
|
|
11
|
+
* The address an agent passes is ALWAYS the absolute folder path; the `.sock`
|
|
12
|
+
* file itself lives OUTSIDE the cwd (decisão fixada — "Transporte local"). The
|
|
13
|
+
* folder is hashed to the file name, so the mapping is deterministic and both
|
|
14
|
+
* the inbox (its own socket) and a sender (the peer's socket) land on the same
|
|
15
|
+
* file without coordinating.
|
|
16
|
+
*
|
|
17
|
+
* Wave 0 only *parses* what it is handed — contacts (known routes) live in the
|
|
18
|
+
* agent's context/CLAUDE.md (decisão Q5), not in an allowlist module. The
|
|
19
|
+
* `<label>→pubkey` resolution and remote send arrive in Wave C; here we keep
|
|
20
|
+
* the parser and the local route→socket mapping.
|
|
21
|
+
*/
|
|
22
|
+
export type Address = {
|
|
23
|
+
kind: "local";
|
|
24
|
+
path: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "remote";
|
|
27
|
+
label: string;
|
|
28
|
+
path: string;
|
|
29
|
+
};
|
|
30
|
+
export declare class AddressError extends Error {
|
|
31
|
+
constructor(message: string);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parses a mesh address. A `:` separates a remote `<label>` from its `/path`;
|
|
35
|
+
* with no `:` the whole string is a local absolute path (decisão fixada:
|
|
36
|
+
* "Sem ':' → local"). Both the local path and the remote path must be
|
|
37
|
+
* absolute — the folder is the canonical route.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseAddress(raw: string): Address;
|
|
40
|
+
/**
|
|
41
|
+
* The inbox socket path for a folder. Single source of truth shared by the
|
|
42
|
+
* inbox server (its own socket) and the send client (a local peer's socket).
|
|
43
|
+
*
|
|
44
|
+
* `~/.pi/remote-pi/socks/<roomId>.sock`, where `roomId = roomIdForCwd(folder)`
|
|
45
|
+
* (`sha256(realpath(folder))[:12]` — the same hash `cwd_lock` uses). The folder
|
|
46
|
+
* is the address; the hash is only the file name. `realpath` canonicalization
|
|
47
|
+
* means `/a` and a symlink to `/a` map to the same socket.
|
|
48
|
+
*/
|
|
49
|
+
export declare function apiSockPath(folderPath: string): string;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { isAbsolute, join } from "node:path";
|
|
3
|
+
import { roomIdForCwd } from "../rooms.js";
|
|
4
|
+
export class AddressError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "AddressError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parses a mesh address. A `:` separates a remote `<label>` from its `/path`;
|
|
12
|
+
* with no `:` the whole string is a local absolute path (decisão fixada:
|
|
13
|
+
* "Sem ':' → local"). Both the local path and the remote path must be
|
|
14
|
+
* absolute — the folder is the canonical route.
|
|
15
|
+
*/
|
|
16
|
+
export function parseAddress(raw) {
|
|
17
|
+
const trimmed = raw.trim();
|
|
18
|
+
if (!trimmed)
|
|
19
|
+
throw new AddressError("empty address");
|
|
20
|
+
const colon = trimmed.indexOf(":");
|
|
21
|
+
if (colon === -1) {
|
|
22
|
+
if (!isAbsolute(trimmed)) {
|
|
23
|
+
throw new AddressError(`local address must be an absolute path: ${trimmed}`);
|
|
24
|
+
}
|
|
25
|
+
return { kind: "local", path: trimmed };
|
|
26
|
+
}
|
|
27
|
+
const label = trimmed.slice(0, colon);
|
|
28
|
+
const path = trimmed.slice(colon + 1);
|
|
29
|
+
if (!label)
|
|
30
|
+
throw new AddressError(`remote address missing label: ${trimmed}`);
|
|
31
|
+
if (!path)
|
|
32
|
+
throw new AddressError(`remote address missing path: ${trimmed}`);
|
|
33
|
+
if (!isAbsolute(path)) {
|
|
34
|
+
throw new AddressError(`remote address path must be absolute: ${trimmed}`);
|
|
35
|
+
}
|
|
36
|
+
return { kind: "remote", label, path };
|
|
37
|
+
}
|
|
38
|
+
/** Directory holding inbox sockets, resolved at call time (not module load) so
|
|
39
|
+
* tests can redirect it via `REMOTE_PI_HOME` — the same override `cwd_lock`
|
|
40
|
+
* honors. Kept OUT of the cwd: `sun_path` is capped at 104 chars on macOS
|
|
41
|
+
* (EINVAL at ≥105), so a socket nested inside a deep cwd would overflow. */
|
|
42
|
+
function socksDir() {
|
|
43
|
+
const root = process.env["REMOTE_PI_HOME"] || homedir();
|
|
44
|
+
return join(root, ".pi", "remote-pi", "socks");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The inbox socket path for a folder. Single source of truth shared by the
|
|
48
|
+
* inbox server (its own socket) and the send client (a local peer's socket).
|
|
49
|
+
*
|
|
50
|
+
* `~/.pi/remote-pi/socks/<roomId>.sock`, where `roomId = roomIdForCwd(folder)`
|
|
51
|
+
* (`sha256(realpath(folder))[:12]` — the same hash `cwd_lock` uses). The folder
|
|
52
|
+
* is the address; the hash is only the file name. `realpath` canonicalization
|
|
53
|
+
* means `/a` and a symlink to `/a` map to the same socket.
|
|
54
|
+
*/
|
|
55
|
+
export function apiSockPath(folderPath) {
|
|
56
|
+
return join(socksDir(), `${roomIdForCwd(folderPath)}.sock`);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/session/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA4B3C,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,eAAe,CAAC,CAAC;IAEtD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;QACjB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,YAAY,CAAC,2CAA2C,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC1C,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,YAAY,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;IAC/E,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,YAAY,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,YAAY,CAAC,yCAAyC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC;AAED;;;6EAG6E;AAC7E,SAAS,QAAQ;IACf,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,OAAO,EAAE,CAAC;IACxD,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,OAAO,IAAI,CAAC,QAAQ,EAAE,EAAE,GAAG,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/session/broker.d.ts
CHANGED
|
@@ -8,26 +8,25 @@ import { type Envelope } from "./envelope.js";
|
|
|
8
8
|
* Auto-suffix on name collision: when a peer registers a name already taken,
|
|
9
9
|
* the broker assigns `<name>#N` and returns it in the register ack.
|
|
10
10
|
*
|
|
11
|
-
* ## ACK protocol (plan/25 Wave 0)
|
|
11
|
+
* ## ACK protocol (plan/25 Wave 0; reliable delivery per plan/34)
|
|
12
12
|
*
|
|
13
13
|
* For **unicast non-broker** envelopes the broker synchronously emits an ACK
|
|
14
|
-
* envelope back to the sender
|
|
14
|
+
* envelope back to the sender once it has delivered:
|
|
15
15
|
*
|
|
16
|
-
* - target
|
|
17
|
-
* -
|
|
16
|
+
* - target online → deliver envelope, ACK `received`
|
|
17
|
+
* - no such peer → silent drop (sender times out)
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* the two.
|
|
19
|
+
* plan/34 removed the busy-drop: a message that arrives while the target is
|
|
20
|
+
* mid-turn is **always delivered**, never dropped. The Pi harness
|
|
21
|
+
* (`sendMessage(triggerTurn:true)`) enqueues mid-turn messages and processes
|
|
22
|
+
* them in the upcoming turn, so the broker needs no busy gate or mailbox.
|
|
23
|
+
* Consequently `busy` is no longer a possible ACK status for unicast new
|
|
24
|
+
* work — the sender always gets `received`. (Turn-lifecycle / working
|
|
25
|
+
* indicators live in `index.ts` via room_meta over the relay, not here.)
|
|
27
26
|
*
|
|
28
27
|
* Broadcast/multicast/broker-addressed envelopes are not ACKed (no single
|
|
29
28
|
* authoritative recipient or no semantic match). The audit log carries the
|
|
30
|
-
* ACK status (`received |
|
|
29
|
+
* ACK status (`received | denied | none`) per envelope.
|
|
31
30
|
*/
|
|
32
31
|
export interface BrokerOptions {
|
|
33
32
|
server: Server;
|
|
@@ -56,13 +55,11 @@ export interface RemoteRouter {
|
|
|
56
55
|
listRemotePeers(): string[];
|
|
57
56
|
}
|
|
58
57
|
/** Local outcome of a cross-PC envelope injection. broker_remote uses this
|
|
59
|
-
* to construct the ACK envelope it sends back via the relay.
|
|
60
|
-
|
|
58
|
+
* to construct the ACK envelope it sends back via the relay. plan/34: `busy`
|
|
59
|
+
* is gone — injection always delivers when the peer exists. */
|
|
60
|
+
export type RemoteInjectStatus = "received" | "denied";
|
|
61
61
|
export declare class Broker {
|
|
62
62
|
private readonly peers;
|
|
63
|
-
/** Peers whose wrapper has signaled they are mid-turn, or to whom the
|
|
64
|
-
* broker has just delivered an envelope (received = commitment). */
|
|
65
|
-
private readonly busyPeers;
|
|
66
63
|
private readonly auditPath?;
|
|
67
64
|
private readonly onRouted?;
|
|
68
65
|
private readonly server;
|
|
@@ -79,10 +76,9 @@ export declare class Broker {
|
|
|
79
76
|
*
|
|
80
77
|
* Returns the ACK status so the caller (broker_remote) can pack and
|
|
81
78
|
* forward an ACK envelope back across the relay:
|
|
82
|
-
* - `received` — target
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* - `busy` — target mid-turn, envelope dropped
|
|
79
|
+
* - `received` — target exists, envelope delivered (plan/34: always
|
|
80
|
+
* delivered when the peer is online — the Pi harness enqueues mid-turn
|
|
81
|
+
* messages, so there is no busy-drop)
|
|
86
82
|
* - `denied` — no such local peer (or write failed) — caller maps to
|
|
87
83
|
* transport_error or denied ACK as it sees fit
|
|
88
84
|
*/
|
package/dist/session/broker.js
CHANGED
|
@@ -4,9 +4,6 @@ import { parse, serialize, uuidv7, EnvelopeError } from "./envelope.js";
|
|
|
4
4
|
const BROKER_NAME = "broker";
|
|
5
5
|
export class Broker {
|
|
6
6
|
peers = new Map();
|
|
7
|
-
/** Peers whose wrapper has signaled they are mid-turn, or to whom the
|
|
8
|
-
* broker has just delivered an envelope (received = commitment). */
|
|
9
|
-
busyPeers = new Set();
|
|
10
7
|
auditPath;
|
|
11
8
|
onRouted;
|
|
12
9
|
server;
|
|
@@ -30,10 +27,9 @@ export class Broker {
|
|
|
30
27
|
*
|
|
31
28
|
* Returns the ACK status so the caller (broker_remote) can pack and
|
|
32
29
|
* forward an ACK envelope back across the relay:
|
|
33
|
-
* - `received` — target
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* - `busy` — target mid-turn, envelope dropped
|
|
30
|
+
* - `received` — target exists, envelope delivered (plan/34: always
|
|
31
|
+
* delivered when the peer is online — the Pi harness enqueues mid-turn
|
|
32
|
+
* messages, so there is no busy-drop)
|
|
37
33
|
* - `denied` — no such local peer (or write failed) — caller maps to
|
|
38
34
|
* transport_error or denied ACK as it sees fit
|
|
39
35
|
*/
|
|
@@ -46,13 +42,6 @@ export class Broker {
|
|
|
46
42
|
const peer = this.peers.get(targetName);
|
|
47
43
|
if (!peer)
|
|
48
44
|
return "denied";
|
|
49
|
-
// Replies (re != null) bypass the busy gate (plan/25 Wave 0 rule —
|
|
50
|
-
// replies resolve pending state, not new LLM turns).
|
|
51
|
-
const isReply = env.re !== null;
|
|
52
|
-
if (!isReply && this.busyPeers.has(targetName)) {
|
|
53
|
-
void this._appendAudit(env, [], "busy", "relay");
|
|
54
|
-
return "busy";
|
|
55
|
-
}
|
|
56
45
|
const line = serialize(env);
|
|
57
46
|
try {
|
|
58
47
|
peer.socket.write(line);
|
|
@@ -60,8 +49,6 @@ export class Broker {
|
|
|
60
49
|
catch {
|
|
61
50
|
return "denied";
|
|
62
51
|
}
|
|
63
|
-
if (!isReply)
|
|
64
|
-
this.busyPeers.add(targetName);
|
|
65
52
|
void this._appendAudit(env, [targetName], "received", "relay");
|
|
66
53
|
this.onRouted?.(env, [targetName]);
|
|
67
54
|
return "received";
|
|
@@ -74,7 +61,6 @@ export class Broker {
|
|
|
74
61
|
for (const p of this.peers.values())
|
|
75
62
|
p.socket.destroy();
|
|
76
63
|
this.peers.clear();
|
|
77
|
-
this.busyPeers.clear();
|
|
78
64
|
await new Promise((resolve) => this.server.close(() => resolve()));
|
|
79
65
|
}
|
|
80
66
|
// ── connection lifecycle ──────────────────────────────────────────────────
|
|
@@ -158,7 +144,6 @@ export class Broker {
|
|
|
158
144
|
if (!conn.name)
|
|
159
145
|
return;
|
|
160
146
|
this.peers.delete(conn.name);
|
|
161
|
-
this.busyPeers.delete(conn.name);
|
|
162
147
|
this._broadcastSystem({ type: "peer_left", name: conn.name }, conn.name);
|
|
163
148
|
}
|
|
164
149
|
// ── routing ───────────────────────────────────────────────────────────────
|
|
@@ -181,38 +166,19 @@ export class Broker {
|
|
|
181
166
|
const delivered = [];
|
|
182
167
|
const line = serialize(env);
|
|
183
168
|
const isUnicast = typeof env.to === "string" && env.to !== "broadcast";
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
// "received = commitment" semantics.
|
|
189
|
-
const isReply = env.re !== null;
|
|
190
|
-
// Synchronous block — Node's single-threaded loop gives atomicity between
|
|
191
|
-
// busy-check and busy-mark (no await between them). Multiple deliveries in
|
|
192
|
-
// the same `for` iteration may interleave with another peer's writes only
|
|
193
|
-
// at await points; the busy-set transition itself is atomic.
|
|
169
|
+
// plan/34: reliable delivery — always write to the target's socket. The
|
|
170
|
+
// Pi harness enqueues messages that arrive mid-turn, so there is no
|
|
171
|
+
// busy-drop and `busy` is no longer a possible ACK status. Unicast sends
|
|
172
|
+
// to an online peer always ACK `received`.
|
|
194
173
|
let ackStatus = "none";
|
|
195
174
|
for (const targetName of targets) {
|
|
196
175
|
const peer = this.peers.get(targetName);
|
|
197
176
|
if (!peer)
|
|
198
177
|
continue; // unknown peer: silent drop (sender times out)
|
|
199
|
-
if (isUnicast && !isReply && this.busyPeers.has(targetName)) {
|
|
200
|
-
// New work for a busy peer → drop + ACK busy. Audit logged below
|
|
201
|
-
// captures the rejection via `ackStatus = "busy"` + delivered=[].
|
|
202
|
-
ackStatus = "busy";
|
|
203
|
-
this._sendAckToSender(env, "busy", targetName);
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
206
178
|
try {
|
|
207
179
|
peer.socket.write(line);
|
|
208
180
|
delivered.push(targetName);
|
|
209
181
|
if (isUnicast) {
|
|
210
|
-
if (!isReply) {
|
|
211
|
-
// "received = commitment" for new work: peer now owns this
|
|
212
|
-
// envelope and will process it in its upcoming turn. Wrapper's
|
|
213
|
-
// turn_end clears the busy flag.
|
|
214
|
-
this.busyPeers.add(targetName);
|
|
215
|
-
}
|
|
216
182
|
ackStatus = "received";
|
|
217
183
|
this._sendAckToSender(env, "received", targetName);
|
|
218
184
|
}
|
|
@@ -286,16 +252,9 @@ export class Broker {
|
|
|
286
252
|
}
|
|
287
253
|
return;
|
|
288
254
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// someone else's busy state.
|
|
293
|
-
if (body.busy)
|
|
294
|
-
this.busyPeers.add(env.from);
|
|
295
|
-
else
|
|
296
|
-
this.busyPeers.delete(env.from);
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
255
|
+
// plan/34: `turn_state` is no longer consumed — the broker doesn't gate
|
|
256
|
+
// delivery on busy state. The Pi extension still publishes working state
|
|
257
|
+
// as room_meta over the relay (index.ts), independent of the broker.
|
|
299
258
|
}
|
|
300
259
|
_broadcastSystem(body, excludeName) {
|
|
301
260
|
for (const [name, peer] of this.peers) {
|