# 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` 解耦,统一依赖浏览器后端接口。 **先做什么** 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` 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` 的硬耦合 **完成后提交** ```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 提前写完后又被迫重构