Files
claw/docs/superpowers/plans/2026-04-01-claw-ws-execution-cards.md
木炎 bdf8e12246 feat: align browser callback runtime and export flows
Consolidate the browser task runtime around the callback path, add safer artifact opening for Zhihu exports, and cover the new service/browser flows with focused tests and supporting docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:44:53 +08:00

426 lines
9.8 KiB
Markdown
Raw 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.
# Claw-WS 开发执行顺序卡片
> 配套计划:[`2026-04-01-claw-ws-parallel-transport.md`](./2026-04-01-claw-ws-parallel-transport.md)
>
> 使用方式:严格按卡片顺序执行。每张卡片完成后先跑卡片内测试,再进入下一张。不要跳卡,不要提前接线,不要先写 service/client 再回头抽象底层。
---
## 卡片 0执行前约束
**目标**
先锁定边界,避免实现过程中把 pipe 模式改坏。
**必须遵守**
- 现有 pipe 模式必须保持可用
- 新增的是并行 `claw-ws` 模式,不是替换 pipe
- v1 只做单客户端、单任务串行
- `browser_action` / `superrpa_browser` 外部命名保持稳定
- 如果 WS `Eval` 不完整,先禁用相关 browser-script skill 暴露
- 不要提前做多客户端、任务队列、管理接口
**完成标准**
- 开发者明确后续所有改动都围绕“抽象复用 + 并行新增”进行
---
## 卡片 1抽共享 SubmitTask Runner
**目标**
把当前 `BrowserMessage::SubmitTask` 的主执行逻辑从 pipe 入口里抽出来,变成共享执行器。
**先做什么**
1. 新增 `tests/task_runner_test.rs`
2. 先写失败用例:
- 空 instruction
- 无 LLM 配置
- 日志顺序仍然是 `LogEntry` -> `TaskComplete`
**要改哪些文件**
- `src/agent/mod.rs`
- `src/lib.rs`
- `src/agent/task_runner.rs`
- `tests/task_runner_test.rs`
**实现动作**
1.`SubmitTaskRequest`
2.`AgentEventSink`
3.`run_submit_task(...)`
4. 让 pipe 入口只做:
- 解包 `BrowserMessage::SubmitTask`
- 转成 `SubmitTaskRequest`
- 调共享 runner
**绝对不要做**
- 不要在这一张卡里引入 ws backend
- 不要改 tool adapter
- 不要碰 service/client
**本卡测试命令**
```bash
cargo test --test runtime_task_flow_test --test task_runner_test
```
**通过标准**
- 老的 `runtime_task_flow_test` 继续绿
- 新的 `task_runner_test` 通过
- pipe 行为无变化
**完成后提交**
```bash
git commit -m "refactor: extract shared submit-task runner"
```
---
## 卡片 2抽 BrowserBackend 抽象
**目标**
把上层 runtime / orchestration / tool adapter 从 `BrowserPipeTool<T>` 解耦,统一依赖浏览器后端接口。
**先做什么**
1. 新增 `tests/browser_backend_capability_test.rs`
2. 先写失败用例:
- pipe backend 元数据不变
- pipe backend 支持 `Eval`
- `supports_eval() == false` 时不暴露 browser-script tools
**要改哪些文件**
- `src/browser/mod.rs`
- `src/browser/backend.rs`
- `src/browser/pipe_backend.rs`
- `src/compat/browser_tool_adapter.rs`
- `src/compat/browser_script_skill_tool.rs`
- `src/compat/runtime.rs`
- `src/compat/orchestration.rs`
- `src/compat/workflow_executor.rs`
- `src/lib.rs`
- `tests/browser_backend_capability_test.rs`
**实现动作**
1. 定义 `BrowserBackend`
2.`pipe_backend` 包装当前 `BrowserPipeTool`
3. 把上层签名改成 `Arc<dyn BrowserBackend>`
4. 保持工具名不变:
- `browser_action`
- `superrpa_browser`
5. 增加 `supports_eval()` gating
**绝对不要做**
- 不要在这一张卡里接浏览器 ws 协议
- 不要建 service
- 不要加 client 协议
**本卡测试命令**
```bash
cargo test --test browser_tool_test --test compat_browser_tool_test --test browser_backend_capability_test
```
**通过标准**
- 现有 browser tool 相关测试不回归
- 新 capability test 通过
- 上层逻辑已脱离 `BrowserPipeTool<T>` 的硬耦合
**完成后提交**
```bash
git commit -m "refactor: abstract browser backend from pipe transport"
```
---
## 卡片 3写死浏览器 WS 协议 Codec
**目标**
单独做浏览器固定 WebSocket 协议编解码层,不把协议细节散落到 backend 和 service 里。
**先做什么**
1. 新增 `tests/browser_ws_protocol_test.rs`
2. 先写失败用例:
- outbound frame 精确编码
- callback payload 解析
- 异常格式拒绝
- v1 action 覆盖完整
**要改哪些文件**
- `src/browser/ws_protocol.rs`
- `tests/browser_ws_protocol_test.rs`
**实现动作**
1. 按浏览器文档编码数组消息
2. 只支持 v1 必需动作:
- `Navigate`
- `GetText`
- `Click`
- `Type`
- `Eval`
3. 定义 callback 解析和关联规则
4. 对 unsupported / malformed 早失败
**绝对不要做**
- 不要在这张卡里连真实浏览器
- 不要写 service 协议
- 不要把网络连接逻辑塞进 codec
**本卡测试命令**
```bash
cargo test --test browser_ws_protocol_test
```
**通过标准**
- codec 单测全绿
- 无网络依赖
- 已能作为 backend 的纯协议层基础
**完成后提交**
```bash
git commit -m "test: codify fixed browser websocket protocol"
```
---
## 卡片 4实现 Browser WS Backend
**目标**
在 codec 之上提供和 pipe backend 类似的阻塞式 `invoke(...)` 能力。
**先做什么**
1. 新增 `tests/browser_ws_backend_test.rs`
2. 先写失败用例:
- `0 + 无 callback` 成功
-`0` 失败
- `0 + callback` 成功
- callback timeout
- socket drop
**要改哪些文件**
- `src/browser/mod.rs`
- `src/browser/ws_backend.rs`
- `tests/browser_ws_backend_test.rs`
**实现动作**
1. 建长连接管理器
2. 先做串行单飞请求
3. 发送前过 `MacPolicy`
4. 统一即时返回和 callback 返回
5. 输出统一 `CommandOutput`
**绝对不要做**
- 不要在这一张卡里接 service 层
- 不要做多并发 browser request
- 不要直接把浏览器 ws 代码散进 runtime
**本卡测试命令**
```bash
cargo test --test browser_ws_backend_test
```
**通过标准**
- backend 在 mocks/fakes 下稳定通过
- invoke 语义与 pipe backend 接近
- 可供上层 runtime 直接替换使用
**完成后提交**
```bash
git commit -m "feat: add browser websocket backend"
```
---
## 卡片 5实现 sg_claw Service
**目标**
新增本地长驻服务端,承接 client 请求并复用共享 task runner。
**先做什么**
1. 新增 `tests/service_ws_session_test.rs`
2. 先写失败用例:
- 首个客户端接入成功
- 第二个客户端收到 busy
- 断开后状态释放
- 任务重入被拒绝
**要改哪些文件**
- `src/service/mod.rs`
- `src/service/protocol.rs`
- `src/service/server.rs`
- `src/bin/sg_claw.rs`
- `src/lib.rs`
- `Cargo.toml`
- `tests/service_ws_session_test.rs`
**实现动作**
1. 定义 client/service 协议
2. 实现 service 端事件 sink
3. 建单活 session 状态机:
- `Idle`
- `ClientAttached`
- `TaskRunning`
4. 路由 `SubmitTask` 到共享 runner
5. 保持 pipe 入口不变
**绝对不要做**
- 不要在这一张卡里做 client 交互体验优化
- 不要加任务队列
- 不要支持多客户端并发
**本卡测试命令**
```bash
cargo test --test service_ws_session_test
```
**通过标准**
- 服务端会话锁生效
- 共享 runner 可被 service 复用
- pipe 模式入口未受影响
**完成后提交**
```bash
git commit -m "feat: add claw-ws service entrypoint"
```
---
## 卡片 6实现 sg_claw_client
**目标**
新增一个薄客户端,提供类似 `claude/codex` 的交互式命令行体验。
**先做什么**
1. 新增 `tests/service_task_flow_test.rs`
2. 先写失败用例:
- submit-task 送达 service
- 日志按顺序流回
- completion 只到一次
- 完成后断开处理清晰
**要改哪些文件**
- `src/bin/sg_claw_client.rs`
- `Cargo.toml`
- `tests/service_task_flow_test.rs`
**实现动作**
1. 建立到本地 service 的 ws 连接
2. 读取用户输入
3. 发送 `SubmitTask`
4. 实时打印日志
5. 收到 `TaskComplete` 结束本轮
**绝对不要做**
- 不要把 runtime、skills、browser backend 复制进 client
- 不要让 client 直接连浏览器
- 不要让 client 承担业务逻辑
**本卡测试命令**
```bash
cargo test --test service_task_flow_test
cargo build --bin sg_claw --bin sg_claw_client
```
**通过标准**
- client 是薄壳
- task flow 正常
- 两个新 binary 可编译
**完成后提交**
```bash
git commit -m "feat: add interactive claw-ws client"
```
---
## 卡片 7最终接线与回归验证
**目标**
把 ws 路径接起来,同时确认 pipe 路径零回归。
**先做什么**
1. 只增加最小配置项:
- `browser_ws_url`
- `service_ws_listen_addr`
2. 检查外部工具命名保持稳定
**要改哪些文件**
- `Cargo.toml`
- `src/lib.rs`
- `src/config/settings.rs`
- `src/runtime/engine.rs`(如确有必要)
**实现动作**
1. 接入最小配置面
2. 确保 pipe / ws 下工具命名一致
3. 跑旧 pipe 回归
4. 跑新 ws 测试
5. 跑全量 Rust tests
6. 编译所有 binary
7. 做一次真实本地 smoke test
**本卡 pipe 回归命令**
```bash
cargo test --test browser_tool_test --test compat_browser_tool_test --test runtime_task_flow_test --test pipe_handshake_test --test pipe_protocol_test --test task_protocol_test
```
**本卡 ws 测试命令**
```bash
cargo test --test task_runner_test --test browser_ws_protocol_test --test browser_ws_backend_test --test browser_backend_capability_test --test service_ws_session_test --test service_task_flow_test
```
**本卡全量命令**
```bash
cargo test --tests
cargo build --bin sgclaw --bin sg_claw --bin sg_claw_client
```
**手工验证**
1. 启动浏览器,确认 `ws://127.0.0.1:12345` 可用
2. `cargo run --bin sg_claw`
3. 新终端运行 `cargo run --bin sg_claw_client`
4. 发一个简单浏览器任务
5. 确认日志流和单次 completion
6. 确认旧 `cargo run` pipe 入口仍可启动
**通过标准**
- pipe 模式零回归
- ws 模式可独立工作
- 两套模式并行存在
**完成后提交**
```bash
git commit -m "feat: wire parallel claw-ws transport"
```
---
## 一句话执行顺序
严格按下面顺序做:
1. 共享 runner
2. browser backend 抽象
3. ws 协议 codec
4. ws backend
5. service
6. client
7. 配置接线 + 回归
如果顺序乱了,最容易出现的问题是:
- 上层重复实现
- pipe 被误伤
- ws 协议细节扩散到整个工程
- service/client 提前写完后又被迫重构