Files
mnote/design/10-review/reference/13-hermes-vscode-plugin-gap-review-v1.md
T

102 lines
7.9 KiB
Markdown
Raw Normal View History

2026-05-21 05:40:06 +08:00
# 13 Hermes VSCode 插件对照审查 v1
2026-05-21 10:19:02 +08:00
> 状态:reference
2026-05-21 09:04:13 +08:00
>
> 归档说明(2026-05-21):P0 缺口已拆分到 `7-30` 至 `7-33` 并完成归档;本文保留 Hermes VSCode 插件对照证据和 P1/P2 参考项。
2026-05-21 05:40:06 +08:00
>
> 日期: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 有 allowlistslash 响应渲染为居中的 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]` 进入 promptMNote 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,允许并行推进:
2026-05-21 09:04:13 +08:00
- `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`
2026-05-21 05:40:06 +08:00
P0 收口后再拆 P1
- slash/system message 与 model/skill 控制面收口。
- queue / interrupt cancel browser smoke。
- assistant markdown 安全渲染评估。