@zonease/aiworker-cli 0.2.1 → 0.3.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.
package/README.md CHANGED
@@ -1,184 +1,173 @@
1
1
  # AIWorker
2
2
 
3
- 自托管 Agent Runtime — 由 **Brain provider**(知识 / 记忆 / 技能)与 **Executor provider**(OpenAI 兼容 chat completions + tool calling)组合而成。
3
+ 自托管 Agent Runtime — 由 **Brain provider**(知识 / 记忆 / 技能)与 **Executor provider**(OpenAI 兼容 / claude-code / codex / gemini-cli / qwen-code / cursor / MCP)组合而成。
4
4
 
5
- 工作站、服务器、k8s pod、docker container 都能跑成一个 worker 加入同一个 fleet。Operator 通过一个 CLI 控制所有 worker。
5
+ 工作站、服务器、k8s pod、docker container 都能跑成一个 worker 加入同一个 fleet。Operator 用一个 CLI 控制所有 worker。
6
6
 
7
7
  ## Features
8
8
 
9
- - **4 种入网路径**:手动 pair、docker auto-launch、自助 self-enroll(unattended)、**OTP-attended enrollment(worker deployer 零凭证)**
10
- - **WS 控制面**:operator worker 共享同一 gateway 入口,按 path 分流
11
- - **多 LLM engine**:`http`(OpenAI / DeepSeek / SiliconFlow 等)/ `claude-code` / `codex` / `gemini-cli` / `qwen-code` / `cursor` / `mcp`
12
- - **多 channel**:Telegram / WhatsApp / Lark / LINE / Web 五种 webhook adapter,全部强制验签
13
- - **Cron / per-tool approvals / hot-reload / fallback chain** 全部内建
14
- - **数据物理隔离**:fleet.db(gateway)与 worker.db(每 worker)AES-256-GCM 各自加密,丢失 master key = 全部失联
15
- - **三档部署**:裸跑(开发)/ systemd(推荐 Linux)/ docker compose(fast-launch)
9
+ - **4 种入网路径**:OTP-attended(worker deployer 零凭证)/ self-enroll(unattended 批量)/ 手动 pair / docker auto-launch
10
+ - **WS 控制面**:operator + worker 共享同一 gateway 入口,按 path 分流(`/ws` basicauth + `/enroll-ws` OTP 专用)
11
+ - **多 LLM engine**:`http` (OpenAI / DeepSeek / SiliconFlow / 任意 OpenAI 兼容) / `claude-code` / `codex` / `acp` (gemini / qwen) / `cursor` / `mcp`
12
+ - **多 channel webhook**:Telegram / WhatsApp / Lark / LINE / Web,全部强制验签
13
+ - **Cron / per-tool approvals / hot-reload / fallback chain** 内建
14
+ - **数据物理隔离**:fleet.db(gateway)与 worker.db(每 worker)AES-256-GCM 各自加密
15
+ - **三档部署**:裸跑 / systemd / docker compose
16
16
 
17
- ## Architecture
17
+ ---
18
18
 
19
- ```
20
- operator ─basicauth─► /ws ──────► gateway
21
- worker ─无凭证─────► /enroll-ws ──────► gateway (OTP enrollment 专用)
22
-
23
-
24
- fleet.db
25
-
26
- outbound WS
27
-
28
- worker process(es)
29
-
30
-
31
- worker.db + LLM engine
32
- ```
19
+ ## 🚀 30 秒 demo
33
20
 
34
- 详见 [`docs/architecture.md`](docs/architecture.md)。
21
+ **目标**:本机起一个 worker,加入远端 gateway,发一条消息让 worker 用 LLM 回。
35
22
 
36
- ## Stack
23
+ ```
24
+ ┌──────────────────────────┐ OTP enroll ┌──────────────────────────┐
25
+ │ 你的工作站 │ wss://<gateway>/ │ 远端 gateway │
26
+ │ │ /enroll-ws │ │
27
+ │ aiworker serve │ ───────────────────────► │ /root/.bun/bin/aiworker │
28
+ │ (workerId 自动 mint) │ │ gateway start (systemd) │
29
+ │ listening :9217 │ ◄─────── OTP YDCR-ZD8M ──│ │
30
+ │ │ │ fleet.db │
31
+ └──────────┬───────────────┘ └─────┬────────────────────┘
32
+ │ │
33
+ │ ┌─────────────────────────────────────────────┴──┐
34
+ │ │ Step 4: operator 在 gateway 同机 loopback │
35
+ │ │ ws://127.0.0.1:9218/ws (空 token bypass) │
36
+ │ │ $ aiworker enroll list │
37
+ │ │ $ aiworker enroll approve YDCR-ZD8M │
38
+ │ └─────────────────────────────────────────────┬──┘
39
+ │ │
40
+ │ ◄─────── enrollment.approved (deviceToken) ────┤
41
+ │ worker.online=true 写 fleet.db │
42
+ │ │
43
+ │ Step 6: chat (operator → gateway → worker) │
44
+ │ ◄─────── chat.send 'hello' ────────────────────┤
45
+ │ orchestrator → executor (claude-code) │
46
+ │ orchestrator → ... → done │
47
+ ├───── chat.message echo ──────────────────────► │
48
+ ▼ ▼
49
+ pkill / SIGTERM fleet.db 持久化
50
+ ```
37
51
 
38
- - Bun workspaces (monorepo: `apps/api` + `apps/cli` + `apps/gateway` + `apps/web` + 7 个 packages)
39
- - Hono OpenAPIHono / Bun.serve / Drizzle ORM / SQLite / Zod / consola
40
- - React 19 + TanStack Router/Query + shadcn/ui + Tailwind v4(web SPA)
52
+ **Worker 端**(你的工作站,零 fleet 凭证):
41
53
 
42
- ---
54
+ ```sh
55
+ bun install -g @zonease/aiworker-cli # 或 npm install -g
43
56
 
44
- ## Install
57
+ export AIWORKER_GATEWAY_URL='wss://your-gateway.example/'
58
+ export AIWORKER_DISPLAY_NAME='my-laptop'
59
+ aiworker serve
60
+ ```
45
61
 
46
- ### Published
62
+ 输出:
47
63
 
48
- ```sh
49
- bun install -g @zonease/aiworker-cli
50
- # 或 npm install -g @zonease/aiworker-cli
51
- # 或从 GitHub Releases 下载单文件 binary(无依赖):
52
- # curl -fsSL https://github.com/ZonEaseTech/aiworker/releases/latest/download/aiworker-linux-x64 -o /usr/local/bin/aiworker
53
- # chmod +x /usr/local/bin/aiworker
54
-
55
- aiworker init # 首次 mint master key 写到 ~/.aiworker/.env
56
- aiworker serve # 默认监听 :9217
57
- aiworker fleet list
58
- aiworker chat <workerId> 'hello'
64
+ ```
65
+ ┌────────────────────────────────────────────────────────────────────────────┐
66
+ │ ⚠️ AIWORKER first-run setup │
67
+ │ AIWORKER_MASTER_KEY (写入 ~/.aiworker/.env, chmod 0600) │
68
+ │ <64 hex chars 离线备份> │
69
+ └────────────────────────────────────────────────────────────────────────────┘
70
+ [worker] id=w_ntssfzwwzzq0
71
+ [worker] AIWORKER_BOOTSTRAP_TOKEN=wtk_VhW4ea1JrfCJFdSQ...
72
+ √ [aiworker serve] worker listening on :9217 (config v1)
73
+ i [aiworker serve] OTP enrolling to wss://your-gateway.example/enroll-ws
74
+ ┌─────────────────────┐
75
+ │ OTP: YDCR-ZD8M │
76
+ │ expires in 300s │
77
+ └─────────────────────┘
59
78
  ```
60
79
 
61
- ### 本地开发
80
+ **Operator 端**(gateway 主机或 basicauth 远端):
62
81
 
63
82
  ```sh
64
- git clone <repo-url>
65
- cd aiworker && bun install
66
- bun apps/cli/src/aiworker.ts <subcmd>
83
+ aiworker enroll list # 看 pending OTP
84
+ aiworker enroll approve YDCR-ZD8M # ✔ 已批准
85
+ aiworker fleet list # online: true
86
+ aiworker chat w_ntssfzwwzzq0 'hello' # NDJSON 流式输出
67
87
  ```
68
88
 
69
- 下面的 Quickstart / cheat sheet 默认用 `aiworker ...`(已发布命令);本地开发态等价 `bun apps/cli/src/aiworker.ts ...`。
89
+ 完整端到端实测见 [docs/changelog.md](docs/changelog.md) 11:50 条目。
70
90
 
71
91
  ---
72
92
 
73
- ## Quickstart
93
+ ## Install
74
94
 
75
- ### 角色
95
+ ### 已发布
76
96
 
77
- ```
78
- operator ─── basicauth + aiworker CLI ─── fleet
79
- worker deployer ─── 跑 aiworker serve ────────── 加入 fleet 后等指令
97
+ ```sh
98
+ bun install -g @zonease/aiworker-cli # 当前 latest 0.2.1(含 in-process gateway / OTP enroll / 6 LLM engine)
99
+ #
100
+ npm install -g @zonease/aiworker-cli
80
101
  ```
81
102
 
82
- ### 选哪种 enrollment?
103
+ binary 跑在 `~/.bun/bin/aiworker` 或 `$(npm bin -g)/aiworker`。第一次跑任意命令时自动 mint master key 写到 `~/.aiworker/.env`(chmod 0600)。
83
104
 
84
- | 场景 | 用 | 一句话 |
85
- |---|---|---|
86
- | 朋友/客户/CI 临时装 worker | **OTP(推荐)** | worker deployer **零凭证**,operator 看 8 字符 OTP 后 approve |
87
- | k8s/docker compose 批量 unattended | self-enroll | env 配 `AIWORKER_JOIN_TOKEN` 自动入网 |
88
- | 高安全单 worker 手动 | 手动 pair | `aiworker pair --bootstrap-token wtk_...` |
89
- | docker fast-launch(gateway 同机) | `aiworker fleet launch` | gateway supervisor 自己拉容器 |
105
+ ### 本地开发
90
106
 
91
- ---
107
+ ```sh
108
+ git clone https://github.com/ZonEaseTech/aiworker
109
+ cd aiworker && bun install
110
+ bun apps/cli/src/aiworker.ts <subcmd> # = aiworker <subcmd>
111
+ ```
92
112
 
93
- ## 路径 1:OTP 入网(最简)
113
+ 下面所有 `aiworker ...` 命令在本地开发态等价 `bun apps/cli/src/aiworker.ts ...`。
94
114
 
95
- ### Worker deployer(任何机器,**零 fleet 凭证 + 零本地 secret 输入**)
115
+ ---
96
116
 
97
- ```sh
98
- # 1. 装 bun(如果没装)
99
- curl -fsSL https://bun.sh/install | bash
117
+ ## 4 种入网路径
100
118
 
101
- # 2. aiworker CLI
102
- bun install -g @zonease/aiworker-cli
103
- # npm install -g @zonease/aiworker-cli
119
+ | 场景 | | Worker 端凭证 | Operator 介入 |
120
+ |---|---|---|---|
121
+ | 朋友/客户/CI 临时装 worker | **OTP(推荐)** | 零(worker 不持任何 fleet 共享 secret) | 看 8 字符 OTP → approve |
122
+ | k8s/docker compose 批量 unattended | self-enroll | `AIWORKER_JOIN_TOKEN`(fleet 共享) | 无(自动入网) |
123
+ | 高安全单 worker 手动 | 手动 pair | worker 启动后输出 `wtk_xxx` bootstrap token | `aiworker pair --bootstrap-token wtk_...` |
124
+ | docker fast-launch(gateway 同机) | `aiworker fleet launch` | gateway 自动注入 | 一行命令 |
104
125
 
105
- # 3. 第一次 init —— 自动 mint master key 写到 ~/.aiworker/.env (chmod 600),
106
- # 控制台显示**一次**,请离线备份。
107
- aiworker init
126
+ ### OTP(推荐)
108
127
 
109
- # 4. 启动 worker,指向你的 gateway(默认监听 :9217)
110
- export AIWORKER_GATEWAY_URL="wss://your-gateway.example/"
111
- export AIWORKER_DISPLAY_NAME="my-laptop" # 可选;默认取 hostname
128
+ Worker:
129
+ ```sh
130
+ export AIWORKER_GATEWAY_URL='wss://your-gateway.example/'
131
+ export AIWORKER_DISPLAY_NAME='my-laptop' # 可选,默认 hostname
112
132
  aiworker serve
113
133
  ```
114
134
 
115
- 控制台输出:
116
-
117
- ```
118
- i [aiworker serve] OTP enrolling to wss://your-gateway.example/enroll-ws; awaiting operator approval
119
- ┌─────────────────────┐
120
- │ OTP: 9CDT-94BK │
121
- │ expires in 300s │
122
- └─────────────────────┘
123
- ```
124
-
125
- 把 OTP 报给 operator。
126
-
127
- ### Operator
128
-
135
+ Operator:
129
136
  ```sh
130
- aiworker enroll list
131
- # {"pending":[{"otp":"9CDT-94BK","displayName":"my-laptop",...}]}
132
-
133
- aiworker enroll approve 9CDT-94BK
134
- # ✔ 已批准
135
-
136
- aiworker fleet list
137
- # {"workers":[{"workerId":"w_xxx","displayName":"my-laptop","online":true,...}]}
137
+ aiworker enroll list # → pending [{ otp, workerId, displayName }]
138
+ aiworker enroll approve <OTP>
138
139
  ```
139
140
 
140
- worker 端同步打:`√ approved as w_xxx; deviceToken=wtk_...,已加入 fleet`。
141
-
142
- ---
143
-
144
- ## 路径 2:self-enroll(自动化批量)
145
-
146
- Worker 端 env 多两个,省去 operator approve:
141
+ ### self-enroll(自动化)
147
142
 
143
+ Worker:
148
144
  ```sh
149
- export AIWORKER_GATEWAY_URL="wss://operator:<basicauth-pwd>@your-gateway.example/ws"
150
- export AIWORKER_JOIN_TOKEN="<gateway 端配的 join token>"
151
- export AIWORKER_DISPLAY_NAME="ci-runner-12"
152
-
153
- bun apps/cli/src/aiworker.ts init
154
- bun apps/cli/src/aiworker.ts serve --port 9217
155
- # 自动加入;operator 端 aiworker fleet list 直接见到
145
+ export AIWORKER_GATEWAY_URL='wss://operator:<basicauth-pwd>@your-gateway.example/ws'
146
+ export AIWORKER_JOIN_TOKEN='<gateway 配置的 join token>'
147
+ export AIWORKER_DISPLAY_NAME='ci-runner-12'
148
+ aiworker serve
149
+ # operator 端立即 aiworker fleet list 见到
156
150
  ```
157
151
 
158
152
  > ⚠️ URL 含 basicauth + JOIN_TOKEN 是 fleet 共享 secret,泄露面大。CI 可接受,朋友机器不要给。
159
153
 
160
- ---
161
-
162
- ## 路径 3:手动 pair(高安全)
154
+ ### 手动 pair(高安全)
163
155
 
164
156
  ```sh
165
- # Worker 端:
166
- bun apps/cli/src/aiworker.ts init
157
+ # Worker:
158
+ aiworker serve --gateway 'wss://operator:<pwd>@gateway/ws'
167
159
  # 抓 stdout 的 wtk_xxx
168
- bun apps/cli/src/aiworker.ts serve --port 9217 --gateway wss://operator:<pwd>@gateway/ws
169
160
 
170
- # Operator 端:
171
- aiworker pair --url wss://operator:<pwd>@gateway/ws \
161
+ # Operator:
162
+ aiworker pair --url 'wss://operator:<pwd>@gateway/ws' \
172
163
  --worker-url http://<worker-host>:9217 \
173
164
  --bootstrap-token wtk_xxx \
174
165
  --display-name production-1
175
166
  ```
176
167
 
177
- > 限制:gateway 必须能 inbound 到 worker `:9217` 验 token。worker 在 NAT 后需要反向 tunnel;改用 OTP 模式避坑。
168
+ > 限制:gateway 必须 inbound 到 worker `:9217` 验 token。worker 在 NAT 后用 OTP 替代。
178
169
 
179
- ---
180
-
181
- ## 路径 4:docker auto-launch
170
+ ### docker auto-launch
182
171
 
183
172
  需要 gateway 启用 `AIWORKER_GATEWAY_CAN_LAUNCH=true` + `docker.sock:ro` mount。
184
173
 
@@ -187,49 +176,46 @@ aiworker fleet launch --display-name demo
187
176
  # gateway supervisor 自动 docker run + scrape bootstrap token + pair
188
177
  ```
189
178
 
190
- 详见 [`docs/deployment.md`](docs/deployment.md) supervisor overlay 段落。
179
+ 详见 [`docs/deployment.md`](docs/deployment.md) supervisor overlay
191
180
 
192
181
  ---
193
182
 
194
- ## Operator 日常 cheat sheet
183
+ ## Operator cheat sheet
195
184
 
196
185
  ```sh
197
186
  # fleet 状态
198
- aiworker fleet list # 谁在线
199
- aiworker fleet info <workerId> # 单个 worker 运行时快照
200
- aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
187
+ aiworker fleet list # 谁在线
188
+ aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
201
189
 
202
- # worker 对话(流式 NDJSON)
190
+ # chat(流式 NDJSON)
203
191
  aiworker chat <workerId> 'hello'
204
192
  aiworker chat <workerId> '继续' --conversation-id <prev-id>
205
193
 
206
194
  # 配置(乐观锁必须带 --if-match)
207
- aiworker config get <workerId> # 读出含 version
195
+ aiworker config get <workerId> # 读出含 version
208
196
  aiworker config set <workerId> "$(cat new.json)" --if-match <version>
209
197
 
210
- # Token 轮换(旧立即失效)
198
+ # Token 轮换
211
199
  aiworker token rotate <workerId>
212
200
 
213
201
  # OTP 审批
214
- aiworker enroll list
215
- aiworker enroll approve <OTP>
216
- aiworker enroll reject <OTP>
202
+ aiworker enroll list / approve <OTP> / reject <OTP>
217
203
 
218
204
  # 日志订阅
219
205
  aiworker logs <workerId> --follow --tail 200
220
206
 
221
- # 审批 per-tool
207
+ # Per-tool approvals
222
208
  aiworker approvals list
223
- aiworker approvals grant <workerId> <taskId> <toolCallId> # allow
209
+ aiworker approvals grant <workerId> <taskId> <toolCallId> # allow
224
210
  aiworker approvals grant <workerId> <taskId> <toolCallId> --deny
225
211
 
226
- # 定时任务
212
+ # Cron
227
213
  aiworker schedule list <workerId>
228
- aiworker schedule add <workerId> --expression '0 9 * * *' --prompt '早报' --channel web --chat-id daily
214
+ aiworker schedule add <workerId> --expression '0 9 * * *' --prompt '早报' --channel web --chat-id daily
229
215
  aiworker schedule remove <workerId> <jobId>
230
216
  ```
231
217
 
232
- `aiworker` operator 默认 gatewayUrl 在 `~/.aiworker/aim.json`。第一次跑:
218
+ Operator 端首次需写 `~/.aiworker/aim.json`:
233
219
 
234
220
  ```sh
235
221
  mkdir -p ~/.aiworker
@@ -244,22 +230,89 @@ EOF
244
230
  chmod 600 ~/.aiworker/aim.json
245
231
  ```
246
232
 
247
- 如果在 gateway 同机跑(loopback),用 `ws://127.0.0.1:9218/ws`,无需 basicauth/token
233
+ > gateway 同机 loopback:用 `ws://127.0.0.1:9218/ws`,无需 basicauth/token(loopback bypass)。
248
234
 
249
235
  ---
250
236
 
251
- ## Worker 配 LLM(claude-code 示例)
237
+ ## Worker 配 LLM executor
238
+
239
+ 新 worker 默认 `executor: { engine: 'http', variant: 'default' }` 但缺 OpenAI key 会失败。配真实 LLM:
240
+
241
+ ### 选 1:claude-code(本地已 `claude login`)
252
242
 
253
243
  ```sh
254
- NEW='{"brains":[],"brainWriteTarget":"","brainRetrieval":"first-match","executor":{"engine":"claude-code","variant":"default"},"channels":[],"evolution":{"enabled":false,"observationRetentionDays":7}}'
255
- aiworker config set <workerId> "$NEW" --if-match <current-version>
244
+ # 1. 拿 worker 当前 config + version
245
+ aiworker config get <workerId>
246
+ # → { "version": 1, "config": {...} }
247
+
248
+ # 2. 切到 claude-code default variant(model=sonnet, timeout=120s)
249
+ NEW='{
250
+ "brains": [],
251
+ "brainWriteTarget": "",
252
+ "brainRetrieval": "first-match",
253
+ "executor": { "engine": "claude-code", "variant": "default" },
254
+ "channels": [],
255
+ "evolution": { "enabled": false, "observationRetentionDays": 7 }
256
+ }'
257
+ aiworker config set <workerId> "$NEW" --if-match 1
258
+
259
+ # 3. chat 验证
260
+ aiworker chat <workerId> '请用中文回我一句话'
261
+ # {"kind":"accepted",...}
262
+ # {"kind":"chat.message","payload":{"role":"assistant","content":"...claude 真实回复..."}}
263
+ # {"kind":"done","payload":{"finishReason":"stop"}}
264
+ ```
265
+
266
+ 要求:worker 进程所在主机能跑 `claude` CLI(PATH 含 `~/.claude/local/claude` 或 npm 全局),且 `~/.claude.json` 有效(`claude login` 已完成)。
267
+
268
+ `opus-plan` variant 切到 opus + plan 模式:`"executor": { "engine": "claude-code", "variant": "opus-plan" }`。
269
+
270
+ ### 选 2:OpenAI 兼容 (OpenAI / DeepSeek / SiliconFlow / etc.)
271
+
272
+ ```json
273
+ {
274
+ "executor": {
275
+ "engine": "http",
276
+ "variant": "default",
277
+ "overrides": {
278
+ "baseUrl": "https://api.deepseek.com/v1",
279
+ "model": "deepseek-chat",
280
+ "apiKeyRef": "secret://openai/deepseek"
281
+ }
282
+ }
283
+ }
256
284
  ```
257
285
 
258
- 可选 `engine`:`http`(OpenAI 兼容)/ `mcp` / `claude-code` / `acp`(gemini/qwen) / `codex` / `cursor`。
286
+ `apiKeyRef` 必须先 register worker `SecretsVault`(POST `/api/worker/secrets`);明文 secret 永不进 `worker_config.configJson`。
287
+
288
+ ### 选 3:ACP gemini / qwen
289
+
290
+ ```json
291
+ { "executor": { "engine": "acp", "variant": "gemini" } }
292
+ ```
293
+
294
+ 要求:worker 主机有 `gemini` CLI(`npm install -g @google/generative-ai-cli`)+ `~/.gemini/` auth。
295
+
296
+ ### 选 4:codex / cursor / mcp
297
+
298
+ 详见 [`docs/executor-engines.md`](docs/executor-engines.md)(含每 engine 安装/auth recipe)。
259
299
 
260
300
  ---
261
301
 
262
- ## 部署形态对比
302
+ ## Architecture & deployment
303
+
304
+ 详见:
305
+ - [`docs/architecture.md`](docs/architecture.md) — monorepo 布局、数据流、安全模型、env 全表
306
+ - [`docs/gateway.md`](docs/gateway.md) — WS 协议(METHODS / EVENTS)+ 4 enroll path 实现
307
+ - [`docs/deployment.md`](docs/deployment.md) — 三档部署 run book
308
+ - [`docs/deployment-public-https.md`](docs/deployment-public-https.md) — 可选 Cloudflare + Caddy 公网叠加层(含 BUG-007 fail-closed basicauth)
309
+ - [`docs/executor-engines.md`](docs/executor-engines.md) — 每 LLM engine 的 auth/install recipe
310
+
311
+ ```
312
+ apps/{api, cli, web} + packages/{core, gateway, gateway-proto, shared, storage-sqlite, fs-layout}
313
+ ```
314
+
315
+ 部署形态:
263
316
 
264
317
  | 形态 | 适用 | 入口 | docker |
265
318
  |------|------|------|--------|
@@ -267,19 +320,17 @@ aiworker config set <workerId> "$NEW" --if-match <current-version>
267
320
  | **systemd**(Linux 推荐) | 服务器长跑 | `aiworker install systemd [--user\|--system]` | 无 |
268
321
  | **docker compose** | 不愿装 bun / per-worker 隔离 | `ops/compose/docker-compose.yml`(GHCR 镜像) | 有 |
269
322
 
270
- 详见 [`docs/deployment.md`](docs/deployment.md);公网 HTTPS(Cloudflare + Caddy)单独叠加层在 [`docs/deployment-public-https.md`](docs/deployment-public-https.md)。
271
-
272
323
  ---
273
324
 
274
325
  ## 关键 env
275
326
 
276
327
  | 变量 | 用于 | 说明 |
277
328
  |---|---|---|
278
- | `AIWORKER_MASTER_KEY` | gateway / worker | 64 hex;丢了 fleet.db 解不开 — **必须组织级离线备份** |
279
- | `INTERNAL_SHARED_SECRET` | gateway / 远程 operator | ≥16 chars;远程 aiworker CLI bearer |
329
+ | `AIWORKER_MASTER_KEY` | gateway / worker | 64 hex;丢了 fleet.db / worker.db 解不开 — **必须组织级离线备份** |
330
+ | `INTERNAL_SHARED_SECRET` | gateway / 远程 operator | ≥16 chars;远程 operator bearer |
280
331
  | `AIWORKER_JOIN_TOKEN` | gateway / self-enroll worker | self-enroll 模式触发;与 INTERNAL_SHARED_SECRET 解耦 |
281
332
  | `AIWORKER_GATEWAY_URL` | worker | OTP / self-enroll 模式连入口 |
282
- | `AIWORKER_DISPLAY_NAME` | worker | operator 端识别用 |
333
+ | `AIWORKER_DISPLAY_NAME` | worker | operator 端识别用(默认 hostname) |
283
334
  | `AIWORKER_HOME` | gateway / worker | 默认 `~/.aiworker` |
284
335
  | `WORKER_DB_PATH` | worker | 默认 `$AIWORKER_HOME/worker.db` |
285
336
  | `AIWORKER_FLEET_DB_PATH` | gateway | 默认 `$AIWORKER_HOME/fleet.db` |
@@ -287,19 +338,18 @@ aiworker config set <workerId> "$NEW" --if-match <current-version>
287
338
  | `PORT` | worker | 默认 `9217` |
288
339
  | `AIWORKER_ENROLL_OTP_TTL_SEC` | gateway | OTP 过期秒数,默认 300,[30, 3600] |
289
340
 
290
- 完整列表见 `apps/api/.env.example` `ops/compose/.env.example`。
341
+ 完整列表:`apps/api/.env.example` + `ops/compose/.env.example`。
291
342
 
292
343
  ---
293
344
 
294
- ## 故障排查(高频 3 条)
345
+ ## 故障排查(高频)
295
346
 
296
347
  | 现象 | 原因 | 修法 |
297
348
  |---|---|---|
298
349
  | `aiworker fleet list` → `WebSocket Expected 101 status code` | aim.json `gatewayUrl` 缺 `/ws` 或 basicauth | 重写 `~/.aiworker/aim.json`(见上) |
299
- | OTP `aiworker enroll approve` 后 worker `online: false` | gateway 版本旧(缺 BUG-009 fix,commit `233548b` 起修) | 服务器 `git pull && systemctl restart aiworker-gateway` |
300
- | 公网 `/health` 返回 401 | 你忘了带 basicauth | `curl -u operator:<pwd> https://your-gateway/health` |
301
-
302
- 详见 [`docs/deployment-public-https.md` § Troubleshooting](docs/deployment-public-https.md)。
350
+ | 公网 `/health` 返回 401 | Caddy basicauth | `curl -u operator:<pwd> https://your-gateway/health` |
351
+ | OTP enroll 后 `aiworker chat` `executor error: OpenAI API key is not configured` | worker 没配 LLM | 走"Worker LLM executor"段,切 claude-code / 配 OpenAI key |
352
+ | systemd `aiworker-gateway` exit 1 `gateway 入口未找到` | 用了 0.2.0 旧 cli | `bun install -g @zonease/aiworker-cli@latest`(≥0.2.1)+ restart |
303
353
 
304
354
  ---
305
355
 
@@ -308,10 +358,8 @@ aiworker config set <workerId> "$NEW" --if-match <current-version>
308
358
  - **fleet.db / worker.db 物理隔离**:gateway 永不存 worker 的业务数据
309
359
  - **AES-256-GCM** 加密 `registered_workers.apiTokenEnc` + `worker_secrets`
310
360
  - **timing-safe** bearer 比较
311
- - **5 channel webhook 强制验签**(Telegram secret token / WhatsApp HMAC / Lark AES + token / LINE channel signature / Web binding token)
312
- - **Caddy 路径分流**:`/ws` basicauth 守 operator + 已配对 worker,`/enroll-ws` 仅接受 OTP submit;fail-closed(缺 `/etc/caddy/auth.snippet` 直接拒启动)
313
-
314
- 详见 [CLAUDE.md § Security](CLAUDE.md) 与 [`docs/architecture.md` § 加密与认证](docs/architecture.md)。
361
+ - **5 channel webhook 强制验签**(Telegram / WhatsApp / Lark / LINE / Web binding token)
362
+ - **Caddy 路径分流**:`/ws` basicauth 守 operator + 已配对 worker,`/enroll-ws` 仅接受 OTP submit;fail-closed(缺 `/etc/caddy/auth.snippet` 直接拒启动,BUG-007)
315
363
 
316
364
  ---
317
365
 
@@ -335,7 +383,7 @@ bun run test # 全工作区
335
383
  bun run lint
336
384
  ```
337
385
 
338
- 文档系统(PMA):[`docs/plan/`](docs/plan/) 是历史方案,[`docs/task/`](docs/task/) task 跟踪,[`docs/changelog.md`](docs/changelog.md) 是发布日志。新功能按 `/pma` skill 走 investigate → proposal → implement 三阶段。
386
+ 文档系统(PMA workflow):[`docs/plan/`](docs/plan/) 历史方案、[`docs/task/`](docs/task/) task 跟踪、[`docs/changelog.md`](docs/changelog.md) 发布日志。新功能按 `/pma` skill 走 investigate → proposal → implement 三阶段。
339
387
 
340
388
  ---
341
389
 
@@ -350,11 +398,12 @@ bun run lint
350
398
  | Module | Status |
351
399
  |---|---|
352
400
  | Gateway WS 控制面 | ✅ Production |
353
- | 4 enrollment paths | ✅ Production |
354
- | 7 LLM engines | ✅ Production |
355
- | 5 channel webhooks | ✅ Production |
356
- | Cron / approvals / hot-reload | ✅ Production |
357
- | **CLI 重命名(单 `aiworker` 入口)** | 🚧 Implementing (PLAN-020 / FEAT-028) |
358
- | **npm 发布** | Planned (FEAT-027) |
401
+ | 4 enrollment paths(OTP / self-enroll / pair / launch) | ✅ Production |
402
+ | 6 LLM engines(http / claude-code / acp / codex / cursor / mcp) | ✅ Production |
403
+ | 5 channel webhooks(Telegram / WhatsApp / Lark / LINE / Web) | ✅ Production |
404
+ | Cron / per-tool approvals / hot-reload | ✅ Production |
405
+ | `aiworker` CLI(PLAN-020 / FEAT-028 | ✅ GA |
406
+ | npm 发布(`@zonease/aiworker-cli`) | Latest 0.2.1 |
407
+ | In-process gateway(npm install 场景,REFACTOR-004) | ✅ GA |
359
408
  | Web SPA pending UI | 🔜 Stage-2 |
360
409
  | Multi-host HA | 🔜 Stage-2 |