Files
cdp_hub/docs/api.md
T

118 lines
6.9 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.
# API / 模块合约
MVP 首先提供本地 Go application service 和 CLI;是否增加 loopback HTTP/WebSocket 在 T-203 决策。时间使用 RFC3339,路径使用规范化绝对路径。
## 核心类型
代码权威类型位于 `internal/domain/browser.go`:`BrowserKind`、`LaunchSpec`、`InstanceStatus`、`InstanceView`、`BrowserEvent` 和稳定错误码。`LaunchSpec.Normalize()` 负责 browser kind、绝对 user data dir、受控的 loopback remote debugging port,以及非空时的 http/https URL 校验;空 URL 表示打开浏览器默认页。
`LaunchSpec` 使用已分配的 `RemoteDebugPort`;端口分配不属于 UI,也不允许由 `ExtraArgs` 覆盖。`InstanceView` 返回实际关联端口、PID、占用来源和归属。外部关联只公开经 `DevToolsActivePort` 与 `/json/version` 验证的端口,不公开 CDP WebSocket URL。
只读 CDP 目标查看使用 platform `RemoteDebugTargetInspector`:
```go
type RemoteDebugTarget struct {
ID string
Type string
Title string
URL string // 已移除 userinfo、query 与 fragment
}
type RemoteDebugTargetInspector interface {
ListRemoteDebugTargets(ctx context.Context, kind BrowserKind, port int) ([]RemoteDebugTarget, error)
}
```
调用者必须提供当前实例已经验证的实际端口;实现仍会复核 `/json/version` 的浏览器类型。该接口只请求 loopback HTTP `/json/list`,不公开或使用 `webSocketDebuggerUrl`,也不提供导航、关闭、创建 target 或执行脚本的接口。
UI 编辑使用独立的 `EditableInstance` DTO(`ID`、名称、浏览器类型、User Data Dir、启动 URL、`ProxyID`),不将运行时 PID、状态、来源或实际远程调试端口写回配置。`ProxyProfile` DTO 只包含 `ID`、必填且大小写无关唯一的显示名称、已校验的无认证端点;不提供认证字段。`InstanceRow.ProxyID` 是唯一持久关联,列表中的代理名称是按当前代理 DTO 推导的显示值,不持久化副本。状态刷新使用 `RefreshInstanceStatus(ctx, []InstanceSnapshot) ([]InstanceStatusResult, error)` 形状:每个结果以 `ID` 和快照版本对应,错误可按行返回;实现只能检查调用方提供的实例范围。
## Application service
```go
type BrowserManager interface {
Start(ctx context.Context, spec LaunchSpec) (InstanceView, error)
List(ctx context.Context) ([]InstanceView, error)
Get(ctx context.Context, id string) (InstanceView, error)
Stop(ctx context.Context, id string, force bool) error
Restart(ctx context.Context, id string) (InstanceView, error)
}
```
`Stop(force=false)` 只执行优雅关闭;强制关闭必须由明确用户动作或 CLI `--force` 触发。
平台实现通过实例级 `StopProfile(userDataDir, force)` 执行关闭;force 只对已注册并经过身份绑定的实例生效。
GUI 将优雅停止封装为异步 `InstanceStopper(ctx, InstanceRow) error` adapter;adapter 只接受当前配置行并执行 `force=false`,不暴露平台句柄或允许调用方传递任意 PID。
参数数组由 `internal/platform/browser.BuildArgs` 生成;Chrome/Edge executable 由同包 `Discoverer.Resolve` 解析。二者都不接收 shell 命令行字符串。CDP 端点检测和端口分配均通过 platform port 执行,UI 只消费 DTO 结果。
状态刷新、受管进程退出、目录选择和 CDP 页面目标读取必须通过后台 adapter 回到 UI 结果通道;UI frame 不直接做进程、文件或 CDP I/O。受管退出结果至少包含实例 ID、启动代次、受管 PID、退出码和是否为 Chub 请求停止;UI 以实例 ID、代次和 PID 丢弃过期结果。刷新和页面目标读取都不构成外部实例接管授权。
设置页浏览器 executable 选择使用 platform 文件选择契约;它不发现、启动、关闭或检查浏览器进程:
```go
type ExecutablePicker interface {
ChooseExecutable(ctx context.Context) (string, error)
}
```
Windows 实现只返回绝对 `.exe` 路径;用户取消返回可识别的取消错误。UI 在后台调用该契约,并以 `PathField` 和请求代次丢弃过期结果。选择成功才改写对应 Chrome/Edge 字段;同字段的搜索/选择状态和文字反馈必须独立保存,不能依赖页面底部的全局消息。
Windows 通知区域使用仅限 platform 的内部 DTO;Gio shell 不直接调用 Shell API:
```go
type TrayCommand uint8
const (
TrayCommandShow TrayCommand = iota
TrayCommandRefresh
TrayCommandExit
)
type TrayState struct {
ManagedRunning int
ExternalLinked int
AttentionCount int
}
```
原生 adapter 通过结果通道发布 `TrayCommand`,并只接收 `TrayState` 汇总来更新 Tooltip 或图标状态。不得在 DTO 中放入实例名称、路径、URL、代理、PID、CDP 地址或平台句柄;`TrayCommand` 不是实例启动、停止、重启、删除或接管 API。
本地配置入口统一为:
```go
func DefaultPath() (string, error) // <dir(os.Executable())>\\config.json
func LegacyPath() (string, error) // %APPDATA%\\chub\\config.json,仅用于一次迁移
func OpenDefault() (*Store, error) // 目标优先;必要时校验并原子迁移 legacy
func DefaultInstanceUserDataDir(instanceID string) (string, error) // <dir(os.Executable())>\\user_data_dirs\\<instanceID>
```
调用方不得把当前工作目录作为配置来源,也不得自行复制、删除或合并 legacy 文件。`OpenDefault` 的迁移是文件级配置迁移,不迁移 `UserDataDir`、日志目录或浏览器文件;目标文件存在、legacy 缺失时均不产生写入。`DefaultInstanceUserDataDir` 只生成绝对默认字符串,不创建目录;调用方必须先分配稳定、唯一的实例 ID。迁移失败返回稳定的配置错误,调用方不得改用 legacy 继续写入。
## CLI 当前合约
```text
chub start --browser chrome --user-data-dir <dir> [--profile-directory <name>] [--url <url>]
chub list
chub stop <instance-id> [--force]
chub restart <instance-id>
chub events
```
退出码:0 成功,2 参数错误,3 profile 占用,4 实例不存在,5 身份校验失败,6 系统权限/进程错误。
当前 `list` 和 `events` 已输出 JSON;`events` 输出本地配置快照 JSON,后续 loopback transport 接入后升级为 JSON Lines 持续流。`start/stop/restart` 已保留稳定命令和错误码,等待 BrowserManager adapter 接入。
## 事件
| 事件 | 触发 | 负载 |
| --- | --- | --- |
| `browser.started` | 新实例完成启动 | InstanceView |
| `browser.status.changed` | 状态变化 | instance_id、status、pid、remote_debug_port、ownership、error_code |
| `browser.exited` | Chub 当前会话受管根进程退出 | instance_id、launch_generation、pid、exit_code、expected_stop |
事件禁止携带密码、Cookie、Token、完整代理认证信息或原始系统堆栈。
应用内 `application.EventBus` 使用带缓冲的订阅通道,发布不阻塞进程监控;UI 通过订阅刷新状态,取消订阅会关闭对应通道。