@zonease/aiworker-cli 0.1.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.
Files changed (3) hide show
  1. package/README.md +360 -0
  2. package/aiworker.js +417 -0
  3. package/package.json +25 -0
package/README.md ADDED
@@ -0,0 +1,360 @@
1
+ # AIWorker
2
+
3
+ 自托管 Agent Runtime — 由 **Brain provider**(知识 / 记忆 / 技能)与 **Executor provider**(OpenAI 兼容 chat completions + tool calling)组合而成。
4
+
5
+ 工作站、服务器、k8s pod、docker container 都能跑成一个 worker 加入同一个 fleet。Operator 通过一个 CLI 控制所有 worker。
6
+
7
+ ## Features
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)
16
+
17
+ ## Architecture
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
+ ```
33
+
34
+ 详见 [`docs/architecture.md`](docs/architecture.md)。
35
+
36
+ ## Stack
37
+
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)
41
+
42
+ ---
43
+
44
+ ## Install
45
+
46
+ ### Published(待 FEAT-027 npm publish 上线启用)
47
+
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 serve
56
+ aiworker fleet list
57
+ aiworker chat <workerId> 'hello'
58
+ ```
59
+
60
+ ### 本地开发(当前主路径)
61
+
62
+ ```sh
63
+ git clone <repo-url>
64
+ cd aiworker && bun install
65
+ bun apps/cli/src/aiworker.ts <subcmd>
66
+ ```
67
+
68
+ 下面的 Quickstart / cheat sheet 用本地开发态 `bun apps/cli/src/aiworker.ts ...` 调用;Stage B 完成后等价改写为全局 `aiworker ...`,命令树不变。
69
+
70
+ ---
71
+
72
+ ## Quickstart
73
+
74
+ ### 角色
75
+
76
+ ```
77
+ operator ─── 持 basicauth + aiworker CLI ─── 管 fleet
78
+ worker deployer ─── 跑 aiworker serve ────────── 加入 fleet 后等指令
79
+ ```
80
+
81
+ ### 选哪种 enrollment?
82
+
83
+ | 场景 | 用 | 一句话 |
84
+ |---|---|---|
85
+ | 朋友/客户/CI 临时装 worker | **OTP(推荐)** | worker deployer **零凭证**,operator 看 8 字符 OTP 后 approve |
86
+ | k8s/docker compose 批量 unattended | self-enroll | env 配 `AIWORKER_JOIN_TOKEN` 自动入网 |
87
+ | 高安全单 worker 手动 | 手动 pair | `aiworker pair --bootstrap-token wtk_...` |
88
+ | docker fast-launch(gateway 同机) | `aiworker fleet launch` | gateway supervisor 自己拉容器 |
89
+
90
+ ---
91
+
92
+ ## 路径 1:OTP 入网(最简)
93
+
94
+ ### Worker deployer(任何机器,**零 fleet 凭证**)
95
+
96
+ ```sh
97
+ # 1. 装 bun
98
+ curl -fsSL https://bun.sh/install | bash
99
+
100
+ # 2. clone + install
101
+ git clone <repo-url>
102
+ cd aiworker && bun install
103
+
104
+ # 3. 最小 env
105
+ export AIWORKER_HOME="$HOME/.aiworker"
106
+ export AIWORKER_MASTER_KEY=$(openssl rand -hex 32) # worker 自己的 vault key
107
+ export WORKER_DB_PATH="$AIWORKER_HOME/worker.db"
108
+ export AIWORKER_GATEWAY_URL="wss://your-gateway.example/" # ← 仅这一个公网地址
109
+ export AIWORKER_DISPLAY_NAME="my-laptop" # 可选
110
+
111
+ # 4. init + serve
112
+ bun apps/cli/src/aiworker.ts init
113
+ bun apps/cli/src/aiworker.ts serve --port 3001
114
+ ```
115
+
116
+ 控制台输出:
117
+
118
+ ```
119
+ i [aiworker serve] OTP enrolling to wss://your-gateway.example/enroll-ws; awaiting operator approval
120
+ ┌─────────────────────┐
121
+ │ OTP: 9CDT-94BK │
122
+ │ expires in 300s │
123
+ └─────────────────────┘
124
+ ```
125
+
126
+ 把 OTP 报给 operator。
127
+
128
+ ### Operator
129
+
130
+ ```sh
131
+ aiworker enroll list
132
+ # {"pending":[{"otp":"9CDT-94BK","displayName":"my-laptop",...}]}
133
+
134
+ aiworker enroll approve 9CDT-94BK
135
+ # ✔ 已批准
136
+
137
+ aiworker fleet list
138
+ # {"workers":[{"workerId":"w_xxx","displayName":"my-laptop","online":true,...}]}
139
+ ```
140
+
141
+ worker 端同步打:`√ approved as w_xxx; deviceToken=wtk_...,已加入 fleet`。
142
+
143
+ ---
144
+
145
+ ## 路径 2:self-enroll(自动化批量)
146
+
147
+ Worker 端 env 多两个,省去 operator approve:
148
+
149
+ ```sh
150
+ export AIWORKER_GATEWAY_URL="wss://operator:<basicauth-pwd>@your-gateway.example/ws"
151
+ export AIWORKER_JOIN_TOKEN="<gateway 端配的 join token>"
152
+ export AIWORKER_DISPLAY_NAME="ci-runner-12"
153
+
154
+ bun apps/cli/src/aiworker.ts init
155
+ bun apps/cli/src/aiworker.ts serve --port 3001
156
+ # 自动加入;operator 端 aiworker fleet list 直接见到
157
+ ```
158
+
159
+ > ⚠️ URL 含 basicauth + JOIN_TOKEN 是 fleet 共享 secret,泄露面大。CI 可接受,朋友机器不要给。
160
+
161
+ ---
162
+
163
+ ## 路径 3:手动 pair(高安全)
164
+
165
+ ```sh
166
+ # Worker 端:
167
+ bun apps/cli/src/aiworker.ts init
168
+ # 抓 stdout 的 wtk_xxx
169
+ bun apps/cli/src/aiworker.ts serve --port 3001 --gateway wss://operator:<pwd>@gateway/ws
170
+
171
+ # Operator 端:
172
+ aiworker pair --url wss://operator:<pwd>@gateway/ws \
173
+ --worker-url http://<worker-host>:3001 \
174
+ --bootstrap-token wtk_xxx \
175
+ --display-name production-1
176
+ ```
177
+
178
+ > 限制:gateway 必须能 inbound 到 worker `:3001` 验 token。worker 在 NAT 后需要反向 tunnel;改用 OTP 模式避坑。
179
+
180
+ ---
181
+
182
+ ## 路径 4:docker auto-launch
183
+
184
+ 需要 gateway 启用 `AIWORKER_GATEWAY_CAN_LAUNCH=true` + `docker.sock:ro` mount。
185
+
186
+ ```sh
187
+ aiworker fleet launch --display-name demo
188
+ # gateway supervisor 自动 docker run + scrape bootstrap token + pair
189
+ ```
190
+
191
+ 详见 [`docs/deployment.md`](docs/deployment.md) 的 supervisor overlay 段落。
192
+
193
+ ---
194
+
195
+ ## Operator 日常 cheat sheet
196
+
197
+ ```sh
198
+ # fleet 状态
199
+ aiworker fleet list # 谁在线
200
+ aiworker fleet info <workerId> # 单个 worker 运行时快照
201
+ aiworker fleet remove <workerId> # 摘除(deviceToken 立即失效)
202
+
203
+ # 与 worker 对话(流式 NDJSON)
204
+ aiworker chat <workerId> 'hello'
205
+ aiworker chat <workerId> '继续' --conversation-id <prev-id>
206
+
207
+ # 配置(乐观锁必须带 --if-match)
208
+ aiworker config get <workerId> # 读出含 version
209
+ aiworker config set <workerId> "$(cat new.json)" --if-match <version>
210
+
211
+ # Token 轮换(旧立即失效)
212
+ aiworker token rotate <workerId>
213
+
214
+ # OTP 审批
215
+ aiworker enroll list
216
+ aiworker enroll approve <OTP>
217
+ aiworker enroll reject <OTP>
218
+
219
+ # 日志订阅
220
+ aiworker logs <workerId> --follow --tail 200
221
+
222
+ # 审批 per-tool
223
+ aiworker approvals list
224
+ aiworker approvals grant <workerId> <taskId> <toolCallId> # allow
225
+ aiworker approvals grant <workerId> <taskId> <toolCallId> --deny
226
+
227
+ # 定时任务
228
+ aiworker schedule list <workerId>
229
+ aiworker schedule add <workerId> --expression '0 9 * * *' --prompt '早报' --channel web --chat-id daily
230
+ aiworker schedule remove <workerId> <jobId>
231
+ ```
232
+
233
+ `aiworker` operator 默认 gatewayUrl 在 `~/.aiworker/aim.json`。第一次跑:
234
+
235
+ ```sh
236
+ mkdir -p ~/.aiworker
237
+ cat > ~/.aiworker/aim.json <<EOF
238
+ {
239
+ "gatewayUrl": "wss://operator:<basicauth-pwd>@your-gateway.example/ws",
240
+ "deviceId": "op-$(uuidgen)",
241
+ "deviceToken": "<INTERNAL_SHARED_SECRET>",
242
+ "defaultWorkerId": ""
243
+ }
244
+ EOF
245
+ chmod 600 ~/.aiworker/aim.json
246
+ ```
247
+
248
+ 如果在 gateway 同机跑(loopback),用 `ws://127.0.0.1:3000/ws`,无需 basicauth/token。
249
+
250
+ ---
251
+
252
+ ## Worker 配 LLM(claude-code 示例)
253
+
254
+ ```sh
255
+ NEW='{"brains":[],"brainWriteTarget":"","brainRetrieval":"first-match","executor":{"engine":"claude-code","variant":"default"},"channels":[],"evolution":{"enabled":false,"observationRetentionDays":7}}'
256
+ aiworker config set <workerId> "$NEW" --if-match <current-version>
257
+ ```
258
+
259
+ 可选 `engine`:`http`(OpenAI 兼容)/ `mcp` / `claude-code` / `acp`(gemini/qwen) / `codex` / `cursor`。
260
+
261
+ ---
262
+
263
+ ## 部署形态对比
264
+
265
+ | 形态 | 适用 | 入口 | docker |
266
+ |------|------|------|--------|
267
+ | **裸跑** | 开发 / CI | `aiworker gateway start` / `aiworker serve` 前台 | 无 |
268
+ | **systemd**(Linux 推荐) | 服务器长跑 | `aiworker install systemd [--user\|--system]` | 无 |
269
+ | **docker compose** | 不愿装 bun / per-worker 隔离 | `ops/compose/docker-compose.yml`(GHCR 镜像) | 有 |
270
+
271
+ 详见 [`docs/deployment.md`](docs/deployment.md);公网 HTTPS(Cloudflare + Caddy)单独叠加层在 [`docs/deployment-public-https.md`](docs/deployment-public-https.md)。
272
+
273
+ ---
274
+
275
+ ## 关键 env
276
+
277
+ | 变量 | 用于 | 说明 |
278
+ |---|---|---|
279
+ | `AIWORKER_MASTER_KEY` | gateway / worker | 64 hex;丢了 fleet.db 解不开 — **必须组织级离线备份** |
280
+ | `INTERNAL_SHARED_SECRET` | gateway / 远程 operator | ≥16 chars;远程 aiworker CLI bearer |
281
+ | `AIWORKER_JOIN_TOKEN` | gateway / self-enroll worker | self-enroll 模式触发;与 INTERNAL_SHARED_SECRET 解耦 |
282
+ | `AIWORKER_GATEWAY_URL` | worker | OTP / self-enroll 模式连入口 |
283
+ | `AIWORKER_DISPLAY_NAME` | worker | operator 端识别用 |
284
+ | `AIWORKER_HOME` | gateway / worker | 默认 `~/.aiworker` |
285
+ | `WORKER_DB_PATH` | worker | 默认 `$AIWORKER_HOME/worker.db` |
286
+ | `AIWORKER_FLEET_DB_PATH` | gateway | 默认 `$AIWORKER_HOME/fleet.db` |
287
+ | `AIWORKER_GATEWAY_PORT` | gateway | 默认 3000 |
288
+ | `AIWORKER_ENROLL_OTP_TTL_SEC` | gateway | OTP 过期秒数,默认 300,[30, 3600] |
289
+
290
+ 完整列表见 `apps/api/.env.example` 与 `ops/compose/.env.example`。
291
+
292
+ ---
293
+
294
+ ## 故障排查(高频 3 条)
295
+
296
+ | 现象 | 原因 | 修法 |
297
+ |---|---|---|
298
+ | `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)。
303
+
304
+ ---
305
+
306
+ ## 安全模型
307
+
308
+ - **fleet.db / worker.db 物理隔离**:gateway 永不存 worker 的业务数据
309
+ - **AES-256-GCM** 加密 `registered_workers.apiTokenEnc` + `worker_secrets`
310
+ - **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)。
315
+
316
+ ---
317
+
318
+ ## Backup checklist
319
+
320
+ - **`AIWORKER_MASTER_KEY`** — 离线保管。丢失 = fleet.db 全部 worker 必须重 enroll
321
+ - **fleet.db** — gateway 卷
322
+ - **每个 worker 的 worker.db** — worker 自己的卷
323
+ - **`INTERNAL_SHARED_SECRET`** — operator 凭证
324
+ - **`AIWORKER_JOIN_TOKEN`** — fleet 共享 secret(self-enroll 用)
325
+ - **Caddy basicauth bcrypt hash** — `/etc/caddy/auth.snippet`
326
+
327
+ ---
328
+
329
+ ## Development
330
+
331
+ ```sh
332
+ bun install
333
+ bun run typecheck # 9 packages 全过
334
+ bun run test # 全工作区
335
+ bun run lint
336
+ ```
337
+
338
+ 文档系统(PMA):[`docs/plan/`](docs/plan/) 是历史方案,[`docs/task/`](docs/task/) 是 task 跟踪,[`docs/changelog.md`](docs/changelog.md) 是发布日志。新功能按 `/pma` skill 走 investigate → proposal → implement 三阶段。
339
+
340
+ ---
341
+
342
+ ## License
343
+
344
+ [MIT](LICENSE) © 2026 ZonEase Tech
345
+
346
+ ---
347
+
348
+ ## Status
349
+
350
+ | Module | Status |
351
+ |---|---|
352
+ | 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) |
359
+ | Web SPA pending UI | 🔜 Stage-2 |
360
+ | Multi-host HA | 🔜 Stage-2 |