Slate v2 Lexical 测试收割处理指南:从 1996 条上游测试到可执行的测试处理台账
【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate
本篇技术指南围绕 Slate v2 Lexical Harvest Test Processing Ralplan 展开,讲解如何将 Lexical 编辑器的测试收割(harvest)成果系统化地处理为 Slate v2 的测试处理计划。读者将掌握一套可复用的方法论:以处理台账(processing ledger)为骨架,以「行为家族分组 + 证明类型分离 + 保守 Issue 声明」为纪律,把 271 条上游测试行逐条路由为 already-applied、covered、refactor-existing、create-new、defer、reject 六类状态,并生成可直接交给执行端的小粒度实施切片。
背景:Lexical 测试收割完成了什么
Slate v2 项目将 Lexical 视为测试语料库(test corpus)而非架构捐赠者。收割阶段(harvest)对 Lexical 仓库的全部测试文件做了系统盘点,产出三类核心工件:
| 工件 | 关键数据 | 位置 |
|---|---|---|
| 收割报告 | 收割完成,评分0.93 | inventory.md |
| 全量清单 | 271 条清单行、196 条可运行行、124 条 portable、13 条 portable-mixed、33 条 product-shell、12 条 harness、89 条 skip、0 条 uncertain | inventory.md |
| 测试名索引 | 137 个 portable/portable-mixed 可运行文件、1996 条 test/describe/it 名称 | test-index.md |
从 inventory.md 记录的清单命令可以看出,收割按测试路径特征(__tests__、test、spec、e2e、playwright、fixtures等)与排除规则(dist、build、node_modules、__snapshots__)过滤,最终形成全量分类。
一个关键的背景约束是:之前的选择性实施车道(selected apply lane)只覆盖了 IME/history、剪贴板语料、浏览器传输、表格包含(containment)四个领域,其余全部处于 backlog。因此「Lexical 收割已完成」不等于「Lexical 测试已处理完毕」——这正是本计划诞生的原因。
核心判断:不要逐条复制 Lexical 测试
计划的首要结论非常明确:
正确的下一步不是「复制全部 Lexical 测试」,那会既嘈杂又错误。正确做法是:把每一条 Lexical 源行处理进一份 Slate owner 台账,然后让执行端(
ralph)只实现那些作为可移植(portable)Slate 行为存活下来的行。
原因是收割数据的广度足以淹没实现:271 条清单行中,大量行编码的是 Lexical 内部实现(节点类、命令注册表、Composer/插件身份、私有 MIME 格式、Playground 产品外壳)、应用外壳或重复行为,逐条搬运只会让 Slate 更难维护。
决策原则
- 保留可移植行为,不保留 Lexical 架构:只搬运不变量(invariant),不搬运节点类生命周期、命令分发或框架外壳。
- 保持 Slate 原始(raw)且不预设立场:不把 Lexical 的整表选择模型、autolink 策略等悄悄塞进核心。
- 证明必须匹配行为类型:浏览器传输用浏览器行证明,模型不变量用单元行证明,真机移动端声明必须用真机行证明。
- DRY 胜过测试数量虚荣:已有 owner 时优先加强现有测试,而不是新建重复测试。
- Issue 声明需要精确复现证明,而不是「感觉」。
选项评估
| 选项 | 结论 | 理由 |
|---|---|---|
| 逐条移植全部 Lexical 测试 | 拒绝 | 大多数行编码 Lexical 内部、应用外壳或重复行为,会让 Slate 更难维护 |
| 认为选择性实施车道已经足够 | 拒绝 | 用户明确要求处理全部 Lexical 测试,报告仍将更广泛的行标记为 backlog |
| 先构建源行处理台账 | 采纳 | 台账覆盖所有行、让 skip 保持诚实、给执行端可运行的小切片 |
| 现在就强行关闭真机/表格/yjs | 拒绝 | 当前证明 owner 不支持这些声明,缺设备/模型/协作车道 |
边界声明(Non-goals)
计划明确划出不做的事:不移植 Lexical 节点类、命令注册表、Composer/插件身份、私有 MIME 格式、Playground 产品外壳、ESLint 工具链、发布夹具、框架外壳行为;不用桌面 Playwright 移动视口冒充真机 IME 证明;不把原始 Slate 悄悄改造成 Lexical 的整表选择模型;不创建 1996 个一次性测试。
处理台账:六类状态与文件级路由
计划的核心产出是 slate-processing-ledger.md,它以文件粒度为每个 portable 与 portable-mixed 源文件分配处理状态:
| 状态 | 含义 |
|---|---|
already-applied | 选择性实施车道已添加或加强对应的 Slate v2 证明 |
covered | 当前 Slate v2 已有足够好的证明行,除非后续审计发现漂移 |
refactor-existing | 加强、拆分、重命名或拓宽现有 Slate 测试;优先于重复新建 |
create-new | 新增一条 Slate v2 单元/浏览器行 |
defer | 行为有效,但需要真机设备、yjs 浏览器、表格模型或后续接受的 owner |
reject | 不是可移植的原始 Slate 行为目标 |
台账的最终账目覆盖了全部 137 个 portable/portable-mixed 源文件:5个 already-applied、1个 covered、12个 create-new、83个 refactor-existing、21个 defer、15个 reject。此外台账还定义了plate-owned覆盖层:当残差行为真正适合 Plate 插件/示例/文档而非原始 Slate v2 时,路由到 Plate 侧(链接/autolink 语法、列表缩进、markdown 导入导出、mention/hashtag 等插件文法、React Composer/工具栏外壳)。
行为家族核算
收割清单按行为家族统计并分派处理车道:
| 家族 | 行数 | 处理车道 |
|---|---|---|
portable editor behavior | 39 | 核心模型、选择、变换、历史、浏览器拆分 |
serialization-parsing / marks-inline | 20 | 列表/markdown/html/richtext 单元与浏览器行 |
selection-dom-mapping / void-atom | 19 | DOM 选择、行内原子、caret、mention/link/void 边界 |
core package behavior | 16 | Slate 包单元契约;拒绝仅 Lexical 生命周期场景 |
clipboard-paste / browser-engine | 14 | 剪贴板契约与 paste-html 浏览器语料 |
tables-grid / selection-dom-mapping | 10 | 现在只做包含(containment);表格模型行另立 |
mixed portable invariant | 9 | 从产品插件行为中拆出有用的原始不变量 |
beforeinput-input / browser-engine | 7 | model-input 策略与 Playwright 输入传输行 |
ime-composition / history-undo-redo | 2 | 基本已应用;核验无未处理命名行 |
collaboration-remote / history-undo-redo | 1 | 基质已覆盖;yjs 浏览器延迟 |
harness | 12 | 仅技术手法,无直接 Slate 行为行 |
product-shell | 33 | 除非拆出原始不变量,否则拒绝 |
skip | 89 | 保留原因地拒绝 |
现有 Slate v2 证明 owner 分布
计划在实时源码中盘点出当前 Slate v2 的证明 owner,这决定了「已覆盖」与「需要新建」的边界:
| 行为 | 当前 owner(文档记录路径) | 状态 |
|---|---|---|
| IME 经浏览器运行时 | rendering-strategy-runtime.test.ts、richtext.test.ts、mentions.test.ts | 强已有/应用覆盖 |
| IME 行内 void 与 undo 压力 | generated-editing.test.ts | 选择性车道已覆盖 |
| 组合历史(composition history) | slate-history/test/history-contract.ts | 选择性车道已覆盖 |
| 浏览器插入传输 | plaintext.test.ts | 选择性车道已覆盖 |
| 合成粘贴兼容 | plaintext.test.ts | 已覆盖;Firefox skip 诚实 |
| Google Docs 字号粘贴 | paste-html.test.ts | 选择性车道已覆盖 |
| Google Sheets 表格粘贴 | paste-html.test.ts | 选择性车道已覆盖 |
| 表格三击包含 | tables.test.ts | 选择性车道已覆盖 |
| 表格拖拽包含 | tables.test.ts | 已覆盖;非整表选择 |
| DOM 覆盖 IME | dom-coverage-boundaries.test.ts | 有用证明 owner |
实施阶段:Phase 0 到 Phase 8
计划按阶段推进,前两阶段是纯规划,后续按证明类型分闸:
- Phase 0(处理台账):只创建
slate-processing-ledger.md,为每个 portable/portable-mixed 源文件记账,不触碰.tmp/slate-v2。 - Phase 1(文本单元与破坏性删除包级对齐):从 Lexical #7163 grapheme 矩阵起步,重构
text-units-contract.ts与现有 delete/unit-character 夹具而非创建重复行;首切片仅包级,除非暴露浏览器专属缺口。首要命令:cd .tmp/slate-v2 && bun test ./packages/slate/test/text-units-contract.ts;实现后关闭命令:cd .tmp/slate-v2 && bun check。 - Phase 2(剪贴板 HTML 源钻取):逐行打开 Lexical link/list/text-format/table 源行,为每行命名预期的 Slate value/DOM 输出,并判定属于原始解析器行为还是示例应用策略。此阶段不编辑代码,不重跑 ClawSweeper(除非声明变化)。已于 2026-05-09 完成,接受/拒绝/延迟行全部记录在台账的
Clipboard HTML Row-Level Source Drill节。 - Phase 3(剪贴板 HTML 语料残差):按小切片实施——先是 text-format HTML(Google Docs BIU 跨度 + 安全的语义
<b>处理);再是简单 anchor 导入;再是 Lexical #3193 风格的 noisy link-in-list 最小夹具;再是基础无序列表导入;再是紧凑嵌套列表语料;再是列表项内的嵌套div文本边界;再是 Google Docs 表格导入(rows/cells、多段落单元格、11pt文本);最后是 Quip 表格导入(单元格内b<br>b换行文本)。每个切片都在 paste-html.test.ts 对应的浏览器 owner(.tmp/slate-v2/playwright/integration/examples/paste-html.test.ts)留下浏览器证明。 - Phase 4(DOM 突变修复残差):把 Lexical
Mutations.spec.mjs当作refactor-existing;只有当压力复查确认richtext.test.ts、生成压力或策略单元 owner 缺失不变量时才加强。浏览器突变行为必须用 Playwright 证明,包策略测试只作支撑。 - Phase 5(焦点、滚动与原生浏览器输入):处理 TextEntry、Events、Keyboard、Focus、AutoScroll 与剩余 Mutations 行;原生传输或 DOM 权威是行为本身时必须用浏览器证明;不把桌面视口行冒充真机/原始 IME 关闭。
- Phase 6(选择与行内/void 原子残差):mention 删除/粘贴边界、link/hashtag/HR 导航(仅当 Slate 拥有等价原始不变量);把原始行内行为与产品工具栏、autolink、应用外壳策略分离。
- Phase 7(表格模型决策):保留 containment 与三击证明;在 Slate 接受表格选择模型前不声明多单元格/整表选择;本计划不接受表格选择模型。
- Phase 8(协作/浏览器):保留协作/历史基质行;只有存在真实 collab owner 时才添加 yjs/browser 行;本计划不声明协作浏览器对等。
Ralph-ready 切片:允许做什么、禁止做什么
| 顺序 | 切片 | 允许的工作 | 禁止的工作 | 必需证明 |
|---|---|---|---|---|
| 1 | 文本单元/删除包级对等 | 只向现有 Slate text-unit/delete owner 添加缺失的 Lexical #7163 破坏性 Unicode 行 | 无浏览器、真机、表格、协作或 Issue 声明;不重写删除行为 | bun test text-units-contract.ts;触碰夹具时补单元命令;关闭前bun check |
| 2 | 剪贴板 HTML 源钻取 | 读取精确 Lexical link/list/text-format/table 行并映射到预期输出与 owner | 不改.tmp/slate-v2代码;声明不变则不重跑 ClawSweeper | 仅规划产物 |
| 3 | 剪贴板残差实施 | 只添加源钻取命名的解析器/浏览器缺口 | 无产品工具栏/autolink 行为;不重复已有覆盖 | 聚焦包/浏览器证明 +bun check |
| 4 | DOM 突变/焦点/行内残差 | 命名缺失不变量后加强现有浏览器或策略 owner | 无单元-only 关闭浏览器行为;无真机声明 | 聚焦 Playwright owner + 相关包策略证明 |
| 5 | 表格/真机/协作车道 | 仅独立未来计划 | 不隐藏整表选择、真机或 slate-yjs 浏览器声明 | 先存在表格模型、真机或协作浏览器证明 owner |
压力测试、维护者异议与高风险门禁
压力测试结论
压力测试保持计划保守,不新增 Issue 声明、不编辑.tmp/slate-v2:
- 文本单元/删除包级对等:保留第一。Lexical #7163 有密集的 portable Unicode 矩阵,当前 Slate 在
text-units-contract.ts有清晰 owner,包级证明避免浏览器抖动与构建成本。压缩契约行在不改动架构的前提下增加价值。 - 剪贴板 HTML 残差:保留第二但收窄。现有 Slate 已覆盖富片段、行内 void 复制粘贴、多行纯文本、Google Docs 字号、Google Sheets 表格与生成粘贴闯关。盲目移植 Lexical link/list 文件会重复覆盖并引入产品工具栏策略。实施前必须源钻取。
- DOM 突变修复:降级为 refactor-existing。
richtext.test.ts已同步粗体标记内的浏览器文本突变并记录 selectionchange/修复内核结果;新独立 suite 是重复,除非Mutations.spec.mjs暴露缺失断言。 - 焦点/自动滚动:保留为后期浏览器切片。placeholder focus/IME 已存在,huge-document 只证明可见性;Lexical AutoScroll/Focus 行有价值但混合了原始编辑器行为与应用滚动策略。
- 行内原子/链接粘贴:接受的原始行已应用。源读确认 portable 原始行是边界复制粘贴与部分链接片段保留;paste-inside-link 拆分是 link 插件策略而非通用核心法则。
- 表格:保留延迟。现有表格测试证明 containment、三击、拖拽、Enter 与单元格导航;整表/合并单元格/多单元格行为是模型决策。
- 真机与协作浏览器:保留延迟。桌面/移动视口证明无法满足真机行,当前协作证明仅为包级基质。
维护者异议台账(节选)
计划用「最有力公平异议 → 钢人反论 → 接受的修订」三段式逐条审问决策,代表性修订包括:剪贴板残差不能作为一次宽泛抓包实施、必须先源钻取;焦点/自动滚动必须证明原始编辑器行为而非产品外壳布局;DOM 突变修复保持 refactor-only 但要求下个 owner 先检查richtext或生成压力是否已覆盖;表格、真机、协作浏览器延迟是明确的非声明(non-claim)。
高风险门禁与三场景预演
主要风险是虚假自信:单元行、台账行或规划命令被误认为浏览器、设备或 Issue 修复证明。门禁按爆炸半径设防:
- 文本单元/删除:首个切片可从聚焦包证明出发,不做浏览器/真机/表格/Issue 声明;实现后必须全量
bun check。 - 剪贴板 HTML:源钻取先于代码;声明不变时源钻取前无需 ClawSweeper 同步。
- DOM 突变/焦点/滚动/行内:浏览器行不能被包测试关闭;只有命名缺失不变量后才新增或重构 Playwright 行。
- 表格/真机/协作:显式非声明。#2558 不声明;真机需
SLATE_BROWSER_RAW_MOBILE_REQUIRED=1 bun test:mobile-device-proof:raw门禁;协作浏览器需真实 slate-yjs/browser owner。 - 规划与验证门禁:
plate-2完成检查只证明规划状态;任何 Slate v2 行为声明必须引用从.tmp/slate-v2运行的命令。
三场景预演(pre-mortem):虚假证明(包行关闭浏览器粘贴/IME/焦点)→ 证明类型归属显式化;范围蔓延(剪贴板残差变成跨解析器/示例/列表/链接/表格的宽泛粘贴重写)→ Phase 2 仅源钻取,命名精确行后才允许代码;声明漂移(「已处理 Lexical 测试」被暗示为表格/真机/协作或 Issue 修复声明)→ 非声明在计划、检查点、续接提示中反复重申。
已执行切片成果:从 ralplan 到代码与测试
截至文档记录的 2026-05-09,ralph已执行大量源读与实施切片,形成「红行 → 实现 → 聚焦证明 → 全量bun check」的闭环。以下按家族摘录代表性成果(均为文档记录事实):
文本单元与删除
- Lexical #7163 已应用:
text-units-contract.ts获得显式 Slate 文本单元距离与前后向unit: "character"删除证明;delete-text.ts移除过时的复杂脚本反向删除恢复逻辑,使删除与getCharacterDistance遵循同一文本单元边界法则,泰语 unit-character 夹具同步对齐。 - Lexical #7246 锁定:
delete-contract.ts证明段首 Backspace 合并进前一个列表项。 - Lexical #7319 拆分:可移植 block-void 行为暴露真实缺口——
delete-text.ts现在把相邻 void/只读元素内的折叠删除目标视为路径删除,逐个删除相邻块 void,回归锁定在transforms/delete/voids-false/block-after-multiple-reverse.tsx。 - 通用法则沉淀为解决方案笔记:2026-05-09-slate-v2-adjacent-block-void-delete-must-path-delete-one-target.md。
剪贴板与粘贴 HTML
- Google Docs BIU 跨度与安全语义
<b>:paste-html.test.ts证明 Google Docs<b style="font-weight:normal">包装不产生粗体、普通语义<b>映射粗体、body 级行内字符串先转文本节点再包段落。 - 简单 anchor、noisy link-in-list(Lexical #3193 风格)、基础
ul、紧凑嵌套列表、列表项内嵌套div边界、Google Docs 表格(2x3、多段落单元格、11pt)、Quip 表格(b<br>b换行文本)均已加入浏览器语料。 - 核心 HTML 块形状(纯 DOM 文本、畸形
<p>Hello!<p>、单个div、嵌套 span/div、div内嵌套 span、span 内嵌套div)由paste-html-import.ts以通用div块边界导入修复。配套法则见 2026-05-09-html-div-boundaries-must-survive-inline-wrappers.md。 - 原生列表片段粘贴:
insert-fragment.ts以显式结构化片段替换先于通用行内/块解包,clipboard-contract.ts覆盖部分列表项、选中文本内插入、列表项内段落片段、列表尾段落片段等七类行。配套法则见 2026-05-09-native-list-fragment-paste-must-run-before-generic-fragment-unwrapping.md。 - 空目标片段粘贴保留首块包装:粘贴到空引用块时首文本块填充引用、尾段落提升其后。见 2026-05-09-empty-target-fragment-paste-keeps-first-block-wrapper.md。
- 代码源 HTML 导入:Quip
<pre>、VS Codewhite-space: pre行div、GitHub 代码表导入为一个<pre><code>块,使用 DataTransfer 插入边界而非原生剪贴板(Chromium 会先压平<pre>)。见 2026-05-09-lexical-codeblock-harvest-rows-need-data-transfer-boundaries.md。 - 图像 HTML:
<p><img></p>与<figure><img><figcaption>两种 Lexical 导出形状;paste-html-import.ts解包仅含块元素的段落包装。见 2026-05-09-block-only-html-paragraphs-must-not-wrap-block-voids.md。
DOM 修复、焦点与滚动
dom-repair-policy-contract.ts新增结构恢复管理器策略证明:子列表突变回滚,字符数据突变保留用于文本同步。- 焦点/自动滚动:
richtext.test.ts证明失焦时保留模型选择、可滚动编辑器根与可滚动父级中跨行输入时 caret 可见;editable.tsx对空行 caret 零矩形场景回退到滚动 leaf 矩形。
行内边界、caret 与选择重基
- 行内粘贴/mention/link/HR 边界:
inlines.test.ts证明行内链接边界纯文本与富 HTML 粘贴都留在链接外;clipboard-contract.ts证明部分链接片段复制/粘贴保留链接属性。 - caret 破坏性范围删除矩阵:
delete-contract.ts证明扩展范围删除在锚点折叠前修剪两侧兄弟 leaf 边与跨块边。 - 选择重基不变量:
selection-rebase-contract.ts证明被选 leaf 消失时选择落在最近存活行内点;LexicalRootNode切片进一步证明删除被选首块重基到下一个存活块、删除唯一被选块清空选择。 - 原始文本操作选择修复:
operations-contract.ts证明split_node跨分裂文本分支重基扩展选择、merge_node把选择重基进存活文本分支。 - 行内链接插入后移出:
inlines.tsx在折叠插入链接后移出一个偏移。见 2026-05-09-collapsed-inline-link-insertion-must-move-selection-outside.md。
历史、序列化、热键与状态 API
- 历史栈法则:
history-contract.ts证明 undo 后新编辑清空 redo 栈、选中块属性 undo/redo、忽略空更新同时捕获节点属性历史。 - 序列化:
state-tx-public-api-contract.ts证明富原始文档值经 JSON 往返、可重水合为initialValue、不序列化pathToId/idToPath运行时索引元数据。 - 热键:
hotkeys.ts证明isHotkey先按语义字母键匹配、处理大写、拒绝 ASCII 重映射布局物理键、对非英文单字母布局回退event.code。 - 根拆分拒绝:
split-nodes.ts对Editor.splitNodes(..., { at: [] })抛出直接编辑器根错误。
列表、标题、引用、markdown 与格式化
- 相邻 markdown 列表合并(#3433):
markdown-shortcuts.tsx合并相邻项目符号列表包装,浏览器行证明一个ul中two在one前。 - 标题/引用 Enter 策略:
richtext.tsx用统一的 exit-on-Enter 策略处理heading-one/heading-two/block-quote,中间 Enter 走通用核心 split 路径。 - 有序列表起始数字(
25.→ol start="25")与列表 Backspace 退出解包进入markdown-shortcuts.tsx。 - 清除格式:
richtext.tsx暴露 clear-formatting 按钮,只移除选中文本 mark、重置块对齐、保留 blockquote 结构。 - 空段落居中(ElementFormat):折叠选择下显式定位包含块路径。
- mark 热键:
tx.marks.toggle默认值改为true,插入前清空继承折叠 mark;snapshot-contract.ts证明Editor.toggleMark行为;richtext.tsx阻止编辑器自有 mark 热键的浏览器默认处理。 - 列表工具函数:
query-contract.ts证明嵌套列表深度、非根顶层列表祖先、后代列表祖先、terminal/非 terminal 列表项路径。 - 代码行 Tab 缩进与 Shift+Tab 多行缩进进入
code-highlighting.test.ts。 - 装饰文本令牌:
highlighted-text.tsx为普通文本添加 hashtag 风格投影,覆盖 Space 拆分、Delete/Backspace 边界、瞬态前缀导航、分隔符增删与删除#后稳定 caret。 - Mac
Ctrl+Oopen-line:open-line插入断行变体经slate-dom热键与slate-react键盘/突变运行时实现,直接在当前块前插入空段落。 - beforeinput 替换:
runtime-before-input-events.ts在下一个模型属主 beforeinput 前冲刷排队原生文本修复,mutation-controller.ts应用提供替换目标范围,selection-reconciler.ts尊重扩展insertText目标范围;Mac 风格insertTranspose(Ctrl+T 交换相邻字符)成为一级transpose-character命令。
被拒/延迟的代表性行
- LexicalElementHelpers(class 字符串增删)被拒为 Lexical DOM 工具助手。
- SpecialTexts 括号触发高亮被拒为产品变换/主题策略。
- Lexical markdown 导入/导出、markdown-link transformer、checklist 私有属性、HR 插入/拆分、自定义表宽/合并网格/rowspan/colspan/空行合成、paste-inside-link 拆分、原始 autolink 插件行为、表格单元格块归一化,全部延迟到显式未来 owner(markdown 序列化、list/checklist、HR/block-void、表格布局/模型、link 插件)。
- 真机移动、协作浏览器、整表选择为显式非声明。
Issue 核算:零新增声明的纪律
计划在 Issue 核算上保持高度保守,最终核算为 no-op:
- 计划记录
0条新增精确Fixes #...或Improves #...声明。 - pr-description.md 保持固定 Issue 声明
31、相关矩阵行158、Lexical 收割精确声明0。 - issue-coverage-matrix.md 保持 #5894
Not claimed、#4730Related、#3387Related、#3872Related、#4716Related、#5355Not claimed、#2558Not claimed。 - 相关分类遵循「related/proof-route only」:表格类(#4658/#4643/#5355 相关压力,#2558/#5550/#5551/#5924/#4851 不声明)、剪贴板类(#4440/#3557/#4542/#3155/#4716/#2694 相关)、IME/真机类(#5912/#4223/#5281 非声明)等。
- ClawSweeper 仅在公共行为、Issue 声明或相关表面发生实质变化时重跑;零声明变化时最终核算可为 no-op 复查。
关闭评分与验证命令
计划关闭评分0.92,六个维度均不低于0.85:台账核算0.95、Issue 诚实0.94、证明归属0.93、实施切片就绪0.91、非声明保护0.94、可维护性0.90。关闭门禁全部通过:最终评分达标、无维度低于0.85、10 个规划 pass 完成且第 11 个为关闭、无隐藏.tmp/slate-v2实现声明、首个ralph交接切片足够窄。
规划仓库门禁(文档记录,需在对应检出目录执行):
# 规划仓库(plate-2) pnpm lint:fix bun run completion-check -- --file .tmp/completion-checks/slate-v2-lexical-harvest-test-processing-ralplan.mdSlate v2 后续实施切片门禁:
# 在 .tmp/slate-v2(slate-v2 检出)中 bun test ./packages/slate/test/text-units-contract.ts bun test ./packages/slate-dom/test/clipboard-boundary.ts bun test ./packages/slate-history/test/history-contract.ts PLAYWRIGHT_RETRIES=0 bunx playwright test playwright/integration/examples/paste-html.test.ts --project=chromium PLAYWRIGHT_RETRIES=0 bunx playwright test playwright/integration/examples/tables.test.ts --project=chromium bun check浏览器/发布关闭门禁:bun check:full;真机设备门禁:SLATE_BROWSER_RAW_MOBILE_REQUIRED=1 bun test:mobile-device-proof:raw。
浏览器行纪律:当浏览器行构建或共享 Slate v2 站点时必须串行执行,不得并行运行多个站点支撑的 Playwright 命令;IME 行必须使用诚实的 DOM 组合边界,合成或仅模型选择不足以证明原生浏览器行为;DOM 选择计划必须按 owner 为外部测试源排序——Lexical 在浏览器回归形状与 skip 纪律上强,但不代表每个 DOM 选择架构选择都该采纳。
方法论总结:把上游测试语料变成可执行的工程资产
这份 ralplan 最有价值之处在于把「另一个编辑器的 271 条测试」转化为一份可审计、可执行、可关闭的工程计划:
- 台账先行:所有 portable/portable-mixed 源文件先路由到六类状态,让拒绝与延迟都有具体理由,杜绝「静默丢弃」。
- 按不变量家族分组,不按上游文件形状分组:优先加强已有 Slate 测试,只有不变量没有诚实证明时才新建。
- 证明类型与行为严格配对:模型不变量走包测试,浏览器传输走 Playwright,真机声明走真机门禁;绝不混合。
- 小切片 + 显式允许/禁止清单:每个
ralph切片都写明允许的工作、禁止的工作与必需证明命令,避免范围蔓延。 - Issue 声明零容忍漂移:related/proof-route 与 not-claimed 是默认态,任何精确
Fixes/Improves都需要复现证明。 - 每次执行沉淀可复用法则:30 余条解决方案笔记分布在 docs/solutions 的
best-practices、logic-errors、workflow-issues分类下,把「红行 → 修复 → 法则」的循环固化下来。
对于任何需要跨编辑器移植测试覆盖、或在核心编辑器与插件层之间划分测试所有权的团队,这份计划提供了可直接套用的模板:先建台账、再定切片、最后用证明门禁收口。仓库中完整的处理台账见 slate-processing-ledger.md,行为家族与切片优先级可直接作为后续执行计划的输入。
【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考