docs: organize active mnote execution checklists
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
# 7-39 Page AI agent selector / context authorization settings v1
|
||||
|
||||
> 创建时间:2026-05-28
|
||||
> 状态:`done`
|
||||
> 来源:用户反馈:旧 Page AI UI 信息过载;“编辑当前文件 / 工作区任务”模式难以区分;应参考 Cline 在聊天输入区选择 agent,并在设置里按 agent 拆分配置;共性设置包含授权区域,且授权区域应按用户保存到 SQLite。
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 Page AI sidebar 已能接 Hermes / Reasonix ACP、run target snapshot、changed files 审计和 SQLite directory grant。但 UI 仍把 agent、profile、runtime、skills、history、gateway、工具参数和错误解释混在一个抽屉中。
|
||||
|
||||
这导致两个问题:
|
||||
|
||||
- 用户真正要做的只是“选择 agent + 勾选要发给 AI 的上下文地址”,但现有 UI 暴露了太多 Hermes/ACP 运行细节。
|
||||
- “编辑当前文件”和“工作区任务”作为主模式不稳定:本地 Markdown、打开资源、选区、文件夹和 changed files 都可能参与同一轮请求,按模式分流反而会误导。
|
||||
|
||||
因此后续 Page AI 主线应从“模式切换”改为“agent 选择 + contextRefs 勾选 + SQLite 授权区域”的结构。
|
||||
|
||||
## 2. 参考对照
|
||||
|
||||
### 2.1 Cline
|
||||
|
||||
可借鉴模型:
|
||||
|
||||
- 聊天输入区附近直接选择当前 agent / provider,让用户在提问前完成路由决策。
|
||||
- 设置页按 agent/provider 拆分,只把模型、profile、API、能力开关等差异配置放在各自页面。
|
||||
- 共性配置只放所有 agent 都需要理解的内容,例如上下文、授权、审计、历史保留。
|
||||
|
||||
只作参考实现:
|
||||
|
||||
- Cline 的 VSCode extension 状态和 provider 配置模型不能直接搬到 MNote;MNote 的授权区域必须继续走 SQLite control-plane,而不是浏览器 localStorage 或扩展全局状态。
|
||||
|
||||
不适合 MNote:
|
||||
|
||||
- 不把“工作区 root”当作天然可读写范围。MNote 必须基于 `directory_grants` / `AiAccessScope` / allowed roots 显式授权。
|
||||
|
||||
### 2.2 Sidex / VSCode workbench
|
||||
|
||||
可借鉴模型:
|
||||
|
||||
- 资源、编辑器、工作区和最近修改项应以可选引用表达,而不是把 UI 分成互斥大模式。
|
||||
- Explorer / editor / panel 可以共享同一份打开资源快照,但不把 UI 层选择变成新的树或页面真相。
|
||||
|
||||
只作参考实现:
|
||||
|
||||
- VSCode / Sidex 的工作台布局、tab model、context key 可以作为交互参考;MNote 的真实对象边界仍由 Rust kernel projection、local-first source 和 control-plane 决定。
|
||||
|
||||
不适合 MNote:
|
||||
|
||||
- 不把 VSCode extension host 或工作台状态当成 MNote 的资源生命周期真相。
|
||||
|
||||
## 3. 产品决策
|
||||
|
||||
### 3.1 主聊天面
|
||||
|
||||
主聊天面只保留四类默认可见元素:
|
||||
|
||||
- 当前 agent 选择器:位于输入框下方或紧邻输入框,默认可快速切换 `Hermes`、`Reasonix`、`Chat-only`,未来可扩展其他 agent。
|
||||
- ContextRefs 选择器:用勾选 chip / popover 选择要发送的地址,例如当前页、当前选区、当前打开资源、指定文件、指定文件夹、最近 changed files。
|
||||
- 输入框和发送/停止按钮。
|
||||
- 简短状态:只显示“可用 / 需要授权 / 正在运行 / 失败”,不默认显示 gateway、profile、tool trace、参数 JSON。
|
||||
|
||||
“编辑当前文件 / 工作区任务”不再作为主模式。它们退化为 contextRefs 的预设组合:
|
||||
|
||||
- 编辑当前文件:勾选当前页或当前文件 + 必要的写权限 allowed root。
|
||||
- 工作区任务:勾选一个或多个文件夹 / changed files / 打开资源 + 必要的读写授权。
|
||||
|
||||
### 3.2 共性设置
|
||||
|
||||
共性设置只保留所有 agent 共享的配置:
|
||||
|
||||
- 授权区域:来自 SQLite `directory_grants`,按当前用户隔离;展示 root、权限、递归、来源、状态。
|
||||
- 默认上下文勾选:保存到 SQLite `user_ui_preferences`,按用户、workspace、source 隔离。
|
||||
- changed files 展示策略:默认收起,只显示摘要;需要时展开路径/hash/mtime/actor。
|
||||
- 隐私与审计:是否记录 local agent audit、是否展示工具细节、是否允许发送选区/页面摘要。
|
||||
|
||||
共性设置不放 Hermes profile、Reasonix skill、provider API key、模型 preset 等 agent 差异项。
|
||||
|
||||
### 3.3 Agent 设置
|
||||
|
||||
设置页按 agent 拆分:
|
||||
|
||||
- Hermes:profile、Hermes 设置入口、Hermes/ACP runtime 兼容提示、Hermes 专属 tool 开关。
|
||||
- Reasonix:ACP runtime、Reasonix skill 只读/可用状态、Reasonix 专属能力说明。
|
||||
- Chat-only:模型或 provider 选择、是否允许读取 contextRefs;默认不请求文件写权限。
|
||||
- 未来 agent:通过 registry 增加 `agentId`、显示名、能力、设置 schema、运行入口。
|
||||
|
||||
每个 agent 只能保存自身差异设置。默认 agent、默认 contextRefs 和授权区域仍属于共性设置。
|
||||
|
||||
## 4. 数据与合同
|
||||
|
||||
### 4.1 SQLite 使用边界
|
||||
|
||||
优先复用现有 control-plane:
|
||||
|
||||
- `directory_grants`:每用户授权区域真相。用于生成 allowed roots,不能由前端本地状态代替。
|
||||
- `user_ui_preferences`:每用户 UI 偏好。用于默认 agent、contextRefs 默认勾选、授权区域排序/最近使用、UI 密度、changed files 默认折叠状态。
|
||||
|
||||
建议 preference scope / key:
|
||||
|
||||
- `scope = "ai.common"`,`key = "default_agent_id"`
|
||||
- `scope = "ai.common"`,`key = "context_refs.default_selected"`
|
||||
- `scope = "ai.common"`,`key = "allowed_roots.default_selected"`
|
||||
- `scope = "ai.common"`,`key = "allowed_roots.order"`
|
||||
- `scope = "ai.common"`,`key = "changed_files.visibility"`
|
||||
- `scope = "ai.agent.hermes"`,`key = "profile_id"`
|
||||
- `scope = "ai.agent.reasonix"`,`key = "skill_panel_filter"`
|
||||
- `scope = "ai.agent.chat_only"`,`key = "model_id"`
|
||||
|
||||
除非现有表无法表达这些键值,否则第一阶段不新增 SQLite 表。
|
||||
|
||||
### 4.2 请求合同草案
|
||||
|
||||
```json
|
||||
{
|
||||
"agentId": "reasonix",
|
||||
"message": "把选中的 Markdown 小节整理成 checklist",
|
||||
"contextRefs": [
|
||||
{
|
||||
"kind": "current_page",
|
||||
"documentId": "local:page:example",
|
||||
"rootUri": "file:///mnt/Data1T/mnote"
|
||||
},
|
||||
{
|
||||
"kind": "folder",
|
||||
"rootUri": "file:///mnt/Data1T/mnote",
|
||||
"relativePath": "design/07-ai"
|
||||
}
|
||||
],
|
||||
"allowedRoots": [
|
||||
{
|
||||
"rootUri": "file:///mnt/Data1T/mnote",
|
||||
"permission": "write",
|
||||
"source": "sqlite_directory_grant"
|
||||
}
|
||||
],
|
||||
"runTargetSnapshot": {
|
||||
"version": "mnote.page_ai_run_target_snapshot.v1",
|
||||
"source": "open_editors_snapshot"
|
||||
},
|
||||
"audit": true
|
||||
}
|
||||
```
|
||||
|
||||
合同要求:
|
||||
|
||||
- `agentId` 是主路由字段,不能再隐含在 Hermes profile 或 ACP runtime 里。
|
||||
- `contextRefs` 是用户勾选的上下文地址,不等同于授权。
|
||||
- `allowedRoots` 必须由 SQLite 授权区域和当前用户权限解析得到。
|
||||
- `runTargetSnapshot` 继续从 `OpenEditorsSnapshot` 冻结,防止 run 过程中 UI 切换导致目标漂移。
|
||||
|
||||
## 5. 旧 UI 精简规则
|
||||
|
||||
默认聊天面应移除或收敛:
|
||||
|
||||
- 顶部同时展示 Hermes/profile/model/gateway 的多重状态。
|
||||
- 空态长解释、示例段落和“后端 AI 会话”等实现细节文案。
|
||||
- Runtime 页默认暴露 gateway health、queue、tools、trace、audit JSON。
|
||||
- Skills 页默认展示大量参数、来源和技术标签。
|
||||
- 工具调用卡默认展示 args/result/raw trace。
|
||||
- 输入框 placeholder 固定写“问 Hermes...”。
|
||||
|
||||
替代方式:
|
||||
|
||||
- 默认只显示 agent 名称、上下文 chips、运行状态和最终回答。
|
||||
- 工具调用、changed files、audit、gateway、queue 进入“高级 / 调试”折叠区。
|
||||
- 错误文案先给用户动作,例如“需要授权该文件夹”,再提供可展开技术详情。
|
||||
- Hermes / Reasonix 的差异通过 agent selector 和 agent 设置页表达,不在聊天主面堆说明。
|
||||
|
||||
## 6. Checklist
|
||||
|
||||
### Batch A - 现状冻结与视觉基线
|
||||
|
||||
- [x] 截图记录当前 Page AI sidebar 默认聊天面、Agent、Runtime、Skills、History 页。
|
||||
- [x] 标注必须删除/折叠的冗余信息:profile/model/gateway、runtime queue、tool trace、长空态说明、Hermes 固定文案。
|
||||
- [x] 对照 Cline agent selector 和 Sidex/VSCode context/resource 模型,形成最小信息架构图。
|
||||
- [x] 验证:浏览器截图 + 本文档补充截图路径或 smoke 证据。
|
||||
|
||||
证据:旧 UI 基线截图在 `tmp/task502-page-ai-baseline/01-chat.png`、`02-agent.png`、`03-skills.png`、`04-runtime.png`、`05-history.png`;收敛后截图在 `tmp/task502-page-ai-agent-selector-context-smoke/01-agent-selector-context.png`。
|
||||
|
||||
### Batch B - Agent registry 与主选择器
|
||||
|
||||
- [x] 定义 `agentId` registry:`hermes`、`reasonix`、`chat_only`,包含显示名、能力、是否可写文件、设置页入口。
|
||||
- [x] 在聊天输入区附近增加 agent selector,替代“Hermes 固定入口”。
|
||||
- [x] 发送请求时 payload 显式包含 `agentId`,旧 Hermes/Reasonix ACP 路径保持兼容。
|
||||
- [x] 验证:node smoke 断言切换 agent 后 payload 和 UI badge 正确。
|
||||
|
||||
证据:`rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` 的 `PAGE_AI_AGENT_REGISTRY`;`scripts/task502-page-ai-agent-selector-context-smoke.js` 断言 `hermes/reasonix/chat_only` 和 run payload `agentId=reasonix`。
|
||||
|
||||
### Batch C - ContextRefs 勾选器
|
||||
|
||||
- [x] 定义 `contextRefs` 类型:当前页、选区、当前打开资源、文件、文件夹、changed files。
|
||||
- [x] ContextRefs 从 `OpenEditorsSnapshot`、当前 selection 和授权目录解析,不新增第二套页面/树真相。
|
||||
- [x] “编辑当前文件 / 工作区任务”改为预设组合,不再作为主模式。
|
||||
- [x] 验证:浏览器 smoke 勾选/取消 contextRefs 后 payload 稳定。
|
||||
|
||||
证据:`PAGE_AI_CONTEXT_REF_REGISTRY` 覆盖 `current_page/selection/active_editor/file/folder/changed_files`;`task502` 断言取消 `current_page` 后 payload 不含 `current_page/pageText/pageXml/contextBlocks`,并保留 `active_editor/folder/changed_files`。
|
||||
|
||||
### Batch D - SQLite per-user 授权区域
|
||||
|
||||
- [x] 共性设置页展示当前用户的 `directory_grants`,支持按 read/write、recursive、source、status 展示。
|
||||
- [x] allowedRoots 只从当前用户 SQLite grant 解析;未授权目录必须提示授权,不允许前端绕过。
|
||||
- [x] 修复/补齐 Page AI 与 ACP session create 的授权路径一致性,确保已授权本地文件夹不会误报无权访问。
|
||||
- [x] 验证:Rust 定点测试覆盖不同用户 grant 隔离;浏览器 smoke 覆盖授权目录可用、未授权目录阻断。
|
||||
|
||||
证据:`hermes_client.rs::enforce_local_ai_run_access` 服务端按当前 actor 调 `resolve_access` 重算 `allowedRoots`;`sqlite.rs::resolve_access_does_not_match_sibling_uri_prefix` 修复 URI 前缀串扰;`local_ai_run_access_*` 覆盖 Alice/Bob 隔离与 `chat_only` read-only 降级;`task502` 验证授权 chip 来源为 `sqlite_directory_grant`。
|
||||
|
||||
### Batch E - UI preference per-user 持久化
|
||||
|
||||
- [x] 用 `user_ui_preferences` 保存默认 agent、默认 contextRefs、授权区域排序/默认勾选、changed files 折叠策略。
|
||||
- [x] preference key 必须带 user/workspace/source/scope 边界。
|
||||
- [x] 不用 localStorage 作为长期真相;最多作为临时 UI cache。
|
||||
- [x] 验证:Rust/JS smoke 覆盖 Alice/Bob 设置隔离。
|
||||
|
||||
证据:`ui_preferences.rs` 支持 `ai.common.*` 与 `ai.agent.*`,并返回 `aiPreferences`;`ui_preferences_api_persists_ai_preferences_per_user_and_workspace` 验证 Alice/Bob 隔离;`task502` 捕获 PUT `ai.common.default_agent_id` 与 `ai.common.context_refs.default_selected`。
|
||||
|
||||
### Batch F - Agent 分页设置
|
||||
|
||||
- [x] 设置页拆为 Common / Hermes / Reasonix / Chat-only。
|
||||
- [x] Common 只放授权、默认 contextRefs、隐私/审计、changed files 显示策略。
|
||||
- [x] Hermes 只放 Hermes profile/upstream/tool 相关设置。
|
||||
- [x] Reasonix 只放 Reasonix ACP/skill 相关设置。
|
||||
- [x] Chat-only 默认不申请文件写权限。
|
||||
- [x] 验证:浏览器 smoke 检查不同 agent 设置页不串项。
|
||||
|
||||
证据:`ensurePageAiDrawer` 拆出 Common/Hermes/Reasonix/Chat-only/高级面板;`task502` 用真实浏览器检查 Common 不含 `Hermes profile/ACP runtime`,Hermes 不混 Reasonix,Reasonix 不混 Hermes,Chat-only 不混 ACP runtime。
|
||||
|
||||
### Batch G - 旧 UI 冗余收敛
|
||||
|
||||
- [x] 默认聊天面隐藏 gateway/model/profile 技术细节,只保留 agent badge 和简短状态。
|
||||
- [x] Runtime/Skills/History 收敛为高级/调试入口,默认不进入主聊天流。
|
||||
- [x] 工具调用卡默认只展示摘要;args/result/raw trace 需展开。
|
||||
- [x] changed files 默认摘要,展开后才显示路径/hash/mtime/actor。
|
||||
- [x] 验证:浏览器截图对比,确保主面没有冗余解释和技术噪音。
|
||||
|
||||
证据:`sidebar-page-ai-runtime.js` 默认标题状态改为 agent/授权/AI session,旧 `Hermes session` 与固定 `问 Hermes` 文案退出默认聊天面;`task502` 断言默认聊天面不含 `问 Hermes/model.default/gateway:/Hermes profile`;changed files 仍由 `task453-local-folder-page-ai-changed-files-smoke.js` 验证摘要与 dirty 阻断。
|
||||
|
||||
### Batch H - 合同与回归
|
||||
|
||||
- [x] 补最小 JS/Rust 合同注释或文档,说明 `agentId + contextRefs + allowedRoots + runTargetSnapshot` 的边界。
|
||||
- [x] 保持 Hermes / Reasonix 旧 payload 兼容,必要时在 route 层做窄 adapter。
|
||||
- [x] 更新 Page AI smoke,覆盖 agent 切换、contextRefs、SQLite 授权、per-user preference、旧路径兼容。
|
||||
- [x] 运行 `git diff --check`、相关 Rust 定点测试、node smoke;涉及代码图修改后运行 `codegraph sync .`。
|
||||
|
||||
证据:JS 合同注释位于 `PAGE_AI_AGENT_REGISTRY` 前;服务端兼容仍走 `/api/hermes/client/runs` 和 ACP `profile/acpRuntime` adapter;最终验证矩阵见本次执行汇报。
|
||||
|
||||
## 7. 非目标
|
||||
|
||||
- 不实现 Phase C 流式 apply / suggest review。
|
||||
- 不把 local-first 普通 Markdown 编辑改回粗粒度 `mnote.page.save`。
|
||||
- 不新增第二套树真相、页面真相、资源生命周期真相或授权真相。
|
||||
- 不把 agent 设置写入浏览器 localStorage 作为长期存储。
|
||||
- 不在本批次重构 Hermes / Reasonix agent 内部运行时。
|
||||
|
||||
## 8. 待确认产品点
|
||||
|
||||
- Agent selector 的精确位置:输入框下方一行,还是输入框左侧/上方 compact row。
|
||||
- ContextRefs 默认勾选:是否默认包含当前页和当前选区,还是只默认当前页。
|
||||
- Chat-only 是否允许读取文件夹摘要,或严格只允许聊天文本和显式勾选的页面摘要。
|
||||
- 技术调试入口默认是否仅管理员可见,还是普通用户也可展开。
|
||||
Reference in New Issue
Block a user