Skip to content

Latest commit

 

History

History
535 lines (365 loc) · 53.3 KB

open-learning-runtime-roadmap.md

File metadata and controls

535 lines (365 loc) · 53.3 KB

Repeaty 开发进度与 v1.0 发布准备

  • 文档版本:0.26(2026-10-20)
  • 代码基线:PR #31 / #32 已合并;0.26.0 包含自适应阅读、混合学习与用户追加授权的收尾项
  • 维护方式:一名个人开发者;不把外部贡献计入交付所需人力
  • 近期目标:完成最后两项并冻结功能,只做 v1.0.0 发布准备与修复
  • 范围约束:旧长期候选不再自动推进,新功能需重新获得用户明确授权

0. 目标与执行方式

Repeaty 已经可以制卡、复习、备份,并提供静态、后端和桌面三个版本。LeetCode 的作答记录、恢复、登录验证和历史读取已完成。Anki 基础导入、重复导入更新与文本 / Markdown 摘录制卡已完成,MCP 草稿支持本机保存、跨重启编辑与确认;数值题仍然暂缓。

近期流程是:

笔记 / 卡片 → 一次练习 → 提交答案 → 评估结果 → 用户确认评分 → FSRS 安排复习

来源材料、片段提取和阅读队列在有实际需求时逐步加入,长期形成:

来源 → 片段 → 学习活动 → 作答 → 评估 → 复习记录 → 下次学习

自适应阅读与混合学习之后,用户明确追加了 2.5 中的收尾范围。这批完成后不再从长期列表继续挑选新功能,只修复、验证、整理文档与准备正式发布。v1.0 的具体门槛见 发布清单。

1. 当前基线与保留范围

1.1 已实现,后续继续维护

能力 当前实现
前端 Vue 3 + TypeScript + Vite,三个版本复用界面
传统卡片 正反面、双向、挖空;一条笔记可以生成多张独立复习的卡片
内容 Markdown、代码块、KaTeX 公式、图片、音频;支持长文本和附件
复习 ts-fsrs;四档评分、每卡组目标记忆率和每日额度、撤销、暂停、暂缓、顽固卡
整理与练习 标签、组合搜索、批量操作;专项练习可选择是否更新复习进度
数据 分记录存储、增量检查点;流式 .repeaty 备份、旧版 JSON 恢复、CSV / TSV 导入
入门与语言 首次使用自动添加入门卡组;English / 中文(简体)
应用插件 纯前端插件、本地插件;显示题目 / 显示答案,可选编辑器与设置
LeetCode 桌面内置本地插件,中国站默认、可切换国际站;支持判题及手动 / 自动评分建议
工程 已有单元、浏览器、服务端与桌面原生测试,三平台安装包构建、GitHub Pages CI 和分支保护
许可证 MIT

已有能力无需作为新项目重新开发。新增练习类型必须继续支持双语、备份、媒体和版本隔离。

实现入口:数据模型、调度、工作空间操作、插件接口、评估摘要。现有使用边界见 README、插件文档 和 桌面说明。

1.2 三个版本继续保留

项目 纯前端版 带后端版 桌面版
存储 浏览器 IndexedDB 每账户独立 SQLite 默认本机 IndexedDB;可切换上游账户库
账户 无 已有用户名、密码与会话 本地无需账户;连接上游时登录
离线 支持 需要连接服务 本地模式支持
纯前端插件 支持 支持 支持
本地插件 不支持 不支持 支持
内置 LeetCode 不包含 不包含 本机访问,凭据留在本机

新增通用能力应适用于三个版本。本地进程、原生文件接口和本地 MCP 等能力仅在桌面提供,不把它们变成基础复习的依赖。纯前端产物继续不包含账户客户端、Tauri 和本地插件代码。

开源后端继续负责账户、学习数据和媒体存储,不添加服务端插件执行系统。桌面使用上游库时,本地插件仍在本机运行,凭据不得混入学习记录或发给上游。

私有仓库的 dev 分支独立维护 IAM、个人部署和受信任的服务端 LeetCode 接入;本计划不把这些功能移入开源版本,也不改变私有服务的部署。

1.3 本轮不做的架构调整

  • 保留 Vue,不迁移 React。
  • 保留 ts-fsrs,不为接入新题型或 MCP 先迁移 Rust 调度核心。
  • 保留当前仓库与目录,不先建立新的 monorepo。
  • 保留 MIT、现有账户边界和三个版本的存储方式。
  • 桌面 SQLite、Rust / WASM 共享核心、FSRS 新算法和个人参数拟合列为独立评估项;近期核心功能不依赖它们。

2. 优先级与个人开发节奏

2.1 已完成的核心

  1. 保留现有 Note / Card 身份,补上练习会话、原始答案和独立评估记录。
  2. 保留每次 LeetCode 提交的代码、语言、提交编号、判题结果和错误状态。
  3. 将评估结果、评分建议与最终复习评分分开;失败重试、撤销和恢复不重复安排复习。
  4. 适配现有 LeetCode 插件,继续维护当前判题流程。

数值题尚未确定需求,暂缓开发与设计,不作为验证数据模型的前置条件。先只做 LeetCode 实际需要的接口。每增加一个类型,才扩展它实际需要的协议;不提前建设六类插件框架。

2.2 已合并:渐进学习核心流程

本阶段在 feat/source-details 一次完成核心流程与整体验收,PR #31 已于 2026-10-20 合并到 main。0.24.0 安装包尚未单独发布。开发中分批 commit、push,不为子功能单独开 PR。

  • 原文与摘录的标题、来源链接编辑。
  • 材料批量整理:选择本页或全部筛选结果,统一设置优先级、阅读日期、归档与恢复,失败整批回滚。
  • 多级摘录:从摘录继续提取,逐级查看出处,保留各层正文、位置、安排与卡片;删除中间材料后其余内容仍可用。
  • 阅读安排撤销:撤销最近一次单篇或批量安排,保留后续的正文信息、阅读位置和卡片评分;已变化的目标不能被旧操作覆盖。
  • 日常入口:学习概览展示待阅读材料,能够进入一轮阅读,并衔接正常卡片复习。
  • 整体验收:三个版本、旧库升级、层级校验、原文定位、失败恢复、撤销、重启、备份、多媒体 / 长文本与原生桌面验证。

本地验收通过 276 项单元测试、137 项浏览器测试(静态 59、桌面 44、后端 34)与 43 项 Rust 测试;原生 WebKit / Tauri 验证多级出处、整批撤销、每日轮次和实际退出重开。包含旧库 / 备份、128 MiB 媒体与长文本回归;格式、类型、Schema、Clippy 与三个版本构建通过。

PDF / 网页采集、Obsidian、自适应阅读算法继续保留在长期计划。本阶段复用现有 Source、不可变快照与 FSRS,不增加独立 Fragment 平台。

Anki 基础导入、重复导入更新与材料摘录制卡已分别在 0.9.0、0.10.0、0.11.0 完成。文本 / Markdown 的快照、摘录、制卡、回看、独立导出和备份已适用于三个版本。

0.12.0 已发布桌面本地库的三个只读查询。0.13.0 在此基础上加入主动分享摘录、接收草稿、逐条编辑确认保存,支持问答、双向和挖空卡并保留出处。0.14.0 将草稿、用户保存的编辑与附件存入本地辅助表,跨重启恢复;切上游时隐藏,返回本地后继续。接收不产生正式学习记录,确认生成卡片与消费草稿使用同一事务。授权和重试表仍留在内存,草稿不进入备份。复用现有编辑器,不增加独立片段树或模型服务。见 ADR 004 与 MCP 文档。

0.15.0 已实现阅读位置:原文与 Markdown 预览自动保存位置和显示方式,材料列表提供「继续阅读」,支持重启、窄屏与完整备份恢复。见 ADR 005。

0.16.0 已发布待阅读、稍后阅读、已归档和全部材料。按本机日期安排,到期自动可读;归档保留原文、位置和关联卡片,可恢复为今天待阅读。安排与当前位置在同一事务中保存,复用三版本的记录、备份与操作前快照。它不改变 FSRS,不引入独立 ReadingTopic。见 ADR 006。

0.17.0 已发布高、普通、低阅读优先级,默认普通。待阅读先按优先级、再按日期排列;未来和归档材料不会因此提前出现,更改时保留原安排和位置。沿用 Source、事务、操作前快照和完整备份,不改变 FSRS;已完成三版本、迁移、失败重试和桌面重启验收。见 ADR 007。

0.18.0 已发布临时阅读轮次:开始时固定待阅读顺序,下一篇先保存位置,延后与归档后继续,最后显示本轮结束。每份快照本轮至多出现一次,调整优先级留到下一轮;失效快照自动跳过。失败不推进,离开页面或退出应用即结束轮次,材料位置与安排保留。已完成三版本、服务故障、迟到响应、备份及原生重启验收,不改变学习数据格式或 FSRS。见 ADR 008。

渐进阅读参考 Foliole,已核对阅读操作、选区提取、优先级和队列规则;参考笔记记录对应源码与适用范围。0.19.0 已发布「原文 → 一级摘录 → 卡片」:保存选区不需要卡组,摘录有独立正文、位置、日期与优先级,能回看实际出处或用整段 / 局部制卡。删除原文后摘录与卡片仍保留;完整备份、快照和旧库升级保留关联与进度。沿用 Source 与现有编辑器,不建 Fragment 表。已完成三版本、原生重启、配额 / 服务故障、重复 Unicode 与备份恢复,见 ADR 009。0.24.0 的多级提取沿用 Source;父级设置继承、自适应间隔与混合队列继续长期评估。

0.20.0 已发布「本篇摘录」:按原文位置分页列出摘录、正文预览与实际关联卡片数。支持精确定位选区、打开独立阅读器、同范围已有摘录提示;定位不依靠文本搜索。轮次中使用弹窗,保留原篇与顺序;普通导航先保存位置,失败不跳转。列表从当前库生成,沿用 0.19.0 的数据与 API 版本。见 ADR 010。

0.21.0 已发布「稍后阅读」的明天、3 天后、1 周后的快捷日期,显示实际日期并保留手动输入。点选只更新表单,保存才提交;取消保留原安排。原文和独立摘录共用现有位置与日期事务,保存成功才继续本轮下一篇,失败保留日期和当前篇。不新增数据字段或后端接口,不改变卡片 FSRS,也不实现自动延长间隔。验收覆盖三版本、双语窄屏、键盘、日历边界、失败重试、重启与备份。

0.22.0 已发布「读过,安排下次」:每篇原文与摘录分别保存上次间隔,按 1、3、7、14、30 天递增,之后保持 30 天。确认前显示实际日期,取消与普通阅读不推进;手动日期、归档及优先级保留阶梯。重置后下次从 1 天开始,当前日期保持不变。位置和安排仍在一个事务中保存,成功后才继续轮次,失败可重试。旧库不补写间隔;快照与完整备份保留新字段,见 ADR 011。

0.23.0 已发布材料类型、阅读优先级与标题组合筛选,四个队列的数量同步更新。「阅读筛选结果」包含全部分页中符合条件的待阅读材料,未来安排与归档继续排除;保留不受筛选影响的全量入口。本轮固定身份与顺序,「再读一轮」重新应用原条件;失败不启动轮次,离开页面不恢复。筛选是临时界面状态,沿用 0.22.0 数据与 API 格式。见 阅读轮次决定。

0.24.0 已补齐本阶段核心并随 PR #31 合并:材料信息编辑、跨页批量安排、最多 32 层摘录及出处路径、最近一次单篇 / 整批安排撤销、首页今日阅读与卡片复习入口。安排失败整批回滚,撤销保留之后的信息、位置和评分;刷新、退出、切库或恢复后清除临时撤销。多级关系沿用 Source 与独立正文,采用 Library / JSON v12、IndexedDB v15、SQLite v9、API v10 和 .repeaty v9,旧库与备份保留原记录。见 ADR 012。

Anki 原始字段、revlog 保留和导入桥接仍按需求单独评估,Repeaty → Anki 导出不在当前计划内。

LeetCode 根据真实使用反馈维护。第一批不切换判题来源,也不接入 Judge0;通用编程裁判只有重新确认需求后才立项。

2.3 已合并:MCP 客户端接入

PR #32 已合并 Codex、Claude Code 和 Claude Desktop 接入,复用已有五个工具、选区分享和草稿确认。PR 阶段质量检查与三平台构建 / stdio 验证通过。

  • 安装程序提供无界面 stdio 入口,代理运行中应用的本机接口,不直接读写数据库。
  • 设置页生成三种客户端配置,保留临时 HTTP 配置;路径保留空格和 Unicode,配置不包含访问密钥。
  • 关闭 / 开启、窗口重载与应用重启后可复用 stdio 配置;MCP 开关和摘录分享仍由用户主动开启,不恢复授权。
  • 真实程序验证离线发现、重连、长文本草稿与原子确认;三平台 CI 验证 stdio,保留静态 / 后端产物隔离。

本阶段不增加模型 API 配置或应用内生成,不接入上游账户库,不实现持久授权。数据、API 与备份格式不变。见 ADR 013 与 客户端用法。

本地验收通过 276 项单元测试(另 1 项跳过)、138 项浏览器测试(静态 59、桌面 45、后端 34)、16 项桌面 Rust 测试与 Clippy。真实 release 程序通过无图形会话 stdio 测试;Linux WebKit / Tauri 跑通查询、端口轮换、切库、分享、三类长文本草稿、重试、确认和实际退出重开。生成配置经本机 Codex 与 Claude Code 读取验证,不调用模型,也不修改用户客户端配置;Claude Desktop 的界面未在本机运行,三平台 stdio 由 CI 验证。

2.4 最后一批功能:自适应阅读与混合学习

在 feat/adaptive-mixed-study 实现,分批 commit、push,功能、测试、文档与发布准备集中在一个 PR。

  • 阅读反馈与实际经过天数生成有界间隔,保存前预览,按篇保留状态;兼容原固定阶梯。
  • 按可选比例穿插 FSRS 卡片与有限阅读轮次,沿用额度、插件与保存操作。
  • 分别撤销评分 / 阅读安排,保留另一类已经提交的记录,重启保留学习数据。
  • Library / JSON v13、IndexedDB v16、SQLite v10、API v11、.repeaty v10 迁移与备份;旧库不补写理解反馈。
  • 本地完成三版本、真实桌面、旧库、故障与完整媒体回归;协调手动安排与后台位置保存,补充阅读保存重试验证。
  • 合并最后一批功能;之后只进行 v1.0 发布准备与修复。

设计与边界见 ADR 014。当前开发号 0.26.0 不代表已经发布 v1.0.0。

本地验收通过 291 项单元测试(另 1 项跳过)、147 项浏览器测试(静态 62、桌面 48、账户 37)与 49 项 Rust 测试。Linux 真实桌面跑通自适应反馈、混合轮次、分别撤销与实际退出重开。格式、类型、Schema、Clippy、构建与静态产物隔离通过;合并后的 CI / Pages 和 Windows / macOS 人工验收仍需按发布清单检查。

2.5 用户追加授权的发布收尾

继续更新 PR #33,不为各个小改动新开 PR;学习数据、API 与备份格式仍沿用 0.26.0。

  • 中文标点紧邻闭合加粗的兼容修复;按语言标记高亮代码。
  • 评分性能分析与可复现的真实界面基准,减少题面重建、历史扫描和评分后的元数据等待。
  • 统一设置、插件设置和按级别选择顶部弹出 / 页内通知;信息自动关闭,警告与错误手动关闭。
  • 所有版本内置答题历史圆球,显示长度与翻面时机可配置。
  • 复习中按 E 或从菜单编辑,保存后重新作答;进度按卡片 ID 保留,混合学习沿用原比例与撤销。
  • 卡组显示今日可学的新卡、学习中和到期复习数量,以及未学、稍后到期和额度限制。
  • 无需 MCP 的 AI 制卡 skill,通过复制 / 下载说明生成 CSV,再预览导入;静态版离线可读取说明。
  • 核验本批 PR CI 并合并;之后继续功能冻结与正式发布准备。

本地 299 项单元测试(另 1 项跳过)、158 项浏览器测试(静态 68、桌面 50、账户 40)通过。Linux 原生程序验证编辑、重新作答、代码高亮、进度保留、评分 / 撤销、历史设置重启和实际 skill 文件导出。性能结果见 记录。Windows / macOS 的人工 GUI 验收仍在 v1.0 发布清单中。

2.6 功能冻结与范围外候选

以下旧长期列表仅保留作历史记录,不属于 v1.0 的后续开发任务,也不在发布后自动恢复执行。

数值题暂缓,待需求明确后再决定是否开发。Judge0、Anki 导入兼容与历史保留、可编辑外部来源、持久授权、应用内模型 API、SymPy、Obsidian、公开扩展 SDK 按需求逐项评估。这些项目不纳入 v1.0,不再据此启动功能开发。

暂不计划:商业云服务、订阅支付、多人协作、自动跨端同步、原生手机应用、知识图谱研究、新记忆算法、插件市场、完整 Anki 动态模板兼容。

3. 架构:从现有代码逐步扩展

3.1 继续使用的实现

模块 近期做法
界面与应用逻辑 Vue + TypeScript;从 useLibrary 提取需要复用的应用操作,避免整体重写
领域校验 延续 Zod 模型;需要服务端校验的数据通过现有脚本导出 JSON Schema
调度 在 ts-fsrs 外封装评分、预览和状态更新,不改变既有评分结果
本地存储 扩展 IndexedDB 的记录、迁移、检查点和附件接口
服务端存储 扩展 Rust / Axum 的账户库、允许的记录集合与事务校验
桌面 Tauri 2;复用本地插件注册表、IPC、上游传输与原生备份接口
暂缓的数值评估 需求未定,暂不开发,不增加依赖
编程评估 复用现有 LeetCode 本地插件与编辑器;Judge0 长期另议
数学展示 复用 KaTeX;符号计算作为后续可选本地能力

Monaco、Python 运行时和新的 Rust crate 都按真实需求引入,不作为第一批基础设施。

3.2 目标调用边界

  • UI 和插件通过应用操作保存作答、请求评估、确认评分。
  • 裁判输出结果与依据;只有应用操作负责决定是否生成复习记录、计算调度并提交事务。
  • 前端插件与应用同处一个 JavaScript 环境,本地插件也是可信代码;这些边界是接口约定,不构成安全沙箱。
  • 服务端保持账户隔离、Schema 校验与 revision 冲突检查;不把客户端提供的字段视为权限证明。
  • 远端数据变更或账户 / endpoint 切换后,旧请求不得写入新的工作空间。

当前调度在客户端执行,服务端保存经校验的数据。应用层评分接口不应被描述成已有的服务端权威判题;若以后需要这种能力,另立设计与迁移方案。

3.3 未来能力在哪些版本运行

计划能力 纯前端版 带后端版网页 桌面版
LeetCode 练习记录、自评 可保留导入记录,不执行插件 可存储记录,不执行插件 本地判题,记录保存至所选学习库
Judge0、SymPy 暂不提供内置接入 暂不提供内置接入 可选本地插件
Anki 文件导入 优先验证,受浏览器资源限制 前端处理,账户库保存 复用导入器与原生文件能力
材料 / 摘录、阅读队列 材料、摘录、位置与日期队列 材料、摘录、位置与日期队列 材料、摘录、位置与日期队列
本地 MCP Server 不提供 本计划不增加远程 MCP 服务 本地查询、摘录分享与草稿确认
Obsidian 桥接 不要求具备本机连接器 不在服务端安装连接器 长期通过本机接口接入

表中的长期项不代表已经实现。某版本暂不支持执行的题型仍应保留题目与记录,可以备份;不能悄悄当作普通卡片判题。

4. 数据模型与兼容规则

4.1 身份沿用现有模型

  • Deck 继续负责分组与复习配置。
  • Note 继续保存共享内容、标签、媒体和插件数据。
  • Card 继续作为最小独立调度单位,保留现有 ID 与 variant。双向笔记和不同挖空编号继续各自复习。
  • Activity 近期作为面向题型的视图 / 接口概念,映射到已有 Card,不立即新建一套重复的内容表。
  • 修改共享题面不自动重置进度;新增或删除卡片变体沿用现有确认规则。
  • 编辑后的题面不能改变旧作答的含义;Attempt 需关联内容版本,并保存可回看的必要题面与评估配置快照。

4.2 近期只新增必要的记录

概念 用途与需要验证的字段
PracticeRun 一次练习某张卡片;关联 cardId、模式、开始 / 结束时间、是否更新进度、最终复习记录
Attempt 一次提交;关联练习、题面版本、答案版本、原始答案、用时、提示使用情况
Evaluation 一次评估;关联 Attempt、请求 ID、裁判与版本、执行状态、结果、证据和规则配置
ReviewEvent 一次已确认的复习反馈;沿用现有 Review 关联,保存最终评分、评分来源、候选评分及规则版本
ReviewRetraction 对已提交评分的撤销;关联原记录,保留审计信息,恢复原调度及相关副作用
ScheduleCheckpoint 迁移时保存现有调度状态与已知配置;历史不完整时作为后续重放起点

PracticeRun 与现有批量选卡的 StudySession 含义不同:一个学习会话可以包含多次单卡练习,一次单卡练习可以有多次提交和评估。字段与命名在第一批实现中验证,不在此冻结完整 SDK。

表中列的是需要表达的含义,不要求每个概念各建一张新表。优先扩展现有 Review 和检查点;只为需要独立查询、保留或重试的数据新增记录集合。

原始代码与答案不塞入 plugin.data 或现有 Assessment 摘要;大内容按独立记录 / 资源保存,定义大小上限并纳入备份。摘要可继续用于旧界面展示。

4.3 一次练习何时更新 FSRS

  1. 每次提交保存一个 Attempt,可以对应多个 Evaluation。
  2. 评估完成后展示结果和可选评分建议,用户确认四档评分。
  3. 更新进度的练习最多提交一条最终 ReviewEvent;同一确认重试不能重复评分。
  4. 只练习模式保存作答与评估,但不生成调度反馈,不消耗每日复习额度。
  5. 裁判不可用或结果未验证时,可以重试、退出,或明确选择人工评分;不自动记为“重来”。
  6. 原有 LeetCode 自动建议按尝试次数和用时计算,规则需可追踪;判题结果不直接等于某档 FSRS 评分。

结果至少区分 pass、fail、partial、unverified、unknown;执行状态另区分 pending、running、completed、failed、cancelled、expired。请求超时是执行失败,不能冒充答案错误。

人工自评题允许没有自动评估器。普通翻面复习不强制填写答案,也不为了凑齐记录额外增加操作。

4.4 异步评估与幂等

  • 请求绑定工作空间、练习、Attempt、题面 / 答案版本和幂等 ID。
  • 重试同一个请求不重复创建有效结果;同一个 ID 携带不同内容时拒绝。
  • 题面或答案已变更、练习已结束、用户已切库时,迟到结果不能覆盖当前结果或更新调度。
  • 请求具备超时与取消;重启后的未完成请求标记中断,不自动重新提交外部代码。
  • 评分提交携带工作空间 revision,评估记录、最终评分和调度更新保持一致。
  • 日志、题面快照和评估证据设置大小限制;账号 Cookie、API key 不进入题目、日志或备份。

4.5 撤销与调度历史

当前 undoReview 会删除最后一条 Review。第一批保留现有 Review 的撤销实现,并在练习记录中保留评分已撤销的状态。完整追加事件日志作为后续独立工作;如引入,必须与撤销记录一起实现。

  • 第一版继续只支持撤销最后一次有效评分;不提供任意编辑历史评分。
  • 当前撤销继续恢复调度、同笔记卡片的自动暂缓和顽固卡标记等副作用;提交证据独立保存。后续事件日志再采用追加关联事件。
  • 队列、额度和统计按有效评分计算,不能把已撤销事件再次计入。
  • 新记录保存库版本、算法版本、参数 / 目标记忆率、计算时间和前后调度状态;配置快照或其可解析引用必须可备份。
  • 旧库建立迁移检查点,不为缺失的答案、用时或裁判结果编造历史。
  • 保证迁移后的受支持事件可以校验和重放;不承诺缺少完整历史的旧库可以从零重建。

追加历史是评分审计约定,不等于永不允许删除个人数据。删除笔记 / 卡组、恢复备份和清理记录需明确级联范围;迁移前检查点用于恢复,不能意外重新激活已删除数据。

4.6 各种版本号分开处理

0.8.0 已将数据模型从 library v4 升至 v5、IndexedDB 从 5 升至 6、后端 API 从 v2 升至 v3、SQLite schema 从 1 升至 2、.repeaty 容器从 1 升至 2。它们用途不同,不用一个版本号替代全部兼容判断。0.8.1 的提交恢复与独立历史沿用这些格式。0.11.0 的材料制卡再升级为 Library v6、IndexedDB v8、API v4、SQLite v3、.repeaty v3;0.14.0 将 IndexedDB 升至 v9,加入独立草稿表。0.15.0 的阅读位置使用 Library v7、IndexedDB v10、API v5、SQLite v4、.repeaty v4 和 JSON v7;0.16.0 的阅读队列使用 Library v8、IndexedDB v11、API v6、SQLite v5、.repeaty v5 和 JSON v8;0.17.0 的手动阅读优先级使用 Library v9、IndexedDB v12、API v7、SQLite v6、.repeaty v6 和 JSON v9;0.18.0 的临时轮次沿用这些格式,不持久化轮次索引。0.19.0 的独立摘录使用 Library v10、IndexedDB v13、API v8、SQLite v7、.repeaty v7 和 JSON v10,防止旧客户端写回时丢失摘录类型或出处;现有记录表继续使用。0.20.0 的列表、卡片计数与重复选区匹配为派生视图,0.21.0 的快捷日期复用原安排操作,均沿用这些格式。0.22.0 的逐篇递增间隔使用 Library v11、IndexedDB v14、API v9、SQLite v8、.repeaty v8 和 JSON v11,仍沿用记录表;旧库不补写阶梯。旧备份、检查点和待确认草稿继续保留;旧客户端通过版本门槛拒绝写回,避免丢失新字段。0.23.0 的材料筛选与轮次范围只在页面中保留,沿用这些格式。0.24.0 为多级出处语义升级至 Library / JSON v12、IndexedDB v15、API v10、SQLite v9 和 .repeaty v9;批量安排、撤销与日常入口复用既有提交接口。

增加记录集合时需同时检查:

  • Zod 模型、IndexedDB 迁移、记录索引与增量检查点。
  • 服务端 STORES、JSON Schema、外键 / 事务和账户隔离。
  • 账户库客户端、桌面上游传输和工作空间切换。
  • .repeaty 清单、分片、恢复校验、旧版 JSON 导入和媒体回收。
  • 新客户端连接旧服务、旧客户端读取新库的行为;不兼容时明确拒绝,不静默丢弃新增字段。

5. 功能拆分与验收

A. 近期:LeetCode 作答与复习记录

只完善已有 LeetCode 题型,继续由 LeetCode 官方判题,保留中国站 / 国际站、本机登录、手动评分和自动建议。

  • 按单卡练习保存多次提交,每次记录语言、代码、提交时间、正式编号与判题结果。

  • 提交前先持久化意图;响应丢失时保留未知状态,不自动重新提交。

  • 原始提交记录独立于临时编辑草稿和最终评分摘要,重启后可查看。

  • 用户确认评分时一次保存关联信息与调度;只练习保留记录,不改变进度或额度。

  • 撤销评分保留提交证据,记录评分已撤销;先沿用现有 Review 撤销方式,完整追加事件日志不作为第一批前置。

  • 记录随 .repeaty 和 JSON 备份往返,可保存在桌面本地库或上游账户库;Cookie 始终留在本机。

  • 未确认提交可手动关联已有编号,经本机核对后查询结果,不重发代码。

  • 独立历史入口支持题目、卡组、结果筛选与分页;插件不可用时仍可查看通用记录。

  • 保存登录信息后只读验证并显示账号;登录失效、网页验证、网络故障和限流分别提示,保留代码与待查询提交。

  • 提交正文按需读取,两处历史按页显示;保存状态避免重复校验未变化记录,备份分批读取完整代码。实现与基准见 性能记录。

此阶段已随 0.8.3 发布,继续收集真实账号和桌面使用反馈;数值题与其他裁判保持原排期。

完成条件: 同一题错答一次再通过 → 查看两次代码与判题详情 → 确认评分 → 重启仍可查看历史 → 撤销后进度与额度恢复但提交历史仍在。只练习再完成一轮,不产生复习评分。另验证判题离线、响应丢失、恢复查询、保存失败和账户 / endpoint 切换。

数值题尚未确定需求,暂缓,不在本阶段引入新的数值输入、容差规则或评估器。

B. 长期候选:通用编程题与 Judge0

  • 桌面本地插件配置 Judge0 地址,凭据仅本机保存,不增加 Repeaty 服务端插件路由。
  • 先支持一种语言和 stdin / stdout 题型;题目保存测试集、运行限制和明确的输出比较规则。
  • 管理提交与轮询,区分编译错误、WA、TLE、请求失败和中断。
  • 展示每次提交的结果、用时和评分建议,用户确认后才更新复习。
  • 第一版使用简单编辑器;函数入口适配、SQL、自定义 Checker 和 Monaco 按需求后续加入。

Judge0 负责运行代码;Repeaty 负责测试集、比较规则和结果解释。零测试用例不能返回通过。界面区分“通过提供的测试”与“官方 OJ Accepted”。

完成条件: 不同正确实现通过同一测试集;错误、超时和离线均有明确状态;重复轮询、重启和迟到结果不重复评分。未知代码只在配置了隔离措施的外部执行服务运行,Repeaty 不代用户部署公共裁判。

现有 LeetCode 使用网页接口,存在接口变化风险;继续作为可关闭的桌面功能维护,不能成为通用判题或核心复习的依赖。浏览器扩展导入本人提交结果仅作为远期备选,不替换当前应用插件定义。

C. Anki 基础导入与重复导入更新已完成

Anki 集成只规划 Anki → Repeaty。当前不考虑 Repeaty → Anki 导出;来源字段、历史保留和进度迁移仍按实际需求单独评估。

0.9.0 先交付已有题型的最小导入,三版本共用:

  • 读取真实 Anki 导出的旧版兼容包和新版压缩包。
  • 将标准两字段 Basic、双向、Cloze 转为本机笔记,按新卡导入图片与音频。
  • 确认前预览数量与内容,提供跳过 / 调整报告,取消不写库。
  • 用稳定 GUID 身份去重,保留已有编辑和进度;备份恢复后仍可去重。
  • 验证离线解析、失败重试、SQLite 账户库和原生 WebKit / Wasm。

原始笔记 ID 与 GUID 对应关系可下载报告,GUID 编码在笔记 ID 中。转换后的内容和媒体进入学习库;第一版不保存原始字段定义、HTML、模板或 revlog,请保留原 .apkg。实现边界与样例见 Anki 导入。

0.10.0 已完成重复导入更新:

  • 按 GUID 比较内容、类型、格式、标签及附件内容,默认保留已有笔记。
  • 展开两份内容与媒体,分页、逐条选择更新,并下载选择和卡片变化报告。
  • 保留相同变体的卡片 ID、FSRS 进度、状态和历史;新增变体从新卡开始。
  • 类型 / 挖空编号变化列出卡片增删及关联历史,重新选择后需重新确认。
  • 批量事务、失败重试、导入前快照;旧库变化时拒绝陈旧预览。

没有来源内容基线,差异不自动区分 Anki 修改和本地修改;不做自动合并,不删除文件之外的笔记。后续按独立小版本推进,不作为此次发布前置条件:

  1. 收集真实 Basic、双向、Cloze、多字段、LaTeX、媒体和带历史样例。
  2. 导入 Basic / Cloze 与媒体,保留来源 ID、GUID、字段、卡片变体和可取得的原始 revlog;不能转换的内容生成报告。
  3. 学习进度与内容导入分开选择。保留现有到期安排、从可用历史重建、按新卡导入的差异必须说明,原始间隔不能直接当作 FSRS 记忆状态。
  4. 若实际使用需要自动合并,另行设计来源内容基线与修改冲突规则;当前保持显式选择。
  5. 最后再考虑通过 AnkiConnect 从 Anki 单向导入 Repeaty,不做反向写入或双向实时同步。

旧版兼容包、现代压缩包、包含 / 不包含学习进度分别验收。复杂 HTML / JavaScript 模板、图片遮挡和完整调度语义不在近期兼容承诺内,导入内容不能执行任意脚本。

D. 材料与多级摘录;外部来源长期评估

0.11.0 已发布:

  • 粘贴文本或导入 UTF-8 文本 / Markdown,保存独立原文快照与可选链接。
  • 按原文位置选取摘录,以现有编辑器制作普通、双向或挖空笔记。
  • 复习显示答案后查看原文,定位并高亮摘录;查看不额外改变评分。
  • 元数据分记录存储,正文按需读取;重新导入不覆盖旧快照。
  • 原文可独立导出 / 删除,完整备份与操作前快照保留来源关联;三版本及旧库迁移验收。

0.19.0 已发布独立阅读摘录,复用 Source、独立正文和 origin 起止位置。可以先保存选区,单独安排阅读,再制作问答、双向或挖空卡;删除与备份保留既有进度。0.24.0 在原模型上支持多级摘录、逐级出处和中间节点删除,不引入 Fragment 表。外部编辑后的锚点恢复与来源版本合并保留为长期项:

  • 当前 Source 已保留标题、链接、独立正文和直接父级锚点;外部文件版本与锚点恢复按实际样例再设计。
  • 第一版保存用户选定内容的本地快照和原始链接,不要求重新打开网络或外部软件才能复习。
  • 区分来源快照与外部文件的最新版本,外部修改不会无提示改写已有题目。
  • 支持来源内容的独立删除与导出,说明哪些外部文件并未纳入备份。
  • 后续接入 Obsidian 前,先验证文件重命名、移动和局部编辑后的引用恢复。

完整编辑器、网页爬取与 PDF 标注后置。不要为后续来源系统提前拆掉现有笔记编辑器。

E. 已完成:MCP 与 Codex / Claude 接入

0.12.0 已完成运行时桥接与本地只读查询。原生 WebKit 已验证外部客户端通过 Rust 和 IPC Channel 查询 IndexedDB,不需要迁移存储或领域核心。首版有开启 / 关闭、临时 Bearer 密钥、作用域撤销、分页修订检查和超时,并覆盖三个版本的回归。

0.13.0 已实现选区授权与制卡草稿,复用 NoteEditor 和 saveExcerptNote;0.14.0 已发布独立草稿存储、未完成编辑与附件保存、作用域恢复及原子确认。外部客户端只能取得主动分享的一段摘录,并提交待确认草稿;草稿接收与重试不改变正式笔记、卡片或进度。应用在用户确认时检查作用域、来源位置和引用。0.25.0 在此基础上增加 stdio 代理与三种客户端配置;其他写入、持久授权和内置模型继续单独评估。

  • 只读首批:查询到期卡片、题目、练习历史与学习统计。
  • Source 的选区查询与草稿已接入;多级提取仍沿用 Source,独立 Fragment 不是前置条件。
  • 修改操作经应用服务校验,草稿在界面确认后提交;AI 无权直接修改调度或标记掌握。
  • MCP Server 与界面共用工作空间选择、权限、revision 和事务规则;禁止独立进程绕过应用逻辑直写主库。
  • 已采用桌面进程内的 Streamable HTTP 和应用服务桥接;数据仍在 WebView IndexedDB,rmcp 不直接读取学习库文件。传输选择及代价见 ADR 002。
  • 应用未运行时,stdio 可发现工具,查询返回不可用;正在保存 / 恢复时也返回不可用,窗口无响应时超时。未来若引入锁定与写入确认,也须校验对应状态;若必须迁移存储或领域核心,另立 ADR,重新评估成本。
  • 本机连接也要校验身份和库作用域;默认不开放全部文件,不把材料中的指令当作工具授权。
  • 切换账户或 endpoint 立即撤销旧作用域;第一版不开放上游账户库和远程 MCP 服务。

应用内接口使用 Streamable HTTP,Codex / Claude 通过安装程序的 stdio 模式访问;SDK 固定为 rmcp 3.5.1。内置模型配置、自动生成和学习建议分别立项;密钥存储与发送材料的范围需明确,密钥不进入学习库或备份。

完成条件: 外部客户端可以查询本地今日任务;可选写入仅生成待确认草稿,界面确认后才成为题目。拒绝访问、退出应用、切库和请求失败都不会修改进度。

F. 渐进阅读收尾;其余候选移出 v1.0

符号数学: SymPy 作为可选桌面本地能力。先支持受限语法与明确的变量定义域,再扩展等价检查。不能证明时返回 unverified;随机数值抽查不能冒充符号证明。禁止直接对任意输入调用不安全解析,需限制语法、进程权限、时间和内存;Python 分发、升级和三平台打包成本单独评估。

Obsidian: 仅在 Source / Fragment 接口稳定后开发连接器。通过官方 API 获取用户选区,保存内容快照与返回链接;结合 vault、路径、块 / 标题锚点和 hash 重定位。默认不修改原文件;写入块 ID 或 frontmatter 前展示具体变化并确认。Repeaty 不依赖 Obsidian 才能运行。

渐进阅读: 0.15.0 已实现文本 / Markdown 的保存位置与继续阅读;0.16.0 已发布日期队列、延后与归档,安排随当前库、快照和备份保留。队列按日期运行,与 FSRS 独立;没读完不产生“重来”评分。0.17.0 已发布手动优先级,0.18.0 已发布有限阅读轮次与下一篇;0.19.0 已发布独立一级摘录,0.20.0 已实现原文内的摘录列表与定位,参考 Foliole 的阅读与提取流程。0.21.0 已发布手动阅读间隔快捷选项;0.22.0 已发布固定阶梯的递增间隔;0.23.0 已发布材料筛选与筛选阅读轮次;0.24.0 已合并材料信息编辑、批量整理、多级提取、撤销与日常入口。0.26.0 收尾自适应间隔与混合学习;ReadingTopic、PDF 与复杂网页布局不纳入 v1.0。

这三项可分别延期或取消,不捆绑成一个发布条件。

G. 不纳入 v1.0:扩展 SDK 与可替换核心

继续使用现有纯前端 / 本地插件清单,先验证现有 LeetCode 的完整流程;第二种评估器有实际需求时再加入。第三方模块依旧按部署安装,新增原生模块需要重编译桌面。

至少两种实际评估器稳定后,再整理 manifest、apiVersion、数据迁移、错误码、超时和契约测试。接口可区分题型、展示、评估和来源导入,但不一次实现所有扩展点。

未知、禁用或版本不匹配的插件继续保留数据和备份,不执行,也不占用复习额度。需要公开 SDK 时再写独立示例仓库;市场、在线安装和自动更新不纳入本计划。

未来采用进程、MCP 或 JSON-RPC 只代表调用隔离;没有操作系统强制措施时不能宣称具备安全沙箱。第三方代码不得获得主数据库接口,且宿主需限制其可用操作。

桌面 SQLite、fsrs-rs、FSRS 新版本与参数拟合单独做实验,具备跨版本迁移、调度差异样例和浏览器兼容方案后再决定是否替换。SchedulerAdapter 先作为内部接口,不开放任意插件控制调度。

6. 完成状态与发布顺序

阶段 状态 范围
基础卡片与数据 已完成 三个版本、FSRS、媒体、备份与插件
LeetCode 已完成 提交证据、判题、恢复、评分与独立历史
Anki 与材料 已完成 基础导入、选择性更新、材料与多级摘录
MCP 已合并,0.25.0 本地查询、持久草稿、Codex / Claude
阅读与复习收尾 当前最后一批,0.26.0 自适应、混合学习与 2.5 中的授权收尾
v1.0 准备 功能冻结后执行 回归、迁移、文档、安装包、已知限制与发布

先完成最后一批并通过检查,再冻结功能。之后按 v1.0 清单推进,不新增产品功能,不用长期候选填充下一个版本。缺陷、数据损坏与账户隔离问题优先修复;未核验的发布项目保持未完成。

7. 第一批任务与依赖

M0 的决定见 LeetCode 练习与提交记录。M1 首批实现仅包含现有 LeetCode 的记录、历史、评分和备份;数值题继续暂缓。

以下是已完成的 LeetCode 核心实施顺序。E 的本机制卡草稿持久化已发布,2.2 的渐进学习核心随 PR #31 合并;当前阅读与授权收尾见 2.4 / 2.5,之后只做 v1.0 发布准备。

  1. 记录设计决定与样例。 确定 Card 身份、PracticeRun 与 StudySession 的区别、评分 / 撤销规则、旧库检查点和记录容量。
  2. 补模型与迁移。 定义最小 Zod / JSON Schema,扩展 IndexedDB、服务端账户库、备份格式与旧版本拒绝策略。
  3. 补应用操作。 保存提交、接收评估、确认评分、撤销与幂等;复用现有 revision 冲突处理,界面不自行拼装调度状态。
  4. 接入 LeetCode 记录。 复用现有 Vue 组件和本地调用,提交前后保存记录并提供历史查看。
  5. 关联评分与恢复。 确认评分关联本轮练习,撤销后保留提交;旧记录只展示已知摘要,不编造代码。
  6. 验证与发布。 三版本完整流程、旧库 / 备份往返、原生桌面与静态产物隔离通过后发布小版本。

对应依赖为:设计 → 模型 / 迁移 → 应用操作 → 题型适配 → 验证 / 发布。不把这些任务标为彼此独立,不要求一个人并行维护十个 Issue。

8. 仓库与提交方式

沿用现有目录:

  • src/core:模型、纯领域函数、调度、存储与备份。
  • src/composables:工作空间状态;可复用操作逐步提取,减少对 Vue 生命周期的依赖。
  • src/plugins 与 examples/plugins:题型、展示和评估适配。
  • src/backend 与 src/platform:账户库客户端、各版本存储选择。
  • server:账户服务、SQLite 持久化、Schema 与事务校验,不加载插件。
  • src-tauri 与 crates/leetcode-local:桌面能力、原生传输与现有本地插件。
  • tests、scripts、.github/workflows:复用现有测试、性能基准和发布流程。
  • docs:ADR、兼容说明和必要的接口文档;有确定接口时再拆 PROTOCOL 或 SDK 文档。

不要为了未来模块先搬目录。只有代码复用和依赖关系已经需要时,才新增公共包或 crate。

每批围绕一个可检查的变化 commit & push,例如“新增记录与兼容”“接入 LeetCode 历史”“补失败恢复”。迁移与对应恢复逻辑一起合并;走现有 PR / CI 和分支保护,不强推 main。计划变更不自动部署私有服务。

9. 验证与发布要求

9.1 核心功能必须验证

  • 旧 v4 库升级保留 Note / Card ID、双向和挖空变体、到期时间、附件与既有评分。
  • 普通翻面复习、只练习、每日额度、暂停 / 暂缓、顽固卡和最后一次撤销行为保持一致。
  • 重复提交、同 ID 不同内容、评估超时、乱序返回与评分失败不会重复更新调度。
  • 页面刷新、应用退出、账户切换、endpoint 切换和 revision 冲突不会把记录写错库。
  • 静态版、账户版和桌面本地 / 上游模式中的新记录可保存、重开与备份恢复。
  • .repeaty 往返覆盖新记录、旧记录、长文本、公式、图片和音频;缺失附件、格式不兼容和取消导入不能破坏现有库。
  • 插件关闭或不可用时,数据仍可保留与导出;静态构建不携带本地能力。
  • 新交互的中英文、键盘操作、窄屏和正文可读性满足既有使用方式。

9.2 按改动选择检查

文档改动检查格式、链接与代码事实,不为它新增功能测试。核心或持久化变更运行相应单元测试、构建与版本端到端测试;服务端或原生变更补 Rust 检查。合并继续满足仓库已有的全部必需 CI。

沿用 npm run check、npm run check:server、npm run test:e2e:desktop 和桌面构建 / 原生测试流程。安装包与升级恢复随涉及的功能验收,不推迟到“插件生态完成”。

9.3 性能目标

复用现有 benchmark,记录机器、版本、卡片数、历史数和媒体规模,再比较升级前后的启动、到期查询、评分与备份耗时。

10,000 个调度单位、Today 本地查询 P95 < 500 ms 可作为待测目标,不当作已实现承诺。不能只测数量少的新库;作答历史增长后,分页加载详情,避免一次加载所有答案与评估证据。索引与查询改造由测量结果驱动。

0.8.3 工作分支已加入独立历史基准:1 万张卡、10 万条复习记录、2 万次练习、6 万份代码。启动仍保留题面、调度与提交摘要的内存视图,代码及裁判详情按需读取。该基准不等于 Today 查询 P95 的验收,结果与导入 / 导出代价在性能记录中单独说明。

10. 数据与安全边界

  • 迁移前保留可恢复检查点;未知新版本明确拒绝打开。恢复失败不覆盖旧库。
  • SQLite 备份使用一致性快照或受支持的备份接口,不能随意复制正在写入的数据库文件;IndexedDB 也需在一致事务中读取。
  • .repeaty 保存学习数据和选定来源快照;外部 Vault、在线题库和第三方服务不能宣称已完整备份。
  • 账户库继续验证所属账户,导入 / 导出和新增记录不能跨库读取。
  • LeetCode Cookie 与 Judge0 / LLM 凭据不上传到开源账户服务,不进入内容快照、评估证据或错误日志;凭据存储的改进单独验证,不声称现有明文文件已经加密。
  • 调用外部裁判或模型前说明会发送哪些源码、测试或材料,保留不启用这些功能的使用方式。
  • 数值题使用受限解析;符号表达式解析与提交代码均不在应用主进程任意执行。
  • 自定义服务地址需要明确协议、目标、重定向与凭据发送规则,原生桥接不开放任意文件 / 网络代理。
  • 新接口的权限检查由宿主实施;前端插件开关、manifest 和 MCP 工具描述本身都不是权限隔离。
  • 用户删除作答 / 来源的范围、检查点保留期限、附件回收及备份中的历史副本需要说明;避免审计记录无限增长。

11. 主要风险与缩减方案

风险 处理方式
一人同时维护多个集成 只执行下一个里程碑;先完善现有 LeetCode,新增题型与其他集成按需求延期
新记录牵动多个格式和存储 复用现有 Schema 与存储接口,迁移、备份和客户端兼容作为同一批工作
Activity 抽象导致旧卡进度丢失 先映射已有 Card ID,不重建笔记 / 卡片,不强制普通卡填写答案
审计日志与撤销、删除冲突 同时设计有效事件、撤销副作用与级联删除,保留旧库检查点
Judge0 服务或 LeetCode 接口不可用 展示明确错误,保留作答,允许手动评分;不阻塞传统卡片
SymPy 依赖和安全成本过高 长期可选,先保留现有 LeetCode 和人工评分,未验证就不自动判对
MCP 不能直接访问 WebView 数据 先做应用服务桥接实验;失败则延期,不据此强行重写全部核心
Anki 新格式与模板成本高 先限定 Basic / Cloze + 媒体;高级内容报告限制,不静默丢失
来源锚点失效或外部文件丢失 保存选定快照和原链接,提供手动修复;不自动覆盖原文件
Rust 调度或 SQLite 迁移扩大范围 独立实验与差异测试,维持现有实现直到迁移收益和兼容方案明确

12. 依赖、许可证与参考

项目继续采用 MIT。现有依赖按当前锁文件维护;新增 Judge0、SymPy、MCP 或 Anki 相关依赖时检查所用版本的许可证与分发要求,不因计划提及就提前加入运行时。

  • 调度继续使用 ts-fsrs;fsrs-rs 是未来候选,采用 BSD-3-Clause。算法升级以实际稳定发布与差异测试为准,不追随未验证的主分支。
  • Anki 格式参考导出手册与导入手册。Anki 源码采用 AGPL-3.0-or-later;实现兼容不等于直接复制或捆绑其源码。
  • AnkiConnect 使用官方迁移后的上游,迁移说明见原仓库。
  • Judge0 采用 GPL-3.0;计划通过 HTTP 访问用户自行配置的服务,捆绑 / 分发另行检查。
  • SymPy 解析文档明确了字符串解析的风险;它不是任意数学答案的安全判题沙箱。
  • MCP 参考规范和官方 Rust SDK;落地时固定经过验证的版本。
  • 渐进阅读参考 Foliole,核对版本与范围见参考笔记。本阶段复用现有 Source / Note.excerpt,不以其完整 Topic 树和自动调度作为前置条件。
  • Obsidian 连接器参考 Vault API。核心应用不依赖 Obsidian;渐进阅读可参考 SuperMemo 说明与 Incremental Reading Toolkit,复用代码前核对具体文件与许可证。

后续修订在本文件中更新基线、已完成项和下一批任务;版本与实现事实以仓库代码为准。