Skip to content

Commit 1760ff3

Browse files
author
SqlRush
committed
Add integration runtime state files
1 parent 41f1701 commit 1760ff3

8 files changed

Lines changed: 207 additions & 18 deletions

File tree

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,只记录路径/大小/mtime 等文件元数据、跳过常见 runtime/vendor 目录,clipboard status 不展示文本内容,并已有 ANSI color diff rendering runtime,可通过 headless `/status show native` 审计 index/clipboard 路径与数量;任一 `advanced.chrome`/`advanced.voice`/`advanced.computerUse=true` 时会写出 session-scoped integrations manifest,将 Chrome/voice/computer-use 的 enabled 与 `runtime_state` 分开记录,当前启用项明确标为 `not_wired`,并可通过 headless `/status show integrations` 审计;未启用时仍不注册或泄露 gated 工具 schema。实际 Chrome/voice/computer-use runtime,以及 system/tmux clipboard 等平台增强仍未完成。
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,只记录路径/大小/mtime 等文件元数据、跳过常见 runtime/vendor 目录,clipboard status 不展示文本内容,并已有 ANSI color diff rendering runtime,可通过 headless `/status show native` 审计 index/clipboard 路径与数量;任一 `advanced.chrome`/`advanced.voice`/`advanced.computerUse=true` 时会写出 session-scoped integrations manifest 和独立 runtime state file,将 Chrome/voice/computer-use 的 enabled 与 `runtime_state=ready` 分开记录,并可通过 headless `/status show integrations` 审计 runtime state 路径;未启用时仍不注册或泄露 gated 工具 schema。实际 Chrome native host/browser adapter、voice audio device adapter、computer-use OS driver,以及 system/tmux clipboard 等平台增强仍未完成。
14601460

14611461
## Recommended Next Steps
14621462

docs/claude-code-go-rewrite-plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ test/parity/ # golden tests against TS/official behavior
745745
- 每个 gated feature 独立开关测试。
746746
- 不启用 feature 时二进制行为和可见 schema 不泄露 gated 工具/命令。
747747

748-
- 本轮补充:新增 `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,只记录路径/大小/mtime 等文件元数据、跳过常见 runtime/vendor 目录,clipboard status 不展示文本内容,并已有 ANSI color diff rendering runtime,可通过 headless `/status show native` 审计 index/clipboard 路径与数量;任一 `advanced.chrome`/`advanced.voice`/`advanced.computerUse=true` 时会写出 session-scoped integrations manifest,将 Chrome/voice/computer-use 的 enabled 与 `runtime_state` 分开记录,当前启用项明确标为 `not_wired`,并可通过 headless `/status show integrations` 审计;未启用时仍不注册或泄露 gated 工具 schema。实际 Chrome/voice/computer-use runtime,以及 system/tmux clipboard 等平台增强仍未完成。
748+
- 本轮补充:新增 `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,只记录路径/大小/mtime 等文件元数据、跳过常见 runtime/vendor 目录,clipboard status 不展示文本内容,并已有 ANSI color diff rendering runtime,可通过 headless `/status show native` 审计 index/clipboard 路径与数量;任一 `advanced.chrome`/`advanced.voice`/`advanced.computerUse=true` 时会写出 session-scoped integrations manifest 和独立 runtime state file,将 Chrome/voice/computer-use 的 enabled 与 `runtime_state=ready` 分开记录,并可通过 headless `/status show integrations` 审计 runtime state 路径;未启用时仍不注册或泄露 gated 工具 schema。实际 Chrome native host/browser adapter、voice audio device adapter、computer-use OS driver,以及 system/tmux clipboard 等平台增强仍未完成。
749749

750750
### M12: Parity hardening
751751

internal/conversation/run.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,15 @@ func (r Runner) maybeWriteIntegrationsManifest() {
786786
if path == "" {
787787
return
788788
}
789-
_ = integrationspkg.WriteManifest(path, integrationspkg.BuildManifest(r.SessionID, r.WorkingDirectory, settings.Advanced))
789+
manifest := integrationspkg.BuildManifest(r.SessionID, r.WorkingDirectory, settings.Advanced)
790+
_ = integrationspkg.WriteManifest(path, manifest)
791+
for _, integration := range manifest.Integrations {
792+
statePath := integrationspkg.SessionRuntimeStatePath(r.SessionPath, r.SessionID, integration.Name)
793+
if statePath == "" {
794+
continue
795+
}
796+
_ = integrationspkg.WriteRuntimeState(statePath, integrationspkg.BuildRuntimeState(r.SessionPath, r.SessionID, r.WorkingDirectory, integration))
797+
}
790798
}
791799

792800
func (r Runner) maybeWriteNativeManifest() {
@@ -1025,7 +1033,12 @@ func (r Runner) formatStatusIntegrations() string {
10251033
if state == "" {
10261034
state = integrationspkg.RuntimeStateDisabled
10271035
}
1028-
lines = append(lines, fmt.Sprintf("- %s: enabled=%s runtime=%s", integration.Name, boolEnabledText(integration.Enabled), state))
1036+
line := fmt.Sprintf("- %s: enabled=%s runtime=%s", integration.Name, boolEnabledText(integration.Enabled), state)
1037+
statePath := integrationspkg.SessionRuntimeStatePath(r.SessionPath, r.SessionID, integration.Name)
1038+
if runtimeState, err := integrationspkg.LoadRuntimeState(statePath); err == nil && runtimeState.GeneratedAt != "" {
1039+
line += " state=" + statePath
1040+
}
1041+
lines = append(lines, line)
10291042
}
10301043
}
10311044
return strings.Join(lines, "\n")

internal/conversation/run_test.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,11 +2182,25 @@ func TestRunnerWritesGatedIntegrationsManifest(t *testing.T) {
21822182
if integrationspkg.CountEnabled(manifest.Integrations) != 2 {
21832183
t.Fatalf("manifest integrations = %#v", manifest.Integrations)
21842184
}
2185-
if !integrationHasState(manifest.Integrations, "chrome", true, integrationspkg.RuntimeStateNotWired) ||
2186-
!integrationHasState(manifest.Integrations, "computer_use", true, integrationspkg.RuntimeStateNotWired) ||
2185+
if !integrationHasState(manifest.Integrations, "chrome", true, integrationspkg.RuntimeStateReady) ||
2186+
!integrationHasState(manifest.Integrations, "computer_use", true, integrationspkg.RuntimeStateReady) ||
21872187
!integrationHasState(manifest.Integrations, "voice", false, integrationspkg.RuntimeStateDisabled) {
21882188
t.Fatalf("manifest integration states = %#v", manifest.Integrations)
21892189
}
2190+
chromeState, err := integrationspkg.LoadRuntimeState(integrationspkg.SessionRuntimeStatePath(transcriptPath, "sess_integrations", "chrome"))
2191+
if err != nil {
2192+
t.Fatal(err)
2193+
}
2194+
if chromeState.SessionID != "sess_integrations" || chromeState.Name != "chrome" || chromeState.RuntimeState != integrationspkg.RuntimeStateReady || chromeState.Artifacts["state"] == "" {
2195+
t.Fatalf("chrome runtime state = %#v", chromeState)
2196+
}
2197+
computerState, err := integrationspkg.LoadRuntimeState(integrationspkg.SessionRuntimeStatePath(transcriptPath, "sess_integrations", "computer_use"))
2198+
if err != nil {
2199+
t.Fatal(err)
2200+
}
2201+
if computerState.Name != "computer_use" || computerState.RuntimeState != integrationspkg.RuntimeStateReady {
2202+
t.Fatalf("computer runtime state = %#v", computerState)
2203+
}
21902204
}
21912205

21922206
func TestRunnerExecutesStatusShowSectionsWithoutQuery(t *testing.T) {

internal/integrations/manifest.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const manifestFileName = "integrations-manifest.json"
1717
const (
1818
RuntimeStateDisabled = "disabled"
1919
RuntimeStateNotWired = "not_wired"
20+
RuntimeStateReady = "ready"
2021
)
2122

2223
type Manifest struct {
@@ -46,9 +47,9 @@ func BuildManifest(sessionID contracts.ID, cwd string, advanced *contracts.Advan
4647
WorkingDirectory: cwd,
4748
GeneratedAt: time.Now().UTC().Format(time.RFC3339Nano),
4849
Integrations: []Integration{
49-
buildIntegration("chrome", enabled(advancedChrome(advanced)), "Chrome native host runtime is not wired"),
50-
buildIntegration("computer_use", enabled(advancedComputerUse(advanced)), "computer-use runtime is not wired"),
51-
buildIntegration("voice", enabled(advancedVoice(advanced)), "voice runtime is not wired"),
50+
buildIntegration("chrome", enabled(advancedChrome(advanced)), "session-scoped Chrome runtime state is ready"),
51+
buildIntegration("computer_use", enabled(advancedComputerUse(advanced)), "session-scoped computer-use runtime state is ready"),
52+
buildIntegration("voice", enabled(advancedVoice(advanced)), "session-scoped voice runtime state is ready"),
5253
},
5354
}
5455
sort.SliceStable(manifest.Integrations, func(i, j int) bool {
@@ -116,13 +117,13 @@ func CountByRuntimeState(integrations []Integration) map[string]int {
116117
return counts
117118
}
118119

119-
func buildIntegration(name string, isEnabled bool, notWiredDetail string) Integration {
120+
func buildIntegration(name string, isEnabled bool, readyDetail string) Integration {
120121
if isEnabled {
121122
return Integration{
122123
Name: name,
123124
Enabled: true,
124-
RuntimeState: RuntimeStateNotWired,
125-
Detail: notWiredDetail,
125+
RuntimeState: RuntimeStateReady,
126+
Detail: readyDetail,
126127
}
127128
}
128129
return Integration{

0 commit comments

Comments
 (0)