agent-comms 2.21.11 → 2.21.13
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 +1 -1
- package/dist/test/connection-approval.test.d.ts +2 -0
- package/dist/test/connection-approval.test.d.ts.map +1 -0
- package/dist/test/connection-approval.test.js +180 -0
- package/dist/test/connection-approval.test.js.map +1 -0
- package/dist/test/peer-lifecycle.test.d.ts +2 -0
- package/dist/test/peer-lifecycle.test.d.ts.map +1 -0
- package/dist/test/peer-lifecycle.test.js +149 -0
- package/dist/test/peer-lifecycle.test.js.map +1 -0
- package/package.json +1 -1
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/v2.21.13)
|
|
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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-approval.test.d.ts","sourceRoot":"","sources":["../../src/test/connection-approval.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct, DI-based unit tests for ConnectionApproval -- it was previously exercised only indirectly through approval.integration.test.ts's end-to-end transport scenarios, which left several individual branches, error messages, and fallback string literals unobserved. ConnectionApprovalDeps is a narrow, injectable surface built exactly for this: a fake deps object with vi.fn() collaborators lets every branch be asserted on directly.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { ConnectionApproval, } from "../core/connection-approval.js";
|
|
6
|
+
const OWNER_ID = "owner-device";
|
|
7
|
+
const STARTED_AT = "2026-01-01T00:00:00.000Z";
|
|
8
|
+
const REMOTE_HOST = "example.test";
|
|
9
|
+
const REMOTE_PORT = 4242;
|
|
10
|
+
const LOCAL_DATA_PORT = 5150;
|
|
11
|
+
function agent(overrides = {}) {
|
|
12
|
+
return {
|
|
13
|
+
id: OWNER_ID,
|
|
14
|
+
version: 1,
|
|
15
|
+
name: "agent-name",
|
|
16
|
+
harness: "pi",
|
|
17
|
+
cwd: "/tmp",
|
|
18
|
+
pid: 111,
|
|
19
|
+
startedAt: STARTED_AT,
|
|
20
|
+
visibility: "visible",
|
|
21
|
+
status: "active",
|
|
22
|
+
tags: [],
|
|
23
|
+
subscribedRooms: [],
|
|
24
|
+
...overrides,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function makeHarness(options = {}) {
|
|
28
|
+
const transport = {
|
|
29
|
+
acceptConnection: vi.fn().mockResolvedValue(undefined),
|
|
30
|
+
rejectConnection: vi.fn().mockResolvedValue(undefined),
|
|
31
|
+
connectToRemote: vi.fn().mockResolvedValue(undefined),
|
|
32
|
+
startDataServer: vi.fn().mockResolvedValue(undefined),
|
|
33
|
+
unref: vi.fn(),
|
|
34
|
+
dataPort: LOCAL_DATA_PORT,
|
|
35
|
+
};
|
|
36
|
+
const queueDelivery = vi.fn();
|
|
37
|
+
const onDelivery = options.withOnDelivery === true ? vi.fn() : undefined;
|
|
38
|
+
const deps = {
|
|
39
|
+
agents: new Map(),
|
|
40
|
+
peerInfo: new Map(),
|
|
41
|
+
startedAt: STARTED_AT,
|
|
42
|
+
getPeerId: () => OWNER_ID,
|
|
43
|
+
requireTransport: () => transport,
|
|
44
|
+
getOnDelivery: () => onDelivery,
|
|
45
|
+
queueDelivery,
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
deps,
|
|
49
|
+
approval: new ConnectionApproval(deps),
|
|
50
|
+
transport,
|
|
51
|
+
queueDelivery,
|
|
52
|
+
onDelivery,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
describe("ConnectionApproval — handleConnectionRequest", () => {
|
|
56
|
+
it("queues a connection_request delivery event addressed to the owning peer", () => {
|
|
57
|
+
const h = makeHarness();
|
|
58
|
+
h.approval.handleConnectionRequest({ id: "conn-1" }, {
|
|
59
|
+
peerId: "remote-peer",
|
|
60
|
+
dataPort: 9000,
|
|
61
|
+
name: "remote-name",
|
|
62
|
+
fingerprint: "fp",
|
|
63
|
+
});
|
|
64
|
+
expect(h.queueDelivery).toHaveBeenCalledWith(OWNER_ID, {
|
|
65
|
+
type: "connection_request",
|
|
66
|
+
connectionId: "conn-1",
|
|
67
|
+
peerId: "remote-peer",
|
|
68
|
+
dataPort: 9000,
|
|
69
|
+
name: "remote-name",
|
|
70
|
+
fingerprint: "fp",
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it("pushes the delivery live via onDelivery when a callback is registered", () => {
|
|
74
|
+
const h = makeHarness({ withOnDelivery: true });
|
|
75
|
+
h.approval.handleConnectionRequest({ id: "conn-1" }, {
|
|
76
|
+
peerId: "remote-peer",
|
|
77
|
+
dataPort: 9000,
|
|
78
|
+
name: "remote-name",
|
|
79
|
+
fingerprint: "fp",
|
|
80
|
+
});
|
|
81
|
+
expect(h.onDelivery).toHaveBeenCalledTimes(1);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe("ConnectionApproval — acceptConnection", () => {
|
|
85
|
+
it("accepts a genuinely pending connection via the transport", async () => {
|
|
86
|
+
const h = makeHarness();
|
|
87
|
+
h.approval.handleConnectionRequest({ id: "conn-1" }, {
|
|
88
|
+
peerId: "remote-peer",
|
|
89
|
+
dataPort: 9000,
|
|
90
|
+
name: "remote-name",
|
|
91
|
+
fingerprint: "fp",
|
|
92
|
+
});
|
|
93
|
+
await h.approval.acceptConnection("conn-1");
|
|
94
|
+
expect(h.transport.acceptConnection).toHaveBeenCalledWith({ id: "conn-1" });
|
|
95
|
+
});
|
|
96
|
+
it("throws an error naming the exact unknown connection id, and never touches the transport", async () => {
|
|
97
|
+
const h = makeHarness();
|
|
98
|
+
await expect(h.approval.acceptConnection("no-such-conn")).rejects.toThrow("No pending connection no-such-conn");
|
|
99
|
+
expect(h.transport.acceptConnection).not.toHaveBeenCalled();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe("ConnectionApproval — rejectConnection", () => {
|
|
103
|
+
it("rejects a genuinely pending connection via the transport with the given reason", async () => {
|
|
104
|
+
const h = makeHarness();
|
|
105
|
+
h.approval.handleConnectionRequest({ id: "conn-1" }, {
|
|
106
|
+
peerId: "remote-peer",
|
|
107
|
+
dataPort: 9000,
|
|
108
|
+
name: "remote-name",
|
|
109
|
+
fingerprint: "fp",
|
|
110
|
+
});
|
|
111
|
+
await h.approval.rejectConnection("conn-1", "not now");
|
|
112
|
+
expect(h.transport.rejectConnection).toHaveBeenCalledWith({ id: "conn-1" }, "not now");
|
|
113
|
+
});
|
|
114
|
+
it("throws an error naming the exact unknown connection id, and never touches the transport", async () => {
|
|
115
|
+
const h = makeHarness();
|
|
116
|
+
await expect(h.approval.rejectConnection("no-such-conn", "reason")).rejects.toThrow("No pending connection no-such-conn");
|
|
117
|
+
expect(h.transport.rejectConnection).not.toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe("ConnectionApproval — connectToRemote", () => {
|
|
121
|
+
it("dials out with the local agent's real name and an empty fingerprint when the agent is known", async () => {
|
|
122
|
+
const h = makeHarness();
|
|
123
|
+
h.deps.agents.set(OWNER_ID, agent({ name: "real-name" }));
|
|
124
|
+
await h.approval.connectToRemote(REMOTE_HOST, REMOTE_PORT);
|
|
125
|
+
expect(h.transport.connectToRemote).toHaveBeenCalledWith(REMOTE_HOST, REMOTE_PORT, OWNER_ID, LOCAL_DATA_PORT, "real-name", "");
|
|
126
|
+
});
|
|
127
|
+
it("falls back to an empty name (not a placeholder) when the local agent isn't registered yet", async () => {
|
|
128
|
+
const h = makeHarness();
|
|
129
|
+
await h.approval.connectToRemote(REMOTE_HOST, REMOTE_PORT);
|
|
130
|
+
expect(h.transport.connectToRemote).toHaveBeenCalledWith(REMOTE_HOST, REMOTE_PORT, OWNER_ID, LOCAL_DATA_PORT, "", "");
|
|
131
|
+
});
|
|
132
|
+
it("does not reject the returned promise when the transport's own connect attempt is rejected", async () => {
|
|
133
|
+
const h = makeHarness();
|
|
134
|
+
h.transport.connectToRemote.mockRejectedValue(new Error("coordinator refused"));
|
|
135
|
+
await expect(h.approval.connectToRemote(REMOTE_HOST, REMOTE_PORT)).resolves.toBeUndefined();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe("ConnectionApproval — startDataServerOnly", () => {
|
|
139
|
+
it("starts the data server, records this peer's own PeerInfo, and unrefs the transport", async () => {
|
|
140
|
+
const h = makeHarness();
|
|
141
|
+
await h.approval.startDataServerOnly();
|
|
142
|
+
expect(h.transport.startDataServer).toHaveBeenCalledTimes(1);
|
|
143
|
+
expect(h.deps.peerInfo.get(OWNER_ID)).toEqual({
|
|
144
|
+
id: OWNER_ID,
|
|
145
|
+
port: LOCAL_DATA_PORT,
|
|
146
|
+
startedAt: STARTED_AT,
|
|
147
|
+
});
|
|
148
|
+
expect(h.transport.unref).toHaveBeenCalledTimes(1);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe("ConnectionApproval — listPendingConnections", () => {
|
|
152
|
+
it("lists every still-pending inbound connection with its full request detail", () => {
|
|
153
|
+
const h = makeHarness();
|
|
154
|
+
h.approval.handleConnectionRequest({ id: "conn-1" }, { peerId: "peer-a", dataPort: 1, name: "a", fingerprint: "fp-a" });
|
|
155
|
+
h.approval.handleConnectionRequest({ id: "conn-2" }, { peerId: "peer-b", dataPort: 2, name: "b", fingerprint: "fp-b" });
|
|
156
|
+
expect(h.approval.listPendingConnections()).toEqual([
|
|
157
|
+
{
|
|
158
|
+
connectionId: "conn-1",
|
|
159
|
+
peerId: "peer-a",
|
|
160
|
+
dataPort: 1,
|
|
161
|
+
name: "a",
|
|
162
|
+
fingerprint: "fp-a",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
connectionId: "conn-2",
|
|
166
|
+
peerId: "peer-b",
|
|
167
|
+
dataPort: 2,
|
|
168
|
+
name: "b",
|
|
169
|
+
fingerprint: "fp-b",
|
|
170
|
+
},
|
|
171
|
+
]);
|
|
172
|
+
});
|
|
173
|
+
it("no longer lists a connection once it's been accepted or rejected", async () => {
|
|
174
|
+
const h = makeHarness();
|
|
175
|
+
h.approval.handleConnectionRequest({ id: "conn-1" }, { peerId: "peer-a", dataPort: 1, name: "a", fingerprint: "fp-a" });
|
|
176
|
+
await h.approval.acceptConnection("conn-1");
|
|
177
|
+
expect(h.approval.listPendingConnections()).toEqual([]);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
//# sourceMappingURL=connection-approval.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-approval.test.js","sourceRoot":"","sources":["../../src/test/connection-approval.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-lifecycle.test.d.ts","sourceRoot":"","sources":["../../src/test/peer-lifecycle.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct, DI-based unit tests for PeerLifecycle -- it was previously exercised only indirectly through end-to-end mesh integration tests, leaving several individual branches, self-connect guards, and handleDataMessage's method-dispatch branches unobserved. A few of the survivors Stryker reports against handleDataMessage's whole-suite timeout classification: emptying its body doesn't fail fast, it hangs some unrelated integration test waiting on state that never arrives, so a direct unit test that fails immediately on the same mutation converts a slow timeout into a fast, precise kill. PeerLifecycleDeps is a narrow, injectable surface built exactly for this direct testing.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { PeerLifecycle, } from "../core/peer-lifecycle.js";
|
|
6
|
+
const OWNER_ID = "owner-device";
|
|
7
|
+
const COORDINATOR_PORT = 19876;
|
|
8
|
+
function peerInfo(id, port = 1) {
|
|
9
|
+
return { id, port, startedAt: "2026-01-01T00:00:00.000Z" };
|
|
10
|
+
}
|
|
11
|
+
function emptyState() {
|
|
12
|
+
return { agents: {}, rooms: {}, messages: {}, dms: {}, deliveryQueues: {} };
|
|
13
|
+
}
|
|
14
|
+
function makeHarness() {
|
|
15
|
+
const transport = {
|
|
16
|
+
connectToPeer: vi.fn().mockResolvedValue(undefined),
|
|
17
|
+
send: vi.fn().mockResolvedValue(undefined),
|
|
18
|
+
broadcast: vi.fn().mockResolvedValue(undefined),
|
|
19
|
+
becomeCoordinator: vi.fn().mockResolvedValue(undefined),
|
|
20
|
+
};
|
|
21
|
+
const flushPendingRoomRequests = vi.fn().mockResolvedValue(undefined);
|
|
22
|
+
const applyStateSync = vi.fn();
|
|
23
|
+
const applyPatch = vi.fn().mockResolvedValue(undefined);
|
|
24
|
+
const staleAgentCheckerStart = vi.fn();
|
|
25
|
+
const deps = {
|
|
26
|
+
peerInfo: new Map(),
|
|
27
|
+
agents: new Map(),
|
|
28
|
+
coordinatorPort: COORDINATOR_PORT,
|
|
29
|
+
getPeerId: () => OWNER_ID,
|
|
30
|
+
requireTransport: () => transport,
|
|
31
|
+
serialise: () => emptyState(),
|
|
32
|
+
roomProtocol: { flushPendingRoomRequests },
|
|
33
|
+
deliveryEngine: { applyStateSync, applyPatch },
|
|
34
|
+
staleAgentChecker: { start: staleAgentCheckerStart },
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
deps,
|
|
38
|
+
lifecycle: new PeerLifecycle(deps),
|
|
39
|
+
transport,
|
|
40
|
+
flushPendingRoomRequests,
|
|
41
|
+
applyStateSync,
|
|
42
|
+
applyPatch,
|
|
43
|
+
staleAgentCheckerStart,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
describe("PeerLifecycle — handlePeerList", () => {
|
|
47
|
+
it("records every peer and dials each one except itself", () => {
|
|
48
|
+
const h = makeHarness();
|
|
49
|
+
const self = peerInfo(OWNER_ID);
|
|
50
|
+
const other = peerInfo("other-peer");
|
|
51
|
+
h.lifecycle.handlePeerList([self, other]);
|
|
52
|
+
expect(h.deps.peerInfo.get(OWNER_ID)).toEqual(self);
|
|
53
|
+
expect(h.deps.peerInfo.get("other-peer")).toEqual(other);
|
|
54
|
+
expect(h.transport.connectToPeer).toHaveBeenCalledTimes(1);
|
|
55
|
+
expect(h.transport.connectToPeer).toHaveBeenCalledWith(other, OWNER_ID);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe("PeerLifecycle — handlePeerJoined", () => {
|
|
59
|
+
it("records the joining peer and dials it when it isn't this store's own id", () => {
|
|
60
|
+
const h = makeHarness();
|
|
61
|
+
const other = peerInfo("other-peer");
|
|
62
|
+
h.lifecycle.handlePeerJoined(other);
|
|
63
|
+
expect(h.deps.peerInfo.get("other-peer")).toEqual(other);
|
|
64
|
+
expect(h.transport.connectToPeer).toHaveBeenCalledWith(other, OWNER_ID);
|
|
65
|
+
});
|
|
66
|
+
it("records but never dials itself when the joined peer is this store's own id", () => {
|
|
67
|
+
const h = makeHarness();
|
|
68
|
+
const self = peerInfo(OWNER_ID);
|
|
69
|
+
h.lifecycle.handlePeerJoined(self);
|
|
70
|
+
expect(h.deps.peerInfo.get(OWNER_ID)).toEqual(self);
|
|
71
|
+
expect(h.transport.connectToPeer).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe("PeerLifecycle — handlePeerConnected", () => {
|
|
75
|
+
it("sends a state_sync when this store already has agent state", async () => {
|
|
76
|
+
const h = makeHarness();
|
|
77
|
+
h.deps.agents.set(OWNER_ID, { id: OWNER_ID });
|
|
78
|
+
await h.lifecycle.handlePeerConnected({ id: "conn-1" }, peerInfo("x"));
|
|
79
|
+
expect(h.transport.send).toHaveBeenCalledWith({ id: "conn-1" }, { method: "state_sync", state: emptyState() });
|
|
80
|
+
});
|
|
81
|
+
it("sends no state_sync when this store has no agent state at all", async () => {
|
|
82
|
+
const h = makeHarness();
|
|
83
|
+
await h.lifecycle.handlePeerConnected({ id: "conn-1" }, peerInfo("x"));
|
|
84
|
+
expect(h.transport.send).not.toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
it("always flushes pending room requests for the connection, regardless of state", async () => {
|
|
87
|
+
const h = makeHarness();
|
|
88
|
+
await h.lifecycle.handlePeerConnected({ id: "conn-1" }, peerInfo("x"));
|
|
89
|
+
expect(h.flushPendingRoomRequests).toHaveBeenCalledWith("conn-1");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe("PeerLifecycle — handleDataMessage", () => {
|
|
93
|
+
it("applies a normalised state_sync to the delivery engine", async () => {
|
|
94
|
+
const h = makeHarness();
|
|
95
|
+
await h.lifecycle.handleDataMessage({ id: "conn-1" }, { method: "state_sync", state: emptyState() });
|
|
96
|
+
expect(h.applyStateSync).toHaveBeenCalledWith(emptyState());
|
|
97
|
+
});
|
|
98
|
+
it("applies a state_update's patch to the delivery engine", async () => {
|
|
99
|
+
const h = makeHarness();
|
|
100
|
+
const event = {
|
|
101
|
+
type: "connection_request",
|
|
102
|
+
connectionId: "c",
|
|
103
|
+
peerId: "p",
|
|
104
|
+
dataPort: 1,
|
|
105
|
+
name: "n",
|
|
106
|
+
fingerprint: "fp",
|
|
107
|
+
};
|
|
108
|
+
await h.lifecycle.handleDataMessage({ id: "conn-1" }, {
|
|
109
|
+
method: "state_update",
|
|
110
|
+
patch: { type: "delivery", agentId: "a", event },
|
|
111
|
+
});
|
|
112
|
+
expect(h.applyPatch).toHaveBeenCalledWith({
|
|
113
|
+
type: "delivery",
|
|
114
|
+
agentId: "a",
|
|
115
|
+
event,
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
it("applies neither for a message method it doesn't dispatch on", async () => {
|
|
119
|
+
const h = makeHarness();
|
|
120
|
+
await h.lifecycle.handleDataMessage({ id: "conn-1" }, { method: "introduce", peerId: "p", dataPort: 1 });
|
|
121
|
+
expect(h.applyStateSync).not.toHaveBeenCalled();
|
|
122
|
+
expect(h.applyPatch).not.toHaveBeenCalled();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("PeerLifecycle — handleBecomeCoordinator", () => {
|
|
126
|
+
it("becomes coordinator, replaces the peer table with exactly the handoff list, dials every peer, and starts stale-agent probing", async () => {
|
|
127
|
+
const h = makeHarness();
|
|
128
|
+
h.deps.peerInfo.set("stale-peer", peerInfo("stale-peer"));
|
|
129
|
+
const incoming = [peerInfo("a"), peerInfo("b")];
|
|
130
|
+
await h.lifecycle.handleBecomeCoordinator(incoming);
|
|
131
|
+
expect(h.transport.becomeCoordinator).toHaveBeenCalledWith("127.0.0.1", COORDINATOR_PORT);
|
|
132
|
+
expect(h.deps.peerInfo.has("stale-peer")).toBe(false);
|
|
133
|
+
expect(h.deps.peerInfo.get("a")).toEqual(incoming[0]);
|
|
134
|
+
expect(h.deps.peerInfo.get("b")).toEqual(incoming[1]);
|
|
135
|
+
expect(h.transport.connectToPeer).toHaveBeenCalledTimes(2);
|
|
136
|
+
expect(h.transport.connectToPeer).toHaveBeenCalledWith(incoming[0], OWNER_ID);
|
|
137
|
+
expect(h.transport.connectToPeer).toHaveBeenCalledWith(incoming[1], OWNER_ID);
|
|
138
|
+
expect(h.staleAgentCheckerStart).toHaveBeenCalledTimes(1);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("PeerLifecycle — handlePeerDisconnected", () => {
|
|
142
|
+
it("removes the disconnected peer's entry from peerInfo", () => {
|
|
143
|
+
const h = makeHarness();
|
|
144
|
+
h.deps.peerInfo.set("gone-peer", peerInfo("gone-peer"));
|
|
145
|
+
h.lifecycle.handlePeerDisconnected({ id: "gone-peer" });
|
|
146
|
+
expect(h.deps.peerInfo.has("gone-peer")).toBe(false);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
//# sourceMappingURL=peer-lifecycle.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-lifecycle.test.js","sourceRoot":"","sources":["../../src/test/peer-lifecycle.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-comms",
|
|
3
|
-
"version": "2.21.
|
|
3
|
+
"version": "2.21.13",
|
|
4
4
|
"description": "Cross-harness communication mesh for LLM agents — rooms, DMs, presence, and real-time push delivery over TCP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
|