@zonease/aiworker-cli 0.2.1 → 0.4.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,175 @@
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
 
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
77
101
  ```
78
- operator ─── 持 basicauth + aiworker CLI ─── 管 fleet
79
- worker deployer ─── 跑 aiworker serve ────────── 加入 fleet 后等指令
80
- ```
81
-
82
- ### 选哪种 enrollment?
83
102
 
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 自己拉容器 |
90
-
91
- ---
103
+ binary 跑在 `~/.bun/bin/aiworker` `$(npm bin -g)/aiworker`。第一次跑任意命令时自动 mint master key 写到 `~/.aiworker/.env`(chmod 0600)。
92
104
 
93
- ## 路径 1:OTP 入网(最简)
105
+ **项目级 worker**(PLAN-023,可选):在 git repo 内 `aiworker init` 默认在 `<cwd>/.aiworker/` 落项目级 layout(每 project 一份独立 worker.db / master key / persona / skills),engine(claude / codex / cursor)保持 user 级共享。`aiworker scope` 诊断当前命中的 layout。详见 [docs/cli.md §`aiworker init`](docs/cli.md)。
94
106
 
95
- ### Worker deployer(任何机器,**零 fleet 凭证 + 零本地 secret 输入**)
107
+ ### 本地开发
96
108
 
97
109
  ```sh
98
- # 1. 装 bun(如果没装)
99
- curl -fsSL https://bun.sh/install | bash
100
-
101
- # 2. 装 aiworker CLI
102
- bun install -g @zonease/aiworker-cli
103
- # 或 npm install -g @zonease/aiworker-cli
104
-
105
- # 3. 第一次 init —— 自动 mint master key 写到 ~/.aiworker/.env (chmod 600),
106
- # 控制台显示**一次**,请离线备份。
107
- aiworker init
108
-
109
- # 4. 启动 worker,指向你的 gateway(默认监听 :9217)
110
- export AIWORKER_GATEWAY_URL="wss://your-gateway.example/"
111
- export AIWORKER_DISPLAY_NAME="my-laptop" # 可选;默认取 hostname
112
- aiworker serve
110
+ git clone https://github.com/ZonEaseTech/aiworker
111
+ cd aiworker && bun install
112
+ bun apps/cli/src/aiworker.ts <subcmd> # = aiworker <subcmd>
113
113
  ```
114
114
 
115
- 控制台输出:
115
+ 下面所有 `aiworker ...` 命令在本地开发态等价 `bun apps/cli/src/aiworker.ts ...`。
116
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。
117
+ ---
126
118
 
127
- ### Operator
119
+ ## 4 种入网路径
128
120
 
129
- ```sh
130
- aiworker enroll list
131
- # {"pending":[{"otp":"9CDT-94BK","displayName":"my-laptop",...}]}
121
+ | 场景 | 用 | Worker 端凭证 | Operator 介入 |
122
+ |---|---|---|---|
123
+ | 朋友/客户/CI 临时装 worker | **OTP(推荐)** | 零(worker 不持任何 fleet 共享 secret) | 看 8 字符 OTP → approve |
124
+ | k8s/docker compose 批量 unattended | self-enroll | `AIWORKER_JOIN_TOKEN`(fleet 共享) | 无(自动入网) |
125
+ | 高安全单 worker 手动 | 手动 pair | worker 启动后输出 `wtk_xxx` bootstrap token | `aiworker pair --bootstrap-token wtk_...` |
126
+ | docker fast-launch(gateway 同机) | `aiworker fleet launch` | gateway 自动注入 | 一行命令 |
132
127
 
133
- aiworker enroll approve 9CDT-94BK
134
- # ✔ 已批准
128
+ ### OTP(推荐)
135
129
 
136
- aiworker fleet list
137
- # {"workers":[{"workerId":"w_xxx","displayName":"my-laptop","online":true,...}]}
130
+ Worker:
131
+ ```sh
132
+ export AIWORKER_GATEWAY_URL='wss://your-gateway.example/'
133
+ export AIWORKER_DISPLAY_NAME='my-laptop' # 可选,默认 hostname
134
+ aiworker serve
138
135
  ```
139
136
 
140
- worker 端同步打:`√ approved as w_xxx; deviceToken=wtk_...,已加入 fleet`。
141
-
142
- ---
143
-
144
- ## 路径 2:self-enroll(自动化批量)
137
+ Operator:
138
+ ```sh
139
+ aiworker enroll list # → pending [{ otp, workerId, displayName }]
140
+ aiworker enroll approve <OTP>
141
+ ```
145
142
 
146
- Worker 端 env 多两个,省去 operator approve:
143
+ ### self-enroll(自动化)
147
144
 
145
+ Worker:
148
146
  ```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 直接见到
147
+ export AIWORKER_GATEWAY_URL='wss://operator:<basicauth-pwd>@your-gateway.example/ws'
148
+ export AIWORKER_JOIN_TOKEN='<gateway 配置的 join token>'
149
+ export AIWORKER_DISPLAY_NAME='ci-runner-12'
150
+ aiworker serve
151
+ # operator 端立即 aiworker fleet list 见到
156
152
  ```
157
153
 
158
154
  > ⚠️ URL 含 basicauth + JOIN_TOKEN 是 fleet 共享 secret,泄露面大。CI 可接受,朋友机器不要给。
159
155
 
160
- ---
161
-
162
- ## 路径 3:手动 pair(高安全)
156
+ ### 手动 pair(高安全)
163
157
 
164
158
  ```sh
165
- # Worker 端:
166
- bun apps/cli/src/aiworker.ts init
159
+ # Worker:
160
+ aiworker serve --gateway 'wss://operator:<pwd>@gateway/ws'
167
161
  # 抓 stdout 的 wtk_xxx
168
- bun apps/cli/src/aiworker.ts serve --port 9217 --gateway wss://operator:<pwd>@gateway/ws
169
162
 
170
- # Operator 端:
171
- aiworker pair --url wss://operator:<pwd>@gateway/ws \
163
+ # Operator:
164
+ aiworker pair --url 'wss://operator:<pwd>@gateway/ws' \
172
165
  --worker-url http://<worker-host>:9217 \
173
166
  --bootstrap-token wtk_xxx \
174
167
  --display-name production-1
175
168
  ```
176
169
 
177
- > 限制:gateway 必须能 inbound 到 worker `:9217` 验 token。worker 在 NAT 后需要反向 tunnel;改用 OTP 模式避坑。
170
+ > 限制:gateway 必须 inbound 到 worker `:9217` 验 token。worker 在 NAT 后用 OTP 替代。
178
171
 
179
- ---
180
-
181
- ## 路径 4:docker auto-launch
172
+ ### docker auto-launch
182
173
 
183
174
  需要 gateway 启用 `AIWORKER_GATEWAY_CAN_LAUNCH=true` + `docker.sock:ro` mount。
184
175
 
@@ -187,49 +178,46 @@ aiworker fleet launch --display-name demo
187
178
  # gateway supervisor 自动 docker run + scrape bootstrap token + pair
188
179
  ```
189
180
 
190
- 详见 [`docs/deployment.md`](docs/deployment.md) supervisor overlay 段落。
181
+ 详见 [`docs/deployment.md`](docs/deployment.md) supervisor overlay
191
182
 
192
183
  ---
193
184
 
194
- ## Operator 日常 cheat sheet
185
+ ## Operator cheat sheet
195
186
 
196
187
  ```sh
197
188
  # fleet 状态
198
- aiworker fleet list # 谁在线
199
- aiworker fleet info <workerId> # 单个 worker 运行时快照
200
- aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
189
+ aiworker fleet list # 谁在线
190
+ aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
201
191
 
202
- # worker 对话(流式 NDJSON)
192
+ # chat(流式 NDJSON)
203
193
  aiworker chat <workerId> 'hello'
204
194
  aiworker chat <workerId> '继续' --conversation-id <prev-id>
205
195
 
206
196
  # 配置(乐观锁必须带 --if-match)
207
- aiworker config get <workerId> # 读出含 version
197
+ aiworker config get <workerId> # 读出含 version
208
198
  aiworker config set <workerId> "$(cat new.json)" --if-match <version>
209
199
 
210
- # Token 轮换(旧立即失效)
200
+ # Token 轮换
211
201
  aiworker token rotate <workerId>
212
202
 
213
203
  # OTP 审批
214
- aiworker enroll list
215
- aiworker enroll approve <OTP>
216
- aiworker enroll reject <OTP>
204
+ aiworker enroll list / approve <OTP> / reject <OTP>
217
205
 
218
206
  # 日志订阅
219
207
  aiworker logs <workerId> --follow --tail 200
220
208
 
221
- # 审批 per-tool
209
+ # Per-tool approvals
222
210
  aiworker approvals list
223
- aiworker approvals grant <workerId> <taskId> <toolCallId> # allow
211
+ aiworker approvals grant <workerId> <taskId> <toolCallId> # allow
224
212
  aiworker approvals grant <workerId> <taskId> <toolCallId> --deny
225
213
 
226
- # 定时任务
214
+ # Cron
227
215
  aiworker schedule list <workerId>
228
- aiworker schedule add <workerId> --expression '0 9 * * *' --prompt '早报' --channel web --chat-id daily
216
+ aiworker schedule add <workerId> --expression '0 9 * * *' --prompt '早报' --channel web --chat-id daily
229
217
  aiworker schedule remove <workerId> <jobId>
230
218
  ```
231
219
 
232
- `aiworker` operator 默认 gatewayUrl 在 `~/.aiworker/aim.json`。第一次跑:
220
+ Operator 端首次需写 `~/.aiworker/aim.json`:
233
221
 
234
222
  ```sh
235
223
  mkdir -p ~/.aiworker
@@ -244,22 +232,89 @@ EOF
244
232
  chmod 600 ~/.aiworker/aim.json
245
233
  ```
246
234
 
247
- 如果在 gateway 同机跑(loopback),用 `ws://127.0.0.1:9218/ws`,无需 basicauth/token
235
+ > gateway 同机 loopback:用 `ws://127.0.0.1:9218/ws`,无需 basicauth/token(loopback bypass)。
248
236
 
249
237
  ---
250
238
 
251
- ## Worker 配 LLM(claude-code 示例)
239
+ ## Worker 配 LLM executor
240
+
241
+ 新 worker 默认 `executor: { engine: 'http', variant: 'default' }` 但缺 OpenAI key 会失败。配真实 LLM:
242
+
243
+ ### 选 1:claude-code(本地已 `claude login`)
252
244
 
253
245
  ```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>
246
+ # 1. 拿 worker 当前 config + version
247
+ aiworker config get <workerId>
248
+ # → { "version": 1, "config": {...} }
249
+
250
+ # 2. 切到 claude-code default variant(model=sonnet, timeout=120s)
251
+ NEW='{
252
+ "brains": [],
253
+ "brainWriteTarget": "",
254
+ "brainRetrieval": "first-match",
255
+ "executor": { "engine": "claude-code", "variant": "default" },
256
+ "channels": [],
257
+ "evolution": { "enabled": false, "observationRetentionDays": 7 }
258
+ }'
259
+ aiworker config set <workerId> "$NEW" --if-match 1
260
+
261
+ # 3. chat 验证
262
+ aiworker chat <workerId> '请用中文回我一句话'
263
+ # {"kind":"accepted",...}
264
+ # {"kind":"chat.message","payload":{"role":"assistant","content":"...claude 真实回复..."}}
265
+ # {"kind":"done","payload":{"finishReason":"stop"}}
266
+ ```
267
+
268
+ 要求:worker 进程所在主机能跑 `claude` CLI(PATH 含 `~/.claude/local/claude` 或 npm 全局),且 `~/.claude.json` 有效(`claude login` 已完成)。
269
+
270
+ `opus-plan` variant 切到 opus + plan 模式:`"executor": { "engine": "claude-code", "variant": "opus-plan" }`。
271
+
272
+ ### 选 2:OpenAI 兼容 (OpenAI / DeepSeek / SiliconFlow / etc.)
273
+
274
+ ```json
275
+ {
276
+ "executor": {
277
+ "engine": "http",
278
+ "variant": "default",
279
+ "overrides": {
280
+ "baseUrl": "https://api.deepseek.com/v1",
281
+ "model": "deepseek-chat",
282
+ "apiKeyRef": "secret://openai/deepseek"
283
+ }
284
+ }
285
+ }
256
286
  ```
257
287
 
258
- 可选 `engine`:`http`(OpenAI 兼容)/ `mcp` / `claude-code` / `acp`(gemini/qwen) / `codex` / `cursor`。
288
+ `apiKeyRef` 必须先 register worker `SecretsVault`(POST `/api/worker/secrets`);明文 secret 永不进 `worker_config.configJson`。
289
+
290
+ ### 选 3:ACP gemini / qwen
291
+
292
+ ```json
293
+ { "executor": { "engine": "acp", "variant": "gemini" } }
294
+ ```
295
+
296
+ 要求:worker 主机有 `gemini` CLI(`npm install -g @google/generative-ai-cli`)+ `~/.gemini/` auth。
297
+
298
+ ### 选 4:codex / cursor / mcp
299
+
300
+ 详见 [`docs/executor-engines.md`](docs/executor-engines.md)(含每 engine 安装/auth recipe)。
259
301
 
260
302
  ---
261
303
 
262
- ## 部署形态对比
304
+ ## Architecture & deployment
305
+
306
+ 详见:
307
+ - [`docs/architecture.md`](docs/architecture.md) — monorepo 布局、数据流、安全模型、env 全表
308
+ - [`docs/gateway.md`](docs/gateway.md) — WS 协议(METHODS / EVENTS)+ 4 enroll path 实现
309
+ - [`docs/deployment.md`](docs/deployment.md) — 三档部署 run book
310
+ - [`docs/deployment-public-https.md`](docs/deployment-public-https.md) — 可选 Cloudflare + Caddy 公网叠加层(含 BUG-007 fail-closed basicauth)
311
+ - [`docs/executor-engines.md`](docs/executor-engines.md) — 每 LLM engine 的 auth/install recipe
312
+
313
+ ```
314
+ apps/{api, cli, web} + packages/{core, gateway, gateway-proto, shared, storage-sqlite, fs-layout}
315
+ ```
316
+
317
+ 部署形态:
263
318
 
264
319
  | 形态 | 适用 | 入口 | docker |
265
320
  |------|------|------|--------|
@@ -267,19 +322,17 @@ aiworker config set <workerId> "$NEW" --if-match <current-version>
267
322
  | **systemd**(Linux 推荐) | 服务器长跑 | `aiworker install systemd [--user\|--system]` | 无 |
268
323
  | **docker compose** | 不愿装 bun / per-worker 隔离 | `ops/compose/docker-compose.yml`(GHCR 镜像) | 有 |
269
324
 
270
- 详见 [`docs/deployment.md`](docs/deployment.md);公网 HTTPS(Cloudflare + Caddy)单独叠加层在 [`docs/deployment-public-https.md`](docs/deployment-public-https.md)。
271
-
272
325
  ---
273
326
 
274
327
  ## 关键 env
275
328
 
276
329
  | 变量 | 用于 | 说明 |
277
330
  |---|---|---|
278
- | `AIWORKER_MASTER_KEY` | gateway / worker | 64 hex;丢了 fleet.db 解不开 — **必须组织级离线备份** |
279
- | `INTERNAL_SHARED_SECRET` | gateway / 远程 operator | ≥16 chars;远程 aiworker CLI bearer |
331
+ | `AIWORKER_MASTER_KEY` | gateway / worker | 64 hex;丢了 fleet.db / worker.db 解不开 — **必须组织级离线备份** |
332
+ | `INTERNAL_SHARED_SECRET` | gateway / 远程 operator | ≥16 chars;远程 operator bearer |
280
333
  | `AIWORKER_JOIN_TOKEN` | gateway / self-enroll worker | self-enroll 模式触发;与 INTERNAL_SHARED_SECRET 解耦 |
281
334
  | `AIWORKER_GATEWAY_URL` | worker | OTP / self-enroll 模式连入口 |
282
- | `AIWORKER_DISPLAY_NAME` | worker | operator 端识别用 |
335
+ | `AIWORKER_DISPLAY_NAME` | worker | operator 端识别用(默认 hostname) |
283
336
  | `AIWORKER_HOME` | gateway / worker | 默认 `~/.aiworker` |
284
337
  | `WORKER_DB_PATH` | worker | 默认 `$AIWORKER_HOME/worker.db` |
285
338
  | `AIWORKER_FLEET_DB_PATH` | gateway | 默认 `$AIWORKER_HOME/fleet.db` |
@@ -287,19 +340,18 @@ aiworker config set <workerId> "$NEW" --if-match <current-version>
287
340
  | `PORT` | worker | 默认 `9217` |
288
341
  | `AIWORKER_ENROLL_OTP_TTL_SEC` | gateway | OTP 过期秒数,默认 300,[30, 3600] |
289
342
 
290
- 完整列表见 `apps/api/.env.example` `ops/compose/.env.example`。
343
+ 完整列表:`apps/api/.env.example` + `ops/compose/.env.example`。
291
344
 
292
345
  ---
293
346
 
294
- ## 故障排查(高频 3 条)
347
+ ## 故障排查(高频)
295
348
 
296
349
  | 现象 | 原因 | 修法 |
297
350
  |---|---|---|
298
351
  | `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)。
352
+ | 公网 `/health` 返回 401 | Caddy basicauth | `curl -u operator:<pwd> https://your-gateway/health` |
353
+ | OTP enroll 后 `aiworker chat` `executor error: OpenAI API key is not configured` | worker 没配 LLM | 走"Worker LLM executor"段,切 claude-code / 配 OpenAI key |
354
+ | systemd `aiworker-gateway` exit 1 `gateway 入口未找到` | 用了 0.2.0 旧 cli | `bun install -g @zonease/aiworker-cli@latest`(≥0.2.1)+ restart |
303
355
 
304
356
  ---
305
357
 
@@ -308,10 +360,9 @@ aiworker config set <workerId> "$NEW" --if-match <current-version>
308
360
  - **fleet.db / worker.db 物理隔离**:gateway 永不存 worker 的业务数据
309
361
  - **AES-256-GCM** 加密 `registered_workers.apiTokenEnc` + `worker_secrets`
310
362
  - **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)。
363
+ - **5 channel webhook 强制验签**(Telegram / WhatsApp / Lark / LINE / Web binding token)
364
+ - **Caddy 路径分流**:`/ws` basicauth 守 operator + 已配对 worker,`/enroll-ws` 仅接受 OTP submit;fail-closed(缺 `/etc/caddy/auth.snippet` 直接拒启动,BUG-007)
365
+ - **`/admin/*`(fleet + worker UI)** 与 `/ws`、`/api/*` 同等级——公网必须走 basicauth。新发布 worker bundle 不含 secret,但 prompt 用户输入 bearer 的登录界面如果裸暴露会被钓鱼。`aiworker {gateway start, serve}` 默认挂 `/admin/*`,关掉用 `--no-serve-web` 或 env `AIWORKER_GATEWAY_NO_SERVE_WEB=1` / `AIWORKER_WORKER_NO_SERVE_WEB=1`(PLAN-022 / FEAT-033)
315
366
 
316
367
  ---
317
368
 
@@ -335,7 +386,7 @@ bun run test # 全工作区
335
386
  bun run lint
336
387
  ```
337
388
 
338
- 文档系统(PMA):[`docs/plan/`](docs/plan/) 是历史方案,[`docs/task/`](docs/task/) task 跟踪,[`docs/changelog.md`](docs/changelog.md) 是发布日志。新功能按 `/pma` skill 走 investigate → proposal → implement 三阶段。
389
+ 文档系统(PMA workflow):[`docs/plan/`](docs/plan/) 历史方案、[`docs/task/`](docs/task/) task 跟踪、[`docs/changelog.md`](docs/changelog.md) 发布日志。新功能按 `/pma` skill 走 investigate → proposal → implement 三阶段。
339
390
 
340
391
  ---
341
392
 
@@ -350,11 +401,12 @@ bun run lint
350
401
  | Module | Status |
351
402
  |---|---|
352
403
  | 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) |
404
+ | 4 enrollment paths(OTP / self-enroll / pair / launch) | ✅ Production |
405
+ | 6 LLM engines(http / claude-code / acp / codex / cursor / mcp) | ✅ Production |
406
+ | 5 channel webhooks(Telegram / WhatsApp / Lark / LINE / Web) | ✅ Production |
407
+ | Cron / per-tool approvals / hot-reload | ✅ Production |
408
+ | `aiworker` CLI(PLAN-020 / FEAT-028 | ✅ GA |
409
+ | npm 发布(`@zonease/aiworker-cli`) | Latest 0.2.1 |
410
+ | In-process gateway(npm install 场景,REFACTOR-004) | ✅ GA |
359
411
  | Web SPA pending UI | 🔜 Stage-2 |
360
412
  | Multi-host HA | 🔜 Stage-2 |