chore: align mvp design governance

- 统一 local-first MVP 后阶段架构口径,补充 process 执行总序和 Reasonix 协作记录

- 归档已完成的 design checklist,标注参考型 process,更新 AGENTS/REASONIX/架构文档

- 补充文件树/主编辑器下载与上下文菜单相关实现、bug 记录和 smoke 脚本

验证:git diff --check;codegraph sync .;cargo test -p mnote-web;node --check scripts/task476-filetree-editor-context-menu-download-smoke.js
This commit is contained in:
lix-2026
2026-05-21 09:04:13 +08:00
parent fd94792ea6
commit 1956a8a21a
69 changed files with 3390 additions and 111 deletions
+15 -3
View File
@@ -799,7 +799,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
if (typeof runtime.default !== 'function' || typeof runtime.mount !== 'function' || typeof runtime.unmount !== 'function') {
throw new Error('island runtime 导出不完整');
}
await runtime.default(wasmUrl);
await runtime.default({ module_or_path: wasmUrl });
if (typeof runtime.mount_mindmap_shell === 'function' && typeof runtime.unmount_mindmap_shell === 'function') {
window.__MNOTE_MINDMAP_RUST_SHELL__ = {
mount: runtime.mount_mindmap_shell,
@@ -3260,6 +3260,14 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
}
};
const currentWebShellDocumentId = () => {
const fromBody = document.body?.dataset?.documentId || '';
if (fromBody) return String(fromBody).trim();
const pageTab = document.querySelector('[data-mnote-main-tab="page"]');
if (pageTab instanceof HTMLElement) return String(pageTab.getAttribute('data-document-id') || '').trim();
return '';
};
const normalizeResourceTabKind = (input) => {
const kind = String(input?.kind || '').trim().toLowerCase();
const title = String(input?.title || input?.fileName || input?.path || '').trim().toLowerCase();
@@ -3365,7 +3373,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
: '页面';
const pageEntry = {
objectIdentity: 'page',
documentId: String(nodes.pageTab?.getAttribute?.('data-document-id') || currentDocumentId() || '').trim(),
documentId: String(nodes.pageTab?.getAttribute?.('data-document-id') || currentWebShellDocumentId() || '').trim(),
workspaceId: String(nodes.pageTab?.getAttribute?.('data-workspace-id') || currentWebShellWorkspaceId() || '').trim(),
title: pageTitle || '页面',
kind: 'page',
@@ -3772,7 +3780,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
};
const openMindmapResourceTab = async (entry, input) => {
const documentId = String(input.documentId || currentDocumentId() || '').trim();
const documentId = String(input.documentId || currentWebShellDocumentId() || '').trim();
const mindmapId = String(input.mindmapId || input.assetId || '').trim();
if (!documentId || !mindmapId) throw new Error('mindmap_resource_identity_missing');
const targetUrl = new URL(`/mindmap/${encodeURIComponent(documentId)}/${encodeURIComponent(mindmapId)}`, window.location.origin);
@@ -4645,6 +4653,10 @@ mod tests {
assert!(html.contains("getOpenEditorsSnapshot"));
assert!(html.contains("bindMainEditorTabStrip"));
assert!(html.contains("data-mnote-tab-strip-bound"));
assert!(html.contains("currentWebShellDocumentId"));
assert!(!html
.contains("nodes.pageTab?.getAttribute?.('data-document-id') || currentDocumentId()"));
assert!(html.contains("runtime.default({ module_or_path: wasmUrl })"));
assert!(html.contains("positionSlashMenuForRoot"));
assert!(html.contains("menu.style.position = 'fixed';"));
assert!(html.contains("installGlobalSlashMenuPositioning();"));