Skip to content

Commit 509a375

Browse files
author
SqlRush
committed
Add Chrome native host handshake protocol
1 parent b489022 commit 509a375

4 files changed

Lines changed: 66 additions & 3 deletions

File tree

cmd/claude/main.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
)
3333

3434
const version = "0.0.0-dev"
35+
const chromeNativeHostProtocolVersion = "1"
3536

3637
func main() {
3738
os.Exit(run(os.Args[1:], os.Stdin, os.Stdout, os.Stderr))
@@ -236,8 +237,14 @@ func handleChromeNativeHostMessage(raw json.RawMessage) map[string]any {
236237
switch strings.ToLower(strings.TrimSpace(messageType)) {
237238
case "ping":
238239
return map[string]any{"type": "pong", "ok": true}
240+
case "hello", "capabilities":
241+
return chromeNativeHostCapabilitiesResponse()
242+
case "runtime", "session":
243+
return chromeNativeHostRuntimeResponse(strings.ToLower(strings.TrimSpace(messageType)))
239244
case "status":
240-
return map[string]any{"type": "status", "ok": true, "runtime": "ccgo", "version": version}
245+
response := chromeNativeHostRuntimeResponse("status")
246+
response["capabilities"] = chromeNativeHostCapabilities()
247+
return response
241248
default:
242249
if messageType == "" {
243250
messageType = "(missing)"
@@ -246,6 +253,42 @@ func handleChromeNativeHostMessage(raw json.RawMessage) map[string]any {
246253
}
247254
}
248255

256+
func chromeNativeHostCapabilitiesResponse() map[string]any {
257+
return map[string]any{
258+
"type": "capabilities",
259+
"ok": true,
260+
"runtime": "ccgo",
261+
"version": version,
262+
"protocol_version": chromeNativeHostProtocolVersion,
263+
"capabilities": chromeNativeHostCapabilities(),
264+
}
265+
}
266+
267+
func chromeNativeHostRuntimeResponse(responseType string) map[string]any {
268+
if responseType == "" {
269+
responseType = "runtime"
270+
}
271+
return map[string]any{
272+
"type": responseType,
273+
"ok": true,
274+
"runtime": "ccgo",
275+
"version": version,
276+
"protocol_version": chromeNativeHostProtocolVersion,
277+
"pid": os.Getpid(),
278+
}
279+
}
280+
281+
func chromeNativeHostCapabilities() map[string]any {
282+
return map[string]any{
283+
"ping": true,
284+
"status": true,
285+
"hello": true,
286+
"capabilities": true,
287+
"runtime": true,
288+
"session": true,
289+
}
290+
}
291+
249292
func applyCWDFlag(state *bootstrap.State, raw string) error {
250293
cwd := strings.TrimSpace(raw)
251294
if cwd == "" {

cmd/claude/main_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ func TestRunChromeNativeHostRespondsToMessages(t *testing.T) {
107107
if err := integrationspkg.WriteChromeNativeMessage(&stdin, map[string]any{"type": "status"}); err != nil {
108108
t.Fatal(err)
109109
}
110+
if err := integrationspkg.WriteChromeNativeMessage(&stdin, map[string]any{"type": "hello"}); err != nil {
111+
t.Fatal(err)
112+
}
113+
if err := integrationspkg.WriteChromeNativeMessage(&stdin, map[string]any{"type": "session"}); err != nil {
114+
t.Fatal(err)
115+
}
110116
code := run([]string{"--chrome-native-host"}, &stdin, &stdout, &stderr)
111117
if code != 0 {
112118
t.Fatalf("exit = %d stderr=%s", code, stderr.String())
@@ -122,6 +128,20 @@ func TestRunChromeNativeHostRespondsToMessages(t *testing.T) {
122128
if status["type"] != "status" || status["runtime"] != "ccgo" || status["version"] != version {
123129
t.Fatalf("status = %#v", status)
124130
}
131+
if capabilities, ok := status["capabilities"].(map[string]any); !ok || capabilities["ping"] != true || capabilities["session"] != true {
132+
t.Fatalf("status capabilities = %#v", status["capabilities"])
133+
}
134+
hello := readNativeHostTestMessage(t, &stdout)
135+
if hello["type"] != "capabilities" || hello["protocol_version"] != chromeNativeHostProtocolVersion {
136+
t.Fatalf("hello = %#v", hello)
137+
}
138+
if capabilities, ok := hello["capabilities"].(map[string]any); !ok || capabilities["capabilities"] != true {
139+
t.Fatalf("hello capabilities = %#v", hello["capabilities"])
140+
}
141+
session := readNativeHostTestMessage(t, &stdout)
142+
if session["type"] != "session" || session["runtime"] != "ccgo" || session["protocol_version"] != chromeNativeHostProtocolVersion {
143+
t.Fatalf("session = %#v", session)
144+
}
125145
}
126146

127147
func TestRunChromeNativeHostReportsUnsupportedMessage(t *testing.T) {

docs/cc-100-roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ M7 补充:terminal input parser 和 configurable keybinding name parser 现在
14561456
- Chrome/computer-use/voice/native integrations。
14571457
- enterprise/gated/platform-specific behavior。
14581458

1459-
当前状态:已新增 `advanced` settings gate 地基,覆盖 bridge/LSP/telemetry/Chrome/voice/computer-use/native integrations 的独立 bool 开关解析、settings merge、headless `/config show advanced` 和 `/config search` 审计;`advanced.telemetry=true` 时会在 session 目录写入安全摘要 JSONL 诊断事件,记录事件类型、session/model、tool/progress keys、token/compact/error 摘要,不写入用户/助手正文或工具结果内容,并已有安全 JSONL 读取、类型/模型过滤、汇总统计、deterministic trace/span id、JSON summary export、可配置 `telemetryExport` 本地 JSONL exporter / HTTP backend POST、endpoint 脱敏 status,以及 headless `/status show telemetry` trace/span/exporter 审计地基;`advanced.lsp=true` 时才向模型暴露只读 `LSPDiagnostics` 工具,用于读取 session-scoped diagnostics snapshot,并支持 file/severity/limit 过滤,底层已能解析 LSP `textDocument/publishDiagnostics` params/notification payload、按文件替换 snapshot、按 LSP 空 diagnostics 语义清空旧文件诊断;同时会写出 session-scoped LSP manager status,按默认或显式 server definitions 解析 workspace/root marker/file extension 命中情况,将已匹配但未启动的 server 标为 `not_started`,并可通过 headless `/status show lsp` 审计 diagnostics 与 manager runtime state;LSP Content-Length framed JSON-RPC reader/writer 与 diagnostics stream processor 已能持续消费 `textDocument/publishDiagnostics` notification、捕获 initialize response capabilities 并更新 session snapshot;LSP server process lifecycle API 已可启动配置命令、消费 stdout framed diagnostics stream,并把 `running`/`exited`/`failed`、PID 和时间戳写回 manager status;LSP client handshake send path 已可向 server stdin 写入 `initialize`、`initialized` 和 `textDocument/didOpen` framed JSON-RPC,支持 root/client/document metadata 和 file URI/language 默认推断;conversation runner 在 `advanced.lsp=true` 且显式或默认 server definitions 命中 workspace 时,会自动启动可执行命令存在的 LSP server、发送 handshake/startup documents、对缺失命令保持可审计 `not_started` reason,并复用 session diagnostics/manager status 生命周期;`advanced.bridge=true` 时会写出 session-scoped bridge manifest 和 direct connect state,列出 bridge-safe slash/local command 元数据,启动 loopback-only direct HTTP/WebSocket endpoint,提供 `/health`、`/manifest`、`/resolve`、`/execute` 和 `/ws` JSON 通道,执行前强制 bridge-safe 白名单并默认不回传展开后的 prompt 正文,支持可选 bearer/`X-Bridge-Token` token guard,并可通过 headless `/status show bridge` 审计 manifest、HTTP URL、WebSocket URL 和 token-required 状态;`advanced.nativeIntegrations=true` 时会写出 session-scoped native capability manifest、native file index、native clipboard state 和 system/tmux/OSC52 clipboard adapter 检测结果,只记录路径/大小/mtime 等文件元数据、跳过常见 runtime/vendor 目录,clipboard status 不展示文本内容,并已有 ANSI color diff rendering runtime、system/tmux 外部剪贴板命令读写执行 API 和显式 `/native clipboard read|write` 用户路径,可通过 headless `/status show native` 审计 index/clipboard 路径、数量与 adapter 命令计划;任一 `advanced.chrome`/`advanced.voice`/`advanced.computerUse=true` 时会写出 session-scoped integrations manifest 和独立 runtime state file,将 Chrome/voice/computer-use 的 enabled 与 `runtime_state=ready` 分开记录,并记录 browser/native-host、audio-capture、screen-capture/input-control adapter 探测结果;`advanced.chrome=true` 时还会写出 session-scoped Chrome native host manifest 与 wrapper artifact,并已有 `--chrome-native-host` fast path、Chrome native messaging length-prefixed JSON frame 编解码和 ping/status 响应,以及显式 `/native chrome status|install` 用户路径,可将 manifest/wrapper 安装到 macOS/Linux Chrome/Chromium/Edge NativeMessagingHosts 目录,并在 Windows 通过 HKCU NativeMessagingHosts 注册表项注册 manifest;`advanced.voice=true` 时会写出 session-scoped voice capture plan artifact,记录选中的 audio-capture adapter、16kHz/mono/pcm_s16le/streaming 参数,并已有受 duration/max-bytes 限制的 voice capture command runner API、可配置 `CLAUDE_VOICE_TRANSCRIBE_COMMAND` 的 STT command runner,以及显式 `/native voice capture|transcribe` 用户路径;`advanced.computerUse=true` 时会写出 session-scoped computer-use driver plan artifact,记录 screen-capture/input-control adapter、png 截图格式和 screen_pixels 坐标系,并已有 screen capture stdout 捕获、显式 `/native computer screenshot` 与 `/native computer move|click|type|key` 用户路径,以及 xdotool、macOS osascript、Windows PowerShell 输入执行 API,可通过 headless `/status show integrations` 审计 runtime state 路径与 adapter/manifest/voice/computer-use plan 命令计划;未启用时仍不注册或泄露 gated 工具 schema。实际 Chrome 浏览器扩展端协议、voice 实时/服务端 STT 体验、computer-use Wayland/权限边界与更深交互接入等平台增强仍未完成。
1459+
当前状态:已新增 `advanced` settings gate 地基,覆盖 bridge/LSP/telemetry/Chrome/voice/computer-use/native integrations 的独立 bool 开关解析、settings merge、headless `/config show advanced` 和 `/config search` 审计;`advanced.telemetry=true` 时会在 session 目录写入安全摘要 JSONL 诊断事件,记录事件类型、session/model、tool/progress keys、token/compact/error 摘要,不写入用户/助手正文或工具结果内容,并已有安全 JSONL 读取、类型/模型过滤、汇总统计、deterministic trace/span id、JSON summary export、可配置 `telemetryExport` 本地 JSONL exporter / HTTP backend POST、endpoint 脱敏 status,以及 headless `/status show telemetry` trace/span/exporter 审计地基;`advanced.lsp=true` 时才向模型暴露只读 `LSPDiagnostics` 工具,用于读取 session-scoped diagnostics snapshot,并支持 file/severity/limit 过滤,底层已能解析 LSP `textDocument/publishDiagnostics` params/notification payload、按文件替换 snapshot、按 LSP 空 diagnostics 语义清空旧文件诊断;同时会写出 session-scoped LSP manager status,按默认或显式 server definitions 解析 workspace/root marker/file extension 命中情况,将已匹配但未启动的 server 标为 `not_started`,并可通过 headless `/status show lsp` 审计 diagnostics 与 manager runtime state;LSP Content-Length framed JSON-RPC reader/writer 与 diagnostics stream processor 已能持续消费 `textDocument/publishDiagnostics` notification、捕获 initialize response capabilities 并更新 session snapshot;LSP server process lifecycle API 已可启动配置命令、消费 stdout framed diagnostics stream,并把 `running`/`exited`/`failed`、PID 和时间戳写回 manager status;LSP client handshake send path 已可向 server stdin 写入 `initialize`、`initialized` 和 `textDocument/didOpen` framed JSON-RPC,支持 root/client/document metadata 和 file URI/language 默认推断;conversation runner 在 `advanced.lsp=true` 且显式或默认 server definitions 命中 workspace 时,会自动启动可执行命令存在的 LSP server、发送 handshake/startup documents、对缺失命令保持可审计 `not_started` reason,并复用 session diagnostics/manager status 生命周期;`advanced.bridge=true` 时会写出 session-scoped bridge manifest 和 direct connect state,列出 bridge-safe slash/local command 元数据,启动 loopback-only direct HTTP/WebSocket endpoint,提供 `/health`、`/manifest`、`/resolve`、`/execute` 和 `/ws` JSON 通道,执行前强制 bridge-safe 白名单并默认不回传展开后的 prompt 正文,支持可选 bearer/`X-Bridge-Token` token guard,并可通过 headless `/status show bridge` 审计 manifest、HTTP URL、WebSocket URL 和 token-required 状态;`advanced.nativeIntegrations=true` 时会写出 session-scoped native capability manifest、native file index、native clipboard state 和 system/tmux/OSC52 clipboard adapter 检测结果,只记录路径/大小/mtime 等文件元数据、跳过常见 runtime/vendor 目录,clipboard status 不展示文本内容,并已有 ANSI color diff rendering runtime、system/tmux 外部剪贴板命令读写执行 API 和显式 `/native clipboard read|write` 用户路径,可通过 headless `/status show native` 审计 index/clipboard 路径、数量与 adapter 命令计划;任一 `advanced.chrome`/`advanced.voice`/`advanced.computerUse=true` 时会写出 session-scoped integrations manifest 和独立 runtime state file,将 Chrome/voice/computer-use 的 enabled 与 `runtime_state=ready` 分开记录,并记录 browser/native-host、audio-capture、screen-capture/input-control adapter 探测结果;`advanced.chrome=true` 时还会写出 session-scoped Chrome native host manifest 与 wrapper artifact,并已有 `--chrome-native-host` fast path、Chrome native messaging length-prefixed JSON frame 编解码和 ping/status/hello/capabilities/session/runtime 响应,以及显式 `/native chrome status|install` 用户路径,可将 manifest/wrapper 安装到 macOS/Linux Chrome/Chromium/Edge NativeMessagingHosts 目录,并在 Windows 通过 HKCU NativeMessagingHosts 注册表项注册 manifest;`advanced.voice=true` 时会写出 session-scoped voice capture plan artifact,记录选中的 audio-capture adapter、16kHz/mono/pcm_s16le/streaming 参数,并已有受 duration/max-bytes 限制的 voice capture command runner API、可配置 `CLAUDE_VOICE_TRANSCRIBE_COMMAND` 的 STT command runner,以及显式 `/native voice capture|transcribe` 用户路径;`advanced.computerUse=true` 时会写出 session-scoped computer-use driver plan artifact,记录 screen-capture/input-control adapter、png 截图格式和 screen_pixels 坐标系,并已有 screen capture stdout 捕获、显式 `/native computer screenshot` 与 `/native computer move|click|type|key` 用户路径,以及 xdotool、macOS osascript、Windows PowerShell 输入执行 API,可通过 headless `/status show integrations` 审计 runtime state 路径与 adapter/manifest/voice/computer-use plan 命令计划;未启用时仍不注册或泄露 gated 工具 schema。实际 Chrome 扩展 UI/事件通道、voice 实时/服务端 STT 体验、computer-use Wayland/权限边界与更深交互接入等平台增强仍未完成。
14601460

14611461
## Recommended Next Steps
14621462

0 commit comments

Comments
 (0)