134 lines
9.8 KiB
Markdown
134 lines
9.8 KiB
Markdown
# 手机客户端操作 WorkBuddy 会话 · 方案与分工(2026-09-28)
|
||||
|
|
|
|||
|
|
> **用户需求(原话)**:「我想做个**客户端**方便手机操作,不想用浏览器不稳定,**确认没问题就指定步骤分工实现**」
|
|||
|
|
> **性质**:规划件(确认结论 + 分工 + 分步)。落地按 §4 的棒次执行。
|
|||
|
|
> **证据分级**:`【已验】`有实测读数 | `【源码在】`代码在位未跑 | `【待实测】`机制在位、行为未验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 0 判定(三句话)
|
|||
|
|
|
|||
|
|
1. **没问题 —— 技术前提全部确认**:WorkBuddy 自带 gateway 提供一整套**面向客户端**的 API(含 **SSE 实时尾随** 与 **发指令**),**不用自研协议、不用反向代理**。
|
|||
|
|
2. **做客户端比做浏览器页更对路**:官方本就是按「外部客户端连接」设计的(`/jobs` 那一套的摘要措辞就是"智能体实例 / 尾随 / 发送后续指令"),而且**有严格防爆破限流 ⇒ 官方预期就是长连接客户端,不是轮询页面**。
|
|||
|
|
3. **但仍有两个点必须先实测**(一次只读调用即可定论)—— 见 §3。**这两个点不解决,"客户端"就只是纸面方案。**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1 技术确认(全部实测)
|
|||
|
|
|
|||
|
|
### 1.1 API 齐备 —— `jobs` 这一套就是客户端需要的全部
|
|||
|
|
|
|||
|
|
| 端点 | 官方摘要(原文) | 客户端用途 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `GET /api/v1/jobs` | **列出智能体实例** | 会话列表(首页) |
|
|||
|
|
| `GET /api/v1/jobs/{id}/transcript` | 立即读取智能体 transcript replay | 进会话时加载历史 |
|
|||
|
|
| `GET /api/v1/jobs/{id}/stream` | **回放并尾随智能体 transcript** | ⭐ **实时看输出(SSE)** |
|
|||
|
|
| `POST /api/v1/jobs/{id}/reply` | **向智能体发送后续指令** | ⭐ **手机发消息** |
|
|||
|
|
| `POST /api/v1/jobs/{id}/stop` / `respawn` | 停止 / 重新拉起 | 中断与重连 |
|
|||
|
|
| `POST /api/v1/jobs/resume` | 恢复归档会话为智能体 | 回到旧会话 |
|
|||
|
|
| `GET /api/v1/jobs/events` | **订阅智能体列表变化** | 列表实时刷新 |
|
|||
|
|
|
|||
|
|
**补充一套(会话视角,非必须但可用)**:`GET /sessions`|`GET /sessions/live`(当前活会话 + writer 占用)|`POST /sessions/{id}/reply`(**不占用 writer**)|`GET /sessions/{id}/history`。
|
|||
|
|
|
|||
|
|
### 1.2 实时流 = SSE【已验】
|
|||
|
|
|
|||
|
|
`text/event-stream` 在 CLI 内出现 **46** 次、`EventSource` **16** 次 ⇒ 客户端用标准 SSE 客户端即可,⛔ **不需要 WebSocket,也不需要轮询**。
|
|||
|
|
|
|||
|
|
### 1.3 鉴权:默认开,且有**防爆破限流**(这条决定客户端架构)
|
|||
|
|
|
|||
|
|
- `--auth <mode>`,**默认 `password`**(`none` 会「让任何本机进程执行命令并读写文件」)。
|
|||
|
|
- 取序:`CODEBUDDY_GATEWAY_PASSWORD` → `settings.gateway.password` → **随机生成**。
|
|||
|
|
- 带凭据方式:**`?password=<x>` query** 或 **Cookie**。
|
|||
|
|
- 🔴 **限流**:`minuteLimiter(2, 60s)` + `hourLimiter(12, 3600s)`(在鉴权中间件内,防爆破)⇒ **客户端必须建立 Cookie 会话后复用,⛔ 绝不能每次请求都带 query 密码**,否则几分钟内就被打满。
|
|||
|
|
|
|||
|
|
### 1.4 网络可达性【已验】
|
|||
|
|
|
|||
|
|
CLI 官方提示原文:`codebuddy --serve --host 0.0.0.0 --port <port>` → 「Access via `http://<your-ip>:<port>`」⇒ **支持局域网直连**;另有 tunnel 选项(`CODEBUDDY_GATEWAY_FORCE_TUNNEL`)。默认 `--host 127.0.0.1`(**当前即默认态,手机连不上**)。
|
|||
|
|
|
|||
|
|
### 1.5 客户端基座已就绪(不用从零起)
|
|||
|
|
|
|||
|
|
| 件 | 实测 |
|
|||
|
|
|---|---|
|
|||
|
|
| Android 壳 | `E:/github/dsh-client/apps/android`,**Capacitor 8.5.2**(`appId com.dsh.client`) |
|
|||
|
|
| 既有 APK | `app-debug.apk` **4,118,462 B**(曾构建成功) |
|
|||
|
|
| 构建工具链 | `E:/Android`:**JDK 21** + SDK android-36 + adb 37.0.1(实测 `java -version`/`adb version` 均可用) |
|
|||
|
|
| 壳的地址策略 | 配置注明「平台地址一律**运行时注入**,⛔ 不写死」⇒ 与"连哪台电脑的 gateway"天然契合 |
|
|||
|
|
|
|||
|
|
⚠️ 必读坑:该壳的 `@capacitor/[email protected]` **要求 Java 21**(用 JDK 17 会报 `Java compilation initialization error`)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2 方案:客户端形态与数据流
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Android 客户端(Capacitor 壳 + 自写页面/逻辑)
|
|||
|
|
│ ① SSE 建长连(/jobs/{id}/stream)—— 实时看,不轮询
|
|||
|
|
│ ② POST /jobs/{id}/reply —— 发消息
|
|||
|
|
│ ③ GET /jobs —— 列表
|
|||
|
|
▼
|
|||
|
|
WorkBuddy gateway(WorkBuddy.exe 内起,默认 127.0.0.1:<随机口>)
|
|||
|
|
▼
|
|||
|
|
你电脑上的 WorkBuddy 会话(同一份会话库)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**客户端最小功能集(MVP)**:会话列表 → 进会话看历史 → **SSE 跟实时输出** → 发一句 → 中断/重连。就这五件事,别的先不做。
|
|||
|
|
|
|||
|
|
**承载三选一**(按"不带来其他东西"排序):
|
|||
|
|
|
|||
|
|
| 方案 | 做法 | 优 | 缺 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **A · 局域网直连**(推荐先走) | gateway 改绑 `--host 0.0.0.0 --port <固定>`,手机同 WiFi 直连 | **零新增**、当天可验、不出内网 | 只在家里/同一 WiFi 用 |
|
|||
|
|
| **B · 官方隧道** | `CODEBUDDY_GATEWAY_FORCE_TUNNEL` | 官方实现、无需自建 | 依赖厂商隧道服务,行为待实测 |
|
|||
|
|
| **C · ai1net 覆盖网络** | 复用既有中继(设备声明端口 + 443 兜底,已 28 条判据绿) | 出门也能用、数据自己拿着 | 要动平台侧一条通道(属另一条线) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3 🔴 两个必须先实测的点("确认没问题"的最后一公里)
|
|||
|
|
|
|||
|
|
| # | 未验证点 | 为什么关键 | 怎么验(一条即可定论) | 成本 |
|
|||
|
|
|---|---|---|---|---|
|
|||
|
|
| **U1** | **`/jobs` 认不认得「桌面 App 里正在聊的那个会话」** | 若不认,客户端只能操作"gateway 自己起的会话",那就**不是**你要的"操作现在的会话" | 取到凭据后调 `GET /api/v1/jobs`,看列表里有没有当前会话;再 `GET /sessions/live` 看 `sessionId` 是否指向它 | 只读,**零副作用** |
|
|||
|
|
| **U2** | **凭据怎么稳定给客户端** | 本机 `settings.json` **无 `gateway` 段** ⇒ 密码是**随机生成**的(代码里会存进 settings,但本机未见)⇒ 现在拿不到,客户端接不上 | 定一个可控密码(写 `settings.gateway.password` 或设 `CODEBUDDY_GATEWAY_PASSWORD`),重启宿主后验 401→200 | 一处配置,可撤回 |
|
|||
|
|
|
|||
|
|
⚠️ **U2 有个前置约束**:改配置需 **重启 WorkBuddy** 才生效 —— 而**本会话就跑在 WorkBuddy 里**(重启会中断当前会话)⇒ 这一步必须**由你选时机**,或改为"设环境变量后由你重启一次"。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4 分工与步骤(按你此前定的口径:本会话管平台宿主、anywhere 管 Android)
|
|||
|
|
|
|||
|
|
| 棒 | 归属 | 做什么 | 判据(可机器验) |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **第 1 棒** | **本会话(平台/宿主线)** | ① 定 U2:设一个可控凭据(写入或 env,与你确认时机)② 重启后验 `401 → 200` ③ 跑 U1 只读实测,把"认不认当前会话"定论 ④ 定承载方案(A/B/C 选一)⑤ 出**对接单**给客户端线 | `GET /api/v1/jobs` 有返回且含目标会话 ⇒ U1 定论;`/health` 从 401 变 200 ⇒ U2 定论 |
|
|||
|
|
| **第 2 棒** | **anywhere 线(Android)** | 按对接单实现客户端 MVP:列表 / 历史 / **SSE 尾随** / 发送 / 重连;复用 `E:/github/dsh-client/apps/android` 壳 + `E:/Android` 工具链出包 | 装机后可列会话、可看到实时输出、可发一条并被电脑端会话采纳 |
|
|||
|
|
| **第 3 棒** | **联调(两条线合)** | 真机端到端 + 断网重连 + 后台切回 | 全程无轮询(看服务端限流计数不打满);切后台再回来能续上 |
|
|||
|
|
|
|||
|
|
**为什么这么分**:第 1 棒全是"宿主侧 + 一次只读调用",属本会话的能力半径(不动平台代码、不动插件);第 2 棒是 Android 工程活,正是 anywhere 线的分工;第 3 棒必须两条线合,因为要同时看两端。
|
|||
|
|
|
|||
|
|
**⛔ 本方案不做的**:不改 dsh 平台 · 不改 one 插件 · 不自研协议/反向代理 · 不引入第三方隧道(除非选 B)· 不做浏览器页(用户已明确排除)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5 风险与边界
|
|||
|
|
|
|||
|
|
1. **重启宿主**:U2 生效需重启 WorkBuddy,会中断当前会话 ⇒ 时机由你定。
|
|||
|
|
2. **权限面**:gateway 能**在你电脑上执行任务、改会话**。**只绑 `127.0.0.1` 时风险最低**;一旦改 `0.0.0.0` 或挂中继,**可见面显著扩大** ⇒ 那一步我之前给你的"权限影响评估"必须先做(R5)。
|
|||
|
|
3. **限流是设计不是障碍**:客户端只要走 SSE + Cookie 会话就不会碰到;⛔ 若写成轮询页(正是你不想要的那种),会被限流打满 —— 这反过来证明**客户端形态是对的**。
|
|||
|
|
4. **凭据强度**:自设密码请用长随机串;⛔ 不要用 `--auth none`(那等于"任何本机进程都能执行命令")。
|
|||
|
|
5. **官方 `web-ui` 未构建且源码不在本机** ⇒ 界面要自写(这正是"做客户端"的代价,已在分工里算上)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附:取证命令与读数
|
|||
|
|
|
|||
|
|
| # | 取证点 | 读数 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 1 | 提取 CLI 内全部 `/api/v1` 路由 | **129 条** |
|
|||
|
|
| 2 | 「401 = 路由存在 / 404 = 不存在」免凭据判据 | `/sessions/live`、`/sessions/xxx/reply` 均 **401**(非 404) |
|
|||
|
|
| 3 | `jobs` 端点摘要 | 列出智能体实例 · **回放并尾随 transcript** · **发送后续指令** · 订阅列表变化 · 停止/重拉/恢复 |
|
|||
|
|
| 4 | SSE 证据 | `text/event-stream` **46** 次 · `EventSource` **16** 次 |
|
|||
|
|
| 5 | `--auth` 默认值 | **password**(`none` =「让任何本机进程执行命令并读写文件」) |
|
|||
|
|
| 6 | 鉴权限流 | `RateLimiter(2, 60s)` + `RateLimiter(12, 3600s)` |
|
|||
|
|
| 7 | 监听参数 | `--host` 默认 `127.0.0.1`;官方提示 `--host 0.0.0.0 --port N` → `http://<your-ip>:N` |
|
|||
|
|
| 8 | gateway 宿主 | `WorkBuddy.exe`(端口 50753/53305/57900) |
|
|||
|
|
| 9 | 本机 settings | **无 `gateway` 段** ⇒ 凭据需定(U2) |
|
|||
|
|
| 10 | Android 基座 | `apps/android` Capacitor 8.5.2 · APK 4,118,462 B · `E:/Android` JDK21+Sdk36+adb 可用 |
|