extension logs --follow 与动作类命令底下的那一层。只有当你要针对这个 socket 编写自己的 harness 时,才需要这个页面。除此之外,CLI 的命令才是受支持的接口。
dev 服务器把这个通道挂在 ready.json 公布的 controlPort 上的 /extjs-control 路径。客户端用信封版本 1 加一个角色来打招呼,角色为 producer、consumer 或 controller。
extension-develop 包会从它的 bridge-entry 模块导出本页涉及的每一个类型与常量,所以 harness 永远不必把这些线路字符串抄进自己的源码里。
LogEvent(版本 1)
每一帧一条日志记录,带v: 1。broker 在接收时分配 seq,并把 runId 归一化为该会话 ready.json 中的值,这样这些行才能和契约对上。
已知时,可选的定位字段会一并附上:
url、hostname、tabId、frameId、windowId、title、stack、errorName、sourceExtensionId、incognito,以及一个自由形式的 data 对象。
dx.signal 事件是运行时针对 dev 循环自身发出的结构化诊断。请按它的 code 与 status 分支处理,并把 remediation 呈现给用户。这个结构是先于它的生产者预留的:目前还没有任何发射方发布,所以今天流里的每个事件携带的都是 log。
ReadyFrame 与 capabilities
握手成功后,服务端会回一个 ready 帧:capabilities 告诉 controller 这个会话会接受什么:eval、storage、reload、可打开的界面,以及用于深层 DOM 检查的 deepDom。deepDom 是一个桥接 capability 字段,不是 CLI flag。bufferedFrom 是仍可回放的最旧缓冲 seq。
GapFrame
broker 宁可丢记录也不会卡住,而且它会明说。gap 帧会告诉你丢了多少条记录、以及为什么:reason 是 ring_overflow、rate_limit、disk_slow 或 slow_consumer 之一。
CommandFrame 与结果
controller 发命令时要带上cmdId、一个 op 和一个目标上下文:
回应是一个结果帧,带有相同的
cmdId、ok、可选的 value,以及在相关时出现的 truncated 与 durationMs。命令帧要求会话是以 --allow-control 启动的,而 eval 还额外要求 --allow-eval。
拒绝码
当 guest 端拒绝一条命令时,结果帧的error.code 会在浏览器自己那句话旁边带上一个机器名。请按码分支,永远不要按文字分支:
导出的常量是
REFUSAL_NEEDS_HEADED_WINDOW、REFUSAL_NEEDS_USER_GESTURE、REFUSAL_SURFACE_NOT_OPEN 与 REFUSAL_API_UNAVAILABLE。
WebSocket 关闭码
4000 段的关闭码都是有意的拒绝,绝不是传输失败:服务端的其他帧
服务端还会广播一些 dev 循环相关的帧,harness 应当容忍它们,也可以加以利用:reload:发给 service worker producer 的一次性重载信号,带一个reloadType,取值为full、service-worker、content-scripts或page。其中page这种只是通知,不做别的。ping:一个保活帧,用来重置 MV3 service worker 的空闲计时器。忽略它即可。
下一步
- 只要 CLI 命令够用就优先用它们,从 ready.json 开始。
- 用 错误码 把桥接失败映射到信封里的错误码。

