zcode-acp-server 0.2.0 → 0.3.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.
- package/README.md +101 -15
- package/README.zh-CN.md +68 -13
- package/dist/bin/hub.d.ts +16 -0
- package/dist/bin/hub.d.ts.map +1 -0
- package/dist/bin/hub.js +41 -0
- package/dist/bin/hub.js.map +1 -0
- package/dist/handlers/account.d.ts +43 -0
- package/dist/handlers/account.d.ts.map +1 -0
- package/dist/handlers/account.js +59 -0
- package/dist/handlers/account.js.map +1 -0
- package/dist/handlers/io.d.ts +20 -1
- package/dist/handlers/io.d.ts.map +1 -1
- package/dist/handlers/io.js +57 -2
- package/dist/handlers/io.js.map +1 -1
- package/dist/handlers/replay.d.ts +79 -0
- package/dist/handlers/replay.d.ts.map +1 -0
- package/dist/handlers/replay.js +252 -0
- package/dist/handlers/replay.js.map +1 -0
- package/dist/handlers/session.d.ts.map +1 -1
- package/dist/handlers/session.js +64 -65
- package/dist/handlers/session.js.map +1 -1
- package/dist/handlers/slash.d.ts +23 -1
- package/dist/handlers/slash.d.ts.map +1 -1
- package/dist/handlers/slash.js +67 -6
- package/dist/handlers/slash.js.map +1 -1
- package/dist/index.js +47 -17
- package/dist/index.js.map +1 -1
- package/dist/remote/broadcast.d.ts +47 -0
- package/dist/remote/broadcast.d.ts.map +1 -0
- package/dist/remote/broadcast.js +121 -0
- package/dist/remote/broadcast.js.map +1 -0
- package/dist/remote/config.d.ts +32 -0
- package/dist/remote/config.d.ts.map +1 -0
- package/dist/remote/config.js +65 -0
- package/dist/remote/config.js.map +1 -0
- package/dist/remote/endpoint.d.ts +30 -0
- package/dist/remote/endpoint.d.ts.map +1 -0
- package/dist/remote/endpoint.js +213 -0
- package/dist/remote/endpoint.js.map +1 -0
- package/dist/remote/hub-server.d.ts +41 -0
- package/dist/remote/hub-server.d.ts.map +1 -0
- package/dist/remote/hub-server.js +346 -0
- package/dist/remote/hub-server.js.map +1 -0
- package/dist/server.d.ts +41 -7
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +69 -11
- package/dist/server.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +17 -1
- package/dist/utils.js.map +1 -1
- package/docs/ARCHITECTURE.md +47 -15
- package/docs/BACKLOG.md +3 -1
- package/docs/DEVELOPMENT.md +26 -0
- package/docs/PROTOCOL.md +67 -27
- package/docs/REMOTE-CLIENTS.md +260 -0
- package/docs/REPLAY-GUIDE.md +131 -0
- package/docs/TROUBLESHOOTING.md +39 -6
- package/docs/adr/0001-bridge-lifetime-follows-primary-client.md +14 -0
- package/docs/adr/0002-stateless-hub-over-per-bridge-acp-endpoints.md +23 -0
- package/docs/adr/0003-tail-replay-meta-and-cursor-pagination.md +40 -0
- package/docs/proposals/0001-tail-session-replay.md +136 -0
- package/docs/proposals/0002-plan-quota-usage.md +81 -0
- package/package.json +5 -2
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zcode-acp-hub — machine-level singleton for remote access.
|
|
3
|
+
*
|
|
4
|
+
* The hub is the ONLY public entry point (the port a tunnel maps). It does
|
|
5
|
+
* exactly three things (ADR-0002): token auth, instance discovery, and
|
|
6
|
+
* byte-level WebSocket proxying from a remote client to one bridge's loopback
|
|
7
|
+
* ACP endpoint. It holds no session state and understands no ACP — a proxied
|
|
8
|
+
* connection stays bound to one instance for its whole lifetime.
|
|
9
|
+
*
|
|
10
|
+
* Bridges register via POST /api/register every 10s (the registration doubles
|
|
11
|
+
* as the heartbeat; entries older than the heartbeat TTL are pruned). A client
|
|
12
|
+
* that needs an immediately-honest list (e.g. a phone app's pull-to-refresh)
|
|
13
|
+
* passes ?probe=1 to /api/instances: the hub TCP-probes each registered
|
|
14
|
+
* loopback port and prunes unreachable bridges before answering — no periodic
|
|
15
|
+
* probing, the cost is paid only when someone refreshes. When no instance is
|
|
16
|
+
* registered and no proxy is active for `idleExitMs`, the hub exits — the
|
|
17
|
+
* next bridge re-spawns it on demand.
|
|
18
|
+
*/
|
|
19
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
20
|
+
import { createServer } from "node:http";
|
|
21
|
+
import net from "node:net";
|
|
22
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
23
|
+
import { AGENT_INFO, compareVersions, log, warn } from "../utils.js";
|
|
24
|
+
const HEARTBEAT_TIMEOUT_MS = 30_000;
|
|
25
|
+
const IDLE_EXIT_MS = 10 * 60_000;
|
|
26
|
+
const PING_INTERVAL_MS = 30_000;
|
|
27
|
+
/** Per-instance TCP probe timeout for /api/instances?probe=1. */
|
|
28
|
+
const PROBE_TIMEOUT_MS = 500;
|
|
29
|
+
const MAX_BODY_BYTES = 1024 * 1024;
|
|
30
|
+
/** Constant-time token compare (hash both to equal length first). */
|
|
31
|
+
function tokenEquals(a, b) {
|
|
32
|
+
const ha = createHash("sha256").update(a).digest();
|
|
33
|
+
const hb = createHash("sha256").update(b).digest();
|
|
34
|
+
return timingSafeEqual(ha, hb);
|
|
35
|
+
}
|
|
36
|
+
function authorized(req, url, token) {
|
|
37
|
+
const header = req.headers.authorization;
|
|
38
|
+
if (header?.startsWith("Bearer "))
|
|
39
|
+
return tokenEquals(header.slice(7), token);
|
|
40
|
+
const query = url.searchParams.get("token");
|
|
41
|
+
return query !== null && tokenEquals(query, token);
|
|
42
|
+
}
|
|
43
|
+
function setCors(res) {
|
|
44
|
+
// The web UI is deployed as a separate origin; the token is the boundary.
|
|
45
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
46
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
47
|
+
res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
|
|
48
|
+
}
|
|
49
|
+
async function readJson(req) {
|
|
50
|
+
const chunks = [];
|
|
51
|
+
let size = 0;
|
|
52
|
+
try {
|
|
53
|
+
// The async iterator rejects when the client aborts mid-body — a truncated
|
|
54
|
+
// POST must degrade to "invalid body", not reject into the event loop.
|
|
55
|
+
for await (const chunk of req) {
|
|
56
|
+
size += chunk.length;
|
|
57
|
+
if (size > MAX_BODY_BYTES)
|
|
58
|
+
return null;
|
|
59
|
+
chunks.push(chunk);
|
|
60
|
+
}
|
|
61
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
62
|
+
return typeof parsed === "object" && parsed !== null
|
|
63
|
+
? parsed
|
|
64
|
+
: null;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function validSessions(raw) {
|
|
71
|
+
if (!Array.isArray(raw))
|
|
72
|
+
return null;
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const s of raw) {
|
|
75
|
+
const rec = s;
|
|
76
|
+
if (typeof rec?.sessionId !== "string")
|
|
77
|
+
return null;
|
|
78
|
+
out.push({
|
|
79
|
+
sessionId: rec.sessionId,
|
|
80
|
+
...(typeof rec.title === "string" ? { title: rec.title } : {}),
|
|
81
|
+
updatedAt: typeof rec.updatedAt === "number" ? rec.updatedAt : Date.now(),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* TCP-probe a bridge's loopback endpoint. Loopback refusals are instant, so
|
|
88
|
+
* the timeout only guards pathological cases; a bare connect+destroy is
|
|
89
|
+
* harmless to the bridge's HTTP server.
|
|
90
|
+
*/
|
|
91
|
+
function portOpen(port, timeoutMs) {
|
|
92
|
+
return new Promise((resolve) => {
|
|
93
|
+
const socket = new net.Socket();
|
|
94
|
+
const done = (ok) => {
|
|
95
|
+
socket.destroy();
|
|
96
|
+
resolve(ok);
|
|
97
|
+
};
|
|
98
|
+
socket.setTimeout(timeoutMs);
|
|
99
|
+
socket.once("connect", () => done(true));
|
|
100
|
+
socket.once("timeout", () => done(false));
|
|
101
|
+
socket.once("error", () => done(false));
|
|
102
|
+
socket.connect(port, "127.0.0.1");
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Start the hub. Resolves once listening; rejects on bind failure (including
|
|
107
|
+
* EADDRINUSE when another hub already owns the port).
|
|
108
|
+
*/
|
|
109
|
+
export function startHub(options) {
|
|
110
|
+
const { port, host, token, heartbeatTimeoutMs = HEARTBEAT_TIMEOUT_MS, idleExitMs = IDLE_EXIT_MS, pingIntervalMs = PING_INTERVAL_MS, onIdleExit, } = options;
|
|
111
|
+
const instances = new Map();
|
|
112
|
+
const proxyPairs = new Set();
|
|
113
|
+
const timers = [];
|
|
114
|
+
let idleSince = null;
|
|
115
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
116
|
+
const server = createServer((req, res) => {
|
|
117
|
+
// Async handler failures (malformed URL, aborted body) must never escape
|
|
118
|
+
// into the event loop — warn and drop the connection.
|
|
119
|
+
void handleHttp(req, res).catch((e) => {
|
|
120
|
+
warn(`hub: request failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
121
|
+
res.destroy();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
server.on("upgrade", (req, socket, head) => {
|
|
125
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
126
|
+
if (url.pathname !== "/acp") {
|
|
127
|
+
socket.destroy();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (!authorized(req, url, token)) {
|
|
131
|
+
warn("hub: unauthorized WS upgrade rejected");
|
|
132
|
+
socket.destroy();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const entry = instances.get(url.searchParams.get("instance") ?? "");
|
|
136
|
+
if (!entry) {
|
|
137
|
+
warn("hub: WS upgrade for unknown instance rejected");
|
|
138
|
+
socket.destroy();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Dial the bridge's loopback endpoint before accepting the client side,
|
|
142
|
+
// so a dead bridge fails the upgrade instead of half-opening a pipe.
|
|
143
|
+
const bridge = new WebSocket(`ws://127.0.0.1:${entry.port}/acp`);
|
|
144
|
+
bridge.once("open", () => {
|
|
145
|
+
wss.handleUpgrade(req, socket, head, (client) => startProxy(client, bridge));
|
|
146
|
+
});
|
|
147
|
+
bridge.once("error", (e) => {
|
|
148
|
+
warn(`hub: dial bridge :${entry.port} failed: ${e.message}`);
|
|
149
|
+
socket.destroy();
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
async function handleHttp(req, res) {
|
|
153
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
154
|
+
setCors(res);
|
|
155
|
+
if (req.method === "OPTIONS") {
|
|
156
|
+
res.writeHead(204);
|
|
157
|
+
res.end();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (url.pathname === "/api/health") {
|
|
161
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
162
|
+
res.end("ok");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (url.pathname === "/api/instances" && req.method === "GET") {
|
|
166
|
+
if (!authorized(req, url, token)) {
|
|
167
|
+
res.writeHead(401, { "Content-Type": "text/plain" });
|
|
168
|
+
res.end("unauthorized");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// On-demand liveness probe (?probe=1): verify every registered bridge's
|
|
172
|
+
// loopback port and prune the unreachable ones before answering, so a
|
|
173
|
+
// client refresh gets an honest list instead of waiting out the
|
|
174
|
+
// heartbeat TTL (hard-killed bridges never unregister).
|
|
175
|
+
if (["1", "true"].includes((url.searchParams.get("probe") ?? "").toLowerCase())) {
|
|
176
|
+
const probes = await Promise.all(Array.from(instances.entries(), async ([id, entry]) => ({
|
|
177
|
+
id,
|
|
178
|
+
ok: await portOpen(entry.port, PROBE_TIMEOUT_MS),
|
|
179
|
+
})));
|
|
180
|
+
for (const { id, ok } of probes) {
|
|
181
|
+
if (!ok) {
|
|
182
|
+
instances.delete(id);
|
|
183
|
+
idleSince = null; // re-arm the idle clock on membership change
|
|
184
|
+
log(`hub: pruned instance ${id} (probe: endpoint unreachable)`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const list = Array.from(instances.values())
|
|
189
|
+
.sort((a, b) => a.startedAt - b.startedAt)
|
|
190
|
+
.map((e) => ({
|
|
191
|
+
id: e.id,
|
|
192
|
+
port: e.port,
|
|
193
|
+
pid: e.pid,
|
|
194
|
+
startedAt: e.startedAt,
|
|
195
|
+
workspace: e.workspace,
|
|
196
|
+
sessions: e.sessions,
|
|
197
|
+
}));
|
|
198
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
199
|
+
res.end(JSON.stringify(list));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if ((url.pathname === "/api/register" || url.pathname === "/api/unregister") &&
|
|
203
|
+
req.method === "POST") {
|
|
204
|
+
const body = await readJson(req);
|
|
205
|
+
if (!body || typeof body.token !== "string" || !tokenEquals(body.token, token)) {
|
|
206
|
+
res.writeHead(401, { "Content-Type": "text/plain" });
|
|
207
|
+
res.end("unauthorized");
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const id = typeof body.id === "string" ? body.id : "";
|
|
211
|
+
if (!id) {
|
|
212
|
+
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
213
|
+
res.end("missing id");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (url.pathname === "/api/register") {
|
|
217
|
+
const bridgePort = typeof body.port === "number" ? body.port : 0;
|
|
218
|
+
const sessions = validSessions(body.sessions);
|
|
219
|
+
if (!(bridgePort >= 1 && bridgePort <= 65535) || !sessions) {
|
|
220
|
+
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
221
|
+
res.end("invalid register payload");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const prev = instances.get(id);
|
|
225
|
+
instances.set(id, {
|
|
226
|
+
id,
|
|
227
|
+
port: bridgePort,
|
|
228
|
+
pid: typeof body.pid === "number" ? body.pid : 0,
|
|
229
|
+
startedAt: prev?.startedAt ?? Date.now(),
|
|
230
|
+
workspace: typeof body.workspace === "string" ? body.workspace : "",
|
|
231
|
+
sessions,
|
|
232
|
+
lastSeen: Date.now(),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
instances.delete(id);
|
|
237
|
+
idleSince = null; // re-arm the idle clock on membership change
|
|
238
|
+
}
|
|
239
|
+
// Version self-upgrade: a bridge NEWER than this hub just registered,
|
|
240
|
+
// so this process is running stale code. Reply first (the bridge
|
|
241
|
+
// re-spawns the hub from its own, newer dist when it sees `restarting`),
|
|
242
|
+
// then exit. Equal/older/absent versions never trigger a restart.
|
|
243
|
+
const stale = url.pathname === "/api/register" &&
|
|
244
|
+
typeof body.version === "string" &&
|
|
245
|
+
compareVersions(body.version, AGENT_INFO.version) > 0;
|
|
246
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
247
|
+
res.end(JSON.stringify(stale ? { ok: true, restarting: true } : { ok: true }));
|
|
248
|
+
if (stale) {
|
|
249
|
+
log(`hub: bridge ${body.version} is newer than hub ${AGENT_INFO.version} — restarting to upgrade`);
|
|
250
|
+
const restart = setTimeout(() => {
|
|
251
|
+
void close().finally(() => onIdleExit?.());
|
|
252
|
+
}, 500);
|
|
253
|
+
restart.unref();
|
|
254
|
+
}
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
258
|
+
res.end("not found");
|
|
259
|
+
}
|
|
260
|
+
function startProxy(client, bridge) {
|
|
261
|
+
const pair = { client, bridge };
|
|
262
|
+
proxyPairs.add(pair);
|
|
263
|
+
const teardown = () => {
|
|
264
|
+
if (!proxyPairs.delete(pair))
|
|
265
|
+
return;
|
|
266
|
+
client.close();
|
|
267
|
+
bridge.close();
|
|
268
|
+
};
|
|
269
|
+
// Forward with the frame's binary flag intact: `ws.send(buffer)` defaults
|
|
270
|
+
// to a BINARY frame, and the SDK's WS server drops non-text frames.
|
|
271
|
+
const forward = (to) => (data, isBinary) => {
|
|
272
|
+
if (to.readyState === WebSocket.OPEN)
|
|
273
|
+
to.send(data, { binary: isBinary });
|
|
274
|
+
};
|
|
275
|
+
client.on("message", forward(bridge));
|
|
276
|
+
bridge.on("message", forward(client));
|
|
277
|
+
client.on("close", teardown);
|
|
278
|
+
client.on("error", teardown);
|
|
279
|
+
bridge.on("close", teardown);
|
|
280
|
+
bridge.on("error", teardown);
|
|
281
|
+
}
|
|
282
|
+
// Prune instances whose bridge stopped heartbeating (crash or Zed exit).
|
|
283
|
+
const pruner = setInterval(() => {
|
|
284
|
+
const now = Date.now();
|
|
285
|
+
for (const [id, entry] of instances) {
|
|
286
|
+
if (now - entry.lastSeen > heartbeatTimeoutMs) {
|
|
287
|
+
instances.delete(id);
|
|
288
|
+
idleSince = null;
|
|
289
|
+
log(`hub: pruned instance ${id} (heartbeat timeout)`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}, Math.min(heartbeatTimeoutMs / 2, 5_000));
|
|
293
|
+
pruner.unref();
|
|
294
|
+
timers.push(pruner);
|
|
295
|
+
// Keepalive pings on both legs — tunnels (notably Cloudflare) drop idle WS.
|
|
296
|
+
const pinger = setInterval(() => {
|
|
297
|
+
for (const { client, bridge } of proxyPairs) {
|
|
298
|
+
if (client.readyState === WebSocket.OPEN)
|
|
299
|
+
client.ping();
|
|
300
|
+
if (bridge.readyState === WebSocket.OPEN)
|
|
301
|
+
bridge.ping();
|
|
302
|
+
}
|
|
303
|
+
}, pingIntervalMs);
|
|
304
|
+
pinger.unref();
|
|
305
|
+
timers.push(pinger);
|
|
306
|
+
// Idle exit: with nothing registered and nobody proxied, the hub exits; the
|
|
307
|
+
// next bridge re-spawns it on demand (see endpoint.ts).
|
|
308
|
+
const idleCheck = setInterval(() => {
|
|
309
|
+
if (instances.size > 0 || proxyPairs.size > 0) {
|
|
310
|
+
idleSince = null;
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (idleSince === null)
|
|
314
|
+
idleSince = Date.now();
|
|
315
|
+
if (Date.now() - idleSince >= idleExitMs) {
|
|
316
|
+
log("hub: idle for too long with no instances — exiting");
|
|
317
|
+
clearInterval(idleCheck);
|
|
318
|
+
void close().finally(() => onIdleExit?.());
|
|
319
|
+
}
|
|
320
|
+
}, Math.min(idleExitMs / 4, 10_000));
|
|
321
|
+
idleCheck.unref();
|
|
322
|
+
timers.push(idleCheck);
|
|
323
|
+
async function close() {
|
|
324
|
+
for (const t of timers)
|
|
325
|
+
clearInterval(t);
|
|
326
|
+
for (const { client, bridge } of proxyPairs) {
|
|
327
|
+
client.terminate();
|
|
328
|
+
bridge.terminate();
|
|
329
|
+
}
|
|
330
|
+
proxyPairs.clear();
|
|
331
|
+
wss.close();
|
|
332
|
+
server.closeAllConnections?.();
|
|
333
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
334
|
+
}
|
|
335
|
+
return new Promise((resolve, reject) => {
|
|
336
|
+
server.once("error", reject);
|
|
337
|
+
server.listen(port, host, () => {
|
|
338
|
+
// port 0 binds an ephemeral port — report the actual one (used by tests).
|
|
339
|
+
const addr = server.address();
|
|
340
|
+
const bound = typeof addr === "object" && addr !== null ? addr.port : port;
|
|
341
|
+
log(`hub: listening on ${host}:${bound} (instances: 0)`);
|
|
342
|
+
resolve({ port: bound, close });
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=hub-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-server.js","sourceRoot":"","sources":["../../src/remote/hub-server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type * as acp from "@agentclientprotocol/sdk";
|
|
10
10
|
import { ZcodeBackend } from "./backend/index.js";
|
|
11
11
|
import { BackgroundTaskListener } from "./handlers/background-tasks.js";
|
|
12
|
+
import { ClientRegistry } from "./remote/broadcast.js";
|
|
12
13
|
/** Client capabilities advertised in the initialize request. */
|
|
13
14
|
export interface ClientCapabilities {
|
|
14
15
|
fs?: {
|
|
@@ -72,6 +73,13 @@ export declare class ZcodeAcpServer {
|
|
|
72
73
|
* passed through unchanged. */
|
|
73
74
|
mcpServers?: acp.McpServer[];
|
|
74
75
|
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Session cwds (acp_sid → cwd), recorded at session/new and lazy-recovery.
|
|
78
|
+
* Unlike pendingSessions this survives materialization — the hub discovery
|
|
79
|
+
* payload needs a workspace label for live sessions, whose pending entries
|
|
80
|
+
* are deleted on first use.
|
|
81
|
+
*/
|
|
82
|
+
readonly sessionCwds: Map<string, string>;
|
|
75
83
|
/** Currently running turns, keyed by the ACP request id. */
|
|
76
84
|
readonly pendingTurns: Map<number, PendingTurn>;
|
|
77
85
|
/**
|
|
@@ -80,16 +88,27 @@ export declare class ZcodeAcpServer {
|
|
|
80
88
|
* concurrent prompts from both missing each other and registering at once.
|
|
81
89
|
*/
|
|
82
90
|
readonly preemptLocks: Map<string, Promise<void>>;
|
|
83
|
-
/** Capabilities advertised by
|
|
91
|
+
/** Capabilities advertised by connected clients (Zed, JetBrains, remote). */
|
|
84
92
|
clientCapabilities: ClientCapabilities;
|
|
85
93
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
94
|
+
* All connected ACP clients (the stdio editor plus any remote WebSocket
|
|
95
|
+
* clients). Handlers push notifications through `clients.broadcast()` so
|
|
96
|
+
* every attached client sees the same stream; the registry replaces the old
|
|
97
|
+
* single `acpClient` reference. Background listeners use it to push
|
|
98
|
+
* `session/update` notifications outside request handlers.
|
|
91
99
|
*/
|
|
92
|
-
|
|
100
|
+
readonly clients: ClientRegistry;
|
|
101
|
+
/**
|
|
102
|
+
* Lightweight session summaries for the remote hub's discovery API
|
|
103
|
+
* (acp_sid → { title, updatedAt }). In-memory only — the hub holds no
|
|
104
|
+
* business state and the bridge dies with its editor, so persistence would
|
|
105
|
+
* buy nothing. Maintained by `touchSessionSummary` at session registration,
|
|
106
|
+
* title set, and turn completion.
|
|
107
|
+
*/
|
|
108
|
+
readonly sessionSummaries: Map<string, {
|
|
109
|
+
title?: string;
|
|
110
|
+
updatedAt: number;
|
|
111
|
+
}>;
|
|
93
112
|
/** Session titles already set, to enforce set-once (acp_sid → title). */
|
|
94
113
|
readonly sessionTitles: Map<string, string>;
|
|
95
114
|
/**
|
|
@@ -143,6 +162,13 @@ export declare class ZcodeAcpServer {
|
|
|
143
162
|
* background-task listener needs the reverse lookup to address notifications).
|
|
144
163
|
*/
|
|
145
164
|
registerSession(acpSid: string, zcodeSid: string): void;
|
|
165
|
+
/** Update a session's discovery summary (title sticky once set). */
|
|
166
|
+
touchSessionSummary(acpSid: string, title?: string): void;
|
|
167
|
+
/**
|
|
168
|
+
* Best-effort workspace label for the hub discovery payload: first known
|
|
169
|
+
* session cwd, else the bridge process cwd.
|
|
170
|
+
*/
|
|
171
|
+
workspaceLabel(): string;
|
|
146
172
|
/**
|
|
147
173
|
* Ensure a background-task listener is registered for the session. Idempotent
|
|
148
174
|
* — returns the existing listener if already registered (covers resume/load
|
|
@@ -171,6 +197,14 @@ export declare class ZcodeAcpServer {
|
|
|
171
197
|
* `session/request_permission`.
|
|
172
198
|
*/
|
|
173
199
|
supportsElicitationForm(): boolean;
|
|
200
|
+
/**
|
|
201
|
+
* OR-merge capabilities from a newly connected client. Each connection runs
|
|
202
|
+
* its own `initialize`; boolean capabilities are unioned across clients so a
|
|
203
|
+
* feature advertised by ANY attached client (Zed or a remote one) enables the
|
|
204
|
+
* richer interaction path, and `_meta` flags (e.g. terminal_output) merge
|
|
205
|
+
* shallowly. Idempotent for re-connecting clients with equal capabilities.
|
|
206
|
+
*/
|
|
207
|
+
mergeClientCapabilities(caps: ClientCapabilities): void;
|
|
174
208
|
/** Handle `initialize`: negotiate version + declare agent capabilities. */
|
|
175
209
|
initialize(params: acp.InitializeRequest): Promise<acp.InitializeResponse>;
|
|
176
210
|
}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAErD,OAAO,EAIL,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { loadZcodeCredentials, mergeEnvWithCreds, resolveZcodeCommand, ZcodeBackend, } from "./backend/index.js";
|
|
10
10
|
import { BackgroundTaskListener } from "./handlers/background-tasks.js";
|
|
11
|
+
import { enqueueSessionSend } from "./handlers/io.js";
|
|
12
|
+
import { ClientRegistry } from "./remote/broadcast.js";
|
|
11
13
|
import { AGENT_INFO, PROTOCOL_VERSION, log } from "./utils.js";
|
|
12
14
|
export class ZcodeAcpServer {
|
|
13
15
|
/** The ZCode subprocess client (lazy — spawned on first use). */
|
|
@@ -35,6 +37,13 @@ export class ZcodeAcpServer {
|
|
|
35
37
|
* share one `session/create` instead of creating two backend sessions.
|
|
36
38
|
*/
|
|
37
39
|
pendingSessions = new Map();
|
|
40
|
+
/**
|
|
41
|
+
* Session cwds (acp_sid → cwd), recorded at session/new and lazy-recovery.
|
|
42
|
+
* Unlike pendingSessions this survives materialization — the hub discovery
|
|
43
|
+
* payload needs a workspace label for live sessions, whose pending entries
|
|
44
|
+
* are deleted on first use.
|
|
45
|
+
*/
|
|
46
|
+
sessionCwds = new Map();
|
|
38
47
|
/** Currently running turns, keyed by the ACP request id. */
|
|
39
48
|
pendingTurns = new Map();
|
|
40
49
|
/**
|
|
@@ -43,16 +52,24 @@ export class ZcodeAcpServer {
|
|
|
43
52
|
* concurrent prompts from both missing each other and registering at once.
|
|
44
53
|
*/
|
|
45
54
|
preemptLocks = new Map();
|
|
46
|
-
/** Capabilities advertised by
|
|
55
|
+
/** Capabilities advertised by connected clients (Zed, JetBrains, remote). */
|
|
47
56
|
clientCapabilities = {};
|
|
48
57
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
58
|
+
* All connected ACP clients (the stdio editor plus any remote WebSocket
|
|
59
|
+
* clients). Handlers push notifications through `clients.broadcast()` so
|
|
60
|
+
* every attached client sees the same stream; the registry replaces the old
|
|
61
|
+
* single `acpClient` reference. Background listeners use it to push
|
|
62
|
+
* `session/update` notifications outside request handlers.
|
|
63
|
+
*/
|
|
64
|
+
clients = new ClientRegistry();
|
|
65
|
+
/**
|
|
66
|
+
* Lightweight session summaries for the remote hub's discovery API
|
|
67
|
+
* (acp_sid → { title, updatedAt }). In-memory only — the hub holds no
|
|
68
|
+
* business state and the bridge dies with its editor, so persistence would
|
|
69
|
+
* buy nothing. Maintained by `touchSessionSummary` at session registration,
|
|
70
|
+
* title set, and turn completion.
|
|
54
71
|
*/
|
|
55
|
-
|
|
72
|
+
sessionSummaries = new Map();
|
|
56
73
|
/** Session titles already set, to enforce set-once (acp_sid → title). */
|
|
57
74
|
sessionTitles = new Map();
|
|
58
75
|
/**
|
|
@@ -119,6 +136,22 @@ export class ZcodeAcpServer {
|
|
|
119
136
|
registerSession(acpSid, zcodeSid) {
|
|
120
137
|
this.sessionMap.set(acpSid, zcodeSid);
|
|
121
138
|
this.acpSidByZcodeSid.set(zcodeSid, acpSid);
|
|
139
|
+
this.touchSessionSummary(acpSid);
|
|
140
|
+
}
|
|
141
|
+
/** Update a session's discovery summary (title sticky once set). */
|
|
142
|
+
touchSessionSummary(acpSid, title) {
|
|
143
|
+
const existing = this.sessionSummaries.get(acpSid);
|
|
144
|
+
this.sessionSummaries.set(acpSid, {
|
|
145
|
+
title: title ?? existing?.title,
|
|
146
|
+
updatedAt: Date.now(),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Best-effort workspace label for the hub discovery payload: first known
|
|
151
|
+
* session cwd, else the bridge process cwd.
|
|
152
|
+
*/
|
|
153
|
+
workspaceLabel() {
|
|
154
|
+
return this.sessionCwds.values().next().value ?? process.cwd();
|
|
122
155
|
}
|
|
123
156
|
/**
|
|
124
157
|
* Ensure a background-task listener is registered for the session. Idempotent
|
|
@@ -151,14 +184,16 @@ export class ZcodeAcpServer {
|
|
|
151
184
|
* the bridge on a notification failure.
|
|
152
185
|
*/
|
|
153
186
|
async notifyByZcodeSid(zcodeSid, update) {
|
|
154
|
-
|
|
155
|
-
if (!cx)
|
|
187
|
+
if (this.clients.size === 0)
|
|
156
188
|
return false;
|
|
157
189
|
const acpSid = this.resolveAcpSid(zcodeSid);
|
|
158
190
|
if (!acpSid)
|
|
159
191
|
return false;
|
|
160
192
|
try {
|
|
161
|
-
|
|
193
|
+
// Broadcast notify swallows per-client failures internally (warn only).
|
|
194
|
+
// Serialized through the replay guard so a background emission queues
|
|
195
|
+
// behind an in-flight replay batch for the same session.
|
|
196
|
+
await enqueueSessionSend(acpSid, () => this.clients.broadcast().notify("session/update", { sessionId: acpSid, update }));
|
|
162
197
|
return true;
|
|
163
198
|
}
|
|
164
199
|
catch (e) {
|
|
@@ -180,10 +215,33 @@ export class ZcodeAcpServer {
|
|
|
180
215
|
supportsElicitationForm() {
|
|
181
216
|
return this.clientCapabilities.elicitation?.form != null;
|
|
182
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* OR-merge capabilities from a newly connected client. Each connection runs
|
|
220
|
+
* its own `initialize`; boolean capabilities are unioned across clients so a
|
|
221
|
+
* feature advertised by ANY attached client (Zed or a remote one) enables the
|
|
222
|
+
* richer interaction path, and `_meta` flags (e.g. terminal_output) merge
|
|
223
|
+
* shallowly. Idempotent for re-connecting clients with equal capabilities.
|
|
224
|
+
*/
|
|
225
|
+
mergeClientCapabilities(caps) {
|
|
226
|
+
const cur = this.clientCapabilities;
|
|
227
|
+
const next = { ...cur, ...caps };
|
|
228
|
+
next.fs = {
|
|
229
|
+
readTextFile: cur.fs?.readTextFile || caps.fs?.readTextFile,
|
|
230
|
+
writeTextFile: cur.fs?.writeTextFile || caps.fs?.writeTextFile,
|
|
231
|
+
};
|
|
232
|
+
next.terminal = cur.terminal || caps.terminal;
|
|
233
|
+
next.elicitation = {
|
|
234
|
+
form: cur.elicitation?.form || caps.elicitation?.form,
|
|
235
|
+
url: cur.elicitation?.url || caps.elicitation?.url,
|
|
236
|
+
};
|
|
237
|
+
if (cur._meta || caps._meta)
|
|
238
|
+
next._meta = { ...cur._meta, ...caps._meta };
|
|
239
|
+
this.clientCapabilities = next;
|
|
240
|
+
}
|
|
183
241
|
/** Handle `initialize`: negotiate version + declare agent capabilities. */
|
|
184
242
|
async initialize(params) {
|
|
185
243
|
const clientInfo = params.clientInfo ?? null;
|
|
186
|
-
this.
|
|
244
|
+
this.mergeClientCapabilities(params.clientCapabilities ?? {});
|
|
187
245
|
log(`initialize: client protocolVersion=${params.protocolVersion}` +
|
|
188
246
|
`, client=${clientInfo?.name ?? "unknown"}` +
|
|
189
247
|
`, version=${clientInfo?.version ?? "unknown"}` +
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AA0B/D,MAAM,OAAO,cAAc;IACzB,iEAAiE;IACjE,OAAO,GAAwB,IAAI,CAAC;IACpC,4EAA4E;IACnE,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD;;;;;;OAMG;IACM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtD;;;;;;;;;;;OAWG;IACM,eAAe,GAAG,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const PROTOCOL_VERSION = 1;
|
|
|
9
9
|
export declare const AGENT_INFO: {
|
|
10
10
|
readonly name: "zcode-acp-server";
|
|
11
11
|
readonly title: "ZCode";
|
|
12
|
-
readonly version:
|
|
12
|
+
readonly version: string;
|
|
13
13
|
};
|
|
14
14
|
/** Path to the ZCode v2 config (credentials + provider/model metadata). */
|
|
15
15
|
export declare const ZCODE_CREDS_PATH: string;
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAmBlC,4DAA4D;AAC5D,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,QAK5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCjB,CAAC;AAEX,0EAA0E;AAC1E,eAAO,MAAM,WAAW;;;;0BAIL,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0B/C,CAAC;AAEX,iGAAiG;AACjG,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAGhF,CAAC;AAoBF,qEAAqE;AACrE,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGrC;AAED,0DAA0D;AAC1D,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAmB5D"}
|