agent-comms 2.18.2 → 2.18.4
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/bridges/user/web/dist/bundle.js +1 -1
- package/dist/bridges/user/web/frontend/project-tree.js +3 -3
- package/dist/bridges/user/web/frontend/project-tree.js.map +1 -1
- package/dist/bridges/user/web/test/port-discovery.unit.test.js +10 -11
- package/dist/bridges/user/web/test/port-discovery.unit.test.js.map +1 -1
- package/dist/bridges/user/web/test/web-server.integration.test.js +12 -13
- package/dist/bridges/user/web/test/web-server.integration.test.js.map +1 -1
- package/dist/core/identity-store.d.ts.map +1 -1
- package/dist/core/identity-store.js +16 -5
- package/dist/core/identity-store.js.map +1 -1
- package/dist/core/identity.d.ts +6 -5
- package/dist/core/identity.d.ts.map +1 -1
- package/dist/core/identity.js +13 -11
- package/dist/core/identity.js.map +1 -1
- package/dist/core/test/bridge.unit.test.js +11 -12
- package/dist/core/test/bridge.unit.test.js.map +1 -1
- package/dist/core/test/identity.unit.test.js +21 -22
- package/dist/core/test/identity.unit.test.js.map +1 -1
- package/dist/test/approval.integration.test.js +52 -45
- package/dist/test/approval.integration.test.js.map +1 -1
- package/dist/test/become-coordinator-actual-port.integration.test.d.ts +0 -2
- package/dist/test/become-coordinator-actual-port.integration.test.d.ts.map +1 -1
- package/dist/test/become-coordinator-actual-port.integration.test.js +14 -39
- package/dist/test/become-coordinator-actual-port.integration.test.js.map +1 -1
- package/dist/test/bridge-mesh.test.js +9 -10
- package/dist/test/bridge-mesh.test.js.map +1 -1
- package/dist/test/broadcast-window.integration.test.js +4 -7
- package/dist/test/broadcast-window.integration.test.js.map +1 -1
- package/dist/test/coordinator-socket-error.integration.test.js +3 -4
- package/dist/test/coordinator-socket-error.integration.test.js.map +1 -1
- package/dist/test/create-room-mints-owner-grant.test.js +9 -8
- package/dist/test/create-room-mints-owner-grant.test.js.map +1 -1
- package/dist/test/create-room-name-sanitisation.test.js +6 -7
- package/dist/test/create-room-name-sanitisation.test.js.map +1 -1
- package/dist/test/dm-admission.integration.test.js +10 -11
- package/dist/test/dm-admission.integration.test.js.map +1 -1
- package/dist/test/federation.integration.test.js +21 -20
- package/dist/test/federation.integration.test.js.map +1 -1
- package/dist/test/filestore.test.js +16 -17
- package/dist/test/filestore.test.js.map +1 -1
- package/dist/test/handshake.test.js +26 -27
- package/dist/test/handshake.test.js.map +1 -1
- package/dist/test/identity-cert.test.js +3 -4
- package/dist/test/identity-cert.test.js.map +1 -1
- package/dist/test/identity-device-id.test.js +6 -7
- package/dist/test/identity-device-id.test.js.map +1 -1
- package/dist/test/identity-restart.integration.test.js +9 -10
- package/dist/test/identity-restart.integration.test.js.map +1 -1
- package/dist/test/identity-store.test.js +36 -21
- package/dist/test/identity-store.test.js.map +1 -1
- package/dist/test/listener-policy.integration.test.js +63 -56
- package/dist/test/listener-policy.integration.test.js.map +1 -1
- package/dist/test/mcp-registry-retry.test.js +10 -11
- package/dist/test/mcp-registry-retry.test.js.map +1 -1
- package/dist/test/mesh-e2e.integration.test.js +26 -19
- package/dist/test/mesh-e2e.integration.test.js.map +1 -1
- package/dist/test/presence-readvertise.integration.test.js +5 -6
- package/dist/test/presence-readvertise.integration.test.js.map +1 -1
- package/dist/test/random-id.test.js +3 -4
- package/dist/test/random-id.test.js.map +1 -1
- package/dist/test/room-admission-tool-actions.test.js +20 -15
- package/dist/test/room-admission-tool-actions.test.js.map +1 -1
- package/dist/test/room-destroy-revocation.integration.test.js +3 -4
- package/dist/test/room-destroy-revocation.integration.test.js.map +1 -1
- package/dist/test/room-invite-directed.integration.test.js +13 -12
- package/dist/test/room-invite-directed.integration.test.js.map +1 -1
- package/dist/test/room-join-admission.test.js +31 -24
- package/dist/test/room-join-admission.test.js.map +1 -1
- package/dist/test/room-kick-revocation.integration.test.js +5 -6
- package/dist/test/room-kick-revocation.integration.test.js.map +1 -1
- package/dist/test/room-leave-revocation.integration.test.js +10 -9
- package/dist/test/room-leave-revocation.integration.test.js.map +1 -1
- package/dist/test/room-path.test.js +16 -17
- package/dist/test/room-path.test.js.map +1 -1
- package/dist/test/room-read-directed.integration.test.js +14 -11
- package/dist/test/room-read-directed.integration.test.js.map +1 -1
- package/dist/test/room-router.test.js +27 -29
- package/dist/test/room-router.test.js.map +1 -1
- package/dist/test/room-send-directed.integration.test.js +11 -12
- package/dist/test/room-send-directed.integration.test.js.map +1 -1
- package/dist/test/room-send-retry-queue.test.js +10 -11
- package/dist/test/room-send-retry-queue.test.js.map +1 -1
- package/dist/test/room-send-retry.integration.test.js +5 -8
- package/dist/test/room-send-retry.integration.test.js.map +1 -1
- package/dist/test/room-state-sync.integration.test.js +18 -15
- package/dist/test/room-state-sync.integration.test.js.map +1 -1
- package/dist/test/room-token-store.test.js +21 -22
- package/dist/test/room-token-store.test.js.map +1 -1
- package/dist/test/room-token-verification.test.js +19 -20
- package/dist/test/room-token-verification.test.js.map +1 -1
- package/dist/test/state-sync-convergence.test.js +25 -26
- package/dist/test/state-sync-convergence.test.js.map +1 -1
- package/dist/test/visibility.integration.test.js +48 -49
- package/dist/test/visibility.integration.test.js.map +1 -1
- package/dist/test/wire-mesh-identity.test.js +7 -8
- package/dist/test/wire-mesh-identity.test.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-router.test.js","sourceRoot":"","sources":["../../src/test/room-router.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"room-router.test.js","sourceRoot":"","sources":["../../src/test/room-router.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Membership is set up by minting and persisting the member's own token directly, not by driving a real room.join round trip: MeshStore's legacy full-state-sync (still active per the "both paths coexist" transition) makes two mesh-connected peers instantly aware of any room the moment it's created, so member.joinRoom(room.id, ...) always takes the already-known-locally branch rather than the wire-level remote-join path -- the same race #73's own tests had to route around, and irrelevant to what this file actually tests (room.send, not room.join).
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
7
|
-
import { test } from "node:test";
|
|
6
|
+
import { test, expect } from "vitest";
|
|
8
7
|
import { mintCapabilityToken } from "wire-mesh-core/domain/tokens";
|
|
9
8
|
import { createSystemClock } from "wire-mesh-core/adapters/system-clock";
|
|
10
9
|
import { deviceIdFromHex } from "wire-mesh-core/domain/device-id";
|
|
@@ -57,12 +56,12 @@ async function grantMembership(ownerSlot, memberSlot, roomPath, memberDeviceHex)
|
|
|
57
56
|
expires: clock.now() + 60_000,
|
|
58
57
|
delegationsRemaining: 0,
|
|
59
58
|
});
|
|
60
|
-
|
|
59
|
+
expect(verdict.ok, "expected the fixture grant to mint successfully").toBeTruthy();
|
|
61
60
|
if (!verdict.ok)
|
|
62
61
|
return;
|
|
63
62
|
saveRoomToken(memberSlot, roomPath, verdict.token);
|
|
64
63
|
}
|
|
65
|
-
|
|
64
|
+
test("a directed room.send delivers to the recipient's own onDelivery", async () => {
|
|
66
65
|
const { owner, ownerSlot, member, memberSlot } = await makeConnectedPair(freshPort());
|
|
67
66
|
try {
|
|
68
67
|
const room = await owner.createRoom({
|
|
@@ -79,19 +78,19 @@ void test("a directed room.send delivers to the recipient's own onDelivery", asy
|
|
|
79
78
|
await owner.sendRoomMessageDirected(room.id, member.peerId, "hello there");
|
|
80
79
|
await waitFor(() => deliveries.some((event) => event.type === "room_message"), "member receives the directed room.send");
|
|
81
80
|
const delivered = deliveries.find((event) => event.type === "room_message");
|
|
82
|
-
|
|
83
|
-
if (delivered
|
|
81
|
+
expect(delivered).toBeTruthy();
|
|
82
|
+
if (delivered?.type !== "room_message")
|
|
84
83
|
return;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
expect(delivered.message.content).toBe("hello there");
|
|
85
|
+
expect(delivered.message.from).toBe(owner.peerId);
|
|
86
|
+
expect(delivered.message.room).toBe(room.id);
|
|
88
87
|
}
|
|
89
88
|
finally {
|
|
90
89
|
await member.shutdown();
|
|
91
90
|
await owner.shutdown();
|
|
92
91
|
}
|
|
93
92
|
});
|
|
94
|
-
|
|
93
|
+
test("a directed room.send from a member (not just the owner) also delivers", async () => {
|
|
95
94
|
const { owner, ownerSlot, member, memberSlot } = await makeConnectedPair(freshPort());
|
|
96
95
|
try {
|
|
97
96
|
const room = await owner.createRoom({
|
|
@@ -113,7 +112,7 @@ void test("a directed room.send from a member (not just the owner) also delivers
|
|
|
113
112
|
await owner.shutdown();
|
|
114
113
|
}
|
|
115
114
|
});
|
|
116
|
-
|
|
115
|
+
test("sendRoomMessageDirected throws when this store holds no token for the room", async () => {
|
|
117
116
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
118
117
|
try {
|
|
119
118
|
const room = await owner.createRoom({
|
|
@@ -123,7 +122,7 @@ void test("sendRoomMessageDirected throws when this store holds no token for the
|
|
|
123
122
|
description: "",
|
|
124
123
|
});
|
|
125
124
|
// Deliberately not granted -- member has no persisted token for this room.
|
|
126
|
-
await
|
|
125
|
+
await expect(member.sendRoomMessageDirected(room.id, owner.peerId, "uninvited")).rejects.toThrow(/No room:member token/);
|
|
127
126
|
}
|
|
128
127
|
finally {
|
|
129
128
|
await member.shutdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-send-directed.integration.test.js","sourceRoot":"","sources":["../../src/test/room-send-directed.integration.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"room-send-directed.integration.test.js","sourceRoot":"","sources":["../../src/test/room-send-directed.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unit tests for the directed room.send fan-out's own retry queue (P3.5): a send that fails because its target member isn't currently reachable is queued rather than thrown or dropped, and retried the moment that member's connection is (re)established -- handlePeerConnected fires for exactly that event, so these tests trigger it directly via store.events.onPeerConnected rather than driving a real second peer (see room-send-retry.integration.test.ts for the real, two-peer version of this same acceptance behaviour).
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
5
|
-
import { test } from "node:test";
|
|
4
|
+
import { test, expect } from "vitest";
|
|
6
5
|
import { MeshStore } from "../core/mesh-store.js";
|
|
7
6
|
import { deleteRoomToken } from "../core/identity-store.js";
|
|
8
7
|
import { waitFor, wireTestTransport } from "./test-transport.js";
|
|
@@ -47,7 +46,7 @@ function fakeTransport() {
|
|
|
47
46
|
},
|
|
48
47
|
};
|
|
49
48
|
}
|
|
50
|
-
|
|
49
|
+
test("a room.send to an unreachable member is queued and retried once it reconnects", async () => {
|
|
51
50
|
const store = new MeshStore();
|
|
52
51
|
await wireTestTransport(store);
|
|
53
52
|
const owner = await store.registerAgent({
|
|
@@ -68,12 +67,12 @@ void test("a room.send to an unreachable member is queued and retried once it re
|
|
|
68
67
|
const { transport, attempts, setConnected } = fakeTransport();
|
|
69
68
|
store.setTransport(transport);
|
|
70
69
|
await store.sendRoomMessage(room.id, owner.id, "hello");
|
|
71
|
-
|
|
70
|
+
expect(attempts.length, "the first, failed attempt was made").toBe(1);
|
|
72
71
|
setConnected(true);
|
|
73
72
|
store.events.onPeerConnected({ id: MEMBER_ID }, { id: MEMBER_ID, port: 0, startedAt: new Date().toISOString() });
|
|
74
73
|
await waitFor(() => attempts.length === 2, "the queued send to retry once the member reconnects");
|
|
75
74
|
});
|
|
76
|
-
|
|
75
|
+
test("the retry queue is bounded oldest-first per member", async () => {
|
|
77
76
|
const store = new MeshStore();
|
|
78
77
|
await wireTestTransport(store);
|
|
79
78
|
const owner = await store.registerAgent({
|
|
@@ -97,7 +96,7 @@ void test("the retry queue is bounded oldest-first per member", async () => {
|
|
|
97
96
|
for (let i = 0; i < QUEUE_CAP + overflow; i++) {
|
|
98
97
|
await store.sendRoomMessage(room.id, owner.id, `msg-${String(i)}`);
|
|
99
98
|
}
|
|
100
|
-
|
|
99
|
+
expect(attempts.length).toBe(QUEUE_CAP + overflow);
|
|
101
100
|
attempts.length = 0;
|
|
102
101
|
setConnected(true);
|
|
103
102
|
store.events.onPeerConnected({ id: MEMBER_ID }, { id: MEMBER_ID, port: 0, startedAt: new Date().toISOString() });
|
|
@@ -109,10 +108,10 @@ void test("the retry queue is bounded oldest-first per member", async () => {
|
|
|
109
108
|
return undefined;
|
|
110
109
|
return typeof params.text === "string" ? params.text : undefined;
|
|
111
110
|
}
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
expect(textOf(attempts[0])).toBe(`msg-${String(overflow)}`);
|
|
112
|
+
expect(textOf(attempts[attempts.length - 1])).toBe(`msg-${String(QUEUE_CAP + overflow - 1)}`);
|
|
114
113
|
});
|
|
115
|
-
|
|
114
|
+
test("a flush drops (not re-queues) a send whose room this store no longer holds a token for", async () => {
|
|
116
115
|
const store = new MeshStore();
|
|
117
116
|
const slot = await wireTestTransport(store);
|
|
118
117
|
const owner = await store.registerAgent({
|
|
@@ -133,11 +132,11 @@ void test("a flush drops (not re-queues) a send whose room this store no longer
|
|
|
133
132
|
const { transport, attempts } = fakeTransport();
|
|
134
133
|
store.setTransport(transport);
|
|
135
134
|
await store.sendRoomMessage(room.id, owner.id, "hello");
|
|
136
|
-
|
|
135
|
+
expect(attempts.length).toBe(1);
|
|
137
136
|
deleteRoomToken(slot, room.id);
|
|
138
137
|
store.events.onPeerConnected({ id: MEMBER_ID }, { id: MEMBER_ID, port: 0, startedAt: new Date().toISOString() });
|
|
139
138
|
// No token to present -- give the flush a moment to run, then confirm it made no further attempt.
|
|
140
139
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
141
|
-
|
|
140
|
+
expect(attempts.length).toBe(1);
|
|
142
141
|
});
|
|
143
142
|
//# sourceMappingURL=room-send-retry-queue.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-send-retry-queue.test.js","sourceRoot":"","sources":["../../src/test/room-send-retry-queue.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"room-send-retry-queue.test.js","sourceRoot":"","sources":["../../src/test/room-send-retry-queue.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integration test for issue #28's own acceptance behaviour, re-verified against P3.5's directed fan-out: a room message sent while its recipient is offline must still reach the recipient once it reconnects. Unlike the legacy full-state-sync this replaces, a directed room.send to a disconnected member fails immediately rather than eventually converging, so the fan-out queues it for retry (pendingRoomSends) and flushes that queue the moment the member's connection is (re)established (handlePeerConnected). Replaces downtime-replay.integration.test.ts, whose own scenario relied on deliveryQueues/applyStateSync -- machinery this fan-out no longer uses for message delivery.
|
|
3
3
|
*/
|
|
4
|
-
import * as assert from "node:assert/strict";
|
|
5
4
|
import * as fs from "node:fs";
|
|
6
5
|
import { tmpdir } from "node:os";
|
|
7
6
|
import path from "node:path";
|
|
7
|
+
import { test, expect } from "vitest";
|
|
8
8
|
import { deviceIdToHex } from "wire-mesh-core/domain/device-id";
|
|
9
9
|
import { createSystemClock } from "wire-mesh-core/adapters/system-clock";
|
|
10
10
|
import { createRevocationView } from "wire-mesh-core/domain/revocation-view";
|
|
@@ -36,7 +36,7 @@ async function waitFor(what, check) {
|
|
|
36
36
|
return;
|
|
37
37
|
await sleep(100);
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
expect(false, `timed out waiting for ${what}`).toBeTruthy();
|
|
40
40
|
}
|
|
41
41
|
async function main() {
|
|
42
42
|
const dir = fs.mkdtempSync(path.join(tmpdir(), "agent-comms-send-retry-"));
|
|
@@ -93,7 +93,7 @@ async function main() {
|
|
|
93
93
|
await sleep(200);
|
|
94
94
|
// B restarts in the same slot: same identity, same agent ID, same persisted room:member token -- the queued send retries the moment the reconnection to A completes.
|
|
95
95
|
const identityB2 = loadOrCreateIdentity(slot);
|
|
96
|
-
|
|
96
|
+
expect(deviceIdToHex(Uint8Array.from(identityB2.deviceId))).toBe(deviceIdToHex(Uint8Array.from(identityB.deviceId)));
|
|
97
97
|
const b2 = await makePeer(identityB2, slot);
|
|
98
98
|
b2.store.onDelivery = (_id, ev) => {
|
|
99
99
|
b2.deliveries.push(ev);
|
|
@@ -115,10 +115,7 @@ async function main() {
|
|
|
115
115
|
releaseIdentityLock(slot);
|
|
116
116
|
console.log("✓ a queued room.send retries and delivers on reconnect");
|
|
117
117
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
process.exitCode = 1;
|
|
121
|
-
// The sequence above keeps mesh handles open when it fails partway; exit explicitly so a failure cannot hang the runner.
|
|
122
|
-
process.exit(1);
|
|
118
|
+
test("a room.send queued for a disconnected member retries and delivers once that member reconnects", async () => {
|
|
119
|
+
await main();
|
|
123
120
|
});
|
|
124
121
|
//# sourceMappingURL=room-send-retry.integration.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-send-retry.integration.test.js","sourceRoot":"","sources":["../../src/test/room-send-retry.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"room-send-retry.integration.test.js","sourceRoot":"","sources":["../../src/test/room-send-retry.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,SAAS,GAAG,KAAK,CAAC;AACxB,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAOpE,iLAAiL;AACjL,KAAK,UAAU,QAAQ,CACrB,QAAsB,EACtB,IAAkB;IAElB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;IACvC,KAAK,CAAC,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,KAAK,CAAC,YAAY,CAChB,IAAI,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,gBAAgB,CAAC,CACtE,CAAC;IACF,KAAK,CAAC,WAAW,CAAC;QAChB,QAAQ,EAAE,MAAM,cAAc,CAAC,QAAQ,CAAC;QACxC,KAAK,EAAE,iBAAiB,EAAE;QAC1B,IAAI;QACJ,UAAU,EAAE,oBAAoB,EAAE;KACnC,CAAC,CAAC;IACH,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC;AAED,gEAAgE;AAChE,KAAK,UAAU,OAAO,CACpB,IAAY,EACZ,KAA6B;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,MAAM,KAAK,EAAE;YAAE,OAAO;QAC1B,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,yBAAyB,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC;IACvE,MAAM,KAAK,GAAiB;QAC1B,OAAO,EAAE,aAAa;QACtB,GAAG,EAAE,QAAQ;QACb,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,2BAA2B,CAAC,CAAC;KACtE,CAAC;IAEF,2DAA2D;IAC3D,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7D,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACrB,MAAM,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;QAC1B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,aAAa;QACtB,GAAG,EAAE,QAAQ;QACb,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,UAAU,EAAE,SAAS;QACrB,IAAI,EAAE,EAAE;KACT,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9D,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;QACvB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM;QACrB,WAAW,EAAE,qBAAqB;KACnC,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAEjB,mNAAmN;IACnN,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACtB,0EAA0E;IAC1E,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,cAAc;QACnB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,UAAU,EAAE,SAAS;QACrB,IAAI,EAAE,EAAE;KACT,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,OAAO,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE,CAC5D,OAAO,CAAC,OAAO,CACb,CAAC,CAAC,KAAK;SACJ,oBAAoB,EAAE;SACtB,IAAI,CACH,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,WAAW,KAAK,EAAE,CAAC,KAAK,CAAC,MAAM,CAClE,CACJ,CACF,CAAC;IACF,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,WAAW,CAAC;IAElB,eAAe;IACf,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAEjB,yKAAyK;IACzK,MAAM,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC7E,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAEjB,qKAAqK;IACrK,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAC9D,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CACnD,CAAC;IACF,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5C,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;QAChC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC,CAAC;IACF,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACtB,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,cAAc;QACnB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,UAAU,EAAE,SAAS;QACrB,IAAI,EAAE,EAAE;KACT,CAAC,CAAC;IAEH,8IAA8I;IAC9I,MAAM,OAAO,CACX,sDAAsD,EACtD,KAAK,IAAI,EAAE,CACT,EAAE,CAAC,UAAU,CAAC,IAAI,CAChB,CAAC,EAAE,EAAE,EAAE,CACL,EAAE,CAAC,IAAI,KAAK,cAAc;QAC1B,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,qBAAqB,CAC/C,CACJ,CAAC;IAEF,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACzB,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;AACxE,CAAC;AAED,IAAI,CAAC,+FAA+F,EAAE,KAAK,IAAI,EAAE;IAC/G,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC,CAAC"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integration test for room-state sync (P3.6): a joiner's own local Room record gets the room's real name/description/type from room.join's response, and a later room.members refresh picks up changes made after the join (here, simulated by mutating the owner's own room record directly, since no rename/re-describe verb exists yet).
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
5
|
-
import { test } from "node:test";
|
|
4
|
+
import { test, expect } from "vitest";
|
|
6
5
|
import { MeshStore } from "../core/mesh-store.js";
|
|
7
6
|
import { waitFor, wireTestTransport } from "./test-transport.js";
|
|
8
7
|
let nextPort = 21_010;
|
|
@@ -45,7 +44,7 @@ async function joinAndAccept(owner, member, roomId) {
|
|
|
45
44
|
owner.acceptRoomJoin(roomId, member.peerId);
|
|
46
45
|
await joinPromise;
|
|
47
46
|
}
|
|
48
|
-
|
|
47
|
+
test("a joiner's own local room record carries the room's real name, description, and type", async () => {
|
|
49
48
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
50
49
|
try {
|
|
51
50
|
const room = await owner.createRoom({
|
|
@@ -56,18 +55,20 @@ void test("a joiner's own local room record carries the room's real name, descri
|
|
|
56
55
|
});
|
|
57
56
|
await joinAndAccept(owner, member, room.id);
|
|
58
57
|
const memberCopy = await member.getRoom(room.id);
|
|
59
|
-
|
|
58
|
+
expect(memberCopy).toBeTruthy();
|
|
59
|
+
if (memberCopy === undefined)
|
|
60
|
+
throw new Error("expected member's own copy of the room");
|
|
60
61
|
// createRoom slugs the raw name before storing it (General-Chat, not General Chat) -- the point of this assertion is that member's own copy matches owner's own stored value exactly, not the pre-slug input.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
expect(memberCopy.name).toBe("General-Chat");
|
|
63
|
+
expect(memberCopy.description).toBe("the main room");
|
|
64
|
+
expect(memberCopy.type).toBe("private");
|
|
64
65
|
}
|
|
65
66
|
finally {
|
|
66
67
|
await member.shutdown();
|
|
67
68
|
await owner.shutdown();
|
|
68
69
|
}
|
|
69
70
|
});
|
|
70
|
-
|
|
71
|
+
test("refreshRoomMembers re-syncs a member's own local room record from the owner", async () => {
|
|
71
72
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
72
73
|
try {
|
|
73
74
|
const room = await owner.createRoom({
|
|
@@ -79,24 +80,26 @@ void test("refreshRoomMembers re-syncs a member's own local room record from the
|
|
|
79
80
|
await joinAndAccept(owner, member, room.id);
|
|
80
81
|
// A change on the owner's own side that room.join's own response never carries after the fact -- refreshRoomMembers is the only way member ever learns of it.
|
|
81
82
|
const ownerCopy = await owner.getRoom(room.id);
|
|
82
|
-
|
|
83
|
+
expect(ownerCopy).toBeTruthy();
|
|
84
|
+
if (ownerCopy === undefined)
|
|
85
|
+
throw new Error("expected owner's own copy of the room");
|
|
83
86
|
ownerCopy.description = "renamed after the join";
|
|
84
87
|
const refreshed = await member.refreshRoomMembers(room.id);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
expect(refreshed.description).toBe("renamed after the join");
|
|
89
|
+
expect(refreshed.members.includes(owner.peerId)).toBeTruthy();
|
|
90
|
+
expect(refreshed.members.includes(member.peerId)).toBeTruthy();
|
|
88
91
|
const memberCopy = await member.getRoom(room.id);
|
|
89
|
-
|
|
92
|
+
expect(memberCopy?.description).toBe("renamed after the join");
|
|
90
93
|
}
|
|
91
94
|
finally {
|
|
92
95
|
await member.shutdown();
|
|
93
96
|
await owner.shutdown();
|
|
94
97
|
}
|
|
95
98
|
});
|
|
96
|
-
|
|
99
|
+
test("refreshRoomMembers throws for a DM path -- no Room record exists to refresh", async () => {
|
|
97
100
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
98
101
|
try {
|
|
99
|
-
await
|
|
102
|
+
await expect(member.refreshRoomMembers(`${owner.peerId}+${member.peerId}`)).rejects.toThrow(/not found/i);
|
|
100
103
|
}
|
|
101
104
|
finally {
|
|
102
105
|
await member.shutdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-state-sync.integration.test.js","sourceRoot":"","sources":["../../src/test/room-state-sync.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"room-state-sync.integration.test.js","sourceRoot":"","sources":["../../src/test/room-state-sync.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unit tests for per-room capability token persistence (core/identity-store).
|
|
3
3
|
*/
|
|
4
|
-
import * as assert from "node:assert/strict";
|
|
5
4
|
import * as fs from "node:fs";
|
|
6
5
|
import { tmpdir } from "node:os";
|
|
7
6
|
import path from "node:path";
|
|
8
|
-
import { test } from "
|
|
7
|
+
import { test, expect } from "vitest";
|
|
9
8
|
import { loadOrCreateIdentity, loadRoomTokens, saveRoomToken, deleteRoomToken, releaseIdentityLock, } from "../core/identity-store.js";
|
|
10
9
|
function tempSlot(harness) {
|
|
11
10
|
const dir = fs.mkdtempSync(path.join(tmpdir(), "agent-comms-room-token-test-"));
|
|
@@ -28,60 +27,60 @@ const TOKEN_B = [
|
|
|
28
27
|
];
|
|
29
28
|
const ROOM_A = "aa".repeat(32) + "/general";
|
|
30
29
|
const ROOM_B = "bb".repeat(32) + "/other-room";
|
|
31
|
-
|
|
30
|
+
test("loadRoomTokens returns an empty map before anything is saved", () => {
|
|
32
31
|
const { slot } = tempSlot("pi");
|
|
33
32
|
loadOrCreateIdentity(slot);
|
|
34
|
-
|
|
33
|
+
expect(loadRoomTokens(slot)).toEqual({});
|
|
35
34
|
releaseIdentityLock(slot);
|
|
36
35
|
});
|
|
37
|
-
|
|
36
|
+
test("saveRoomToken persists a token retrievable by loadRoomTokens", () => {
|
|
38
37
|
const { slot } = tempSlot("claude-code");
|
|
39
38
|
loadOrCreateIdentity(slot);
|
|
40
39
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
41
40
|
const tokens = loadRoomTokens(slot);
|
|
42
|
-
|
|
41
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_A);
|
|
43
42
|
releaseIdentityLock(slot);
|
|
44
43
|
});
|
|
45
|
-
|
|
44
|
+
test("saveRoomToken round-trips a token whose payload is null", () => {
|
|
46
45
|
const { slot } = tempSlot("codex");
|
|
47
46
|
loadOrCreateIdentity(slot);
|
|
48
47
|
saveRoomToken(slot, ROOM_B, TOKEN_B);
|
|
49
48
|
const tokens = loadRoomTokens(slot);
|
|
50
|
-
|
|
49
|
+
expect(tokens[ROOM_B]).toEqual(TOKEN_B);
|
|
51
50
|
releaseIdentityLock(slot);
|
|
52
51
|
});
|
|
53
|
-
|
|
52
|
+
test("saveRoomToken for a second room does not disturb the first", () => {
|
|
54
53
|
const { slot } = tempSlot("mcp");
|
|
55
54
|
loadOrCreateIdentity(slot);
|
|
56
55
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
57
56
|
saveRoomToken(slot, ROOM_B, TOKEN_B);
|
|
58
57
|
const tokens = loadRoomTokens(slot);
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_A);
|
|
59
|
+
expect(tokens[ROOM_B]).toEqual(TOKEN_B);
|
|
61
60
|
releaseIdentityLock(slot);
|
|
62
61
|
});
|
|
63
|
-
|
|
62
|
+
test("saveRoomToken overwrites an existing token for the same room", () => {
|
|
64
63
|
const { slot } = tempSlot("opencode");
|
|
65
64
|
loadOrCreateIdentity(slot);
|
|
66
65
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
67
66
|
saveRoomToken(slot, ROOM_A, TOKEN_B);
|
|
68
67
|
const tokens = loadRoomTokens(slot);
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_B);
|
|
69
|
+
expect(Object.keys(tokens).length).toBe(1);
|
|
71
70
|
releaseIdentityLock(slot);
|
|
72
71
|
});
|
|
73
|
-
|
|
72
|
+
test("deleteRoomToken removes only the named room's token", () => {
|
|
74
73
|
const { slot } = tempSlot("user");
|
|
75
74
|
loadOrCreateIdentity(slot);
|
|
76
75
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
77
76
|
saveRoomToken(slot, ROOM_B, TOKEN_B);
|
|
78
77
|
deleteRoomToken(slot, ROOM_A);
|
|
79
78
|
const tokens = loadRoomTokens(slot);
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
expect(ROOM_A in tokens).toBe(false);
|
|
80
|
+
expect(tokens[ROOM_B]).toEqual(TOKEN_B);
|
|
82
81
|
releaseIdentityLock(slot);
|
|
83
82
|
});
|
|
84
|
-
|
|
83
|
+
test("room tokens survive reloading the identity file across a fresh load", () => {
|
|
85
84
|
const { slot } = tempSlot("pi");
|
|
86
85
|
loadOrCreateIdentity(slot);
|
|
87
86
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
@@ -89,16 +88,16 @@ void test("room tokens survive reloading the identity file across a fresh load",
|
|
|
89
88
|
// A fresh process re-loading the same slot.
|
|
90
89
|
loadOrCreateIdentity(slot);
|
|
91
90
|
const tokens = loadRoomTokens(slot);
|
|
92
|
-
|
|
91
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_A);
|
|
93
92
|
releaseIdentityLock(slot);
|
|
94
93
|
});
|
|
95
|
-
|
|
94
|
+
test("saving a room token does not disturb the persisted key material", () => {
|
|
96
95
|
const { slot } = tempSlot("claude-code");
|
|
97
96
|
const identity = loadOrCreateIdentity(slot);
|
|
98
97
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
99
98
|
const reloaded = loadOrCreateIdentity(slot);
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
expect(reloaded.privateKey).toBe(identity.privateKey);
|
|
100
|
+
expect(reloaded.certificate).toBe(identity.certificate);
|
|
102
101
|
releaseIdentityLock(slot);
|
|
103
102
|
});
|
|
104
103
|
//# sourceMappingURL=room-token-store.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-token-store.test.js","sourceRoot":"","sources":["../../src/test/room-token-store.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"room-token-store.test.js","sourceRoot":"","sources":["../../src/test/room-token-store.test.ts"],"names":[],"mappings":"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"}
|