Files
mnote/AGENTS.md
T

197 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 仓库协作指南(AGENTS
## 当前主线
- 当前长期方向以 `tree-first graph kernel` 为准,不以 `BlockNote-first``Mindmap-first` 为准。
- 当前已经进入 local-first MVP 后阶段:最小可用闭环已建立,后续重点是底座统一、compat 瘦身和产品化闭环,不再把新增能力建立在旧 Convex / Next / BlockNote 主链上。
- 当前产品形态固定为:`VSCode 简化版工作区 + tiptap 的 Markdown 前端编辑器 + OpenHub + LightRAG AI + simplemindmap/office 插件 + Wolai 主题 Web 壳 + 鉴权控制面`
- 本地文件夹是早期产品默认数据真相;本地 `.md` 是页面正文真相。Turso/libSQL `control-plane` 是默认 auth、membership、share grants、sync state、AI policy、OpenHub scope / AI policy 控制面;`Convex` / 服务端只保留为历史迁移源、显式 cloud source、compat 和 sync replica 边界,不再作为新增能力的默认正文、附件、AI 会话全文主存储或默认控制面。旧 ACP/Hermes runtime session 只保留为 legacy/debug/兼容边界。
- `Rust kernel` 持有树、子树、边、projection、query、command 的语义主导权;新增树规则不要继续散落到前端、Next route 或临时 compat 层。
- `mnote-web` 是当前 Rust Web 承载层,负责 transport、projection 分发、兼容切流;`compat``fixture` 只用于过渡和测试,不应继续承载长期业务语义。`3000` 是唯一前端公开入口;`3104` 已退役为仅显式 debug/internal 使用的边界。`/tree``/document-debug` 等 debug 壳默认关闭,仅在显式 debug/runtime 验证时启用。
- 前端 runtime 已完成第一轮模块级拆分:`layout.rs` / `tree.rs` / `web_shell.rs` 不再是大型内嵌 JS 的主要定位入口。查 Sidebar、FileTree、tree shell、document adapter 等浏览器功能时,默认先看 `rust/crates/mnote-web/browser/*.js`;查 tiptap island 行为时,默认先看 `rust/spikes/leptos-tiptap-spike/src/editor_runtime/*.rs`,再回到根 `lib.rs` / Rust route。
- 前端主路径应消费稳定 projection,不应在 UI 层重新拼出第二份对象真相。
- Next `documents/page` 读取主链已优先消费 Rust `mnote.page_aggregate.v1` 快照;TS `page-aggregate-builder` 仅保留为历史 adapter / test helper,不再作为 runtime fallback,也不再把“前端手工拼 `meta + content`”描述为当前主路径。
- `3000` 当前主壳已接入 Rust Web WebSocket push 主链(`/api/realtime/ws`+ SSE fallback`/api/tree/events`)的 snapshot / delta / resync consumer,并已有 browser smoke 验证(2026-05-17 WS 迁移 `57ec8322`);后续收口重点是统一 live cache 与减少补偿链,而不是把它描述成“还没接 live stream”。
- 文档页默认主编辑器已切到页面内 `leptos-tiptap` island`BlockNote` 已退出文档页默认主路径,只保留为历史参考实现 / 对照材料。
- Page Aggregate 当前已输出 `blockDocument / blockProjectionVersion / projectionSource``projectionSource=documents.content`),标题/正文/页面设置写入后 smoke 已通过(`task110``task-page-aggregate-body-sync-smoke``task-page-aggregate-options-sync-smoke`);页面/块 AI 旧 Hermes tools 读取和写入块投影只作为兼容证据,不再代表当前 Page AI 主路径;但这仍是从 `documents.content` / local markdown content 投影出来的过渡态,不是 EditorBlockDocument 原生落库完成态。客户端 `PageAggregateClientState` reducer 仍在,页面域单一真源未完全闭环。
- 当前最优先的架构收口不是继续扩编辑器 UI,而是在 local-first MVP 基线上推进 `WorkspacePath/ObjectIdentity` runtime 消费统一、`DocumentBuffer/BufferStore``Page Aggregate` 单一真源收口、`tree command cutover` 收尾、`tree realtime event stream` live cache 统一(WS push 主链 2026-05-17 上线,SSE 降级为 fallback)和 OpenHub + LightRAG 深度融合、agent diff / 冲突合并 / 本地轻量搜索 / 分享同步产品化。AI 侧普通 Markdown 编辑主路径已收口为“当前文件引用 + selection + allowed roots + OpenHub/native agent patch/diff + watcher 同步”;知识库问答、资料 OCR / parse / index / RAG 主路径为 LightRAG + OpenHub tool facadeWeKnora 仅保留为历史设计、参考实现或备用 provider 边界;`mnote.doc.fetch``mnote.doc.markdown_edit``mnote.doc.apply_block_ops``mnote.block.*` 只作为 cloud / remote agent / compat fallback 或复杂结构辅助;`review session`/流式 apply 属于 Phase C(设计冻结,当前不实施),不扩新 AI 功能,不把粗粒度 `mnote.page.save` 当成精确块编辑主入口。
## 组件定位
- `leptos-tiptap` island 是当前文档页默认主编辑区 runtime,但不是系统事实源。
- `BlockNote` 是历史参考实现 / 对照材料,不再是运行时系统组件、默认回退编辑器或系统事实源。
- `Mindmap``tree-first graph` 的一种视图和编辑挂件,不是对象真相层。
- `OnlyOffice` 是独立页面型编辑器,不直接嵌入 `BlockNote` 画布;正文中通常通过附件块跳转进入。
- `page-ai/block-edit-workflow` route 只保留为兼容门面或非 local source 的快捷路径,不作为 local-first 普通 Markdown 编辑默认主路径;local-first 下优先给 OpenHub/native agent 授权文件引用并让 agent 使用自身文件编辑能力。`mnote.doc.markdown_edit` 是 cloud / remote agent / compat fallback`mnote.block.*` 保留为结构性辅助。
- `LightRAG + OpenHub` 是当前默认知识库与 Page AI 融合方向,负责资料库问答、检索、引用和 MNote 宿主集成;MNote 维护 source registry、allowed roots / 权限、FileTree 灯号、资料库设置 UI、status UI、citation/open-reference 映射和 agent tool facade。WeKnora 仅保留为历史设计、参考实现或备用 provider 边界;LiteParse、旧 OCR sidecar、旧 evidence search / local-index agent tools 已退役到 legacy / recycle 边界,不再作为新增主路径。
- 树域三层模型:`Resource Tree`kernel 对象组织真源)→ `File Tree`(主组织投影,`{title}.md` 为页面正文行)→ `Page Tree`(导航投影,不持有结构真相)。涉及资源归属优先走 Rust kernel 的 `KernelObjectIdentity` / `KernelProjectionResourceKind`
## Runtime 模块定位
- `mnote-web` 浏览器 runtime 的当前 canonical 入口是 `rust/crates/mnote-web/browser/`
- Sidebar 装配:`sidebar-tree-runtime.js`,已拆出 workspace、page tree、filetree command/open/upload、attachment open、page settings、live apply 等模块。
- FileTree 通用能力:`filetree-runtime.js``filetree-selection-runtime.js``filetree-context-menu-runtime.js``filetree-dnd-runtime.js``filetree-keyboard-runtime.js`
- Page AI sidebar host`sidebar-page-ai-runtime.js`owner 属于 `07-ai`,不归 `03-rust-web` tree/filetree runtime。
- 文档页 host adapter`document-editor-adapter-runtime.js`,已拆出 pane、resource tab、mindmap host、slash positioning、Tiptap conversion、session 等模块。
- debug/internal tree shell`tree-shell-runtime.js`,已拆出 page、filetree、picker、DOM、render、icons、state 等模块。
- `leptos-tiptap` island 的当前 canonical 入口是 `rust/spikes/leptos-tiptap-spike/src/editor_runtime/`;新增编辑器行为不得继续直接堆入 `lib.rs`,除非它确实是 wasm-bindgen entrypoint、Leptos 壳层信号编排或仍未形成稳定模块边界。
- CodeGraph 查 JS 功能时应能直接定位这些 `.js` 文件中的顶层函数;若结果仍落到 Rust raw string 或大型旧壳,先检查是否查错历史 / recycle 路径或索引未同步。
## 目录优先级
- `/mnt/Data1T/mnote/recycle/wolai-frontend/src/`
wolai-frontendNext.js React 前端)已退役移入 recycle,不作为当前实现依据。页面、编辑器、Sidebar、树视图、阅读态、交互壳默认先看 Rust mnote-web SSR`rust/crates/mnote-web/src/`)。
- `/mnt/Data1T/mnote/recycle/wolai-frontend/convex/`
已随 wolai-frontend 移入 recycle,不允许作为当前 Convex deploy fallback。
- `/mnt/Data1T/mnote/recycle/20260522-convex-runtime-retirement/convex/`
`convex/` functions 源码已软删除到这里,只作为历史审计 / 迁移对照素材;不再作为 active deploy source。默认控制面已由 Turso/libSQL `control-plane` 承接。
- `/mnt/Data1T/mnote/rust/crates/core-protocol/`
Kernel 类型、projection 协议、树/图核心术语先看这里。
- `/mnt/Data1T/mnote/rust/crates/bridge-runtime/`
Kernel query / command / subtree / graph traversal 入口先看这里。
- `/mnt/Data1T/mnote/rust/crates/mnote-web/`
Rust Web route、transport、compat、tree shell、projection 分发先看这里。
- `/mnt/Data1T/mnote/wolai-backend/app/`
辅助后端、异步处理、接口配合先看这里。
- `/mnt/Data1T/mnote/recycle/20260522-convex-runtime-retirement/infra/convex/`
Convex 自托管服务基础设施已软删除到回收区;只作为显式 cloud source / compat / sync replica 或历史数据导出的历史对照,不再被 `desktop:hot` / `dev:hot` 默认启动链路要求。
- `/mnt/Data1T/mnote/src/components/onlyoffice/`
只在处理 OnlyOffice 静态资源、插件或兼容问题时进入。
- `/mnt/Data1T/mnote/recycle/`
默认视为历史回收区,不作为当前实现依据,除非任务明确要求。
## 架构约束
- 涉及树、页面结构、文件树、Sidebar、阅读投影、搜索投影、引用边语义时,优先判断是否应落到 Rust kernel,而不是直接改前端拼装逻辑。
- 前端可以做展示、交互和局部适配,但不要新增第二套树真相、排序真相或 projection 契约。
- `mnote-web``compat route` 可以承接过渡流量,但不要把新的长期业务逻辑继续堆进 compat。
- 浏览器主链默认禁止新增基于 `setInterval`、周期 `setTimeout` 或轮询 fallback 的数据刷新、状态同步和资源存在性检查,尤其是页面树、文件树、文档页、附件、AI 面板等高频可见路径。优先使用 Rust realtime event stream、WebSocket/SSE、watcher、`tree:delta/resync``page-aggregate-synced``MutationObserver` 和显式 command result 驱动刷新;只有在明确标注的 legacy/debug/internal 边界下,才允许短期保留轮询,并且必须在设计/bug 说明里记录原因、退出条件和内存/CPU 风险。
- 涉及文档页标题、页面设置、正文保存、页头与树一致性时,优先判断是否应收口到 `Page Aggregate`,不要继续在页面壳或 island 外侧拼第二份页面真相。
- 涉及页面新建、重命名、移动、归档、恢复、嵌入时,优先沿 `tree.*` 正式命名推进;`documents.*` 只视为兼容层,不应继续扩写为长期命令面。
- 涉及 local-first AI 普通 Markdown 编辑时,优先沿“授权文件引用 + `AiAccessScope` + allowed roots + OpenHub/native agent 原生 patch/diff + 文件版本冲突模型 + watcher 同步”推进;涉及 cloud / remote agent / 复杂结构辅助时,才沿 `mnote.doc.*` / `mnote.block.*` legacy tool facade 与 Rust `EditorCommand` 推进。`mnote.page.save` 只作为页面级兜底写入工具。
- 涉及资源归属(哪个页面拥有哪个 mindmap/附件)、object identity 和资源生命周期时,优先沿 Resource Tree → File Tree projection → `tree.resource.*` 命令面推进;`tree.*` 是正式命令面,`documents.*` 只视为兼容层。
- 页面 AI 编辑当前 local-first 主路径为:页面定位到真实 `.md` 文件,MNote 计算 `AiAccessScope` / allowed roots / selectionOpenHub/native agent 在白名单目录内用自身 patch/diff/文件编辑能力写入,MNote 通过 watcher / refresh 同步 tiptap。Hermes/Reasonix 只保留为 legacy/debug/外部工作流边界。`mnote.doc.markdown_edit` 只作为 cloud / remote agent / compat fallback`mnote.block.*` 保留为结构性辅助(拖拽排序等)。流式 apply + suggest/review(参考 BlockNote AI)作为 Phase C 设计冻结,当前不实施。
- Page AI / OpenHub / 知识库这类用户入口首屏必须优先保证真实任务区可用:对话、输入框、知识库列表/详情占主体空间;debug、scope、health、route guard 等诊断信息只能放在折叠诊断区、开发态或日志中,不得默认挤占用户输入和阅读区域。
- MNote + OpenHub 深度融合的交互能力优先改 OpenHub 源码本体(React/FastAPI/服务边界),MNote 只提供 auth、scope、proxy、文件/引用回跳等宿主胶水;不得用 MNote 侧 DOM 注入、悬浮按钮或拦截脚本伪装成 OpenHub 原生能力。
- OpenHub/opencode 等 legacy fallback 只能保留为显式 debug/internal 边界;普通用户 UI 不得出现切换到 fallback 的按钮、入口或引导文案。
- 涉及知识库资料索引 / OCR / RAG 时,默认沿 OpenHub + LightRAG 与 provider-neutral `mnote.knowledge_rag.*` / `/api/knowledge-rag/*` 推进。WeKnora 只作为历史设计、参考实现或备用 provider 边界;新增功能不得再假设 WeKnora 是默认 provider。
- 需要架构判断时,优先参考:
- `/mnt/Data1T/mnote/ARCHITECTURE.md`
- `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md`
- `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`
- `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md`
- `/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md`
- `/mnt/Data1T/mnote/design/05-editor-mainline/reference/5-5-page-aggregate-single-truth-alignment-v1.md`
- `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-6-page-aggregate-alignment-checklist-v1.md`
- `/mnt/Data1T/mnote/design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md`
- `/mnt/Data1T/mnote/design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md`
- `/mnt/Data1T/mnote/design/03-rust-web/done/3-3-rust-web-tree-realtime-event-stream-v1.md`
- `design/03-rust-web/done/3-14-rust-web-tree-realtime-ws-push-v1.md`
- `/mnt/Data1T/mnote/design/10-review/done/08-kernel-architecture-next-priority-review-and-checklist.md`
- `/mnt/Data1T/mnote/design/10-review/done/09-page-ai-fast-block-edit-runtime-review.md`
- `/mnt/Data1T/mnote/design/10-review/done/10-current-mnote-ai-runtime-review-v1.md`
- `/mnt/Data1T/mnote/design/10-review/done/11-current-full-architecture-review-v1.md`
- `/mnt/Data1T/mnote/design/04-tree-domain/done/4-24-resource-tree-filetree-pagetree-source-contract-checklist-v1.md`
- `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-12-main-editor-object-tab-resource-alignment-checklist-v1.md`
- `/mnt/Data1T/mnote/design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md`
- `/mnt/Data1T/mnote/design/03-rust-web/reference/3-23-sidebar-local-folder-resource-runtime-followup-v1.md`
- `/mnt/Data1T/mnote/design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md`
- `/mnt/Data1T/mnote/design/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.md`
- `/mnt/Data1T/mnote/design/10-review/done/20-post-lightrag-runtime-hardening-checklist-v1.md`
## 设计稿目录规则
- `design/01-*``design/10-*` 主线大类统一按目录表达状态:`process/` 放当前可执行项,`done/` 放已完成项,`reference/` 放参考材料,必要时用 `draft/` 放未成形草稿。
- 主线设计稿在推进中、且可直接拆 checklist 执行时放到对应大类的 `process/`
- 主线设计稿在当前真实代码中已完成后,必须移动到对应大类的 `done/`
- 参考实现、review 证据、对照矩阵、候选合同、测试流程基线等不直接执行的材料必须移动到对应大类的 `reference/`,不要继续占用 `process/`
- 尚未形成可执行 checklist 的新设想先放 `draft/`;进入实施前必须拆成明确 owner、验收和归档条件。
- 已被后续实现或更新稿明确覆盖、但又不属于 `done` 的旧主线稿,必须移动到 `design/old/` 并标记为 `[recycle]`,不要继续占用活跃 `process/`
- `design/old/` 下的历史废弃稿也统一按 `process/``done/` 分层,但标题继续标记 `[recycle]`
- `design/90-reference/` 只放参考资料,不参与 `process/done` 状态迁移。
## Bugs 目录规则
- `bugs/` 默认镜像 `design/` 的主线分类方式,按对应大类放置缺陷。
- 每个大类继续按 `process/``done/` 分层:
- `process/`:缺陷已确认存在,仍在修复或验证中
- `done/`:缺陷已修复,且已有真实代码与验证证据
- 新确认的缺陷先放 `process/`;修复完成后必须移动到同类目的 `done/`,不要在两个目录同时保留同一条缺陷。
- 缺陷归类以真正 owner 和长期主线为准,不以表面症状命名:
- `sidebar/topbar/breadcrumb/文档页壳/Wolai 体验对齐` 优先归到 `05-editor-mainline/`
- `projection/row model/selection/focus/keyboard/DnD/tree command` 优先归到 `04-tree-domain/`
- 当发现bug时,不仅仅是修bug,因为我们当前还处于mvp,需要看bug后面是否反映的是系统的缺失,如果需要系统性的开发,可以写deisign。如果边界不清,应该让user确认。
## 协作边界
- 仅修改与当前任务直接相关的文件。
- 不要擅自恢复、覆盖、删除用户已有改动。
- 若发现与当前任务无关的脏改动,保持不动;若怀疑会影响当前任务,先确认再处理。
- 若当前问题只是 UI 表现异常,先确认是否是实验性 tree shell、compat 路径、轮询或 fallback 混入首屏主链,而不是直接怀疑 Convex 本身。
- 若发现现有轮询或定时刷新链路,不要直接在其上继续叠加补丁;先确认是否能改成事件驱动、watcher/realtime 推送或命令结果定点刷新,再决定是否保留临时 fallback。
- 子 agent 只能作为受控叶子 worker:任务书必须限定读写范围、验证命令、交付文件和禁止项;不得自行再启动 runner、subagent、额外 worktree 或修改任务书。Codex 主控必须复核 diff、handoff/result、验证证据和 git 状态后才能采纳;Reasonix/Hermes 只属于历史 provider 边界。
- 主控必须维护当前 subagent 的任务书、写入范围和采纳状态。任何 `worker` 启动后到完成/取消前,都视为可能写入;主控不得同时手工修改同一文件范围,也不得再派第二个 worker 修改同一范围。
- 主控不得因为自己已经手工完成同一范围就提前关闭仍在运行的实现型 subagent;若该 worker 的写入范围已失效,必须先 interrupt/send_input 明确取消并说明其结果不再采纳,随后等待 shutdown/完成通知。只有已完成、已取消且确认不会再写入、或用户明确要求停止时,才 close_agent。
- 使用 subagent 的目标是缩短关键路径。委派前必须确认子任务不会阻塞主控下一步、不会与主控或其它 worker 写同一文件、且主控有明确的结果采纳点;否则主控直接做。若 subagent 结果晚到,主控必须标记“未采纳”或复核后合并,不能让后台结果与主线程补丁并存成冲突。
- 进入最终测试或最终回复前,主控必须确认本轮仍在运行的实现型 subagent 已完成、已明确取消并停止,或其输出已被标记为不采纳;不得在后台 worker 仍可能写入时声称已完成。
## CodeGraph 使用
- 当前项目已配置 CodeGraph MCP;结构性代码问题优先使用 `codegraph_*` 工具:`codegraph_search` 查符号,`codegraph_callers` / `codegraph_callees` 查调用关系,`codegraph_impact` 做影响分析,`codegraph_context` / `codegraph_explore` 获取聚焦上下文,`codegraph_files` 查看索引文件结构,`codegraph_status` 检查索引健康。
- CodeGraph 是当前开发态代码图主工具;代码改动后运行 `codegraph sync .`,大范围重构、排除规则变化或索引异常时运行 `codegraph index . --force`。只有查找字面文本、日志字符串、注释原文,或已经明确目标文件时,才优先用 `rg` / 直接读文件。
- 提交 git 前必须再次运行 `codegraph sync .`,随后用 `codegraph status .``codegraph_status` 确认没有 pending changes;若仍有 pending、索引异常或本轮改动包含大范围重构 / 排除规则变化,改跑 `codegraph index . --force` 后再提交。
## Reference-Code 快速对照流程
- 对照 VSCode / Sidex / Zed / Lapce / Tiptap 等参考实现时,先确认实际源码目录和对应 `.codegraph/` 是否存在;当前优先参考 `/mnt/Data1T/mnote/reference-code/sidex-main` 的完整 VSCode 工作台源码,`reference-code/vscode` 只作为裁剪版辅助证据。
- 每次只围绕一个功能切面做对照,例如 Explorer 打开目标、编辑器 tab、资源生命周期、拖拽排序、快捷键或 overlay 定位;不要一次性抽象迁移整个参考项目。
- 推荐步骤:`codegraph_status` 确认索引 -> `codegraph_search/context` 找参考实现入口 -> `codegraph_callers/callees` 看调用链 -> 对应查 MNote 当前链路 -> 映射到 Rust kernel / mnote-web / 前端 host 的正确边界 -> 补 smoke 或测试。
- 对照结论必须区分“可直接采用的交互/状态模型”“只适合作参考的实现细节”“不符合 MNote local-first / tree-first 主线的内容”;不要把参考项目中的 UI 层状态当成 MNote 的新事实源。
## 常用命令
- 根目录热启动:`npm run desktop:hot`
- 前端开发(已迁移至 Rust SSR):`npm run desktop:hot` 启动后直接访问 `http://localhost:3000`
- 前端检查:Rust 测试 `cargo test -p mnote-web`Rust SSR 与 API),旧 React 前端已移入 recycle
- 后端开发:`cd /mnt/Data1T/mnote/wolai-backend && uvicorn app.main:app --reload --port 8000`
- Convex 自托管:仅在显式 cloud / compat / sync replica 或历史导出场景参考 `/mnt/Data1T/mnote/recycle/20260522-convex-runtime-retirement/infra/convex/README.md`
- Control-plane 后端选择:默认 `MNOTE_CONTROL_PLANE_BACKEND=libsql-local`;云端开发使用 `MNOTE_CONTROL_PLANE_BACKEND=turso-remote``turso-local-replica` 并配置 `MNOTE_TURSO_DATABASE_URL``MNOTE_TURSO_AUTH_TOKEN``sqlite` 不再是 mnote-web 运行时后端,只保留给 control-plane-admin 迁移 / 导出和测试隔离。
- Turso dev 数据库:[Turso CLI](https://docs.turso.tech/cli/installation) `turso db create mnote-dev`,创建 token 后设置环境变量即可。
## Smoke 基线
- 当前 smoke 分类与默认基线以 `scripts/TESTING_REFERENCE.md` 为准。
- 默认浏览器验证入口是 `3000 Rust SSR + leptos-tiptap island + local-first workspace + Turso/libSQL control-plane auth`
- **脚本纪律**:所有 smoke 和测试脚本不得直接 `sqlite3` CLI 写 control-plane DB;需要 seed 数据时必须走 Rust API、测试 seed endpoint、`scripts/lib/control-plane-dev-seed.js``scripts/lib/control-plane-test-env.js` helper。直写脚本必须标注理由和退出条件。
- 退役 Convex / Next / 3104 / BlockNote 路径的 smoke 不作为默认回归基线;只有显式 legacy/cloud/compat 任务才运行对应脚本。
## 默认测试账号
- 后续网页测试、浏览和 smoke 默认使用当前 SQLite control-plane Auth 测试账号:邮箱 `mnote.e2e@example.com`,密码 `MnoteE2E123!`,用户名 `mnote-e2e`
- 优先从 `http://localhost:3000/auth` 点击“测试账号快速登录”进入;若需手动注册,也必须注册同一组账号,不要改用 `MNOTE_DEV_AUTH=1` 跳过真实 auth。
- 需要核验登录是否真实生效时,优先检查当前 `mnote_session` 是否能解析到 libSQL/Turso control-plane 用户会话,避免把 `devFallback` 当成真实登录;Convex JWT 只属于历史 / cloud compat 边界。
## 前端测试方法
- 看页面当前真实渲染结果、登录态下实际内容、JS 渲染后的 `localhost` 页面时,优先用 `/doko`;它适合读取真实 Chrome 中已经渲染完成的页面。
- 做交互测试、文件创建/删除/移动、上传、快速登录、侧边栏展开、回归断言时,优先用浏览器自动化测试工具;这类任务不要只靠 `/doko`
- 推荐顺序是:先用 `/doko` 快速确认页面是否正常渲染,再用浏览器自动化测试工具验证关键交互链路。
- 影响主页入口、Sidebar、tree shell、文档页首屏时,优先补或复用 `scripts/task*-smoke.js` 这类 smoke 脚本。
- 排查高 CPU / 高内存 / 卡顿时,先看是否存在首屏误走实验性 tree shell、compat fallback、重复请求、轮询或回链面板持续刷新,再看数据底座。
## Wolai-aline 对标流程
- 凡任务涉及 `wolai-aline`、Wolai 对标、复刻 Wolai 体验或把 `3000` 行为与 Wolai 页面比对,必须启用 `/home/lix/.codex/skills/wolai-aline` skill,并参考 `/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/reference/wolai-aline-test-flow-v1.md`
- Wolai-aline 任务默认采用“Wolai 基线取证(默认只读,编辑器任务仅在明确授权的 editable-test mode 下执行)-> 本地 RED smoke -> 小范围实现 -> 本地验证 -> subagent 浏览器对标复测 -> 主线程截图复核 -> 汇报剩余差异”的流程。
- 浏览器对标测试必须使用 subagent 执行;subagent 只做浏览器验证和截图,不修改源码、不还原文件、不清理证据;编辑器任务可在明确声明的 editable-test mode 下做最小编辑验证。
- Wolai 默认优先只读;编辑器对标只有在用户明确给出测试页和授权时才可做最小范围编辑测试。其他 Wolai 页面写入仍需沙盒页 URL 和明确授权。
- 即使在授权测试页,也禁止未经确认地删除、移动、归档、发布、评论、改权限或批量修改既有非测试内容;编辑测试必须记录前后截图、动作链、输入内容和清理状态。
- 对标验收不能只看文案或 DOM 是否存在;必须检查截图中的控件形态、开启/关闭状态、hover/active 状态、快捷键行为、URL 是否跳转等真实体验差异。
- 发现截图或实测行为与本地实现不一致时,先把差异补进 smoke 形成可复现失败,再修改实现并复测。
- Wolai owner 登录态优先复用 `/mnt/Data1T/mnote/tmp/wolai-playwright-profile`;遇到登录或滑块验证,不绕过,记录阻塞并让用户介入。
## 文件编码与风格
- 所有新增或修改文件统一使用 UTF-8。
- TS/TSX 默认 2 空格缩进,Python 默认 4 空格缩进。