zcode-acp-server 0.11.8 → 0.14.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/README.md +144 -32
- package/dist/backend/client.d.ts.map +1 -1
- package/dist/backend/client.js +10 -0
- package/dist/backend/client.js.map +1 -1
- package/dist/backend/listener.d.ts.map +1 -1
- package/dist/backend/listener.js +6 -5
- package/dist/backend/listener.js.map +1 -1
- package/dist/backend/resolve.d.ts.map +1 -1
- package/dist/backend/resolve.js +35 -1
- package/dist/backend/resolve.js.map +1 -1
- package/dist/bin/hub.d.ts +3 -3
- package/dist/bin/hub.d.ts.map +1 -1
- package/dist/bin/hub.js +22 -12
- package/dist/bin/hub.js.map +1 -1
- package/dist/bin/quota.d.ts +14 -6
- package/dist/bin/quota.d.ts.map +1 -1
- package/dist/bin/quota.js +27 -19
- package/dist/bin/quota.js.map +1 -1
- package/dist/cli.d.ts +38 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +129 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/runtime-model.d.ts +10 -10
- package/dist/config/runtime-model.js +10 -10
- package/dist/handlers/account.d.ts +1 -1
- package/dist/handlers/account.js +1 -1
- package/dist/handlers/dispatch.d.ts.map +1 -1
- package/dist/handlers/dispatch.js +42 -36
- package/dist/handlers/dispatch.js.map +1 -1
- package/dist/handlers/io.d.ts.map +1 -1
- package/dist/handlers/io.js +19 -13
- package/dist/handlers/io.js.map +1 -1
- package/dist/handlers/session.d.ts +58 -4
- package/dist/handlers/session.d.ts.map +1 -1
- package/dist/handlers/session.js +317 -87
- package/dist/handlers/session.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -8
- package/dist/index.js.map +1 -1
- package/dist/interaction/adapter.d.ts +1 -0
- package/dist/interaction/adapter.d.ts.map +1 -1
- package/dist/interaction/adapter.js +5 -1
- package/dist/interaction/adapter.js.map +1 -1
- package/dist/quota/color.d.ts +4 -4
- package/dist/quota/color.d.ts.map +1 -1
- package/dist/quota/color.js +7 -5
- package/dist/quota/color.js.map +1 -1
- package/dist/quota/combined.d.ts +1 -1
- package/dist/quota/combined.js +4 -4
- package/dist/quota/combined.js.map +1 -1
- package/dist/quota/format.d.ts +1 -1
- package/dist/quota/opencode-go/format.d.ts.map +1 -1
- package/dist/quota/opencode-go/format.js +5 -1
- package/dist/quota/opencode-go/format.js.map +1 -1
- package/dist/quota/opencode-go/index.d.ts +1 -1
- package/dist/quota/opencode-go/index.js +1 -1
- package/dist/quota/opencode-go/types.d.ts +1 -1
- package/dist/quota/opencode-go/types.js +1 -1
- package/dist/quota/rounding.d.ts +8 -0
- package/dist/quota/rounding.d.ts.map +1 -0
- package/dist/quota/rounding.js +10 -0
- package/dist/quota/rounding.js.map +1 -0
- package/dist/remote/config.d.ts +1 -1
- package/dist/remote/config.d.ts.map +1 -1
- package/dist/remote/config.js +1 -1
- package/dist/remote/config.js.map +1 -1
- package/dist/remote/endpoint.d.ts +1 -1
- package/dist/remote/endpoint.d.ts.map +1 -1
- package/dist/remote/endpoint.js +6 -1
- package/dist/remote/endpoint.js.map +1 -1
- package/dist/remote/hub-server.d.ts +1 -1
- package/dist/remote/hub-server.d.ts.map +1 -1
- package/dist/remote/hub-server.js +13 -10
- package/dist/remote/hub-server.js.map +1 -1
- package/dist/remote/session-rename-endpoint.d.ts +20 -0
- package/dist/remote/session-rename-endpoint.d.ts.map +1 -0
- package/dist/remote/session-rename-endpoint.js +108 -0
- package/dist/remote/session-rename-endpoint.js.map +1 -0
- package/dist/repl/App.d.ts +108 -0
- package/dist/repl/App.d.ts.map +1 -0
- package/dist/repl/App.js +706 -0
- package/dist/repl/App.js.map +1 -0
- package/dist/repl/history.d.ts +25 -0
- package/dist/repl/history.d.ts.map +1 -0
- package/dist/repl/history.js +73 -0
- package/dist/repl/history.js.map +1 -0
- package/dist/repl/input-buffer.d.ts +77 -0
- package/dist/repl/input-buffer.d.ts.map +1 -0
- package/dist/repl/input-buffer.js +174 -0
- package/dist/repl/input-buffer.js.map +1 -0
- package/dist/repl/model.d.ts +275 -0
- package/dist/repl/model.d.ts.map +1 -0
- package/dist/repl/model.js +596 -0
- package/dist/repl/model.js.map +1 -0
- package/dist/repl/mouse.d.ts +49 -0
- package/dist/repl/mouse.d.ts.map +1 -0
- package/dist/repl/mouse.js +165 -0
- package/dist/repl/mouse.js.map +1 -0
- package/dist/repl/run.d.ts +12 -0
- package/dist/repl/run.d.ts.map +1 -0
- package/dist/repl/run.js +902 -0
- package/dist/repl/run.js.map +1 -0
- package/dist/server.d.ts +19 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +32 -4
- package/dist/server.js.map +1 -1
- package/dist/tasks-index.d.ts +7 -0
- package/dist/tasks-index.d.ts.map +1 -1
- package/dist/tasks-index.js +50 -9
- package/dist/tasks-index.js.map +1 -1
- package/dist/translators/tool-helpers.d.ts.map +1 -1
- package/dist/translators/tool-helpers.js +3 -0
- package/dist/translators/tool-helpers.js.map +1 -1
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/BACKLOG.md +40 -21
- package/docs/REMOTE-CLIENTS.md +37 -8
- package/docs/TROUBLESHOOTING.md +1 -1
- package/docs/adr/0007-unified-cli-entry-and-bin-pruning.md +40 -0
- package/package.json +9 -4
package/docs/REMOTE-CLIENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
How to attach any out-of-editor client — browser SPA, mobile app, CLI, desktop
|
|
4
4
|
tool — to bridge sessions over the network. This document IS the contract:
|
|
5
|
-
everything here is implemented by `zcode-acp
|
|
5
|
+
everything here is implemented by the hub daemon (`zcode-acp hub`) and the bridge's remote
|
|
6
6
|
endpoint; anything not written here is not part of the contract.
|
|
7
7
|
|
|
8
8
|
ACP method semantics are defined by the [ACP spec](https://agentclientprotocol.com);
|
|
@@ -52,6 +52,7 @@ 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. |
|
|
56
57
|
| `POST /api/upgrade` | required | Trigger the hub's own staleness check — see [Hub self-upgrade](#hub-self-upgrade). |
|
|
57
58
|
|
|
@@ -91,9 +92,12 @@ HTTP auth: `Authorization: Bearer <token>` or `?token=<token>`.
|
|
|
91
92
|
`session/load` puts the remote client on the same notification stream as
|
|
92
93
|
the editor tab: turns driven from either side stream live to both. A
|
|
93
94
|
conversation with no editor placeholder is advertised under its backend
|
|
94
|
-
id (`sess_…`), still loadable via pass-through resume.
|
|
95
|
-
|
|
96
|
-
|
|
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.
|
|
97
101
|
- `sessions[].status` is a coarse `"running" | "idle"` indicator riding the
|
|
98
102
|
heartbeat (up to ~10s stale; absent on older bridges — treat as unknown).
|
|
99
103
|
For the live value poll [`/api/instances/{id}/status`](#session-running-status).
|
|
@@ -110,9 +114,9 @@ HTTP auth: `Authorization: Bearer <token>` or `?token=<token>`.
|
|
|
110
114
|
**accessible** (every listed id resolves and resumes through that bridge).
|
|
111
115
|
Retired conversations of the project are NOT listed even though the
|
|
112
116
|
backend store still has them — the store only enriches live entries with
|
|
113
|
-
the
|
|
114
|
-
|
|
115
|
-
|
|
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.
|
|
116
120
|
- Entries are **deduped across instances**: several bridges of the same
|
|
117
121
|
project (e.g. a leaked old process plus the current one) can all hold the
|
|
118
122
|
same live conversation under the same id; the hub keeps one copy per
|
|
@@ -178,7 +182,7 @@ pull-only request — callable any time after `initialize`, no session required.
|
|
|
178
182
|
Fetch once after attach and on demand; quota changes are slow, there is no
|
|
179
183
|
push.
|
|
180
184
|
|
|
181
|
-
Both channels return the same payload, mirroring the `zcode-quota` CLI card's
|
|
185
|
+
Both channels return the same payload, mirroring the `zcode-acp quota` CLI card's
|
|
182
186
|
data model — one GLM section plus one Opencode Go section — so clients can
|
|
183
187
|
reproduce the CLI layout exactly:
|
|
184
188
|
|
|
@@ -292,6 +296,31 @@ Cross-instance note: if the same conversation is also registered by another
|
|
|
292
296
|
bridge of the project, the hub's dedupe re-attaches it under that instance —
|
|
293
297
|
close it there too.
|
|
294
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
|
+
|
|
295
324
|
## Hub self-upgrade
|
|
296
325
|
|
|
297
326
|
```text
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -341,7 +341,7 @@ http://127.0.0.1:<hub-port>/api/health` fails, or `/api/*` returns 401.
|
|
|
341
341
|
1. 401 means a token mismatch — `ZCODE_ACP_REMOTE_TOKEN` must be identical in
|
|
342
342
|
the bridge env, the hub env (if run manually), and the client request.
|
|
343
343
|
2. A dead hub self-heals: the next bridge heartbeat (≤10s; worst ~1min under
|
|
344
|
-
the spawn throttle) re-spawns
|
|
344
|
+
the spawn throttle) re-spawns the hub daemon. Retry with backoff rather
|
|
345
345
|
than restarting anything by hand.
|
|
346
346
|
3. Confirm the ports match: the client must reach `ZCODE_ACP_HUB_PORT`
|
|
347
347
|
(default 8377) through the tunnel, and the tunnel maps exactly that one
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Unified CLI entry and bin pruning
|
|
2
|
+
|
|
3
|
+
The package grew three separate bins (`zcode-acp-server`, `zcode-acp-hub`,
|
|
4
|
+
`zcode-quota`) plus a planned terminal chat surface. Installing four sibling
|
|
5
|
+
commands for one tool is noisy, and each new surface would add another. We
|
|
6
|
+
decided to ship one human-facing entry point — the Unified CLI, `zcode-acp` —
|
|
7
|
+
with every surface as a subcommand: `quota`, `hub`, and `server`. Bare
|
|
8
|
+
`zcode-acp` opens the interactive REPL: an Ink-rendered chat UI (the renderer
|
|
9
|
+
Claude Code and Gemini CLI use) speaking ACP to a spawned bridge over stdio,
|
|
10
|
+
with the update pump, permission picker, and turn state machine owned by this
|
|
11
|
+
package. The REPL is written in-house rather than borrowed — no embeddable
|
|
12
|
+
interactive ACP client library exists (acpx is headless-only; the interactive
|
|
13
|
+
clients Toad/Hydra/Nori are external tools or heavyweight daemons), and we
|
|
14
|
+
control both protocol ends already.
|
|
15
|
+
|
|
16
|
+
Bin declarations are pruned to `zcode-acp` and `zcode-acp-server`. The server
|
|
17
|
+
bin stays because it is the command name hardcoded in existing editor configs
|
|
18
|
+
(Zed, JetBrains) across ~2.5k monthly downloads — removing it would break every
|
|
19
|
+
current user at once; it is an editor contract, not a human alias. The
|
|
20
|
+
`zcode-acp-hub` and `zcode-quota` bins are removed in 0.12.0 with a README
|
|
21
|
+
migration note (`zcode-acp hub` / `zcode-acp quota`); the hub's own binary file
|
|
22
|
+
stays in `dist/bin/hub.js` because bridges spawn it by absolute path, not by
|
|
23
|
+
command name, so the remote feature is unaffected.
|
|
24
|
+
|
|
25
|
+
Bin-name detection is `basename(argv[1])`, which works through Unix symlinks
|
|
26
|
+
but not through Windows `.cmd` shims (they spawn `node ...\dist\cli.js`, so
|
|
27
|
+
the bin name never reaches argv). Bare invocation without a TTY therefore
|
|
28
|
+
falls back to the stdio server — the only sensible reading of a piped, no-TTY
|
|
29
|
+
launch, and exactly what a Windows editor spawn needs. The explicit
|
|
30
|
+
`zcode-acp repl` subcommand keeps a hard TTY check and errors instead.
|
|
31
|
+
|
|
32
|
+
We rejected keeping all old bins as silent aliases (five installed commands;
|
|
33
|
+
the redundancy was the original complaint), removing every old bin including
|
|
34
|
+
`zcode-acp-server` (breaks all existing editor configs at once; revisit at
|
|
35
|
+
1.0), and bundling [acpx](https://github.com/openclaw/acpx) as a `chat`
|
|
36
|
+
passthrough subcommand (evaluated first: its engine is headless-only, so it
|
|
37
|
+
cannot host the interactive REPL that is the actual requirement, and keeping
|
|
38
|
+
it beside the in-house REPL would mean two terminal surfaces, a pre-1.0
|
|
39
|
+
dependency, and an extra Node engine bump for no remaining use — dropped
|
|
40
|
+
before release).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zcode-acp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
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",
|
|
@@ -23,9 +23,8 @@
|
|
|
23
23
|
"zcode"
|
|
24
24
|
],
|
|
25
25
|
"bin": {
|
|
26
|
-
"zcode-acp
|
|
27
|
-
"zcode-acp-
|
|
28
|
-
"zcode-quota": "dist/bin/quota.js"
|
|
26
|
+
"zcode-acp": "dist/cli.js",
|
|
27
|
+
"zcode-acp-server": "dist/cli.js"
|
|
29
28
|
},
|
|
30
29
|
"main": "dist/index.js",
|
|
31
30
|
"types": "dist/index.d.ts",
|
|
@@ -37,6 +36,11 @@
|
|
|
37
36
|
],
|
|
38
37
|
"dependencies": {
|
|
39
38
|
"@agentclientprotocol/sdk": "^1.3.0",
|
|
39
|
+
"chalk": "^6.0.0",
|
|
40
|
+
"ink": "^7.1.1",
|
|
41
|
+
"ink-spinner": "^5.0.0",
|
|
42
|
+
"react": "^19.2.8",
|
|
43
|
+
"string-width": "^8.2.2",
|
|
40
44
|
"ws": "^8.21.3"
|
|
41
45
|
},
|
|
42
46
|
"peerDependencies": {
|
|
@@ -45,6 +49,7 @@
|
|
|
45
49
|
"devDependencies": {
|
|
46
50
|
"@eslint/js": "^9.0.0",
|
|
47
51
|
"@types/node": "^22.0.0",
|
|
52
|
+
"@types/react": "^19.2.18",
|
|
48
53
|
"@types/ws": "^8.18.1",
|
|
49
54
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
50
55
|
"@typescript-eslint/parser": "^8.0.0",
|