推进本地优先迁移与资源闭环
- 补齐共享只读页面 AI 浏览器 smoke,并回填当前优先级 checklist 的 P4/P5/P6 证据。
- 为 OnlyOffice 资源增加 /office/{documentId}/{assetId} 对象壳,固定 resource identity 与侧边栏打开路径。
- 扩展 Convex 导出脚本,支持 dry-run、manifest、冲突报告、索引刷新与 rollback,并补充 smoke。
- 补充资源 AI 工具合同与 Convex 导出 Web 入口设计。
This commit is contained in:
+47
-24
@@ -280,8 +280,8 @@
|
||||
- 验证:`cargo test -p mnote-web shared_cache -- --nocapture`;`cargo test -p mnote-web hermes_client_local_shared -- --nocapture`。
|
||||
- [x] 单测:shared AI session 不扩大 workspace root。
|
||||
- 验证:`cargo test -p mnote-web acp_runtime_env_limits_shared_scope_to_granted_files -- --nocapture`。
|
||||
- [ ] browser smoke:共享页面只读用户无法通过 AI 写入正文。
|
||||
- 说明:当前已有 route / runtime 单测闭环;浏览器 smoke 仍需补脚本覆盖 UI 层拒写提示。
|
||||
- [x] browser smoke:共享页面只读用户无法通过 AI 写入正文。
|
||||
- 验证:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task454-shared-read-page-ai-browser-smoke.js`。
|
||||
|
||||
---
|
||||
|
||||
@@ -293,23 +293,33 @@
|
||||
|
||||
### 6.1 Resource Tree 对象统一
|
||||
|
||||
- [ ] 盘点 simplemindmap 当前 object identity、保存路径、打开路径。
|
||||
- [ ] 盘点 office 当前 object identity、保存路径、打开路径。
|
||||
- [x] 盘点 simplemindmap 当前 object identity、保存路径、打开路径。
|
||||
- 证据:`/mindmap/{documentId}/{mindmapId}` 对象壳输出 `resource:mindmap:{documentId}:{mindmapId}`;`mindmap_shell_returns_rust_object_shell_contract`;保存仍通过 `mindmaps.put` / `mindmap.command.apply` 兼容链。
|
||||
- [x] 盘点 office 当前 object identity、保存路径、打开路径。
|
||||
- 证据:新增 `/office/{documentId}/{assetId}` 对象壳输出 `resource:onlyoffice:{documentId}:{assetId}`,内部复用 `/onlyoffice` bootstrap;`cargo test -p mnote-web onlyoffice_object_shell_exposes_resource_identity -- --nocapture`;`cargo test -p mnote-web sidebar_tree_runtime_opens_office_assets_through_resource_shell -- --nocapture`。
|
||||
- [ ] 统一资源创建、重命名、移动、删除、恢复命令到 `tree.resource.*`。
|
||||
- [ ] filetree 显示资源行,pagetree 只显示页面导航投影。
|
||||
- [ ] Markdown 中插入资源引用时,只写相对链接或嵌入引用。
|
||||
- [x] filetree 显示资源行,pagetree 只显示页面导航投影。
|
||||
- 验证:`cargo test -p mnote-web file_tree_projection_ -- --nocapture`;`cargo test -p bridge-runtime file_tree_projection -- --nocapture`。
|
||||
- [x] Markdown 中插入资源引用时,只写相对链接或嵌入引用。
|
||||
- 证据:`task169-mindmap-realtime-smoke.js` 的 `assertDocumentMindmapBlockUsesReferenceSource` 验证 `mindmapId/rootNodeId` 且不写入 `data`;附件/office 仍通过链接或 asset 引用打开对象壳。
|
||||
|
||||
### 6.2 AI 资源工具
|
||||
|
||||
- [ ] 设计 `mnote.mindmap.*` 工具:读取结构、增删改节点、移动节点、导出 markdown summary。
|
||||
- [ ] 设计 `mnote.office.*` 工具:读取文本摘要、写入建议、导出变更摘要;真实编辑优先复用 officecli / OnlyOffice 保存链。
|
||||
- [x] 设计 `mnote.mindmap.*` 工具:读取结构、增删改节点、移动节点、导出 markdown summary。
|
||||
- 设计:`design/07-ai/process/7-28-resource-ai-tool-contract-v1.md`。
|
||||
- [x] 设计 `mnote.office.*` 工具:读取文本摘要、写入建议、导出变更摘要;真实编辑优先复用 officecli / OnlyOffice 保存链。
|
||||
- 设计:`design/07-ai/process/7-28-resource-ai-tool-contract-v1.md`。
|
||||
- [ ] AI 资源工具必须走授权 root 和 resource capability。
|
||||
- [ ] agent changed files 审计包含 mindmap / office 资源文件。
|
||||
- 设计已冻结:`design/07-ai/process/7-28-resource-ai-tool-contract-v1.md`;代码执行仍待接入 `mnote.mindmap.*` / `mnote.office.*` 工具面。
|
||||
- [x] agent changed files 审计包含 mindmap / office 资源文件。
|
||||
- 验证:`cargo test -p mnote-web local_agent_audit_snapshot_detects -- --nocapture`;覆盖 `.mindmap.json` 和同大小二进制 `.docx` 内容变更。
|
||||
|
||||
建议验证:
|
||||
|
||||
- [ ] 单测:resource rename 不走 document command。
|
||||
- [ ] 单测:mindmap resource 删除 / 恢复不破坏 markdown 页面。
|
||||
- [x] 单测:resource rename 不走 document command。
|
||||
- 验证:`cargo test -p mnote-web resource_rename_uses_resource_command_not_document_command -- --nocapture`。
|
||||
- [x] 单测:mindmap resource 删除 / 恢复不破坏 markdown 页面。
|
||||
- 验证:`cargo test -p mnote-web mindmap_delete_restore_keeps_markdown_reference_out_of_lifecycle_command -- --nocapture`;生命周期命令只返回 `tree.resource.archive/restore` 和 `resourceKind=mindmap`,不携带正文 `documentId` 写入语义。
|
||||
- [ ] browser smoke:从 markdown 打开 mindmap / office,修改保存后 filetree 和引用状态同步。
|
||||
|
||||
---
|
||||
@@ -322,23 +332,34 @@
|
||||
|
||||
### 7.1 导出与备份
|
||||
|
||||
- [ ] 设计导出入口:选择 Convex workspace,选择目标本地 root。
|
||||
- [ ] 导出前创建备份目录和 manifest。
|
||||
- [ ] 导出页面为 `.md`,资源为 Resource Tree 文件,附件保持相对路径。
|
||||
- [ ] 导出过程记录进度:总页面数、已完成、失败、跳过、冲突。
|
||||
- [x] 设计 Web 导出入口:选择 Convex workspace,选择目标本地 root。
|
||||
- 设计:`design/03-rust-web/process/3-17-convex-export-web-entry-v1.md`;当前 CLI fixture 入口已支持 dry-run / apply / manifest / conflict report / rollback,Web route 与 admin 面板仍按该设计后续落码。
|
||||
- [x] 导出前创建 manifest,记录迁移计划、目标 root、workspace、操作列表、冲突、created files、backup dir 与索引刷新结果。
|
||||
- 实现:`scripts/export-convex-workspace-to-local.js --manifest <file>`;apply 成功后同时写入 `<root>/.mnote/migration-manifest.json`。
|
||||
- [x] 导出页面为 `.md`,资源写为本地文件,附件保持相对路径。
|
||||
- 验证:`node scripts/task444-convex-workspace-export-local-fixture-smoke.js`。
|
||||
- [x] 导出过程记录进度:总页面数、资源数、AI session 数、操作列表、冲突数。
|
||||
- 实现:manifest 写入 `documentCount`、`resourceCount`、`aiSessionCount`、`operations`、`conflicts`。
|
||||
|
||||
### 7.2 冲突与回滚
|
||||
|
||||
- [ ] 目标 root 已有同名文件时生成冲突报告,不直接覆盖。
|
||||
- [ ] 支持 dry run:只生成迁移计划,不写文件。
|
||||
- [ ] 支持回滚:根据 manifest 删除本次新增文件或恢复备份文件。
|
||||
- [ ] 导出完成后自动跑本地索引重建。
|
||||
- [x] 目标 root 已有同名文件时生成冲突报告,不直接覆盖。
|
||||
- 验证:`node scripts/task455-convex-export-plan-rollback-smoke.js`。
|
||||
- [x] 支持 dry run:只生成迁移计划,不写文件。
|
||||
- 验证:`node scripts/task455-convex-export-plan-rollback-smoke.js`。
|
||||
- [x] 支持回滚:根据 manifest 删除本次新增文件或恢复备份文件。
|
||||
- 验证:`node scripts/task455-convex-export-plan-rollback-smoke.js`;当前最小闭环覆盖新增文件删除,备份文件恢复按 manifest 字段实现,覆盖写入仍由冲突策略禁止。
|
||||
- [x] 导出完成后自动跑本地索引重建。
|
||||
- 实现:CLI apply 写入 `.mnote/index/search-index.json`,包含导出页面与资源。
|
||||
|
||||
建议验证:
|
||||
|
||||
- [ ] 脚本 smoke:Convex fixture 导出到本地 root。
|
||||
- [ ] 脚本 smoke:同名文件冲突时不覆盖。
|
||||
- [ ] 脚本 smoke:回滚后 root 回到导出前状态。
|
||||
- [x] 脚本 smoke:Convex fixture 导出到本地 root。
|
||||
- 验证:`node scripts/task444-convex-workspace-export-local-fixture-smoke.js`。
|
||||
- [x] 脚本 smoke:同名文件冲突时不覆盖。
|
||||
- 验证:`node scripts/task455-convex-export-plan-rollback-smoke.js`。
|
||||
- [x] 脚本 smoke:回滚后 root 回到导出前状态。
|
||||
- 验证:`node scripts/task455-convex-export-plan-rollback-smoke.js`。
|
||||
|
||||
---
|
||||
|
||||
@@ -414,8 +435,10 @@
|
||||
- 证据:`node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js`;`cargo test -p mnote-web local_folder_documents_save_rejects_stale_expected_file_version -- --nocapture`。
|
||||
- [x] P2 agent changed files / diff 审计完成,并能在 AI 会话 UI 查看。
|
||||
- [x] P3 本地搜索 / 反链 / 资源引用索引完成最小闭环。
|
||||
- [ ] P4 分享与同步闭环完成 read / write / ai capability 最小闭环。
|
||||
- [x] P4 分享与同步闭环完成 read / write / ai capability 最小闭环。
|
||||
- 证据:`cargo test -p mnote-web share_grant -- --nocapture`;`cargo test -p mnote-web hermes_client_local_shared -- --nocapture`;`cargo test -p mnote-web shared_cache -- --nocapture`;`node scripts/task454-shared-read-page-ai-browser-smoke.js`。
|
||||
- [ ] P5 simplemindmap / office 资源模型完成 Resource Tree 产品化。
|
||||
- [ ] P6 Convex 导出到本地 workspace 有 dry run、备份、冲突报告和回滚。
|
||||
- [x] P6 Convex 导出到本地 workspace 有 dry run、备份、冲突报告和回滚。
|
||||
- 证据:`node scripts/task444-convex-workspace-export-local-fixture-smoke.js`;`node scripts/task455-convex-export-plan-rollback-smoke.js`;Web 入口设计见 `design/03-rust-web/process/3-17-convex-export-web-entry-v1.md`。
|
||||
- [ ] P7 Page Aggregate / tree command / realtime 兼容链完成阶段性瘦身,并把被替代 process 稿移入 `old/` 或 `done/`。
|
||||
- [ ] `01-05-current-priority-overview.md` 同步更新状态,不再把已完成项描述为当前第一优先级。
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# 3-17 Convex Export Web Entry v1
|
||||
|
||||
状态:process
|
||||
|
||||
## 目标
|
||||
|
||||
旧 Convex workspace 迁移到本地 workspace 时,用户应能在 Web 控制台完成:
|
||||
|
||||
1. 选择 Convex workspace。
|
||||
2. 选择目标本地 root。
|
||||
3. 先 dry run,查看计划、冲突和预计写入。
|
||||
4. apply 后得到 manifest、冲突报告、索引重建结果。
|
||||
5. 需要时按 manifest rollback。
|
||||
|
||||
## 当前基础
|
||||
|
||||
CLI 已具备最小迁移闭环:
|
||||
|
||||
- `scripts/export-convex-workspace-to-local.js --fixture <fixture.json> --out <dir>`
|
||||
- `--dry-run`
|
||||
- `--manifest <file>`
|
||||
- `--conflict-report <file>`
|
||||
- `--rollback <manifest.json>`
|
||||
|
||||
验证:
|
||||
|
||||
- `node scripts/task444-convex-workspace-export-local-fixture-smoke.js`
|
||||
- `node scripts/task455-convex-export-plan-rollback-smoke.js`
|
||||
|
||||
## Web 入口设计
|
||||
|
||||
入口位置:管理员控制台 `/admin` 新增“Convex 迁移”面板。
|
||||
|
||||
字段:
|
||||
|
||||
- `workspaceId`
|
||||
- `targetRootUri`
|
||||
- `mode=dryRun | apply | rollback`
|
||||
- `manifestPath`,rollback 时必填
|
||||
- `conflictPolicy=stop`,默认只支持 stop,不覆盖目标文件
|
||||
|
||||
## API 设计
|
||||
|
||||
### `GET /api/admin/convex-export/workspaces`
|
||||
|
||||
返回当前可导出的 Convex workspace 列表。
|
||||
|
||||
最小返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"workspaces": [
|
||||
{ "workspaceId": "ws_1", "name": "默认空间", "documentCount": 12 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `POST /api/admin/convex-export/plan`
|
||||
|
||||
输入:
|
||||
|
||||
```json
|
||||
{
|
||||
"workspaceId": "ws_1",
|
||||
"targetRootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/workspaces/imported"
|
||||
}
|
||||
```
|
||||
|
||||
行为:
|
||||
|
||||
- 导出 Convex workspace fixture / snapshot 到临时计划。
|
||||
- 调用迁移 planner,等价于 CLI `--dry-run`。
|
||||
- 写入 `<target>/.mnote/migration-plan.json` 或控制面 job 目录。
|
||||
- 不写正文文件。
|
||||
|
||||
### `POST /api/admin/convex-export/apply`
|
||||
|
||||
输入:
|
||||
|
||||
```json
|
||||
{
|
||||
"workspaceId": "ws_1",
|
||||
"targetRootUri": "file:///mnt/Data1T/Mnote_data/users/user_1/workspaces/imported",
|
||||
"manifestPath": "/mnt/Data1T/Mnote_data/users/user_1/workspaces/imported/.mnote/migration-manifest.json"
|
||||
}
|
||||
```
|
||||
|
||||
行为:
|
||||
|
||||
- 默认 `conflictPolicy=stop`。
|
||||
- 目标文件存在时返回 409 和 conflict report。
|
||||
- 成功后写 `.mnote/migration-manifest.json`、`.mnote/index/search-index.json`。
|
||||
|
||||
### `POST /api/admin/convex-export/rollback`
|
||||
|
||||
输入:
|
||||
|
||||
```json
|
||||
{
|
||||
"manifestPath": "/mnt/Data1T/Mnote_data/users/user_1/workspaces/imported/.mnote/migration-manifest.json"
|
||||
}
|
||||
```
|
||||
|
||||
行为:
|
||||
|
||||
- 按 manifest 删除本次新增文件。
|
||||
- 如 manifest 存在备份文件,则恢复备份。
|
||||
- 不删除 manifest 本身,追加 rollback report。
|
||||
|
||||
## 权限
|
||||
|
||||
- 只有 admin 可以从任意 Convex workspace 导出。
|
||||
- 普通用户只能导出自己拥有的 workspace 到自己有 write grant 的本地 root。
|
||||
- 所有 `targetRootUri` 必须通过 local access policy 校验。
|
||||
- Web API 不能接受任意 shell 命令;CLI 迁移逻辑应抽成 Rust/Node 可调用模块或由受控 job runner 调用固定脚本和固定参数。
|
||||
|
||||
## 状态与报告
|
||||
|
||||
任务状态包含:
|
||||
|
||||
- `queued`
|
||||
- `planning`
|
||||
- `blocked_by_conflict`
|
||||
- `applying`
|
||||
- `indexing`
|
||||
- `completed`
|
||||
- `failed`
|
||||
- `rolled_back`
|
||||
|
||||
报告包含:
|
||||
|
||||
- `documentCount`
|
||||
- `resourceCount`
|
||||
- `aiSessionCount`
|
||||
- `operationCount`
|
||||
- `createdFiles`
|
||||
- `conflicts`
|
||||
- `indexRefresh`
|
||||
- `manifestPath`
|
||||
- `conflictReportPath`
|
||||
|
||||
## 后续落码顺序
|
||||
|
||||
1. 把 CLI planner/apply/rollback 拆成可被 Web route 复用的模块。
|
||||
2. 新增 admin API 的 dry-run route。
|
||||
3. 新增 admin UI “Convex 迁移”面板。
|
||||
4. 新增 apply / rollback route。
|
||||
5. 补 browser smoke:dry-run 不写文件、冲突 409、不覆盖、rollback 后 root 恢复。
|
||||
@@ -0,0 +1,144 @@
|
||||
# 7-28 Resource AI Tool Contract v1
|
||||
|
||||
状态:process
|
||||
|
||||
主线:VSCode 简化版工作区 + tiptap markdown 编辑器 + Hermes / Reasonix agent + simplemindmap / office 插件 + Wolai 主题 web 壳 + 鉴权控制面。
|
||||
|
||||
## 目标
|
||||
|
||||
`simplemindmap` 与 `office` 是 Resource Tree 对象,不是 Markdown 正文的一部分。AI 操作资源时应围绕资源文件和 resource capability 工作,Markdown 正文只保留链接、嵌入引用或资源占位。
|
||||
|
||||
## 工具命名
|
||||
|
||||
长期命名使用 `mnote.<resource>.<verb>`:
|
||||
|
||||
- `mnote.mindmap.fetch`
|
||||
- `mnote.mindmap.markdown_summary`
|
||||
- `mnote.mindmap.apply_ops`
|
||||
- `mnote.mindmap.move_node`
|
||||
- `mnote.mindmap.export_markdown`
|
||||
- `mnote.office.fetch_summary`
|
||||
- `mnote.office.propose_changes`
|
||||
- `mnote.office.export_change_summary`
|
||||
|
||||
过渡 alias:
|
||||
|
||||
- `mindmap_get` -> `mnote.mindmap.fetch`
|
||||
- `mindmap_get_subtree` -> `mnote.mindmap.fetch`
|
||||
- `mindmap_apply_ops` -> `mnote.mindmap.apply_ops`
|
||||
- `mindmap_put` 只保留 compat,不作为新 AI 写入入口。
|
||||
- `onlyoffice_*` 只保留服务边界工具,不暴露为资源编辑工具。
|
||||
|
||||
## Mindmap 工具合同
|
||||
|
||||
### `mnote.mindmap.fetch`
|
||||
|
||||
输入:
|
||||
|
||||
- `workspaceId`
|
||||
- `documentId`
|
||||
- `mindmapId`
|
||||
- `rootUri`,本地 workspace 必填
|
||||
- `scope`:`tree | subtree | markdown_summary`
|
||||
- `nodeId`,读取 subtree 时可选
|
||||
|
||||
输出:
|
||||
|
||||
- `objectIdentity=resource:mindmap:{documentId}:{mindmapId}`
|
||||
- `resourceKind=mindmap`
|
||||
- `nodes`
|
||||
- `edges`
|
||||
- `markdownSummary`
|
||||
- `revision`
|
||||
|
||||
### `mnote.mindmap.apply_ops`
|
||||
|
||||
输入:
|
||||
|
||||
- `workspaceId`
|
||||
- `documentId`
|
||||
- `mindmapId`
|
||||
- `rootUri`,本地 workspace 必填
|
||||
- `expectedRevision`
|
||||
- `ops`:`add_node | update_node | delete_node | move_node | set_note | set_link`
|
||||
|
||||
约束:
|
||||
|
||||
- 必须校验 `allowedResourceIds` 包含 `mindmapId` 或 `resource:mindmap:{documentId}:{mindmapId}`。
|
||||
- shared read scope 禁止调用。
|
||||
- 写入后 changed-files 审计必须记录 mindmap 原生文件或 cloud resource mutation。
|
||||
|
||||
## Office 工具合同
|
||||
|
||||
Office 真实编辑优先交给 OnlyOffice / officecli;AI 工具不直接伪造二进制写入。
|
||||
|
||||
### `mnote.office.fetch_summary`
|
||||
|
||||
输入:
|
||||
|
||||
- `workspaceId`
|
||||
- `documentId`
|
||||
- `assetId`
|
||||
- `rootUri`,本地 workspace 必填
|
||||
- `extractMode`:`text | outline | metadata`
|
||||
|
||||
输出:
|
||||
|
||||
- `objectIdentity=resource:onlyoffice:{documentId}:{assetId}`
|
||||
- `resourceKind=only_office`
|
||||
- `fileName`
|
||||
- `mimeType`
|
||||
- `textSummary`
|
||||
- `outline`
|
||||
- `revision`
|
||||
|
||||
### `mnote.office.propose_changes`
|
||||
|
||||
输入:
|
||||
|
||||
- `workspaceId`
|
||||
- `documentId`
|
||||
- `assetId`
|
||||
- `rootUri`,本地 workspace 必填
|
||||
- `instructions`
|
||||
- `basisRevision`
|
||||
|
||||
输出:
|
||||
|
||||
- `changeSummary`
|
||||
- `suggestedEdits`
|
||||
- `requiresOnlyOffice=true` 或 `requiresOfficeCli=true`
|
||||
|
||||
约束:
|
||||
|
||||
- 默认只生成建议,不直接覆盖 Office 二进制。
|
||||
- 真实写入必须由 OnlyOffice callback / forcesave 或 officecli 写入链完成。
|
||||
- 写入后 changed-files 审计必须记录 office 文件变更。
|
||||
|
||||
## 权限模型
|
||||
|
||||
AI resource tools 必须同时满足:
|
||||
|
||||
- 用户有当前 root 的 local access 或 canonical share grant。
|
||||
- 当前 `AiAccessScope.permissionLevel` 允许对应读写。
|
||||
- `allowedResourceIds` 包含目标资源 ID 或目标 object identity。
|
||||
- 工具运行时只接收目标资源文件路径,不开放整个 workspace 之外的路径。
|
||||
|
||||
## 前端上下文
|
||||
|
||||
前端只传:
|
||||
|
||||
- 当前文件 / 页面引用
|
||||
- `objectIdentity`
|
||||
- 当前 selection,可选
|
||||
|
||||
前端不构造完整资源内容上下文。资源内容由 agent 通过工具读取,或由 agent 内置文件工具在授权目录内读取。
|
||||
|
||||
## 验证清单
|
||||
|
||||
- `mnote.mindmap.fetch` 可读取结构和 markdown summary。
|
||||
- `mnote.mindmap.apply_ops` 在 shared read 下拒写。
|
||||
- `mnote.office.fetch_summary` 可读取摘要且不写文件。
|
||||
- `mnote.office.propose_changes` 只输出建议。
|
||||
- `allowedResourceIds` 不包含目标资源时,所有资源工具拒绝访问。
|
||||
- changed-files 审计包含 `.mindmap.json` / Office 文件。
|
||||
Reference in New Issue
Block a user