状态:代码已交付(2026-08-23) 依据:用户对话 2026-08-23(笔记页截图 4 点抱怨:碎片捕获无头绪 · 分组混乱交互不明 · 路由理由放置存疑 · 需要自主新建笔记)+ 市场调研(捕获收件箱模式 / Gmail 分类透明性 / 自动组织先例)+ 三项用户裁决(方案 A 三栏 · 二元论碎片 · 升笔记轻确认) 前置:v0.12.1(OCR 引擎回归修复)交付后开工 实施裁决(2026-08-23 用户最终确认):feedCapture 开关默认开启(快速记录收件箱转正,不再是预览);Phase 1 + Phase 2 全量实施
笔记页从"550px 一栏塞三职(筛选+列表+详情)"重构为三栏分工(组筛选 / 笔记列表 / 阅读编辑),给碎片补上向上的出路(升为笔记),把路由理由与组管理收敛进 ⓘ 弹层,新建笔记零对话框——四个抱怨分别对应:概念分家、职责分离、信息收敛、入口去摩擦。
| # | 项目 | 类型 | 落点 |
|---|---|---|---|
| 1 | 三栏布局重构 | P0 交互债 | 240px 组侧栏 + 320px 笔记列表(常驻)+ 阅读/编辑(现有 NoteReadingView);搜索/标签过滤时列表原位切换,不再换布局 |
| 2 | 收件箱动线(碎片→笔记) | P0 产品缺口 | 碎片=原料(二元论裁决);快速记录→收件箱(恒常可见)→ 升笔记/升卡/删除;新增 promote_fragment_to_note(事务建笔记+删碎片) |
| 3 | 路由信息收敛 | P1 信息债 | 组行小字(系统自动归类/⚠待确认/已改判 + ⓘ);ⓘ 弹层=人话归因+明细折叠+改判+组管理(闪卡/结算/复习本组/周契约) |
| 4 | 新建笔记零对话框 | P2 摩擦 | 去 window.prompt;新建即编辑态;落未归组(全部笔记可见) |
| 5 | 文档与治理 | 伴随 | requirements-pool 回填 REQ 编号(实施时)· 本版本文档 · CHANGELOG(交付时) |
| 调研结论 | 来源 | 对应变化 |
|---|---|---|
| 捕获面必须与检索面互相喂养;胜出模式 =「Capture everywhere, triage in ONE inbox」 | 捕获模式横评(Apple Notes/Notion/Obsidian/MindWiki) | 快速记录→收件箱恒常首项,不再藏到 feed 开关后 |
| 自动分类:结果可见、原因不展示(Gmail 页签只给"归错了可改",从不解释信号) | Gmail Categories 机制、Apple Photos 人物相册:聚类与确认界面分离 | 路由理由人话一行 + 信号明细默认折叠(REQ-198 "可见"重释:可见=结果+一句话,非算法原文) |
| 组织范式:过滤器/容器/详情严格分离(Gmail 页签、Apple Notes 文件夹+列表+内容、Notion 视图≠容器) | NoteLyn 组织系统分析 | 三栏拆分;组行单击=仅过滤 |
| 中文音视频转笔记:听悟/讯飞为"终点/转写工具"(组织缺失或靠用户自理),Ai好记=显式三级目录 | 通义听悟、讯飞听见、Ai好记实测 | 组=粗粒度容器(课程/主题/独立),不学三级目录(YAGNI) |
| 新建:主流零对话框、第一行即标题(Apple Notes/Notion/Obsidian 快速捕获) | 同上横评 | 去 prompt,新建即编辑 |
┌──────────────┬───────────────────┬─────────────────────────────┐
│ 笔记组 (240px) │ 笔记列表 (320px) │ 阅读 / 编辑(自适应) │
├──────────────┼───────────────────┼─────────────────────────────┤
│ ⚡ 快速记录 │ 当前视图名 +搜索+排序│ 标题+来源徽标+操作行 │
│ 📥 收件箱 (3) │ 笔记卡片列表 │ Markdown 渲染(回链/任务勾选)│
│ 📁 全部笔记 │ (空态引导) │ 辅助面板:版本时间线/AI补充 │
│ 📁 组… │ │ │
│ ─────────── │ │ │
│ 🎴 复习 12 │ │ │
└──────────────┴───────────────────┴─────────────────────────────┘原 NoteGroupPanel(545 行,职责三合一)按职责拆分:组筛选侧栏 + ⓘ 弹层 + 收件箱视图,各自单文件 ≤300 行(AGENTS.md §3.1)。
碎片 = 灵感/待处理原料,不是短笔记。短笔记可直接用「新建笔记」,碎片入口存在的意义是比新建更轻(零标题/零选组/零结构)。现状病根:v0.11.4 明确"碎片→笔记升级不做(身份诚实)"——捕获产物只有升卡/删除两条出口,无向上通道 → 永远躺在隐藏 feed 组里 →"无头绪"。
本版补上出口(对 v0.11.4 范围决策的修订):
捕获(快速记录/剪贴板)──► 📥 收件箱(fragment 列表)
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
✍ 升为笔记 ⚙ 升为闪卡 🗑 删除
(轻确认) (现有多句卡生成) (二次确认)
│
▼
进入笔记链路:编辑/AI精修/版本/归组/生成闪卡/搜索- 升笔记=轻确认(用户裁决):碎片卡内联展开标题(预填首句可改)+ 归组下拉(默认未归组)+ 确认 →
promote_fragment_to_note事务建笔记+删碎片 → 右侧自动打开新笔记(闭环可见)。 - 收件箱只装碎片;未归组笔记(
group_id IS NULL)显示在「全部笔记」——两种实体 UI 分家,各走各的动线(修正:草案中"收件箱=未归组笔记视图"作废,二元论下不成立)。 - 收件箱恒常可见(固定侧栏首项 + 待处理计数),不再依赖 feedCapture 开关隐藏。
- 空态引导:「一句灵感,三种归宿——升为笔记沉淀它,升为闪卡复习它,或删除它。」
组行下方一行小字(系统自动归类 · ⓘ / ⚠ 待确认 · ⓘ / 已改判 · ⓘ;⚠ 时淡橙描边保留),组行单击只做过滤(现状:单击=过滤+展开双动作——"不知道如何去交互"的直接原因)。
ⓘ 弹层四区:
- 人话归因:
系统按内容特征归入:画面以术语表为主(60 条术语);信号明细(术语表成块/画面文字密度等原文)折叠在"查看明细",默认不展开; - 改判:课程组/主题组/独立组 + 领域下拉 + 确认(修改即记忆,REQ-198 保留);
- 组管理:⚙ 生成闪卡 | 🧹 结算(含结算计划)| 🎴 复习本组 | 📥 移入/移出选中笔记;
- 周契约卡(REQ-200,组级承诺→组级详情)。
window.prompt 移除:点「✍ 新建」→ create_note(未命名笔记, "") → 立即进入编辑态聚焦首行(Apple Notes/Notion 式);落未归组(全部笔记可见);标题编辑器内可改。
| 变更 | 说明 |
|---|---|
promote_fragment_to_note(fragmentId, title, groupId?) |
新命令;事务建 notes(source=manual, 正文=碎片文本+图)+ 删 fragment;标题必填(前端保证);groupId 可选 |
capture_fragment / list_group_fragments / delete_fragment / update_fragment_group |
保留,语义不变;删除加二次确认(前端化) |
| feed 组地形 / fragments 表 | 保留不动(免迁移;对比 A-2 一元论:免 fragments→notes 迁移) |
| feedCapture 功能开关 | 语义改为「快速记录入口」开关;默认值建议改开(本重构即转正,不再是预览)——待实施前用户最终确认 |
| 组件 | 动作 |
|---|---|
NoteGroupPanel.tsx |
拆分为 GroupSidebar.tsx(筛选侧栏)+ RouteInfoPopover.tsx(ⓘ 弹层,≤300 行/文件) |
FeedFragmentList.tsx |
改造为收件箱碎片卡(升笔记内联表单 + 升卡 + 删) |
NotesPage.tsx |
三栏编排;groupFilter 只做过滤 |
NoteListView.tsx |
常驻中部(去掉 flatMode 隐藏依赖) |
WeekContractCard.tsx |
迁入 RouteInfoPopover |
handleCreate |
去 prompt |
- 三元分离:筛选(侧栏)/ 列表(中部)/ 详情(右侧)各司一职;一个手势只触发一个动作——回应当前"组头单击=过滤+展开"的双动作歧义。
- 碎片是原料(二元论,用户裁决):碎片≠短笔记;补 v0.11.4"升级不做"的出口,范围修订在版本文档记录,不改 ADR。
- 结果可见、原因不展示(市场先例):路由理由人话一行 + ⓘ 明细折叠;REQ-198"可见可改"重释为"决策结果可感知、原因可按需、误判可一键纠正"。
- 收件箱只装碎片:未归组笔记不混入收件箱(两种实体、两条动线),延续"活沉淀"(note-design-philosophy)——笔记是过渡态,碎片是最粗的证据。
- YAGNI:不做拖拽归组(保留"移入选中笔记"按钮)、不做碎片批量处理(逐条,学习仪式感)、不做学习循环功能改动(只挪 UI 位置);三级目录/双链/图谱不做(产品边界,见注记哲学 §二)。
- 零后端破坏:Phase 1 纯前端先行;fragments/feed 语义零迁移,单一新命令,测试回归面小。
- Phase 1(纯前端,零后端改动):三栏拆分 + 组行交互修正 + ⓘ 弹层(迁入路由理由/改判/组管理/周契约)+ 新建去 prompt + 收件箱视图常驻(碎片列表迁移)。
- Phase 2(后端 + 开关):
promote_fragment_to_note+ 碎片卡升笔记/升卡接线 + feedCapture 开关语义调整(默认值已裁决:改开)。 - 验收走查:种子数据过 捕获→升级→编辑→归组→闪卡 全链。
NoteGroupPanel.tsx(545 行,三合一)按职责拆分并删除:GroupSidebar.tsx(240px 组筛选侧栏)——行单击=仅过滤(删除"单击=过滤+展开"双动作);行小字=人话归因一行 + ⓘ;⚡ 快速记录、📥 收件箱(恒常首项+计数)、📁 全部笔记、🎴 复习徽标。RouteInfoPopover.tsx(ⓘ 弹层,≤300 行)——四区:人话归因 + 信号明细默认折叠("查看明细"展开)/ 改判(修改即记忆)/ 组管理(生成闪卡·结算含计划·复习本组·移入移出选中笔记)/ 周契约卡(WeekContractCard独立组件由弹层引用);fixed 锚定组行下方 + 透明背板/ESC 关闭。
NotesPage.tsx三栏编排:view: notes | inbox中部原位切换;groupFilter只做过滤;搜索/标签过滤激活时 NoteListView 原位显示结果(不再 flatMode 换布局);focusNoteId 跨页直达简化为滚动定位(无展开依赖);noteTree.ts树形合并纯函数与单测下线(v0.11.5 树模式被三栏取代)。- 行数豁免登记同步(
docs/standards/line-limit-exemptions.md):NoteGroupPanel(545)与 NoteEditView(登记值过期,实测 ≤300)登记移除;NotesPage.tsx(328 行)正式登记(编排层内聚,拆分计划:快捷键/收件箱动线回调拆 hooks)。 - 新建笔记:
handleCreate去window.prompt——create_note(未命名笔记,"")→ 立即编辑态聚焦首行(NoteEditView autoFocus),落未归组(全部笔记可见),并自动切回笔记视图+全部过滤(新建即见闭环)。
promote_fragment_to_note(fragment_id, title, group_id?)新命令:单事务(读碎片→建 notes(source=manual, 正文=碎片文本)→图片搬运fragments/→notes-images/{nid}/并写入 markdown 引用→删碎片);图片搬运失败降级纯文本笔记(碎片文本不丢);标题后端必填校验;require_feed_enabled对称准入。promote_fragment_to_card(fragment_id)新命令:复用card_from_fragment多句卡规则;幂等(card_by_fragment查重——已升级返回 0 不报错,可重复触发);未归组碎片明确报错引导先归组/升笔记(flashcards.group_id NOT NULL 契约);记fragment_upgraded指标(与组生成同口径)。FeedFragmentList.tsx改造为收件箱碎片卡(全量 active 碎片,不再依赖 feed 组展开):✍ 升为笔记(内联轻确认表单:标题预填首句可改 + 归组下拉默认未归组→确认后右侧自动打开新笔记)/ ⚙ 升为闪卡 / 🗑 删除(二次确认);空态引导"一句灵感,三种归宿"。- feedCapture 开关:默认值改开(
feature_flagsDefault + 测试同步);语义改为「快速记录入口」(设置页文案更新);后端命令准入保留(减面不减安全)。
- Rust:cargo test 新增 5 测(碎片升笔记 文本/图片搬运/图片缺失降级/碎片不存在 + flashcard 幂等判据)全绿;cargo clippy 零新增警告;cargo check 通过。
- 前端:
tsc --noEmit零错误;vitest 67 通过(新增 10 测:routeReason 人话归因 5 + inbox 预填/预览 5 + jsdom 组件测试 收件箱状态机 4(捕获→升笔记→移除/升卡幂等/删除二次确认/空态)+ ⓘ 弹层 4(四区齐全/改判契约/生成闪卡/ESC);测试基建:jsdom+@testing-library/react+ vitest include 扩展.tsx,组件测试按文件@vitest-environment jsdom切换环境);npm run build通过。 - 待真机验收:种子数据过 捕获→升级→编辑→归组→闪卡 全链(验收标准 1-4 走查)。
- ⓘ 弹层定位用视口 fixed 锚定(最初设计为侧栏内 absolute;fixed 简化背板关闭逻辑,视觉等价)。
noteTree.ts被三栏取代后删除(含单测)——v0.11.5 树形合并是"展开组必看笔记"的过渡形态,三栏下组行只过滤、列表常驻,树无消费方(YAGNI);如后续需要"组内速览"再以独立视图恢复。- 收件箱碎片卡未逐个显示所属组名(Fragment 契约不含 name;补计需要额外 join——YAGNI,升笔记/升卡时组选择已可见)。
- HIGH:
promote_fragment_to_note原实现"伪事务"——with_conn 只给&Connection无法开事务,rusqlite 默认 autocommit 使建笔记/删碎片各自提交,④ 失败留"笔记已建/碎片未删"半态;改为直接锁 +conn.transaction()+commit()(与 versioned_save 既有模式一致)。 - MED:ⓘ 弹层跨组 state 串组——组 A 改判/结算/明细选择(未确认)复用进组 B(key 缺失);修复
key={group.id}重置表单态 + GroupSidebar 组件测试(切换组判类回到目标组 kind)。 - MED:升笔记 onPromoted 只调
load("")不同步清keyword/tagFilter——防抖 effect 用旧搜索词重新覆盖列表(新笔记"被搜索态淹没");修复同步清空三过滤态。 - LOW:捕获/弹层变更后双 load(显式 load + onChanged→refreshToken 再 load)→ 统一由 refreshToken 驱动;升卡成功
setErr重复;升笔记标题输入补maxLength=100(与后端 TITLE_MAX_CHARS 同口径);inbox.ts截断改按码点切(防切半代理对残字);文档"視口"错字。 - 观察项(登记不修):archived 碎片可升笔记(与 delete/update 旧命令行为一致);升卡成功静默(幂等语义,验收允许);编辑态+弹层同开时 ESC 双触发(边缘场景);db 层文件名沿用碎片名(同毫秒+4hex 后缀碰撞概率 1/65536,单笔记同目录冲突极低)。
- 验证:cargo check/clippy 通过、promote 4 测全绿;tsc 零错误、vitest 83 通过(新增 GroupSidebar 2 测:组行单击仅过滤 + 弹层串组重置)、build 通过。
- 侧栏组行单击=仅过滤(中部列表切换,无展开动作);⚠ 待确认组淡橙描边小字显示;ⓘ 弹层四区齐全,明细默认折叠。
- 快速记录捕获 → 收件箱计数 +1;升笔记(轻确认)→ 右侧自动打开新笔记、碎片从收件箱移除、新笔记在「全部笔记」可见;升卡幂等可重复触发;删除有二次确认;空态文案正确。
- 「✍ 新建」无 prompt,直接进入编辑态,落未归组;搜索/标签激活时中部列表原位切换为搜索结果(布局不变)。
- ⓘ 弹层内改判后组行小字变「已改判」且路由记忆生效(再次归组走新偏好);弹层内生成闪卡/结算/复习本组/周契约可用。
- 全量回归:
cargo test(含新命令单测)/cargo clippy/npx tsc --noEmit/npx vitest run/npm run build全绿;前端组件测试覆盖收件箱状态机(捕获→升笔记→移除)与 ⓘ 弹层交互。
- note-design-philosophy.md(活沉淀:笔记=证据到知识过渡态)
- requirements-pool:REQ-195
198(组容器/路由可见可改·本版重释)、REQ-199201(内容分型/周契约/feed 消费闭环·本版补升级出口) - v0.11.md(v0.11.5 树形合并为本版三栏重构的前身)· v0.12.0.md · v0.12.1.md
- 市场调研:捕获收件箱模式(MindWiki 横评)· 自动组织透明性(Gmail/Apple Photos)· 中文音视频笔记横评(听悟/讯飞/Ai好记)