# 13 Hermes VSCode 插件对照审查 v1 > 状态:reference > > 归档说明(2026-05-21):P0 缺口已拆分到 `7-30` 至 `7-33` 并完成归档;本文保留 Hermes VSCode 插件对照证据和 P1/P2 参考项。 > > 日期:2026-05-20 > > 范围:`reference-code/hermes-vscode-main` 对照 MNote 当前 `mnote-web` Hermes / ACP / Page AI 实现。 ## 1. 审查方法 本轮先以 Hermes VSCode 插件为参考实现,核查它对 ACP runtime、会话恢复、权限请求、tool call、上下文注入和 Webview 控制面的处理方式,再对照 MNote 当前 Rust Web 主链: - 参考实现:`src/acpClient.ts`、`src/sessionManager.ts`、`src/protocol.ts`、`src/chatPanel.ts`、`src/sessionStore.ts`、`src/webview/main.ts`、`src/webview/renderers.ts`、`src/modelCatalog.ts`、`src/skillCatalog.ts`。 - MNote 实现:`rust/crates/mnote-web/src/acp_client.rs`、`acp_session_manager.rs`、`acp_bridge.rs`、`routes/hermes_client.rs`、`ssr/pages/layout.rs`。 - 审查口径:不把 VSCode UI 状态照搬为 MNote 真相源;MNote 继续遵守 local-first、Rust Web 承载、Page AI 文件引用 + agent 原生 patch/diff + watcher 同步主线。 ## 2. Hermes VSCode 可借鉴模型 - `SessionManager.ensureSession()` 在已有 `storedSessionId` 时必须调用 ACP `session/load`。仅把旧 session id 写回内存会产生 phantom session,后续 `session/prompt` 可能静默失败。 - `AcpClient` 区分 JSON-RPC response、notification 和 incoming request;`session/request_permission` 通过 handler 返回真实 allow / deny 结果。 - `session/update` 中的 `tool_call.locations[]` 会被解析保存;`tool_call_update completed` 后,`read` 打开 preview editor,`edit` 打开 persistent editor。 - `session_info_update` 会更新会话标题;`plan` / todo tool 输出可渲染为任务 overlay,而不是丢弃。 - Webview 对 slash command 有 allowlist,slash 响应渲染为居中的 system message,不混入普通 user / assistant 泡泡。 - model / skill picker 来自 Hermes 本地缓存和 `SKILL.md` 目录,作为 agent 控制面的一部分。 - Prompt 注入包含 cwd、active file、selection、open tabs、附件引用和 skills advisory,不把这些上下文当成长期正文真相。 ## 3. MNote 当前状态 - Rust `AcpSessionManager` 已有 `session/new`、`session/prompt`、`session/cancel`、streaming dedup、typed event 和 usage / thought / tool / plan / session info 解析雏形。 - `acp_bridge.rs` 已把 TextDelta、ThoughtDelta、ToolCall、ToolCallUpdate、UsageUpdate、PermissionRequest 转成 SSE,但 `SessionInfoUpdate` 和 `PlanUpdate` 当前仍被丢弃。 - `layout.rs` Page AI 已有 session list/detail/search/resume/rename/delete、localStorage cache、Convex/local ACP runtime store、permission dialog、tool event UI、profile/skills 控制面和 usage summary。 - `routes/hermes_client.rs` 已有 local-first AI session JSONL、Convex ACP runtime store、run queue、abort 和 local agent audit。 - 当前 `resume_session` 只恢复 MNote/Convex/local 会话历史,不等同于对 ACP adapter 调用 `session/load` 注册底层 ACP session。 - 当前 `AcpClient` 对 incoming `session/request_permission` 仍立即返回 unsupported/deny,前端按钮没有真正回传 ACP 决策。 - 当前 `SessionUpdate::ToolCall` 类型未保留 `locations`,因此无法像 Hermes VSCode 一样把 read/edit 工具结果联动到主编辑器 tab。 ## 4. P0 缺口 ### P0-1 ACP `session/load` 恢复缺失 MNote 有会话列表、恢复按钮和 runtime store,但恢复更多是 MNote 会话历史层的恢复。对 ACP runtime 来说,若没有对 adapter 调用 `session/load { sessionId, cwd, mcpServers: [] }`,后续 prompt 可能对应不到 agent 侧真实 session。 建议:在 `AcpSessionManager` 增加 stored ACP session id / `load_session` / `ensure_session` 能力;在 `hermes_client` 的 ACP run 启动处尽量使用已保存 ACP session id 进行 load,失败再 `session/new`。 ### P0-2 权限请求缺少真实 allow / deny 闭环 前端存在 permission dialog,但后端 `AcpClient` 对 incoming request 立即返回 JSON-RPC error,再广播 denied。用户点击允许/拒绝不能影响当前 ACP 请求。 建议:`AcpClient` 增加 incoming request handler;`AcpSessionManager` 把 `session/request_permission` 转成 pending request;`routes/hermes_client` 提供按 run/session/permission id 决策的短生命周期接口;超时默认 deny。 ### P0-3 tool `locations[]` 与 read/edit 打开联动缺失 Hermes VSCode 会保存 tool locations,并在 read/edit 完成后打开对应文件。MNote 当前 tool SSE 只有 raw input / output,不保留 `locations`,也没有把 tool 完成联动到 main editor resource tab / file tree target。 建议:扩展 ACP 类型、event 和 SSE 数据,保留 `locations`;前端对 completed read/edit 工具提供“打开”动作,优先复用现有 main editor resource tab,不默认新浏览器窗口。 ### P0-4 `session_info_update` / `plan` 被桥接层丢弃 MNote 已在 `AcpSessionManager` 解析 `SessionInfoUpdate` 和 `PlanUpdate`,但 `acp_bridge` 当前返回 `None`。会话自动标题、agent plan/todo 不能进入 UI,也不能进入 runtime event 记录。 建议:转发 `session.info.updated` 和 `plan.updated` SSE;前端更新当前会话标题,并将 plan/todo 作为轻量状态面板或 tool/system message 渲染。 ## 5. P1 缺口 - slash command 响应仍更像普通聊天消息,缺少参考实现中的 system message 视觉语义和 allowlist 明确边界。 - skills / model 控制面已存在,但未完全对齐 Hermes 本地 model cache 与 `SKILL.md` 目录;需要确认是否存在过期 profile / skill 混用。 - busy queue / interrupt cancel 已有队列和 stop,但与参考实现“第二条消息排队、interrupt 立即 unblock”的交互语义仍需 smoke 覆盖。 - Page AI session restore 需要区分 MNote session id、ACP adapter session id、run id,避免 UI 把任意历史 session 当作可继续底层 ACP 对话。 - tool raw output 中的 todo JSON 还没有独立 overlay,计划状态只能混在 tool card 中。 ## 6. P2 缺口 - Webview markdown rendering / sanitization 参考实现使用 `marked` + `DOMPurify`;MNote 当前对 assistant 消息仍偏纯文本逃逸,后续可评估富文本安全渲染。 - active file / selection / open tabs 上下文注入需要继续与 MNote editor group / resource tab 模型对齐。 - Hermes 插件中 attachments 以 `[Referenced file: path]` 进入 prompt;MNote local-first 已有文件 scope,但附件引用提示仍可更清晰。 - session store 的 max 20 sessions / max 300 messages 可作为 MNote localStorage/local JSONL 裁剪策略参考。 ## 7. 不建议照搬 - 不照搬 VSCode Webview 的 DOM/CSS 结构;MNote 仍使用 Wolai 主题 Page AI drawer。 - 不把 VSCode `workspaceState` 当作 MNote 会话真相;local-first 下本地 JSONL / Convex control-plane / runtime registry 各自职责不变。 - 不把 Hermes 插件中的自动打开文件行为做成不可控跳转;MNote 应默认在 main editor resource tab 打开,并保留显式新窗口入口。 - 不在 UI 层新增第二套文件权限真相;权限和 allowed roots 仍由 Rust Web / local-first scope 决定。 - 不把 Page AI block-edit workflow 扩成普通 Markdown 主路径;local folder 继续走文件引用 + agent 原生 patch/diff + watcher 同步。 ## 8. 执行拆分 本 review 先拆四份 P0 checklist,允许并行推进: - `design/07-ai/done/7-30-acp-session-load-resume-checklist-v1.md` - `design/07-ai/done/7-31-acp-permission-decision-loop-checklist-v1.md` - `design/07-ai/done/7-32-acp-tool-location-and-open-action-checklist-v1.md` - `design/07-ai/done/7-33-acp-session-info-plan-ui-checklist-v1.md` P0 收口后再拆 P1: - slash/system message 与 model/skill 控制面收口。 - queue / interrupt cancel browser smoke。 - assistant markdown 安全渲染评估。