zcode-acp-server 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +16 -4
  2. package/dist/backend/types.d.ts +17 -0
  3. package/dist/backend/types.d.ts.map +1 -1
  4. package/dist/handlers/io.d.ts +13 -0
  5. package/dist/handlers/io.d.ts.map +1 -1
  6. package/dist/handlers/io.js +36 -0
  7. package/dist/handlers/io.js.map +1 -1
  8. package/dist/handlers/replay.d.ts.map +1 -1
  9. package/dist/handlers/replay.js +131 -20
  10. package/dist/handlers/replay.js.map +1 -1
  11. package/dist/handlers/session.d.ts.map +1 -1
  12. package/dist/handlers/session.js +5 -0
  13. package/dist/handlers/session.js.map +1 -1
  14. package/dist/index.js +8 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/remote/broadcast.d.ts +11 -0
  17. package/dist/remote/broadcast.d.ts.map +1 -1
  18. package/dist/remote/broadcast.js +21 -0
  19. package/dist/remote/broadcast.js.map +1 -1
  20. package/dist/remote/endpoint.d.ts +32 -11
  21. package/dist/remote/endpoint.d.ts.map +1 -1
  22. package/dist/remote/endpoint.js +109 -28
  23. package/dist/remote/endpoint.js.map +1 -1
  24. package/dist/remote/file-endpoint.d.ts +23 -0
  25. package/dist/remote/file-endpoint.d.ts.map +1 -0
  26. package/dist/remote/file-endpoint.js +348 -0
  27. package/dist/remote/file-endpoint.js.map +1 -0
  28. package/dist/remote/hub-server.d.ts.map +1 -1
  29. package/dist/remote/hub-server.js +55 -2
  30. package/dist/remote/hub-server.js.map +1 -1
  31. package/dist/server.d.ts +7 -9
  32. package/dist/server.d.ts.map +1 -1
  33. package/dist/server.js +13 -11
  34. package/dist/server.js.map +1 -1
  35. package/docs/ARCHITECTURE.md +12 -6
  36. package/docs/REMOTE-CLIENTS.md +65 -14
  37. package/docs/REPLAY-GUIDE.md +45 -15
  38. package/docs/adr/0004-session-scoped-readonly-file-access.md +39 -0
  39. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -64,16 +64,13 @@ export class ZcodeAcpServer {
64
64
  clients = new ClientRegistry();
65
65
  /**
66
66
  * Lightweight session summaries for the remote hub's discovery API
67
- * (acp_sid → { title, updatedAt, hasActivity, unavailable }). In-memory only
68
- * — the hub holds no business state and the bridge dies with its editor, so
67
+ * (acp_sid → { title, updatedAt, hasActivity }). In-memory only — the hub
68
+ * holds no business state and the bridge dies with its editor, so
69
69
  * persistence would buy nothing. Maintained by `touchSessionSummary` at
70
70
  * session registration, title set, and turn completion. `hasActivity` gates
71
71
  * the discovery payload: an editor restart auto-resumes its stored
72
72
  * placeholder, materializing an empty backend session — never-used sessions
73
- * stay invisible to remote clients until first real use. `unavailable` is
74
- * set by the heartbeat's availability probe (session-liveness.ts) when this
75
- * backend can no longer serve the session (e.g. a restarted project took it
76
- * over via a new bridge) and clears when it answers messages again.
73
+ * stay invisible to remote clients until first real use.
77
74
  */
78
75
  sessionSummaries = new Map();
79
76
  /** Session titles already set, to enforce set-once (acp_sid → title). */
@@ -164,8 +161,6 @@ export class ZcodeAcpServer {
164
161
  // A title only exists once the session produced content (auto-title on
165
162
  // first end_turn, or a stored title adopted on resume/load).
166
163
  hasActivity: existing?.hasActivity || title !== undefined,
167
- // Keep the heartbeat-liveness verdict across mapping/title touches.
168
- unavailable: existing?.unavailable,
169
164
  });
170
165
  }
171
166
  /**
@@ -182,12 +177,16 @@ export class ZcodeAcpServer {
182
177
  });
183
178
  }
184
179
  /**
185
- * Best-effort workspace label for the hub discovery payload: first known
186
- * session cwd, else the bridge process cwd.
180
+ * The bridge's project directory: first known session cwd, else the bridge
181
+ * process cwd (Zed spawns the server with the worktree root as cwd).
187
182
  */
188
- workspaceLabel() {
183
+ projectCwd() {
189
184
  return this.sessionCwds.values().next().value ?? process.cwd();
190
185
  }
186
+ /** Best-effort workspace label for the hub discovery payload. */
187
+ workspaceLabel() {
188
+ return this.projectCwd();
189
+ }
191
190
  /**
192
191
  * Ensure a background-task listener is registered for the session. Idempotent
193
192
  * — returns the existing listener if already registered (covers resume/load
@@ -289,6 +288,9 @@ export class ZcodeAcpServer {
289
288
  promptCapabilities: { image: true, audio: false, embeddedContext: false },
290
289
  mcpCapabilities: { http: false, sse: false },
291
290
  sessionCapabilities: { list: {}, resume: {}, fork: {} },
291
+ // Read-only session file access lives on the bridge's loopback /fs
292
+ // endpoint, hub-proxied at /api/instances/{id}/fs/* (ADR-0004).
293
+ _meta: { zcode: { fs: true } },
292
294
  },
293
295
  // The GLM API key is read from ~/.zcode/v2/config.json by the ZCode
294
296
  // backend subprocess; the editor never needs to supply credentials.
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -197,12 +197,13 @@ API only because the ZCode backend itself sends them for inference.
197
197
 
198
198
  ### `remote/` — Remote access (opt-in via `ZCODE_ACP_REMOTE=1`)
199
199
 
200
- | File | Responsibility |
201
- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
202
- | `broadcast.ts` | ClientRegistry + broadcast proxy: notify fans out to all clients; request is first-response-wins with loser `$/cancel_request` |
203
- | `config.ts` | ENV parsing (gate, mandatory token, hub/bridge ports) |
204
- | `endpoint.ts` | Loopback ACP endpoint (SDK AcpServer transport, port auto-increment) + hub registration/heartbeat |
205
- | `hub-server.ts` | The hub singleton: token auth, instance discovery, byte-level WS proxying, heartbeat pruning, on-demand `?probe=1` liveness, idle exit, version self-upgrade |
200
+ | File | Responsibility |
201
+ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
202
+ | `broadcast.ts` | ClientRegistry + broadcast proxy: notify fans out to all clients; request is first-response-wins with loser `$/cancel_request` |
203
+ | `config.ts` | ENV parsing (gate, mandatory token, hub/bridge ports) |
204
+ | `endpoint.ts` | Loopback ACP endpoint (SDK AcpServer transport, port auto-increment) + hub registration/heartbeat |
205
+ | `file-endpoint.ts` | Read-only `GET /fs/list` + `GET /fs/file` on the loopback server (ADR-0004): Session Root scoping, byte/line windows, streaming |
206
+ | `hub-server.ts` | The hub singleton: token auth, instance discovery, byte-level WS proxying, heartbeat pruning, on-demand `?probe=1` liveness, idle exit, version self-upgrade |
206
207
 
207
208
  When enabled, the same `AgentApp` serves the stdio editor and a loopback
208
209
  WebSocket endpoint. Every connection (editor or remote) joins the broadcast
@@ -226,6 +227,11 @@ drops bridges that stopped registering — the fallback for hard kills — and
226
227
  on demand, so a client refresh gets an immediately-honest list with no
227
228
  background probing cost.
228
229
 
230
+ Session file access (ADR-0004) rides the same loopback server: the bridge
231
+ serves read-only `GET /fs/list` + `GET /fs/file` scoped to each session's cwd,
232
+ and the hub byte-proxies them at `/api/instances/{id}/fs/*` — no new port, and
233
+ the hub still holds no path semantics.
234
+
229
235
  ## Key State Machines
230
236
 
231
237
  ### Turn state
@@ -74,20 +74,34 @@ HTTP auth: `Authorization: Bearer <token>` or `?token=<token>`.
74
74
  registered bridge's loopback port and prunes unreachable ones before
75
75
  answering. A plain `GET` returns the heartbeat-based view, which can list a
76
76
  hard-killed bridge for up to the 30s heartbeat TTL.
77
- - `sessions[].sessionId` is the ACP session id: pass it to `session/load`
78
- after connecting. `title` is adopted from the backend for resumed sessions
79
- and set after a fresh session's first turn it can still be absent for a
80
- session that has never completed a turn.
81
- - `sessions` only lists sessions with real interaction. Editors restart into a
82
- stored placeholder and materialize an empty backend session those stay
83
- hidden and appear within one heartbeat (~10s) after their first prompt (or
84
- a titled resume/load).
85
- - `sessions` is also **availability-verified**: before every heartbeat the
86
- bridge probes its idle sessions against its own backend, and a session it
87
- can no longer serve (e.g. the project restarted under a newer bridge while
88
- the old process leaked) is dropped from the list within one heartbeat
89
- (~10s) instead of lingering as an entry that opens empty. It reappears if
90
- the bridge can serve it again. Treat list membership as "openable".
77
+ - `sessions[].sessionId` is the **ACP session id the editor uses** for that
78
+ conversation (placeholder ids are stable across bridges Zed stores them
79
+ and the durable alias store records them). Attaching under it via
80
+ `session/load` puts the remote client on the same notification stream as
81
+ the editor tab: turns driven from either side stream live to both. A
82
+ conversation with no editor placeholder is advertised under its backend
83
+ id (`sess_…`), still loadable via pass-through resume. `title` comes from
84
+ the backend session store; sessions that never completed a turn have no
85
+ title and are not listed.
86
+ - **Prompt echo**: when any client sends `session/prompt`, the bridge
87
+ broadcasts the user's text to every OTHER attached client as a
88
+ `user_message_chunk` (messageId prefixed `uprompt_`). Your own prompts are
89
+ never echoed back to you render them locally as you send them. Without
90
+ this rule a turn driven from the other side arrives without the user
91
+ message that started it.
92
+ - `sessions` is gated on two rules: the conversation must be **currently
93
+ running** (a live registration in the advertising bridge — an open editor
94
+ tab, or a remote attachment that ran a turn) and **accessible** (every
95
+ listed id resolves and resumes through that bridge). Retired conversations
96
+ of the project are NOT listed even though the backend store still has them
97
+ — the store only enriches live entries with the authoritative title and a
98
+ cross-bridge `updatedAt`.
99
+ - Entries are **deduped across instances**: several bridges of the same
100
+ project (e.g. a leaked old process plus the current one) can all hold the
101
+ same live conversation under the same id; the hub keeps one copy per
102
+ session — the instance whose copy has the freshest `updatedAt` (i.e. the
103
+ bridge actually driving it). Attach to whichever instance the entry
104
+ appears under.
91
105
  - Poll every 3–5s. There is no push notification for registry changes yet.
92
106
  - Fields are **additive-only** across releases — ignore fields you don't know.
93
107
 
@@ -181,6 +195,43 @@ exactly:
181
195
  later. Only transport-level failures reject the request.
182
196
  - Cached ~10s server-side (same caches as the `/quota` command).
183
197
 
198
+ ## Session files (read-only)
199
+
200
+ Browse and download files of a session's project — served by the bridge,
201
+ byte-proxied by the hub, guarded by the same token as everything else
202
+ (ADR-0004). Capability probe: `initialize` returns
203
+ `agentCapabilities._meta.zcode.fs === true`.
204
+
205
+ ```text
206
+ GET {hub}/api/instances/{id}/fs/list?sessionId=…&path=<rel> one directory level
207
+ GET {hub}/api/instances/{id}/fs/file?sessionId=…&path=<rel> file bytes
208
+ &offset=…&length=… byte window → 206 + Content-Range
209
+ &line=…&limit=… text window (defaults 1 / 200, cap 5000)
210
+ ```
211
+
212
+ - `path` resolves against the session's root cwd — the directory the session
213
+ was created or loaded with. Absolute paths work only when they land inside
214
+ it; `..` segments and symlinks pointing outside the root are rejected
215
+ (403).
216
+ - `list` returns `{ root, entries: [{name, kind: "file"|"dir"|"symlink",
217
+ size, mtime}], truncated }`. Dotfiles are included — filter client-side.
218
+ Entries sort dirs-first in byte order; `truncated: true` marks more than
219
+ 2000 entries. Symlinks report placeholder stats (`size: 0`); reading
220
+ through one resolves and scope-checks the target.
221
+ - `file` streams with `Content-Length` and a Content-Type inferred from the
222
+ extension (`application/octet-stream` fallback) — `<a download>`,
223
+ `<img src>`, and `fetch` streaming all work directly. `HEAD` is supported.
224
+ - Byte and line windows are mutually exclusive (400). A line window returns
225
+ `text/plain` with `X-Zcode-First-Line` set to the first served line;
226
+ memory is O(limit), so it works on arbitrarily large logs.
227
+ - Errors: `400` bad params · `403` unknown session / path escapes the root ·
228
+ `404` not found / unknown instance · `416` offset beyond EOF · `502`
229
+ bridge port unreachable. A `404` right after a bridge upgrade is the hub
230
+ self-upgrading to learn the route — retry.
231
+ - Read-only by design, and the token remains the security boundary as
232
+ everywhere else; the session root contains accidents (wrong path joins),
233
+ not attackers.
234
+
184
235
  ## Slash-command handling
185
236
 
186
237
  Only the commands the bridge advertises via `available_commands_update` (plus
@@ -72,31 +72,61 @@ differently:
72
72
  - `usage_update` / `available_commands_update` are session-level metadata,
73
73
  not list items.
74
74
 
75
- ### Collapsed harness blocks (`_meta.zcode.collapsed`)
75
+ ### Collapsed harness blocks (tool_call form)
76
76
 
77
- Replayed user messages that are harness plumbing rather than user speech may
78
- carry a top-level `_meta` on the `session/update` notification:
77
+ Replayed user messages that are harness plumbing rather than user speech are
78
+ delivered as **`tool_call` updates, not `user_message_chunk`** — tool_call is
79
+ the one update kind every ACP editor (Zed, JetBrains, …) renders folded by
80
+ default, so the collapse works with zero client-side opt-in. The full text
81
+ rides in the tool_call's `content` block (expandable); the `kind` rides the
82
+ update's `_meta`:
79
83
 
80
84
  ```json
81
85
  {
82
86
  "sessionId": "…",
83
87
  "update": {
84
- "sessionUpdate": "user_message_chunk",
85
- "content": { "type": "text", "text": "This session is being continued …" },
86
- "messageId": ""
87
- },
88
- "_meta": { "zcode": { "collapsed": true, "kind": "context-handoff" } }
88
+ "sessionUpdate": "tool_call",
89
+ "toolCallId": "histfold_…",
90
+ "title": "Context handoff",
91
+ "kind": "other",
92
+ "status": "completed",
93
+ "content": [
94
+ {
95
+ "type": "content",
96
+ "content": { "type": "text", "text": "This session is being continued …" }
97
+ }
98
+ ],
99
+ "_meta": { "zcode": { "collapsed": true, "kind": "context-handoff" } }
100
+ }
89
101
  }
90
102
  ```
91
103
 
92
- - `kind: "context-handoff"` — the context-window continuation summary. The
93
- full text is in the chunk as usual; render it **collapsed behind an expand
94
- control** (e.g. a one-line label like "前序会话摘要") instead of a wall of
95
- text attributed to the user.
104
+ - `kind: "context-handoff"` — the context-window continuation summary, one
105
+ per compaction (a long session can carry dozens). Title: `Context handoff`.
106
+ - `kind: "compact"` the same compaction product on backends that tag it
107
+ with `semantics.kind: "compact_summary"` (session/compact, auto-compact,
108
+ and context-window handoff all land here). Title comes from the store's
109
+ own `summary.title` (observed: `Compact summary`) — so a reload shows
110
+ where history was compacted instead of silently missing the bridge's live
111
+ 🔄/✓ auto-compact notices, which never enter backend history.
112
+ - `kind: "tool-transcript"` — `Called the X tool with the following input:
113
+ {…}\nResult of calling…` messages: tool_use/tool_result pairs the harness
114
+ rewrites into text on resume, one per historical tool call. Title is
115
+ `X · <first string value of the input JSON>` (e.g.
116
+ `Read · /src/main.go`), capped at 60 characters; falls back to `X tool`.
117
+ - `kind: "task-notification"` — `<task-notification>` blocks the harness
118
+ injects when a background task (build, sub-agent) finishes, delivered as
119
+ standalone user messages. Title is the block's decoded `<summary>` line
120
+ (e.g. `Background command "Build release APK" completed (exit code 0)`),
121
+ capped at 60 characters; falls back to `Background task`.
96
122
  - Harness noise that carries no value (TodoWrite/Read usage nudges) is
97
- stripped before replay — you never see it.
98
- - Unknown `kind`s: render collapsed too (or fall back to plain text). Ignoring
99
- `_meta` entirely is always safe the text is complete without it.
123
+ stripped before replay — you never see it. Synthetic messages the backend
124
+ marks `transcriptVisibility: "hidden"` and that fit no collapse shape
125
+ (plan-file references and similar plumbing) are dropped entirely.
126
+ - Render all kinds as an ordinary collapsed tool card keyed by `toolCallId`;
127
+ the text is complete behind the expand. Unknown `kind`s: render collapsed
128
+ too. These updates never collide with live tool_call ids (they carry the
129
+ `histfold_` prefix).
100
130
 
101
131
  ## Turn running state (`replayMeta.turnActive` + `$/zcode/turnState`)
102
132
 
@@ -0,0 +1,39 @@
1
+ # Remote file access: session-scoped, read-only, over hub-proxied HTTP
2
+
3
+ Remote clients could see session diffs and tool-call text but had no way to
4
+ browse or download files of the project a session lives in. We decided to give
5
+ the bridge a read-only file endpoint on its existing loopback HTTP server
6
+ (`GET /fs/list`, `GET /fs/file`), proxied byte-for-byte by the hub at
7
+ `GET /api/instances/{id}/fs/*` — the same proxy pattern as `/acp`. The hub
8
+ still touches no filesystem and understands no path semantics (ADR-0002
9
+ holds); scope checks and reads happen in the bridge, against its own
10
+ `sessionCwds` map: a request names a `sessionId`, and the path (after
11
+ `path.resolve` + `realpath`, defeating `..` and symlink escapes) must stay
12
+ inside that session's root cwd. Newly created sessions are readable
13
+ immediately because the bridge consults the in-process map, not a heartbeat
14
+ replica.
15
+
16
+ Read-only is deliberate: token holders can already drive the agent to write
17
+ files through the permission flow, but a direct write path would widen
18
+ token-theft damage from "control sessions" to "arbitrary filesystem writes",
19
+ with no consistency protection against running turns. The loopback endpoint
20
+ itself is unauthenticated, exactly like the ACP WebSocket next to it — only
21
+ the hub (the sole public entry) enforces the token. Responses stream
22
+ (`createReadStream` + `Content-Length`), so there is no per-request size cap;
23
+ `offset`/`length` and `line`/`limit` (mutually exclusive) serve binary
24
+ chunking and text windowing. `agentCapabilities._meta.zcode.fs` advertises the
25
+ capability to clients.
26
+
27
+ We rejected three alternatives. ACP extension methods (`_zcode/fs/*`) with
28
+ base64 bodies: the SDK's WS server drops non-text frames, so a binary channel
29
+ means bypassing the SDK transport; base64 adds 33%; and — decisively — a
30
+ multi-MB response blocks every `session/update` behind it on the same
31
+ WebSocket (head-of-line blocking), while HTTP gives downloads, `<img src>`,
32
+ caching, and future `Range` support for free. The hub reading files itself:
33
+ security-wise equivalent (the token already grants full session control), but
34
+ the hub's registry only knows activity-gated sessions, so a fresh
35
+ `session/new` session would have no cwd until its first turn — fixing that
36
+ would turn the heartbeat payload from a display summary into an authoritative
37
+ session→directory map, a second implementation of the session semantics
38
+ ADR-0002 keeps out of the hub. External tools (filebrowser, `rclone serve`):
39
+ separate token, port, and lifetime, with no link to sessions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcode-acp-server",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "description": "Agent Client Protocol (ACP) server bridging headless ZCode to editors like Zed and JetBrains.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",