agent-comms 3.8.0 → 3.10.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 (193) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +5 -1
  4. package/dist/bridges/cc-peer/default-front.d.ts +20 -0
  5. package/dist/bridges/cc-peer/default-front.d.ts.map +1 -0
  6. package/dist/bridges/cc-peer/default-front.js +28 -0
  7. package/dist/bridges/cc-peer/default-front.js.map +1 -0
  8. package/dist/bridges/cc-peer/front-controller.d.ts +50 -0
  9. package/dist/bridges/cc-peer/front-controller.d.ts.map +1 -0
  10. package/dist/bridges/cc-peer/front-controller.js +84 -0
  11. package/dist/bridges/cc-peer/front-controller.js.map +1 -0
  12. package/dist/bridges/cc-peer/front-relay.d.ts +42 -0
  13. package/dist/bridges/cc-peer/front-relay.d.ts.map +1 -0
  14. package/dist/bridges/cc-peer/front-relay.js +43 -0
  15. package/dist/bridges/cc-peer/front-relay.js.map +1 -0
  16. package/dist/bridges/cc-peer/front-runtime.d.ts +18 -0
  17. package/dist/bridges/cc-peer/front-runtime.d.ts.map +1 -0
  18. package/dist/bridges/cc-peer/front-runtime.js +76 -0
  19. package/dist/bridges/cc-peer/front-runtime.js.map +1 -0
  20. package/dist/bridges/cc-peer/front.d.ts +32 -0
  21. package/dist/bridges/cc-peer/front.d.ts.map +1 -0
  22. package/dist/bridges/cc-peer/front.js +37 -0
  23. package/dist/bridges/cc-peer/front.js.map +1 -0
  24. package/dist/bridges/cc-peer/run.d.ts.map +1 -1
  25. package/dist/bridges/cc-peer/run.js +2 -0
  26. package/dist/bridges/cc-peer/run.js.map +1 -1
  27. package/dist/bridges/claude-code/channel.d.ts.map +1 -1
  28. package/dist/bridges/claude-code/channel.js +2 -0
  29. package/dist/bridges/claude-code/channel.js.map +1 -1
  30. package/dist/bridges/codex/tool.d.ts.map +1 -1
  31. package/dist/bridges/codex/tool.js +2 -0
  32. package/dist/bridges/codex/tool.js.map +1 -1
  33. package/dist/bridges/mcp/server.d.ts.map +1 -1
  34. package/dist/bridges/mcp/server.js +2 -0
  35. package/dist/bridges/mcp/server.js.map +1 -1
  36. package/dist/bridges/opencode/plugin.d.ts.map +1 -1
  37. package/dist/bridges/opencode/plugin.js +2 -0
  38. package/dist/bridges/opencode/plugin.js.map +1 -1
  39. package/dist/bridges/pi/extension.d.ts.map +1 -1
  40. package/dist/bridges/pi/extension.js +2 -0
  41. package/dist/bridges/pi/extension.js.map +1 -1
  42. package/dist/bridges/user/controller.d.ts.map +1 -1
  43. package/dist/bridges/user/controller.js +4 -0
  44. package/dist/bridges/user/controller.js.map +1 -1
  45. package/dist/core/agent-registry.d.ts +3 -0
  46. package/dist/core/agent-registry.d.ts.map +1 -1
  47. package/dist/core/agent-registry.js +25 -14
  48. package/dist/core/agent-registry.js.map +1 -1
  49. package/dist/core/bind-retry.d.ts +10 -0
  50. package/dist/core/bind-retry.d.ts.map +1 -0
  51. package/dist/core/bind-retry.js +24 -0
  52. package/dist/core/bind-retry.js.map +1 -0
  53. package/dist/core/bridge-mesh.d.ts +9 -0
  54. package/dist/core/bridge-mesh.d.ts.map +1 -1
  55. package/dist/core/bridge-mesh.js +20 -1
  56. package/dist/core/bridge-mesh.js.map +1 -1
  57. package/dist/core/dm-token-verification.d.ts +28 -0
  58. package/dist/core/dm-token-verification.d.ts.map +1 -0
  59. package/dist/core/dm-token-verification.js +38 -0
  60. package/dist/core/dm-token-verification.js.map +1 -0
  61. package/dist/core/gossip-directory.d.ts +4 -1
  62. package/dist/core/gossip-directory.d.ts.map +1 -1
  63. package/dist/core/gossip-directory.js +11 -1
  64. package/dist/core/gossip-directory.js.map +1 -1
  65. package/dist/core/hub-forwarding.d.ts +13 -0
  66. package/dist/core/hub-forwarding.d.ts.map +1 -0
  67. package/dist/core/hub-forwarding.js +30 -0
  68. package/dist/core/hub-forwarding.js.map +1 -0
  69. package/dist/core/hub-session.d.ts +14 -4
  70. package/dist/core/hub-session.d.ts.map +1 -1
  71. package/dist/core/hub-session.js +44 -12
  72. package/dist/core/hub-session.js.map +1 -1
  73. package/dist/core/identity-store.d.ts +8 -0
  74. package/dist/core/identity-store.d.ts.map +1 -1
  75. package/dist/core/identity-store.js +18 -0
  76. package/dist/core/identity-store.js.map +1 -1
  77. package/dist/core/index.d.ts +3 -1
  78. package/dist/core/index.d.ts.map +1 -1
  79. package/dist/core/index.js +2 -1
  80. package/dist/core/index.js.map +1 -1
  81. package/dist/core/mesh-store-shared.d.ts +5 -1
  82. package/dist/core/mesh-store-shared.d.ts.map +1 -1
  83. package/dist/core/mesh-store-shared.js +7 -0
  84. package/dist/core/mesh-store-shared.js.map +1 -1
  85. package/dist/core/mesh-store.d.ts +11 -2
  86. package/dist/core/mesh-store.d.ts.map +1 -1
  87. package/dist/core/mesh-store.js +24 -4
  88. package/dist/core/mesh-store.js.map +1 -1
  89. package/dist/core/peer-lifecycle.d.ts +4 -0
  90. package/dist/core/peer-lifecycle.d.ts.map +1 -1
  91. package/dist/core/peer-lifecycle.js +18 -0
  92. package/dist/core/peer-lifecycle.js.map +1 -1
  93. package/dist/core/room-lifecycle.d.ts +12 -1
  94. package/dist/core/room-lifecycle.d.ts.map +1 -1
  95. package/dist/core/room-lifecycle.js +47 -3
  96. package/dist/core/room-lifecycle.js.map +1 -1
  97. package/dist/core/room-messaging.d.ts +2 -2
  98. package/dist/core/room-messaging.d.ts.map +1 -1
  99. package/dist/core/room-messaging.js +1 -1
  100. package/dist/core/room-messaging.js.map +1 -1
  101. package/dist/core/room-protocol.d.ts +1 -1
  102. package/dist/core/room-protocol.d.ts.map +1 -1
  103. package/dist/core/room-protocol.js +17 -1
  104. package/dist/core/room-protocol.js.map +1 -1
  105. package/dist/core/user-identity.d.ts +10 -0
  106. package/dist/core/user-identity.d.ts.map +1 -1
  107. package/dist/core/user-identity.js +47 -9
  108. package/dist/core/user-identity.js.map +1 -1
  109. package/dist/core/wire-mesh-transport.d.ts +5 -3
  110. package/dist/core/wire-mesh-transport.d.ts.map +1 -1
  111. package/dist/core/wire-mesh-transport.js +25 -24
  112. package/dist/core/wire-mesh-transport.js.map +1 -1
  113. package/dist/test/agent-registry.test.js +56 -0
  114. package/dist/test/agent-registry.test.js.map +1 -1
  115. package/dist/test/bind-retry.test.d.ts +2 -0
  116. package/dist/test/bind-retry.test.d.ts.map +1 -0
  117. package/dist/test/bind-retry.test.js +42 -0
  118. package/dist/test/bind-retry.test.js.map +1 -0
  119. package/dist/test/bridge-mesh.test.js +16 -2
  120. package/dist/test/bridge-mesh.test.js.map +1 -1
  121. package/dist/test/cc-peer-default-front.test.d.ts +2 -0
  122. package/dist/test/cc-peer-default-front.test.d.ts.map +1 -0
  123. package/dist/test/cc-peer-default-front.test.js +71 -0
  124. package/dist/test/cc-peer-default-front.test.js.map +1 -0
  125. package/dist/test/cc-peer-front-controller.test.d.ts +2 -0
  126. package/dist/test/cc-peer-front-controller.test.d.ts.map +1 -0
  127. package/dist/test/cc-peer-front-controller.test.js +206 -0
  128. package/dist/test/cc-peer-front-controller.test.js.map +1 -0
  129. package/dist/test/cc-peer-front-relay.test.d.ts +2 -0
  130. package/dist/test/cc-peer-front-relay.test.d.ts.map +1 -0
  131. package/dist/test/cc-peer-front-relay.test.js +177 -0
  132. package/dist/test/cc-peer-front-relay.test.js.map +1 -0
  133. package/dist/test/cc-peer-front.test.d.ts +2 -0
  134. package/dist/test/cc-peer-front.test.d.ts.map +1 -0
  135. package/dist/test/cc-peer-front.test.js +109 -0
  136. package/dist/test/cc-peer-front.test.js.map +1 -0
  137. package/dist/test/delivery-engine-delivery.test.js +2 -0
  138. package/dist/test/delivery-engine-delivery.test.js.map +1 -1
  139. package/dist/test/delivery-engine-directed-notify.test.js +2 -0
  140. package/dist/test/delivery-engine-directed-notify.test.js.map +1 -1
  141. package/dist/test/delivery-engine.test.js +2 -0
  142. package/dist/test/delivery-engine.test.js.map +1 -1
  143. package/dist/test/dm-send-capability-admission.integration.test.d.ts +5 -0
  144. package/dist/test/dm-send-capability-admission.integration.test.d.ts.map +1 -0
  145. package/dist/test/dm-send-capability-admission.integration.test.js +90 -0
  146. package/dist/test/dm-send-capability-admission.integration.test.js.map +1 -0
  147. package/dist/test/dm-token-verification.test.d.ts +5 -0
  148. package/dist/test/dm-token-verification.test.d.ts.map +1 -0
  149. package/dist/test/dm-token-verification.test.js +164 -0
  150. package/dist/test/dm-token-verification.test.js.map +1 -0
  151. package/dist/test/gateway-forwarding.integration.test.d.ts +7 -0
  152. package/dist/test/gateway-forwarding.integration.test.d.ts.map +1 -0
  153. package/dist/test/gateway-forwarding.integration.test.js +185 -0
  154. package/dist/test/gateway-forwarding.integration.test.js.map +1 -0
  155. package/dist/test/identity-restart.integration.test.js +6 -0
  156. package/dist/test/identity-restart.integration.test.js.map +1 -1
  157. package/dist/test/identity-store.test.js +45 -1
  158. package/dist/test/identity-store.test.js.map +1 -1
  159. package/dist/test/mesh-e2e.integration.test.js +7 -1
  160. package/dist/test/mesh-e2e.integration.test.js.map +1 -1
  161. package/dist/test/mesh-smoke.runner.js +4 -1
  162. package/dist/test/mesh-smoke.runner.js.map +1 -1
  163. package/dist/test/mesh-store-orchestration.test.js +73 -2
  164. package/dist/test/mesh-store-orchestration.test.js.map +1 -1
  165. package/dist/test/peer-lifecycle.test.js +61 -2
  166. package/dist/test/peer-lifecycle.test.js.map +1 -1
  167. package/dist/test/room-join-admission.test.js +6 -0
  168. package/dist/test/room-join-admission.test.js.map +1 -1
  169. package/dist/test/room-lifecycle-membership.test.js +2 -0
  170. package/dist/test/room-lifecycle-membership.test.js.map +1 -1
  171. package/dist/test/room-lifecycle-remote.test.js +2 -0
  172. package/dist/test/room-lifecycle-remote.test.js.map +1 -1
  173. package/dist/test/room-lifecycle.test.js +2 -0
  174. package/dist/test/room-lifecycle.test.js.map +1 -1
  175. package/dist/test/room-messaging-durable-send.test.js +3 -1
  176. package/dist/test/room-messaging-durable-send.test.js.map +1 -1
  177. package/dist/test/room-messaging.test.js +25 -6
  178. package/dist/test/room-messaging.test.js.map +1 -1
  179. package/dist/test/room-protocol-admission.test.js +2 -0
  180. package/dist/test/room-protocol-admission.test.js.map +1 -1
  181. package/dist/test/room-protocol-notify.test.js +2 -0
  182. package/dist/test/room-protocol-notify.test.js.map +1 -1
  183. package/dist/test/room-protocol.test.js +2 -0
  184. package/dist/test/room-protocol.test.js.map +1 -1
  185. package/dist/test/room-send-retry.integration.test.js +6 -0
  186. package/dist/test/room-send-retry.integration.test.js.map +1 -1
  187. package/dist/test/test-transport.d.ts +1 -1
  188. package/dist/test/test-transport.d.ts.map +1 -1
  189. package/dist/test/test-transport.js +10 -2
  190. package/dist/test/test-transport.js.map +1 -1
  191. package/dist/test/user-identity.test.js +62 -1
  192. package/dist/test/user-identity.test.js.map +1 -1
  193. package/package.json +1 -1
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Unit tests for CcPeerFront -- the coordinator-only periodic controller (front-controller.ts) that attaches/detaches fronted sessions on each tick, driven by injected roster/probe/attach/detach/inbound-routing dependencies so it's testable with fake timers and no real cc-peer/MeshStore involved.
3
+ */
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { CcPeerFront, } from "../bridges/cc-peer/front-controller.js";
6
+ const POLL_INTERVAL_MS = 5000;
7
+ /** How many poll intervals stop() must survive with zero further polling -- arbitrary beyond "more than one", chosen to make a lingering timer's own recurrence visible rather than a one-off fluke (matches stale-agent-checker.test.ts's own HALT_CHECK_INTERVAL_COUNT convention). */
8
+ const HALT_CHECK_INTERVAL_COUNT = 3;
9
+ /** A pid standing in for a real live agent-comms bridge holding a slot's lock -- arbitrary beyond "a plausible process id", used only to prove the yield path treats "probe returned a pid" as "session now fronts itself". */
10
+ const LIVE_LOCK_HOLDER_PID = 4242;
11
+ function rosterEntry(overrides = {}) {
12
+ return {
13
+ pid: 111,
14
+ cwd: "/tmp/project",
15
+ version: "2.1.269",
16
+ messagingSocketPath: "/tmp/sock-111",
17
+ ...overrides,
18
+ };
19
+ }
20
+ /** Unwraps the resolved value of a mocked attach() call's Nth invocation, asserting it actually happened -- vi's own mock.results indexing returns undefined for a call that never occurred, which every call site here has already asserted against via toHaveBeenCalledTimes. */
21
+ async function attachResult(attach, callIndex = 0) {
22
+ const value = await attach.mock.results[callIndex]?.value;
23
+ if (value === undefined) {
24
+ throw new Error(`attach() was never called at index ${String(callIndex)}`);
25
+ }
26
+ return value;
27
+ }
28
+ function stubRecord(entry) {
29
+ return {
30
+ pid: entry.pid,
31
+ cwd: entry.cwd,
32
+ messagingSocketPath: entry.messagingSocketPath,
33
+ handleInbound: vi.fn(),
34
+ detached: false,
35
+ };
36
+ }
37
+ function harness(initialRoster) {
38
+ const roster = [...initialRoster];
39
+ const attach = vi.fn(async (entry) => Promise.resolve(stubRecord(entry)));
40
+ const detach = vi.fn(async (record) => {
41
+ record.detached = true;
42
+ return Promise.resolve();
43
+ });
44
+ const probeSlotOwner = vi.fn(() => undefined);
45
+ const onError = vi.fn();
46
+ const deps = {
47
+ listRoster: async () => Promise.resolve([...roster]),
48
+ probeSlotOwner,
49
+ attach,
50
+ detach,
51
+ pollIntervalMs: POLL_INTERVAL_MS,
52
+ onError,
53
+ };
54
+ return {
55
+ front: new CcPeerFront(deps),
56
+ deps,
57
+ roster,
58
+ attach,
59
+ detach,
60
+ probeSlotOwner,
61
+ onError,
62
+ };
63
+ }
64
+ describe("CcPeerFront — start/stop", () => {
65
+ beforeEach(() => {
66
+ vi.useFakeTimers();
67
+ });
68
+ afterEach(() => {
69
+ vi.useRealTimers();
70
+ });
71
+ it("does nothing until start() is called", async () => {
72
+ const h = harness([rosterEntry()]);
73
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS * 2);
74
+ expect(h.attach).not.toHaveBeenCalled();
75
+ h.front.stop();
76
+ });
77
+ it("attaches a session on the first poll tick", async () => {
78
+ const h = harness([rosterEntry({ pid: 1 })]);
79
+ h.front.start();
80
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
81
+ expect(h.attach).toHaveBeenCalledTimes(1);
82
+ await h.front.stop();
83
+ });
84
+ it("calling start() twice does not create a second timer", async () => {
85
+ const setIntervalSpy = vi.spyOn(globalThis, "setInterval");
86
+ const h = harness([]);
87
+ h.front.start();
88
+ h.front.start();
89
+ expect(setIntervalSpy).toHaveBeenCalledTimes(1);
90
+ await h.front.stop();
91
+ });
92
+ it("stop() halts further polling", async () => {
93
+ const h = harness([rosterEntry({ pid: 1 })]);
94
+ h.front.start();
95
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
96
+ expect(h.attach).toHaveBeenCalledTimes(1);
97
+ await h.front.stop();
98
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS * HALT_CHECK_INTERVAL_COUNT);
99
+ expect(h.attach).toHaveBeenCalledTimes(1);
100
+ });
101
+ it("stop() detaches every currently-fronted session", async () => {
102
+ const h = harness([rosterEntry({ pid: 1 })]);
103
+ h.front.start();
104
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
105
+ expect(h.attach).toHaveBeenCalledTimes(1);
106
+ const record = await attachResult(h.attach);
107
+ await h.front.stop();
108
+ expect(h.detach).toHaveBeenCalledTimes(1);
109
+ expect(record.detached).toBe(true);
110
+ });
111
+ });
112
+ describe("CcPeerFront — attach/detach diffing across ticks", () => {
113
+ beforeEach(() => {
114
+ vi.useFakeTimers();
115
+ });
116
+ afterEach(() => {
117
+ vi.useRealTimers();
118
+ });
119
+ it("does not re-attach a session already fronted from a previous tick", async () => {
120
+ const h = harness([rosterEntry({ pid: 1 })]);
121
+ h.front.start();
122
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
123
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
124
+ expect(h.attach).toHaveBeenCalledTimes(1);
125
+ await h.front.stop();
126
+ });
127
+ it("attaches a session that appears in the roster on a later tick", async () => {
128
+ const h = harness([]);
129
+ h.front.start();
130
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
131
+ expect(h.attach).not.toHaveBeenCalled();
132
+ h.roster.push(rosterEntry({ pid: 2 }));
133
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
134
+ expect(h.attach).toHaveBeenCalledTimes(1);
135
+ await h.front.stop();
136
+ });
137
+ it("detaches a session that has exited (no longer in the roster)", async () => {
138
+ const h = harness([rosterEntry({ pid: 1 })]);
139
+ h.front.start();
140
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
141
+ expect(h.attach).toHaveBeenCalledTimes(1);
142
+ h.roster.length = 0;
143
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
144
+ expect(h.detach).toHaveBeenCalledTimes(1);
145
+ await h.front.stop();
146
+ });
147
+ it("yields a session the moment its own slot is claimed by a live bridge, without re-attaching it", async () => {
148
+ const h = harness([rosterEntry({ pid: 1, cwd: "/tmp/yields" })]);
149
+ h.front.start();
150
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
151
+ expect(h.attach).toHaveBeenCalledTimes(1);
152
+ const record = await attachResult(h.attach);
153
+ // A real agent-comms bridge has since taken the slot over -- the probe now reports its pid.
154
+ h.probeSlotOwner.mockReturnValue(LIVE_LOCK_HOLDER_PID);
155
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
156
+ expect(h.detach).toHaveBeenCalledTimes(1);
157
+ expect(record.detached).toBe(true);
158
+ expect(h.attach).toHaveBeenCalledTimes(1);
159
+ // Even if the slot frees up again later, this front never re-attaches on its own within the same run -- the session is expected to keep its own bridge running from here.
160
+ h.probeSlotOwner.mockReturnValue(undefined);
161
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
162
+ expect(h.attach).toHaveBeenCalledTimes(2);
163
+ await h.front.stop();
164
+ });
165
+ it("routes an inbound message to the fronted session it came from", async () => {
166
+ const h = harness([
167
+ rosterEntry({ pid: 1, messagingSocketPath: "/tmp/sock-1" }),
168
+ ]);
169
+ h.front.start();
170
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
171
+ const record = await attachResult(h.attach);
172
+ h.front.handleInboundMessage({ from: "uds:/tmp/sock-1", body: "hi" });
173
+ expect(record.handleInbound).toHaveBeenCalledWith({
174
+ from: "uds:/tmp/sock-1",
175
+ body: "hi",
176
+ });
177
+ await h.front.stop();
178
+ });
179
+ it("silently ignores an inbound message matching no fronted session", async () => {
180
+ const h = harness([]);
181
+ expect(() => h.front.handleInboundMessage({ from: "uds:/tmp/unknown", body: "hi" })).not.toThrow();
182
+ });
183
+ it("reports a roster failure via onError rather than throwing out of the poll timer", async () => {
184
+ const h = harness([]);
185
+ const failure = new Error("roster unavailable");
186
+ h.deps.listRoster = async () => Promise.reject(failure);
187
+ h.front.start();
188
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
189
+ expect(h.onError).toHaveBeenCalledWith(failure);
190
+ await h.front.stop();
191
+ });
192
+ it("reports an attach failure via onError without losing track of other sessions", async () => {
193
+ const h = harness([
194
+ rosterEntry({ pid: 1, cwd: "/tmp/a" }),
195
+ rosterEntry({ pid: 2, cwd: "/tmp/b" }),
196
+ ]);
197
+ const failure = new Error("cc-peer send failed");
198
+ h.attach.mockImplementationOnce(async () => Promise.reject(failure));
199
+ h.front.start();
200
+ await vi.advanceTimersByTimeAsync(POLL_INTERVAL_MS);
201
+ expect(h.onError).toHaveBeenCalledWith(failure);
202
+ expect(h.attach).toHaveBeenCalledTimes(2);
203
+ await h.front.stop();
204
+ });
205
+ });
206
+ //# sourceMappingURL=cc-peer-front-controller.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-peer-front-controller.test.js","sourceRoot":"","sources":["../../src/test/cc-peer-front-controller.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EACL,WAAW,GAGZ,MAAM,wCAAwC,CAAC;AAGhD,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,yRAAyR;AACzR,MAAM,yBAAyB,GAAG,CAAC,CAAC;AACpC,+NAA+N;AAC/N,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAElC,SAAS,WAAW,CAClB,YAAsD,EAAE;IAExD,OAAO;QACL,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,cAAc;QACnB,OAAO,EAAE,SAAS;QAClB,mBAAmB,EAAE,eAAe;QACpC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAMD,mRAAmR;AACnR,KAAK,UAAU,YAAY,CACzB,MAAuE,EACvE,SAAS,GAAG,CAAC;IAEb,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;IAC1D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,KAAsC;IACxD,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,aAAa,EAAE,EAAE,CAAC,EAAE,EAAyC;QAC7D,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC;AAgBD,SAAS,OAAO,CAAC,aAA+C;IAC9D,MAAM,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,CAAwC,KAAK,EAAE,KAAK,EAAE,EAAE,CAC1E,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CACnC,CAAC;IACF,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,CAClB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC,CACF,CAAC;IACF,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,CAC1B,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAuD,CAAC;IAC7E,MAAM,IAAI,GAAgC;QACxC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QACpD,cAAc;QACd,MAAM;QACN,MAAM;QACN,cAAc,EAAE,gBAAgB;QAChC,OAAO;KACR,CAAC;IACF,OAAO;QACL,KAAK,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC;QAC5B,IAAI;QACJ,MAAM;QACN,MAAM;QACN,MAAM;QACN,cAAc;QACd,OAAO;KACR,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACxC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,cAAc,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,cAAc,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACrB,MAAM,EAAE,CAAC,wBAAwB,CAC/B,gBAAgB,GAAG,yBAAyB,CAC7C,CAAC;QACF,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAErB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAExC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1C,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACpB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+FAA+F,EAAE,KAAK,IAAI,EAAE;QAC7G,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE5C,4FAA4F;QAC5F,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QAEpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1C,0KAA0K;QAC1K,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,CAAC,GAAG,OAAO,CAAC;YAChB,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,mBAAmB,EAAE,aAAa,EAAE,CAAC;SAC5D,CAAC,CAAC;QACH,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE5C,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC;YAChD,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,EAAE,CACV,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CACvE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAChD,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC5F,MAAM,CAAC,GAAG,OAAO,CAAC;YAChB,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;YACtC,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;SACvC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACjD,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;QAEpD,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cc-peer-front-relay.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-peer-front-relay.test.d.ts","sourceRoot":"","sources":["../../src/test/cc-peer-front-relay.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Direct, DI-based unit tests for buildFrontedSessionRecord/detachFrontedSession -- the pure relay wiring front-relay.ts exposes, tested against fake store/tool/peer objects rather than a real MeshStore or local Claude Code session, mirroring cc-peer-bridge.test.ts's own approach for the one-shot bridge command.
3
+ */
4
+ import { describe, expect, it, vi } from "vitest";
5
+ import { buildFrontedSessionRecord, detachFrontedSession, } from "../bridges/cc-peer/front-relay.js";
6
+ function rosterEntry(overrides = {}) {
7
+ return {
8
+ pid: 222,
9
+ cwd: "/tmp/project",
10
+ version: "2.1.269",
11
+ messagingSocketPath: "/tmp/sock-222",
12
+ ...overrides,
13
+ };
14
+ }
15
+ function fakeStore() {
16
+ const setAgentOfflineCalls = [];
17
+ let shutdownCalls = 0;
18
+ return {
19
+ onDelivery: undefined,
20
+ setAgentOfflineCalls,
21
+ get shutdownCalls() {
22
+ return shutdownCalls;
23
+ },
24
+ setAgentOffline: vi.fn(async (id) => {
25
+ setAgentOfflineCalls.push(id);
26
+ return Promise.resolve();
27
+ }),
28
+ shutdown: vi.fn(async () => {
29
+ shutdownCalls += 1;
30
+ return Promise.resolve();
31
+ }),
32
+ };
33
+ }
34
+ function fakePeer() {
35
+ const sendCalls = [];
36
+ return {
37
+ sendCalls,
38
+ send: vi.fn(async (target, body) => {
39
+ sendCalls.push({ target, body });
40
+ return Promise.resolve({ msgId: "msg-1" });
41
+ }),
42
+ };
43
+ }
44
+ function fakeTool() {
45
+ const handleCalls = [];
46
+ return {
47
+ handleCalls,
48
+ handle: vi.fn(async (ctx, action) => {
49
+ handleCalls.push({ ctx, action });
50
+ return Promise.resolve({ content: "ok", isError: false });
51
+ }),
52
+ };
53
+ }
54
+ function roomMessage(overrides = {}) {
55
+ return {
56
+ id: "msg-1",
57
+ from: "peer-a",
58
+ room: "owner/project",
59
+ content: "hi from the mesh",
60
+ timestamp: "2026-01-01T00:00:00.000Z",
61
+ readBy: [],
62
+ ...overrides,
63
+ };
64
+ }
65
+ describe("buildFrontedSessionRecord — outbound (mesh -> cc-peer)", () => {
66
+ it("wires store.onDelivery to send the formatted event to the session's own pid", () => {
67
+ const store = fakeStore();
68
+ const peer = fakePeer();
69
+ const entry = rosterEntry({ pid: 333 });
70
+ buildFrontedSessionRecord({
71
+ entry,
72
+ agentId: "agent-1",
73
+ roomId: "owner/project",
74
+ store,
75
+ tool: fakeTool(),
76
+ peer,
77
+ });
78
+ expect(store.onDelivery).toBeDefined();
79
+ const event = {
80
+ type: "room_message",
81
+ message: roomMessage(),
82
+ };
83
+ void store.onDelivery?.("agent-1", event);
84
+ expect(peer.sendCalls).toHaveLength(1);
85
+ expect(peer.sendCalls[0]?.target).toEqual({ pid: 333 });
86
+ });
87
+ });
88
+ describe("buildFrontedSessionRecord — inbound (cc-peer -> mesh)", () => {
89
+ it("returns a record whose handleInbound posts into the session's own project room", () => {
90
+ const tool = fakeTool();
91
+ const entry = rosterEntry({ cwd: "/tmp/my-project" });
92
+ const record = buildFrontedSessionRecord({
93
+ entry,
94
+ agentId: "agent-1",
95
+ roomId: "owner/my-project",
96
+ store: fakeStore(),
97
+ tool,
98
+ peer: fakePeer(),
99
+ });
100
+ record.handleInbound({
101
+ from: "local-session",
102
+ fromName: "my-local-session",
103
+ body: "hello from cc-peer",
104
+ });
105
+ expect(tool.handleCalls).toHaveLength(1);
106
+ expect(tool.handleCalls[0]).toEqual({
107
+ ctx: {
108
+ agentId: "agent-1",
109
+ harness: "claude-code",
110
+ cwd: "/tmp/my-project",
111
+ pid: process.pid,
112
+ },
113
+ action: {
114
+ action: "send",
115
+ target: "owner/my-project",
116
+ content: "my-local-session: hello from cc-peer",
117
+ },
118
+ });
119
+ });
120
+ it("falls back to the raw from id when the session has no registered display name", () => {
121
+ const tool = fakeTool();
122
+ const record = buildFrontedSessionRecord({
123
+ entry: rosterEntry(),
124
+ agentId: "agent-1",
125
+ roomId: "owner/project",
126
+ store: fakeStore(),
127
+ tool,
128
+ peer: fakePeer(),
129
+ });
130
+ record.handleInbound({ from: "local-session", body: "hi" });
131
+ const call = tool.handleCalls[0];
132
+ expect(call.action.content).toBe("local-session: hi");
133
+ });
134
+ });
135
+ describe("buildFrontedSessionRecord — record shape", () => {
136
+ it("carries the roster entry's own pid/cwd/messagingSocketPath, matching what CcPeerFront diffs and routes on", () => {
137
+ const entry = rosterEntry({
138
+ pid: 444,
139
+ cwd: "/tmp/other",
140
+ messagingSocketPath: "/tmp/sock-444",
141
+ });
142
+ const record = buildFrontedSessionRecord({
143
+ entry,
144
+ agentId: "agent-1",
145
+ roomId: "owner/other",
146
+ store: fakeStore(),
147
+ tool: fakeTool(),
148
+ peer: fakePeer(),
149
+ });
150
+ expect(record.pid).toBe(entry.pid);
151
+ expect(record.cwd).toBe(entry.cwd);
152
+ expect(record.messagingSocketPath).toBe(entry.messagingSocketPath);
153
+ });
154
+ });
155
+ describe("detachFrontedSession", () => {
156
+ it("marks the agent offline, then shuts its store down", async () => {
157
+ const store = fakeStore();
158
+ await detachFrontedSession({ agentId: "agent-1", store });
159
+ expect(store.setAgentOfflineCalls).toEqual(["agent-1"]);
160
+ expect(store.shutdownCalls).toBe(1);
161
+ });
162
+ it("shuts the store down only after setAgentOffline resolves, not concurrently with it", async () => {
163
+ const store = fakeStore();
164
+ const order = [];
165
+ vi.mocked(store.setAgentOffline).mockImplementation(async () => {
166
+ order.push("offline");
167
+ return Promise.resolve();
168
+ });
169
+ vi.mocked(store.shutdown).mockImplementation(async () => {
170
+ order.push("shutdown");
171
+ return Promise.resolve();
172
+ });
173
+ await detachFrontedSession({ agentId: "agent-1", store });
174
+ expect(order).toEqual(["offline", "shutdown"]);
175
+ });
176
+ });
177
+ //# sourceMappingURL=cc-peer-front-relay.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-peer-front-relay.test.js","sourceRoot":"","sources":["../../src/test/cc-peer-front-relay.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cc-peer-front.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-peer-front.test.d.ts","sourceRoot":"","sources":["../../src/test/cc-peer-front.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Unit tests for the cc-peer front's pure decision logic (bridges/cc-peer/front.ts) -- roster filtering, slot computation, and inbound message routing, all tested purely over data with no real cc-peer/MeshStore/filesystem involved.
3
+ */
4
+ import { describe, expect, it } from "vitest";
5
+ import { isCcPeerLibraryPeer, computeFrontSlot, selectSessionsToFront, matchInboundMessageSession, } from "../bridges/cc-peer/front.js";
6
+ function rosterEntry(overrides = {}) {
7
+ return {
8
+ pid: 111,
9
+ cwd: "/tmp/project",
10
+ version: "2.1.269",
11
+ messagingSocketPath: "/tmp/sock-111",
12
+ ...overrides,
13
+ };
14
+ }
15
+ /** A pid standing in for a real live agent-comms bridge holding a slot's lock -- arbitrary beyond "a plausible process id", used only to prove selectSessionsToFront treats "probe returned a pid" as "already fronted", not to assert anything about the value itself. */
16
+ const LIVE_LOCK_HOLDER_PID = 4242;
17
+ describe("isCcPeerLibraryPeer", () => {
18
+ it("is true for an entry carrying cc-peer's own literal version marker", () => {
19
+ expect(isCcPeerLibraryPeer(rosterEntry({ version: "cc-peer" }))).toBe(true);
20
+ });
21
+ it("is false for an entry reporting a real Claude Code version", () => {
22
+ expect(isCcPeerLibraryPeer(rosterEntry({ version: "2.1.269" }))).toBe(false);
23
+ });
24
+ });
25
+ describe("computeFrontSlot", () => {
26
+ it("uses the claude-code harness, matching the real claude-code bridge's own slot", () => {
27
+ expect(computeFrontSlot("/tmp/project")).toEqual({
28
+ harness: "claude-code",
29
+ cwd: "/tmp/project",
30
+ });
31
+ });
32
+ it("is distinct per cwd", () => {
33
+ expect(computeFrontSlot("/tmp/a")).not.toEqual(computeFrontSlot("/tmp/b"));
34
+ });
35
+ });
36
+ describe("selectSessionsToFront", () => {
37
+ it("excludes cc-peer-library peers regardless of slot state", () => {
38
+ const libraryPeer = rosterEntry({ pid: 1, version: "cc-peer" });
39
+ const selected = selectSessionsToFront([libraryPeer], () => undefined);
40
+ expect(selected).toEqual([]);
41
+ });
42
+ it("excludes a real session whose own slot is already held by a live bridge", () => {
43
+ const alreadyFronted = rosterEntry({ pid: 2, cwd: "/tmp/self-fronted" });
44
+ const selected = selectSessionsToFront([alreadyFronted], (slot) => slot.cwd === "/tmp/self-fronted" ? LIVE_LOCK_HOLDER_PID : undefined);
45
+ expect(selected).toEqual([]);
46
+ });
47
+ it("selects a real session whose own slot is unheld", () => {
48
+ const unfronted = rosterEntry({ pid: 3, cwd: "/tmp/unfronted" });
49
+ const selected = selectSessionsToFront([unfronted], () => undefined);
50
+ expect(selected).toEqual([unfronted]);
51
+ });
52
+ it("probes the slot computed from the entry's own cwd, not an unrelated one", () => {
53
+ const entry = rosterEntry({ pid: 4, cwd: "/tmp/watched" });
54
+ let probedSlot;
55
+ selectSessionsToFront([entry], (slot) => {
56
+ probedSlot = slot;
57
+ return undefined;
58
+ });
59
+ expect(probedSlot).toEqual({ harness: "claude-code", cwd: "/tmp/watched" });
60
+ });
61
+ it("handles a mixed roster, keeping only the unfronted real sessions", () => {
62
+ const libraryPeer = rosterEntry({ pid: 1, version: "cc-peer" });
63
+ const selfFronted = rosterEntry({ pid: 2, cwd: "/tmp/self-fronted" });
64
+ const unfronted = rosterEntry({ pid: 3, cwd: "/tmp/unfronted" });
65
+ const selected = selectSessionsToFront([libraryPeer, selfFronted, unfronted], (slot) => slot.cwd === "/tmp/self-fronted" ? LIVE_LOCK_HOLDER_PID : undefined);
66
+ expect(selected).toEqual([unfronted]);
67
+ });
68
+ });
69
+ describe("matchInboundMessageSession", () => {
70
+ it("matches a fronted session by the uds:<socketPath> envelope convention", () => {
71
+ const a = {
72
+ messagingSocketPath: "/tmp/sock-a",
73
+ label: "a",
74
+ };
75
+ const b = {
76
+ messagingSocketPath: "/tmp/sock-b",
77
+ label: "b",
78
+ };
79
+ const match = matchInboundMessageSession([a, b], {
80
+ from: "uds:/tmp/sock-b",
81
+ });
82
+ expect(match).toBe(b);
83
+ });
84
+ it("returns undefined when no fronted session's socket matches", () => {
85
+ const a = {
86
+ messagingSocketPath: "/tmp/sock-a",
87
+ label: "a",
88
+ };
89
+ const match = matchInboundMessageSession([a], {
90
+ from: "uds:/tmp/sock-unknown",
91
+ });
92
+ expect(match).toBeUndefined();
93
+ });
94
+ it("returns undefined when the message carries no from field at all", () => {
95
+ const a = {
96
+ messagingSocketPath: "/tmp/sock-a",
97
+ label: "a",
98
+ };
99
+ expect(matchInboundMessageSession([a], {})).toBeUndefined();
100
+ });
101
+ it("never matches a from value missing the uds: prefix, even with an otherwise identical path", () => {
102
+ const a = {
103
+ messagingSocketPath: "/tmp/sock-a",
104
+ label: "a",
105
+ };
106
+ expect(matchInboundMessageSession([a], { from: "/tmp/sock-a" })).toBeUndefined();
107
+ });
108
+ });
109
+ //# sourceMappingURL=cc-peer-front.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-peer-front.test.js","sourceRoot":"","sources":["../../src/test/cc-peer-front.test.ts"],"names":[],"mappings":"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"}
@@ -126,6 +126,8 @@ function makeHarness() {
126
126
  identity: {},
127
127
  revocation: { record: revocationRecord },
128
128
  dataStorage: {},
129
+ userIdentity: {},
130
+ userIdentityOptions: {},
129
131
  }),
130
132
  requireTransport: () => transport,
131
133
  getOnDelivery: () => onDelivery,