zcode-acp-server 0.11.5 → 0.11.9

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.
@@ -52,7 +52,9 @@ ACP editor ────── stdio ──────────┘
52
52
  | `GET /api/instances` | required | Registered bridge instances. Add `?probe=1` to verify first. |
53
53
  | `GET /api/instances/{id}/status` | required | Real-time per-session running status of one bridge. |
54
54
  | `POST /api/instances/{id}/sessions/{sessionId}/close` | required | Retire a session from remote discovery — see [Closing a session](#closing-a-session). |
55
+ | `POST /api/instances/{id}/sessions/{sessionId}/rename` | required | Rename a session — see [Renaming a session](#renaming-a-session). |
55
56
  | `GET /api/quota` | required | Account-level usage stats — same payload as `account/usage_stats`, no ACP connection needed. |
57
+ | `POST /api/upgrade` | required | Trigger the hub's own staleness check — see [Hub self-upgrade](#hub-self-upgrade). |
56
58
 
57
59
  HTTP auth: `Authorization: Bearer <token>` or `?token=<token>`.
58
60
 
@@ -90,9 +92,12 @@ HTTP auth: `Authorization: Bearer <token>` or `?token=<token>`.
90
92
  `session/load` puts the remote client on the same notification stream as
91
93
  the editor tab: turns driven from either side stream live to both. A
92
94
  conversation with no editor placeholder is advertised under its backend
93
- id (`sess_…`), still loadable via pass-through resume. `title` comes from
94
- the backend session store once the backend has titled it; sessions whose
95
- first turn is still running carry the provisional prompt-derived title.
95
+ id (`sess_…`), still loadable via `session/load` pass-through resume. The
96
+ title is set exactly once by the bridge from the first line of the first
97
+ prompt (capped at 80 chars), the moment that prompt is sent — and never
98
+ changes automatically afterwards; a manual rename is the only later
99
+ modifier. Sessions born in a previous bridge lifetime get their title from
100
+ the session store on load/resume.
96
101
  - `sessions[].status` is a coarse `"running" | "idle"` indicator riding the
97
102
  heartbeat (up to ~10s stale; absent on older bridges — treat as unknown).
98
103
  For the live value poll [`/api/instances/{id}/status`](#session-running-status).
@@ -109,9 +114,9 @@ HTTP auth: `Authorization: Bearer <token>` or `?token=<token>`.
109
114
  **accessible** (every listed id resolves and resumes through that bridge).
110
115
  Retired conversations of the project are NOT listed even though the
111
116
  backend store still has them — the store only enriches live entries with
112
- the authoritative title and a cross-bridge `updatedAt`. Entries may carry
113
- a provisional title (first line of the first prompt, capped at 60 chars)
114
- until the backend's own auto-title lands.
117
+ the stored title and a cross-bridge `updatedAt`. The auto-title is set once
118
+ at the first prompt (first non-empty line, capped at 80 chars) and is never
119
+ revised by later turns.
115
120
  - Entries are **deduped across instances**: several bridges of the same
116
121
  project (e.g. a leaked old process plus the current one) can all hold the
117
122
  same live conversation under the same id; the hub keeps one copy per
@@ -291,6 +296,58 @@ Cross-instance note: if the same conversation is also registered by another
291
296
  bridge of the project, the hub's dedupe re-attaches it under that instance —
292
297
  close it there too.
293
298
 
299
+ ## Renaming a session
300
+
301
+ ```text
302
+ POST {hub}/api/instances/{id}/sessions/{sessionId}/rename
303
+ body: { "title": "new name" } → 200 { "ok": true, "title": "…" }
304
+ ```
305
+
306
+ The session title is set **once**, automatically, from the first prompt of a
307
+ freshly created session (first non-empty line, capped at 80 chars) — this
308
+ endpoint is the only later modifier. ACP has no client→agent rename channel,
309
+ and an editor-side rename lives in the editor's own storage forever, so the
310
+ remote side is where a rename enters the system.
311
+
312
+ The bridge applies the rename everywhere: its in-memory title pin (no later
313
+ automatic write can touch it), the discovery summary (live within one
314
+ heartbeat), the ZCode App's tasks-index (`title_overridden=1`, same marker the
315
+ App's own rename sets), and a `session_info_update` broadcast to every
316
+ attached client — the editor tab updates live. The title is normalized like
317
+ the auto-title: flattened to one line, trimmed, capped at 80 chars; an
318
+ all-whitespace title is rejected with `400`.
319
+
320
+ Errors: `400` missing/empty title or oversized body (>4 KB), `401` bad token,
321
+ `404` unknown session (or instance), `502` bridge unreachable. Renaming during
322
+ a running turn is allowed — titles are no longer turn-coupled.
323
+
324
+ ## Hub self-upgrade
325
+
326
+ ```text
327
+ POST {hub}/api/upgrade → 200 { "ok": true, "restarting": false, "reason": "up-to-date",
328
+ "runningVersion": "0.11.6", "diskVersion": "0.11.6" }
329
+ ```
330
+
331
+ Lets a remote client pick up a hub that was rebuilt on the machine (e.g. code
332
+ edited and `pnpm build` run through a remote agent session). The client only
333
+ **triggers** the check — the restart decision is entirely the hub's own. The
334
+ hub restarts onto the on-disk code only when it judges that code NEWER than
335
+ itself, by either signal:
336
+
337
+ - the on-disk `package.json` version is newer than the version frozen into
338
+ the running process at start, **or**
339
+ - any `.js` under `dist/` has an mtime later than process start (a rebuild,
340
+ even without a version bump).
341
+
342
+ When `restarting` is `true`, the hub exits ~500ms after replying, re-spawns
343
+ itself from the on-disk dist, and bridges re-register on their next heartbeat
344
+ (≤10s). Poll `GET /api/health` until it answers again, then refresh
345
+ `/api/instances` and reconnect. A respawned hub starts after the newest dist
346
+ mtime, so the condition self-negates — no restart loops, and an OLDER on-disk
347
+ version never triggers anything.
348
+
349
+ Errors: `401` bad token. `GET` (or any other method) falls through to `404`.
350
+
294
351
  ## Session files (read-only)
295
352
 
296
353
  Browse and download files of a session's project — served by the bridge,
@@ -303,6 +360,7 @@ GET {hub}/api/instances/{id}/fs/list?sessionId=…&path=<rel> one directory l
303
360
  GET {hub}/api/instances/{id}/fs/file?sessionId=…&path=<rel> file bytes
304
361
  &offset=…&length=… byte window → 206 + Content-Range
305
362
  &line=…&limit=… text window (defaults 1 / 200, cap 5000)
363
+ &dl=1 Content-Disposition: attachment (download, not inline)
306
364
  ```
307
365
 
308
366
  - `path` resolves against the session's root cwd — the directory the session
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcode-acp-server",
3
- "version": "0.11.5",
3
+ "version": "0.11.9",
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",