Files
dsh_ai1net_server/交付物/手机客户端操作WorkBuddy会话-方案与分工-20260928.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

135 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 手机客户端操作 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 可用 |