Files
mnote/design/old/07-ai/process/7-64-recycle-codexmobile-embed-page-ai-v1.md
T
2026-06-25 21:08:17 +08:00

13 KiB
Raw Blame History

7-64 [recycle] CodexMobile 嵌入 Page AI 方案 v1

创建时间:2026-06-23

当前状态:RECYCLE

Owner07-ai / Page AI / CodexMobile embed

上位依据:

  • design/07-ai/done/7-62-page-ai-board-first-full-rewrite-v1.md
  • design/07-ai/process/7-63-page-ai-board-first-productization-v1.md
  • design/07-ai/done/7-38-page-ai-sidebar-runtime-owner-split-v1.md

过时原因:已由 design/07-ai/process/7-65-opencode-webui-embed-page-ai-v1.md 替代;Page AI 新主路径只接入 opencode 官方 runtime + 官方 WebUI。

1. 核心结论

放弃 Board-first 和自研聊天 UI 两条路,改为 fork CodexMobile 开源代码 → 精简 → iframe 嵌入 MNote

MNote Page AI = MNote 原生上下文 pills + CodexMobile 精简版 iframe
CodexMobile   = Vue 3 SPA + Express server → Codex CLI app-server (RPC)

理由:

  • CodexMobilefriuns2/codex-mobileMIT675)已提供成熟的聊天 UI、流式渲染、session 管理、plan/tool 卡片
  • 当前 MNote Page AI runtime4457 行 JS+ Rust bridge~20000 行)维护成本高,且聊天体验不如 CodexMobile
  • CodexMobile 直接对接 Codex CLICodexRelay 已解决 DeepSeek 兼容,不需要 Board 中介
  • 嵌入方案比自研省 90% 代码量,比 Board-first 少一层依赖

2. CodexMobile 现状

2.1 仓库信息

项目
仓库 friuns2/codex-mobile
协议 MIT
星数 675
语言 TypeScript (Vue 3 + Express)
本地版本 v0.1.90 (/home/lix/.local/lib/node_modules/codexapp/)
当前运行 codexapp --no-login --no-tunnel --no-open --port 5900

2.2 架构

浏览器 Vue SPA (hash router)
  ↓ fetch /codex-api/rpc
Express httpServer.ts
  ↓ codexAppServerBridge.ts
Codex CLI app-server (RPC over HTTP)
  ↓
Codex CLI (实际 agent 执行)

2.3 核心模块

模块 文件 作用
RPC 桥接 codexAppServerBridge.ts (~2500行) 代理所有 Codex RPC 调用
API 网关 codexGateway.ts 线程/消息/模型/账户等高层 API
RPC 客户端 codexRpcClient.ts 底层 RPC 调用与错误处理
HTTP 服务 httpServer.ts Express + WebSocket + 静态文件
聊天 UI ThreadConversation.vue 消息气泡、plan 卡片、工具卡片
输入框 ThreadComposer.vue 消息输入、发送、模型选择
侧边栏 SidebarThreadTree.vue 线程列表、搜索、切换
布局 DesktopLayout.vue 整体布局框架

3. 精简方案

3.1 删除清单

删除模块 原因
xterm 终端 (terminalManager.ts, ThreadTerminalPanel.vue) MNote 不是终端
文件浏览 (localBrowseUi.ts) MNote 有 FileTree
Firebase auth MNote 用 SQLite control-plane
Telegram bridge (telegramThreadBridge.ts) 无关
Composio 集成 无关
OpenRouter proxy (openRouterProxy.ts) 无关
Zen proxy (zenProxy.ts) 无关
Custom endpoint proxy (customEndpointProxy.ts) 无关
Free mode (freeMode.ts) 无关
Skills routes/hub (skillsRoutes.ts, SkillsHub.vue, SkillCard.vue) 无关
Review git (reviewGit.ts, ReviewPane.vue) 无关
Automations (AutomationsPanel.vue) 无关
Directory hub (DirectoryHub.vue) 无关
Account menu (AccountMenu.vue) 简化
Rate limit status (RateLimitStatus.vue) 无关
Dictation (useDictation.ts) 无关
GitHub skills sync (useGithubSkillsSync.ts) 无关
API methods panel (ApiMethodsPanel.vue) 调试工具
Pending request panel (ThreadPendingRequestPanel.vue) 简化
Queued messages (QueuedMessages.vue) 简化
Composer dropdowns (runtime/search/skill picker) 简化
Header git branch dropdown 无关

3.2 保留清单

保留模块 作用
codexAppServerBridge.ts 核心 RPC 桥接
codexGateway.ts 高层 API
codexRpcClient.ts RPC 客户端
httpServer.ts Express + WebSocket
authMiddleware.ts 简化为 MNote token 验证
ThreadConversation.vue 聊天气泡
ThreadComposer.vue 输入框
SidebarThreadTree.vue 线程列表
DesktopLayout.vue 布局
ContentHeader.vue 顶部信息
appServerDtos.ts 类型定义
codexErrors.ts 错误处理
WebSocket 流式事件 实时消息

3.3 新增:postMessage Bridge

MNote 原生层与 CodexMobile iframe 之间的通信协议:

// MNote → CodexMobile
interface MnoteContextMessage {
  type: 'mnote:context';
  payload: {
    workspaceId: string;
    documentId: string;
    pageTitle: string;
    rootUri: string;           // file:///...
    primaryTarget: {
      absolutePath: string;
      relativePath: string;
    };
    selection?: {
      text: string;
    };
    allowedRoots: Array<{
      rootUri: string;
      permission: 'read' | 'write';
    }>;
    knowledgeContext?: string;  // LightRAG 查询结果
  };
}

// CodexMobile → MNote
interface CodexMobileEvent {
  type: 'codex:file-changed' | 'codex:session-update' | 'codex:ready';
  payload: {
    changedFiles?: string[];
    sessionId?: string;
    threadId?: string;
  };
}

4. 集成架构

4.1 整体拓扑

┌──────────────────────────────────────────────────┐
│ MNote Rust SSR (localhost:3000)                   │
│                                                    │
│  ┌─ Page AI Panel ──────────────────────────────┐ │
│  │ ┌─ MNote 原生上下文 pills ──────────────────┐ │ │
│  │ │ [当前页] [选区] [知识库] [allowed roots]   │ │ │
│  │ └────────────────────────────────────────────┘ │ │
│  │ ┌─ iframe ───────────────────────────────────┐ │ │
│  │ │ CodexMobile 精简版 SPA                     │ │ │
│  │ │ (Vue 3, hash router, 独立端口 5900)        │ │ │
│  │ │                                             │ │ │
│  │ │ ThreadConversation + ThreadComposer         │ │ │
│  │ └────────────────────────────────────────────┘ │ │
│  │ postMessage ↑↓                                 │ │
│  └────────────────────────────────────────────────┘ │
│                                                    │
│  /codex-mobile/* → reverse proxy → 127.0.0.1:5900 │
└──────────────────────────────────────────────────┘
                          ↓
               CodexMobile Express (5900)
                          ↓
               Codex CLI app-server (RPC)
                          ↓
               Codex CLI + CodexRelay → DeepSeek

4.2 Rust 侧改动

// mnote-web routes/mod.rs 新增
.route("/codex-mobile/{*path}", any(codex_mobile_proxy))

// codex_mobile_proxy: 反向代理到 127.0.0.1:5900
// 仅对已认证 session 放行
// 注入 X-Mnote-Workspace-Id / X-Mnote-Document-Id header

4.3 前端侧改动

// sidebar-page-ai-runtime.js 精简为:
// 1. 渲染上下文 pills(当前页、选区、知识库)
// 2. 创建 iframe 指向 /codex-mobile/
// 3. postMessage 监听与转发
// 4. 文件变更事件 → watcher 刷新编辑器

// 删除:
// - 所有 provider 选择逻辑 (Hermes/Reasonix/Chat-only)
// - 所有 session/message/run 持久化逻辑
// - 所有 Board bridge 调用
// - 所有 workflow/worker 选择器
// 预计从 4457 行精简到 ~300 行

4.4 Rust 侧删除

删除文件:
- routes/page_ai_board.rs (317 行)
- routes/page_ai_workflow.rs (967 行)
- routes/hermes_client.rs 中 Page AI 相关部分

保留:
- hermes_tools/doc.rs 中的 mnote.doc.* tools(非 Page AI 路径仍需要)

5. 上下文注入机制

5.1 注入时机

  1. Page AI 面板打开时:注入当前页路径、workspaceId、documentId
  2. 用户选中文本时:注入 selection
  3. 用户切换页面时:更新 primaryTarget
  4. 用户触发知识库查询时:注入 knowledgeContext

5.2 注入方式

MNote 通过 iframe.contentWindow.postMessage() 发送 mnote:contextCodexMobile 内新增 useMnoteBridge.ts composable 接收并注入到 Codex CLI 的 system prompt 中。

// CodexMobile 侧新增 useMnoteBridge.ts
// 监听 postMessage,将上下文追加到 thread/start 的 system prompt
// ponytail: 最小实现,只做 system prompt 注入,不做 UI 展示

5.3 文件编辑闭环

用户输入 "把当前页的 A 替换为 B"
  → Codex CLI 通过 CodexRelay 执行
  → Codex CLI 直接编辑 primaryTarget.absolutePath
  → 磁盘文件变化
  → CodexMobile 检测文件变更 → postMessage 'codex:file-changed'
  → MNote watcher 检测到文件变化 → 刷新 tiptap 编辑器

6. 实施计划

Phase AFork 与精简(1天)

  • git clone https://github.com/friuns2/codex-mobile/mnt/Data1T/mnote/codex-mobile/
  • 删除 3.1 清单中的所有模块
  • 简化 authMiddleware.ts:接受 MNote session token
  • 新增 useMnoteBridge.tspostMessage 监听
  • 验证 npm run build 通过
  • 验证精简版可独立运行(codexapp --port 5900

Phase BMNote 集成(1天)

  • Rust 新增 /codex-mobile/{*path} 反向代理路由
  • sidebar-page-ai-runtime.js 精简为上下文 pills + iframe + postMessage
  • 删除 page_ai_board.rspage_ai_workflow.rs
  • 上下文 pills 实现(当前页、选区、知识库引用)
  • postMessage bridge 双向通信验证

Phase C:闭环验证(0.5天)

  • smoke:打开 Page AI → 看到 CodexMobile 聊天界面
  • smoke:发送消息 → 流式回复可见
  • smoke:编辑当前页 → 文件变化 → 编辑器刷新
  • smoke:刷新页面 → 会话恢复
  • smoke:上下文 pills 正确显示当前页信息

Phase D:旧代码清理(后续)

  • 归档 sidebar-page-ai-runtime.js 旧代码
  • 归档 hermes_client.rs Page AI 相关代码
  • 更新 ARCHITECTURE.mdCURRENT_ARCHITECTURE.md

7. 验收标准

7.1 聊天体验

  • 用户可在 Page AI 面板中与 Codex 对话
  • 流式回复实时可见
  • 支持 stop / retry / copy
  • 刷新页面后会话历史可恢复
  • plan 卡片和工具调用卡片可见(含 plan 持久化补丁)

7.2 上下文注入

  • 上下文 pills 显示当前页标题和路径
  • 选区内容自动注入
  • Codex 能读取和编辑当前页文件
  • 文件编辑后 MNote 编辑器自动刷新

7.3 代码精简

  • sidebar-page-ai-runtime.js 从 4457 行精简到 <500 行
  • 删除 page_ai_board.rspage_ai_workflow.rs~1300 行)
  • 不再依赖 Agent Board 服务

8. 风险与处理

风险 处理
CodexMobile 上游更新导致 fork 过时 定期 rebase,只保留精简 diff
Codex CLI 不可用 降级提示 "Codex CLI 未运行",不伪装可用
iframe 跨域问题 同源反向代理(/codex-mobile/*),无跨域
postMessage 安全 验证 origin,只接受已知消息类型
plan 卡片刷新消失 已有 codexmobile-plan-persist.js 补丁,合入 fork
npm 升级清空 codexapp 目录 fork 到 MNote 仓库内,不依赖 npm 全局安装

9. 与旧方案的对比

Board-first (7-62/7-63) CodexMobile 嵌入 (本方案)
MNote 代码量 ~4457 JS + ~20000 Rust ~500 JS + ~50 Rust
聊天 UI 成熟度 自研,持续打磨 675 开源验证
依赖服务 Agent Board (必须) Codex CLI (必须)
Agent 选择 通过 Board 间接 直接使用 Codex CLI
Provider 适配 Board 负责 CodexRelay 负责
上下文注入 自研 pills 自研 pills + system prompt
维护负担 Board bridge + 聊天 UI 追上游 + postMessage bridge
差异化 上下文 pills 上下文 pills + 成熟聊天体验

10. 非目标

  • 不把 CodexMobile 的终端、文件浏览、Skills、Review 等功能带入 MNote
  • 不替换 MNote 的 FileTree、编辑器、知识库等核心功能
  • 不要求 CodexMobile 支持 MNote 特有的资源类型(mindmap、OnlyOffice
  • 不实现 CodexMobile 与 MNote auth 的 SSO 统一(短期独立 auth,长期可选)