chore: seed sgclaw rust baseline

This commit is contained in:
zyl
2026-03-25 02:17:55 +00:00
parent 5063adc530
commit 8757bbb266
26 changed files with 2825 additions and 0 deletions

View File

@@ -0,0 +1,396 @@
# sgClaw 浏览器团队开发启动文档
**适用对象**Chromium / C++ 浏览器开发团队P2
**目标**:浏览器团队拿到本文档后即可独立启动开发,并在一个周期后与 sgClaw 项目团队完成 Pipe 联调。
**协议版本**`1.0`
**冻结日期**`2026-03-24`
---
## 1. 开发目标
浏览器团队本周期只负责浏览器侧 Pipe 接入,不负责 LLM、Skill、Memory、Agent 推理。
本周期结束时,浏览器侧必须具备以下能力:
1. 能从浏览器主进程启动 `sgclaw` Rust 子进程。
2. 能通过 `stdin/stdout``sgclaw` 进行双向 `JSON Line` 通信。
3. 能解析 sgClaw 发来的 `command` 消息,并路由到现有 `CommandRouter`
4. 能执行最小可联调动作:`click``type``navigate``getText`
5. 能返回结构化 `response` 消息。
6. 能在浏览器侧执行域名和 action 白名单校验。
本周期不做:
1. 不改现有 `CommandRouter` 的核心接口。
2. 不新造一套浏览器操作 API。
3. 不改为 HTTP、WebSocket、Named Pipe。
4. 不实现 Rust 侧逻辑。
---
## 2. 架构边界
浏览器侧是父进程,`sgclaw` 是子进程。浏览器侧新增三个模块:
1. `SgClawProcessHost`
负责子进程启动、停止、状态管理、异常退出处理。
2. `PipeListener`
负责异步读取 `sgclaw stdout`,按行解析 JSON 并分发。
3. `MacWhitelistCheck`
负责浏览器侧二次安全校验,防止越权 action 落到 `CommandRouter`
浏览器侧数据流固定如下:
`Side Panel / UI -> SgClawProcessHost -> STDIO Pipe -> sgclaw`
`sgclaw -> STDIO Pipe -> PipeListener -> MacWhitelistCheck -> CommandRouter -> response`
---
## 3. 浏览器团队负责的交付物
本周期交付以下文件或等价模块:
1. `sgclaw_process_host.h`
2. `sgclaw_process_host.cc`
3. `pipe_listener.h`
4. `pipe_listener.cc`
5. `mac_whitelist_check.h`
6. `mac_whitelist_check.cc`
7. `rules.json`
8. `sgclaw_unittests` 中对应单元测试
建议目录:
```text
chrome/browser/superrpa/sgclaw/
sgclaw_process_host.h
sgclaw_process_host.cc
pipe_listener.h
pipe_listener.cc
mac_whitelist_check.h
mac_whitelist_check.cc
test/
sgclaw_process_host_unittest.cc
pipe_listener_unittest.cc
mac_whitelist_check_unittest.cc
resources/
rules.json
```
---
## 4. 冻结接口
### 4.1 传输协议
1. 传输层固定为 `STDIO Pipe`
2. 编码固定为 `UTF-8`
3. 消息边界固定为 `JSON Line`,每行一条完整 JSON。
4. 单条消息最大 `1 MB`
5. `stdout` 只允许输出协议消息,日志必须走 `stderr`
### 4.2 握手协议
浏览器发送:
```json
{"type":"init","version":"1.0","hmac_seed":"0123456789abcdef","capabilities":["browser_action"]}
```
sgClaw 返回:
```json
{"type":"init_ack","version":"1.0","agent_id":"uuid-v4","supported_actions":["click","type","navigate","getText","getHtml","waitForSelector","pageScreenshot","select","scrollTo","getAomSnapshot","storageSet","storageGet","zombieSpawn","zombieKill"]}
```
约束:
1. 浏览器必须在子进程启动后 `5s` 内发送 `init`
2. `5s` 内收不到 `init_ack`,判定启动失败。
3. `version` 不一致,必须立即终止会话。
### 4.3 command 消息格式
```json
{
"type":"command",
"seq":12,
"action":"click",
"params":{"selector":"#submit","wait_after":300},
"security":{
"expected_domain":"oa.example.com",
"hmac":"<hex>"
}
}
```
字段要求:
1. `seq` 为正整数,必须唯一。
2. `action` 必须在白名单内。
3. `params` 必须是对象。
4. `security.expected_domain``security.hmac` 必须存在。
### 4.4 response 消息格式
成功:
```json
{
"type":"response",
"seq":12,
"success":true,
"data":{"text":"提交成功"},
"aom_snapshot":[],
"timing":{"queue_ms":2,"exec_ms":38}
}
```
失败:
```json
{
"type":"response",
"seq":12,
"success":false,
"data":{
"error":{
"code":"CMD_SELECTOR_NOT_FOUND",
"message":"selector '#submit' not found"
}
},
"aom_snapshot":[],
"timing":{"queue_ms":1,"exec_ms":10}
}
```
约束:
1. 一个 `command.seq` 只能对应一个 `response.seq`
2. 失败必须返回结构化错误,不允许只返回字符串。
3. `timing` 必须始终带上。
---
## 5. 本周期最小 Action 集
联调周期只强制四个动作:
1. `click`
2. `type`
3. `navigate`
4. `getText`
动作语义:
1. `click`
调用现有点击能力,支持可选 `wait_after`
2. `type`
在目标输入框输入文本,支持 `clear_first`
3. `navigate`
导航到目标 URL。
4. `getText`
获取目标节点文本。
其余 action 可保留接口但不进入本周期强制验收。
---
## 6. 浏览器侧实现要求
### 6.1 SgClawProcessHost
必须实现:
1. 单例,避免重复创建多个 `sgclaw` 子进程。
2. `Start()` 创建匿名管道并启动子进程。
3. `Stop()` 正常关闭并在超时后强制结束。
4. `OnProcessCrash()` 记录错误并更新状态。
5. 状态机至少包含 `Idle -> Starting -> Running -> Stopped / Crashed`
建议接口:
```cpp
class SgClawProcessHost {
public:
bool Start();
void Stop();
bool IsRunning() const;
bool SendLine(std::string json_line);
};
```
### 6.2 PipeListener
必须实现:
1. 持续读取 `stdout`
2. 以换行符切分 `JSON Line`
3. 拒绝空行、非 JSON、超过 1MB 的消息。
4. 能按 `seq` 追踪一次请求的完整生命周期。
5. 管道断开时通知 `SgClawProcessHost`
### 6.3 CommandRouter 对接
必须实现:
1. `command.action` 到现有浏览器命令的映射表。
2. 尽量复用现有 `CommandRouter`
3. 不允许在 Pipe 层直接写新的页面控制逻辑。
4. response 必须从实际执行结果构造,不允许伪造成功。
建议映射:
1. `click -> CommandRouter.click`
2. `type -> CommandRouter.type`
3. `navigate -> CommandRouter.navigate`
4. `getText -> CommandRouter.getText`
### 6.4 MacWhitelistCheck
必须实现:
1. action 白名单校验。
2. expected_domain 与当前页面域名比对。
3. `rules.json` 加载失败时默认拒绝。
4. 拒绝时返回统一错误码。
建议错误码:
1. `MAC_ACTION_NOT_ALLOWED`
2. `MAC_DOMAIN_NOT_ALLOWED`
3. `MAC_RULES_LOAD_FAILED`
4. `PIPE_INVALID_JSON`
5. `PIPE_MESSAGE_TOO_LARGE`
---
## 7. 浏览器团队开发顺序
### Day 1-2
1. 完成 `SgClawProcessHost` 骨架。
2. 用 dummy 子进程验证启动和退出。
3. 打通 `stdin/stdout` 读写通道。
验收:
1. 能启动 `echo` 或测试进程。
2. 能发送一行字符串并收到回写。
### Day 3-4
1. 完成 `PipeListener`
2. 完成 `init -> init_ack` 握手。
3. 建立 `command` / `response` 解析结构。
验收:
1. 能与 Rust 侧互发 JSON Line。
2. 能处理 `seq` 对应关系。
### Day 5-6
1. 接入 `CommandRouter`
2. 完成 4 个最小 action。
3. 完成 `MacWhitelistCheck`
验收:
1. Rust 发起 `click/type/navigate/getText` 时浏览器真实执行。
2. 非白名单域名被拒绝。
### Day 7
1. 完成浏览器侧单元测试。
2. 提供联调分支和运行说明。
3. 预留半天与项目团队联调。
---
## 8. 浏览器团队自测清单
- [ ] `Start()` 成功启动真实 `sgclaw` 二进制。
- [ ] `Start()` 重复调用不会启动多个实例。
- [ ] `Stop()` 能正常关闭进程。
- [ ] `init -> init_ack` 成功。
- [ ] 超过 1MB 的 JSON 消息会被拒绝。
- [ ] 非 JSON 行会被拒绝。
- [ ] `click/type/navigate/getText` 能成功返回。
- [ ] 域名不匹配时返回 `MAC_DOMAIN_NOT_ALLOWED`
- [ ] `rules.json` 缺失时默认拒绝。
- [ ] 日志中能按 `seq` 查到请求和响应。
---
## 9. 联调输入输出样例
### 9.1 手动握手
浏览器发:
```json
{"type":"init","version":"1.0","hmac_seed":"00112233445566778899aabbccddeeff","capabilities":["browser_action"]}
```
期待 Rust 回:
```json
{"type":"init_ack","version":"1.0","agent_id":"00000000-0000-0000-0000-000000000000","supported_actions":["click","type","navigate","getText","getHtml","waitForSelector","pageScreenshot","select","scrollTo","getAomSnapshot","storageSet","storageGet","zombieSpawn","zombieKill"]}
```
### 9.2 最小 click 联调
Rust 发:
```json
{"type":"command","seq":1,"action":"click","params":{"selector":"#login-btn"},"security":{"expected_domain":"oa.example.com","hmac":"<hex>"}}
```
浏览器回:
```json
{"type":"response","seq":1,"success":true,"data":{},"aom_snapshot":[],"timing":{"queue_ms":1,"exec_ms":35}}
```
---
## 10. 联调日必须提供的东西
浏览器团队在联调前必须准备:
1. 可运行的浏览器分支。
2. `sgclaw` 子进程启动入口。
3. `rules.json` 默认测试配置。
4. 最小测试页面,至少包含一个输入框、一个按钮、一个文本节点。
5. 一份 action 到 `CommandRouter` 的映射表。
6. 一份错误码表。
---
## 11. 周期结束验收标准
以下全部满足,浏览器团队本周期完成:
1. 能在浏览器中稳定启动和停止 `sgclaw`
2. `init -> init_ack` 成功率 100%。
3. `click/type/navigate/getText` 联调通过。
4. 所有失败场景均返回结构化错误。
5. 域名和 action 白名单生效。
6. 与项目团队在同一测试页完成一次端到端演示。
---
## 12. 依赖与协作方式
浏览器团队只依赖以下冻结输入:
1. Pipe 协议版本:`1.0`
2. 消息结构:`init / init_ack / command / response`
3. 最小 action`click/type/navigate/getText`
4. 安全字段:`expected_domain``hmac`
除以上四项外,本周期内其他细节不应阻塞浏览器侧开发。