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.
Files changed (2) hide show
  1. package/README.md +210 -111
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -3,233 +3,332 @@
3
3
  [![npm version](https://img.shields.io/npm/v/nx-ce)](https://www.npmjs.com/package/nx-ce)
4
4
  [![CI](https://github.com/joke-lx/nx-ce/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/joke-lx/nx-ce/actions/workflows/npm-publish.yml)
5
5
 
6
- **nx-ce** 是一个轻量级 Node.js 适配器,封装了 `@anthropic-ai/claude-agent-sdk`。
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
- **nx-ce** is a lightweight Node.js adapter for `@anthropic-ai/claude-agent-sdk`.
11
- It exposes the SDK via a WebSocket server or stdin/stdout protocol,
12
- supporting both one-shot cold-start queries and persistent server sessions.
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
- ## 项目家族 / Family
16
+ ## Family / 项目家族
17
17
 
18
- | Package | 角色 / Role |
18
+ | Package | Role / 角色 |
19
19
  |---------|-------------|
20
- | **nx-ce** | Claude Engine — SDK 适配层 / SDK adapter layer |
21
- | [nx-sx](https://github.com/jokelx/nx-sx) | Sandbox eXecution — 窗口/终端管理器 / window & terminal manager |
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
- ## 安装 / Install
25
+ ## Install / 安装
26
26
 
27
27
  ```bash
28
28
  npm install nx-ce
29
- # 或全局安装 / or install globally
29
+ # or globally
30
30
  npm install -g nx-ce
31
31
  ```
32
32
 
33
33
  ---
34
34
 
35
- ## 命令行用法 / CLI Usage
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
- ### `nx-ce query <prompt>` 一次性冷启动查询 / One-shot cold-start query
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
- | 选项 / Flag | 说明 / Description |
48
- |-------------|-------------------|
49
- | `--model <id>` | 模型 ID 覆盖(默认 `claude-sonnet-4-6`)/ Model override |
50
- | `--claude-path <path>` | Claude CLI 可执行文件路径 / Path to Claude CLI binary |
51
- | `--system-prompt <text>` | 系统提示词覆盖 / System prompt override |
52
- | `--resume <sessionId>` | 续接之前的会话(长对话)/ Resume a prior session |
53
- | `--skill <name>[,<name>...]` | 加载指定 Skill(逗号分隔,传 `all` 加载全部)/ Load specific skills |
54
- | `--include-metadata` | 输出中附带 skills/tools/slash_commands 信息 / Include skill/tool metadata in output |
55
- | `--no-persist` | 不持久化会话 / Don't persist session |
56
- | `--env "KEY=value,KEY2=val"` | 额外环境变量 / Extra environment variables |
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
- ### `nx-ce serve` — WebSocket 持久化服务器 / WebSocket server
69
+ ### JSON output
59
70
 
60
- 单例进程,多客户端共享一个 SDK 会话,请求排队处理。
61
- Single process with multi-client support and FIFO query queue.
71
+ ```json
72
+ // Default
73
+ { "text": "2", "sessionId": "sess_abc" }
62
74
 
63
- ```bash
64
- nx-ce serve # 默认端口 3100
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
- | 选项 / Flag | 说明 / Description |
70
- |-------------|-------------------|
71
- | `--name <name>` | 实例名称(默认 `"default"`)/ Instance name |
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
- > WebSocket 地址: `ws://127.0.0.1:3100`
83
+ **Single process. Multiple concurrent sessions. FIFO queries per session.**
78
84
 
79
- ### `nx-ce status` — 查看实例状态 / Show instance state
85
+ 单例进程。多会话隔离。每个会话独立 SDK agentQuery,互不阻塞。
80
86
 
81
87
  ```bash
82
- nx-ce status # 列出所有实例 / List all instances
83
- nx-ce status --name chat-tab-1 # 查看指定实例 / Show specific instance
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
- ### `nx-ce help` 显示帮助 / Show help
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 help
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 协议 / WebSocket Protocol
95
-
96
- 服务端地址 `ws://127.0.0.1:PORT`(默认 3100)。所有消息均为 JSON 字符串(不含长度前缀)。
113
+ ## WebSocket Protocol / WebSocket 协议
97
114
 
98
- Server at `ws://127.0.0.1:PORT` (default 3100). All messages are JSON strings (no length prefix).
115
+ Server: `ws://127.0.0.1:PORT`. All messages are JSON (no length prefix).
99
116
 
100
- ### 客户端发送 / Client → Server
117
+ ### Client → Server / 客户端发送
101
118
 
102
- | type | 字段 / Fields | 说明 / Description |
119
+ | type | Fields / 字段 | Description / 说明 |
103
120
  |------|---------------|-------------------|
104
- | `query` | `prompt: string`, `id?: string` | 发起查询 / Submit a query |
105
- | `ping` | | 心跳检测 / Heartbeat |
106
- | `getSkills` | | 拉取技能/工具列表 / Fetch skills & tools |
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
- ### 服务端发送 / Server → Client
139
+ ### Server → Client / 服务端发送
115
140
 
116
- **连接建立 / On connect:**
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": [...], "tools": [...], "slashCommands": [...], "agents": [...] }
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
- **查询响应 / Query response (streamed chunks):**
158
+ **Query response (streamed chunks) / 查询响应(流式块):**
125
159
 
126
160
  ```json
127
- ← { "type": "text", "content": "这是一段回复..." }
128
- ← { "type": "thinking", "content": "模型思考过程..." }
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
- **其他 / Other:**
168
+ **Other / 其他:**
134
169
 
135
170
  ```json
136
- ← { "type": "pong", "sessionId": "sess_xxx" }
137
- ← { "type": "skills", "skills": [...], "tools": [...], "slashCommands": [...], "agents": [...] }
138
- ← { "type": "error", "content": "error message" }
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
- ### 完整示例 / Full exchange
179
+ ### Full exchange example / 完整示例
142
180
 
143
181
  ```
144
- → { "type": "query", "prompt": "Hello" }
145
- ← { "type": "text", "content": "Hello! How can I help you today?" }
146
- ← { "type": "done", "sessionId": "sess_abc123" }
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": "ping" }
149
- ← { "type": "pong", "sessionId": "sess_abc123" }
187
+ → { "type":"ping" }
188
+ ← { "type":"pong", "sessionId":"sess_abc", "serverTime":... }
150
189
  ```
151
190
 
152
- ### 单例机制 / Singleton guarantee
191
+ ---
153
192
 
154
- 重复启动 `nx-ce serve` 会在同一端口上失败:
193
+ ## Multi-Session Architecture / 多会话架构
155
194
 
156
195
  ```
157
- 端口 3100 已被占用 nx-ce 单例进程已在运行中
158
- Port 3100 already in use — another nx-ce instance is running
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
- `nx-ce query` 子命令仍使用长度前缀 JSON(Chrome Native Messaging 格式):
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
- ### 查询(一次性)/ Query (one-shot)
223
+ ## `nx-ce status` — Instance Status / 查看实例状态
172
224
 
173
- ```
174
- { "prompt": "...", "model": "...", "systemPrompt": "..." }
175
- { "text": "...", "sessionId": "sess_xxx" }
225
+ ```bash
226
+ nx-ce status # List all instances
227
+ nx-ce status --name chat-1 # Show specific instance
176
228
  ```
177
229
 
178
- ### 带元数据输出 / With metadata
179
-
180
- ```
181
- ← { "text": "...", "sessionId": "sess_xxx",
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
- ## 架构 / Architecture
238
+ ## `nx-ce skills` — List Available Skills / 列出可用 Skill
188
239
 
240
+ ```bash
241
+ nx-ce skills --cwd "D:/project"
189
242
  ```
190
- Chrome Extension / 浏览器扩展
191
- ↕ WebSocket (ws://127.0.0.1:3100)
192
- nx-ce serve (Node.js) ← 单例进程 / singleton process
193
- @anthropic-ai/claude-agent-sdk
194
- Claude Code CLI (子进程 / subprocess)
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
- ## 状态持久化 / State
200
-
201
- 状态持久化到 `~/.nx-ce/instances/{name}.json`。
202
- 每个命名实例存储其 PID、会话 ID 和启动时间,用于崩溃恢复和会话续接。
253
+ ## State Persistence / 状态持久化
203
254
 
204
- Persisted to `~/.nx-ce/instances/{name}.json`. Each named instance stores its PID, session ID, and start time for crash recovery and session resumption.
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
- ## 开发 / Development
297
+ ## Development / 开发
219
298
 
220
299
  ```bash
221
- # 本地运行一次查询 / Run a one-shot query
300
+ # One-shot query
222
301
  node ./bin/nx-ce.js query "你好"
223
302
 
224
- # 启动 WebSocket 服务 / Start WebSocket server
303
+ # Start server
225
304
  node ./bin/nx-ce.js serve --port 3100
226
305
 
227
- # 检查语法 / Check syntax
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
- ## License / 许可证
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.4",
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",