@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 +219 -167
- package/aiworker.js +239 -207
- package/drizzle/worker/0003_rare_cloak.sql +7 -0
- package/drizzle/worker/meta/0003_snapshot.json +873 -0
- package/drizzle/worker/meta/_journal.json +7 -0
- package/package.json +3 -2
- package/web/fleet/assets/index-BPew1ixe.css +2 -0
- package/web/fleet/assets/index-DzBnJ6fr.js +20 -0
- package/web/fleet/favicon.svg +4 -0
- package/web/fleet/index.html +14 -0
- package/web/worker/assets/index-BPew1ixe.css +2 -0
- package/web/worker/assets/index-ZLEe-oRM.js +30 -0
- package/web/worker/favicon.svg +4 -0
- package/web/worker/index.html +14 -0
package/README.md
CHANGED
|
@@ -1,184 +1,175 @@
|
|
|
1
1
|
# AIWorker
|
|
2
2
|
|
|
3
|
-
自托管 Agent Runtime — 由 **Brain provider**(知识 / 记忆 / 技能)与 **Executor provider**(OpenAI 兼容
|
|
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
|
|
5
|
+
工作站、服务器、k8s pod、docker container 都能跑成一个 worker 加入同一个 fleet。Operator 用一个 CLI 控制所有 worker。
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **4
|
|
10
|
-
- **WS 控制面**:operator
|
|
11
|
-
- **多 LLM engine**:`http
|
|
12
|
-
- **多 channel**: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
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
21
|
+
**目标**:本机起一个 worker,加入远端 gateway,发一条消息让 worker 用 LLM 回。
|
|
35
22
|
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
57
|
+
export AIWORKER_GATEWAY_URL='wss://your-gateway.example/'
|
|
58
|
+
export AIWORKER_DISPLAY_NAME='my-laptop'
|
|
59
|
+
aiworker serve
|
|
60
|
+
```
|
|
45
61
|
|
|
46
|
-
|
|
62
|
+
输出:
|
|
47
63
|
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
aiworker serve
|
|
57
|
-
aiworker
|
|
58
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
89
|
+
完整端到端实测见 [docs/changelog.md](docs/changelog.md) 11:50 条目。
|
|
70
90
|
|
|
71
91
|
---
|
|
72
92
|
|
|
73
|
-
##
|
|
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
|
-
|
|
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
|
-
###
|
|
107
|
+
### 本地开发
|
|
96
108
|
|
|
97
109
|
```sh
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
119
|
+
## 4 种入网路径
|
|
128
120
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
134
|
-
# ✔ 已批准
|
|
128
|
+
### OTP(推荐)
|
|
135
129
|
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
Operator:
|
|
138
|
+
```sh
|
|
139
|
+
aiworker enroll list # → pending [{ otp, workerId, displayName }]
|
|
140
|
+
aiworker enroll approve <OTP>
|
|
141
|
+
```
|
|
145
142
|
|
|
146
|
-
|
|
143
|
+
### self-enroll(自动化)
|
|
147
144
|
|
|
145
|
+
Worker:
|
|
148
146
|
```sh
|
|
149
|
-
export AIWORKER_GATEWAY_URL=
|
|
150
|
-
export AIWORKER_JOIN_TOKEN=
|
|
151
|
-
export AIWORKER_DISPLAY_NAME=
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
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
|
|
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)
|
|
181
|
+
详见 [`docs/deployment.md`](docs/deployment.md) supervisor overlay。
|
|
191
182
|
|
|
192
183
|
---
|
|
193
184
|
|
|
194
|
-
## Operator
|
|
185
|
+
## Operator cheat sheet
|
|
195
186
|
|
|
196
187
|
```sh
|
|
197
188
|
# fleet 状态
|
|
198
|
-
aiworker fleet list
|
|
199
|
-
aiworker fleet
|
|
200
|
-
aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
|
|
189
|
+
aiworker fleet list # 谁在线
|
|
190
|
+
aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
|
|
201
191
|
|
|
202
|
-
#
|
|
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>
|
|
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
|
-
#
|
|
209
|
+
# Per-tool approvals
|
|
222
210
|
aiworker approvals list
|
|
223
|
-
aiworker approvals grant <workerId> <taskId> <toolCallId>
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
235
|
+
> gateway 同机 loopback:用 `ws://127.0.0.1:9218/ws`,无需 basicauth/token(loopback bypass)。
|
|
248
236
|
|
|
249
237
|
---
|
|
250
238
|
|
|
251
|
-
## Worker 配 LLM
|
|
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
|
-
|
|
255
|
-
aiworker config
|
|
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
|
-
|
|
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;远程
|
|
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
|
-
|
|
343
|
+
完整列表:`apps/api/.env.example` + `ops/compose/.env.example`。
|
|
291
344
|
|
|
292
345
|
---
|
|
293
346
|
|
|
294
|
-
##
|
|
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
|
-
|
|
|
300
|
-
|
|
|
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
|
|
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/)
|
|
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
|
-
|
|
|
355
|
-
| 5 channel webhooks | ✅ Production |
|
|
356
|
-
| Cron / approvals / hot-reload | ✅ Production |
|
|
357
|
-
|
|
|
358
|
-
|
|
|
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 |
|