acp-websocket-transport 0.1.1
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/dist/examples/client.d.ts +9 -0
- package/dist/examples/client.d.ts.map +1 -0
- package/dist/examples/client.js +51 -0
- package/dist/examples/client.js.map +1 -0
- package/dist/examples/echo-agent.d.ts +14 -0
- package/dist/examples/echo-agent.d.ts.map +1 -0
- package/dist/examples/echo-agent.js +67 -0
- package/dist/examples/echo-agent.js.map +1 -0
- package/dist/examples/server.d.ts +11 -0
- package/dist/examples/server.d.ts.map +1 -0
- package/dist/examples/server.js +36 -0
- package/dist/examples/server.js.map +1 -0
- package/dist/src/auth.d.ts +110 -0
- package/dist/src/auth.d.ts.map +1 -0
- package/dist/src/auth.js +135 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/client.d.ts +109 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +125 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/index.d.ts +58 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +59 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/server.d.ts +117 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +203 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/transport.d.ts +24 -0
- package/dist/src/transport.d.ts.map +1 -0
- package/dist/src/transport.js +120 -0
- package/dist/src/transport.js.map +1 -0
- package/dist/tests/auth.test.d.ts +2 -0
- package/dist/tests/auth.test.d.ts.map +1 -0
- package/dist/tests/auth.test.js +115 -0
- package/dist/tests/auth.test.js.map +1 -0
- package/dist/tests/client.test.d.ts +2 -0
- package/dist/tests/client.test.d.ts.map +1 -0
- package/dist/tests/client.test.js +121 -0
- package/dist/tests/client.test.js.map +1 -0
- package/dist/tests/e2e.test.d.ts +8 -0
- package/dist/tests/e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e.test.js +130 -0
- package/dist/tests/e2e.test.js.map +1 -0
- package/dist/tests/server.test.d.ts +2 -0
- package/dist/tests/server.test.d.ts.map +1 -0
- package/dist/tests/server.test.js +173 -0
- package/dist/tests/server.test.js.map +1 -0
- package/dist/tests/transport.test.d.ts +2 -0
- package/dist/tests/transport.test.d.ts.map +1 -0
- package/dist/tests/transport.test.js +137 -0
- package/dist/tests/transport.test.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
+
import WebSocket from "ws";
|
|
3
|
+
import { WebSocketACPServer } from "../src/server.js";
|
|
4
|
+
import { bearerAuth } from "../src/auth.js";
|
|
5
|
+
/** Absolute path to the compiled echo-agent. Built by tsc before tests run. */
|
|
6
|
+
const ECHO_AGENT = new URL("../dist/examples/echo-agent.js", import.meta.url)
|
|
7
|
+
.pathname;
|
|
8
|
+
// ─── helpers ─────────────────────────────────────────────────────────────────
|
|
9
|
+
function openWs(port, headers) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const ws = new WebSocket(`ws://localhost:${port}`, { headers });
|
|
12
|
+
ws.once("open", () => resolve(ws));
|
|
13
|
+
ws.once("error", reject);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Collects all messages from a WebSocket into a queue.
|
|
18
|
+
* Returns a function that pops the next message (waiting if necessary).
|
|
19
|
+
*/
|
|
20
|
+
function messageQueue(ws) {
|
|
21
|
+
const queue = [];
|
|
22
|
+
const waiters = [];
|
|
23
|
+
const errorWaiters = [];
|
|
24
|
+
ws.on("message", (data) => {
|
|
25
|
+
const msg = JSON.parse(data.toString());
|
|
26
|
+
const waiter = waiters.shift();
|
|
27
|
+
if (waiter) {
|
|
28
|
+
waiter(msg);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
queue.push(msg);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
ws.on("error", (err) => {
|
|
35
|
+
for (const ew of errorWaiters.splice(0))
|
|
36
|
+
ew(err);
|
|
37
|
+
});
|
|
38
|
+
ws.on("close", () => {
|
|
39
|
+
const err = new Error("WebSocket closed");
|
|
40
|
+
for (const ew of errorWaiters.splice(0))
|
|
41
|
+
ew(err);
|
|
42
|
+
for (const w of waiters.splice(0))
|
|
43
|
+
w({ jsonrpc: "2.0", method: "_closed" });
|
|
44
|
+
});
|
|
45
|
+
return () => new Promise((resolve, reject) => {
|
|
46
|
+
const queued = queue.shift();
|
|
47
|
+
if (queued != null) {
|
|
48
|
+
resolve(queued);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
waiters.push(resolve);
|
|
52
|
+
errorWaiters.push(reject);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async function sendAndReceive(nextMsg, ws, msg) {
|
|
57
|
+
const p = nextMsg();
|
|
58
|
+
ws.send(JSON.stringify(msg));
|
|
59
|
+
return p;
|
|
60
|
+
}
|
|
61
|
+
// ─── tests ───────────────────────────────────────────────────────────────────
|
|
62
|
+
describe("WebSocketACPServer (no auth)", () => {
|
|
63
|
+
let server;
|
|
64
|
+
let port;
|
|
65
|
+
beforeAll(async () => {
|
|
66
|
+
server = new WebSocketACPServer({
|
|
67
|
+
port: 0,
|
|
68
|
+
command: "node",
|
|
69
|
+
args: [ECHO_AGENT],
|
|
70
|
+
});
|
|
71
|
+
await server.listening();
|
|
72
|
+
port = server.address.port;
|
|
73
|
+
});
|
|
74
|
+
afterAll(async () => {
|
|
75
|
+
await server.close().catch(() => { });
|
|
76
|
+
});
|
|
77
|
+
it("accepts a connection and reflects an initialize request", async () => {
|
|
78
|
+
const ws = await openWs(port);
|
|
79
|
+
const nextMsg = messageQueue(ws);
|
|
80
|
+
const req = {
|
|
81
|
+
jsonrpc: "2.0",
|
|
82
|
+
id: 1,
|
|
83
|
+
method: "initialize",
|
|
84
|
+
params: {
|
|
85
|
+
protocolVersion: 0,
|
|
86
|
+
clientInfo: { name: "test-client", version: "0.0.1" },
|
|
87
|
+
clientCapabilities: {},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
const response = await sendAndReceive(nextMsg, ws, req);
|
|
91
|
+
expect(response.id).toBe(1);
|
|
92
|
+
expect(response.result
|
|
93
|
+
?.agentInfo?.name).toBe("echo-agent");
|
|
94
|
+
ws.close();
|
|
95
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
96
|
+
});
|
|
97
|
+
it("handles multiple sequential requests", async () => {
|
|
98
|
+
const ws = await openWs(port);
|
|
99
|
+
const nextMsg = messageQueue(ws);
|
|
100
|
+
const initReq = {
|
|
101
|
+
jsonrpc: "2.0",
|
|
102
|
+
id: 1,
|
|
103
|
+
method: "initialize",
|
|
104
|
+
params: {
|
|
105
|
+
protocolVersion: 0,
|
|
106
|
+
clientInfo: { name: "test-client", version: "0.0.1" },
|
|
107
|
+
clientCapabilities: {},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
await sendAndReceive(nextMsg, ws, initReq);
|
|
111
|
+
const sessionReq = {
|
|
112
|
+
jsonrpc: "2.0",
|
|
113
|
+
id: 2,
|
|
114
|
+
method: "session/new",
|
|
115
|
+
params: {
|
|
116
|
+
cwd: "/tmp",
|
|
117
|
+
mcpServers: [],
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const sessionResp = await sendAndReceive(nextMsg, ws, sessionReq);
|
|
121
|
+
const sessionId = sessionResp
|
|
122
|
+
.result?.sessionId;
|
|
123
|
+
expect(typeof sessionId).toBe("string");
|
|
124
|
+
expect(sessionId.length).toBeGreaterThan(0);
|
|
125
|
+
ws.close();
|
|
126
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
127
|
+
});
|
|
128
|
+
it("closes the WebSocket when the agent process exits", async () => {
|
|
129
|
+
const ws = await openWs(port);
|
|
130
|
+
const nextMsg = messageQueue(ws);
|
|
131
|
+
const initReq = {
|
|
132
|
+
jsonrpc: "2.0",
|
|
133
|
+
id: 1,
|
|
134
|
+
method: "initialize",
|
|
135
|
+
params: { protocolVersion: 0, clientCapabilities: {} },
|
|
136
|
+
};
|
|
137
|
+
await sendAndReceive(nextMsg, ws, initReq);
|
|
138
|
+
const closePromise = new Promise((resolve) => ws.once("close", (code) => resolve(code)));
|
|
139
|
+
ws.close(1000);
|
|
140
|
+
const code = await closePromise;
|
|
141
|
+
expect(code).toBe(1000);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("WebSocketACPServer (bearer auth)", () => {
|
|
145
|
+
let server;
|
|
146
|
+
let port;
|
|
147
|
+
beforeAll(async () => {
|
|
148
|
+
server = new WebSocketACPServer({
|
|
149
|
+
port: 0,
|
|
150
|
+
command: "node",
|
|
151
|
+
args: [ECHO_AGENT],
|
|
152
|
+
verifyClient: bearerAuth(["valid-token"]),
|
|
153
|
+
});
|
|
154
|
+
await server.listening();
|
|
155
|
+
port = server.address.port;
|
|
156
|
+
});
|
|
157
|
+
afterAll(async () => {
|
|
158
|
+
await server.close().catch(() => { });
|
|
159
|
+
});
|
|
160
|
+
it("accepts a connection with a valid bearer token", async () => {
|
|
161
|
+
const ws = await openWs(port, { Authorization: "Bearer valid-token" });
|
|
162
|
+
expect(ws.readyState).toBe(WebSocket.OPEN);
|
|
163
|
+
ws.close();
|
|
164
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
165
|
+
});
|
|
166
|
+
it("rejects a connection with an invalid token (HTTP 401)", async () => {
|
|
167
|
+
await expect(openWs(port, { Authorization: "Bearer wrong-token" })).rejects.toThrow();
|
|
168
|
+
});
|
|
169
|
+
it("rejects a connection with no Authorization header", async () => {
|
|
170
|
+
await expect(openWs(port)).rejects.toThrow();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
//# sourceMappingURL=server.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../tests/server.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.test.d.ts","sourceRoot":"","sources":["../../tests/transport.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import WebSocket, { WebSocketServer } from "ws";
|
|
3
|
+
import { wsStream } from "../src/transport.js";
|
|
4
|
+
/** Opens a local WebSocket server and a connected client, returns both sockets. */
|
|
5
|
+
async function createPair() {
|
|
6
|
+
const wss = new WebSocketServer({ port: 0 });
|
|
7
|
+
await new Promise((resolve) => wss.once("listening", resolve));
|
|
8
|
+
const { port } = wss.address();
|
|
9
|
+
const [serverWs, clientWs] = await new Promise((resolve) => {
|
|
10
|
+
const client = new WebSocket(`ws://localhost:${port}`);
|
|
11
|
+
wss.once("connection", (server) => {
|
|
12
|
+
// Ensure the client open event has also fired
|
|
13
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
14
|
+
resolve([server, client]);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
client.once("open", () => resolve([server, client]));
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
return { wss, serverWs, clientWs };
|
|
22
|
+
}
|
|
23
|
+
describe("wsStream", () => {
|
|
24
|
+
let wss;
|
|
25
|
+
let serverWs;
|
|
26
|
+
let clientWs;
|
|
27
|
+
beforeEach(async () => {
|
|
28
|
+
({ wss, serverWs, clientWs } = await createPair());
|
|
29
|
+
});
|
|
30
|
+
afterEach(async () => {
|
|
31
|
+
// Terminate connections first so wss.close() callback fires promptly
|
|
32
|
+
serverWs.terminate();
|
|
33
|
+
clientWs.terminate();
|
|
34
|
+
await new Promise((resolve) => {
|
|
35
|
+
wss.close(() => resolve());
|
|
36
|
+
// Safety timeout in case close callback stalls
|
|
37
|
+
setTimeout(resolve, 500);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
// ── readable ──────────────────────────────────────────────────────────
|
|
41
|
+
it("enqueues a parsed AnyMessage when a text frame arrives", async () => {
|
|
42
|
+
const stream = wsStream(serverWs);
|
|
43
|
+
const reader = stream.readable.getReader();
|
|
44
|
+
const msg = {
|
|
45
|
+
jsonrpc: "2.0",
|
|
46
|
+
id: 1,
|
|
47
|
+
method: "ping",
|
|
48
|
+
params: {},
|
|
49
|
+
};
|
|
50
|
+
clientWs.send(JSON.stringify(msg));
|
|
51
|
+
const { done, value } = await reader.read();
|
|
52
|
+
expect(done).toBe(false);
|
|
53
|
+
expect(value).toEqual(msg);
|
|
54
|
+
reader.releaseLock();
|
|
55
|
+
});
|
|
56
|
+
it("ignores binary frames silently", async () => {
|
|
57
|
+
const stream = wsStream(serverWs);
|
|
58
|
+
const reader = stream.readable.getReader();
|
|
59
|
+
// Send a binary frame, then a text frame — only the text one should arrive
|
|
60
|
+
clientWs.send(Buffer.from([0x01, 0x02, 0x03])); // binary
|
|
61
|
+
const textMsg = { jsonrpc: "2.0", method: "notify" };
|
|
62
|
+
clientWs.send(JSON.stringify(textMsg));
|
|
63
|
+
const { done, value } = await reader.read();
|
|
64
|
+
expect(done).toBe(false);
|
|
65
|
+
expect(value).toEqual(textMsg);
|
|
66
|
+
reader.releaseLock();
|
|
67
|
+
});
|
|
68
|
+
it("errors the readable when a malformed JSON frame arrives", async () => {
|
|
69
|
+
const stream = wsStream(serverWs);
|
|
70
|
+
const reader = stream.readable.getReader();
|
|
71
|
+
clientWs.send("not-valid-json{{{");
|
|
72
|
+
await expect(reader.read()).rejects.toThrow(SyntaxError);
|
|
73
|
+
reader.releaseLock();
|
|
74
|
+
});
|
|
75
|
+
it("closes the readable when the remote WebSocket closes", async () => {
|
|
76
|
+
const stream = wsStream(serverWs);
|
|
77
|
+
const reader = stream.readable.getReader();
|
|
78
|
+
clientWs.close(1000);
|
|
79
|
+
const { done } = await reader.read();
|
|
80
|
+
expect(done).toBe(true);
|
|
81
|
+
reader.releaseLock();
|
|
82
|
+
});
|
|
83
|
+
// ── writable ──────────────────────────────────────────────────────────
|
|
84
|
+
it("sends a JSON text frame when writing to the writable", async () => {
|
|
85
|
+
const stream = wsStream(clientWs);
|
|
86
|
+
const writer = stream.writable.getWriter();
|
|
87
|
+
const received = [];
|
|
88
|
+
serverWs.on("message", (data) => received.push(data.toString("utf8")));
|
|
89
|
+
const msg = { jsonrpc: "2.0", method: "notify" };
|
|
90
|
+
await writer.write(msg);
|
|
91
|
+
// Wait for the frame to arrive
|
|
92
|
+
await new Promise((resolve) => {
|
|
93
|
+
const check = () => received.length > 0 ? resolve() : setTimeout(check, 10);
|
|
94
|
+
check();
|
|
95
|
+
});
|
|
96
|
+
expect(JSON.parse(received[0])).toEqual(msg);
|
|
97
|
+
writer.releaseLock();
|
|
98
|
+
});
|
|
99
|
+
it("serialises multiple writes in order", async () => {
|
|
100
|
+
const stream = wsStream(clientWs);
|
|
101
|
+
const writer = stream.writable.getWriter();
|
|
102
|
+
const received = [];
|
|
103
|
+
serverWs.on("message", (data) => received.push(JSON.parse(data.toString("utf8"))));
|
|
104
|
+
const msgs = [
|
|
105
|
+
{ jsonrpc: "2.0", id: 1, method: "first", params: {} },
|
|
106
|
+
{ jsonrpc: "2.0", id: 2, method: "second", params: {} },
|
|
107
|
+
{ jsonrpc: "2.0", id: 3, method: "third", params: {} },
|
|
108
|
+
];
|
|
109
|
+
for (const m of msgs)
|
|
110
|
+
await writer.write(m);
|
|
111
|
+
await new Promise((resolve) => {
|
|
112
|
+
const check = () => received.length >= msgs.length ? resolve() : setTimeout(check, 10);
|
|
113
|
+
check();
|
|
114
|
+
});
|
|
115
|
+
expect(received).toEqual(msgs);
|
|
116
|
+
writer.releaseLock();
|
|
117
|
+
});
|
|
118
|
+
// ── round-trip ────────────────────────────────────────────────────────
|
|
119
|
+
it("supports a full round-trip through two wsStream instances", async () => {
|
|
120
|
+
const serverStream = wsStream(serverWs);
|
|
121
|
+
const clientStream = wsStream(clientWs);
|
|
122
|
+
const writer = clientStream.writable.getWriter();
|
|
123
|
+
const reader = serverStream.readable.getReader();
|
|
124
|
+
const request = {
|
|
125
|
+
jsonrpc: "2.0",
|
|
126
|
+
id: 42,
|
|
127
|
+
method: "session/prompt",
|
|
128
|
+
params: { sessionId: "s1", text: "hello" },
|
|
129
|
+
};
|
|
130
|
+
await writer.write(request);
|
|
131
|
+
const { value } = await reader.read();
|
|
132
|
+
expect(value).toEqual(request);
|
|
133
|
+
writer.releaseLock();
|
|
134
|
+
reader.releaseLock();
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=transport.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.test.js","sourceRoot":"","sources":["../../tests/transport.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "acp-websocket-transport",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "WebSocket transport layer for ACP (Agent Client Protocol) — TypeScript client library",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/src/index.js",
|
|
7
|
+
"types": "dist/src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/src/index.js",
|
|
11
|
+
"types": "./dist/src/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"lint": "eslint src tests examples"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"ws": "^8.20.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@agentclientprotocol/sdk": "^0.18.2",
|
|
28
|
+
"zod": "^3.25.0 || ^4.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@agentclientprotocol/sdk": "^0.18.2",
|
|
32
|
+
"@types/node": "^22.0.0",
|
|
33
|
+
"@types/ws": "^8.18.1",
|
|
34
|
+
"typescript": "^5.8.3",
|
|
35
|
+
"vitest": "^3.1.1",
|
|
36
|
+
"zod": "^4.0.0"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|