279 lines
46 KiB
Markdown
279 lines
46 KiB
Markdown
# 7-68 OpenHub + WeKnora + MNote 深度融合执行 Checklist v1
|
||||
|
|
|
|||
|
|
状态:process
|
|||
|
|
Owner:07-ai / mnote-web / control-plane / knowledge-provider
|
|||
|
|
日期:2026-06-25
|
|||
|
|
|
|||
|
|
上位设计:`design/07-ai/process/7-68-openhub-weknora-mnote-deep-fusion-v1.md`
|
|||
|
|
|
|||
|
|
## 0. 执行原则
|
|||
|
|
|
|||
|
|
- 保留各系统已完成能力:OpenHub 保留 AI 面板、FastAPI、SQLite session/message、Redis 临时态、skill/tool permission、opencode client;WeKnora 保留 KB/API/CLI/MCP/search/index;MNote 保留 auth/workspace/resource tree/document pane/source registry。
|
|||
|
|
- 只在产品真相冲突处做胶水:登录入口、workspace/rootUri scope、知识库 source truth、文件打开、citation 回跳、OpenHub 非 AI 入口裁剪、Git snapshot 禁用。
|
|||
|
|
- 不把未确认能力写成已完成能力:当前 OpenHub 源码未确认独立 MCP 管理 UI/API,第一阶段通过 MNote 注册 WeKnora CLI/MCP/API tool 到 OpenHub/opencode。
|
|||
|
|
- 不把 Redis 当持久真相:OpenHub message 真相在 SQLite,MNote auth/source/file truth 在 control-plane/本地文件,WeKnora Redis 属于其内部队列/缓存。
|
|||
|
|
|
|||
|
|
## 1. P0 设计冻结与旧路径降级
|
|||
|
|
|
|||
|
|
- [x] 在 `design/07-ai/process/7-65-opencode-webui-embed-page-ai-v1.md` 顶部加覆盖说明:官方 opencode WebUI iframe 仅保留 fallback,不是 Page AI 主线。
|
|||
|
|
- [x] 在 `design/07-ai/process/7-66-opencode-native-page-ai-ui-v1.md` 顶部加覆盖说明:自研 native UI 仅保留 fallback,不继续扩自研聊天框。
|
|||
|
|
- [x] 在 `design/07-ai/process/7-67-openhub-page-ai-fusion-v1.md` 顶部加覆盖说明:已被 7-68 覆盖,路线改为嵌入 OpenHub AI 面板并保留 FastAPI/opencode client。
|
|||
|
|
- [x] 搜索 `design/07-ai/`、`scripts/`、`rust/crates/mnote-web/browser/` 中仍把 LightRAG 描述为默认知识库 provider 的文案,列出需改文件,不在本任务中顺手改代码。
|
|||
|
|
- [x] 标记 `7-50` 到 `7-57` 中 LightRAG 相关 done 文档为历史事实:曾经完成,不再代表当前新主线。
|
|||
|
|
|
|||
|
|
P0 搜索记录(2026-06-25):
|
|||
|
|
|
|||
|
|
- 已在 `design/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.md`、`7-51`、`7-52`、`7-55`、`7-56`、`7-57` 顶部标记历史口径:LightRAG 曾完成,但不再代表当前新主线;WeKnora 是 7-68 默认 provider。
|
|||
|
|
- 仍需后续单独迁移或归档的 active/process 文档:`design/07-ai/process/7-47-mnote-public-capability-plugin-registry-v1.md`、`design/07-ai/process/7-54-raganything-multimodal-retrieval-alignment-v1.md`、`design/07-ai/process/7-61-yuxi-reference-middleware-extensions-dashboard-v1.md`。这些文档仍含 LightRAG 默认主线语义,应按 7-68 后续批次改为 WeKnora / provider-neutral 或移入 `design/old/`。
|
|||
|
|
- 仍需后续代码迁移的 LightRAG 残留:`rust/crates/mnote-web/browser/document-resource-tab-runtime.js`、`rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js`、`scripts/reasonix-acp-wrapper.mjs`、`scripts/task538-knowledge-rag-source-scope-api-smoke.js`、`scripts/task542-knowledge-rag-search-grouping-and-short-query-smoke.js`、`scripts/TESTING_REFERENCE.md`、`scripts/task530-knowledge-rag-page-ai-final-answer-smoke.js`。本轮先完成 7-68 主链静态边界与 WeKnora facade,不批量重写所有 legacy smoke。
|
|||
|
|
|
|||
|
|
## 2. P0 OpenHub 源码事实冻结
|
|||
|
|
|
|||
|
|
- [x] 固定 OpenHub 源码路径:`/tmp/mnote-openhub-research/OpenHub`;若后续要深改,先建立可复核源码快照或 CodeGraph 索引。
|
|||
|
|
- [x] 记录 FastAPI 入口:`smart-query-backend/app/main.py`,router 包括 `auth/query/session/admin/files/internal/knowledge/admin_knowledge/channels`。
|
|||
|
|
- [x] 记录 opencode client:`app/services/opencode_client.py` 使用 `OPENCODE_BASE_URL`,并支持 `directory` 参数。
|
|||
|
|
- [x] 记录 opencode launcher:`app/services/opencode_launcher.py` 可启动 `opencode serve`;集成时 `workdir` 必须来自 MNote rootUri,不用 OpenHub 默认路径。
|
|||
|
|
- [x] 记录 session/message 真相:`init_db.py` 的 `conversation_sessions/conversation_messages` 与 `app/database.py`。
|
|||
|
|
- [x] 记录 Redis 用途:`app/core/auth.py`、`app/database.py` 中的 token/rate-limit/workspace cache/图片临时态;不得写成消息队列主链。
|
|||
|
|
- [x] 记录自动 Git snapshot 触发点:`app/services/stream.py`、`app/services/task_executor.py`、`app/api/session.py` restore API。
|
|||
|
|
- [x] 记录冲突入口:`App.jsx` 的 `/login`、`/admin`;`FileManager.jsx`;`KnowledgeManager.jsx`;`GitTimeMachine.jsx`。
|
|||
|
|
|
|||
|
|
P0 OpenHub 记录(2026-06-25):
|
|||
|
|
|
|||
|
|
- 源码路径已固定为 `/tmp/mnote-openhub-research/OpenHub`。
|
|||
|
|
- FastAPI 入口 `/tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/main.py` include routers:`auth/query/session/admin/files/internal/smart_entity/smart_entity_tasks/knowledge/admin_knowledge/channels`。
|
|||
|
|
- `app/config.py` 中 `OPENCODE_BASE_URL` 默认 `http://127.0.0.1:4096`;`app/services/opencode_client.py` 的 `get/post/put/patch` 支持把 `directory` 写入 query params。
|
|||
|
|
- `app/services/opencode_launcher.py` 可启动 `opencode serve`;`main.py` 中 `opencode_auto_start` 当前默认 workdir 仍有 OpenHub 自带 fallback,MNote 集成时必须由 rootUri 派生或禁用 auto-start。
|
|||
|
|
- Git snapshot 写链真实存在:`app/services/stream.py`、`app/services/task_executor.py` 会 init git / has_changes / create_snapshot;`app/api/session.py` 暴露 snapshot list/detail/diff/restore/restore-file 路由。
|
|||
|
|
- 冲突入口真实存在:前端 `src/App.jsx` 有 `/login` 与 `/admin`;OpenHub 还包含 FileManager / KnowledgeManager / GitTimeMachine 相关入口,MNote host 第一阶段必须 guard 或转接。
|
|||
|
|
|
|||
|
|
## 3. P0 WeKnora 源码事实冻结
|
|||
|
|
|
|||
|
|
- [x] 固定 WeKnora 源码路径:`/mnt/Data1T/Mnote_data/weknora/WeKnora`。
|
|||
|
|
- [x] 记录 KB UI 入口:`frontend/src/views/knowledge/KnowledgeBaseList.vue`、`KnowledgeBase.vue`、`KnowledgeBaseEditorModal.vue`、`frontend/src/components/knowledge-processing-timeline.vue`。
|
|||
|
|
- [x] 记录多 KB 检索:`docs/api/knowledge-search.md` 与 router `/api/v1/knowledge-search`,请求必须带 `knowledge_base_id(s)` 或 `knowledge_ids`。
|
|||
|
|
- [x] 记录单 KB hybrid-search:`client/knowledgebase.go` 的 `/api/v1/knowledge-bases/:id/hybrid-search`。
|
|||
|
|
- [x] 记录 `SearchResult` 全字段:`id/content/knowledge_id/knowledge_base_id/chunk_index/knowledge_title/start_at/end_at/seq/score/match_type/sub_chunk_id/metadata/chunk_type/parent_chunk_id/image_info/knowledge_filename/knowledge_source/knowledge_channel/chunk_metadata/matched_content/knowledge_description`。
|
|||
|
|
- [x] 记录 CLI MCP:`cli/internal/mcp/tools.go`、`cli/cmd/mcp/serve.go`;第一阶段默认采用只读 curated surface。
|
|||
|
|
- [x] 记录 Python `mcp-server/` 作为后续写能力参考,第一阶段不默认暴露给 OpenHub/opencode。
|
|||
|
|
- [x] 记录 WeKnora Redis/Asynq/Langfuse 属于 WeKnora stack,不和 OpenHub Redis keyspace 混用。
|
|||
|
|
|
|||
|
|
P0 WeKnora 记录(2026-06-25):
|
|||
|
|
|
|||
|
|
- 源码路径已固定为 `/mnt/Data1T/Mnote_data/weknora/WeKnora`。
|
|||
|
|
- KB UI 入口已定位:`KnowledgeBaseList.vue`、`KnowledgeBase.vue`、`KnowledgeBaseEditorModal.vue`、`knowledge-processing-timeline.vue`。
|
|||
|
|
- 多 KB 搜索合同来自 `docs/api/knowledge-search.md`:`POST /api/v1/knowledge-search`,请求至少包含 `knowledge_base_id` 或 `knowledge_base_ids`;可用 `knowledge_ids` 限定文件。
|
|||
|
|
- `client/knowledgebase.go` 记录 `HybridSearch` 路径 `/api/v1/knowledge-bases/:id/hybrid-search`;`SearchResult` 包含 `id/content/knowledge_id/chunk_index/knowledge_title/start_at/end_at/seq/score/match_type/chunk_type/image_info/metadata/knowledge_filename/knowledge_source/knowledge_channel/matched_content`,服务端还有 parent/sub/chunk metadata 等扩展字段,本轮 MNote mapper 以原始 chunk 保留这些字段。
|
|||
|
|
- CLI MCP 已定位:`cli/internal/mcp/tools.go` 注册 curated tools;`cli/cmd/mcp/serve.go` 构建 `weknora mcp serve`,当前 stdio-only。第一阶段 MNote 暴露自己的只读 facade,不默认开放 Python `mcp-server` 写能力。
|
|||
|
|
|
|||
|
|
## 4. P1 OpenHub 服务栈接入
|
|||
|
|
|
|||
|
|
- [x] 为 MNote dev-hot 增加 OpenHub 开关:`ENABLE_OPENHUB=1`、`OPENHUB_BACKEND_CMD`、`OPENHUB_BACKEND_PORT`、`OPENHUB_REDIS_URL/DB`、`OPENHUB_OPENCODE_BASE_URL`。
|
|||
|
|
- [~] 启动顺序明确为 Redis -> opencode serve -> OpenHub FastAPI -> MNote host health proxy。
|
|||
|
|
- [x] health 输出区分 `openhub_fastapi`、`openhub_redis`、`opencode_serve`、`weknora_api`、`weknora_cli_mcp`、`mnote_binding`。
|
|||
|
|
- [x] 禁止 kill-port/destructive launcher 行为;端口被占用时只报告占用 PID 和进程名。
|
|||
|
|
- [~] OpenHub `opencode_auto_start` 若启用,`opencode_workdir` 必须由 MNote 当前 rootUri 派生;否则 MNote 自己启动 opencode serve 并让 OpenHub 复用。
|
|||
|
|
- [x] 加环境开关或最小 fork patch 禁用 OpenHub 自动 `git init/commit/restore`。
|
|||
|
|
- [~] smoke:OpenHub FastAPI 可 `/openapi.json` 或 health 探针;Redis 可认证连接;opencode serve 可访问;WeKnora CLI profile/doctor 可通过;WeKnora stdio MCP handshake 仍未作为最终通过项。
|
|||
|
|
|
|||
|
|
P1 OpenHub 服务栈记录:
|
|||
|
|
|
|||
|
|
- `scripts/desktop-hot.js` 已增加 `ENABLE_OPENHUB`、`OPENHUB_CMD`、`OPENHUB_PORT`、`OPENHUB_BACKEND_DIR`、`OPENHUB_REDIS_HEALTH_URL`、`MNOTE_OPENHUB_BASE_URL`、`MNOTE_OPENHUB_DISABLE_GIT_SNAPSHOT_RESTORE`,并补 `scripts/desktop-hot.test.js`。
|
|||
|
|
- 当前实现的变量名是 `OPENHUB_CMD` / `OPENHUB_PORT`,不是 checklist 早期草案里的 `OPENHUB_BACKEND_CMD` / `OPENHUB_BACKEND_PORT`;后续若需要兼容别名可再补。
|
|||
|
|
- `desktop-hot` 不释放或 kill OpenHub 端口;OpenHub Redis 目前只有 health URL 检查,不负责启动 Redis。
|
|||
|
|
- `MNOTE_OPENHUB_DISABLE_GIT_SNAPSHOT_RESTORE=1` 已作为 MNote 启动环境默认值和 smoke 断言;OpenHub 研究源码 `/tmp/mnote-openhub-research/OpenHub/smart-query-backend` 已最小 patch:`git_snapshot.py` 中央拦截 `init/config/add/commit/checkout/restore/reset/revert`,`stream.py`、`task_executor.py` 跳过自动 snapshot,`session.py` 的 restore / restore-file 在禁用时返回 403。`scripts/task770-openhub-git-snapshot-restore-guard-static-smoke.js` 和 Python guard 探针已通过。
|
|||
|
|
- 当前真实探针:OpenHub FastAPI `127.0.0.1:18080`、opencode `127.0.0.1:4096`、MNote `3021` 均可达;WeKnora 在 MNote 进程携带 `MNOTE_WEKNORA_API_KEY` 后 `/api/page-ai/openhub/status` 返回 ready。Redis 目前只作为 OpenHub 内部可选依赖/降级链路,MNote health 仅支持外部 URL 探针,不负责启动 Redis;已用 WeKnora `.env` 的 `REDIS_PASSWORD` 真实 `AUTH + PING` 返回 `+OK/+PONG`。
|
|||
|
|
- 2026-06-26 WeKnora CLI 真实 profile smoke:临时 `XDG_CONFIG_HOME` 下执行 `weknora profile add mnote-local --host http://127.0.0.1:8080 --use`,再把 MNote 进程中的 `MNOTE_WEKNORA_API_KEY` pipe 给 `weknora auth login --with-token`,`weknora doctor --no-cache --format json` 返回 4/4 checks passed(base URL、auth、server version、credential storage)。`weknora mcp serve --help` 通过;stdio MCP handshake 探针未稳定完成,保留为 dev-hot/orchestration 后续项。
|
|||
|
|
|
|||
|
|
## 5. P1 登录与 OpenHub Scope
|
|||
|
|
|
|||
|
|
- [x] 新增/扩展 MNote OpenHub bootstrap endpoint:输入当前 `mnote_session + workspace/rootUri + page_resource_id`,输出 OpenHub runtime scope。
|
|||
|
|
- [x] 定义 `openhub_user_key = stable_hash(mnote_user_id)`。
|
|||
|
|
- [x] 定义 `openhub_workspace_key = stable_hash(workspace_id, root_uri)`。
|
|||
|
|
- [x] 定义 `openhub_session_scope = hash(mnote_user_id, workspace_id, root_uri, page_resource_id)`。
|
|||
|
|
- [x] 定义 `weknora_tool_scope = allowed_kb_ids + allowed_source_ids + citation_policy`。
|
|||
|
|
- [x] 禁用 OpenHub 前端 `/login` 跳转和 localStorage token 作为 MNote 产品入口;由 MNote proxy/header/bootstrap 注入受控身份。
|
|||
|
|
- [x] 保留 OpenHub 后端 user/session owner 校验;映射到 MNote 派生 OpenHub user,不共享单一 OpenHub 用户。
|
|||
|
|
- [~] rootUri/workspace 切换时新建或切换 OpenHub session;旧 binding 标记 `stale/archived`。
|
|||
|
|
- [x] 测试:两个 MNote 用户同一页面不能读到同一个 OpenHub session/message/skill/tool permission scope。
|
|||
|
|
|
|||
|
|
P1 scope 记录:
|
|||
|
|
|
|||
|
|
- 新增 `rust/crates/mnote-web/src/routes/page_ai_openhub.rs`,`/api/page-ai/openhub/bootstrap` 输出 camelCase 与 snake_case scope:`openhubUserKey/openhub_user_key`、`openhubWorkspaceKey/workspace_key`、`openhubSessionScope/session_scope`、`skillScope/skill_scope`、`toolPermissionScope/tool_permission_scope`、`weknoraToolScope/weknora_tool_scope`。
|
|||
|
|
- MNote 侧已拒绝 OpenHub JWT/localStorage 作为产品入口;`/page-ai/openhub/login` 等非 AI 路由由 MNote guard。
|
|||
|
|
- OpenHub 研究源码已消费 `X-MNote-*` headers 派生后端 user/scope,并保留 session owner guard。
|
|||
|
|
- 2026-06-26 `node --check scripts/task775-openhub-mnote-scope-isolation-smoke.js` 与 `node scripts/task775-openhub-mnote-scope-isolation-smoke.js`:通过。直连 OpenHub MNote header scope 创建 session `task775-openhub-scope-1782410072554-157c8c`,Owner A 可读取自己写入的 user message,Owner B 读取同一 session messages 返回 403 `无权访问该会话`;stream 阶段模型不可用不影响 owner guard 验收,因为消息持久化和隔离均已验证。
|
|||
|
|
|
|||
|
|
## 6. P1 Page AI 嵌入 OpenHub AI 面板
|
|||
|
|
|
|||
|
|
- [x] 在 `rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js` 设计嵌入方式:iframe 或 reverse proxy 二选一。
|
|||
|
|
- [x] 只暴露 OpenHub AI 页面;`/login`、`/admin`、FileManager、KnowledgeManager、GitTimeMachine、Team/Scheduler/SmartEntity 非 MVP 入口隐藏、404 或转 MNote。
|
|||
|
|
- [~] 保留 AI 主界面、history/session 抽屉、skill/agent 设置、tool/model permission、tool card、diff、changed files、运行日志。
|
|||
|
|
- [x] 如果 OpenHub 无 MCP 管理 UI,只显示 WeKnora MCP/CLI tool 连接状态和 MNote scope,不新建完整 MCP 管理器。
|
|||
|
|
- [x] MNote context 注入字段:user display、workspace/rootUri、page path/title/resource id、selection 摘要、allowed roots、session/skill/tool/weknora scope。
|
|||
|
|
- [x] changed file chip 点击走 MNote document pane bridge。
|
|||
|
|
- [x] OpenHub KnowledgeManager 入口若出现,跳转 MNote WeKnora 知识库页;不得打开 OpenHub knowledge tables。
|
|||
|
|
- [x] browser smoke:登录 MNote 后打开 Page AI,不出现 OpenHub/WeKnora 登录页。
|
|||
|
|
- [x] browser/API smoke:OpenHub session/message 已持久化并可读;刷新后 UI history 恢复已完成真实浏览器验收。
|
|||
|
|
|
|||
|
|
P1 Page AI host 记录:
|
|||
|
|
|
|||
|
|
- `sidebar-page-ai-runtime.js` 默认打开 OpenHub host drawer,iframe 指向 `/page-ai/openhub/ai?scope=...`;`localStorage mnote.page_ai.openhub_host=0` 可回退 `/page-ai/opencode`。
|
|||
|
|
- `page_ai_openhub.rs` 与 `routes/mod.rs` 已挂 `/page-ai/openhub/ai` 静态 shell 和 `/page-ai/openhub/ai/{*path}` proxy;`login/admin/file/files/knowledge/git` 路由已 guard。
|
|||
|
|
- OpenHub React 前端已做 MNote embed 最小补丁:`mnoteEmbed.js` 识别 `/page-ai/openhub/ai` 嵌入态,`BrowserRouter` 使用 `/page-ai/openhub/ai` basename,API 默认走 `/page-ai/openhub/ai/api`,请求自动携带 `scope/mnoteScope`,无 token 不再发送 `Bearer null`,401 不跳 OpenHub `/login`,`/login/admin/file/files/knowledge/git` 前缀导航回 AI 根页;嵌入态隐藏 OpenHub FileManager、KnowledgeManager、GitTimeMachine、SmartEntity/Team 入口和对应 drawer。
|
|||
|
|
- MNote `ai_shell` 已从 OpenHub FastAPI 根 `/` 拉取 SPA index.html 并重写 `/assets/...` 到 `/page-ai/openhub/ai/assets/...`;OpenHub React dist 已复制到 `smart-query-backend/static/`。
|
|||
|
|
- 2026-06-26 浏览器 smoke `node scripts/task773-page-ai-openhub-browser-smoke.js`:通过。MNote 3000 可达,测试账号真实登录成功(`authMode=sqliteSession`),Page AI drawer、OpenHub host chrome 与 `/page-ai/openhub/ai?scope=...&mnoteScope=...` iframe 可见,未出现 OpenHub/WeKnora 登录页;iframe 内 OpenHub React UI 可见,文本 marker 包含 `OpenHub 平台/开始对话/历史记录/技能管理`,`openhubReactConnected=true`、`staticBoundaryOnly=false`,冲突入口 `文件管理/知识库/时光机/智能体/协作任务/团队状态` 不再出现在嵌入态正文。截图:`tmp/7-68-runtime/page-ai-openhub-browser.png`;结果 JSON:`tmp/7-68-runtime/page-ai-openhub-browser-result.json`。
|
|||
|
|
- 2026-06-26 send/history smoke `node scripts/task774-openhub-mnote-send-and-file-edit-e2e.js`:通过。MNote SQLite 测试账号登录后,经 MNote proxy 调 OpenHub `/api/models` 返回 66 个真实 opencode 模型,选用 `opencodego/deepseek-v4-flash` 发送真实 stream,OpenHub SQLite 可读取同一 session 的 user/assistant message。结果 JSON:`tmp/7-68-runtime/openhub-send-smoke-result.json`。
|
|||
|
|
- 2026-06-26 changed files bridge smoke `node scripts/task776-openhub-changed-files-bridge-smoke.js`:通过。OpenHub MNote host mode `/api/sessions/{session_id}/diff` 从 opencode tool event metadata 提取真实 changed file path,并返回 `diffAvailable=false` 与限制说明,不伪造 diff content;结果命中 `knowledge-rag-fixtures-7-68/task774-openhub-file-edit-1782409309451.md`。OpenHub 前端 `DiffViewer` / `SmartQueryPage` 通过 `postMNoteOpenFile` 发送 `mnote:open-file`,MNote host 监听后复用现有 document pane open-file bridge。
|
|||
|
|
- 2026-06-26 `BASE_URL=http://127.0.0.1:3021 node scripts/task786-openhub-history-refresh-browser-smoke.js`:通过。真实浏览器创建 OpenHub session message,刷新后 history drawer 可见 marker,点击 session 后当前 message area 可见同一 marker;OpenHub API message/history 同步验证通过。该轮 stream 返回“所有模型均不可用” error event,但 user message/session/history 持久化与 UI 恢复已验收;真实 AI reply 由 `task774` 覆盖。截图:`tmp/task786-openhub-history-refresh-browser-smoke/openhub-history-refresh.png`。
|
|||
|
|
|
|||
|
|
## 7. P1 OpenHub 原生 opencode 链路
|
|||
|
|
|
|||
|
|
- [x] 保留 OpenHub FastAPI prompt/event/diff client,不在 MNote 重写 event parser。
|
|||
|
|
- [x] 确认 OpenHub prompt 请求携带 `directory = MNote rootUri`。
|
|||
|
|
- [x] 确认 OpenHub 能监听 opencode `/global/event` 并渲染 assistant/tool part。
|
|||
|
|
- [x] 确认 OpenHub 能读取 changed files/diff,并将 path 暴露给 MNote bridge。
|
|||
|
|
- [x] MNote 只存 artifact index:`openhub_session_id + kind + provider_id + path/citation payload`,不复制消息全文。
|
|||
|
|
- [x] 当前打开文档被 opencode/OpenHub changed-file bridge 标记后,MNote 走 watcher 或 `refreshPrimaryDocument()` 刷新。
|
|||
|
|
- [~] smoke:让 OpenHub AI 修改 rootUri 内测试 Markdown,MNote document pane 可见变更,且没有 OpenHub Git snapshot commit。当前已覆盖真实 opencode 文件修改 + 模拟 OpenHub changed-file bridge 刷新;单条端到端 AI 修改“当前已打开文档”仍可后续补强。
|
|||
|
|
|
|||
|
|
P1 opencode 链路记录:
|
|||
|
|
|
|||
|
|
- MNote 当前只做 host/status/bootstrap/proxy 边界,没有重写 OpenHub prompt/event parser。
|
|||
|
|
- OpenHub 后端 `query.py` 已在 MNote host mode 下使用 `resolve_user_workspace(current_user)`,创建 session 与 stream prompt 均把 `directory` 指向 MNote rootUri 解析出的 workspace path。
|
|||
|
|
- OpenHub 后端 `query.py` 已补 MNote host mode `/api/models`:不再返回空模型,而是调用真实 opencode `/config/providers`,展开 provider/model 并按 opencode `default` 输出 `default/defaultBuild/defaultPlan`;opencode 不可达时返回明确 empty + error,不伪造 mock model。
|
|||
|
|
- 2026-06-26 主控复核:`curl -H X-MNote-* http://127.0.0.1:18080/api/models` 返回 `success=true`、`modelCount=66`、`source=opencode_config_providers`、默认 `openai/gpt-5.3-chat-latest`;`python -m py_compile` 覆盖 `query.py/auth.py/mnote_scope.py` 通过。
|
|||
|
|
- 2026-06-26 `node scripts/task774-openhub-mnote-send-and-file-edit-e2e.js`:通过。经 MNote proxy 发送真实 OpenHub stream,事件包含 `session/step-start/text/reasoning/step-finish/message_complete/session_idle`,OpenHub SQLite `/api/sessions/{id}/messages` 可读 user/assistant 两条消息。
|
|||
|
|
- 2026-06-26 `MNOTE_OPENHUB_FILE_EDIT=1 node scripts/task774-openhub-mnote-send-and-file-edit-e2e.js`:通过。opencode 在 MNote rootUri 内把 `knowledge-rag-fixtures-7-68/task774-openhub-file-edit-1782409309451.md` 修改为 `status: MNOTE_OPENHUB_FILE_EDIT_OK`,stream 事件包含 `tool`,workspace `.git` 在前后均不存在,未创建 OpenHub Git snapshot。当前 document pane 刷新由后续 `task779` 覆盖。
|
|||
|
|
- 2026-06-26 `node scripts/task776-openhub-changed-files-bridge-smoke.js`:通过。MNote proxy fresh bootstrap 后访问 OpenHub `/api/sessions/ses_1002052f0ffeOpebUFbGq4EC76/diff` 返回 `source=opencode_tool_events`、`diffAvailable=false`,changed path 命中上面的真实 file-edit fixture;OpenHub Git snapshot 写链仍禁用,因此只暴露真实 changed path,不生成或伪造行级 diff。当前 document pane 刷新由后续 `task779` 覆盖。
|
|||
|
|
- 2026-06-26 `node scripts/task779-openhub-file-edit-document-pane-refresh-smoke.js`:通过。浏览器打开 local-first 测试 Markdown 后,脚本在 rootUri 内模拟 OpenHub/opencode 改写磁盘文件,再触发 MNote OpenHub changed-file bridge;MNote 侧复用 `mnote:open-file` / local-folder event bus synthetic watch batch / `refreshPrimaryDocument()` / `openPrimaryDocument()`,primary document pane 原地显示新内容,并写入 `data-mnote-page-ai-openhub-document-pane-refresh` 诊断 marker。该 smoke 不新增应用轮询。
|
|||
|
|
- 2026-06-26 MNote 侧新增 `/api/page-ai/openhub/artifact-index` GET/POST 最小边界:写入 `schema=mnote.page_ai_openhub_artifact_index_record.v1` 的轻量索引,只接受 `openhub_session_id/openhubSessionId + kind + provider_id/providerId + path + citation_payload/citationPayload` 等 locator 字段;默认持久化到 rootUri 下 `.mnote/page-ai-openhub-artifact-index.json`,也可由 `MNOTE_OPENHUB_ARTIFACT_INDEX_PATH` 指定。该实现明确 `messageFulltextCopied=false`,并拒绝 `message/messages/content/text/transcript/conversationMessages/assistantMessage/userMessage` 等 OpenHub user/assistant message 全文字段;不是复制 OpenHub SQLite message 表。
|
|||
|
|
- 2026-06-26 `node --check scripts/task778-openhub-artifact-index-static-smoke.js` 与 `node scripts/task778-openhub-artifact-index-static-smoke.js`:通过。静态 smoke 断言 artifact index route、轻量字段、全文字段拒绝、最小文件持久化和本 checklist 记录。
|
|||
|
|
- 2026-06-26 主控 runtime 复核:登录 MNote 测试账号后 POST `/api/page-ai/openhub/artifact-index` 写入 `kind=changed_file`、`providerId=opencode-tool-event-1`、`path=knowledge-rag-fixtures-7-68/task774-openhub-file-edit-1782409309451.md`,GET 同 session 返回 1 条记录,`storage.messageFulltextCopied=false`;携带 `message` 全文字段的 POST 返回 `page_ai_openhub_artifact_index_forbidden_fulltext_field`。
|
|||
|
|
- 2026-06-26 OpenHub 嵌入态已接 MNote artifact index:`mnoteEmbed.js` 从 `mnoteScope` 解出 `rootUri/workspaceId/pageResourceId`,`SmartQueryPage.jsx` 在 changed files diff metadata 加载后 POST `kind=changed_file` 轻量记录,并在 WeKnora citation/tool output 出现时 POST `kind=citation` 轻量记录;请求字段限定为 `openhubSessionId/kind/providerId/path/citationPayload/rootUri/workspaceId/pageResourceId`,citationPayload 递归去除 `message/messages/content/text/transcript/quote/displayQuote/matched_content` 等全文或证据正文键,不发送 OpenHub message/content/text 全文字段。
|
|||
|
|
- 2026-06-26 `node --check scripts/task780-openhub-artifact-index-runtime-smoke.js` 与 `node scripts/task780-openhub-artifact-index-runtime-smoke.js`:通过。smoke 验证 OpenHub 前端静态边界、runtime POST URL/request body 形状、`mnoteScope` 上下文字段、changed_file / citation 轻量 artifact index 记录,以及请求体不含全文字段。
|
|||
|
|
|
|||
|
|
## 8. P1 WeKnora 知识库页面替换
|
|||
|
|
|
|||
|
|
- [x] 建立 MNote `mnote_knowledge_bases` 模型:user/workspace/rootUri/name/provider/provider_kb_id/default_tool_enabled。
|
|||
|
|
- [x] 迁移/扩展 `mnote_knowledge_sources`:兼容旧 `lightRag*` 字段,新增 provider-neutral 字段。
|
|||
|
|
- [x] 知识库列表页复用 WeKnora KB list 体验:名称、描述、文档数、chunk 数、processing 状态、更新时间。
|
|||
|
|
- [x] 知识库详情页复用 WeKnora detail 体验:source 列表、状态、reparse/delete、搜索入口。
|
|||
|
|
- [x] source 添加入口使用 MNote FileTree/resource picker,不使用 WeKnora 独立文件真相。
|
|||
|
|
- [x] 入库前 MNote 校验 allowed roots;文件/文件夹/page resource 转成 WeKnora file/manual/url ingest。
|
|||
|
|
- [x] processing timeline 显示 WeKnora `pending/processing/completed/failed`,并同步到 registry 与 FileTree 灯号。
|
|||
|
|
- [x] 删除 source 只删除 provider index/registry 映射,不删除本地文件。
|
|||
|
|
- [x] browser smoke:创建 KB -> 添加本地文件夹 -> 看到 indexing -> 完成后可搜索。
|
|||
|
|
|
|||
|
|
P1 WeKnora 知识库模型记录:
|
|||
|
|
|
|||
|
|
- 2026-06-26 新增 MNote 后端 `mnote_knowledge_bases` runtime registry:`schema=mnote.knowledge_bases.registry.v1`,持久化到 workspace root 下 `.mnote/index/mnote-knowledge-bases.json`,字段包含 `userId/workspaceId/rootUri/name/provider/providerKbId/defaultToolEnabled/sourceCount/chunkCount/status`;`status` 与 `ingest` 会在有 `rootUri` 时返回 `knowledgeBases`。
|
|||
|
|
- `mnote_knowledge_sources` 边界通过现有 `.mnote/index/lightrag-source-registry.json` 兼容落地:新增 provider-neutral 字段 `provider/providerStatus/providerSourceId/providerKnowledgeId/providerKnowledgeBaseId`,同时保留旧 `lightRagDocId/lightRagStatus/lightRagFilePath` 兼容字段;读写 registry 时会为旧记录补齐 provider-neutral 字段,不删除旧 registry。
|
|||
|
|
- WeKnora ingest 现在写入 source registry 的 provider-neutral 映射,并同步 `mnote_knowledge_bases.sourceCount`;search/open-reference 继续复用 provider ids 与旧 LightRAG/source registry 兼容映射,不破坏已完成 ingest/search/open-reference。
|
|||
|
|
- 2026-06-26 `node --check scripts/task781-knowledge-bases-registry-smoke.js`:通过。
|
|||
|
|
- 2026-06-26 `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3021 node scripts/task781-knowledge-bases-registry-smoke.js`:通过。验证 status 可读 `mnote_knowledge_bases`、ingest 写 provider-neutral source 字段、search 复用同一 WeKnora KB/source 映射;结果文件 `tmp/task781-knowledge-bases-registry-smoke/result.json`。同一脚本曾因 WeKnora 异步索引窗口在 240s 内未返回新 source 而失败一次,随后重跑通过,说明 search readiness 仍有 provider 异步延迟风险。
|
|||
|
|
- 2026-06-26 `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3021 node scripts/task785-weknora-create-kb-folder-ingest-search-smoke.js`:通过。真实 API 创建 WeKnora KB `df7bd813-fef2-40f4-b08d-b47e03a58cea`,ingest 本地文件夹下 2 个 Markdown source,scoped search 命中同一 KB/source 映射;结果文件 `tmp/task785-weknora-create-kb-folder-ingest-search-smoke/result.json`。
|
|||
|
|
- 2026-06-26 `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3022 node scripts/task788-weknora-kb-folder-browser-flow-smoke.js`:通过。真实浏览器 UI 创建 WeKnora KB `dc5e35f6-4d0f-4289-ae79-de8f4dac8441`,UI 添加本地文件夹 source,source registry 映射 2 个 source,UI 指定新 KB 检索并展示 source result,API search 复核命中同一 KB/source;`uiCreatesKb=true`、`uiAddsFolder=true`、`browserVerifiesSearch=true`、`apiVerifiesSearch=true`。截图:`tmp/task788-weknora-kb-folder-browser-flow-smoke/weknora-kb-folder-browser-flow.png`。
|
|||
|
|
- 2026-06-26 修复 WeKnora KB 创建 payload:新增 `embedding_model_id`,默认 `builtin-mnote-embedding`,可由 `MNOTE_WEKNORA_EMBEDDING_MODEL_ID` / `WEKNORA_EMBEDDING_MODEL_ID` 覆盖;否则新 KB 会长期 processing 且 search 无结果。
|
|||
|
|
- 2026-06-26 修复 scoped search:`sourcePaths` 从 registry 推导 `knowledge_ids`,并在 WeKnora 返回后按 source scope 二次过滤,避免同 KB 下其他旧文件污染指定 source 检索。
|
|||
|
|
|
|||
|
|
## 9. P1 WeKnora 检索替换 LightRAG
|
|||
|
|
|
|||
|
|
- [~] 在 `rust/crates/mnote-web/src/routes/knowledge_rag.rs` 或拆分模块中抽出 `KnowledgeProvider` boundary。
|
|||
|
|
- [x] 新增 `weknora` provider,旧 LightRAG 标为 `lightrag_legacy` 并默认隐藏。
|
|||
|
|
- [x] `/api/knowledge-rag/status` 改为 WeKnora health + KB/source registry 状态。
|
|||
|
|
- [x] `/api/knowledge-rag/ingest` 改为 WeKnora ingest,写 provider KB / knowledge / source hash。
|
|||
|
|
- [x] `/api/knowledge-rag/search` 调 `/api/v1/knowledge-search`;单 KB 调试可走 hybrid-search。
|
|||
|
|
- [x] `/api/knowledge-rag/query` 第一阶段用 search results + citations 生成 answer envelope,不启用 WeKnora chat session。
|
|||
|
|
- [x] `/api/knowledge-rag/section-context` 改为 WeKnora chunk/list/by-id + MNote locator,不读 LightRAG sidecar。
|
|||
|
|
- [~] `/api/knowledge-rag/open-reference` 仅接受 provider ids / open-reference token,回查 registry 后生成 MNote locator。
|
|||
|
|
- [x] 映射保留 `content/matched_content/match_type/metadata/chunk_metadata/image_info/parent_chunk_id/sub_chunk_id`。
|
|||
|
|
- [x] UI 不把 score 显示为百分比相似度;只显示排序或弱化分值。
|
|||
|
|
- [x] 单测:SearchResult -> MNote result/citation/open-reference;缺 registry 映射时降级且不伪造路径。
|
|||
|
|
- [x] smoke:WeKnora ingest 本地 md -> MNote search 返回 provider=`weknora` -> open-reference 打开 MNote 文档。
|
|||
|
|
|
|||
|
|
P1 WeKnora 检索记录:
|
|||
|
|
|
|||
|
|
- `knowledge_rag.rs` 默认 provider 为 `weknora`,`MNOTE_KNOWLEDGE_PROVIDER=lightrag|lightrag_legacy` 才进入 legacy。
|
|||
|
|
- `/api/knowledge-rag/status` 返回 `providerConfig.active/default/legacyFallback/weknora/lightrag`、WeKnora health、legacyHealth、registry。
|
|||
|
|
- `/api/knowledge-rag/ingest` 默认 WeKnora provider 时通过 `POST /api/v1/knowledge-bases/:id/knowledge/file` multipart 上传本地授权文件,写回 `providerKnowledgeBaseId/providerKnowledgeId/sourceHash/providerStatus`;缺 KB id 时只登记 `pending_provider_ingest_missing_kb`,不碰 LightRAG staging。
|
|||
|
|
- `/api/knowledge-rag/search` 与 `/api/knowledge-rag/query` 调 WeKnora `/knowledge-search`,请求包含 `query + knowledge_base_ids`,按需 `knowledge_ids/match_count`;API key 只在后端注入。
|
|||
|
|
- WeKnora chunk mapper 保留 provider ids、raw chunk、content/matched_content、metadata/chunk_metadata/image_info/parent/sub chunks;未命中 registry 时 `filePath=null`、`locatorDegraded=true`,不把 `knowledge_filename` 伪装成本地路径。
|
|||
|
|
- `sidebar-page-settings-runtime.js` 已收口 WeKnora 默认 provider、LightRAG legacy fallback、source registry、processing/citation/open-reference 文案;score 只显示 provider 排序分,不再表达为相似度百分比;删除 source 明确不删除本地文件。
|
|||
|
|
- `node scripts/task772-weknora-ingest-search-open-reference-e2e.js` 已真实通过:在 allowed root 下创建 `knowledge-rag-fixtures-7-68/task772-weknora-e2e-1782405331456.md`,MNote `/api/knowledge-rag/ingest` 返回 provider=`weknora`、`mappingStatus=provider_mapped`、`providerKnowledgeBaseId=90cc060c-3a16-4146-9d2b-fef8eb2c2d90`、`providerKnowledgeId=78b2c703-6d6a-4fa6-a881-f5ff6cfb769d`;`/api/knowledge-rag/search` 返回 4 条 weknora reference 并保留 provider ids;`/api/knowledge-rag/open-reference` 返回 `filePath=null`、`sourceRootRelativePath` 为 registry 映射路径、`openAction.params.path` 为本地 source path,未把 provider filename 伪造成本地路径。
|
|||
|
|
- `/api/knowledge-rag/section-context` 已改为 WeKnora provider chunk 优先:有 `providerChunkId` 时调 `/chunks/by-id/:id`,否则按 `providerKnowledgeId` 调 `/chunks/:knowledge_id`;返回 `providerChunkFetch.attempted/ok/source/fetchedChunks`、`providerChunk` metadata 与 MNote locator,且 `sidecarRead=false`。为适配 WeKnora 异步 parse 状态,section-context 对 WeKnora provider 已允许 `pending/submitted/processing/processed/completed/provider_mapped` 的 registry 映射进入 provider chunk fetch;LightRAG legacy sidecar 仍要求 `processed`。
|
|||
|
|
- 2026-06-26 `node scripts/task777-weknora-section-context-smoke.js`:通过。基于 task772 真实 ingest 结果,by-id 命中 `providerChunkId=78f026a5-7bb1-4b82-92f7-ee4f560f5640`,list 命中同一 `providerKnowledgeId=ec461ca5-37f7-471c-b4f7-4ced7be09a01`,两路均返回 `providerChunkFetch.ok=true`、`sidecarRead=false`、文本含 task772 marker。
|
|||
|
|
- 2026-06-26 `cargo test -p mnote-web knowledge_rag --lib -- --test-threads=1`:59 passed;`node scripts/task544-weknora-provider-bridge-static-smoke.js`:通过。
|
|||
|
|
|
|||
|
|
## 10. P1 WeKnora MCP/CLI Tool Bridge
|
|||
|
|
|
|||
|
|
- [x] 定义 MNote 对 OpenHub/opencode 暴露的工具名:`mnote.weknora.search`、`mnote.weknora.open_reference`、`mnote.weknora.list_sources`、`mnote.weknora.get_source_status`。
|
|||
|
|
- [x] 底层第一阶段优先用 Go CLI `weknora mcp serve` 或 MNote HTTP facade 包装同等只读能力。
|
|||
|
|
- [x] tool 调用前注入 KB/source allowlist;禁止直接传未授权 `knowledge_base_id`。
|
|||
|
|
- [x] tool result 返回 provider ids、quote/matched_content、chunk metadata、MNote open-reference token。
|
|||
|
|
- [x] 不把 WeKnora API key 暴露给浏览器或 OpenHub 前端 localStorage。
|
|||
|
|
- [x] Python `mcp-server` 的 create/delete/chunk mutation 不默认暴露;如未来开启写能力,必须经过 MNote 权限审批。
|
|||
|
|
- [~] smoke:OpenHub AI 通过 WeKnora tool 查询 KB,回答中出现可点击 citation,点击后由 MNote 打开本地页面。当前完成 OpenHub host mode 自动 WeKnora search/tool event + clickable citation bridge;仍不是 opencode 原生 MCP 自动选 tool 的完整闭环。
|
|||
|
|
|
|||
|
|
P1 WeKnora tool 记录:
|
|||
|
|
|
|||
|
|
- Hermes tool manifest 与 dispatch 已新增 `mnote.weknora.search/open_reference/list_sources/get_source_status`。
|
|||
|
|
- Tool wrapper 要求 `rootUri` 以及 `scope/allowlist/allowedRoots/aiAccessScope/sourcePaths` 之一,否则返回 `mnote_weknora_scope_required`。
|
|||
|
|
- 当前通过 MNote HTTP facade 调用 WeKnora;没有把 WeKnora API key 暴露到浏览器/localStorage,也没有默认开放 Python mcp-server 写能力。
|
|||
|
|
- 2026-06-26 task782 可写 worker:OpenHub backend 新增 MNote host mode `/api/mnote/tools/call` 只读 facade,通过 MNote 反代受控 headers 与 server-side `X-MNote-Session-Cookie` 调 `/api/hermes/tools/mnote/call`,支持 `mnote.weknora.search/open_reference/list_sources/get_source_status`;OpenHub 不接触 WeKnora API key,也不把 MNote cookie 暴露给前端 localStorage。`stream.py` 在 MNote host mode 下对知识库/资料库/WeKnora/citation/source 类问题先调用 MNote WeKnora search,把结构化 tool result 注入 OpenHub/opencode prompt,并向 OpenHub 前端推送 `mnote.weknora.search` tool event。
|
|||
|
|
- 2026-06-26 task782 可写 worker:OpenHub 前端 `AssistantMessage` 从 WeKnora tool output 的 `citations/uiCitations/references` 渲染 `data-mnote-openhub-citation` 可点击 citation,点击经 `postMNoteOpenReference` 发 `mnote:open-reference`;MNote Page AI host 已接受 `openhub-citation` 并复用 document pane open-file bridge 打开本地页面。新增 `scripts/task782-openhub-weknora-tool-citation-bridge-smoke.js` 覆盖后端 facade、scope/cookie/API key 边界、stream auto tool bridge、citation button 与 postMessage runtime。主控复核:OpenHub `/openapi.json` 已暴露 `/api/mnote/tools/call`,`node scripts/task782-openhub-weknora-tool-citation-bridge-smoke.js` 通过;边界仍标 partial,不宣称 opencode 原生 MCP 自动选 tool 完成。
|
|||
|
|
|
|||
|
|
## 11. P1 验收与证据
|
|||
|
|
|
|||
|
|
- [~] `npm run dev:hot` 或目标启动命令能启动/检查 MNote、OpenHub FastAPI、OpenHub Redis、opencode、WeKnora API、WeKnora CLI/MCP。OpenHub/MNote/opencode/WeKnora API、Redis auth、WeKnora CLI profile/doctor 与 MCP 命令面已探通;stdio MCP handshake 和单命令 dev-hot orchestration 仍作为后续收口。
|
|||
|
|
- [x] 用 `mnote.e2e@example.com` 登录 MNote;Page AI 不出现 OpenHub/WeKnora 登录。
|
|||
|
|
- [x] Page AI 可发送消息,OpenHub SQLite session/message/history 持久化,刷新恢复。
|
|||
|
|
- [x] AI 修改当前 rootUri 内 Markdown,MNote 当前页面刷新后可见。当前证据由 `task774` 真实 opencode 文件修改 + `task779` 浏览器模拟 OpenHub changed-file bridge 刷新组成。
|
|||
|
|
- [x] OpenHub Login/Admin/FileManager/KnowledgeManager/GitTimeMachine 非 AI 入口不接管 MNote。
|
|||
|
|
- [x] WeKnora 知识库页完成 KB 创建、source 添加、状态显示、检索、citation 回跳。
|
|||
|
|
- [x] 旧 LightRAG 默认入口不再出现在主 UI/smoke;legacy fallback 显式标识。
|
|||
|
|
- [x] 保存 smoke 输出、关键截图、失败分层日志。
|
|||
|
|
|
|||
|
|
P1 当前验证证据:
|
|||
|
|
|
|||
|
|
- `cargo check -p mnote-web`:通过。
|
|||
|
|
- `cargo test -p mnote-web knowledge_rag --lib -- --test-threads=1`:59 passed。
|
|||
|
|
- `node scripts/task544-weknora-provider-bridge-static-smoke.js`:通过。
|
|||
|
|
- `node scripts/task768-page-ai-openhub-host-static-smoke.js`:通过。
|
|||
|
|
- `node scripts/task769-weknora-knowledge-settings-ui-static-smoke.js`:通过。
|
|||
|
|
- `node scripts/task770-openhub-git-snapshot-restore-guard-static-smoke.js`:通过。
|
|||
|
|
- `node --check scripts/task773-page-ai-openhub-browser-smoke.js`:通过。
|
|||
|
|
- 早期 `node scripts/task773-page-ai-openhub-browser-smoke.js` 只验证到静态 shell,已被后续 React bundle 接入结果覆盖;保留为阶段证据,不作为当前最终状态。
|
|||
|
|
- `npm run build`(`/tmp/mnote-openhub-research/OpenHub/smart-query-frontend`):通过;Vite 仍提示主 chunk 超过 500 kB,这是既有体积 warning。
|
|||
|
|
- OpenHub React dist 已复制到 `/tmp/mnote-openhub-research/OpenHub/smart-query-backend/static/`,MNote `/page-ai/openhub/ai` 可加载 OpenHub SPA index/assets。
|
|||
|
|
- `node scripts/task773-page-ai-openhub-browser-smoke.js`:通过;测试账号真实登录,Page AI OpenHub host drawer/iframe 可见,OpenHub React UI marker 出现,未出现 OpenHub/WeKnora 登录页;`openhubReactConnected=true`、`staticBoundaryOnly=false`,嵌入态未显示 FileManager/KnowledgeManager/GitTimeMachine 等冲突入口。
|
|||
|
|
- `curl -H X-MNote-* http://127.0.0.1:18080/api/models`:通过;MNote host mode 返回 66 个真实 opencode 模型,`source=opencode_config_providers`,未使用 mock。
|
|||
|
|
- `node scripts/task774-openhub-mnote-send-and-file-edit-e2e.js`:通过;MNote proxy -> OpenHub `/api/models` -> `/api/query/stream` -> OpenHub SQLite `/api/sessions/{id}/messages` 全链路通过,选用 `opencodego/deepseek-v4-flash`。
|
|||
|
|
- `MNOTE_OPENHUB_FILE_EDIT=1 node scripts/task774-openhub-mnote-send-and-file-edit-e2e.js`:通过;opencode 修改 MNote rootUri 内测试 Markdown,最终内容含 `status: MNOTE_OPENHUB_FILE_EDIT_OK`,`.git` 未被 OpenHub 创建。
|
|||
|
|
- `node --check scripts/task772-weknora-ingest-search-open-reference-e2e.js`:通过。
|
|||
|
|
- `node scripts/task772-weknora-ingest-search-open-reference-e2e.js`:通过;当前 shell 未直接暴露 WeKnora env,脚本先输出 `local_weknora_env_not_visible` warning,但继续以 MNote 3000 的 status 和真实 API 调用为准,最终 ingest/search/open-reference 全链路通过。最新主控重跑创建 `knowledge-rag-fixtures-7-68/task772-weknora-e2e-1782408870763.md`,映射到 WeKnora KB `90cc060c-3a16-4146-9d2b-fef8eb2c2d90` 与 knowledge `c6789541-7ad5-47a4-b621-5ef1e2762688`。
|
|||
|
|
- `python -m py_compile /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/api/query.py /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/api/session.py /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/core/auth.py /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/core/mnote_scope.py /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/services/git_snapshot.py /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/services/stream.py /tmp/mnote-openhub-research/OpenHub/smart-query-backend/app/services/task_executor.py`:通过。
|
|||
|
|
- `MNOTE_OPENHUB_DISABLE_GIT_SNAPSHOT_RESTORE=1 PYTHONPATH=/tmp/mnote-openhub-research/OpenHub/smart-query-backend python ...`:通过,确认底层 git 写命令 guard 生效。
|
|||
|
|
- `node --test scripts/desktop-hot.test.js`:6 passed。
|
|||
|
|
- `git diff --check`:通过。
|
|||
|
|
- `codegraph sync .`:完成,报告 synced 38 changed files。
|
|||
|
|
- `node scripts/task776-openhub-changed-files-bridge-smoke.js`:通过;MNote proxy -> OpenHub changed files endpoint 返回真实 opencode tool-event path,且 OpenHub 前端到 MNote document pane open-file bridge 静态边界通过。
|
|||
|
|
- `node scripts/task779-openhub-file-edit-document-pane-refresh-smoke.js`:通过;打开测试 Markdown 后改写 rootUri 内文件并触发 OpenHub changed-file bridge,document pane 可见刷新到新正文,诊断显示 `eventBusSource=openhub_changed_file_bridge`。
|
|||
|
|
- `node --check scripts/task780-openhub-artifact-index-runtime-smoke.js`:通过。
|
|||
|
|
- `node scripts/task780-openhub-artifact-index-runtime-smoke.js`:通过;验证 OpenHub embed changed_file / citation 轻量 artifact index POST 形状,且不含 message/content/text 等全文字段。
|
|||
|
|
- 外部服务真实探针:`/api/page-ai/openhub/status` 在配置 WeKnora API key 后返回 `status=ready`,OpenHub FastAPI `127.0.0.1:18080` ready,opencode `127.0.0.1:4096` ready,WeKnora public `/health` ready,OpenHub `/openapi.json` 暴露 `/api/mnote/tools/call`,Redis `AUTH + PING` 返回 `+OK/+PONG`,WeKnora CLI `profile add + auth login --with-token + doctor --no-cache` 通过,`go run . mcp serve --help` 通过。stdio MCP handshake 未作为最终通过项,因此 dev-hot/CLI/MCP 全链路仍 partial。
|
|||
|
|
- 2026-06-26 task783/task784 UI 增量:`sidebar-page-settings-runtime.js` 在 WeKnora 设置面板增加 KB summary(KB/source/provider docs/processing)、本地文件/文件夹 source picker 边界标记、source row 与 search result 的 `open-source-reference` 控件;`sidebar-tree-runtime.js` 接线该控件到 MNote document pane `openPrimaryDocument`,仍复用 `/api/knowledge-rag/status/ingest/search/delete-source`,未改后端 `knowledge_rag.rs`。`node --check rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js`、`node --check rust/crates/mnote-web/browser/sidebar-tree-runtime.js`、`node --check scripts/task783-weknora-kb-settings-ui-static-smoke.js`、`node --check scripts/task784-weknora-kb-settings-browser-smoke.js`、`node scripts/task783-weknora-kb-settings-ui-static-smoke.js`、`node scripts/task769-weknora-knowledge-settings-ui-static-smoke.js` 均通过。真实 browser smoke 使用临时 3018 MNote 实例与已有 task772 WeKnora 入库结果:`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3018 node scripts/task784-weknora-kb-settings-browser-smoke.js` 通过,截图 `tmp/task784-weknora-kb-settings-browser-smoke/weknora-kb-settings.png`;验证 KB summary 包含 KB `90cc060c-3a16-4146-9d2b-fef8eb2c2d90`,source row/search result/open-reference/delete-preserve-local-file 控件可见。仍 partial:未创建新的 KB;未真实点击 open-reference 后断言文档 pane 跳转;未完成 checklist 第 8 节“创建 KB -> 添加本地文件夹 -> indexing -> 完成后搜索”的完整链路。
|
|||
|
|
- 2026-06-26 task788 UI 完整链路增量:`sidebar-page-settings-runtime.js` 新增 WeKnora KB select、创建 KB 控件,ingest/search 带当前选中 `providerKnowledgeBaseId`;`sidebar-tree-runtime.js` 接线 create-kb 与 KB select change。主控复核 `node --check rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js`、`node --check rust/crates/mnote-web/browser/sidebar-tree-runtime.js`、`node --check scripts/task788-weknora-kb-folder-browser-flow-smoke.js` 通过;临时当前构建 MNote `3022` 上 `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3022 node scripts/task788-weknora-kb-folder-browser-flow-smoke.js` 通过,UI 创建 KB `dc5e35f6-4d0f-4289-ae79-de8f4dac8441`、UI 添加文件夹 source、UI 指定新 KB 检索、API search 复核均通过。
|
|||
|
|
- 2026-06-26 用户纠正后知识库页面替换增量:原“资料库问答/资料源管理”小面板不符合 7-68,已改为 WeKnora 风格“知识库列表 + 知识库详情/文档管理”页面。`sidebar-page-settings-runtime.js` 补入 KB 面包屑、Documents/Wiki/Graph/Search 页签、source/tag 侧栏、文档搜索/筛选、添加文档/文件夹、列表/网格切换、processing/status 与 open-reference 控件;`main.css` 补齐对应布局;新增 `scripts/task790-weknora-kb-page-experience-static-smoke.js` 与 `scripts/task79x-weknora-kb-page-browser-smoke.js`。
|
|||
|
|
- 2026-06-26 纠正后复核:`node --check rust/crates/mnote-web/browser/sidebar-page-settings-runtime.js`、`node --check scripts/task790-weknora-kb-page-experience-static-smoke.js`、`node --check scripts/task79x-weknora-kb-page-browser-smoke.js`、`node scripts/task783-weknora-kb-settings-ui-static-smoke.js`、`node scripts/task789-weknora-kb-page-ui-reference-static-smoke.js`、`node scripts/task790-weknora-kb-page-experience-static-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3022 node scripts/task79x-weknora-kb-page-browser-smoke.js` 均通过。浏览器结果确认 `openedReplacementPanel=true`、`notOldSimpleSettingsPanel=true`、`hasKnowledgeBaseListCards=true`、`hasDetailStructure=true`、`hasDocumentTabs=true`、`hasSearchAndFilter=true`;截图 `tmp/task79x-weknora-kb-page-browser-smoke/weknora-kb-page-browser-smoke.png`。
|
|||
|
|
- 2026-06-26 Page AI 截图复核:`MNOTE_UI_BASE_URL=http://127.0.0.1:3022 node scripts/task773-page-ai-openhub-browser-smoke.js` 通过,截图 `tmp/7-68-runtime/page-ai-openhub-browser.png`;OpenHub React UI marker 可见,`openhubReactConnected=true`、`staticBoundaryOnly=false`,未出现 OpenHub/WeKnora 登录页或 FileManager/KnowledgeManager/GitTimeMachine 冲突入口。
|
|||
|
|
- 2026-06-26 `BASE_URL=http://127.0.0.1:3021 node scripts/task786-openhub-history-refresh-browser-smoke.js`:通过;OpenHub session/message/history 刷新恢复已由浏览器和 API 双重验证,结果文件 `tmp/task786-openhub-history-refresh-browser-smoke/result.json`。
|
|||
|
|
- 2026-06-26 `MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3021 node scripts/task787-weknora-default-lightrag-legacy-smoke.js`:通过;静态扫描 33 个主 UI/smoke 文件,`violations=[]`,status API 的默认/active provider 为 WeKnora,LightRAG 仅作为显式 legacy fallback。
|
|||
|
|
|
|||
|
|
## 12. P2 后续优化
|
|||
|
|
|
|||
|
|
- [ ] 若需要开放 OpenHub Admin/tool/model 管理,先做 MNote role -> OpenHub admin scope 映射设计。
|
|||
|
|
- [ ] 若需要完整 MCP 管理 UI,再单独设计 OpenHub/MNote MCP 管理面,不混入首版嵌入。
|
|||
|
|
- [ ] 若需要 WeKnora chat/agent-chat,作为 OpenHub tool 内部 provider call,不变更 Page AI session 真相。
|
|||
|
|
- [ ] 若需要版本恢复,走 MNote DocumentBuffer/watcher/显式用户确认策略,不恢复 OpenHub GitTimeMachine 写链。
|