nx-ce 0.1.4 → 0.1.5
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 +210 -111
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,233 +3,332 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/nx-ce)
|
|
4
4
|
[](https://github.com/joke-lx/nx-ce/actions/workflows/npm-publish.yml)
|
|
5
5
|
|
|
6
|
-
**nx-ce**
|
|
7
|
-
通过长度前缀的 JSON 协议在 stdin/stdout 上暴露 SDK 接口,
|
|
8
|
-
支持一次性冷启动查询与 WebSocket 持久化服务器两种运行模式。
|
|
6
|
+
**nx-ce** is a lightweight Node.js adapter for `@anthropic-ai/claude-agent-sdk`. It provides two modes:
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
- **`nx-ce query`** — one-shot cold-start queries (stateless, CLI-friendly)
|
|
9
|
+
- **`nx-ce serve`** — WebSocket multi-session server (persistent, concurrent clients)
|
|
10
|
+
|
|
11
|
+
**nx-ce** 是一个轻量级 Node.js 适配器,封装了 `@anthropic-ai/claude-agent-sdk`。支持两种运行模式:
|
|
12
|
+
一次性冷启动查询与多会话 WebSocket 持久化服务器。
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Family / 项目家族
|
|
17
17
|
|
|
18
|
-
| Package |
|
|
18
|
+
| Package | Role / 角色 |
|
|
19
19
|
|---------|-------------|
|
|
20
|
-
| **nx-ce** | Claude Engine — SDK
|
|
21
|
-
| [nx-sx](https://github.com/jokelx/nx-sx) | Sandbox eXecution —
|
|
20
|
+
| **nx-ce** | Claude Engine — SDK adapter layer / SDK 适配层 |
|
|
21
|
+
| [nx-sx](https://github.com/jokelx/nx-sx) | Sandbox eXecution — window & terminal manager / 窗口终端管理器 |
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Install / 安装
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
npm install nx-ce
|
|
29
|
-
#
|
|
29
|
+
# or globally
|
|
30
30
|
npm install -g nx-ce
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
##
|
|
35
|
+
## Quick Start / 快速开始
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# One-shot query (stateless)
|
|
39
|
+
nx-ce query "用中文回答:1+1=?" --model claude-haiku-4-5
|
|
40
|
+
|
|
41
|
+
# Start WebSocket server (persistent, multi-session)
|
|
42
|
+
nx-ce serve --port 3100
|
|
43
|
+
|
|
44
|
+
# In another terminal, connect via WebSocket (see test/serve-test.mjs)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
## `nx-ce query` — One-shot Cold-Start Query / 一次性冷启动查询
|
|
38
50
|
|
|
39
51
|
```bash
|
|
40
52
|
nx-ce query "解释这段代码" --model claude-sonnet-4-6
|
|
41
|
-
nx-ce query "Explain this code" --model claude-haiku-4-5 --no-persist
|
|
42
53
|
nx-ce query "继续之前的对话" --resume sess_abc123
|
|
43
54
|
nx-ce query "Analyze" --skill git-workflow,code-review
|
|
44
55
|
nx-ce query "Analyze" --skill all
|
|
45
56
|
```
|
|
46
57
|
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
| `--model <id>` |
|
|
50
|
-
| `--claude-path <path>` | Claude CLI
|
|
51
|
-
| `--system-prompt <text>` |
|
|
52
|
-
| `--resume <sessionId>` |
|
|
53
|
-
| `--skill <name>[,<name>...]` |
|
|
54
|
-
| `--include-metadata` |
|
|
55
|
-
| `--no-persist` |
|
|
56
|
-
| `--env "KEY=
|
|
58
|
+
| Flag | Description / 说明 |
|
|
59
|
+
|------|-------------------|
|
|
60
|
+
| `--model <id>` | Model override (default `claude-sonnet-4-6`) / 模型 ID |
|
|
61
|
+
| `--claude-path <path>` | Path to Claude CLI binary / Claude CLI 路径 |
|
|
62
|
+
| `--system-prompt <text>` | System prompt override / 系统提示词覆盖 |
|
|
63
|
+
| `--resume <sessionId>` | Resume a prior session (long conversation) / 续接会话 |
|
|
64
|
+
| `--skill <name>[,<name>...]` | Load specific skills (comma-separated, or `all`) / 加载 Skill |
|
|
65
|
+
| `--include-metadata` | Include skills/tools/slashCommands in output / 附带元数据 |
|
|
66
|
+
| `--no-persist` | Don't persist session / 不持久化 |
|
|
67
|
+
| `--env "KEY=val,KEY2=val"` | Extra environment variables / 额外环境变量 |
|
|
57
68
|
|
|
58
|
-
###
|
|
69
|
+
### JSON output
|
|
59
70
|
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
```json
|
|
72
|
+
// Default
|
|
73
|
+
{ "text": "2", "sessionId": "sess_abc" }
|
|
62
74
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
nx-ce serve --port 3100 # 指定端口
|
|
66
|
-
nx-ce serve --name chat-tab-1
|
|
75
|
+
// With --include-metadata
|
|
76
|
+
{ "text": "2", "sessionId": "sess_abc", "metadata": { "skills": [...], "tools": [...], ... } }
|
|
67
77
|
```
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
| `--port <port>` | WebSocket 端口(默认 `3100`)/ WebSocket port |
|
|
73
|
-
| `--model <id>` | 模型 ID 覆盖 / Model override |
|
|
74
|
-
| `--claude-path <path>` | Claude CLI 可执行文件路径 / Path to Claude CLI binary |
|
|
75
|
-
| `--env "KEY=value,..."` | 额外环境变量 / Extra environment variables |
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## `nx-ce serve` — WebSocket Multi-Session Server / WebSocket 多会话服务器
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
**Single process. Multiple concurrent sessions. FIFO queries per session.**
|
|
78
84
|
|
|
79
|
-
|
|
85
|
+
单例进程。多会话隔离。每个会话独立 SDK agentQuery,互不阻塞。
|
|
80
86
|
|
|
81
87
|
```bash
|
|
82
|
-
nx-ce
|
|
83
|
-
nx-ce
|
|
88
|
+
nx-ce serve # default port 3100
|
|
89
|
+
nx-ce serve --port 3100
|
|
90
|
+
nx-ce serve --name "main" --port 3100 --cwd "D:/project"
|
|
84
91
|
```
|
|
85
92
|
|
|
86
|
-
|
|
93
|
+
| Flag | Description / 说明 |
|
|
94
|
+
|------|-------------------|
|
|
95
|
+
| `--name <name>` | Instance name (default `default`) / 实例名称 |
|
|
96
|
+
| `--port <port>` | WebSocket port (default `3100`) / 端口 |
|
|
97
|
+
| `--model <id>` | Model override / 模型 ID |
|
|
98
|
+
| `--claude-path <path>` | Path to Claude CLI / CLI 路径 |
|
|
99
|
+
| `--cwd <path>` | Working directory / 工作目录 |
|
|
100
|
+
| `--env "KEY=val,..."` | Extra env vars / 额外环境变量 |
|
|
101
|
+
|
|
102
|
+
> WebSocket address: `ws://127.0.0.1:3100` (localhost only)
|
|
103
|
+
|
|
104
|
+
### Singleton guarantee / 单例保证
|
|
87
105
|
|
|
88
106
|
```bash
|
|
89
|
-
nx-ce
|
|
107
|
+
nx-ce serve --port 3100 # first → OK
|
|
108
|
+
nx-ce serve --port 3100 # second → Port 3100 already in use — another nx-ce serve is running
|
|
90
109
|
```
|
|
91
110
|
|
|
92
111
|
---
|
|
93
112
|
|
|
94
|
-
## WebSocket
|
|
95
|
-
|
|
96
|
-
服务端地址 `ws://127.0.0.1:PORT`(默认 3100)。所有消息均为 JSON 字符串(不含长度前缀)。
|
|
113
|
+
## WebSocket Protocol / WebSocket 协议
|
|
97
114
|
|
|
98
|
-
Server
|
|
115
|
+
Server: `ws://127.0.0.1:PORT`. All messages are JSON (no length prefix).
|
|
99
116
|
|
|
100
|
-
###
|
|
117
|
+
### Client → Server / 客户端发送
|
|
101
118
|
|
|
102
|
-
| type |
|
|
119
|
+
| type | Fields / 字段 | Description / 说明 |
|
|
103
120
|
|------|---------------|-------------------|
|
|
104
|
-
| `query` | `prompt: string`, `id?: string` |
|
|
105
|
-
| `ping` |
|
|
106
|
-
| `getSkills` |
|
|
121
|
+
| `query` | `prompt: string`, `session?: string`, `id?: string` | Submit a query / 发起查询 |
|
|
122
|
+
| `ping` | — | Heartbeat / 心跳 |
|
|
123
|
+
| `getSkills` | `session?: string` | Fetch skills/tools/agents / 拉取元数据 |
|
|
124
|
+
| `getStatus` | `session?: string` | Query session status / 查询状态 |
|
|
125
|
+
| `closeSession` | `session: string` | Close a session / 关闭会话 |
|
|
126
|
+
| `listSessions` | — | List all active sessions / 列出会话 |
|
|
127
|
+
|
|
128
|
+
`session` defaults to `"default"` if omitted.
|
|
107
129
|
|
|
108
130
|
```json
|
|
109
|
-
→ { "type": "query", "prompt": "
|
|
131
|
+
→ { "type": "query", "session": "tab-1", "prompt": "分析这个目录" }
|
|
110
132
|
→ { "type": "ping" }
|
|
111
|
-
→ { "type": "getSkills" }
|
|
133
|
+
→ { "type": "getSkills", "session": "tab-1" }
|
|
134
|
+
→ { "type": "getStatus", "session": "tab-1" }
|
|
135
|
+
→ { "type": "closeSession", "session": "tab-1" }
|
|
136
|
+
→ { "type": "listSessions" }
|
|
112
137
|
```
|
|
113
138
|
|
|
114
|
-
###
|
|
139
|
+
### Server → Client / 服务端发送
|
|
115
140
|
|
|
116
|
-
|
|
141
|
+
**Connection / 连接建立:**
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
← { "type": "connected", "port": 3100, "host": "MY-PC",
|
|
145
|
+
"machineId": "744e51b9-ad7d-85bb-1600-bbfb", "serverTime": 1780736149028 }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Session init (auto-push on first query per session) / 会话初始化(自动推送):**
|
|
117
149
|
|
|
118
150
|
```json
|
|
119
|
-
← { "type": "connected", "sessionId": "sess_xxx", "port": 3100 }
|
|
120
151
|
← { "type": "init", "sessionId": "sess_xxx", "model": "claude-sonnet-4-6",
|
|
121
|
-
"skills": [
|
|
152
|
+
"skills": ["browse", "code-review", ...],
|
|
153
|
+
"tools": ["Read", "Edit", "Bash", ...],
|
|
154
|
+
"slashCommands": ["code-review", "ship", ...],
|
|
155
|
+
"agents": ["Explore", "code-reviewer", ...] }
|
|
122
156
|
```
|
|
123
157
|
|
|
124
|
-
|
|
158
|
+
**Query response (streamed chunks) / 查询响应(流式块):**
|
|
125
159
|
|
|
126
160
|
```json
|
|
127
|
-
← { "type": "
|
|
128
|
-
← { "type": "
|
|
161
|
+
← { "type": "turn_start", "turn": "turn_xxx", "time": ... }
|
|
162
|
+
← { "type": "text", "content": "这是一段回复...", "time": ... }
|
|
163
|
+
← { "type": "thinking", "content": "模型思考过程...", "time": ... }
|
|
129
164
|
← { "type": "tool_use", "name": "readFile", "input": {...}, "id": "toolu_xxx" }
|
|
130
|
-
← { "type": "done", "sessionId": "sess_xxx" }
|
|
165
|
+
← { "type": "done", "sessionId": "sess_xxx", "time": ... }
|
|
131
166
|
```
|
|
132
167
|
|
|
133
|
-
|
|
168
|
+
**Other / 其他:**
|
|
134
169
|
|
|
135
170
|
```json
|
|
136
|
-
← { "type": "pong",
|
|
137
|
-
← { "type": "skills",
|
|
138
|
-
← { "type": "
|
|
171
|
+
← { "type": "pong", "sessionId": "sess_xxx", "serverTime": ... }
|
|
172
|
+
← { "type": "skills", "skills": [...], "tools": [...], ... }
|
|
173
|
+
← { "type": "status", "session": "tab-1", "sessionId": "sess_xxx", "isActive": true, "queueLength": 0, "processing": false }
|
|
174
|
+
← { "type": "session_list", "sessions": [{ "name": "tab-1", ... }, ...] }
|
|
175
|
+
← { "type": "session_closed","session": "tab-1" }
|
|
176
|
+
← { "type": "error", "content": "error message" }
|
|
139
177
|
```
|
|
140
178
|
|
|
141
|
-
###
|
|
179
|
+
### Full exchange example / 完整示例
|
|
142
180
|
|
|
143
181
|
```
|
|
144
|
-
→ { "type":
|
|
145
|
-
← { "type":
|
|
146
|
-
← { "type":
|
|
182
|
+
→ { "type":"query", "session":"tab-1", "prompt":"Hello" }
|
|
183
|
+
← { "type":"turn_start", "turn":"turn_xxx", "time":... }
|
|
184
|
+
← { "type":"text", "content":"Hello! How can I help you today?" }
|
|
185
|
+
← { "type":"done", "sessionId":"sess_abc", "time":... }
|
|
147
186
|
|
|
148
|
-
→ { "type":
|
|
149
|
-
← { "type":
|
|
187
|
+
→ { "type":"ping" }
|
|
188
|
+
← { "type":"pong", "sessionId":"sess_abc", "serverTime":... }
|
|
150
189
|
```
|
|
151
190
|
|
|
152
|
-
|
|
191
|
+
---
|
|
153
192
|
|
|
154
|
-
|
|
193
|
+
## Multi-Session Architecture / 多会话架构
|
|
155
194
|
|
|
156
195
|
```
|
|
157
|
-
|
|
158
|
-
|
|
196
|
+
nx-ce serve (single Node.js process)
|
|
197
|
+
┌───────────────────────────────────────────────────────────┐
|
|
198
|
+
│ WebSocket Server (127.0.0.1:3100) │
|
|
199
|
+
│ │
|
|
200
|
+
│ SessionManager │
|
|
201
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
202
|
+
│ │ "tab-1": { agentQuery(), messageChannel, queue } │ │
|
|
203
|
+
│ │ "tab-2": { agentQuery(), messageChannel, queue } │ │
|
|
204
|
+
│ │ "tab-3": { agentQuery(), messageChannel, queue } │ │
|
|
205
|
+
│ └──────────────────────┬──────────────────────────────┘ │
|
|
206
|
+
│ spawn each | (SDK manages CLI processes) │
|
|
207
|
+
│ Claude CLI ─────┴──── Claude CLI ───── Claude CLI │
|
|
208
|
+
└───────────────────────────────────────────────────────────┘
|
|
159
209
|
```
|
|
160
210
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
## 协议 / Protocol (stdin/stdout)
|
|
211
|
+
### Concurrency guarantees / 竞态保护
|
|
164
212
|
|
|
165
|
-
|
|
213
|
+
| Race / 竞态 | Solution / 方案 |
|
|
214
|
+
|-------------|----------------|
|
|
215
|
+
| Concurrent session creation | `_pendingCreates` Map deduplicates in-flight creation promises |
|
|
216
|
+
| SDK response routing | Each session has independent `for await` loop, writes only to `session.client` |
|
|
217
|
+
| State file overwrite | Per-session files (`{name}.json`) + write lock |
|
|
218
|
+
| Message ordering | Per-session `MonotonicClock` ensures strict time ordering |
|
|
219
|
+
| Client disconnect cleanup | Null client ref + clear queue + 5-min idle timeout auto-destroy |
|
|
166
220
|
|
|
167
|
-
|
|
168
|
-
[4 bytes LE uint32 = 负载长度 / payload length][UTF-8 JSON payload]
|
|
169
|
-
```
|
|
221
|
+
---
|
|
170
222
|
|
|
171
|
-
|
|
223
|
+
## `nx-ce status` — Instance Status / 查看实例状态
|
|
172
224
|
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
|
|
225
|
+
```bash
|
|
226
|
+
nx-ce status # List all instances
|
|
227
|
+
nx-ce status --name chat-1 # Show specific instance
|
|
176
228
|
```
|
|
177
229
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"metadata": { "skills": [...], "tools": [...], "slashCommands": [...] } }
|
|
230
|
+
```json
|
|
231
|
+
{ "name": "chat-1", "pid": 12345, "lifecycleState": "running",
|
|
232
|
+
"sessionId": "sess_abc", "model": "claude-sonnet-4-6",
|
|
233
|
+
"port": 3100, "host": "MY-PC" }
|
|
183
234
|
```
|
|
184
235
|
|
|
185
236
|
---
|
|
186
237
|
|
|
187
|
-
##
|
|
238
|
+
## `nx-ce skills` — List Available Skills / 列出可用 Skill
|
|
188
239
|
|
|
240
|
+
```bash
|
|
241
|
+
nx-ce skills --cwd "D:/project"
|
|
189
242
|
```
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{ "skills": ["code-review", "browse", ...],
|
|
246
|
+
"tools": ["Read", "Edit", "Bash", ...],
|
|
247
|
+
"slashCommands": ["code-review", ...],
|
|
248
|
+
"agents": ["Explore", ...] }
|
|
195
249
|
```
|
|
196
250
|
|
|
197
251
|
---
|
|
198
252
|
|
|
199
|
-
##
|
|
200
|
-
|
|
201
|
-
状态持久化到 `~/.nx-ce/instances/{name}.json`。
|
|
202
|
-
每个命名实例存储其 PID、会话 ID 和启动时间,用于崩溃恢复和会话续接。
|
|
253
|
+
## State Persistence / 状态持久化
|
|
203
254
|
|
|
204
|
-
|
|
255
|
+
State files at `~/.nx-ce/instances/{name}.json`:
|
|
205
256
|
|
|
206
257
|
```json
|
|
207
258
|
{
|
|
208
259
|
"name": "chat-tab-1",
|
|
209
260
|
"pid": 12345,
|
|
210
261
|
"startedAt": "2026-06-06T10:30:00.000Z",
|
|
262
|
+
"updatedAt": "2026-06-06T11:00:00.000Z",
|
|
211
263
|
"sessionId": "sess_abc123",
|
|
212
|
-
"model": "claude-sonnet-4-6"
|
|
264
|
+
"model": "claude-sonnet-4-6",
|
|
265
|
+
"host": "MY-PC",
|
|
266
|
+
"machineId": "a1b2c3d4-e5f6-...",
|
|
267
|
+
"lifecycleState": "running",
|
|
268
|
+
"port": 3100,
|
|
269
|
+
"usage": { "inputTokens": 1500, "outputTokens": 3200, ... }
|
|
213
270
|
}
|
|
214
271
|
```
|
|
215
272
|
|
|
273
|
+
| lifecycleState | Meaning / 含义 |
|
|
274
|
+
|----------------|----------------|
|
|
275
|
+
| `running` | Normal operation / 正常运行 |
|
|
276
|
+
| `stopped` | Clean shutdown / 正常关闭 |
|
|
277
|
+
| `crashed` | Unexpected exit / 异常退出 |
|
|
278
|
+
| `resuming` | Session recovery in progress / 恢复中 |
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Architecture / 架构
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
Chrome Extension / 浏览器扩展
|
|
286
|
+
↕ WebSocket (ws://127.0.0.1:3100)
|
|
287
|
+
nx-ce serve (Node.js)
|
|
288
|
+
├─ SessionManager → agentQuery()
|
|
289
|
+
│ ↕
|
|
290
|
+
│ Claude CLI
|
|
291
|
+
│
|
|
292
|
+
└─ (Native Host via exec.Command → nx-ce query --resume)
|
|
293
|
+
```
|
|
294
|
+
|
|
216
295
|
---
|
|
217
296
|
|
|
218
|
-
##
|
|
297
|
+
## Development / 开发
|
|
219
298
|
|
|
220
299
|
```bash
|
|
221
|
-
#
|
|
300
|
+
# One-shot query
|
|
222
301
|
node ./bin/nx-ce.js query "你好"
|
|
223
302
|
|
|
224
|
-
#
|
|
303
|
+
# Start server
|
|
225
304
|
node ./bin/nx-ce.js serve --port 3100
|
|
226
305
|
|
|
227
|
-
#
|
|
306
|
+
# Run tests (in another terminal)
|
|
307
|
+
node test/serve-test.mjs
|
|
308
|
+
|
|
309
|
+
# Syntax check
|
|
228
310
|
node -c src/*.js
|
|
229
311
|
```
|
|
230
312
|
|
|
231
313
|
---
|
|
232
314
|
|
|
233
|
-
##
|
|
315
|
+
## Test / 测试
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Terminal 1: start server
|
|
319
|
+
node bin/nx-ce.js serve --port 3100
|
|
320
|
+
|
|
321
|
+
# Terminal 2: run tests
|
|
322
|
+
node test/serve-test.mjs
|
|
323
|
+
|
|
324
|
+
# Expected output:
|
|
325
|
+
# PASS: 14 FAIL: 0
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Tests cover: connection, ping/pong, single-session query, multi-session isolation, 3 concurrent sessions, long conversation resume, listSessions, closeSession, getSkills, getStatus.
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## License
|
|
234
333
|
|
|
235
334
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nx-ce",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Claude Engine — SDK adapter layer for native messaging host. Bridges @anthropic-ai/claude-agent-sdk calls over a length-prefixed JSON protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|