agent-comms 3.11.0 → 3.13.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -1
- package/dist/bridges/cc-peer/front-controller.d.ts +20 -0
- package/dist/bridges/cc-peer/front-controller.d.ts.map +1 -1
- package/dist/bridges/cc-peer/front-controller.js +12 -0
- package/dist/bridges/cc-peer/front-controller.js.map +1 -1
- package/dist/bridges/cc-peer/front-relay.d.ts +11 -1
- package/dist/bridges/cc-peer/front-relay.d.ts.map +1 -1
- package/dist/bridges/cc-peer/front-relay.js +35 -4
- package/dist/bridges/cc-peer/front-relay.js.map +1 -1
- package/dist/bridges/cc-peer/front-runtime.d.ts.map +1 -1
- package/dist/bridges/cc-peer/front-runtime.js +20 -0
- package/dist/bridges/cc-peer/front-runtime.js.map +1 -1
- package/dist/bridges/cc-peer/reply-aliases.d.ts +22 -0
- package/dist/bridges/cc-peer/reply-aliases.d.ts.map +1 -0
- package/dist/bridges/cc-peer/reply-aliases.js +56 -0
- package/dist/bridges/cc-peer/reply-aliases.js.map +1 -0
- package/dist/core/bridge-mesh.d.ts.map +1 -1
- package/dist/core/bridge-mesh.js +1 -1
- package/dist/core/bridge-mesh.js.map +1 -1
- package/dist/core/bridge.d.ts +4 -0
- package/dist/core/bridge.d.ts.map +1 -1
- package/dist/core/bridge.js +15 -0
- package/dist/core/bridge.js.map +1 -1
- package/dist/core/gateway-trust.d.ts +25 -0
- package/dist/core/gateway-trust.d.ts.map +1 -0
- package/dist/core/gateway-trust.js +26 -0
- package/dist/core/gateway-trust.js.map +1 -0
- package/dist/core/hub-forwarding.d.ts +7 -5
- package/dist/core/hub-forwarding.d.ts.map +1 -1
- package/dist/core/hub-forwarding.js +13 -6
- package/dist/core/hub-forwarding.js.map +1 -1
- package/dist/core/hub-session.d.ts +5 -1
- package/dist/core/hub-session.d.ts.map +1 -1
- package/dist/core/hub-session.js +20 -5
- package/dist/core/hub-session.js.map +1 -1
- package/dist/core/listener-registry.d.ts +25 -0
- package/dist/core/listener-registry.d.ts.map +1 -0
- package/dist/core/listener-registry.js +52 -0
- package/dist/core/listener-registry.js.map +1 -0
- package/dist/core/mesh-store.d.ts +9 -0
- package/dist/core/mesh-store.d.ts.map +1 -1
- package/dist/core/mesh-store.js +18 -0
- package/dist/core/mesh-store.js.map +1 -1
- package/dist/core/tool.d.ts +6 -0
- package/dist/core/tool.d.ts.map +1 -1
- package/dist/core/tool.js +51 -0
- package/dist/core/tool.js.map +1 -1
- package/dist/core/types.d.ts +16 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/wire-mesh-transport.d.ts +6 -5
- package/dist/core/wire-mesh-transport.d.ts.map +1 -1
- package/dist/core/wire-mesh-transport.js +21 -44
- package/dist/core/wire-mesh-transport.js.map +1 -1
- package/dist/test/cc-peer-front-controller.test.js +61 -0
- package/dist/test/cc-peer-front-controller.test.js.map +1 -1
- package/dist/test/cc-peer-front-relay.test.js +161 -2
- package/dist/test/cc-peer-front-relay.test.js.map +1 -1
- package/dist/test/cc-peer-reply-aliases.test.d.ts +2 -0
- package/dist/test/cc-peer-reply-aliases.test.d.ts.map +1 -0
- package/dist/test/cc-peer-reply-aliases.test.js +93 -0
- package/dist/test/cc-peer-reply-aliases.test.js.map +1 -0
- package/dist/test/gateway-forwarding.integration.test.d.ts +2 -0
- package/dist/test/gateway-forwarding.integration.test.d.ts.map +1 -1
- package/dist/test/gateway-forwarding.integration.test.js +11 -0
- package/dist/test/gateway-forwarding.integration.test.js.map +1 -1
- package/dist/test/gateway-trust-tool.test.d.ts +2 -0
- package/dist/test/gateway-trust-tool.test.d.ts.map +1 -0
- package/dist/test/gateway-trust-tool.test.js +120 -0
- package/dist/test/gateway-trust-tool.test.js.map +1 -0
- package/dist/test/gateway-trust.integration.test.d.ts +5 -0
- package/dist/test/gateway-trust.integration.test.d.ts.map +1 -0
- package/dist/test/gateway-trust.integration.test.js +143 -0
- package/dist/test/gateway-trust.integration.test.js.map +1 -0
- package/dist/test/gateway-trust.test.d.ts +2 -0
- package/dist/test/gateway-trust.test.d.ts.map +1 -0
- package/dist/test/gateway-trust.test.js +60 -0
- package/dist/test/gateway-trust.test.js.map +1 -0
- package/dist/test/hub-forwarding.test.d.ts +2 -0
- package/dist/test/hub-forwarding.test.d.ts.map +1 -0
- package/dist/test/hub-forwarding.test.js +62 -0
- package/dist/test/hub-forwarding.test.js.map +1 -0
- package/dist/test/hub-mode-session.integration.test.js +25 -10
- package/dist/test/hub-mode-session.integration.test.js.map +1 -1
- package/dist/test/test-transport.d.ts.map +1 -1
- package/dist/test/test-transport.js +1 -1
- package/dist/test/test-transport.js.map +1 -1
- package/dist/test/wire-mesh-transport-gateway-trust.test.d.ts +2 -0
- package/dist/test/wire-mesh-transport-gateway-trust.test.d.ts.map +1 -0
- package/dist/test/wire-mesh-transport-gateway-trust.test.js +50 -0
- package/dist/test/wire-mesh-transport-gateway-trust.test.js.map +1 -0
- package/dist/test/wire-mesh-transport.test.js +1 -11
- package/dist/test/wire-mesh-transport.test.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ExaDev/agent-comms)
|
|
4
4
|
[](https://www.npmjs.com/package/agent-comms)
|
|
5
|
-
[](https://github.com/ExaDev/agent-comms/releases/tag/v3.13.0)
|
|
6
6
|
[](https://github.com/ExaDev/agent-comms/actions)
|
|
7
7
|
|
|
8
8
|
Cross-harness communication mesh for LLM agents: rooms, DMs, presence, and visibility over TCP with zero filesystem dependencies.
|
|
@@ -157,6 +157,8 @@ One bridge process relays for exactly one local Claude Code session, the same "o
|
|
|
157
157
|
|
|
158
158
|
A Claude Code session with no agent-comms bridge of its own is still reachable from the mesh: whichever bridge on the machine currently holds the mesh coordinator role fronts every local session it discovers via `cc-peer`'s own roster, using the same `(harness, cwd)` identity slot that session's own `claude-code` bridge would use if it started. Identity belongs to the slot, not to whichever process is currently serving it — the session's own bridge holds the slot when it's live; the front holds it otherwise, and yields the moment a real bridge for that slot appears, so addressing, room membership, and queued deliveries all carry over unchanged across the transition. No configuration is needed: every bridge in this repo wires the front to its own coordinator-role transitions automatically, and a machine with no local Claude Code sessions (or no `cc-peer` sockets at all) runs it as a clean no-op.
|
|
159
159
|
|
|
160
|
+
The fronted session can reply, not just receive. A message with a single originating mesh agent (a DM or a room message) materialises a lazy, per-correspondent reply alias via `cc-peer`'s own `AliasPool` (the `cc-peer/alias-pool` subpath) — a real, natively-discoverable local peer the session can address the way it addresses any other local `cc-peer` peer. Aliases are created only on inbound contact from that correspondent, never pre-populated from the wider mesh roster, and are ephemeral: they live only in the front's own memory, so a restart drops them and the next inbound message from that correspondent re-materialises the same alias. A reply landing on an alias the front no longer recognises (e.g. after a restart) is reported back into the session as a clear error rather than silently dropped.
|
|
161
|
+
|
|
160
162
|
## Adding a new harness
|
|
161
163
|
|
|
162
164
|
A bridge is two things:
|
|
@@ -16,6 +16,18 @@ export interface FrontedSessionRecord {
|
|
|
16
16
|
fromName?: string;
|
|
17
17
|
body: string;
|
|
18
18
|
}>) => void;
|
|
19
|
+
/** Routes a reply arriving on one of this session's own reply aliases into a mesh DM addressed to the correspondent that alias stands for, sent as this session's own device-id (agent-comms#158) -- the session-to-mesh direction for lazy per-correspondent aliases. Only called once handleAliasMessage has already resolved the alias to a known correspondent; a stale alias goes to notifyStaleAlias instead. */
|
|
20
|
+
readonly handleAliasReply: (correspondentId: string, message: Readonly<{
|
|
21
|
+
from?: string;
|
|
22
|
+
fromName?: string;
|
|
23
|
+
body: string;
|
|
24
|
+
}>) => void;
|
|
25
|
+
/** Delivers a clear error back into this session when a reply arrives on an alias the directory no longer maps to any correspondent -- e.g. after a front restart, since reply aliases are ephemeral by design -- rather than silently dropping the reply. */
|
|
26
|
+
readonly notifyStaleAlias: (aliasName: string) => void;
|
|
27
|
+
}
|
|
28
|
+
/** The narrow slice of ReplyAliasDirectory (reply-aliases.ts) CcPeerFront needs to resolve an inbound alias message's own correspondent -- narrowed rather than importing the class directly so front-controller.ts stays free of any construction concern, matching probeSlotOwner's own injected-function convention. */
|
|
29
|
+
export interface CcPeerFrontAliasDirectory {
|
|
30
|
+
correspondentFor: (aliasName: string) => string | undefined;
|
|
19
31
|
}
|
|
20
32
|
export interface CcPeerFrontDeps<TRecord extends FrontedSessionRecord> {
|
|
21
33
|
/** Enumerates the current local cc-peer roster. Rejects propagate to onError rather than throwing out of the poll timer. */
|
|
@@ -26,6 +38,8 @@ export interface CcPeerFrontDeps<TRecord extends FrontedSessionRecord> {
|
|
|
26
38
|
attach: (entry: Readonly<CcPeerRosterEntryLike>) => Promise<TRecord>;
|
|
27
39
|
/** Tears a fronted-session record down (marks its agent offline, shuts its mesh store down). Rejects propagate to onError. */
|
|
28
40
|
detach: (record: TRecord) => Promise<void>;
|
|
41
|
+
/** Resolves an inbound alias message's own alias name back to the correspondent it stands for -- reply-aliases.ts's ReplyAliasDirectory in production. */
|
|
42
|
+
aliasDirectory: CcPeerFrontAliasDirectory;
|
|
29
43
|
pollIntervalMs?: number | undefined;
|
|
30
44
|
onError?: ((error: Error) => void) | undefined;
|
|
31
45
|
}
|
|
@@ -44,6 +58,12 @@ export declare class CcPeerFront<TRecord extends FrontedSessionRecord> {
|
|
|
44
58
|
fromName?: string;
|
|
45
59
|
body: string;
|
|
46
60
|
}>): void;
|
|
61
|
+
/** Routes a reply arriving on a shared reply alias to whichever fronted session actually sent it -- matched the same way as handleInboundMessage, by the envelope's own socket-path convention. A message matching no fronted session is silently dropped, same as handleInboundMessage: there is nowhere for it to go, and we cannot safely address an error back to a session we do not control. Once the sending session is identified, the alias directory resolves which correspondent this reply is for; an alias the directory no longer knows about is reported back into the session as a stale-alias error rather than silently dropped, per agent-comms#158. */
|
|
62
|
+
handleAliasMessage(message: Readonly<{
|
|
63
|
+
alias: string;
|
|
64
|
+
from?: string;
|
|
65
|
+
body: string;
|
|
66
|
+
}>): void;
|
|
47
67
|
private tick;
|
|
48
68
|
private detachOne;
|
|
49
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-controller.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-controller.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKjE,0OAA0O;AAC1O,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,0PAA0P;IAC1P,QAAQ,CAAC,aAAa,EAAE,CACtB,OAAO,EAAE,QAAQ,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,KAClE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"front-controller.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-controller.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAKjE,0OAA0O;AAC1O,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,0PAA0P;IAC1P,QAAQ,CAAC,aAAa,EAAE,CACtB,OAAO,EAAE,QAAQ,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,KAClE,IAAI,CAAC;IACV,uZAAuZ;IACvZ,QAAQ,CAAC,gBAAgB,EAAE,CACzB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,QAAQ,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,KAClE,IAAI,CAAC;IACV,8PAA8P;IAC9P,QAAQ,CAAC,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD;AAED,2TAA2T;AAC3T,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC7D;AAED,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,oBAAoB;IACnE,4HAA4H;IAC5H,UAAU,EAAE,MAAM,OAAO,CAAC,SAAS,qBAAqB,EAAE,CAAC,CAAC;IAC5D,2GAA2G;IAC3G,cAAc,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IACrE,qNAAqN;IACrN,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,qBAAqB,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,8HAA8H;IAC9H,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,0JAA0J;IAC1J,cAAc,EAAE,yBAAyB,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAChD;AAMD,qBAAa,WAAW,CAAC,OAAO,SAAS,oBAAoB;IAI/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,KAAK,CAA6C;gBAE7B,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAErE,4OAA4O;IAC5O,KAAK,IAAI,IAAI;IAOb,oLAAoL;IAC9K,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,6XAA6X;IAC7X,oBAAoB,CAClB,OAAO,EAAE,QAAQ,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,GACpE,IAAI;IAKP,2oBAA2oB;IAC3oB,kBAAkB,CAChB,OAAO,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,GAChE,IAAI;YAaO,IAAI;YA+BJ,SAAS;CAOxB"}
|
|
@@ -41,6 +41,18 @@ export class CcPeerFront {
|
|
|
41
41
|
const record = matchInboundMessageSession(this.fronted.values(), message);
|
|
42
42
|
record?.handleInbound(message);
|
|
43
43
|
}
|
|
44
|
+
/** Routes a reply arriving on a shared reply alias to whichever fronted session actually sent it -- matched the same way as handleInboundMessage, by the envelope's own socket-path convention. A message matching no fronted session is silently dropped, same as handleInboundMessage: there is nowhere for it to go, and we cannot safely address an error back to a session we do not control. Once the sending session is identified, the alias directory resolves which correspondent this reply is for; an alias the directory no longer knows about is reported back into the session as a stale-alias error rather than silently dropped, per agent-comms#158. */
|
|
45
|
+
handleAliasMessage(message) {
|
|
46
|
+
const record = matchInboundMessageSession(this.fronted.values(), message);
|
|
47
|
+
if (!record)
|
|
48
|
+
return;
|
|
49
|
+
const correspondentId = this.deps.aliasDirectory.correspondentFor(message.alias);
|
|
50
|
+
if (correspondentId === undefined) {
|
|
51
|
+
record.notifyStaleAlias(message.alias);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
record.handleAliasReply(correspondentId, message);
|
|
55
|
+
}
|
|
44
56
|
async tick() {
|
|
45
57
|
let roster;
|
|
46
58
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-controller.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-controller.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAE3B,MAAM,YAAY,CAAC;AAGpB,2HAA2H;AAC3H,MAAM,wBAAwB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"front-controller.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,14 @@ export interface FrontRelayPeer {
|
|
|
20
20
|
msgId: string;
|
|
21
21
|
}>;
|
|
22
22
|
}
|
|
23
|
+
/** The narrow slice of AliasPool (cc-peer's own cc-peer/alias-pool subpath) this relay needs -- materialising the real OS-backed reply alias a correspondent's name was already minted for by FrontRelayAliasDirectory. Narrowed so this module has no compile-time dependency on the cc-peer package itself -- front-runtime.ts supplies the real AliasPool. */
|
|
24
|
+
export interface FrontRelayAliasPool {
|
|
25
|
+
ensure: (name: string) => Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/** The narrow slice of ReplyAliasDirectory (reply-aliases.ts) this relay needs to mint/recall the alias name for one correspondent on the mesh-to-session direction. */
|
|
28
|
+
export interface FrontRelayAliasDirectory {
|
|
29
|
+
ensure: (correspondentId: string) => string;
|
|
30
|
+
}
|
|
23
31
|
export interface FrontedRelayRecord extends FrontedSessionRecord {
|
|
24
32
|
agentId: string;
|
|
25
33
|
roomId: string;
|
|
@@ -32,9 +40,11 @@ export interface BuildFrontedSessionRecordDeps {
|
|
|
32
40
|
store: FrontRelayStore;
|
|
33
41
|
tool: Pick<CommsTool, "handle">;
|
|
34
42
|
peer: FrontRelayPeer;
|
|
43
|
+
aliasPool: FrontRelayAliasPool;
|
|
44
|
+
aliasDirectory: FrontRelayAliasDirectory;
|
|
35
45
|
}
|
|
36
46
|
/**
|
|
37
|
-
* Wires both relay directions for one fronted session and returns the record CcPeerFront tracks it under. Mesh-to-session: store.onDelivery sends the formatted event to this session's own pid via the shared peer. Session-to-mesh: the returned handleInbound (called by the front's shared "message" listener once it's matched this record by socket path) posts the message into this session's own project room, exactly as wireCcPeerBridge's own peer.on("message") handler does for the one-shot bridge command.
|
|
47
|
+
* Wires both relay directions for one fronted session and returns the record CcPeerFront tracks it under. Mesh-to-session: store.onDelivery sends the formatted event to this session's own pid via the shared peer -- for an event with a single originating correspondent (a dm or room_message, per correspondentForEvent), it first materialises a reply alias for that correspondent and mentions it in the delivered body, so the session can address a reply to that specific correspondent the way it addresses any other local peer (agent-comms#158). Session-to-mesh: the returned handleInbound (called by the front's shared "message" listener once it's matched this record by socket path) posts the message into this session's own project room, exactly as wireCcPeerBridge's own peer.on("message") handler does for the one-shot bridge command; handleAliasReply (called once CcPeerFront has resolved an inbound alias message to its correspondent) instead sends a mesh DM to that correspondent, as this session's own agentId; notifyStaleAlias delivers a clear error back into the session for a reply on an alias the directory no longer recognises.
|
|
38
48
|
*/
|
|
39
49
|
export declare function buildFrontedSessionRecord(deps: Readonly<BuildFrontedSessionRecordDeps>): FrontedRelayRecord;
|
|
40
50
|
/** Tears a fronted session's record down: marks its agent offline (a courtesy to peers watching its presence), then shuts its mesh store down. There is no identity lock to release -- attach() never took one (loadIdentityForFront's whole point), so a real bridge for this slot can already have claimed it by the time this runs. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-relay.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"front-relay.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,aAAa,CAAC;AAGnE,gMAAgM;AAChM,MAAM,WAAW,eAAe;IAC9B,UAAU,EACN,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GACjE,SAAS,CAAC;IACd,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,mQAAmQ;AACnQ,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,CACJ,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC3B,IAAI,EAAE,MAAM,KACT,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAED,iWAAiW;AACjW,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED,wKAAwK;AACxK,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,cAAc,EAAE,wBAAwB,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,QAAQ,CAAC,6BAA6B,CAAC,GAC5C,kBAAkB,CAkFpB;AAED,0UAA0U;AAC1U,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC,GAC9D,OAAO,CAAC,IAAI,CAAC,CAGf"}
|
|
@@ -4,13 +4,28 @@
|
|
|
4
4
|
* Reuses CcPeerRef/CcPeerInboundMessage from bridge.ts rather than redeclaring them -- the wire shape a shared front-wide peer speaks is identical to the one-shot bridge command's own peer, just addressed by pid instead of a fixed target.
|
|
5
5
|
*/
|
|
6
6
|
import { buildAction, formatDeliveryEvent } from "../../core/bridge.js";
|
|
7
|
+
import { correspondentForEvent } from "./reply-aliases.js";
|
|
7
8
|
/**
|
|
8
|
-
* Wires both relay directions for one fronted session and returns the record CcPeerFront tracks it under. Mesh-to-session: store.onDelivery sends the formatted event to this session's own pid via the shared peer. Session-to-mesh: the returned handleInbound (called by the front's shared "message" listener once it's matched this record by socket path) posts the message into this session's own project room, exactly as wireCcPeerBridge's own peer.on("message") handler does for the one-shot bridge command.
|
|
9
|
+
* Wires both relay directions for one fronted session and returns the record CcPeerFront tracks it under. Mesh-to-session: store.onDelivery sends the formatted event to this session's own pid via the shared peer -- for an event with a single originating correspondent (a dm or room_message, per correspondentForEvent), it first materialises a reply alias for that correspondent and mentions it in the delivered body, so the session can address a reply to that specific correspondent the way it addresses any other local peer (agent-comms#158). Session-to-mesh: the returned handleInbound (called by the front's shared "message" listener once it's matched this record by socket path) posts the message into this session's own project room, exactly as wireCcPeerBridge's own peer.on("message") handler does for the one-shot bridge command; handleAliasReply (called once CcPeerFront has resolved an inbound alias message to its correspondent) instead sends a mesh DM to that correspondent, as this session's own agentId; notifyStaleAlias delivers a clear error back into the session for a reply on an alias the directory no longer recognises.
|
|
9
10
|
*/
|
|
10
11
|
export function buildFrontedSessionRecord(deps) {
|
|
11
|
-
const { entry, agentId, roomId, store, tool, peer } = deps;
|
|
12
|
-
store.onDelivery = (_targetId, event) => {
|
|
13
|
-
|
|
12
|
+
const { entry, agentId, roomId, store, tool, peer, aliasPool, aliasDirectory, } = deps;
|
|
13
|
+
store.onDelivery = async (_targetId, event) => {
|
|
14
|
+
const body = formatDeliveryEvent(event);
|
|
15
|
+
const correspondentId = correspondentForEvent(event);
|
|
16
|
+
if (correspondentId === undefined) {
|
|
17
|
+
await peer.send({ pid: entry.pid }, body);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const aliasName = aliasDirectory.ensure(correspondentId);
|
|
21
|
+
try {
|
|
22
|
+
await aliasPool.ensure(aliasName);
|
|
23
|
+
await peer.send({ pid: entry.pid }, `${body} (reply via peer "${aliasName}")`);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// The alias failed to materialise (e.g. the worker process failed to start) -- deliver the message anyway, just without a reply hint the session couldn't actually use.
|
|
27
|
+
await peer.send({ pid: entry.pid }, body);
|
|
28
|
+
}
|
|
14
29
|
};
|
|
15
30
|
return {
|
|
16
31
|
pid: entry.pid,
|
|
@@ -33,6 +48,22 @@ export function buildFrontedSessionRecord(deps) {
|
|
|
33
48
|
pid: process.pid,
|
|
34
49
|
}, action);
|
|
35
50
|
},
|
|
51
|
+
handleAliasReply: (correspondentId, message) => {
|
|
52
|
+
const action = buildAction({
|
|
53
|
+
action: "dm",
|
|
54
|
+
target: correspondentId,
|
|
55
|
+
content: message.body,
|
|
56
|
+
});
|
|
57
|
+
void tool.handle({
|
|
58
|
+
agentId,
|
|
59
|
+
harness: "claude-code",
|
|
60
|
+
cwd: entry.cwd,
|
|
61
|
+
pid: process.pid,
|
|
62
|
+
}, action);
|
|
63
|
+
},
|
|
64
|
+
notifyStaleAlias: (aliasName) => {
|
|
65
|
+
void peer.send({ pid: entry.pid }, `Reply not delivered: peer "${aliasName}" is no longer a known correspondent (reply aliases don't survive a front restart). Wait for a new message from them and reply to that instead.`);
|
|
66
|
+
},
|
|
36
67
|
};
|
|
37
68
|
}
|
|
38
69
|
/** Tears a fronted session's record down: marks its agent offline (a courtesy to peers watching its presence), then shuts its mesh store down. There is no identity lock to release -- attach() never took one (loadIdentityForFront's whole point), so a real bridge for this slot can already have claimed it by the time this runs. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-relay.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"front-relay.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-relay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-runtime.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"front-runtime.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAM1B,MAAM,WAAW,+BAA+B;IAC9C,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAChD;AAOD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,QAAQ,CAAC,+BAA+B,CAAM,GACtD,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,CAwFzD"}
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
* Untested directly, exactly like run.ts's own real construction (see cc-peer-bridge.test.ts's header comment): front.ts, front-controller.ts, and front-relay.ts already carry the front's entire decision/diffing/relay logic under direct DI-based unit tests, so this file's only remaining job -- calling the real cc-peer/core APIs in the right order -- is exercised by actually running a bridge as this machine's coordinator.
|
|
5
5
|
*/
|
|
6
6
|
import { CcPeer } from "cc-peer";
|
|
7
|
+
import { AliasPool } from "cc-peer/alias-pool";
|
|
7
8
|
import { createBridgeMeshFromIdentity, ensureRegistered, ensureProjectRoom, } from "../../core/index.js";
|
|
8
9
|
import { loadIdentityForFront, probeSlotOwner, } from "../../core/identity-store.js";
|
|
9
10
|
import { CcPeerFront } from "./front-controller.js";
|
|
10
11
|
import { computeFrontSlot } from "./front.js";
|
|
11
12
|
import { buildFrontedSessionRecord, detachFrontedSession, } from "./front-relay.js";
|
|
13
|
+
import { ReplyAliasDirectory } from "./reply-aliases.js";
|
|
12
14
|
/** cc-peer's own registered display name for the front's shared peer -- distinct from any individual fronted session's own agent-comms display name (front-relay.ts's ensureRegistered call uses the session's own cc-peer name/pid for that). */
|
|
13
15
|
const FRONT_PEER_NAME = "agent-comms-front";
|
|
14
16
|
/** Falls back to "claude-code-<pid>" when a session has never picked its own cc-peer display name -- ensureRegistered requires a defaultName, and an unnamed session is still worth fronting under something stable and identifiable. */
|
|
@@ -20,6 +22,8 @@ function defaultSessionName(entry) {
|
|
|
20
22
|
*/
|
|
21
23
|
export function createDefaultCcPeerFront(options = {}) {
|
|
22
24
|
let sharedPeerPromise;
|
|
25
|
+
let aliasPool;
|
|
26
|
+
const aliasDirectory = new ReplyAliasDirectory();
|
|
23
27
|
const front = new CcPeerFront({
|
|
24
28
|
listRoster: async () => {
|
|
25
29
|
const peer = await ensureSharedPeer();
|
|
@@ -28,6 +32,7 @@ export function createDefaultCcPeerFront(options = {}) {
|
|
|
28
32
|
probeSlotOwner,
|
|
29
33
|
attach: async (entry) => attachSession(entry, await ensureSharedPeer()),
|
|
30
34
|
detach: detachFrontedSession,
|
|
35
|
+
aliasDirectory,
|
|
31
36
|
pollIntervalMs: options.pollIntervalMs,
|
|
32
37
|
onError: options.onError,
|
|
33
38
|
});
|
|
@@ -40,6 +45,8 @@ export function createDefaultCcPeerFront(options = {}) {
|
|
|
40
45
|
const peer = await sharedPeerPromise?.catch(() => undefined);
|
|
41
46
|
sharedPeerPromise = undefined;
|
|
42
47
|
await peer?.stop();
|
|
48
|
+
await aliasPool?.stopAll();
|
|
49
|
+
aliasPool = undefined;
|
|
43
50
|
},
|
|
44
51
|
};
|
|
45
52
|
async function ensureSharedPeer() {
|
|
@@ -51,6 +58,17 @@ export function createDefaultCcPeerFront(options = {}) {
|
|
|
51
58
|
});
|
|
52
59
|
return sharedPeerPromise;
|
|
53
60
|
}
|
|
61
|
+
/** Materialises the front's own shared AliasPool on first use (mirroring ensureSharedPeer's own lazy-construction convention) and wires its "message" event -- every reply arriving on any fronted session's own correspondent aliases -- straight into the controller's handleAliasMessage, which resolves the sending session and the alias's own correspondent before routing it on. */
|
|
62
|
+
function ensureAliasPool() {
|
|
63
|
+
if (aliasPool)
|
|
64
|
+
return aliasPool;
|
|
65
|
+
const pool = AliasPool.create();
|
|
66
|
+
pool.on("message", (message) => {
|
|
67
|
+
front.handleAliasMessage(message);
|
|
68
|
+
});
|
|
69
|
+
aliasPool = pool;
|
|
70
|
+
return pool;
|
|
71
|
+
}
|
|
54
72
|
async function attachSession(entry, peer) {
|
|
55
73
|
const slot = computeFrontSlot(entry.cwd);
|
|
56
74
|
const identity = loadIdentityForFront(slot);
|
|
@@ -70,6 +88,8 @@ export function createDefaultCcPeerFront(options = {}) {
|
|
|
70
88
|
store,
|
|
71
89
|
tool,
|
|
72
90
|
peer,
|
|
91
|
+
aliasPool: ensureAliasPool(),
|
|
92
|
+
aliasDirectory,
|
|
73
93
|
});
|
|
74
94
|
}
|
|
75
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"front-runtime.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EACL,4BAA4B,EAC5B,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,cAAc,GACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,yBAAyB,EACzB,oBAAoB,GAErB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"front-runtime.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/front-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy per-correspondent reply aliases for the default cc-peer front (agent-comms#158) -- pure alias-name derivation and the in-memory correspondent↔alias directory the front consults on both the mesh-to-session direction (materialise an alias so the session can address a reply to it) and the session-to-mesh direction (translate a reply arriving on an alias back into the correspondent it stands for).
|
|
3
|
+
*
|
|
4
|
+
* Deliberately not persisted: aliases are ephemeral by design, lost on restart and re-materialised by the next inbound message from that correspondent (see the issue body's "Rejected alternatives" for why a directory of every mesh agent is not minted upfront). Kept free of any real cc-peer/AliasPool construction, exactly like front.ts's pure decision logic -- front-relay.ts and front-controller.ts consult this directory, and front-runtime.ts supplies the real AliasPool the alias names get materialised against.
|
|
5
|
+
*/
|
|
6
|
+
import type { DeliveryEvent } from "../../core/types.js";
|
|
7
|
+
/** Derives the cc-peer peer name a correspondent's reply alias registers under. Deterministic and side-effect-free: the same correspondent id always derives the same name, so ReplyAliasDirectory only needs to remember the mapping, not invent a fresh name per call. */
|
|
8
|
+
export declare function deriveAliasName(correspondentId: string): string;
|
|
9
|
+
/** The mesh agent id a DeliveryEvent originated from, for the event types that carry a single, repliable-to sender -- undefined for every other event type (room membership/status/capability events describe something happening, not a message from one correspondent worth aliasing). */
|
|
10
|
+
export declare function correspondentForEvent(event: Readonly<DeliveryEvent>): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Bounded, in-memory, bijective map between the cc-peer peer names materialised for a front's reply aliases and the mesh correspondent id each one stands for. Bounded by real correspondents, per the issue's own "Rejected alternatives": a name is only ever minted by ensure(), which the front calls solely on genuine inbound contact from that correspondent -- nothing pre-populates this directory with the wider mesh roster.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ReplyAliasDirectory {
|
|
15
|
+
private readonly nameToCorrespondent;
|
|
16
|
+
private readonly correspondentToName;
|
|
17
|
+
/** Returns the alias name for a correspondent, deriving and recording it the first time this correspondent is seen. Idempotent: a correspondent already known always gets back its existing name, so a session's reply target stays stable across repeated inbound contact within the same front lifetime. */
|
|
18
|
+
ensure(correspondentId: string): string;
|
|
19
|
+
/** The correspondent a previously-minted alias name stands for, or undefined for a name this directory never minted (or no longer remembers, e.g. after a front restart cleared it) -- the front's own signal to treat an inbound reply as addressed to a stale alias rather than a known correspondent. */
|
|
20
|
+
correspondentFor(aliasName: string): string | undefined;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=reply-aliases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reply-aliases.d.ts","sourceRoot":"","sources":["../../../src/bridges/cc-peer/reply-aliases.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQzD,4QAA4Q;AAC5Q,wBAAgB,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,4RAA4R;AAC5R,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC7B,MAAM,GAAG,SAAS,CAmBpB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IACjE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IAEjE,8SAA8S;IAC9S,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IASvC,4SAA4S;IAC5S,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAGxD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy per-correspondent reply aliases for the default cc-peer front (agent-comms#158) -- pure alias-name derivation and the in-memory correspondent↔alias directory the front consults on both the mesh-to-session direction (materialise an alias so the session can address a reply to it) and the session-to-mesh direction (translate a reply arriving on an alias back into the correspondent it stands for).
|
|
3
|
+
*
|
|
4
|
+
* Deliberately not persisted: aliases are ephemeral by design, lost on restart and re-materialised by the next inbound message from that correspondent (see the issue body's "Rejected alternatives" for why a directory of every mesh agent is not minted upfront). Kept free of any real cc-peer/AliasPool construction, exactly like front.ts's pure decision logic -- front-relay.ts and front-controller.ts consult this directory, and front-runtime.ts supplies the real AliasPool the alias names get materialised against.
|
|
5
|
+
*/
|
|
6
|
+
/** How many leading hex characters of a correspondent's device-id go into its alias name -- 48 bits of a SHA-256 hash, chosen purely for a short, readable cc-peer peer name; cc-peer's own registry name field has no length or format restriction beyond non-empty (see AliasStartCommandSchema in cc-peer's alias-ipc schema), so this is a readability choice, not a protocol requirement. */
|
|
7
|
+
const ALIAS_ID_LENGTH = 12;
|
|
8
|
+
/** cc-peer peer names materialised for reply aliases are prefixed so they read unambiguously as a mesh correspondent, not a real local Claude Code session, in `roster()`/UI listings that show every locally known peer name side by side. */
|
|
9
|
+
const ALIAS_NAME_PREFIX = "mesh-";
|
|
10
|
+
/** Derives the cc-peer peer name a correspondent's reply alias registers under. Deterministic and side-effect-free: the same correspondent id always derives the same name, so ReplyAliasDirectory only needs to remember the mapping, not invent a fresh name per call. */
|
|
11
|
+
export function deriveAliasName(correspondentId) {
|
|
12
|
+
return `${ALIAS_NAME_PREFIX}${correspondentId.slice(0, ALIAS_ID_LENGTH)}`;
|
|
13
|
+
}
|
|
14
|
+
/** The mesh agent id a DeliveryEvent originated from, for the event types that carry a single, repliable-to sender -- undefined for every other event type (room membership/status/capability events describe something happening, not a message from one correspondent worth aliasing). */
|
|
15
|
+
export function correspondentForEvent(event) {
|
|
16
|
+
switch (event.type) {
|
|
17
|
+
case "dm":
|
|
18
|
+
case "room_message":
|
|
19
|
+
return event.message.from;
|
|
20
|
+
case "room_invite":
|
|
21
|
+
case "member_joined":
|
|
22
|
+
case "member_left":
|
|
23
|
+
case "room_members":
|
|
24
|
+
case "member_status":
|
|
25
|
+
case "delivery_status":
|
|
26
|
+
case "invite_declined":
|
|
27
|
+
case "name_changed":
|
|
28
|
+
case "connection_request":
|
|
29
|
+
case "capability_request":
|
|
30
|
+
return undefined;
|
|
31
|
+
default:
|
|
32
|
+
return event;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Bounded, in-memory, bijective map between the cc-peer peer names materialised for a front's reply aliases and the mesh correspondent id each one stands for. Bounded by real correspondents, per the issue's own "Rejected alternatives": a name is only ever minted by ensure(), which the front calls solely on genuine inbound contact from that correspondent -- nothing pre-populates this directory with the wider mesh roster.
|
|
37
|
+
*/
|
|
38
|
+
export class ReplyAliasDirectory {
|
|
39
|
+
nameToCorrespondent = new Map();
|
|
40
|
+
correspondentToName = new Map();
|
|
41
|
+
/** Returns the alias name for a correspondent, deriving and recording it the first time this correspondent is seen. Idempotent: a correspondent already known always gets back its existing name, so a session's reply target stays stable across repeated inbound contact within the same front lifetime. */
|
|
42
|
+
ensure(correspondentId) {
|
|
43
|
+
const existing = this.correspondentToName.get(correspondentId);
|
|
44
|
+
if (existing !== undefined)
|
|
45
|
+
return existing;
|
|
46
|
+
const name = deriveAliasName(correspondentId);
|
|
47
|
+
this.correspondentToName.set(correspondentId, name);
|
|
48
|
+
this.nameToCorrespondent.set(name, correspondentId);
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
/** The correspondent a previously-minted alias name stands for, or undefined for a name this directory never minted (or no longer remembers, e.g. after a front restart cleared it) -- the front's own signal to treat an inbound reply as addressed to a stale alias rather than a known correspondent. */
|
|
52
|
+
correspondentFor(aliasName) {
|
|
53
|
+
return this.nameToCorrespondent.get(aliasName);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=reply-aliases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reply-aliases.js","sourceRoot":"","sources":["../../../src/bridges/cc-peer/reply-aliases.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,kYAAkY;AAClY,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,+OAA+O;AAC/O,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAElC,4QAA4Q;AAC5Q,MAAM,UAAU,eAAe,CAAC,eAAuB;IACrD,OAAO,GAAG,iBAAiB,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED,4RAA4R;AAC5R,MAAM,UAAU,qBAAqB,CACnC,KAA8B;IAE9B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,IAAI,CAAC;QACV,KAAK,cAAc;YACjB,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAC5B,KAAK,aAAa,CAAC;QACnB,KAAK,eAAe,CAAC;QACrB,KAAK,aAAa,CAAC;QACnB,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe,CAAC;QACrB,KAAK,iBAAiB,CAAC;QACvB,KAAK,iBAAiB,CAAC;QACvB,KAAK,cAAc,CAAC;QACpB,KAAK,oBAAoB,CAAC;QAC1B,KAAK,oBAAoB;YACvB,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,KAAqB,CAAC;IACjC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACb,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEjE,8SAA8S;IAC9S,MAAM,CAAC,eAAuB;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC/D,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,IAAI,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4SAA4S;IAC5S,gBAAgB,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-mesh.d.ts","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,iSAAiS;IACjS,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,sSAAsS;AACtS,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GACrD,cAAc,CAQhB;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GACrD,cAAc,
|
|
1
|
+
{"version":3,"file":"bridge-mesh.d.ts","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,iSAAiS;IACjS,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,sSAAsS;AACtS,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GACrD,cAAc,CAQhB;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GACrD,cAAc,CA8ChB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,6JAA6J;AAC7J,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,UAAU,CAAC,CAUrB"}
|
package/dist/core/bridge-mesh.js
CHANGED
|
@@ -36,7 +36,7 @@ export function createBridgeMeshSyncFromIdentity(identity, slot, coordinatorPort
|
|
|
36
36
|
store.peerId = deviceIdToHex(Uint8Array.from(identity.deviceId));
|
|
37
37
|
// One shared dataStorage instance for both the transport's own data-domain frame responder and the store's own durable-send mint path (P5, agent-comms#50) -- oplogDirFor(slot) needs only the slot, not the async identity below, so this can be constructed synchronously right here.
|
|
38
38
|
const dataStorage = createNodeFsStorage({ dir: oplogDirFor(slot) });
|
|
39
|
-
store.setTransport(new WireMeshTransport(store.events, identity, store.roomVerbHandlers, undefined, () => store.selfStatus, undefined, () => store.hostedRooms, dataStorage, () => store.selfAgentAdvert));
|
|
39
|
+
store.setTransport(new WireMeshTransport(store.events, identity, store.roomVerbHandlers, undefined, () => store.selfStatus, undefined, () => store.hostedRooms, dataStorage, () => store.selfAgentAdvert, store.gatewayTrust));
|
|
40
40
|
const versionChecker = new VersionDriftChecker({
|
|
41
41
|
currentVersion: getOwnPackageVersion(),
|
|
42
42
|
...(fetchLatestVersion !== undefined ? { fetchLatestVersion } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-mesh.js","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAY9D,sSAAsS;AACtS,MAAM,UAAU,oBAAoB,CAClC,IAA4B,EAC5B,eAAwB,EACxB,MAAe,EACf,kBAAsD;IAEtD,OAAO,gCAAgC,CACrC,oBAAoB,CAAC,IAAI,CAAC,EAC1B,IAAI,EACJ,eAAe,EACf,MAAM,EACN,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gCAAgC,CAC9C,QAAsB,EACtB,IAA4B,EAC5B,eAAwB,EACxB,MAAe,EACf,kBAAsD;IAEtD,+RAA+R;IAC/R,MAAM,mBAAmB,GAAG,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,wRAAwR;IACxR,MAAM,WAAW,GAAG,mBAAmB,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpE,KAAK,CAAC,YAAY,CAChB,IAAI,iBAAiB,CACnB,KAAK,CAAC,MAAM,EACZ,QAAQ,EACR,KAAK,CAAC,gBAAgB,EACtB,SAAS,EACT,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EACtB,SAAS,EACT,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,EACvB,WAAW,EACX,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"bridge-mesh.js","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"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"}
|
package/dist/core/bridge.d.ts
CHANGED
|
@@ -48,6 +48,9 @@ export declare const MCP_TOOL_PARAMS: z.ZodObject<{
|
|
|
48
48
|
mesh_listeners: "mesh_listeners";
|
|
49
49
|
mesh_set_visibility: "mesh_set_visibility";
|
|
50
50
|
mesh_get_visibility: "mesh_get_visibility";
|
|
51
|
+
gateway_trust: "gateway_trust";
|
|
52
|
+
gateway_untrust: "gateway_untrust";
|
|
53
|
+
gateway_list_trusted: "gateway_list_trusted";
|
|
51
54
|
}>;
|
|
52
55
|
name: z.ZodOptional<z.ZodString>;
|
|
53
56
|
visibility: z.ZodOptional<z.ZodEnum<{
|
|
@@ -96,6 +99,7 @@ export declare const MCP_TOOL_PARAMS: z.ZodObject<{
|
|
|
96
99
|
capability: z.ZodOptional<z.ZodString>;
|
|
97
100
|
expires: z.ZodOptional<z.ZodNumber>;
|
|
98
101
|
delegationsRemaining: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
device: z.ZodOptional<z.ZodString>;
|
|
99
103
|
}, z.core.$strip>;
|
|
100
104
|
export type ToolParams = z.infer<typeof MCP_TOOL_PARAMS>;
|
|
101
105
|
export declare function buildAction(params: Record<string, unknown>): CommsAction;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/core/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/core/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqE1B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAsBzD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CA8QxE;AAMD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,GACnB,iBAAiB,GAAG,SAAS,CAK/B;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAyChE;AAMD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAmB/D;AAMD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuB9B;AAMD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC3B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAMD,wBAAsB,cAAc,CAClC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
|
package/dist/core/bridge.js
CHANGED
|
@@ -55,6 +55,9 @@ export const MCP_TOOL_PARAMS = z.object({
|
|
|
55
55
|
"mesh_listeners",
|
|
56
56
|
"mesh_set_visibility",
|
|
57
57
|
"mesh_get_visibility",
|
|
58
|
+
"gateway_trust",
|
|
59
|
+
"gateway_untrust",
|
|
60
|
+
"gateway_list_trusted",
|
|
58
61
|
]),
|
|
59
62
|
name: z.string().optional(),
|
|
60
63
|
visibility: VisibilityEnum.optional(),
|
|
@@ -83,6 +86,8 @@ export const MCP_TOOL_PARAMS = z.object({
|
|
|
83
86
|
capability: z.string().optional(),
|
|
84
87
|
expires: z.number().optional(),
|
|
85
88
|
delegationsRemaining: z.number().optional(),
|
|
89
|
+
/** A remote gateway's own device-id (hex), for gateway_trust/gateway_untrust. */
|
|
90
|
+
device: z.string().optional(),
|
|
86
91
|
});
|
|
87
92
|
/**
|
|
88
93
|
* Zod schema for the MCP tool inputSchema field.
|
|
@@ -374,6 +379,16 @@ export function buildAction(params) {
|
|
|
374
379
|
};
|
|
375
380
|
return result;
|
|
376
381
|
}
|
|
382
|
+
case "gateway_trust":
|
|
383
|
+
if (p.device === undefined)
|
|
384
|
+
throw new BuildActionError("gateway_trust", "device");
|
|
385
|
+
return { action: "gateway_trust", device: p.device };
|
|
386
|
+
case "gateway_untrust":
|
|
387
|
+
if (p.device === undefined)
|
|
388
|
+
throw new BuildActionError("gateway_untrust", "device");
|
|
389
|
+
return { action: "gateway_untrust", device: p.device };
|
|
390
|
+
case "gateway_list_trusted":
|
|
391
|
+
return { action: "gateway_list_trusted" };
|
|
377
392
|
default:
|
|
378
393
|
return p.action;
|
|
379
394
|
}
|