zcode-acp-server 0.1.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 (108) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +167 -0
  3. package/README.zh-CN.md +163 -0
  4. package/dist/backend/client.d.ts +103 -0
  5. package/dist/backend/client.d.ts.map +1 -0
  6. package/dist/backend/client.js +344 -0
  7. package/dist/backend/client.js.map +1 -0
  8. package/dist/backend/credentials.d.ts +31 -0
  9. package/dist/backend/credentials.d.ts.map +1 -0
  10. package/dist/backend/credentials.js +93 -0
  11. package/dist/backend/credentials.js.map +1 -0
  12. package/dist/backend/index.d.ts +7 -0
  13. package/dist/backend/index.d.ts.map +1 -0
  14. package/dist/backend/index.js +6 -0
  15. package/dist/backend/index.js.map +1 -0
  16. package/dist/backend/listener.d.ts +63 -0
  17. package/dist/backend/listener.d.ts.map +1 -0
  18. package/dist/backend/listener.js +138 -0
  19. package/dist/backend/listener.js.map +1 -0
  20. package/dist/backend/resolve.d.ts +11 -0
  21. package/dist/backend/resolve.d.ts.map +1 -0
  22. package/dist/backend/resolve.js +116 -0
  23. package/dist/backend/resolve.js.map +1 -0
  24. package/dist/backend/types.d.ts +164 -0
  25. package/dist/backend/types.d.ts.map +1 -0
  26. package/dist/backend/types.js +15 -0
  27. package/dist/backend/types.js.map +1 -0
  28. package/dist/config/model-cache.d.ts +20 -0
  29. package/dist/config/model-cache.d.ts.map +1 -0
  30. package/dist/config/model-cache.js +62 -0
  31. package/dist/config/model-cache.js.map +1 -0
  32. package/dist/config/options.d.ts +36 -0
  33. package/dist/config/options.d.ts.map +1 -0
  34. package/dist/config/options.js +171 -0
  35. package/dist/config/options.js.map +1 -0
  36. package/dist/config/runtime-model.d.ts +33 -0
  37. package/dist/config/runtime-model.d.ts.map +1 -0
  38. package/dist/config/runtime-model.js +96 -0
  39. package/dist/config/runtime-model.js.map +1 -0
  40. package/dist/handlers/dispatch.d.ts +15 -0
  41. package/dist/handlers/dispatch.d.ts.map +1 -0
  42. package/dist/handlers/dispatch.js +183 -0
  43. package/dist/handlers/dispatch.js.map +1 -0
  44. package/dist/handlers/extensions.d.ts +43 -0
  45. package/dist/handlers/extensions.d.ts.map +1 -0
  46. package/dist/handlers/extensions.js +310 -0
  47. package/dist/handlers/extensions.js.map +1 -0
  48. package/dist/handlers/io.d.ts +40 -0
  49. package/dist/handlers/io.d.ts.map +1 -0
  50. package/dist/handlers/io.js +55 -0
  51. package/dist/handlers/io.js.map +1 -0
  52. package/dist/handlers/server-requests.d.ts +34 -0
  53. package/dist/handlers/server-requests.d.ts.map +1 -0
  54. package/dist/handlers/server-requests.js +357 -0
  55. package/dist/handlers/server-requests.js.map +1 -0
  56. package/dist/handlers/session.d.ts +46 -0
  57. package/dist/handlers/session.d.ts.map +1 -0
  58. package/dist/handlers/session.js +738 -0
  59. package/dist/handlers/session.js.map +1 -0
  60. package/dist/handlers/slash.d.ts +16 -0
  61. package/dist/handlers/slash.d.ts.map +1 -0
  62. package/dist/handlers/slash.js +107 -0
  63. package/dist/handlers/slash.js.map +1 -0
  64. package/dist/index.d.ts +11 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +93 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/interaction/adapter.d.ts +136 -0
  69. package/dist/interaction/adapter.d.ts.map +1 -0
  70. package/dist/interaction/adapter.js +353 -0
  71. package/dist/interaction/adapter.js.map +1 -0
  72. package/dist/server.d.ts +73 -0
  73. package/dist/server.d.ts.map +1 -0
  74. package/dist/server.js +97 -0
  75. package/dist/server.js.map +1 -0
  76. package/dist/tasks-index.d.ts +39 -0
  77. package/dist/tasks-index.d.ts.map +1 -0
  78. package/dist/tasks-index.js +152 -0
  79. package/dist/tasks-index.js.map +1 -0
  80. package/dist/translators/event-translator.d.ts +40 -0
  81. package/dist/translators/event-translator.d.ts.map +1 -0
  82. package/dist/translators/event-translator.js +214 -0
  83. package/dist/translators/event-translator.js.map +1 -0
  84. package/dist/translators/index.d.ts +6 -0
  85. package/dist/translators/index.d.ts.map +1 -0
  86. package/dist/translators/index.js +5 -0
  87. package/dist/translators/index.js.map +1 -0
  88. package/dist/translators/projection-differ.d.ts +48 -0
  89. package/dist/translators/projection-differ.d.ts.map +1 -0
  90. package/dist/translators/projection-differ.js +239 -0
  91. package/dist/translators/projection-differ.js.map +1 -0
  92. package/dist/translators/tool-helpers.d.ts +60 -0
  93. package/dist/translators/tool-helpers.d.ts.map +1 -0
  94. package/dist/translators/tool-helpers.js +308 -0
  95. package/dist/translators/tool-helpers.js.map +1 -0
  96. package/dist/translators/types.d.ts +58 -0
  97. package/dist/translators/types.d.ts.map +1 -0
  98. package/dist/translators/types.js +27 -0
  99. package/dist/translators/types.js.map +1 -0
  100. package/dist/utils.d.ts +111 -0
  101. package/dist/utils.d.ts.map +1 -0
  102. package/dist/utils.js +110 -0
  103. package/dist/utils.js.map +1 -0
  104. package/docs/ARCHITECTURE.md +299 -0
  105. package/docs/DEVELOPMENT.md +193 -0
  106. package/docs/PROTOCOL.md +649 -0
  107. package/docs/TROUBLESHOOTING.md +251 -0
  108. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is derived from (or based upon) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for describing the origin of the Work and
141
+ reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 ZCode ACP Server Contributors
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # zcode-acp-server
2
+
3
+ [![CI](https://github.com/zcode-org/zcode-acp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/zcode-org/zcode-acp-server/actions/workflows/ci.yml)
4
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
5
+
6
+ English | **[简体中文](README.zh-CN.md)**
7
+
8
+ A standalone [Agent Client Protocol](https://agentclientprotocol.com/) (ACP) server that bridges the headless **ZCode** app-server to ACP-compatible editors such as [Zed](https://zed.dev) and JetBrains IDEs.
9
+
10
+ The server launches the ZCode headless app-server (`zcode app-server --stdio`) as a subprocess, translates its internal event stream into ACP `session/update` notifications, and bridges ZCode's interaction channel to ACP — preferring `elicitation/create` when the client supports it, and falling back to `session/request_permission` otherwise — so an editor gets a first-class, native coding-agent experience.
11
+
12
+ ## Status
13
+
14
+ Early in-development. Core scaffolding is in place; features are landing incrementally. See the project board for progress.
15
+
16
+ ## Requirements
17
+
18
+ - **Node.js ≥ 22** (the bridge uses `node:sqlite` for tasks-index sync; the
19
+ ZCode CLI runtime also requires Node ≥ 22)
20
+ - The `zcode` CLI installed and on `PATH` (or pointed at via `ZCODE_BIN`)
21
+ - ZCode credentials at `~/.zcode/v2/config.json` (created by the ZCode app)
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ git clone <repo-url>
27
+ cd zcode-acp-server
28
+ pnpm install
29
+ pnpm build
30
+ ```
31
+
32
+ The compiled entry point is `dist/index.js` (also exposed as the
33
+ `zcode-acp-server` bin). Configure your ACP client to launch it — see
34
+ **Configure Zed** below or your editor's ACP docs.
35
+
36
+ ## Configure Zed
37
+
38
+ Add the server to Zed as a custom agent server. In `~/.config/zed/settings.json`
39
+ (`%APPDATA%\Zed\settings.json` on Windows):
40
+
41
+ ```jsonc
42
+ {
43
+ "agent_servers": {
44
+ "ZCode": {
45
+ "type": "custom",
46
+ "command": "node",
47
+ "args": ["/absolute/path/to/zcode-acp-server/dist/index.js"],
48
+ "env": {
49
+ // Point at the ZCode CLI bundled inside the desktop app (not on PATH by default).
50
+ // See the platform-specific path below.
51
+ "ZCODE_BIN": "/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs",
52
+ },
53
+ },
54
+ },
55
+ }
56
+ ```
57
+
58
+ Restart Zed and pick **ZCode** from the agent dropdown.
59
+
60
+ ### `ZCODE_BIN` per platform
61
+
62
+ The ZCode CLI ships inside the desktop app and is not added to `PATH`
63
+ automatically. Point `ZCODE_BIN` at the bundled `zcode.cjs`:
64
+
65
+ | Platform | `ZCODE_BIN` path |
66
+ | ----------- | --------------------------------------------------------------------------- |
67
+ | **macOS** | `/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs` |
68
+ | **Windows** | `%LOCALAPPDATA%\Programs\ZCode\resources\glm\zcode.cjs` |
69
+ | **Linux** | Inside the extracted app directory: `<install-dir>/resources/glm/zcode.cjs` |
70
+
71
+ > If the path doesn't match your install, locate it with:
72
+ >
73
+ > ```bash
74
+ > # macOS / Linux
75
+ > find / -name zcode.cjs -path '*resources/glm*' 2>/dev/null
76
+ > # Windows (PowerShell)
77
+ > Get-ChildItem -Path $env:LOCALAPPDATA,$env:APPDATA,'C:\Program Files' -Recurse -Filter zcode.cjs -ErrorAction SilentlyContinue
78
+ > ```
79
+
80
+ ## Environment variables
81
+
82
+ | Variable | Default | Purpose |
83
+ | ----------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
84
+ | `ZCODE_BIN` | `zcode` | Path to the ZCode CLI binary or its `.cjs` entry |
85
+ | `ZCODE_NODE` | _(discovered)_ | Explicit Node binary to run `ZCODE_BIN` with (must support `node:sqlite`) |
86
+ | `ZCODE_MODEL` | _(from config)_ | Override the active model id |
87
+ | `ZCODE_BASE_URL` | _(from config)_ | Override the provider base URL |
88
+ | `ZCODE_ACP_DEBUG` | _(unset)_ | Set to `1` to enable verbose diagnostic logs (event flow, probe loops, status updates). Default is quiet — only warnings (backend pipe errors, command/permission failures, lock timeouts) are emitted. Enable this when diagnosing bridge issues; the logs appear in `Zed.log` prefixed with `[zcode-acp]`. |
89
+
90
+ ## ACP Registry
91
+
92
+ This server is compatible with the [ACP Registry](https://agentclientprotocol.com/get-started/registry). It advertises a single `agent`-type auth method at `initialize` time — the GLM API key is read from `~/.zcode/v2/config.json` by the ZCode backend, so **no editor-side credentials are required**.
93
+
94
+ The registry submission assets live under [`registry/zcode-acp-server/`](registry/zcode-acp-server/) (`agent.json` + `icon.svg`). Once the package is published to npm, copy that directory into a fork of [`agentclientprotocol/registry`](https://github.com/agentclientprotocol/registry) and open a PR — the CI validates the `agent.json` schema, icon, and that `initialize` returns a non-empty `authMethods`.
95
+
96
+ ## Develop
97
+
98
+ ```bash
99
+ pnpm install
100
+ pnpm build # tsc → dist/
101
+ pnpm typecheck # tsc --noEmit
102
+ pnpm lint # eslint (warnings advisory; errors fail CI)
103
+ pnpm test # vitest
104
+ pnpm format # prettier on src/
105
+ ```
106
+
107
+ CI runs `typecheck`, `lint`, `build`, and `test` on every push and pull
108
+ request — run them locally before pushing (see [CONTRIBUTING.md](CONTRIBUTING.md)).
109
+
110
+ > **Tip (Node version)**: this repo pins Node 22 via a root `.node-version`
111
+ > file. Pair it with [fnm](https://github.com/Schniz/fnm) or
112
+ > [nvm](https://github.com/nvm-sh/nvm) to auto-switch on `cd`. pnpm itself is
113
+ > managed by your local environment (corepack).
114
+
115
+ ## Architecture
116
+
117
+ The server is organised in layers that mirror the ACP protocol:
118
+
119
+ - `backend/` — ZCode subprocess client: spawn, reader-loop multiplexer, event-stream listener, sync request/response
120
+ - `translators/` — turn ZCode events into ACP `session/update` notifications (event streaming + snapshot diff)
121
+ - `interaction/` — bridge ZCode `interaction/*` server requests to ACP, preferring `elicitation/create` and falling back to `session/request_permission` (tool auth, ExitPlanMode, AskUserQuestion)
122
+ - `handlers/` — ACP method handlers (`session/new`, `session/prompt`, ...) and the turn engine
123
+ - `config/` — model / mode / thought-level configOptions and runtime model switching
124
+ - `server.ts` — shared state and handler registration
125
+ - `index.ts` — stdio wiring via the ACP SDK
126
+
127
+ See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full architecture documentation.
128
+
129
+ ## Version Compatibility
130
+
131
+ | ZCode CLI version | Support | Notes |
132
+ | :---------------: | :----------: | ---------------------------------------- |
133
+ | **>= 0.15.0** | Full | All extension methods available |
134
+ | **>= 0.14.8** | Full | Event-stream push, all extension methods |
135
+ | **< 0.14.8** | Incompatible | Event-stream subscription unavailable |
136
+
137
+ ## Documentation
138
+
139
+ - [Architecture](docs/ARCHITECTURE.md) — event stream, dual-path deduplication, module responsibilities
140
+ - [Protocol](docs/PROTOCOL.md) — ZCode JSON-RPC protocol details
141
+ - [Development](docs/DEVELOPMENT.md) — local development, debugging, adding extension methods
142
+ - [Troubleshooting](docs/TROUBLESHOOTING.md) — common-issue troubleshooting
143
+
144
+ ## Contributing
145
+
146
+ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for setup,
147
+ code style, commit conventions, and the PR checklist. Notable changes are
148
+ recorded in [CHANGELOG.md](CHANGELOG.md).
149
+
150
+ ## Related Projects
151
+
152
+ - [zcode-open-bridge](https://github.com/tizerluo/zcode-open-bridge) — a community Python implementation that bridges ZCode to the MCP/ACP ecosystem. The design of this server references its bridge architecture and several handling strategies.
153
+
154
+ ## Acknowledgements
155
+
156
+ - [Agent Client Protocol](https://agentclientprotocol.com/) (Apache-2.0) — the ACP specification
157
+ - [ZCode](https://zcode.z.ai) / [Zhipu Z.AI](https://z.ai) — the GLM model and ZCode CLI
158
+ - [zcode-open-bridge](https://github.com/tizerluo/zcode-open-bridge) — reference implementation that informed this server's design
159
+
160
+ ## License
161
+
162
+ Apache-2.0. This project follows the same license as the upstream ACP specification.
163
+
164
+ ## Disclaimer
165
+
166
+ This is an independent community project and is not affiliated with, endorsed
167
+ by, or sponsored by Zhipu Z.AI. ZCode is a product of Zhipu Z.AI.
@@ -0,0 +1,163 @@
1
+ # zcode-acp-server
2
+
3
+ [![CI](https://github.com/zcode-org/zcode-acp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/zcode-org/zcode-acp-server/actions/workflows/ci.yml)
4
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
5
+
6
+ **[English](README.md)** | 简体中文
7
+
8
+ 一个独立的 [Agent Client Protocol](https://agentclientprotocol.com/)(ACP)服务端,将无头模式的 **ZCode** app-server 桥接到支持 ACP 的编辑器,例如 [Zed](https://zed.dev) 和 JetBrains IDE。
9
+
10
+ 本服务端以子进程方式启动 ZCode 无头 app-server(`zcode app-server --stdio`),将其内部事件流翻译为 ACP `session/update` 通知,并把 ZCode 的交互通道桥接到 ACP —— 当客户端支持时优先使用 `elicitation/create`,否则回退到 `session/request_permission` —— 从而让编辑器获得原生的、一流的编码助手体验。
11
+
12
+ ## 状态
13
+
14
+ 早期开发中。核心框架已就绪,功能正在陆续加入。进度请看项目看板。
15
+
16
+ ## 环境要求
17
+
18
+ - **Node.js ≥ 22**(桥接层用 `node:sqlite` 同步 tasks-index;ZCode CLI
19
+ 运行时也要求 Node ≥ 22)
20
+ - 已安装 `zcode` CLI 并位于 `PATH` 上(或通过 `ZCODE_BIN` 指定)
21
+ - ZCode 凭证位于 `~/.zcode/v2/config.json`(由 ZCode App 创建)
22
+
23
+ ## 安装
24
+
25
+ ```bash
26
+ git clone <repo-url>
27
+ cd zcode-acp-server
28
+ pnpm install
29
+ pnpm build
30
+ ```
31
+
32
+ 编译产物入口为 `dist/index.js`(同时作为 `zcode-acp-server` bin 暴露)。在你的
33
+ ACP 客户端里配置启动它 —— 见下方的 **在 Zed 中配置** 或你的编辑器的 ACP 文档。
34
+
35
+ ## 在 Zed 中配置
36
+
37
+ 将本服务端作为自定义 agent server 添加到 Zed。在 `~/.config/zed/settings.json`
38
+ (Windows 上为 `%APPDATA%\Zed\settings.json`)中:
39
+
40
+ ```jsonc
41
+ {
42
+ "agent_servers": {
43
+ "ZCode": {
44
+ "type": "custom",
45
+ "command": "node",
46
+ "args": ["/absolute/path/to/zcode-acp-server/dist/index.js"],
47
+ "env": {
48
+ // 指向桌面应用内置的 ZCode CLI(默认不在 PATH 上)。
49
+ // 各平台路径见下方表格。
50
+ "ZCODE_BIN": "/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs",
51
+ },
52
+ },
53
+ },
54
+ }
55
+ ```
56
+
57
+ 重启 Zed,然后从 agent 下拉菜单中选择 **ZCode**。
58
+
59
+ ### 各平台的 `ZCODE_BIN` 路径
60
+
61
+ ZCode CLI 内置于桌面应用中,默认不会加到 `PATH`。用 `ZCODE_BIN` 指向内置的
62
+ `zcode.cjs`:
63
+
64
+ | 平台 | `ZCODE_BIN` 路径 |
65
+ | ----------- | ---------------------------------------------------------- |
66
+ | **macOS** | `/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs` |
67
+ | **Windows** | `%LOCALAPPDATA%\Programs\ZCode\resources\glm\zcode.cjs` |
68
+ | **Linux** | 解压后的应用目录内:`<安装目录>/resources/glm/zcode.cjs` |
69
+
70
+ > 如果路径与实际安装不符,可用以下命令定位:
71
+ >
72
+ > ```bash
73
+ > # macOS / Linux
74
+ > find / -name zcode.cjs -path '*resources/glm*' 2>/dev/null
75
+ > # Windows (PowerShell)
76
+ > Get-ChildItem -Path $env:LOCALAPPDATA,$env:APPDATA,'C:\Program Files' -Recurse -Filter zcode.cjs -ErrorAction SilentlyContinue
77
+ > ```
78
+
79
+ ## 环境变量
80
+
81
+ | 变量 | 默认值 | 用途 |
82
+ | ----------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
+ | `ZCODE_BIN` | `zcode` | ZCode CLI 二进制文件路径或其 `.cjs` 入口 |
84
+ | `ZCODE_NODE` | _(自动发现)_ | 显式指定运行 `ZCODE_BIN` 的 Node 二进制(必须支持 `node:sqlite`) |
85
+ | `ZCODE_MODEL` | _(来自 config) | 覆盖当前使用的模型 id |
86
+ | `ZCODE_BASE_URL` | _(来自 config) | 覆盖 provider 的 base URL |
87
+ | `ZCODE_ACP_DEBUG` | _(未设置) | 设为 `1` 可开启详细诊断日志(事件流、探测循环、状态更新)。默认安静——只输出警告类日志(后端管道错误、命令/权限失败、锁等待超时)。诊断桥接问题时开启;日志出现在 `Zed.log` 中,前缀为 `[zcode-acp]`。 |
88
+
89
+ ## ACP Registry
90
+
91
+ 本服务端兼容 [ACP Registry](https://agentclientprotocol.com/get-started/registry)。它在 `initialize` 时声明一个 `agent` 类型的认证方法——GLM API key 由 ZCode 后端从 `~/.zcode/v2/config.json` 读取,**编辑器侧无需配置任何凭据**。
92
+
93
+ Registry 提交资产位于 [`registry/zcode-acp-server/`](registry/zcode-acp-server/)(`agent.json` + `icon.svg`)。包发布到 npm 后,将该目录复制到 [`agentclientprotocol/registry`](https://github.com/agentclientprotocol/registry) 的 fork 中并提 PR——CI 会校验 `agent.json` schema、图标,以及 `initialize` 返回的 `authMethods` 非空。
94
+
95
+ ## 开发
96
+
97
+ ```bash
98
+ pnpm install
99
+ pnpm build # tsc → dist/
100
+ pnpm typecheck # tsc --noEmit
101
+ pnpm lint # eslint(警告为建议性质;错误会导致 CI 失败)
102
+ pnpm test # vitest
103
+ pnpm format # prettier on src/
104
+ ```
105
+
106
+ CI 会在每次 push 和 pull request 时运行 `typecheck`、`lint`、`build` 和
107
+ `test` —— 推送前请在本地跑一遍(见 [CONTRIBUTING.md](CONTRIBUTING.md))。
108
+
109
+ > **提示(Node 版本管理)**:本项目通过根目录的 `.node-version` 锁定 Node 22,
110
+ > 推荐配合 [fnm](https://github.com/Schniz/fnm) 或 [nvm](https://github.com/nvm-sh/nvm)
111
+ > 使用 —— 进入目录即自动切换到 Node 22。pnpm 的版本由本地环境(corepack)管理。
112
+
113
+ ## 架构
114
+
115
+ 服务端按 ACP 协议分层组织:
116
+
117
+ - `backend/` —— ZCode 子进程客户端:spawn、reader-loop 多路复用、事件流监听、同步请求/响应
118
+ - `translators/` —— 将 ZCode 事件转为 ACP `session/update` 通知(事件流 + 快照 diff)
119
+ - `interaction/` —— 将 ZCode `interaction/*` 服务端请求桥接到 ACP,优先 `elicitation/create`,回退 `session/request_permission`(工具授权、ExitPlanMode、AskUserQuestion)
120
+ - `handlers/` —— ACP 方法处理器(`session/new`、`session/prompt` 等)和 turn 引擎
121
+ - `config/` —— model / mode / thought-level 的 configOptions 和运行时模型切换
122
+ - `server.ts` —— 共享状态和处理器注册
123
+ - `index.ts` —— 通过 ACP SDK 的 stdio 连接
124
+
125
+ 完整架构说明见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
126
+
127
+ ## 版本兼容性
128
+
129
+ | ZCode CLI 版本 | 支持 | 说明 |
130
+ | :------------: | :----: | ------------------------ |
131
+ | **>= 0.15.0** | 完整 | 所有扩展方法可用 |
132
+ | **>= 0.14.8** | 完整 | 事件流推送、所有扩展方法 |
133
+ | **< 0.14.8** | 不兼容 | 无事件流订阅能力 |
134
+
135
+ ## 文档
136
+
137
+ - [架构](docs/ARCHITECTURE.md) —— 事件流、双路径去重、模块职责
138
+ - [协议](docs/PROTOCOL.md) —— ZCode JSON-RPC 协议细节
139
+ - [开发](docs/DEVELOPMENT.md) —— 本地开发、调试、新增扩展方法
140
+ - [故障排查](docs/TROUBLESHOOTING.md) —— 常见问题排查
141
+
142
+ ## 贡献
143
+
144
+ 欢迎贡献!请阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 了解环境搭建、代码风格、
145
+ commit 约定和 PR 检查清单。重要变更记录在 [CHANGELOG.md](CHANGELOG.md)。
146
+
147
+ ## 相关项目
148
+
149
+ - [zcode-open-bridge](https://github.com/tizerluo/zcode-open-bridge) —— 一个社区 Python 实现,将 ZCode 接入 MCP/ACP 生态。本项目参考了它的桥接架构和若干处理策略。
150
+
151
+ ## 致谢
152
+
153
+ - [Agent Client Protocol](https://agentclientprotocol.com/)(Apache 2.0)—— ACP 协议规范
154
+ - [ZCode](https://zcode.z.ai) / [智谱 Z.AI](https://z.ai) —— GLM 模型与 ZCode CLI
155
+ - [zcode-open-bridge](https://github.com/tizerluo/zcode-open-bridge) —— 参考实现,本项目的设计借鉴了它的桥接架构
156
+
157
+ ## 许可证
158
+
159
+ Apache-2.0。本项目沿用上游 ACP 规范的同一许可证。
160
+
161
+ ## 免责声明
162
+
163
+ 本项目为独立的社区项目,与智谱 Z.AI 官方无任何隶属、认可或赞助关系。ZCode 是智谱 Z.AI 的产品。
@@ -0,0 +1,103 @@
1
+ /**
2
+ * ZCode subprocess client: spawn, read-loop multiplexer, async request/response.
3
+ *
4
+ * The ZCode app-server is launched as a subprocess (`zcode app-server --stdio`)
5
+ * speaking line-delimited JSON over stdio. A single async read loop demultiplexes
6
+ * inbound messages into three channels:
7
+ * - responses (id, no method) → resolve the matching pending request promise
8
+ * - server→client requests (id + method, id not pending) → server-request queue
9
+ * - notifications (no id):
10
+ * - `session/event` → routed to the registered session listener
11
+ * - anything else → general notification queue
12
+ *
13
+ * Process-group isolation: the subprocess is its own process-group leader
14
+ * (`detached: true`) so `close()` can kill the whole tree (zcode + its model
15
+ * workers) with `process.kill(-pid)` and leave no orphans.
16
+ */
17
+ import { type ChildProcess } from "node:child_process";
18
+ import type { ZcodeEvent, ZcodeInteractionPermissionParams, ZcodeInteractionUserInputParams, ZcodeResponse } from "./types.js";
19
+ /** A server→client request that we must reply to. */
20
+ export interface ServerRequest {
21
+ id: number;
22
+ method: string;
23
+ params: ZcodeInteractionPermissionParams | ZcodeInteractionUserInputParams | Record<string, unknown>;
24
+ }
25
+ /** Listener for `session/event` pushes on a given session. */
26
+ export interface EventListener {
27
+ handleEvent(event: ZcodeEvent): void;
28
+ }
29
+ export declare class ZcodeBackend {
30
+ readonly proc: ChildProcess;
31
+ private readonly pending;
32
+ private readonly serverRequests;
33
+ private readonly listeners;
34
+ private readerDead;
35
+ /** Monotonic id for fire-and-forget sends (send()). Uses a high range to
36
+ * avoid collisions with the server's request ids (low range). */
37
+ private sendIdCounter;
38
+ /** Watchdog process that kills the zcode group if this bridge dies (SIGKILL). */
39
+ private watchdog;
40
+ constructor(argv: string[], env: NodeJS.ProcessEnv);
41
+ /**
42
+ * Spawn a tiny detached watchdog that kills the zcode process group if this
43
+ * bridge process disappears.
44
+ *
45
+ * The detached/kill(-pid) cleanup in `close()` only runs when the bridge
46
+ * exits cleanly enough for the signal handlers to fire (SIGTERM/SIGINT/etc).
47
+ * If the bridge is SIGKILLed (Zed force-kill on reconnect, crash, OOM), the
48
+ * handler never runs and the zcode subprocess group is orphaned. The
49
+ * watchdog closes that gap: it polls the bridge pid every 2s and, once the
50
+ * bridge is gone, sends SIGKILL to the zcode process group, then exits.
51
+ *
52
+ * The watchdog is its own process-group leader (detached) and `unref`'d, so
53
+ * it never holds the event loop open and is not part of the zcode group it
54
+ * kills. It self-terminates as soon as the zcode process exits, so a normal
55
+ * shutdown leaves no lingering watchdog.
56
+ */
57
+ private startWatchdog;
58
+ private startReader;
59
+ private route;
60
+ private resolvePending;
61
+ private markReaderDead;
62
+ registerEventListener(zcodeSid: string, listener: EventListener): void;
63
+ unregisterEventListener(zcodeSid: string): void;
64
+ /** Non-blocking drain of pending server→client requests. */
65
+ pollServerRequests(): ServerRequest[];
66
+ /** Reply to a zcode server→client request with a result (id + result). */
67
+ sendReply(id: number, result: unknown): void;
68
+ /** Reply to a zcode server→client request with an error. */
69
+ sendError(id: number, code: number, message: string): void;
70
+ /** Fire-and-forget notification to ZCode (no id, no response). */
71
+ notify(method: string, params?: Record<string, unknown>): void;
72
+ /**
73
+ * Send a message with an id but WITHOUT registering a pending response
74
+ * (fire-and-forget). Mirrors Python's `_backend.send({"id": ..., ...})` for
75
+ * `session/stop`: some backends route by id presence, so carrying an id is
76
+ * more robust than a bare notify. If the backend replies, the reader's
77
+ * `resolvePending` finds no pending entry and safely discards it.
78
+ */
79
+ send(method: string, params?: Record<string, unknown>): void;
80
+ /**
81
+ * Synchronous request/response: register a pending promise, send, await.
82
+ * Other notifications arriving during the wait are routed async by the
83
+ * reader loop (they don't get swallowed).
84
+ *
85
+ * Returns `{error}` on dead backend, broken pipe, or timeout — never throws.
86
+ */
87
+ request(id: number, method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<ZcodeResponse>;
88
+ /**
89
+ * Kill the whole zcode process group and wait for it to die.
90
+ *
91
+ * SIGTERM → wait up to 3s → SIGKILL if still alive. Mirrors the Python
92
+ * `os.killpg` + `proc.wait(3)` + SIGKILL escalation. Note `proc.killed` is
93
+ * NOT set by `process.kill(-pid)` (group signal), so we track liveness via
94
+ * `exitCode === null` instead. Async so the caller can `await` a full reap
95
+ * before the parent exits (an unref'd timer could be skipped on fast exit,
96
+ * leaving orphans).
97
+ */
98
+ close(): Promise<void>;
99
+ /** Terminate the watchdog process if it is still running. */
100
+ private killWatchdog;
101
+ get isDead(): boolean;
102
+ }
103
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/backend/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EACV,UAAU,EAEV,gCAAgC,EAChC,+BAA+B,EAC/B,aAAa,EACd,MAAM,YAAY,CAAC;AAQpB,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EACJ,gCAAgC,GAAG,+BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChG;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACtC;AAED,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,UAAU,CAAS;IAC3B;sEACkE;IAClE,OAAO,CAAC,aAAa,CAAiB;IACtC,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAA6B;gBAEjC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU;IAmBlD;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,KAAK;IAiCb,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,cAAc;IAgBtB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAItE,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI/C,4DAA4D;IAC5D,kBAAkB,IAAI,aAAa,EAAE;IAKrC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAY5C,4DAA4D;IAC5D,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAW1D,kEAAkE;IAClE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAS9D;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAU5D;;;;;;OAMG;IACG,OAAO,CACX,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,SAAQ,GAChB,OAAO,CAAC,aAAa,CAAC;IA+BzB;;;;;;;;;OASG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC5B,6DAA6D;IAC7D,OAAO,CAAC,YAAY;IAapB,IAAI,MAAM,IAAI,OAAO,CAEpB;CACF"}