agent-comms 6.0.0 → 7.0.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.
Files changed (131) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +4 -2
  4. package/dist/bridges/user/controller.d.ts +1 -1
  5. package/dist/bridges/user/controller.d.ts.map +1 -1
  6. package/dist/bridges/user/controller.js +1 -1
  7. package/dist/bridges/user/controller.js.map +1 -1
  8. package/dist/core/bridge-mesh.d.ts +1 -1
  9. package/dist/core/bridge-mesh.d.ts.map +1 -1
  10. package/dist/core/bridge-mesh.js +2 -1
  11. package/dist/core/bridge-mesh.js.map +1 -1
  12. package/dist/core/gateway-trust.d.ts +5 -5
  13. package/dist/core/gateway-trust.d.ts.map +1 -1
  14. package/dist/core/gateway-trust.js +5 -5
  15. package/dist/core/gateway-trust.js.map +1 -1
  16. package/dist/core/gossip-directory.d.ts +1 -1
  17. package/dist/core/gossip-directory.d.ts.map +1 -1
  18. package/dist/core/gossip-directory.js +4 -2
  19. package/dist/core/gossip-directory.js.map +1 -1
  20. package/dist/core/hub-forwarding.d.ts +4 -18
  21. package/dist/core/hub-forwarding.d.ts.map +1 -1
  22. package/dist/core/hub-forwarding.js +2 -41
  23. package/dist/core/hub-forwarding.js.map +1 -1
  24. package/dist/core/hub-link.d.ts +58 -0
  25. package/dist/core/hub-link.d.ts.map +1 -0
  26. package/dist/core/hub-link.js +118 -0
  27. package/dist/core/hub-link.js.map +1 -0
  28. package/dist/core/hub-session.d.ts +14 -15
  29. package/dist/core/hub-session.d.ts.map +1 -1
  30. package/dist/core/hub-session.js +30 -51
  31. package/dist/core/hub-session.js.map +1 -1
  32. package/dist/core/mesh-graph.d.ts +1 -1
  33. package/dist/core/mesh-graph.js +1 -1
  34. package/dist/core/mesh-store.d.ts +10 -5
  35. package/dist/core/mesh-store.d.ts.map +1 -1
  36. package/dist/core/mesh-store.js +33 -22
  37. package/dist/core/mesh-store.js.map +1 -1
  38. package/dist/core/peer-lifecycle.d.ts +2 -5
  39. package/dist/core/peer-lifecycle.d.ts.map +1 -1
  40. package/dist/core/peer-lifecycle.js +0 -1
  41. package/dist/core/peer-lifecycle.js.map +1 -1
  42. package/dist/core/room-router.d.ts +2 -2
  43. package/dist/core/room-router.d.ts.map +1 -1
  44. package/dist/core/room-router.js +2 -32
  45. package/dist/core/room-router.js.map +1 -1
  46. package/dist/core/shutdown-signals.d.ts +1 -1
  47. package/dist/core/shutdown-signals.js +1 -1
  48. package/dist/core/transport.d.ts +7 -7
  49. package/dist/core/transport.d.ts.map +1 -1
  50. package/dist/core/wire-mesh-transport.d.ts +7 -3
  51. package/dist/core/wire-mesh-transport.d.ts.map +1 -1
  52. package/dist/core/wire-mesh-transport.js +39 -22
  53. package/dist/core/wire-mesh-transport.js.map +1 -1
  54. package/dist/test/bridge-mesh.integration.test.js +15 -1
  55. package/dist/test/bridge-mesh.integration.test.js.map +1 -1
  56. package/dist/test/chat-controller-mesh-errors.integration.test.js +7 -1
  57. package/dist/test/chat-controller-mesh-errors.integration.test.js.map +1 -1
  58. package/dist/test/coordinator-failover-hub.integration.test.d.ts +5 -0
  59. package/dist/test/coordinator-failover-hub.integration.test.d.ts.map +1 -0
  60. package/dist/test/coordinator-failover-hub.integration.test.js +78 -0
  61. package/dist/test/coordinator-failover-hub.integration.test.js.map +1 -0
  62. package/dist/test/coordinator-failover.integration.test.js +3 -6
  63. package/dist/test/coordinator-failover.integration.test.js.map +1 -1
  64. package/dist/test/coordinator-failover.unit.test.js +0 -7
  65. package/dist/test/coordinator-failover.unit.test.js.map +1 -1
  66. package/dist/test/gateway-trust.integration.test.d.ts +1 -1
  67. package/dist/test/gateway-trust.integration.test.js +26 -2
  68. package/dist/test/gateway-trust.integration.test.js.map +1 -1
  69. package/dist/test/gateway-trust.unit.test.js +1 -1
  70. package/dist/test/hub-exposure.integration.test.d.ts +5 -0
  71. package/dist/test/hub-exposure.integration.test.d.ts.map +1 -0
  72. package/dist/test/hub-exposure.integration.test.js +121 -0
  73. package/dist/test/hub-exposure.integration.test.js.map +1 -0
  74. package/dist/test/hub-helpers.d.ts +18 -3
  75. package/dist/test/hub-helpers.d.ts.map +1 -1
  76. package/dist/test/hub-helpers.js +24 -3
  77. package/dist/test/hub-helpers.js.map +1 -1
  78. package/dist/test/hub-link.unit.test.d.ts +2 -0
  79. package/dist/test/hub-link.unit.test.d.ts.map +1 -0
  80. package/dist/test/hub-link.unit.test.js +210 -0
  81. package/dist/test/hub-link.unit.test.js.map +1 -0
  82. package/dist/test/hub-peer-per-store.integration.test.d.ts +9 -0
  83. package/dist/test/hub-peer-per-store.integration.test.d.ts.map +1 -0
  84. package/dist/test/hub-peer-per-store.integration.test.js +211 -0
  85. package/dist/test/hub-peer-per-store.integration.test.js.map +1 -0
  86. package/dist/test/hub-room-domain-verb-trust-bypass.integration.test.js +2 -2
  87. package/dist/test/hub-room-domain-verb-trust-bypass.integration.test.js.map +1 -1
  88. package/dist/test/hub-session-close.integration.test.js +1 -1
  89. package/dist/test/hub-session-close.integration.test.js.map +1 -1
  90. package/dist/test/hub-session-dispatch.unit.test.js +1 -66
  91. package/dist/test/hub-session-dispatch.unit.test.js.map +1 -1
  92. package/dist/test/mesh-graph-trace.integration.test.js +2 -2
  93. package/dist/test/mesh-graph-trace.integration.test.js.map +1 -1
  94. package/dist/test/mesh-smoke.runner.js +1 -3
  95. package/dist/test/mesh-smoke.runner.js.map +1 -1
  96. package/dist/test/mesh-store-orchestration.unit.test.js +11 -41
  97. package/dist/test/mesh-store-orchestration.unit.test.js.map +1 -1
  98. package/dist/test/peer-lifecycle.unit.test.js +0 -8
  99. package/dist/test/peer-lifecycle.unit.test.js.map +1 -1
  100. package/dist/test/principal-membership-trust.integration.test.js +8 -1
  101. package/dist/test/principal-membership-trust.integration.test.js.map +1 -1
  102. package/dist/test/room-join-by-bare-name.integration.test.js +1 -1
  103. package/dist/test/room-join-by-bare-name.integration.test.js.map +1 -1
  104. package/dist/test/test-transport.d.ts +1 -1
  105. package/dist/test/test-transport.d.ts.map +1 -1
  106. package/dist/test/test-transport.js +1 -1
  107. package/dist/test/test-transport.js.map +1 -1
  108. package/dist/test/wire-mesh-transport-hub.integration.test.d.ts +1 -1
  109. package/dist/test/wire-mesh-transport-hub.integration.test.js +96 -9
  110. package/dist/test/wire-mesh-transport-hub.integration.test.js.map +1 -1
  111. package/package.json +1 -1
  112. package/dist/core/coordinator-gateway.d.ts +0 -25
  113. package/dist/core/coordinator-gateway.d.ts.map +0 -1
  114. package/dist/core/coordinator-gateway.js +0 -34
  115. package/dist/core/coordinator-gateway.js.map +0 -1
  116. package/dist/test/coordinator-gateway.unit.test.d.ts +0 -2
  117. package/dist/test/coordinator-gateway.unit.test.d.ts.map +0 -1
  118. package/dist/test/coordinator-gateway.unit.test.js +0 -88
  119. package/dist/test/coordinator-gateway.unit.test.js.map +0 -1
  120. package/dist/test/gateway-forwarding.integration.test.d.ts +0 -9
  121. package/dist/test/gateway-forwarding.integration.test.d.ts.map +0 -1
  122. package/dist/test/gateway-forwarding.integration.test.js +0 -226
  123. package/dist/test/gateway-forwarding.integration.test.js.map +0 -1
  124. package/dist/test/hub-forwarding.unit.test.d.ts +0 -2
  125. package/dist/test/hub-forwarding.unit.test.d.ts.map +0 -1
  126. package/dist/test/hub-forwarding.unit.test.js +0 -102
  127. package/dist/test/hub-forwarding.unit.test.js.map +0 -1
  128. package/dist/test/hub-todevice-routing.integration.test.d.ts +0 -7
  129. package/dist/test/hub-todevice-routing.integration.test.d.ts.map +0 -1
  130. package/dist/test/hub-todevice-routing.integration.test.js +0 -121
  131. package/dist/test/hub-todevice-routing.integration.test.js.map +0 -1
@@ -1,226 +0,0 @@
1
- /**
2
- * Integration tests for the gateway actually forwarding between the local mesh and the hub (agent-comms#155), the core leg of the cross-machine mesh epic (#153) on top of #154's own connection-lifecycle-only gateway. Two independent local meshes ("machine A" and "machine B"), each its own coordinator dialling a shared real relay hub (createRelayHub, the same domain logic the production mesh.exadev.io Durable Object runs, served over local WebSockets via hub-helpers.ts) -- neither mesh is ever directly connected to the other, so anything either side learns about the other can only have arrived via the hub.
3
- *
4
- * Machine A's coordinator (a1) additionally has a second, ordinary local peer (a2) -- proving outbound advertisement and the remote-directory merge work for a local peer that is NOT itself the gateway, not just for the gateway's own agent (which #154 already exercised end-to-end before this issue).
5
- *
6
- * Every gateway here explicitly trusts the specific remote device-ids it needs to (agent-comms#156's own gateway allowlist, added after these tests first landed): the allowlist is deny-all by default, so every test below establishes trust before expecting forwarding/merge/routing to happen -- see gateway-trust.integration.test.ts for the deny-by-default behaviour itself (untrusted forwarding/merge/routing all failing) rather than re-proving it per test here.
7
- */
8
- import { afterEach, describe, expect, it } from "vitest";
9
- import { MeshStore } from "../core/mesh-store.js";
10
- import { dmRoomPath } from "../core/room-path.js";
11
- import { realHubOverWs, TeardownStack } from "./hub-helpers.js";
12
- import { wireTestTransport } from "./test-transport.js";
13
- let nextPort = 22_400;
14
- function freshPort() {
15
- nextPort += 1;
16
- return nextPort;
17
- }
18
- /** Short enough that a gossip re-advertisement (which carries the registerAgent'd agent/self extension) fires within a test's own poll budget, unlike the 20s production default. */
19
- const FAST_GOSSIP_INTERVAL_MS = 50;
20
- const POLL_ATTEMPTS = 100;
21
- const POLL_INTERVAL_MS = 50;
22
- const sleep = async (ms) => new Promise((resolve) => {
23
- setTimeout(resolve, ms);
24
- });
25
- /** Polls an async predicate until it holds, matching broadcast-window.integration.test.ts's own established pattern for this -- the shared test-transport.ts waitFor takes a synchronous condition, which can't await a MeshStore's own async listAgents/serialise-derived checks. */
26
- async function waitFor(what, check) {
27
- for (let i = 0; i < POLL_ATTEMPTS; i++) {
28
- if (await check())
29
- return;
30
- await sleep(POLL_INTERVAL_MS);
31
- }
32
- expect(false, `timed out waiting for ${what}`).toBeTruthy();
33
- }
34
- const cleanups = new TeardownStack();
35
- afterEach(async () => {
36
- await cleanups.run();
37
- });
38
- describe("gateway forwarding", () => {
39
- it("advertises a local peer's agent (not just the gateway's own) onto the hub, and a separate machine's gateway merges it into its own knownDevices/listAgents", async () => {
40
- const hub = await realHubOverWs();
41
- cleanups.push(hub.close);
42
- const a1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
43
- await wireTestTransport(a1, {
44
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
45
- });
46
- await a1.init();
47
- cleanups.push(async () => a1.shutdown());
48
- const a2 = new MeshStore({
49
- coordinatorPort: a1.coordinatorPort,
50
- hubUrl: hub.url,
51
- });
52
- await wireTestTransport(a2, {
53
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
54
- });
55
- await a2.init();
56
- cleanups.push(async () => a2.shutdown());
57
- await a2.registerAgent({
58
- name: "a2-local-peer",
59
- harness: "test",
60
- cwd: "/test/a2",
61
- pid: process.pid,
62
- visibility: "visible",
63
- tags: ["from-a2"],
64
- });
65
- const b1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
66
- await wireTestTransport(b1, {
67
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
68
- });
69
- await b1.init();
70
- cleanups.push(async () => b1.shutdown());
71
- // Deny-all by default (agent-comms#156): a1 needs at least one trusted device to forward anything at all onto the hub, and b1 needs a2's own device-id specifically trusted to merge a2's directory entry (trust is keyed per device, not per remote machine -- see GatewayTrust's own class doc).
72
- a1.addTrustedGateway(b1.peerId);
73
- b1.addTrustedGateway(a2.peerId);
74
- await waitFor("b1 (a separate machine's gateway) to learn of a2 (a non-gateway local peer on machine A) via the hub", async () => {
75
- const agents = await b1.listAgents(b1.peerId);
76
- return agents.some((agent) => agent.id === a2.peerId);
77
- });
78
- const agents = await b1.listAgents(b1.peerId);
79
- const discovered = agents.find((agent) => agent.id === a2.peerId);
80
- expect(discovered).toMatchObject({
81
- id: a2.peerId,
82
- name: "a2-local-peer",
83
- harness: "test",
84
- cwd: "/test/a2",
85
- visibility: "visible",
86
- tags: ["from-a2"],
87
- });
88
- });
89
- it("never advertises a hidden or ghost agent across the hub", async () => {
90
- const hub = await realHubOverWs();
91
- cleanups.push(hub.close);
92
- const a1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
93
- await wireTestTransport(a1, {
94
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
95
- });
96
- await a1.init();
97
- cleanups.push(async () => a1.shutdown());
98
- const aHidden = new MeshStore({
99
- coordinatorPort: a1.coordinatorPort,
100
- hubUrl: hub.url,
101
- });
102
- await wireTestTransport(aHidden, {
103
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
104
- });
105
- await aHidden.init();
106
- cleanups.push(async () => aHidden.shutdown());
107
- await aHidden.registerAgent({
108
- name: "hidden-peer",
109
- harness: "test",
110
- cwd: "/test/hidden",
111
- pid: process.pid,
112
- visibility: "hidden",
113
- tags: [],
114
- });
115
- const aGhost = new MeshStore({
116
- coordinatorPort: a1.coordinatorPort,
117
- hubUrl: hub.url,
118
- });
119
- await wireTestTransport(aGhost, {
120
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
121
- });
122
- await aGhost.init();
123
- cleanups.push(async () => aGhost.shutdown());
124
- await aGhost.registerAgent({
125
- name: "ghost-peer",
126
- harness: "test",
127
- cwd: "/test/ghost",
128
- pid: process.pid,
129
- visibility: "ghost",
130
- tags: [],
131
- });
132
- // A visible control peer on the identical mesh, registered after the hidden/ghost ones -- its own arrival on b1's side is the proof gossip genuinely had time to propagate, ruling out "nothing arrived at all" as a false-negative explanation for hidden/ghost never showing up below.
133
- const aVisible = new MeshStore({
134
- coordinatorPort: a1.coordinatorPort,
135
- hubUrl: hub.url,
136
- });
137
- await wireTestTransport(aVisible, {
138
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
139
- });
140
- await aVisible.init();
141
- cleanups.push(async () => aVisible.shutdown());
142
- await aVisible.registerAgent({
143
- name: "visible-peer",
144
- harness: "test",
145
- cwd: "/test/visible",
146
- pid: process.pid,
147
- visibility: "visible",
148
- tags: [],
149
- });
150
- const b1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
151
- await wireTestTransport(b1, {
152
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
153
- });
154
- await b1.init();
155
- cleanups.push(async () => b1.shutdown());
156
- // Deny-all by default (agent-comms#156) -- a1 needs at least one trusted device to forward at all, and b1 needs the visible control peer's own device-id trusted so its arrival can prove gossip had time to propagate. Trusting only aVisible (never aHidden/aGhost) doesn't weaken this test: hidden/ghost are already filtered out at the source (forwardAdvertsToHub's own AGENT_SELF_GOSSIP_KEY eligibility check, upstream of the trust gate), so this proves the trust gate isn't the reason they never arrive.
157
- a1.addTrustedGateway(b1.peerId);
158
- b1.addTrustedGateway(aVisible.peerId);
159
- await waitFor("b1 to see the visible control peer, proving gossip had time to propagate", async () => {
160
- const agents = await b1.listAgents(b1.peerId);
161
- return agents.some((agent) => agent.id === aVisible.peerId);
162
- });
163
- const agents = await b1.listAgents(b1.peerId);
164
- expect(agents.some((agent) => agent.id === aHidden.peerId)).toBe(false);
165
- expect(agents.some((agent) => agent.id === aGhost.peerId)).toBe(false);
166
- });
167
- it("routes a DM to a remote gateway's own agent through the hub's relay pairing, delivered with the true sender attributed", async () => {
168
- const hub = await realHubOverWs();
169
- cleanups.push(hub.close);
170
- const a1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
171
- await wireTestTransport(a1, {
172
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
173
- });
174
- await a1.init();
175
- cleanups.push(async () => a1.shutdown());
176
- await a1.registerAgent({
177
- name: "a1-gateway",
178
- harness: "test",
179
- cwd: "/test/a1",
180
- pid: process.pid,
181
- visibility: "visible",
182
- tags: [],
183
- });
184
- const b1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
185
- await wireTestTransport(b1, {
186
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
187
- });
188
- await b1.init();
189
- cleanups.push(async () => b1.shutdown());
190
- await b1.registerAgent({
191
- name: "b1-gateway",
192
- harness: "test",
193
- cwd: "/test/b1",
194
- pid: process.pid,
195
- visibility: "visible",
196
- tags: [],
197
- });
198
- // Deny-all by default (agent-comms#156) -- mutual trust: a1 must trust b1 to accept b1's incoming DM request (consume()'s own isTrusted gate on fromDevice), and b1 must trust a1 for sendRoomRequest's own outbound isTrusted gate to route the request (and the later DM) to a1 at all.
199
- a1.addTrustedGateway(b1.peerId);
200
- b1.addTrustedGateway(a1.peerId);
201
- // Two-round DM consent (section 6), exactly like the local-mesh-only dm-admission.integration.test.ts -- b1's own outbound request is what's actually exercised via the new hub-relay fallback, since a1 is not a local peer of b1's own mesh.
202
- const dmPath = dmRoomPath(b1.peerId, a1.peerId);
203
- const requestPromise = b1.requestDmAccess(a1.peerId);
204
- await waitFor("a1 to see b1's pending DM request via the hub", async () => {
205
- await Promise.resolve();
206
- return a1.listPendingRoomJoins().length === 1;
207
- });
208
- const [pending] = a1.listPendingRoomJoins();
209
- expect(pending?.roomPath).toBe(dmPath);
210
- expect(pending?.requesterId).toBe(b1.peerId);
211
- a1.acceptRoomJoin(dmPath, b1.peerId);
212
- await requestPromise;
213
- const message = await b1.sendDm(b1.peerId, a1.peerId, "hello from b1");
214
- await waitFor("a1 to receive the DM via the hub", async () => {
215
- const a1Dms = a1.serialise().dms[dmPath] ?? [];
216
- return a1Dms.some((m) => m.id === message.message.id);
217
- });
218
- const delivered = (a1.serialise().dms[dmPath] ?? []).find((m) => m.id === message.message.id);
219
- expect(delivered).toMatchObject({
220
- from: b1.peerId,
221
- to: a1.peerId,
222
- content: "hello from b1",
223
- });
224
- });
225
- });
226
- //# sourceMappingURL=gateway-forwarding.integration.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gateway-forwarding.integration.test.js","sourceRoot":"","sources":["../../src/test/gateway-forwarding.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,IAAI,QAAQ,GAAG,MAAM,CAAC;AACtB,SAAS,SAAS;IAChB,QAAQ,IAAI,CAAC,CAAC;IACd,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,qLAAqL;AACrL,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,KAAK,GAAG,KAAK,EAAE,EAAU,EAAiB,EAAE,CAChD,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;IAC5B,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,sRAAsR;AACtR,KAAK,UAAU,OAAO,CACpB,IAAY,EACZ,KAA6B;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,MAAM,KAAK,EAAE;YAAE,OAAO;QAC1B,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,yBAAyB,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;AAErC,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,4JAA4J,EAAE,KAAK,IAAI,EAAE;QAC1K,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEzB,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEzC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC;YACvB,eAAe,EAAE,EAAE,CAAC,eAAe;YACnC,MAAM,EAAE,GAAG,CAAC,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,aAAa,CAAC;YACrB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,CAAC,SAAS,CAAC;SAClB,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEzC,mSAAmS;QACnS,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAChC,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAEhC,MAAM,OAAO,CACX,sGAAsG,EACtG,KAAK,IAAI,EAAE;YACT,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAC9C,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC,CACF,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;YAC/B,EAAE,EAAE,EAAE,CAAC,MAAM;YACb,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,UAAU;YACf,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,CAAC,SAAS,CAAC;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEzB,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEzC,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC;YAC5B,eAAe,EAAE,EAAE,CAAC,eAAe;YACnC,MAAM,EAAE,GAAG,CAAC,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,iBAAiB,CAAC,OAAO,EAAE;YAC/B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9C,MAAM,OAAO,CAAC,aAAa,CAAC;YAC1B,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,QAAQ;YACpB,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,eAAe,EAAE,EAAE,CAAC,eAAe;YACnC,MAAM,EAAE,GAAG,CAAC,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,iBAAiB,CAAC,MAAM,EAAE;YAC9B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7C,MAAM,MAAM,CAAC,aAAa,CAAC;YACzB,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,OAAO;YACnB,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,yRAAyR;QACzR,MAAM,QAAQ,GAAG,IAAI,SAAS,CAAC;YAC7B,eAAe,EAAE,EAAE,CAAC,eAAe;YACnC,MAAM,EAAE,GAAG,CAAC,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,iBAAiB,CAAC,QAAQ,EAAE;YAChC,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/C,MAAM,QAAQ,CAAC,aAAa,CAAC;YAC3B,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,eAAe;YACpB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEzC,ufAAuf;QACvf,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAChC,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEtC,MAAM,OAAO,CACX,0EAA0E,EAC1E,KAAK,IAAI,EAAE;YACT,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAC9C,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC,CACF,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wHAAwH,EAAE,KAAK,IAAI,EAAE;QACtI,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEzB,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,aAAa,CAAC;YACrB,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5E,MAAM,iBAAiB,CAAC,EAAE,EAAE;YAC1B,6BAA6B,EAAE,uBAAuB;SACvD,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,aAAa,CAAC;YACrB,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,SAAS;YACrB,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,0RAA0R;QAC1R,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAChC,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAEhC,+OAA+O;QAC/O,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,cAAc,GAAG,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,OAAO,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YACxE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,oBAAoB,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC7C,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,cAAc,CAAC;QAErB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAEvE,MAAM,OAAO,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CACvD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,CACnC,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC;YAC9B,IAAI,EAAE,EAAE,CAAC,MAAM;YACf,EAAE,EAAE,EAAE,CAAC,MAAM;YACb,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=hub-forwarding.unit.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hub-forwarding.unit.test.d.ts","sourceRoot":"","sources":["../../src/test/hub-forwarding.unit.test.ts"],"names":[],"mappings":""}
@@ -1,102 +0,0 @@
1
- /**
2
- * Direct unit tests for forwardAdvertsToHub/pushHubCatchUp's own gateway-trust gate (agent-comms#156) -- previously only exercised indirectly through gateway-forwarding.integration.test.ts's real-hub harness. Uses a fake hub object (isConnected/advertiseDevices) rather than a real HubSession, mirroring gossip-directory.test.ts's own standalone-fixture approach for the sibling gossip-merge function.
3
- */
4
- import { describe, expect, it, vi } from "vitest";
5
- import { forwardAdvertsToHub, makeSendToLocalPeer, pushHubCatchUp, } from "../core/hub-forwarding.js";
6
- import { syntheticAdvert } from "./synthetic-advert.js";
7
- const DEVICE_ID_HEX_LENGTH = 64;
8
- const DEVICE_A_HEX = "a".repeat(DEVICE_ID_HEX_LENGTH);
9
- const DEVICE_B_HEX = "b".repeat(DEVICE_ID_HEX_LENGTH);
10
- function deviceIdBytes(hex) {
11
- const bytes = new Uint8Array(new ArrayBuffer(hex.length / 2));
12
- for (let i = 0; i < bytes.length; i += 1) {
13
- bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
14
- }
15
- return bytes;
16
- }
17
- function entry(hex) {
18
- const device = deviceIdBytes(hex);
19
- return {
20
- device,
21
- advert: syntheticAdvert(device, {
22
- snapshotSeconds: 1,
23
- extensions: { "agent/self": {} },
24
- }),
25
- };
26
- }
27
- function fakeHub(peers = []) {
28
- return {
29
- isConnected: true,
30
- peers: () => peers,
31
- advertiseDevices: vi.fn().mockResolvedValue(undefined),
32
- };
33
- }
34
- describe("forwardAdvertsToHub -- gateway-trust gate", () => {
35
- it("does not advertise anything when no remote gateway is trusted", () => {
36
- const hub = fakeHub();
37
- forwardAdvertsToHub(hub, [entry(DEVICE_A_HEX)], undefined, () => false);
38
- expect(hub.advertiseDevices).not.toHaveBeenCalled();
39
- });
40
- it("advertises once at least one remote gateway is trusted", () => {
41
- const hub = fakeHub();
42
- forwardAdvertsToHub(hub, [entry(DEVICE_A_HEX)], undefined, () => true);
43
- expect(hub.advertiseDevices).toHaveBeenCalledTimes(1);
44
- });
45
- it("still does nothing when not connected, even when trusted", () => {
46
- const hub = fakeHub();
47
- hub.isConnected = false;
48
- forwardAdvertsToHub(hub, [entry(DEVICE_A_HEX)], undefined, () => true);
49
- expect(hub.advertiseDevices).not.toHaveBeenCalled();
50
- });
51
- });
52
- describe("pushHubCatchUp -- gateway-trust gate", () => {
53
- it("does not push the catch-up when no remote gateway is trusted", () => {
54
- const hub = fakeHub();
55
- const knownDevices = new Map([[DEVICE_A_HEX, entry(DEVICE_A_HEX).advert]]);
56
- pushHubCatchUp(hub, knownDevices, undefined, () => false);
57
- expect(hub.advertiseDevices).not.toHaveBeenCalled();
58
- });
59
- it("pushes the catch-up once at least one remote gateway is trusted", () => {
60
- const hub = fakeHub();
61
- const knownDevices = new Map([[DEVICE_A_HEX, entry(DEVICE_A_HEX).advert]]);
62
- pushHubCatchUp(hub, knownDevices, undefined, () => true);
63
- expect(hub.advertiseDevices).toHaveBeenCalledTimes(1);
64
- });
65
- });
66
- describe("pushHubCatchUp -- devices learned from the hub", () => {
67
- it("advertises only the devices this side fronts, never one it learned from the hub", () => {
68
- const hub = fakeHub([DEVICE_B_HEX]);
69
- const knownDevices = new Map([
70
- [DEVICE_A_HEX, entry(DEVICE_A_HEX).advert],
71
- [DEVICE_B_HEX, entry(DEVICE_B_HEX).advert],
72
- ]);
73
- pushHubCatchUp(hub, knownDevices, undefined, () => true);
74
- const advertised = hub.advertiseDevices.mock.calls.flatMap(([entries]) => entries.map((forwarded) => forwarded.advert.device));
75
- expect(advertised).toEqual([entry(DEVICE_A_HEX).advert.device]);
76
- });
77
- it("advertises nothing when every known device was learned from the hub", () => {
78
- const hub = fakeHub([DEVICE_A_HEX]);
79
- const knownDevices = new Map([[DEVICE_A_HEX, entry(DEVICE_A_HEX).advert]]);
80
- pushHubCatchUp(hub, knownDevices, undefined, () => true);
81
- expect(hub.advertiseDevices).not.toHaveBeenCalled();
82
- });
83
- });
84
- describe("makeSendToLocalPeer -- synchronous no-session signal", () => {
85
- const command = { verb: "room:member", params: {} };
86
- const scope = { kind: "room", path: "owner/room" };
87
- it("returns undefined synchronously, never a Promise, when no local session exists for the device", () => {
88
- const send = makeSendToLocalPeer(new Map());
89
- const result = send(DEVICE_A_HEX, command, scope, undefined);
90
- // HubSession branches on `forwarded !== undefined` to decide whether to fall back to local dispatch, so the no-session signal has to be a plain undefined: an async wrapper would return a Promise here (always defined) and silently disable that fallback for every device this gateway doesn't front.
91
- expect(result).toBeUndefined();
92
- });
93
- it("forwards to the local session and returns its own outcome when one exists", async () => {
94
- const outcome = { result: "error", code: "not_connected" };
95
- const sendManageRequest = vi.fn().mockResolvedValue(outcome);
96
- const send = makeSendToLocalPeer(new Map([[DEVICE_A_HEX, { sendManageRequest }]]));
97
- const result = send(DEVICE_A_HEX, command, scope, undefined);
98
- await expect(result).resolves.toBe(outcome);
99
- expect(sendManageRequest).toHaveBeenCalledWith(command, scope, undefined, undefined);
100
- });
101
- });
102
- //# sourceMappingURL=hub-forwarding.unit.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hub-forwarding.unit.test.js","sourceRoot":"","sources":["../../src/test/hub-forwarding.unit.test.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Integration test for agent-comms#184: a hub-relayed manage-request explicitly addressed (relay-data's own `to-device` field, surfaced as `IncomingManageRequest.toDevice` since wire-mesh#170, wire-mesh-core 1.48.1) to a NON-gateway local peer must be routed on to that peer's own local mesh session, not dispatched against the gateway's own local state the way gateway-forwarding.integration.test.ts's "routes a DM to a remote gateway's own agent" case already covers for the gateway itself. Also proves the request's true remote origin (b1) survives the forwarding hop intact -- room-router.ts's own "on-behalf-of" mechanism, not just delivery reaching the right recipient.
3
- *
4
- * Same three-party shape as gateway-forwarding.integration.test.ts: machine A has a coordinator (a1, the gateway, dialled to the hub) and a second, ordinary local peer (a2) that is never itself connected to the hub. Machine B (b1) reaches a2 purely through the hub's relay pairing with a1 -- if toDevice routing didn't exist, b1's request would land at a1's own DM state instead of a2's, since a1's hub session has no way to tell the two apart.
5
- */
6
- export {};
7
- //# sourceMappingURL=hub-todevice-routing.integration.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hub-todevice-routing.integration.test.d.ts","sourceRoot":"","sources":["../../src/test/hub-todevice-routing.integration.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,121 +0,0 @@
1
- /**
2
- * Integration test for agent-comms#184: a hub-relayed manage-request explicitly addressed (relay-data's own `to-device` field, surfaced as `IncomingManageRequest.toDevice` since wire-mesh#170, wire-mesh-core 1.48.1) to a NON-gateway local peer must be routed on to that peer's own local mesh session, not dispatched against the gateway's own local state the way gateway-forwarding.integration.test.ts's "routes a DM to a remote gateway's own agent" case already covers for the gateway itself. Also proves the request's true remote origin (b1) survives the forwarding hop intact -- room-router.ts's own "on-behalf-of" mechanism, not just delivery reaching the right recipient.
3
- *
4
- * Same three-party shape as gateway-forwarding.integration.test.ts: machine A has a coordinator (a1, the gateway, dialled to the hub) and a second, ordinary local peer (a2) that is never itself connected to the hub. Machine B (b1) reaches a2 purely through the hub's relay pairing with a1 -- if toDevice routing didn't exist, b1's request would land at a1's own DM state instead of a2's, since a1's hub session has no way to tell the two apart.
5
- */
6
- import { afterEach, describe, expect, it } from "vitest";
7
- import { MeshStore } from "../core/mesh-store.js";
8
- import { dmRoomPath } from "../core/room-path.js";
9
- import { realHubOverWs, TeardownStack } from "./hub-helpers.js";
10
- import { wireTestTransport } from "./test-transport.js";
11
- let nextPort = 22_500;
12
- function freshPort() {
13
- nextPort += 1;
14
- return nextPort;
15
- }
16
- /** Short enough that a gossip re-advertisement (which carries a1's forwarded advert of a2) fires within a test's own poll budget, matching gateway-forwarding.integration.test.ts's own choice. */
17
- const FAST_GOSSIP_INTERVAL_MS = 50;
18
- const POLL_ATTEMPTS = 100;
19
- const POLL_INTERVAL_MS = 50;
20
- const sleep = async (ms) => new Promise((resolve) => {
21
- setTimeout(resolve, ms);
22
- });
23
- /** Polls an async predicate until it holds -- gateway-forwarding.integration.test.ts's own established pattern for this, duplicated here rather than shared, since neither file exports it. */
24
- async function waitFor(what, check) {
25
- for (let i = 0; i < POLL_ATTEMPTS; i++) {
26
- if (await check())
27
- return;
28
- await sleep(POLL_INTERVAL_MS);
29
- }
30
- expect(false, `timed out waiting for ${what}`).toBeTruthy();
31
- }
32
- const cleanups = new TeardownStack();
33
- afterEach(async () => {
34
- await cleanups.run();
35
- });
36
- describe("hub toDevice routing", () => {
37
- it("routes a DM addressed to a non-gateway local peer to that peer's own state, not the gateway's", async () => {
38
- const hub = await realHubOverWs();
39
- cleanups.push(hub.close);
40
- const a1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
41
- await wireTestTransport(a1, {
42
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
43
- });
44
- await a1.init();
45
- cleanups.push(async () => a1.shutdown());
46
- await a1.registerAgent({
47
- name: "a1-gateway",
48
- harness: "test",
49
- cwd: "/test/a1",
50
- pid: process.pid,
51
- visibility: "visible",
52
- tags: [],
53
- });
54
- const a2 = new MeshStore({
55
- coordinatorPort: a1.coordinatorPort,
56
- hubUrl: hub.url,
57
- });
58
- await wireTestTransport(a2, {
59
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
60
- });
61
- await a2.init();
62
- cleanups.push(async () => a2.shutdown());
63
- await a2.registerAgent({
64
- name: "a2-local-peer",
65
- harness: "test",
66
- cwd: "/test/a2",
67
- pid: process.pid,
68
- visibility: "visible",
69
- tags: [],
70
- });
71
- const b1 = new MeshStore({ coordinatorPort: freshPort(), hubUrl: hub.url });
72
- await wireTestTransport(b1, {
73
- presenceReadvertiseIntervalMs: FAST_GOSSIP_INTERVAL_MS,
74
- });
75
- await b1.init();
76
- cleanups.push(async () => b1.shutdown());
77
- await b1.registerAgent({
78
- name: "b1-remote",
79
- harness: "test",
80
- cwd: "/test/b1",
81
- pid: process.pid,
82
- visibility: "visible",
83
- tags: [],
84
- });
85
- // Deny-all by default (agent-comms#156): a1 needs a trusted remote gateway to forward a2's advert onto the hub at all (forwardAdvertsToHub's own hasAny gate), b1 needs a2's own device-id specifically trusted for sendRoomRequest's own outbound isTrusted gate to route to it via the hub, and a1 needs b1 trusted for consume()'s own inbound gate on the relayed request's fromDevice.
86
- a1.addTrustedGateway(b1.peerId);
87
- b1.addTrustedGateway(a2.peerId);
88
- // Waits for b1 to actually learn of a2 via the hub's own gossip/catch-up (mirroring gateway-forwarding.integration.test.ts's own first test) before addressing a request to it -- otherwise the relay hub has no adjacency entry for a2's device yet and silently drops the relay-connect (spec/relay-hub's own documented behaviour for an unknown target-device), which would time out for a reason unrelated to toDevice routing itself.
89
- await waitFor("b1 to learn of a2 via the hub", async () => {
90
- const agents = await b1.listAgents(b1.peerId);
91
- return agents.some((agent) => agent.id === a2.peerId);
92
- });
93
- const dmPath = dmRoomPath(b1.peerId, a2.peerId);
94
- const requestPromise = b1.requestDmAccess(a2.peerId);
95
- await waitFor("a2 (not a1) to see b1's pending DM request, routed through a1's hub session via toDevice", async () => {
96
- await Promise.resolve();
97
- return a2.listPendingRoomJoins().length === 1;
98
- });
99
- const [pending] = a2.listPendingRoomJoins();
100
- expect(pending?.roomPath).toBe(dmPath);
101
- expect(pending?.requesterId).toBe(b1.peerId);
102
- // The gateway's own DM state must never have seen this request: proves toDevice routing actually redirected it to a2 rather than a1 additionally absorbing a copy.
103
- expect(a1.listPendingRoomJoins()).toHaveLength(0);
104
- a2.acceptRoomJoin(dmPath, b1.peerId);
105
- await requestPromise;
106
- const message = await b1.sendDm(b1.peerId, a2.peerId, "hello from b1");
107
- await waitFor("a2 to receive the DM via the hub, routed through a1", async () => {
108
- const a2Dms = a2.serialise().dms[dmPath] ?? [];
109
- return a2Dms.some((m) => m.id === message.message.id);
110
- });
111
- const delivered = (a2.serialise().dms[dmPath] ?? []).find((m) => m.id === message.message.id);
112
- expect(delivered).toMatchObject({
113
- from: b1.peerId,
114
- to: a2.peerId,
115
- content: "hello from b1",
116
- });
117
- // Again: the gateway's own DM state must stay empty throughout -- the message belongs to a2, never a1.
118
- expect(a1.serialise().dms[dmPath] ?? []).toHaveLength(0);
119
- });
120
- });
121
- //# sourceMappingURL=hub-todevice-routing.integration.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hub-todevice-routing.integration.test.js","sourceRoot":"","sources":["../../src/test/hub-todevice-routing.integration.test.ts"],"names":[],"mappings":"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"}