Files
mnote/design/07-ai/process/7-72-page-ai-pi-ui-completion-plan-v1.md
T

24 KiB
Raw Blame History

7-72 Page AI Pi UI 补全方案 v1

状态:process Owner07-ai / mnote-web / browser runtime 日期:2026-07-05

1. 结论

当前 Pi Lab 已能通过真实 desktop:hot 链路调用 Skill 与 MCP,但 UI 只完成了最基础的聊天和 Markdown 渲染。它还没有达到 Pi 官方 TUI / OpenClaw 类 Web UI 的可用体验基线。

本阶段不应该继续只补零散样式。应按 Pi 事件模型重做一层 PiRunViewModel,把 message_updatetool_execution_*queue_updateabort、extension UI dialog、notification、receipt、artifact 全部归一成浏览器可渲染的运行时间线。

真实验证证据:

  • 清理后 Skill/MCP 配置截图:/tmp/mnote-pi-clean-after-fix-1783222211192/01-admin-ai-skills-after-clean.png
  • 当前 UI 初始状态:/tmp/mnote-pi-ui-gap-audit-1783222292502/01-current-pi-initial.png
  • 当前 UI streaming 状态:/tmp/mnote-pi-ui-gap-audit-1783222292502/03-current-pi-streaming-early.png
  • 当前 UI 回复后状态:/tmp/mnote-pi-ui-gap-audit-1783222292502/04-current-pi-after-reply.png
  • 清理后真实 Skill/MCP 链路:/tmp/mnote-pi-real-after-clean-1783222483/result.json

2. 已清理的问题

重复配置已清理:

  • 删除空 source Skillmnote-browser-smoke-*
  • 删除临时 Skillmnote-pi-skill-proof
  • 删除重复 LightRAG smoke MCPlightrag-smoke-*

清理后有效配置:

  • SkillsChrome BridgeCodeGraphContext7Global SearchMemPalaceSearXNG SearchVPN
  • MCPChrome BridgeCodeGraphContext7MemPalaceSearXNG
  • emptySourceSkills=[]
  • duplicateMcpEndpoints=[]

同时修复了 /api/ai-admin/settings 的删除语义:skillsmcpServers 在 admin 编辑中代表完整目标 registry,不再把旧配置 merge 回来导致删除无效。

3. 对照基线

Pi 官方能力基线:

  • RPC prompt streaming 中必须支持 streamingBehavior: "steer""followUp";不传会在 streaming 中报错。
  • RPC 有独立 steerfollow_upabort 命令。
  • JSON event stream 暴露 queue_updatemessage_updatetool_execution_starttool_execution_updatetool_execution_endcompaction_*
  • TUI 中 Enter 是 steerAlt+Enter 是 follow-upEscape 是 abortAlt+Up 可取回排队消息。
  • TUI Markdown 不是简单 HTML 转换,而是处理 streaming partial fence、thinking block、宽度缓存、主题。
  • extension UI 有 ctx.ui.select()ctx.ui.confirm()ctx.ui.input()ctx.ui.notify(),并支持 AbortSignal 关闭。

OpenClaw / 第三方 Web UI 可参考:

  • openclaw/ui/src/ui/chat/tool-cards.ts:工具卡片默认折叠,展开显示 input/output/raw details/error/sidebar。
  • openclaw/ui/src/ui/chat/grouped-render.ts:消息分组、Markdown sanitation、thinking block、copy-as-markdown。
  • openclaw/ui/src/ui/components/modal-dialog.ts:标准 modal dialog + backdrop + focus trap。
  • openclaw/extensions/qa-lab/web/src/ui-render.ts:长任务 runner、artifact、evidence、capture timeline 的信息架构。

4. 当前 UI 缺口

真实浏览器审计结果:

  • 有 streaming 状态与中止按钮,但 streaming 中输入框没有 steer / follow-up 模式,无法追加或插队。
  • 有 tool receipt 折叠区,但没有按 turn 内时间线显示工具调用开始、参数增量、结果、错误、耗时。
  • 工具调用过程没有和 assistant message 绑定;用户看到的是“模型说自己调用了工具”,不是 UI 明确展示调用过程。
  • 没有 extension UI dialog。审计结果 hasDialog=false
  • 没有独立通知/Toast。当前“通知”只是一个静态按钮,不是 ctx.ui.notify() 的承载面。
  • Markdown 渲染已存在,但缺 thinking block、copy-as-markdown、streaming partial fence 处理、表格/代码块稳定布局。
  • session history 只是列表入口,缺少 resume/fork/tree entry 级别视图。
  • abort 只可点一次停止,没有显示 abort response、aborted stopReason、被恢复的 queued messages。
  • 没有 pending queue 可视化。审计结果 hasFollowupOrSteerControl=false
  • 没有 artifact / citation / diff right railLightRAG、file patch、reference.open 只能混在正文或 receipt 里。

5. 目标 UI 信息架构

Pi Lab 主体分四层:

  1. 顶部运行栏

    • session name / model / thinking / context usage / runtime pid / allowed roots badge
    • streaming、queued、aborted、error 明确状态
    • stop、new、history、settings 以 icon button 呈现
  2. 消息流

    • user / assistant / system 分组
    • assistant 支持 live Markdown、thinking 折叠、copy-as-markdown
    • 每个 turn 下嵌入 tool timeline,而不是只靠 receipt 区
  3. Composer

    • idle:普通发送
    • streaming:显示 segmented controlSteer / Follow-up
    • Stop 后恢复未发送/排队文本
    • 支持图片/附件占位,但第一阶段不实现上传
  4. 右侧/底部详情 rail

    • Tool details:参数、结果、raw JSON、stderr、耗时、receipt id
    • Artifactsdiff、citation、open-reference、文件变更
    • DiagnosticsRPC events、session jsonl、policy snapshot,仅开发态默认折叠

6. 分阶段实施

6.0 执行 Checklist

已完成

  • 完成 Pi 官方 RPC / JSON event / TUI / extension UI 对照,确认 UI 缺口不只是 Markdown 渲染。
  • 完成当前 /page-ai/pi 真实浏览器 UI 缺口审计,证据:/tmp/mnote-pi-ui-gap-audit-1783222292502/result.json
  • 清理重复 Skill/MCP 配置,并修复 admin 设置删除后被 merge 回来的问题。
  • 验证清理后真实 Skill/MCP 链路仍可用,证据:/tmp/mnote-pi-real-after-clean-1783222483/result.json
  • 确认后端 /api/page-ai/pi/send 已支持 streamingBehavior,前端原先未传递。
  • 在 Pi Lab 消息流内新增折叠工具时间线与工具卡,支持 tool_execution_*toolcall_*、后端 tool receipt 统一展示。
  • 工具时间线过滤 thinking/reasoning 内容,避免把模型思考块作为工具详情泄漏到 UI。
  • 在 composer 中新增 Steer / Follow-up 控件,streaming 中允许继续输入并发送 streamingBehavior
  • Stop/abort 改为结构化 aborted 状态,不再把“已中止”拼进正常 Markdown 正文。
  • 新增 Phase 1 浏览器 smoketmp/mnote-pi-ui-phase1-smoke.js
  • 使用 npm run desktop:hot 真启动环境完成 /page-ai/pi 浏览器验证,证据:/tmp/mnote-pi-ui-phase1-1783228146571/result.json
  • 验证截图已产出:
    • 初始态:/tmp/mnote-pi-ui-phase1-1783228146571/01-initial.png
    • Steer/Follow-up 控件:/tmp/mnote-pi-ui-phase1-1783228146571/02-started-with-steer-controls.png
    • streaming 中止按钮:/tmp/mnote-pi-ui-phase1-1783228146571/03-streaming-stop-visible.png
    • 工具时间线展开:/tmp/mnote-pi-ui-phase1-1783228146571/04-tool-timeline-expanded-followup.png
  • Phase 1 smoke 断言通过:
    • hasToolTimeline=true
    • toolCardCount=2
    • hasFollowupControls=true
    • hasQueueControls=true
    • streamingBehaviorSent=true
    • noReasoningLeakInToolTimeline=true
  • 运行 node --check rust/crates/mnote-web/browser/sidebar-page-ai-pi-lab-runtime.js 通过。
  • 运行 node --check tmp/mnote-pi-ui-phase1-smoke.js 通过。
  • 运行 cargo test -p mnote-web page_ai_pi --lib 通过,10 tests passed。
  • 运行 codegraph sync . && codegraph status .,索引 up to date。
  • 处理 Pi JSONL message 事件中的 assistant toolCalltoolResultMCP 不再只能靠正文证明。
  • MCP 工具卡标题已规范化为 mcp:<server>/<tool>,例如 mcp:context7/listmcp:mempalace/mempalace_mempalace_search
  • 新增真实 MCP 工具卡 smoketmp/mnote-pi-mcp-toolcards-smoke.js
  • 使用 npm run desktop:hot 真启动环境完成 Context7 / MemPalace MCP 工具卡验证,证据:/tmp/mnote-pi-mcp-toolcards-1783230894265/result.json
  • MCP 工具卡截图已产出:
    • Context7/tmp/mnote-pi-mcp-toolcards-1783230894265/02-context7-mcp-toolcards.png
    • MemPalace/tmp/mnote-pi-mcp-toolcards-1783230894265/03-mempalace-mcp-toolcards.png
  • MCP 工具卡 smoke 断言通过:
    • hasContext7ToolCard=true
    • hasMemPalaceToolCard=true
    • context7McpCalled=true
    • mempalaceMcpCalled=true
    • noReasoningLeakInToolTimeline=true
  • 新增 PiRunViewModel reducer,统一承接 user prompt、assistant streaming/done/abort、tool upsert、citation、diff、queue_update、clear。
  • 新增 reducer 单元测试:tmp/mnote-pi-run-viewmodel-reducer-test.js
  • reducer 测试通过:node tmp/mnote-pi-run-viewmodel-reducer-test.js
  • Phase 1 smoke 支持桌面/移动 viewport 参数,工具卡可见性断言改为真实可见节点,避免折叠历史 timeline 误判。
  • 使用当前重启后的 npm run desktop:hot 完成桌面真实浏览器验证,证据:/tmp/mnote-pi-ui-phase1-1783234193679/result.json
  • 桌面截图已产出:/tmp/mnote-pi-ui-phase1-1783234193679/04-tool-timeline-expanded-followup.png
  • 使用当前重启后的 npm run desktop:hot 完成移动 viewport 真实浏览器验证,证据:/tmp/mnote-pi-ui-phase1-1783234215942/result.json
  • 移动截图已产出:/tmp/mnote-pi-ui-phase1-1783234215942/04-tool-timeline-expanded-followup.png
  • 移动 composer 控件补齐响应式换行,Steer / Follow-up / queue / model 不再挤出右侧边界。
  • 使用当前重启后的 npm run desktop:hot 完成 Context7 / MemPalace MCP 工具卡复验,证据:/tmp/mnote-pi-mcp-toolcards-1783234246744/result.json
  • 历史 session replay 改为复用 Pi RPC 事件处理链与 PiRunViewModel,不再只把 text delta 渲染成简化消息。
  • queue_update 在 live UI 和 history replay 中都进入同一个 reducer 状态。
  • Phase 1 浏览器 smoke 增加 history replay 断言与截图,证据:/tmp/mnote-pi-ui-phase1-1783240450668/result.json
  • History replay 截图已产出:/tmp/mnote-pi-ui-phase1-1783240450668/05-history-replay-tool-timeline.png
  • 使用 Context7 核对 Pi 官方 extension UI RPCextension_ui_request / extension_ui_response,方法包括 confirm/select/input/editor/notify
  • 后端新增 /api/page-ai/pi/ui-response,把浏览器 dialog 结果写回 Pi RPC stdin,并持久化 extension_ui_response 事件。
  • 前端新增 Extension UI modal host,支持 confirm/select/input/editor,并支持 timeout/cancel。
  • 前端新增 ctx.ui.notify() toast stack,支持 info/warning/error/success 风格。
  • 新增 extension UI 浏览器 smoketmp/mnote-pi-extension-ui-smoke.js
  • 使用 npm run desktop:hot 真启动环境完成 Extension UI 浏览器验证,证据:/tmp/mnote-pi-extension-ui-1783241631879/result.json
  • Extension UI 截图已产出:
    • Confirm dialog/tmp/mnote-pi-extension-ui-1783241631879/01-confirm-dialog.png
    • Select dialog/tmp/mnote-pi-extension-ui-1783241631879/02-select-dialog.png
    • Input dialog/tmp/mnote-pi-extension-ui-1783241631879/03-input-dialog.png
    • Notify toast/tmp/mnote-pi-extension-ui-1783241631879/04-notify-toast.png
  • Extension UI 弹窗位置已按 Pi UI 习惯改为 Pi 面板内部、输入框上方弹出,不再使用全系统居中遮罩。复验证据:/tmp/mnote-pi-extension-ui-1783242363461/result.json
  • Pi 内嵌弹窗/通知截图已产出:
    • Confirm dialog/tmp/mnote-pi-extension-ui-1783242363461/01-confirm-dialog.png
    • Notify toast/tmp/mnote-pi-extension-ui-1783242363461/04-notify-toast.png
  • Extension UI 弹窗底边已对齐到 Pi 输入区上边界,不再遮住输入框。复验证据:/tmp/mnote-pi-extension-ui-1783242834885/result.json
  • 对齐后截图:/tmp/mnote-pi-extension-ui-1783242834885/01-confirm-dialog.png
  • Artifact / Diff / Citation rail 初步完成,消息状态中的 citation、diff、MCP tool result 会进入右侧 Artifacts。
  • Artifact rail 支持 citation 打开引用入口、MCP raw 复制、artifact Markdown 复制,assistant 消息支持 copy-as-markdown。
  • 工具详情已改为默认压缩摘要,Input / Output / Raw 详情折叠显示,避免长 MCP 结果默认占满消息区。
  • Receipts rail 增加打开当前 session JSONL 的入口,使用当前 Pi session events 生成 NDJSON。
  • Artifact rail 浏览器 smoke 已覆盖 citation/diff/MCP/copy/open-session-jsonl/折叠详情断言,证据:/tmp/mnote-pi-artifact-rail-1783244314915/result.json
  • Artifact rail 截图已产出:
    • rail 与工具摘要:/tmp/mnote-pi-artifact-rail-1783244314915/01-artifact-rail.png
    • session JSONL 入口:/tmp/mnote-pi-artifact-rail-1783244314915/02-session-jsonl-action.png
  • Artifacts 不再默认常驻右栏占用 Pi 主界面,改为 commandbar 图标 + 数量 badge,点击后作为 Pi 内部浮层展开。
  • Artifacts 浮层底部停在 composer 上方,不遮住输入框。复验证据:/tmp/mnote-pi-artifact-rail-1783245137938/result.json
  • Artifacts 默认折叠/按需展开截图已产出:
    • 默认折叠,仅显示 badge/tmp/mnote-pi-artifact-rail-1783245137938/01-artifact-button-collapsed.png
    • 点击后 Pi 内部浮层:/tmp/mnote-pi-artifact-rail-1783245137938/02-artifact-popover.png
    • session JSONL 入口:/tmp/mnote-pi-artifact-rail-1783245137938/03-session-jsonl-action.png
  • 临时 Pi UI completion smoke 已纳入正式回归基线:scripts/task-pi-lab-ui-completion-smoke.js
  • History / session tree 已补齐 打开 / 重命名 / Fork 操作入口;重命名走 PATCH /api/page-ai/pi/sessions/{session_id},Fork 以当前历史上下文启动新 Pi runtime。
  • 高风险 MNote tool policy 已接入 Pi bridge 与后端强制校验:policy=ask 时未审批返回 page_ai_pi_lab_tool_approval_required,审批结果写入 tool receipt/audit UI。
  • abort response 已返回并显示 stopReason=abortedcommand=abort 与当前 queued steer/follow-up 数量。
  • 新增 completion 浏览器 smoke 断言:
    • hasHistoryOpen=true
    • hasHistoryRename=true
    • hasHistoryFork=true
    • unapprovedToolCode=page_ai_pi_lab_tool_approval_required
    • hasApprovalReceipt=true
    • abort note 显示 stopReason=abortedqueued steer=1 follow-up=1
  • 使用 npm run desktop:hot 真启动环境完成 completion 浏览器验证,证据:/tmp/mnote-pi-ui-completion-1783246949920/result.json
  • Completion 截图已产出:
    • History 操作入口:/tmp/mnote-pi-ui-completion-1783246949920/01-history-session-actions.png
    • 高风险审批 receipt/audit/tmp/mnote-pi-ui-completion-1783246949920/02-approval-audit-ui.png
    • Abort stopReason / queued messages/tmp/mnote-pi-ui-completion-1783246949920/03-abort-stopreason-queue.png
  • 新增真实 Pi Skill/MCP 浏览器 smokescripts/task-pi-lab-real-skill-mcp-smoke.js,先为 mnote-e2e seed 全部 Skill/MCP 权限,再走真实 /page-ai/pi RPC 链路。
  • 使用 MNOTE_WEB_ALLOW_DEV_FIXTURES=1 npm run desktop:hot 真启动环境完成 Context7 Skill + Context7 MCP + MemPalace MCP 验证,证据:/tmp/mnote-pi-real-skill-mcp-1783253985608/result.json
  • 真实 Skill/MCP 截图已产出:
    • Pi RPC 启动:/tmp/mnote-pi-real-skill-mcp-1783253985608/01-real-pi-started.png
    • Context7 Skill/MCP/tmp/mnote-pi-real-skill-mcp-1783253985608/02-context7-skill-mcp.png
    • MemPalace MCP/tmp/mnote-pi-real-skill-mcp-1783253985608/03-mempalace-mcp.png
  • 真实 Skill/MCP smoke 断言通过:
    • allSkillsEnabled=true
    • allMcpEnabled=true
    • context7SkillCliSource=true
    • vpnSkillCliSource=true
    • context7McpConfigured=true
    • mempalaceMcpConfigured=true
    • context7McpCalled=true
    • mempalaceMcpCalled=true
    • noReasoningLeakInToolTimeline=true
  • 运行 node --check rust/crates/mnote-web/browser/sidebar-page-ai-pi-lab-runtime.js 通过。
  • 运行 node --check scripts/task-pi-lab-ui-completion-smoke.js 通过。
  • 运行 node --check scripts/task-pi-lab-real-skill-mcp-smoke.js 通过。
  • 运行 cargo test -p mnote-web page_ai_pi --lib 通过,11 tests passed。
  • 运行 cargo test -p mnote-web dev_seed --lib 通过,3 tests passed。
  • 运行 codegraph sync . && codegraph status .,索引 up to date。
  • 对照 Pi 官方能力完成输入区收口:Pi 官方支持 --thinking,但无原生 permission popup / plan modeMNote 侧展示 MNote 实际 tool policy / directory grant。
  • 后端 PiLabStartRequest / PiLabSession 增加 thinkingLevel,真实 Pi RPC 启动时传 --thinking <level>,并写入 runtime JSON。
  • Pi 输入区新增 + 菜单,包含当前页、选区、LightRAG、目录权限、执行中引导/排队;附件/拍照与规划模式保持禁用,避免展示未接入假功能。
  • Pi 输入区新增思考深度选择器与 MNote 权限/审批 chip,权限 chip 文案来自当前 runtime policy 与 allowed roots。
  • completion 浏览器 smoke 增加 + 菜单、thinking control、permission chip、plan mode disabled 断言与截图。
  • 使用当前 dev:hot 真启动环境完成输入区 + 菜单 / 权限 / thinking 浏览器验证,证据:/mnt/Data1T/mnote/tmp/pi-plus-20260706-140632/result.json
  • 输入区截图已产出:/mnt/Data1T/mnote/tmp/pi-plus-20260706-140632/00a-plus-permission-thinking-menu.png
  • 运行 node --check rust/crates/mnote-web/browser/sidebar-page-ai-pi-lab-runtime.js 通过。
  • 运行 node --check scripts/task-pi-lab-ui-completion-smoke.js 通过。
  • 运行 node scripts/task-pi-lab-static-smoke.js 通过。
  • 运行 cargo test -p mnote-web page_ai_pi --lib 通过,11 tests passed。
  • 新增输入区真实可用性浏览器 smoke:scripts/task-pi-lab-input-controls-smoke.js,覆盖底部快捷按钮、+ 菜单、权限 chip、thinking selector、发送按钮、streaming 中 steer/follow-up、目录权限入口、禁用附件/拍照/规划模式。
  • 修复 Pi RPC message_update.text_start 后 UI 未进入 streaming 状态的问题,确保菜单里的“作为引导发送 / 作为排队追问发送”真实发送 streamingBehavior=steer/followUp
  • 修正 Pi 输入区目录权限入口为当前设置页真实 panel:/user/ai#ai-admin-access
  • 使用 dev:hot 真启动环境在 http://127.0.0.1:3000 完成输入区全部功能浏览器验证,真实 Pi runtimeMode=rpc,证据:/mnt/Data1T/mnote/tmp/pi-input-3000-real-20260706-151725/result.json
  • 输入区真实功能截图已产出:
    • 当前页/选区/LightRAG/权限 chip/mnt/Data1T/mnote/tmp/pi-input-3000-real-20260706-151725/01-context-actions-working.png
    • streaming 中 steer/follow-up/mnt/Data1T/mnote/tmp/pi-input-3000-real-20260706-151725/02-streaming-send-menu-working.png
    • 目录权限入口:/mnt/Data1T/mnote/tmp/pi-input-3000-real-20260706-151725/03-directory-permission-entry.png
  • 输入区 smoke 断言通过:
    • bottomReadPage=true
    • bottomSelection=true
    • bottomRag=true
    • menuReadPage=true
    • menuSelection=true
    • menuRag=true
    • menuSteerStreamingBehavior=steer
    • menuFollowupStreamingBehavior=followUp
    • restartThinkingLevel=xhigh
    • sendButtonMessage="send button input controls smoke"
    • directoryPermissionUrl=http://127.0.0.1:3000/user/ai#ai-admin-access
    • attachDisabled=true
    • cameraDisabled=true
    • planDisabled=true

进行中

  • 无。

未开始

  • 无。

Phase 1:运行事件时间线

目标:用户必须看见工具正在做什么。

  • 后端把 Pi tool_execution_start/update/endmessage_updatequeue_updateagent_start/end 解包成稳定 SSE event。
  • 浏览器建立 PiRunViewModel
    • turns[]
    • messages[]
    • toolCallsById
    • pendingQueue
    • currentAssistant
    • runtimeStatus
  • 每个工具卡默认折叠显示:工具名、状态、摘要、耗时、allowed/denied。
  • 展开后显示:Input、Output、Raw details、Error。
  • mnote.tool_receipt.write 与 MCP 调用都映射成统一 tool card。

验收:

  • Context7 / MemPalace 测试截图中必须可见折叠工具卡。
  • 工具卡展开后能看到 server/tool/args/result 摘要。
  • browser audit 中 hasToolTimeline=true

Phase 2Streaming 中断与追加回复

目标:补齐 Pi 官方 queue 语义。

  • composer streaming 状态下允许继续输入。
  • 发送按钮旁提供 mode segmented control
    • Steer:发送 {type:"prompt", streamingBehavior:"steer"}
    • Follow-up:发送 {type:"prompt", streamingBehavior:"followUp"}
  • 后端暴露并持久化 queue_update
  • Stop 调用 RPC abort 后显示 abort response 与 stopReason=aborted

验收:

  • streaming 时输入一条 steerUI 显示 queued/steering。
  • follow-up 在当前 turn 完成后自动执行。
  • Escape 或 Stop 后 assistant message 显示 aborted 状态,不把“已中止”混进正常 Markdown 正文。

Phase 3Extension UI Dialog 与通知

目标:让 Pi extension 的交互能力可见可控。

  • 扩展桥支持 ctx.ui.select/confirm/input/notify 事件。
  • 浏览器提供统一 dialog host
    • confirm:标题、说明、Cancel/Confirm
    • select:搜索/键盘选择
    • input:单行/多行输入
    • timeout / AbortSignal 自动关闭
  • 通知用右上角 toast stack,类型包括 info/warning/error/success。
  • 高风险工具审批复用 confirm,但审批结果必须写 audit/receipt。

验收:

  • 测试 extension 调 ctx.ui.confirm(),浏览器出现 modal。
  • AbortSignal 触发后 modal 关闭。
  • ctx.ui.notify() 可见且自动消退。

Phase 4Artifact / Diff / Citation Rail

目标:把 Page AI 和 MNote 工作区真正接上。

  • file patch 工具显示 diff summary 与 changed files。
  • LightRAG citation 显示引用卡,点击走 mnote.reference.open
  • MCP 结果可作为 artifact 固定在右侧 rail。
  • 支持 copy raw / copy markdown / open session jsonl。

验收:

  • local file patch 后可见文件路径、diff summary、watcher refresh 状态。
  • LightRAG 回答中 citations 不只在文本中出现,而是可点击卡片。

Phase 5History / Session Tree / Replay

目标:补齐 Pi 的 session 能力。

  • 历史列表显示 session name、model、last turn、tool count、updated time。
  • 支持 resume、new、fork、rename。
  • 事件 replay 用同一 PiRunViewModel,历史会话不走另一套渲染。
  • debug 才显示原始 JSONL。

验收:

  • 重新打开 /page-ai/pi 可恢复最近 session。
  • 历史会话 tool cards、Markdown、receipts 展示一致。

7. 实施边界

  • 不开放 Pi raw bash/read/write/edit 给普通 Page AI。
  • MCP 继续走 MNote facade-only / sandbox 控制面。
  • Tool card 展示不是权限来源;权限来源仍是 AiAccessScope、allowed roots、admin/user AI policy。
  • Debug / diagnostics 默认折叠,不挤占用户首屏。
  • 不把 OpenClaw 的 UI 代码直接复制进 MNote;只采用信息架构和交互模型。

8. 测试矩阵

  • Unit
    • PiRunViewModel event reducer
    • tool card folding
    • queue_update reducer
    • dialog lifecycle
  • Browser smoke
    • /page-ai/pi start -> prompt -> streaming -> tool timeline -> final Markdown
    • Context7 MCP call tool card
    • MemPalace MCP call tool card
    • Stop/abort visible state
    • Steer/follow-up queue visible state
    • extension confirm/select/input/notify
  • Regression
    • /api/ai-admin/settings 删除 Skill/MCP 后 effective 不再出现残留
    • admin/user AI policy 不能越权启用全局未授权 skill/mcp/model/root