Skip to content

Latest commit

 

History

History
160 lines (127 loc) · 14.4 KB

File metadata and controls

160 lines (127 loc) · 14.4 KB

v0.16.1:笔记体验与 AI 对话闭环(2026-08-31 用户反馈批)

状态:已交付(2026-08-31) 依据:用户实测反馈批(2026-08-31)逐项裁决——图片插入 RangeError / 手动分组不可达 / 正文多色 / 对话转笔记 / AI 任务对话化 / 精修工作台深链 / 右键菜单完整性 / 浏览器原生右键菜单去除;并追加两项增补(笔记行右键菜单、浏览器元素去除)。 前置:v0.16.0 内嵌 AI 对话 · v0.14 B 视觉系统(此版部分重申其裁决,见 REQ-239)

一句话

v0.16.0 用户实测后的一轮体验修复 + 闭环增强小版本:修掉图片插入即崩(CM6 block decoration 违规)与荧光笔"看起来没样式"(hName 缺失)两个实测缺陷;把笔记分组、正文多色、对话→笔记、AI 任务"像对话一样"、精修工作台深链补全成用户可感知的完整能力;并整体去除 WebView2 浏览器痕迹(原生右键菜单),笔记/组/会话行补应用内右键菜单。

用户裁决记录(2026-08-31)

议题 裁决
正文颜色语法 ==[色]文本== 前缀式(12 色板小写 id;无前缀保持默认黄,存量内容零迁移)
对话转笔记 双入口(会话顶栏整段 + AI 消息级至该条)· 内容形态 = 完整对话含问答(提问引用块 + AI 回答全文)
任务对话化 并入聊天线程 + 可追问;追加:会话页使用 AI 精修时自动跳转 AI 对话页
任务发起入口 按钮 + / 快捷命令(/refine /enrich)两处并存
内容多色范围 完整实施(渲染 + CM/textarea 两编辑器工具栏色板按钮 + 规格修订 + 测试)
笔记行右键菜单 完整菜单(移动到组子菜单/固定/复制标题正文/编辑/删除);追加:检测其他部分右键菜单是否完整
浏览器元素去除 先修右键——当前右键是浏览器原生菜单而非应用专有 UI:全局禁用 WebView2 原生右键菜单(host 侧);prompt/confirm/alert 13 处替换本批不做(后续批)

范围(REQ-238~244)

REQ 内容 备注
REQ-238 修复:图片插入 RangeError: Block decorations may not be specified via plugins CM6 明确禁止插件产出 block decoration(disallowBlockEffectsFor);imageDecorationPlugin 改 inline replace——独立行图片所在行仅空白,替换后自然独占一行(视觉等价,零行为回退)
REQ-239 正文多色荧光笔 ==[色]文本== 修订 v0.14 B「多色=伪需求」裁决(用户明确需要);未知色 id 整体原样保留(诚实降级);含代码块/行内代码不误伤、未闭合/跨行降级(沿用旧规则);样式 = note-mark.css 双主题 + WCAG 前景(生成脚本 scripts/gen-mark-css.mjs,改色板先重跑再提交)
REQ-240 对话转笔记 create_note 复用(source=manual);消息级 = 自会话首条至该条的完整上文(纯函数 buildConversationMarkdown 可单测)
REQ-241 AI 任务对话化 发起(工具条 + / 命令)→ 授权/成本一次确认(未授权先同意 + ai_set_authorized,与 AiRefineCard 同红线)→ 任务卡入聊天线程(进行中实时轮询;完成 10 分钟窗口内「在对话中追问」预填结果要点 800 字符截断)→ 会话页精修启动自动跳 AI 对话页(focusTaskId 跨页直达)
REQ-242 任务对话视图 → 精修工作台深链 完成 v0.16.0 登记的"工作台深链后续增强":任务卡「🛠 打开精修工作台」→ 会话页自动切预览视图 + AiRefineCard autoTaskId 取回结果直接展开工作台(免重跑流程)
REQ-243 右键菜单完整性 笔记行完整菜单(组子菜单/固定/复制标题/复制正文/编辑/删除);组行右键 = ⓘ 组管理弹层(同语义);会话行右键 = 打开详情;知识画布/树右键暂不新增(无既有处理语义;原生菜单已全局禁用)
REQ-244 浏览器元素去除 host 侧禁用 WebView2 原生右键菜单(AreDefaultContextMenusEnabled=false——wry with_webview → ICoreWebView2Controller → CoreWebView2() → Settings() 链;主窗/浮窗/框选窗三处);前端 contextmenu preventDefault 兜底(开发浏览器同效);文本输入(input/textarea)应用内右键小菜单(剪切/复制/粘贴/全选)补偿原生菜单消失后的可用性;CodeMirror 编辑区不放行(自有编辑事务)

顺带修复(探测链路时发现的潜藏缺陷)

  • 荧光笔实际无样式:v0.14 B 的 remarkMarkHighlight 产出 mdast mark 节点但未给 data.hName——mdast-util-to-hast 的 defaultUnknownHandler 把未知节点落成 div,NoteMarkdown 的 components.mark 按 hast tagName 匹配从未命中,==文本== 实际渲染为无样式的裸 div。REQ-239 一并修对(hName/hProperties 注入)并锁定端到端测试。
  • App.css 从未被引入(模板残留;ed-low-confidence / chatBlink / 暗色 :root 均为死样式)——未动(引入会改变全局暗色观感),登记为后续项。

设计要点

① 图片插入(REQ-238)

Decoration.replace({ widget })            // 一律内联(无 block:true)
   ▲
   └─ CM6 ViewPlugin decorations 经 disallowBlockEffectsFor 校验——
      block:true → RangeError(用户实测:插入本地图片即报失败)

修复原则:不碰 CM 内部语义、只去违规标志;独立行图片由"所在行除图片语法外仅空白"天然独占一行。回归测试挂 RichEditorView.test.tsx(独立行图片渲染为 widget、不抛 RangeError、语法文本不残留)。

② 正文多色(REQ-239)

解析层(纯函数):==(?:\[[a-z]+\])?([^=\n]+)==
   ├─ [色id] ∈ 12 色板(colorPalette.isColorId 校验)→ mark{colorId}
   ├─ 无前缀 → mark{}(默认黄 —— 存量 ==文本== 零迁移)
   └─ 未知色 id / 未闭合 / 跨行 / 代码块 → 原样保留(不猜色、不吞内容)
渲染层:mdast data { hName:"mark", hProperties.className:["note-mark","note-mark-{id}"] }
   → mdast-util-to-hast applyData 落 <mark class>(修复 hName 缺失)
样式层:note-mark.css —— 默认黄 #fde68a(沿用旧值)+ 12 色 × 双主题
   (前景按 WCAG AA ≥4.5:1 取黑/白;scripts/gen-mark-css.mjs 生成,防手工漂移)
编辑层:🖍 荧光按钮(RichEditorView + NoteEditView 降级版同入口)
   → 色板(NoteColorPicker 复用)→ wrapSelectionCommand ==[色]…== / ==…==

③ 对话转笔记(REQ-240)

顶栏「📄 转笔记」(整段)· AI 消息「📄 存为笔记」(至该条)
   → ChatSaveNoteDialog(标题默认取首条提问首行 ≤60 字;目标组下拉可选)
   → buildConversationMarkdown(纯函数)
        user → > **🧑 你(HH:MM)** + 逐行 > 引用块
        assistant → **🤖 AI(模型 · HH:MM)** + 正文(aborted 标注已停止)
        failed / 空内容跳过(失败内容无知识价值)
   → create_note { title, content, source:"manual", group_id? }
   → 成功态「在笔记页打开」(onOpenNote 现链)

④ 任务对话化(REQ-241)

聊天视图工具条 [✨ 发起任务 ▾] + Composer '/refine|/enrich' → TaskLaunchDialog
   ├─ 目标:会话列表(精修)/ 笔记列表(补充=九子项全选 d1~d3+b1~b6)
   ├─ 授权红线:ai_get_settings.authorized == false → confirm 同意 → ai_set_authorized
   ├─ 成本:ai_refine_estimate / ai_enrich_estimate → confirm(预估失败仅提示未知成本)
   └─ ai_refine_start / ai_enrich_start → onStarted → reloadTasks + selectTask
任务卡(TaskThreadCard,聊天线程内):
   ├─ 进行中 pending/running:实时(排队/进行中文案 + 片数 + 查看轨迹)
   └─ 完成(succeeded/partial_failed,10 分钟窗口):
        「💬 在对话中追问」→ buildTaskFollowUpPrompt(背景引用块 + 结果 800 字截断 + 开放引导)
        预填 Composer → 用户发送 → 继续在聊天线程对话
会话页精修启动 → onTaskStarted(sessionId, taskId) → App setPage("chat") + focusTaskId
   → ChatPage effect selectTask(focusTaskId)(任务视图选中,进度/轨迹即时可见)

⑤ 工作台深链(REQ-242)

TaskConversationView 任务卡(refine & succeeded)
   → onOpenRefineWorkbench(refId, taskId)
   → App:setFocusSessionId + setFocusRefineTaskId + setPage("sessions")
   → SessionsPage → SessionDetailPanel(autoTaskId 到达 → setViewMode("preview"))
   → NotePreviewView → AiRefineCard autoTaskId:
        挂载即 invoke ai_refine_result(taskId) → result + phase=done + 工作台直接展开
        (取回失败 → onAutoTaskMissing 回调——父层提示并清焦点)

⑥ 右键菜单(REQ-243)与元素去除(REQ-244)

host 侧(Windows 唯一可靠通道——DOM preventDefault 不保证抑制 WebView2 原生菜单):
   with_webview → PlatformWebview.controller()
     → ICoreWebView2Controller::CoreWebView2() → ICoreWebView2::Settings()
     → SetAreDefaultContextMenusEnabled(false)          // 失败仅日志(降级不阻断)
前端:
   BrowserChrome 组件(App 壳挂载):
     ① window contextmenu preventDefault(兜底 + 开发浏览器同效)
     ② input/textarea 右键 → 应用内小菜单(剪切/复制/粘贴/全选)
        - 粘贴 = clipboard.readText → setRangeText(光标处) + 补发 input 事件(驱动受控组件)
        - .cm-editor 除外(CM 自有编辑事务;Ctrl+V 主路径不受影响)
    自绘菜单(笔记行/组行/会话行)各自 stopPropagation——事件到不了 window,无竞争

测试

  • Rust:browser_chrome 为纯 host 设置(无业务逻辑需单测;失败仅日志降级);cargo check 零错误——新增直接依赖 webview2-com(lock 内已有 0.38.2,零新增下载)
  • 前端 Vitest(本轮 +39 条,全量 481 通过 / 62 文件):
    • imageDecoration:独立行图片渲染不抛 RangeError(回归——旧代码必挂)
    • remarkMarkHighlight:默认黄/彩色/未知色/混合/未闭合/跨行/代码块(12 测)+ NoteMarkdown 端到端 <mark class=…>(hName 修复锁定)
    • chatTranscript:完整问答/引用块/upToId 截断/failed 跳过/aborted 标注(5 测)+ ChatSaveNoteDialog(保存/归组/失败不关窗/在笔记页打开/取消,5 测)
    • taskFollowUp:结果提取/预填结构/800 截断/无结果降级(6 测)+ TaskLaunchDialog(精修/补充九子项/未授权先同意/取消,4 测)+ TaskThreadCard(进行中/追问/10 分钟窗口/空渲染,4 测)
    • NoteMoveToGroupMenu(3 测)· NoteRowContextMenu(5 测)· BrowserChrome(原生菜单抑制/菜单弹出/粘贴插入/禁用态/ESC,5 测)
  • tsc 零错误;既有套件零回归(工具栏/保存/草稿等路径全部保持绿)

验收标准

  1. 插入本地图片/外链图/剪贴板图片不再报 RangeError,图片以 widget 内联渲染(独立行独占一行)
  2. 编辑态「🖍 荧光」选色包裹选区;阅读态 ==[red]重点== 呈红色底、==重点== 呈默认黄(深色主题双变体)
  3. 会话顶栏「📄 转笔记」保存整段对话(提问引用 + 回答全文);AI 消息「存为笔记」保存至该条的完整上文;可归组;保存后可跳笔记页
  4. 聊天内「✨ 发起任务」//refine /enrich 启动精修/补充;线程任务卡实时显示进行中任务;完成 10 分钟内可「在对话中追问」(Composer 预填结果要点);会话页精修启动自动跳 AI 对话页
  5. AI 任务段精修成功任务卡有「🛠 打开精修工作台」→ 会话页自动展开工作台(结果免重跑)
  6. 全应用右键无浏览器原生菜单;笔记行右键菜单完整可用;组行右键打开 ⓘ 组管理;会话行右键打开详情;文本输入右键有应用内剪切/复制/粘贴/全选
  7. 全量回归通过(cargo check / vitest 481 / tsc)

交付记录(2026-08-31)

Rust:browser_chrome.rs(with_webview → CoreWebView2() → Settings() → SetAreDefaultContextMenusEnabled(false);Windows 专属 + 非 Windows 空实现)· lib.rs setup 主窗接线 + commands_window.rs/commands_overlay.rs(浮窗/框选窗建窗后接线)· Cargo.toml webview2-com = "0.38"(lock 内已有,零下载)

前端:imageDecorationPlugin.ts(block 去除)· remarkMarkHighlight.ts(多色 + hName/hProperties 注入)· note-mark.css + main.tsx(样式入口)+ scripts/gen-mark-css.mjs(生成脚本)· NoteMarkdown.tsx(mark 组件 class 化)· RichEditorView.tsx/NoteEditView.tsx(🖍 荧光色板按钮)· NoteMoveToGroupMenu.tsx(阅读头手动分组)· NoteRowContextMenu.tsx + NoteListRow/NoteListView/NotesPage(右键菜单链)· GroupSidebarRow/GroupSidebar(组行右键 = ⓘ)· SessionListPanel(会话行右键 = 打开详情)· BrowserChrome.tsx(全局抑制 + 文本右键小菜单)+ App.tsx(挂载)· chatTranscript.ts + ChatSaveNoteDialog.tsx + ChatPage(双入口转笔记)· TaskLaunchDialog.tsx + TaskThreadCard.tsx + taskFollowUp.ts + ChatPage/'/' 命令 + AiRefineCard/NotePreviewView/SessionDetailPanel/SessionsPage/App.tsx(工作台深链 + 精修启动自动跳转 + focusTaskId/focusRefineTaskId 跨页直达)

文档:本文档 + requirements-pool REQ-238~244(含 v0.14 B 单色裁决修订说明;编号说明:REQ-231 已由 v0.16.0 预留给聊天上下文注入——本次审查修正)

遗留问题

  • window.prompt/confirm/alert 13 处替换为应用内对话框(聊天重命名/AI Provider 删除/备份恢复/碎片删除/版本回滚/精修授权确认等)——用户裁决本批不做,登记后续批
  • App.css 从未被引入(ed-low-confidence/chatBlink/暗色 :root 为死样式)——引入会改变全局暗色观感,需单独裁决
  • 知识画布/树区域右键菜单暂不新增(无既有处理语义);原生菜单已全局禁用,不会出现浏览器菜单
  • 画布/知识树(@xyflow)内文本编辑(如果有)未纳入 BrowserChrome 文本右键菜单的 contenteditable 通道(仅 .cm-editor 排除)——按需再议