nx-ce 0.1.3 → 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 +232 -94
- package/package.json +3 -2
- package/src/cli.js +4 -2
- package/src/index.js +9 -1
- package/src/serve.js +553 -198
- package/src/session-store.js +56 -2
- package/src/util.js +124 -0
package/README.md
CHANGED
|
@@ -3,194 +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 协议(与 Chrome Native Messaging 格式一致)在 stdin/stdout 上暴露 SDK 接口,
|
|
8
|
-
支持一次性冷启动查询与持久化服务两种运行模式。
|
|
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
|
|
36
40
|
|
|
37
|
-
|
|
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
|
+
---
|
|
48
|
+
|
|
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
|
-
|
|
62
|
-
|
|
71
|
+
```json
|
|
72
|
+
// Default
|
|
73
|
+
{ "text": "2", "sessionId": "sess_abc" }
|
|
74
|
+
|
|
75
|
+
// With --include-metadata
|
|
76
|
+
{ "text": "2", "sessionId": "sess_abc", "metadata": { "skills": [...], "tools": [...], ... } }
|
|
63
77
|
```
|
|
64
78
|
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## `nx-ce serve` — WebSocket Multi-Session Server / WebSocket 多会话服务器
|
|
67
82
|
|
|
68
|
-
|
|
69
|
-
|-------------|-------------------|
|
|
70
|
-
| `--name <name>` | 实例名称(默认 `"default"`)/ Instance name |
|
|
71
|
-
| `--model <id>` | 模型 ID 覆盖 / Model override |
|
|
72
|
-
| `--claude-path <path>` | Claude CLI 可执行文件路径 / Path to Claude CLI binary |
|
|
73
|
-
| `--env "KEY=value,..."` | 额外环境变量 / Extra environment variables |
|
|
83
|
+
**Single process. Multiple concurrent sessions. FIFO queries per session.**
|
|
74
84
|
|
|
75
|
-
|
|
85
|
+
单例进程。多会话隔离。每个会话独立 SDK agentQuery,互不阻塞。
|
|
76
86
|
|
|
77
87
|
```bash
|
|
78
|
-
nx-ce
|
|
79
|
-
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"
|
|
80
91
|
```
|
|
81
92
|
|
|
82
|
-
|
|
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 / 单例保证
|
|
83
105
|
|
|
84
106
|
```bash
|
|
85
|
-
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
|
|
86
109
|
```
|
|
87
110
|
|
|
88
111
|
---
|
|
89
112
|
|
|
90
|
-
##
|
|
113
|
+
## WebSocket Protocol / WebSocket 协议
|
|
114
|
+
|
|
115
|
+
Server: `ws://127.0.0.1:PORT`. All messages are JSON (no length prefix).
|
|
116
|
+
|
|
117
|
+
### Client → Server / 客户端发送
|
|
91
118
|
|
|
92
|
-
|
|
119
|
+
| type | Fields / 字段 | Description / 说明 |
|
|
120
|
+
|------|---------------|-------------------|
|
|
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 / 列出会话 |
|
|
93
127
|
|
|
94
|
-
|
|
128
|
+
`session` defaults to `"default"` if omitted.
|
|
95
129
|
|
|
130
|
+
```json
|
|
131
|
+
→ { "type": "query", "session": "tab-1", "prompt": "分析这个目录" }
|
|
132
|
+
→ { "type": "ping" }
|
|
133
|
+
→ { "type": "getSkills", "session": "tab-1" }
|
|
134
|
+
→ { "type": "getStatus", "session": "tab-1" }
|
|
135
|
+
→ { "type": "closeSession", "session": "tab-1" }
|
|
136
|
+
→ { "type": "listSessions" }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Server → Client / 服务端发送
|
|
140
|
+
|
|
141
|
+
**Connection / 连接建立:**
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
← { "type": "connected", "port": 3100, "host": "MY-PC",
|
|
145
|
+
"machineId": "744e51b9-ad7d-85bb-1600-bbfb", "serverTime": 1780736149028 }
|
|
96
146
|
```
|
|
97
|
-
|
|
147
|
+
|
|
148
|
+
**Session init (auto-push on first query per session) / 会话初始化(自动推送):**
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
← { "type": "init", "sessionId": "sess_xxx", "model": "claude-sonnet-4-6",
|
|
152
|
+
"skills": ["browse", "code-review", ...],
|
|
153
|
+
"tools": ["Read", "Edit", "Bash", ...],
|
|
154
|
+
"slashCommands": ["code-review", "ship", ...],
|
|
155
|
+
"agents": ["Explore", "code-reviewer", ...] }
|
|
98
156
|
```
|
|
99
157
|
|
|
100
|
-
|
|
158
|
+
**Query response (streamed chunks) / 查询响应(流式块):**
|
|
101
159
|
|
|
160
|
+
```json
|
|
161
|
+
← { "type": "turn_start", "turn": "turn_xxx", "time": ... }
|
|
162
|
+
← { "type": "text", "content": "这是一段回复...", "time": ... }
|
|
163
|
+
← { "type": "thinking", "content": "模型思考过程...", "time": ... }
|
|
164
|
+
← { "type": "tool_use", "name": "readFile", "input": {...}, "id": "toolu_xxx" }
|
|
165
|
+
← { "type": "done", "sessionId": "sess_xxx", "time": ... }
|
|
102
166
|
```
|
|
103
|
-
→ { "prompt": "...", "model": "...", "systemPrompt": "..." }
|
|
104
|
-
← { "text": "...", "sessionId": "sess_xxx" }
|
|
105
167
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
168
|
+
**Other / 其他:**
|
|
169
|
+
|
|
170
|
+
```json
|
|
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" }
|
|
109
177
|
```
|
|
110
178
|
|
|
111
|
-
###
|
|
179
|
+
### Full exchange example / 完整示例
|
|
112
180
|
|
|
113
181
|
```
|
|
114
|
-
→ { "
|
|
115
|
-
← { "
|
|
116
|
-
← { "
|
|
117
|
-
← { "
|
|
118
|
-
← { "id":"1", "type":"done", "sessionId":"..." }
|
|
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":... }
|
|
119
186
|
|
|
120
187
|
→ { "type":"ping" }
|
|
121
|
-
← { "type":"pong",
|
|
188
|
+
← { "type":"pong", "sessionId":"sess_abc", "serverTime":... }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
122
192
|
|
|
123
|
-
|
|
124
|
-
← { "type":"skills", "skills":["browse",...], "tools":["Read",...], "slashCommands":[...], "agents":[...] }
|
|
193
|
+
## Multi-Session Architecture / 多会话架构
|
|
125
194
|
|
|
126
|
-
|
|
127
|
-
|
|
195
|
+
```
|
|
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
|
+
└───────────────────────────────────────────────────────────┘
|
|
128
209
|
```
|
|
129
210
|
|
|
130
|
-
|
|
211
|
+
### Concurrency guarantees / 竞态保护
|
|
131
212
|
|
|
132
|
-
|
|
|
133
|
-
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
| ← | `error` | 错误消息 / Error message |
|
|
140
|
-
| → | `ping` | 心跳检测 / Heartbeat |
|
|
141
|
-
| ← | `pong` | 心跳回复 / Heartbeat response |
|
|
142
|
-
| → | `getSkills` | Go 端按需拉取技能/工具列表 / Fetch skills/tools list |
|
|
143
|
-
| ← | `init` / `skills` | 技能列表回复 / Skills metadata response |
|
|
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 |
|
|
144
220
|
|
|
145
221
|
---
|
|
146
222
|
|
|
147
|
-
##
|
|
223
|
+
## `nx-ce status` — Instance Status / 查看实例状态
|
|
148
224
|
|
|
225
|
+
```bash
|
|
226
|
+
nx-ce status # List all instances
|
|
227
|
+
nx-ce status --name chat-1 # Show specific instance
|
|
149
228
|
```
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
↕ @anthropic-ai/claude-agent-sdk
|
|
156
|
-
Claude Code CLI (子进程 / subprocess)
|
|
229
|
+
|
|
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" }
|
|
157
234
|
```
|
|
158
235
|
|
|
159
236
|
---
|
|
160
237
|
|
|
161
|
-
##
|
|
238
|
+
## `nx-ce skills` — List Available Skills / 列出可用 Skill
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
nx-ce skills --cwd "D:/project"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{ "skills": ["code-review", "browse", ...],
|
|
246
|
+
"tools": ["Read", "Edit", "Bash", ...],
|
|
247
|
+
"slashCommands": ["code-review", ...],
|
|
248
|
+
"agents": ["Explore", ...] }
|
|
249
|
+
```
|
|
162
250
|
|
|
163
|
-
|
|
164
|
-
每个命名实例存储其 PID、会话 ID 和启动时间,用于崩溃恢复和会话续接。
|
|
251
|
+
---
|
|
165
252
|
|
|
166
|
-
|
|
253
|
+
## State Persistence / 状态持久化
|
|
167
254
|
|
|
168
|
-
|
|
255
|
+
State files at `~/.nx-ce/instances/{name}.json`:
|
|
169
256
|
|
|
170
257
|
```json
|
|
171
258
|
{
|
|
172
259
|
"name": "chat-tab-1",
|
|
173
260
|
"pid": 12345,
|
|
174
261
|
"startedAt": "2026-06-06T10:30:00.000Z",
|
|
262
|
+
"updatedAt": "2026-06-06T11:00:00.000Z",
|
|
175
263
|
"sessionId": "sess_abc123",
|
|
176
|
-
"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, ... }
|
|
177
270
|
}
|
|
178
271
|
```
|
|
179
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
|
+
|
|
180
295
|
---
|
|
181
296
|
|
|
182
|
-
##
|
|
297
|
+
## Development / 开发
|
|
183
298
|
|
|
184
299
|
```bash
|
|
185
|
-
#
|
|
300
|
+
# One-shot query
|
|
186
301
|
node ./bin/nx-ce.js query "你好"
|
|
187
302
|
|
|
188
|
-
#
|
|
303
|
+
# Start server
|
|
304
|
+
node ./bin/nx-ce.js serve --port 3100
|
|
305
|
+
|
|
306
|
+
# Run tests (in another terminal)
|
|
307
|
+
node test/serve-test.mjs
|
|
308
|
+
|
|
309
|
+
# Syntax check
|
|
189
310
|
node -c src/*.js
|
|
190
311
|
```
|
|
191
312
|
|
|
192
313
|
---
|
|
193
314
|
|
|
194
|
-
##
|
|
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
|
|
195
333
|
|
|
196
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",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
],
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.159"
|
|
33
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.159",
|
|
34
|
+
"ws": "^8.21.0"
|
|
34
35
|
}
|
|
35
36
|
}
|
package/src/cli.js
CHANGED
|
@@ -83,7 +83,7 @@ export async function runCli() {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
case 'serve': {
|
|
86
|
-
// 持久化服务模式
|
|
86
|
+
// WebSocket 持久化服务模式
|
|
87
87
|
const name = flags.name || 'default';
|
|
88
88
|
|
|
89
89
|
const result = await startServe({
|
|
@@ -92,6 +92,7 @@ export async function runCli() {
|
|
|
92
92
|
model: flags.model,
|
|
93
93
|
cwd: flags.cwd || process.cwd(),
|
|
94
94
|
env: flags.env ? parseEnvString(flags.env) : undefined,
|
|
95
|
+
port: flags.port ? parseInt(flags.port, 10) : undefined,
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
return result;
|
|
@@ -132,8 +133,9 @@ export async function runCli() {
|
|
|
132
133
|
--no-persist 不持久化会话
|
|
133
134
|
--env "KEY=value,KEY2=val" 额外环境变量
|
|
134
135
|
|
|
135
|
-
nx-ce serve
|
|
136
|
+
nx-ce serve WebSocket 持久化服务器(单一进程 / 多客户端)
|
|
136
137
|
--name <name> 实例名称(默认: "default")
|
|
138
|
+
--port <port> WebSocket 端口(默认: 3100)
|
|
137
139
|
--model <id> 模型覆盖
|
|
138
140
|
--claude-path <path> Claude CLI 路径
|
|
139
141
|
--env "KEY=value,..." 额外环境变量
|
package/src/index.js
CHANGED
|
@@ -8,5 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
export { runQuery } from './query.js';
|
|
10
10
|
export { listSkills } from './skills.js';
|
|
11
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
readState,
|
|
13
|
+
writeState,
|
|
14
|
+
deleteState,
|
|
15
|
+
listStates,
|
|
16
|
+
LifecycleState,
|
|
17
|
+
createState,
|
|
18
|
+
} from './session-store.js';
|
|
12
19
|
export { readMessage, writeMessage } from './protocol.js';
|
|
20
|
+
export { generateId, MonotonicClock, getMachineId, formatBytes } from './util.js';
|