verify

GitHub

用于 Electron 小说应用前端 UI 的实机自动化验证。通过 Playwright 驱动无头窗口,执行特定场景并截图、记录耗时,支持对比新旧版本界面表现与启动性能。

.claude/skills/verify/SKILL.md EthanYoQ/AI-Novel-Writer

Trigger Scenarios

需要验证前端界面渲染是否正确 进行 PR 合并前的实机 UI 回归测试 测量应用冷启动耗时或内存占用

Install

npx skills add EthanYoQ/AI-Novel-Writer --skill verify -g -y
More Options

Non-standard path

npx skills add https://github.com/EthanYoQ/AI-Novel-Writer/tree/master/.claude/skills/verify -g -y

Use without installing

npx skills use EthanYoQ/AI-Novel-Writer@verify

指定 Agent (Claude Code)

npx skills add EthanYoQ/AI-Novel-Writer --skill verify -a claude-code -g -y

安装 repo 全部 skill

npx skills add EthanYoQ/AI-Novel-Writer --all -g -y

预览 repo 内 skill

npx skills add EthanYoQ/AI-Novel-Writer --list

SKILL.md

Frontmatter
{
    "name": "verify",
    "description": "在真实 Electron 中驱动 AI 小说作家,按场景截图、记录启动耗时并读取只读诊断。前端重设计 RD-0 至 RD-10 每个 PR 的实机验证都走这里。用于「实机验证」「截图对比」「跑一下界面场景」。"
}

verify

驱动脚本是 scripts/redesign/drive.mjs。它用 Playwright 的 _electron 启动当前工作树的构建产物(electron .),每个会话(一次冷启动)一个全新的隔离目录,模型调用全部走本机假服务,不调用真实模型。单跑一个场景就是只含这个场景的会话。

应用窗口不出现在屏幕上。驱动用 electron -r scripts/redesign/offscreen-window.cjs 在应用主进程脚本之前挂上 browser-window-created 监听:窗口一创建就移到所有显示器右侧之外,去掉任务栏按钮,设为不可激活并交还焦点,不打扰正在用电脑的人。截图走页面视口,与窗口位置无关;页面焦点由 Playwright 的焦点模拟提供,document.hasFocus() 仍为 true。每次截图前断言 document.visibilityState 为 visible,防止屏幕外窗口被当作隐藏而停帧。

启动前

在要验证的工作树根目录依次运行:

pnpm install --frozen-lockfile
pnpm rebuild:electron
pnpm build

驱动加载的是 dist/ 与 dist-electron/,改了 src/ 或 electron/ 必须重新 pnpm build。better-sqlite3 刚为 vitest 切到 Node ABI(pnpm prepare:native-node)时,先 pnpm rebuild:electron 再驱动。

命令

pnpm verify:drive -- --scenario <名称> [--theme light|dark] [--shell writer|stage] [--out <目录>] [--dump-dom] [--console] [--video] [--app-root <目录>]
# 等价于
node scripts/redesign/drive.mjs --scenario <名称> ...
  • --theme 默认 light,即外观里的「浅色」;dark 为「深色」。
  • --shell 只对 RD-10 之前的构建(--app-root 指向的 trunk)有意义:不给时不碰外观里的外壳偏好(旧外壳),stage 选 RD-3 起的流程脊外壳,与主题在同一次写入里改,只重载一次;RD-2 及更早的 trunk 不认识 stage,不要传。RD-10 起的构建只有纸墨外壳,外观写在 v3 键里,没有外壳偏好:--shell 不必传,传 writer 直接报错。
  • --video 在每个截图点的 run 期间录屏:CDP Page.startScreencast 收帧,按帧时间戳交给本机 ffmpeg 编成 H.264 mp4,写到 <场景>-<主题>.mp4。不需要 Playwright 自带的 ffmpeg。
  • --out 默认 .runtime/redesign-baseline/(已被 git 忽略)。
  • --app-root 默认当前工作树。性能对照时指向 trunk 的工作树,用同一个驱动测两边;目标工作树也要先跑完上面三条命令,它加载的是自己的 dist-electron/ 和 better-sqlite3。
  • 退出码:0 全部通过;1 有场景失败、残留进程或隔离目录外写入;2 参数错误。

RD-10 删除旧外壳之后,场景分三类:

  • 只走旧外壳的场景只对 trunk 跑(--app-root):下面「场景」表的 8 个基线场景与 baseline-all、nav-*、write-latency、settings-appearance、run-write-steps、legacy-no-chat、arch-legacy-sidebar。对照时 head 一侧改跑对应的新外壳场景。
  • 两种外壳都能跑的场景运行时按页面上有没有纸墨外壳选页面对象,head 与 trunk 用同一条命令:startup-timing、idle-memory、chapter-switch、chapter-open、typing-latency、chapter-regression、blueprint-regression、blueprint-timing、refs-regression、refs-timing、new-project-files。
  • 其余声明了 shell: 'stage' 的场景只对 RD-3 及以后的构建跑。

场景

名称 对应流程 单跑时截图停在 baseline-all 里的不同 用夹具模型
new-project 新建作品 新作品的小说配置页 无 否
open-sample 打开示例作品 项目树刷新完成(蓝图 2/100 章、角色图谱已生成),显示第 1 章与草稿_v1 无 否
write-chapter 写作此章 草稿标签已打开,正文非空 已有预置的草稿_v1,写出的是草稿_v2 是
review AI 审稿 审稿报告标签 审的是最新一稿草稿_v2 是
revise-merge 按确认意见修稿并合并 修稿合并对话框;截图后点完成合并,等对话框关闭 修的是草稿_v2 是
finalize 定稿 已定稿(只读),AI 输出显示后处理完成 定稿的是合并后的草稿_v2,不是草稿_v1 是
run-panel 打开运行面板(现为 AI 输出) 重开作品后从右侧栏打开 AI 输出,显示一条持久运行「第1章候选」 无;它排在审稿之前,因为草稿被修稿改动后这条记录变成「第1章生成记录」 是
settings 打开设置 设置弹窗 截图后关闭设置,接着跑 new-project 否
baseline-all 按共享前置串成 2 个会话跑上面 8 个场景 8 张截图
startup-timing 只启动 不截图,输出启动耗时 否

示例作品名为「灯塔」,第 1 章「旧港」,由公开 IPC 预置后从书房打开;打开后等项目树统一刷新结束再继续,之前的画面随刷新进度变化。

场景的 run 可以调 context.restart():退出应用、用同一隔离目录冷启动(不重写外观),context 里的 app、page 换成新的,用于验证「重启后仍保持」。

scripts/redesign/scenarios.mjs 里每个场景分三段:setup 是单跑时的前置(预置作品、写一章、审稿等),run 从前置状态走到截图状态,after 在截图后执行。一个会话只跑首个场景的 setup,然后依次 run、截图、after。baseline-all 的会话在 BASELINE_SESSIONS:

  • baseline-shelf:settings → new-project。不预置作品,new-project 要在空项目目录里建「灯塔」,与示例作品不能共存。
  • baseline-sample:open-sample → write-chapter → run-panel → review → revise-merge → finalize。预置一次带草稿_v1 的示例作品,后面每步接着上一步的状态。

改动前 baseline-all 每个场景各冷启动一次(8 次);现在 2 次。

输出

在 --out 目录下:

  • <场景>-<主题>.png:场景截图,1440×900(stage-1280 为 1280×900)。
  • --video 时另有 <场景>-<主题>.mp4,结果项的 video 字段指向它。
  • <场景>-<主题>.json:本次运行的结果数组,每个截图点一项。scenario、screenshot 属于这个截图点;session(会话名,单跑时等于场景名)、timing、shell(外壳的 data-shell-presentation,writer 或 stage:startup-timing 取计时那次启动显示的外壳,其余场景取写好外观、重载之后的外壳,用来确认测的就是要测的外壳)、externalRequests、residualProcesses、externalWrites、quit、isolationRoot 属于整个会话,会话里每一项都抄一份;会话用了夹具模型时另含 modelRequests(整个会话里假服务收到的全部请求数,嵌入请求也计入,与 --console 里的 [fake-model] 行一一对应)。失败时含 error:截图点自己的失败写在该项;同一会话里排在失败点之后的截图点不再运行,error 写明是被哪个场景拖住;会话级失败(启动、外部请求、退出、进程枚举)写进该会话的每一项。
  • 失败时额外写 <失败场景>-<主题>.failure.png、.dom.html、.aria.yml 和 <会话>-<主题>.console.log,隔离目录保留以便排查。

每个会话结束后,驱动检查三件事,任一不满足即退出码 1:

  • externalRequests 为空。每个会话都在 Electron 启动后替换主进程的 globalThis.fetch:用夹具模型的会话只放行 https://api.openai.com/v1/* 并改道到本机假服务,其余会话一律不放行。被拒的请求记下来源并抛错。检查范围只有主进程 fetch,且从 electron.launch 返回后才生效;更早的请求、渲染进程的请求和 Electron net 模块的请求都不在内。
  • residualProcesses 为空:应用关闭后,以 --user-data-dir 匹配不到存活进程。子进程退出需要时间,驱动最多查 10 次、间隔 300 ms。
  • externalWrites 为空:~/.vela、%APPDATA%\ai-novel-writer、%APPDATA%\AI小说作家 的最新修改时间不变。

枚举或结束进程本身失败时,原因写进该会话每一项的 error,结果 JSON 照常写出。

只读诊断

node scripts/redesign/drive.mjs --scenario open-sample --dump-dom --console --out <目录>
  • --dump-dom 在每个截图点截图后写 <场景>-<主题>.dom.html(page.content())和 .aria.yml(Playwright 无障碍快照)。改页面对象前先看 .aria.yml,选择器优先用其中的角色与可访问名称。
  • --console 每个会话写一份 <会话>-<主题>.console.log(单跑时会话名就是场景名,baseline-all 为 baseline-shelf、baseline-sample):渲染进程控制台、页面异常、主进程 stdout/stderr,以及假模型每次请求的分类([fake-model] prose|review|revision|character-state|embedding)。

截图可重复性

同一场景连续跑三次再比较:

for i in 1 2 3; do node scripts/redesign/drive.mjs --scenario review --out shots/r$i; done
node scripts/redesign/pixel-diff.mjs shots/r1/review-light.png shots/r2/review-light.png shots/r3/review-light.png

pixel-diff.mjs 输出各张相对第一张的不同像素占比,maxRatio 小于 0.005 时退出码 0,否则 1。尺寸与第一张不同的图记为全部不同(ratio 为 1),reason 写明两边尺寸。任一通道差值超过 2 级才算不同像素(ratio),因为同一状态连续截图时,渲染器在背景模糊和渐变上偶发全屏 ±1~2 级抖动;逐字节比较的结果另列为 strictRatio,供判断差异是不是这种抖动。

启动耗时

startup-timing 的 timing 字段:readyToShowToInteractiveMs(主窗口 ready-to-show 到书房「新建作品」按钮可见,计划里的性能指标)、launchToInteractiveMs、navigationToInteractiveMs。ready-to-show 监听在预加载脚本里、先于移窗挂上,窗口创建前就已就位,所以每次都有值。trunk 与 head 交替各跑 5 次取中位数:

node scripts/redesign/drive.mjs --scenario startup-timing --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario startup-timing --out <目录>

空闲内存

idle-memory 与 startup-timing 一样先在同一隔离目录预启动一次写好主题,再冷启动一次;第二次启动到书房可交互后静置 10 秒,再每隔 1 秒用 app.getAppMetrics() 采样 5 次全部进程的内存,结果写进 memory:workingSetKB、privateKB(Windows 才有私有字节)是各次合计的中位数,byType 按进程类型(Browser、Tab、GPU、Utility 等)各取工作集中位数,samples 是采样次数。不截图、不用夹具模型。计划 RD-10 的性能复测与启动耗时交替跑:trunk 与 head 各 5 次,取中位数比较,跑的时候机器上不开别的程序。

node scripts/redesign/drive.mjs --scenario idle-memory --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario idle-memory --out <目录>

不进 baseline-all 的场景

scenarios.mjs 的 EXTRA_SCENARIOS 只能单跑,不进 baseline-all。run 的返回值写进结果的 measured。需要卡住模型调用时,场景从上下文的 fake.gate 调 hold(),在 after 里 release()。hold() 只卡对话请求;只走嵌入的步骤(参考文本入库)用 hold({ embeddings: true }) 连嵌入一起卡。fake.gate.waiting 是正卡在门上的请求数,截图前等它大于 0,画面才停在确定的那一步。

名称 检查 单跑时截图停在 用夹具模型
write-latency 在渲染进程里计时:点击写作此章弹窗的「开始创作」到 AI 输出标题可见,写进 measured.writeToOutputMs。RD-4 起旧外壳右栏默认是 AI 输出,计时前只在它开着时收起,trunk 不受影响 写作完成 是
nav-switch-project 角色视图加沉浸写作时从标题栏切换到另一部作品,断言退出沉浸、侧栏显示项目树 新作品的小说配置页 否
nav-toast-open 写作完成后再点右侧栏「AI 输出」收起它,点完成提示「打开查看」,断言 AI 输出重新出现 AI 输出里的「第1章候选」 是
nav-status-capsule 卡住模型让写作停在运行中,收起 AI 输出后点状态栏任务胶囊,断言 AI 输出出现 运行中的 AI 输出 是
nav-settings-model 先从标题栏「备份」打开设置并关闭,再点状态栏模型,断言落在「AI 生成模型」 设置弹窗的模型分组 是
nav-kb-import 关掉底部面板后在「小说」视图导入创作资料并确认发送,断言底部面板打开且停在「任务」 知识库页与任务面板 是
nav-card-import 关掉底部面板后在「角色」视图粘贴角色卡并确认发送,断言底部面板打开且停在「任务」 角色页与任务面板 是
nav-batch 关掉底部面板后从章节蓝图启动 1 章批量创作,断言底部面板打开且停在「任务」 批量创作运行中 是
nav-home-import 回到首页,点「小说拆解」把参考小说导入当前作品,连嵌入一起卡住模型,断言离开首页、项目树与 AI 输出出现 项目树刷新完成,第 1 步「导入参考文本与构建知识库」卡在第一个嵌入请求上 是
settings-appearance 旧外壳打开设置并切到「外观」。head 比 trunk 多「界面布局」一组,两边截图不同是预期 设置的外观分区 否
nav-immersive-twice 关掉底部面板后两次切换沉浸写作,断言三块面板恢复到切换前 恢复后的工作台 否
nav-plot-blueprint-source 生成剧情树(假模型回复不是 JSON,落到按蓝图的确定性剧情树),从事件来源打开第 1、2 章蓝图;第 1 章标题改了不保存,断言切换选中后改动仍在,手动选第 2 章后再点第 1 章来源会重新选中第 1 章 章节蓝图选中第 1 章、标题有未保存改动 是

nav- 场景对 trunk(--app-root)与 head 各跑一次,两边都通过即行为一致。write-latency 与 startup-timing 一样交替各跑 5 次取中位数。

新外壳(RD-3 起)

页面对象在 scripts/redesign/pages/stage.mjs,选择器用角色与可访问名称(流程脊是 navigation「创作流程」,章节是其中的列表「章节」,标签条是 tablist「已打开的页面」,顶栏是 banner)。示例作品在 scripts/redesign/stage-sample.mjs:「灯塔」12 章全有蓝图,架构四节齐全,1、2 章定稿,3 章已审稿,4 章草稿,其余待写;与旧外壳基线的 SAMPLE 分开,基线截图不受影响。打开后落在第 4 章(几章都在写时取最后一章在写的,#407 第 2 轮用户决定);seedStageSample 默认等落点后切到第 3 章并关掉第 4 章标签,场景都从只开着第 3 章开始(对照用的旧构建本来就落在第 3 章,不切)。两种外壳都能用这份示例:新外壳从书房打开,旧外壳从项目树打开第 3 章草稿。

名称 检查 截图停在 夹具模型 对应计划
stage-open-sample 流程脊四个阶段的状态(设定、架构、蓝图完成,正文进行中)、章节阶段、当前章为 3、只有一个标签时标签条收起、外壳文字对比度(名称 4.5:1,说明 3:1,底色沿祖先叠加求出) 第 3 章正文 否 lane 1 的新外壳部分、lane 2(浅色)、lane 3(--theme dark)
stage-tabs 依次打开设定与蓝图共三个标签,关掉一个后还剩两个且标签条仍在;after 再关一个,标签条收起 两个标签 否 lane 4
stage-dirty-close 改设定页后关「设定」标签,出现危险确认;after 点「继续编辑」,标签与修改都在 危险确认对话框 否 lane 5
stage-save 改小说配置,顶栏变「未保存」,Ctrl S 后变「已保存」 已保存 否 lane 6
stage-find-chapter Ctrl P 输入「4」回车打开第 4 章,再输入「第3章」打开第 3 章,流程脊当前章随之变化 第 3 章正文 否 lane 7
stage-focus 沉浸写作后流程脊与标签条消失,正文与章节动作条(AI 审稿等)在;after 按 Esc 恢复 沉浸写作 否 lane 8
stage-1280 视口 1280×900:页面无横向滚动,外壳里的名称、章名、位置、搜索提示、保存状态都没有被截断或折行 1280 宽 否 lane 9
stage-migrate RD-10 起:去掉 v3 键、在旧键写入 RD-10 之前的配置后重载,galaxy(v1、旧外壳偏好)与 paper(v2)各走一遍:进入纸墨外壳且不出现启动阻塞,galaxy 迁成深色、paper 迁成浅色,缩放照旧,旧键逐字节不变(供回滚) 纸墨外壳 否 RD-10 lane 3、4
stage-palette Ctrl K 输入「灯」,结果里有第 6 章;after 按 Esc 关闭 Ctrl K 结果 否
stage-run 卡住模型后从章节蓝图写下一章:运行侧页自动打开,顶栏胶囊展开并显示进度;after 先确认侧页开着时 Ctrl K 仍能打开搜索(侧页不是模态层),再放行、等侧页里「上一次运行」显示已完成、新草稿打开 运行侧页与胶囊 是
stage-library 没有打开作品时是书房,没有流程脊;书架空着时唯一的主按钮是「新建作品」,没有模型时有「还没有连接 AI 模型」引导;书房文字对比度 空书房 否 RD-5 lane 2
stage-modal-layers 改设定后从作品菜单打开旧的「导出项目」对话框:Ctrl K 不开搜索、Ctrl W 不弹放弃确认;从主进程关窗,退出确认画在对话框之上(isTopmost 让所有元素参与命中测试后取中心点最上层元素);after 取消退出并关掉导出。RD-5 起设置是页面而不是弹窗,所以模态层改用导出对话框;Radix 对话框会把退出确认设为 aria-hidden,页面对象 exitDialog 按类名找它 退出确认 否 第 3 条
stage-close-key 书房里、搜索框里各按一次 Ctrl W,页面都拦下(defaultPrevented),应用仍在。应用菜单有 CommandOrControl+W 的「关闭」,但驱动注入的按键到不了菜单快捷键,所以断言的是拦截 搜索框 否 第 4 条
stage-reopen 从作品菜单回到书房,用 Ctrl K「打开《灯塔》」重新打开同一部作品(新的项目会话),再次落到最后一章在写的第 4 章 第 4 章正文 否 第 8 条
stage-partial-blueprint 规划 100 章、只有 12 章蓝图:蓝图算完成,落点仍是正文第 4 章 第 4 章正文 否 第 6 条
stage-revert-after-final 第 1 章定稿后再建一份新草稿(版本历史「回退到此版本」的效果):第 1 章回到草稿,但最后一章在写的仍是第 4 章,打开作品落在第 4 章;章节列表里第 1 章按草稿显示,点它打开的是新草稿 第 1 章新草稿 否 第 7 条
stage-new-project 新外壳里新建作品:设定进行中、其余未开始;外壳文字对比度、进度环半径 8.5、设定说明在名字下一行、作品资料图标跟随行文字色 新作品首屏 否 第 20、23、24 条
stage-focus-search 沉浸写作里 Ctrl F 打开正文搜索,Esc 只关搜索框、不退出沉浸;after 再按 Esc 退出沉浸 沉浸写作 否 第 10 条
stage-tour 30–60 秒的导览:四个阶段、Ctrl K、Ctrl P、关标签、沉浸写作、写一章看运行胶囊与侧页。配 --video 录评审视频 写完一章 是 Review gate
chapter-switch 打开第 3 章后,从点击第 4 章到它的正文在编辑器里可见,渲染进程内按帧计时,写进 measured.chapterSwitchMs。旧外壳点草稿箱里的草稿,新外壳点流程脊里的章 第 4 章正文 否 perf

lane 1 的旧外壳部分:head 与 trunk 各跑一次 baseline-all,逐张 pixel-diff.mjs,maxRatio 小于 0.005。

perf:三组交替,各预热 2 次不计,再各计 5 次:trunk 旧外壳、head 旧外壳、head 新外壳。head 旧外壳对 trunk 旧外壳量的是新外壳模块被 App.tsx 静态引入后旧外壳用户付出的启动代价。这是 RD-3 到 RD-9 的做法;RD-10 起 head 没有旧外壳,只比 trunk 旧外壳与 head 纸墨外壳两组,下面带 --shell stage 的命令对 head 去掉 --shell。

node scripts/redesign/drive.mjs --scenario startup-timing --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario startup-timing --out <目录>
node scripts/redesign/drive.mjs --scenario startup-timing --shell stage --out <目录>
node scripts/redesign/drive.mjs --scenario chapter-switch --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario chapter-switch --shell stage --out <目录>

startup-timing 三组都先在同一隔离目录启动一次写好主题(新外壳另写外壳偏好)再退出,计时的是之后那次冷启动;首次启动还要迁移旧配置、建库,与之后的启动不可比,所以两侧都不计首次。启动计时以驱动发现「新建作品」可见为准,Playwright 的轮询间隔随等待时间变长,所以晚出现的界面会被多计一些。

运行侧页(RD-4 起)

场景在 scripts/redesign/run-scenarios.mjs,页面对象在 scripts/redesign/pages/run-sheet.mjs(侧页是 complementary「运行」,分页是其中的 tab,运行与恢复项是 article,按标题命名)。假模型另有两种回复:fake.streamProse({ chunks, intervalMs }) 之后的正文按块定速流出,每块发出的时刻记进 fake.streamLog;fake.replyCharacterCards() 之后,提示词里有「【资料 」时回一份角色提取 JSON(守塔人与林岚),不开时照旧回正文、提取失败。复制类操作在页面里改写 navigator.clipboard.writeText 记录内容,不碰系统剪贴板。

名称 检查 截图停在 夹具模型 对应计划
run-write-steps 旧外壳写一章,measured 记下 AI 输出里的步骤名、正文与聊天按钮、「写作助手」区域的数量;head 与 trunk 各跑一次对照 写完的 AI 输出 是 lane 1
run-live 正文定速流出时侧页「进行中」展开当前步骤,实时输出的句数持续增加 正文流到一半 是 lane 2
run-cancel 卡住模型后在运行卡片上点「取消」:没有进行中的运行,顶栏胶囊消失,「上一次运行」写明已取消 取消后的侧页 是 lane 3
run-batch 删掉 3、4 章草稿后批量写两章:Ctrl P 里只有正在写的第 3 章标生成中;暂停后本章写完即停,2 秒内不再有模型请求,没有章标生成中;after 继续并写完 已暂停 是 lane 4
run-confirm 从角色页粘贴两张角色卡:侧页出现「等你确认」与两个采用方式;after 林岚对应已有、守塔人新建,确认后角色列表多了守塔人、林岚仍只有一个 等你确认 是 lane 5
run-discard 预置一条恢复候选:复制得到原文;「放弃…」出现就地确认条且焦点在「保留」;after 确认放弃,收起再打开侧页(重新读取)后候选不再列出 就地确认条 否 lane 6
run-diagnostics 预置三条调用记录后写一章:诊断分页是宽版,调用表三行,复制安全诊断不含正文与密钥,界面文字没有 token(日志行原文除外) 诊断分页 是 lane 7
run-en 切到英文重载:Ctrl K 搜 assistant、agent、chat 都没有结果;写一章时侧页分页是英文,整页没有聊天字样 英文的进行中 是 lane 8
legacy-no-chat 旧外壳:右侧栏只有「AI 输出」,没有 Agent 按钮,右侧区域名为「AI 输出」,整页没有聊天字样;再点一次收起、再点打开 AI 输出 否 lane 9
run-olddata 预置一条助手任务(两轮历史加一轮回复):打开作品与运行侧页没有报错,界面没有调用任何 agent-generation:*(在主进程里包一层 invoke 计数),侧页不列助手任务;after 重开读出的对话内容与之前相同,项目目录里数据库以外的文件没有改动 进行中 是 lane 10
run-tour 30–60 秒的导览:定速写一章看实时输出与完成,历史里展开这次运行,诊断宽版,放弃恢复候选的就地确认后选「保留」,收起侧页再用 Ctrl K 打开。配 --video 录评审视频 进行中 是 Review gate
write-stream 60 块、每块 50 字、间隔 50 ms 的正文流出(3000 字):measured.fps 是第一块到最后一块显示之间的帧率,appendMedianMs、appendP95Ms 是每块从假模型发出到出现在界面上的延迟。两种外壳都能跑,用 --shell stage 选新外壳 写完一章 是 perf

run-olddata 的状态对比只看对话内容:重开作品时主进程会把旧会话里没写完的助手任务登记为暂停、改期限,这是主进程的租约记账,与界面无关。

书房、设定与设置(RD-5 起)

书房、设定页与设置页的页面对象也在 pages/stage.mjs:书架是列表「最近的作品」,封面按钮叫「预览《书名》」,右侧概览是区域「《书名》概览」,里面唯一的主按钮是「打开《书名》」(只预览的书)或「继续写作 · 下一步」(当前作品);每本书的更多操作是「《书名》更多操作」菜单。openFromLibrary 先点封面再点「打开《书名》」,openFromPalette 从 Ctrl K 打开(同一部作品也会开新的会话)。新建作品的对话框旧外壳叫「新建小说项目」,新外壳叫「新建作品」,bookshelf.createProject 两种都认。设定页的核心大纲是文本框「核心大纲」(缺这项时名字带「 · 必填」),三项必填是下拉「类型」「目标读者」与一组「篇幅」,更多设定是按钮组「更多设定」,展开的每项是同名区域;dirtySetup 在核心大纲末尾补一句。假模型认出配置 JSON 合同的提示词时返回 FIXTURE_CONFIG。设置页是导航「设置分组」,每页标题是一级标题;openSettings 从流程脊打开,showSettingsPage 切页,closeSettings 点「返回作品/返回书房」。

名称 检查 截图停在 夹具模型 对应计划
stage-library-preview 预置示例作品但不打开,点封面预览:概览的阶段进度里架构、蓝图完成,正文进行中;没有流程脊(没有打开);唯一的主按钮是「打开《灯塔》」;文字对比度 预览概览 否 lane 3
stage-library-remove 回到书房,书本菜单「从最近项目移除…」出现确认;after 确认后封面消失、作品文件夹仍在 移除确认 否 lane 4
stage-library-delete 当前作品的书本菜单「删除作品…」,输入「灯」时「删除作品」禁用;after 输入完整书名后可用,再取消,文件夹仍在 删除确认(名字不对) 否 lane 5
stage-update-card 夹具更新源(stubUpdates 替换主进程的更新 IPC,安装只计数);设定页改一项未保存,回书房点「下载更新」再点「立即重启更新」,出现「请先处理未保存的修改」与「返回保存」;after 返回保存,安装次数为 0 更新拦截 否 lane 10
stage-setup-required 新外壳新建「雾岛」,写核心大纲、选类型,不选目标读者:「下一步:故事架构」禁用,提示「选好目标读者就能继续」并由 aria-describedby 关联;设定页唯一的主按钮;对比度;after 选目标读者后点下一步,先保存再到架构 必填未齐 否 lane 6
stage-setup-fill 示例作品的设定页点「AI 补全其余设定」,确认扩写已有内容;夹具按配置 JSON 合同返回(FIXTURE_CONFIG),世界观被填上、核心大纲保留作者原文;再改世界观,设定变为未保存 补全后的世界观 是 lane 7
stage-settings-groups 从流程脊打开设置:分组为常用(AI 模型、外观)、高级(检索模型、网络代理、提示词模板、写作 Skills)、其他(项目备份、关于与更新),落在 AI 模型,位置为「设置 / AI 模型」;外观里放大到 105% 再还原;外观页没有主按钮;对比度;after 按 Esc 回到第 3 章 外观 否 You see、缩放移入外观
stage-settings-dark 设置 → 外观 → 主题选「深色」,外壳变深色;context.restart() 退出应用再用同一隔离目录冷启动,仍是深色,外观里「深色」仍选中;深色对比度 深色外观 否 lane 8
stage-settings-model 设置 → AI 模型,夹具模型的更多操作「删除模型…」出现危险确认;after 取消,模型还在 删除模型确认 否 lane 9
stage-first-model 全新配置的空书房点「还没有连接 AI 模型」里的「添加模型」,落在设置的 AI 模型,空状态「还没有添加模型」,唯一的主按钮是添加模型 首次使用的模型页 否 附录 A 首次使用
stage-rd5-tour 30–60 秒的 RD-5 导览:空书房、新建「雾岛」进入设定页、写核心大纲并补齐必填、展开「文风」、下一步到架构、设置的 AI 模型与外观(切深色再切回)、关于与更新、回书房看书架、删除作品确认(名字不对时禁用)。配 --video 录评审视频 书房 否 Review gate
library-timing 计时会话(与 startup-timing 同样先预启动一次,另用公开 IPC 新建 20 部作品):readyToShowToInteractiveMs(书房「新建作品」可见),以及页面里记下的 renderInteractiveMs(「新建作品」进入 DOM)与 renderShelfMs(20 个「预览《书名》」按钮都进入 DOM),都以导航开始为 0。旧欢迎页与新书房的书本按钮同名,所以对 trunk 也能跑 不截图 否 perf
stage-lazy-retry 主进程 webRequest 拦下设定页代码块(blockChunks),重载后打开示例作品点「设定」,出现「页面没有载入」与「重试」;after 放行后点重试,设定页出现,且请求日志里有带 ?retry= 的设定页代码块 载入失败 否 RD-5 修复第 1 轮
stage-setup-save-fail 设定页改一句后让 project:save 返回失败(failProjectSaves 换掉主进程处理函数):Ctrl S 与「下一步」都在页脚出现 role=alert 的失败说明,仍停在设定、仍是未保存;after 换回处理函数再点保存,变为已保存、失败说明消失 保存失败 否 RD-5 修复第 1 轮
stage-setup-short 新建「雾岛」:必填项先不标红;1440×900、1280×800、1280×720 下「类型」「目标读者」都在底栏之上;after 点开「全局写作要求」,面板不在底栏后面、焦点在它的输入框里 1280×720 设定页 否 RD-5 修复第 1 轮
stage-settings-legacy 模型编辑表单的输入框 40px 高;context.shoot 中途拍下模型编辑、提示词模板、写作 Skills;项目备份页只有「导出本地存档」一个实心主按钮 项目备份 否 RD-5 修复第 1 轮
stage-settings-leave 编辑夹具模型改名,输入框里按 Esc 设置页不关;焦点移出后 Esc 弹「放弃未保存的修改?」;after 继续编辑修改还在,「返回作品」再确认放弃才关;再开设置页从 Ctrl K 选「角色」,设置页收起、「角色」标签选中 放弃确认 否 RD-5 修复第 1 轮
stage-settings-leave-work 作品里开着两个标签,设置页改了夹具模型名、不保存:标签条不显示;依次从流程脊阶段「架构」、流程脊资料「剧情与伏笔」、Ctrl K「蓝图」、Ctrl P「旧港」、Ctrl K「回到书房」、作品菜单「回到书房」离开,每次先弹「放弃未保存的修改?」,「继续编辑」后设置页与输入都在,再走一次选「放弃修改」才到去处 每个入口的确认(leave-<入口>) 否 RD-5 修复第 2 轮
stage-settings-leave-library 书房里从顶栏打开设置、改模型名不保存:Ctrl K「打开《灯塔》」、Ctrl O、Ctrl K「打开作品」(系统对话框打桩为示例作品)、Ctrl N、Ctrl K「新建作品」、Ctrl K「小说拆解与仿写」,每次先确认、继续编辑不走;放弃后打开作品(等「项目数据加载完成」)或弹出新建、拆解对话框 每个入口的确认与到达(leave-、arrived-<入口>) 否 RD-5 修复第 2 轮
new-project-files 新建作品后列出作品文件夹里建出的文件(measured.files)与 .ai-novel/project.json 去掉标识、时间后的形状(measured.manifest)。trunk 与 head、两种外壳(--shell stage)各跑一次,两项都应一致 新建作品后 否 RD-5 lane 1

页面内计时

计时会话(startup-timing、library-timing)启动时设环境变量 DRIVE_RENDER_TIMING,offscreen-window.cjs 据此给默认会话注册页面预加载 render-timing-preload.cjs:它在页面脚本之前装好 MutationObserver,把「新建作品」与书架上的书第一次进入 DOM 的时刻(performance.now())写在 <html> 的 data-drive-interactive、data-drive-shelf 上,驱动启动后读出,写进 timing.renderInteractiveMs、timing.renderShelfMs。它们没有 Playwright 轮询的量化误差。其他场景不注册这个预加载。

改外壳时

类名选择器只出现在 scripts/redesign/pages/,按任务域分文件:shell(启动、外壳就绪、标题栏、状态栏、左右栏与可收起面板)、bookshelf(旧外壳书房与两种外壳的新建作品)、project(项目树)、chapter(单章写作、审稿、修稿合并、定稿)、run-panel(运行面板)、settings(设置,含外观里切换界面布局)、materials(知识库与角色卡导入)、stage(新外壳:流程脊、章节列表、标签条、Ctrl K 与 Ctrl P、保存状态、沉浸写作、书房)、run-sheet(新外壳的运行侧页)。shell.waitForShell 对两种外壳都成立。外壳替换后只改这些页面对象,场景 scripts/redesign/scenarios.mjs 不动。

/.claude/ 在 .gitignore 里,提交本文件的改动要用 git add -f .claude/skills/verify/SKILL.md(或 git add -u)。假模型在 scripts/redesign/fake-model.mjs,按提示词特征返回正文、短细纲(与正文同一段文字,但不参与定速流出)、审稿 JSON、修稿正文、角色状态 JSON 或角色提取 JSON。

架构阶段与角色名单(RD-6 起)

场景在 scripts/redesign/arch-scenarios.mjs,页面对象在 scripts/redesign/pages/architecture.mjs(四节是 region,按节名命名;角色名单左栏是 complementary「角色名单」;生成架构对话框是 dialog「生成架构」)。示例作品沿用「灯塔」,按场景清空架构的某几节;示例作品有蓝图与正文,打开后落在写作位置(用户决定 B,#394 §6),场景等落点定下后从流程脊进架构。驱动读库用界面那次打开作品的会话(在主进程里包一层 project:open 记下租约),不必重开作品。夹具模型对「本次只写第 N 章」的情节大纲请求回这一章的二级标题与正文。

名称 检查 截图停在 夹具模型 对应计划
arch-regression 清空前提、世界观、大纲后从架构页生成(角色名单已预置),measured 记下四份文档与哈希;head 与 trunk(--app-root,旧故事架构总览)各跑一次,四份文档逐字相同 生成完的架构页 是 lane 1
arch-partial 两节已确认:主按钮「继续生成架构」且只有一个、「下一步:章节蓝图」置灰,四节徽标,流程脊同为 2 / 4,角色名单一节列出林岚 架构页 否 lane 2
arch-done 四节已确认:主按钮「下一步:章节蓝图」;after 点它进入蓝图 架构页 否 lane 3
arch-confirm 生成架构对话框:勾选已确认的前提标「将覆盖」,角色名单「保留」,空的两节「新生成」 对话框 否 lane 4
arch-resume 24 章的大纲先生成 1–10 章,从提示条续写 11–16 章,提示条写明第 17–24 章还没有大纲;部分完成不算已确认(页头与流程脊 3 / 4、主按钮继续生成、下一步置灰),运行侧页两张大纲恢复稿按范围区分;after 续写 17–24 章,1–16 章逐字不变、1–24 章各一次 第 17–24 章的续写对话框 是 lane 5
arch-rewrite 大纲写到 16 / 24 章后先把第 1–5 章改成作者旧稿,从「AI 重新生成此节…」选第 1–5 章:默认起始章 17,标「将覆盖第 1–5 章」并写明第 6–16 章原样保留,可以提交;after 生成后第 6 章起逐字不变、第 1–5 章换成本次结果,大纲仍是部分完成 16 / 24,页头与流程脊 3 / 4 第 1–5 章的重写对话框 是 修复第 2 轮
arch-legacy-sidebar --shell writer(发布默认外壳):大纲分批写到 16 / 24 章,侧栏「故事架构 4/4」,情节大纲一行不是待生成、行内有清空按钮、右键「清空情节大纲」可用;侧栏写「角色名单」 右键菜单 否 修复第 2 轮
arch-names-en 英文界面:四节 Premise、Cast、World、Outline,名单菜单「View cast as text」打开「Cast as text」标签与指向 Cast 页的横幅,没有旧名字,名单底栏「1 character」 角色名单 否 修复第 2 轮
arch-clear 世界观「清空此节…」出现危险确认;after 取消,摘要、徽标与数据库里的世界观都不变 危险确认 否 lane 6
arch-cast-save 新建「守塔人」并按 Ctrl S 保存:名单、名单投影(db:character-roster-read 的 renderedMarkdown)、架构页「2 位角色」与「查看角色名单全文」都有守塔人 角色名单 否 lane 7
arch-graph 关系图谱放大、滚轮、拖拽(画面变化)都生效;after 点中心节点打开档案 关系图谱 否 lane 8
arch-cards 角色名单里粘贴两张角色卡,运行侧页确认后守塔人进名单、林岚仍只有一个 角色名单 是 lane 9
arch-import-dialog 导入角色卡对话框与外发确认是同一个纸墨对话框的两步(.pi-dialog、底色等于 --surface,不另弹确认框);after 返回并关闭 外发确认 是 lane 9
arch-dark 用 --theme dark 跑(漏传时开头的主题断言失败):架构页文字对比度达标(名称与正文 4.5:1,说明 3:1),分节卡底色等于 --paper 的计算值 架构页 否 lane 10
arch-timing 从点流程脊「架构」到四节可交互的毫秒数(measured.openMs 按动画帧轮询;openDomMs 是 DOM 达到就绪的时刻,屏幕外窗口的动画帧会被节流;ipcDuringOpen 是这段时间主进程按通道收到的 invoke 数),200 位角色时角色列表第 1 页滚动帧率(measured.scrollFps)。trunk 是旧故事架构标签与旧角色列表,head 是架构阶段与角色名单 角色列表 否 perf
arch-tour 30~60 秒的导览:四节与主按钮、对话框的覆盖与保留、清空此节的危险确认、角色名单保存与关系图谱。配 --video 录评审视频 架构页 否 Review gate

perf 交替各跑 5 次取中位数:

node scripts/redesign/drive.mjs --scenario arch-timing --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario arch-timing --out <目录>

蓝图阶段与写作弹层(RD-7 起)

场景在 scripts/redesign/blueprint-scenarios.mjs,页面对象在 scripts/redesign/pages/blueprint.mjs(章节规划是 complementary「章节规划」,单章蓝图是 region「第 N 章蓝图」,写作弹层是 dialog「本次写作选项」,主按钮「写第 N 章」直接开始写)。新外壳从蓝图写下一章的场景(stage-run、stage-tour、运行侧页各场景、write-stream --shell stage)都改走 blueprint.writeNext;旧外壳仍走 chapter.writeNextChapter。新外壳写作此章按设定里的每章字数写,不再在写作时填字数,所以示例作品的每章字数是夹具模型一次写得完的 100。假模型另记 fake.chats:每次对话请求的种类、模型与消息原文。

名称 检查 截图停在 夹具模型 对应计划
blueprint-regression 第 3 章蓝图带出场人物与作者指导,从蓝图写下一章:旧外壳点「写作第 3 章」在对话框里直接开始,新外壳点「写第 3 章」。measured.requests 是每次模型请求的种类、模型与消息的 sha256,proseMessages 是正文请求原文。trunk(--app-root)与 head(--shell stage)两边的 requests 相同即通过 写出的草稿 是 lane 1
blueprint-page 选中第 5 章:标题「逐章规划」、主按钮「写第 3 章」、12 章规划、页头只有一个拆分主按钮、蓝图页文字对比度(名称 4.5:1,说明 3:1;章节规划的状态文字 .stage-bp-plan-status 每种状态都查,含默认的待写)。选择器清单是 blueprint-scenarios.mjs 的 PAGE_CONTRAST,算法与外壳共用 scenarios.mjs 的 contrastFailures。浅色、深色各跑一次 蓝图页 否 lane 2、lane 10(--theme dark)
blueprint-popover 打开「本次写作选项」:只有本次模型、作者微操指导、折叠的更多(检索关键词),整页只有这一个对话层 写作弹层 否 lane 3
blueprint-preflight 主进程里把 db:continuity-list-before 换成夹具(第 1 章守塔人已死),点写第 3 章:弹层里出现一致性预检,有保存安排、仅本次忽略、改蓝图后重检,模型没有收到请求;after 换回原处理函数后仅本次忽略,写完 一致性预检 是 lane 4
blueprint-overwrite AI 生成蓝图选覆盖后开始:生成对话框先收起,危险确认「覆盖已有蓝图?」写明会替换 12 章;after 取消后生成对话框原样回来,没有错误提示,蓝图不变 覆盖确认 否 lane 5
blueprint-batch 删掉 3、4 章草稿后批量创作 4 章:运行侧页出现批量卡(第 3 至 6 章);after 取消 批量卡 是 lane 6
blueprint-clear 更多蓝图操作的危险分组里清空全部蓝图,危险确认后列表为空,出现空状态与 AI 生成蓝图 空状态 否 lane 7
blueprint-recover 规划 16 章,生成第 13~16 章蓝图(假模型回正文,生成失败留下恢复稿):蓝图页出现恢复稿提示条,「编辑恢复稿」打开恢复稿标签,「继续生成缺少的章节」可用;after 点它,模型再次收到请求 恢复稿标签 是 lane 8
blueprint-save 改第 6 章标题:整页只有顶栏一处「未保存」,Ctrl S 后变「已保存」,重新加载后标题仍在 已保存 否 lane 9
blueprint-finalize-next 第 3 章草稿定稿,设置里开着「定稿后打开下一章」(F-056):落到第 4 章的单章视图,写作弹层由这一章「写作此章」旁的「本次写作选项」打开(aria-controls 指向弹层)并贴着它展开,只弹出写作弹层,没有旧的创作对话框 写作弹层 是 F-056
blueprint-tour 30–60 秒导览:选章改标题保存、清空的危险确认、生成蓝图覆盖、批量创作、写作弹层、一致性预检、仅本次忽略后写完。配 --video 录评审视频 写完一章 是 Review gate
blueprint-timing 300 章蓝图:从点蓝图到第 300 章出现在列表里(openMs),从点第 150 章到它的标题出现(switchMs),渲染进程内按帧计时。旧外壳点项目树「章节蓝图」与列表项,两种外壳都能跑 第 150 章 否 perf
node scripts/redesign/drive.mjs --scenario blueprint-regression --app-root <trunk 工作树> --out <目录>/trunk
node scripts/redesign/drive.mjs --scenario blueprint-regression --shell stage --out <目录>/head
node scripts/redesign/drive.mjs --scenario blueprint-timing --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario blueprint-timing --shell stage --out <目录>

正文单章视图(RD-8 起)

场景在 scripts/redesign/chapter-scenarios.mjs,页面对象在 scripts/redesign/pages/chapter-view.mjs(单章视图是 .stage-ch,审稿侧页是 complementary「审稿报告」,修稿合并是 region「修稿合并」,定稿后处理是 region「定稿后处理」,版本切换器是按钮「本章版本:…」,定稿确认是 dialog「定稿第 N 章?」)。新外壳打开第 N 章就是单章视图,示例作品第 3 章带一份审稿(已审稿,打开时默认展开审稿侧页);待写章显示本章蓝图与「写作此章」,草稿状态主按钮是 AI 审稿,已审稿是「按 N 项意见修稿」,有待合并修稿时直接摆出合并视图,已修稿是定稿,定稿后列出后处理各步。假模型另有 fake.breakCharacterState():之后定稿后处理的角色状态更新收到不是 JSON 的回复而失败,传 false 恢复。

名称 检查 截图停在 夹具模型 对应计划
chapter-regression 删掉 3、4 章草稿后写第 3 章,走完审稿、按意见修稿、全部用修稿合并、等复验、定稿;measured 是定稿正文的 sha256 与后处理各步成败(从数据库读)。trunk(--app-root,旧外壳)与 head(--shell stage)两边相同即通过。读库要回书房重开作品,新外壳之后再打开第 3 章 定稿视图(新外壳)、书房(旧外壳) 是 lane 1
chapter-draft 第 4 章草稿:主按钮 AI 审稿,生命周期停在审稿,版本切换器「草稿 v1 · N 字」 草稿 否 lane 2
chapter-review 第 4 章 AI 审稿后侧页展开;取消、再勾一条意见时主按钮「按 N 项意见修稿」与侧页底部「N / 总数」同步 审稿侧页 是 lane 3
chapter-manual 添加我的意见后修稿,假模型收到的修稿请求里有这条意见 合并视图 是 lane 4
chapter-merge 修稿后合并视图第一处用修稿(多于一处时第二处手动编辑);after 完成合并,正文里是选中的文字 逐段选择 是 lane 5
chapter-finalize 第 3 章从「更多」定稿,确认后正文只读,后处理「4 / 4 完成」(正文文件与三步后处理) 定稿视图 是 lane 6
chapter-retry 角色状态更新失败后点「重试失败步骤」:之后假模型只收到角色状态请求,后处理回到 4 / 4 重试后的定稿视图 是 lane 7
chapter-selection 选中一段:工具条四个纸墨按钮(润色、扩写、续写、改成对话);润色预览后替换,再选一段润色后取消,原文不变 选区工具条 是 lane 8
chapter-delete 第 4 章有 v1、v2:从「更多」删除这一稿出现危险确认;after 确认后版本切换器只剩 v1 危险确认 否 lane 9
chapter-1280 视口 1280×900(配 --theme dark):第 3 章打开时审稿侧页已展开,收起它后正文一行 32~35 字;运行侧页打开后不少于 24 字,页面没有横向滚动 运行侧页与纸面 否 lane 10
chapter-sheet-landing 删掉第 4 章的稿,打开作品落在已审稿的第 3 章:审稿侧页刚出现与 4 秒后都展开(不先开后收);换到带历史审稿的已定稿第 2 章不展开,「更多」里有审稿报告;回到第 3 章仍展开 审稿侧页 否 侧页归属
chapter-sheets-1280、chapter-sheets-1440 第 3 章(已审稿)在该宽度下先开运行侧页、再从「更多」开审稿报告:同一时间只有一个侧页,纸面不被盖住,正文一行不少于 24 字,没有横向滚动 审稿侧页与纸面 否 双侧页
chapter-focus 1440 宽打开第 4 章进入沉浸写作:内容面板无外边距、圆角与阴影(全出血);底部「N / 设定每章字数 字」与进度条;正文首行缩进 36px 沉浸写作 否 Focus 画板
chapter-tour 30~60 秒导览:检查维度、审稿侧页与作者意见、按意见修稿、逐段合并、定稿确认、定稿后处理。配 --video 录评审视频 定稿视图 是 Review gate
chapter-open 1 万字的第 5 章:从点击(新外壳点流程脊里的章,旧外壳点草稿箱)到正文出现且所在滚动区可以滚动,毫秒,不取整。frameMs 按动画帧检查,domMs 在 DOM 变化回调里记,不依赖动画帧 第 5 章 否 perf
typing-latency 在第 5 章第 1 段末尾连续输入 40 个字母:每键从 beforeinput 到正文 DOM 变化(domP95Ms)与之后第一帧(frameP95Ms) 第 5 章 否 perf
node scripts/redesign/drive.mjs --scenario chapter-regression --app-root <trunk 工作树> --out <目录>/trunk
node scripts/redesign/drive.mjs --scenario chapter-regression --shell stage --out <目录>/head
node scripts/redesign/drive.mjs --scenario chapter-open --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario chapter-open --shell stage --out <目录>
node scripts/redesign/drive.mjs --scenario typing-latency --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario typing-latency --shell stage --out <目录>

草稿、审稿、合并、定稿、1280 与沉浸写作各场景都用 contrastFailures 核对单章视图的文字对比度(正文与合并栏 4.5,说明文字 3)。屏幕外窗口的动画帧可能被系统节流,chapter-open 与 typing-latency 都同时报不依赖动画帧的 DOM 口径。RD-X1 起打开作品的默认落点随提交同步落下,读文件树期间打开的运行侧页不再被收起(x1-run-sheet-keep);afterProjectOpenSettles 的 2 秒等待是之前留下的,保留无害。审稿侧页属于单章视图,不随落点收起。

作品资料页(RD-9 起)

场景在 scripts/redesign/refs-scenarios.mjs,页面对象在 scripts/redesign/pages/refs.mjs(流程脊「作品资料」里的三个按钮;剧情树是 table「剧情树」,线索路线是 list「线索路线」,知识库资料是 navigation「资料」,版本历史的章节是 navigation「章节」、各稿是 list「版本时间线」、对比是 region「对比」里的 article「与当前稿的差异」)。示例作品在 seedStageSample 之上加一条伏笔线索「雾钟为何提前」和第 3 章的第二稿。fake.replyPlotTree() 之后的剧情树整理回一份两轨 JSON(定稿章与单数位蓝图章进主线「雾钟与沉船」,双数位蓝图章进支线「父亲的地图」),来源取自提示里的资料;不开时假模型回正文,剧情树落到单轨的确定性快照。知识库导入用 stubOpenFiles 让系统打开对话框直接返回两份资料,外发提取确认点「取消」。

名称 检查 截图停在 夹具模型 对应计划
refs-regression 生成剧情树后从主进程读出快照,measured.tracks 是轨道与事件。head 用 --shell stage,trunk 用 --app-root,两边 tracks 逐字相同即通过 剧情树 是 lane 1
refs-plot 剧情树两行依次是主线、支线,主线有已定稿发生的事件;页面写明只读快照、不参与写作;点事件后出现「打开来源:第 1 章定稿」 选中事件的剧情树 是 lane 2
refs-clear 「更多」里的「清除剧情树…」弹出危险确认;after 取消,剧情树仍在 危险确认 是 lane 3
refs-threads 线索路线起初是埋设未到、推进不显示、解决未到;记录第 1 章定稿里的变化后,埋设一站变成已发生 推进后的线索 否 lane 4
refs-delete 线索行「更多」里的「删除线索…」弹出危险确认;after 取消,线索仍在 危险确认 否 lane 5
refs-kb 导入两份资料后查「雾钟」,结果片段里标出查找词;整窗文字、可访问名称、提示与占位里没有 LanceDB、FTS、BM25、Embedding、向量、query、MCP、token 查找结果 是 lane 6
refs-kb-dirty 改了项目副本不保存就点另一份资料,弹出放弃修改的确认;after 选「继续编辑」,修改还在,再按 Ctrl S 保存后「有未保存的修改」消失 未保存确认 是 lane 7
refs-diff 第 3 章选草稿 v1:对比是 aria-readonly 的差异页,标出新增,区域里没有输入框、可编辑元素或编辑器,没有「完成合并」 只读对比 否 lane 8
refs-revert 回退到草稿 v1:确认里写明新建草稿 v3;确认后时间线依次是草稿 v3、v2、v1,选 v3 显示「与当前稿相同」 回退后的时间线 否 lane 9
refs-dark 用 --theme dark 跑:知识库、版本历史、剧情树三页各查一次资料页文字对比度(标题与正文 4.5:1,说明 3:1;选中章序号、选中稿说明与对比里删去的字按 4.5:1),最后再查外壳 深色剧情树 是 lane 10
refs-kb-finalized 在第 3 章正文里点「定稿」并确认,等运行侧页写明已完成;知识库「定稿章节 1」里是第 3 章、「我导入的 0」,点开只有「这一章由定稿自动收入」,没有编辑框 定稿章节一栏 是 定稿入库
refs-narrow-{plot,kb,history}-{1280,1440} 视口 1280 或 1440,导入资料后运行侧页开着:剧情树的模型、生成与「更多」同一行,线索名称不折行、「更多」与路线同一行;知识库原文宽不小于 300px;版本对比头的标签都不折行、对比正文宽不小于 420px。measured.contentWidth 是内容区宽 侧页开着的资料页 是 窄宽度
refs-tour 30–60 秒的导览:生成剧情树、选事件、清除确认后取消、伏笔线索、导入资料并查找、版本对比、回退新建 v3。配 --video 录评审视频 剧情与伏笔标签 是 Review gate
refs-timing 100 章、每章 5 稿,用夹具模型整理好剧情树并停在剧情树页;计时从点版本历史到第 100 章出现在章节列表(historyOpenMs),再从点剧情树到第 1 章事件出现在表格里(plotOpenMs),渲染进程内按帧计时 剧情树 是 perf

perf:trunk 与 head 交替各跑 5 次,取两项各自的中位数。head 加 --shell stage,trunk 用旧外壳的左栏「历史」「剧情」进入。

node scripts/redesign/drive.mjs --scenario refs-timing --app-root <trunk 工作树> --out <目录>
node scripts/redesign/drive.mjs --scenario refs-timing --shell stage --out <目录>

统一视觉层(RD-V)

场景在 scripts/redesign/visual-scenarios.mjs,都走新外壳,浅深各跑一次。断言的是浮层渲染进带 .paper-ink 的纸墨根或宿主(#ai-novel-ink-overlay),才取得到纸墨令牌与深色。对话框类场景截图前等 400 ms,让遮罩与对话框的淡入走完。

名称 检查 截图停在 夹具模型
rdv-clear 作品菜单「清除生成内容…」:标准危险确认,焦点在「取消」,三类内容是勾选行,取消一项后后果句改成「将清除 2 类内容」;after 按 Esc 关闭 危险确认 否
rdv-alert 书房里在同一目录再建一部同名作品,主进程拒绝,命令式 alertError 渲染进纸墨宿主,焦点在「确定」,旧「新建小说项目」对话框也在宿主里;after 点「确定」 叠在新建作品对话框上的错误弹框 否
rdv-toasts 预置两条调用记录后写一章,在诊断分页连点三次「复制安全诊断」再让剪贴板失败点一次:三次成功合并成一条,出错的另起一条,只有一个提示栈,通知互不重叠,measured.toasts 是栈里的条数 右下角提示栈 是
rdv-toast-error 同上写一章,先复制成功一次让提示栈出现,再打开 Ctrl K 面板(Radix 模态)后让复制失败:出错通知是八角符号,卡片自身不带 role,不在 aria-hidden 子树里,经挂载点 #ai-novel-ink-toasts 的 aria-live="polite" 播报(挂载点内没有任何 role="alert"),面板仍开着;after 按 Esc 面板上方的出错通知 是
rdv-toast-flood 打开样例作品,按 app.getAppPath() 找到构建产物 dist/assets/ToastStack-*.js,在页面里 import 同一模块(与应用共享栈状态),推入 24 条常驻出错通知:栈在顶栏以下(top >= 48)、视口以内,标 data-overflow 可滚动,最新一条露在栈底;滚到顶关掉最早那条剩 23 条,中途拍 rdv-toast-flood-top。推入函数是按压缩产物里的 exiting:!1 找到的,换压缩器或改了条目字段就要改这里 滚回底部的满栈 否
rdv-clear-busy 主进程的 db:project-clear-generated-data 换成永不返回,点「清除所选」:按钮写「清除中…」、aria-busy、禁用,三个勾选禁用,Esc 关不掉,指针停在按钮上 清除中的危险确认 否
rdv-run-failure 粘贴一张角色卡但假模型不回提取 JSON:运行失败,运行卡里的失败提示是朱批(没有底色);关掉导入对话框 运行侧页的失败提示 是
rdv-export 作品菜单「导出…」:旧导出对话框 Portal 进纸墨宿主,外壳是 pi-dialog 导出对话框 否
rdv-import-novel 作品菜单「小说拆解与仿写…」:旧拆解对话框 Portal 进纸墨宿主 拆解对话框 否
rdv-settings 从流程脊打开设置,先进「提示词模板」中途拍 rdv-settings-prompts,再进「项目备份」;after 点「返回作品」。两页都是旧面板,看旧按钮变体在新外壳下换成纸墨按钮 项目备份(中途一张提示词模板) 否
rdv-tour 30–60 秒的评审导览:清除生成内容的危险确认(勾掉一项)、旧导出对话框、写一章后连点「复制安全诊断」看提示栈(两次成功合并,一次失败另起出错通知)、粘贴角色卡看运行失败的朱批提示。配 --video 录评审视频 运行失败提示 是

外部审查修复(RD-X1)

场景在 scripts/redesign/x1-scenarios.mjs,都走新外壳。竞态用主进程通道上的门稳定复现:holdChannel(app, 通道, { after }) 卡住接下来的调用,after: true 时先交给原处理函数、卡住的是回复(主进程已做完、渲染进程迟迟收不到);untilHeld 等到有调用卡在门上,releaseChannel 放行。recordCalls 记下通道之后每次调用所属的作品路径,stubChannel 把通道换成固定回复并计数;两者遇到主进程没有的通道都直接报错,通道改名后断言不会因为记不到调用而假绿。seedTwoBooks 先建「港口」(三章定稿,第 3 章定稿带历史审稿),再建并打开灯塔;两部作品第 3 章的稿 id 相同。假模型另有 fake.failProse():之后的正文回复(含 streamProse 的流式回复)以 content_filter 结束,写稿在这次打开里失败。蓝图页的 generateRange 让「架构还不完整」警告与运行侧页展开竞争等待,调用前运行侧页要收起。除 x1-open-folder-cancel(RD-V 栈顶上也应通过)和 x1-import-overlap(RD-V 栈顶不适用)外,每个场景对 RD-V 栈顶的构建(--app-root)跑一次应失败;所有场景对 head 跑一次都应通过。

名称 检查 截图停在 夹具模型 对应
x1-kb-late-read 导入两份资料;点「守塔人小传」时读取卡住,切到版本历史再切回,改「沉船名录」后放行:编辑框仍是改过的沉船名录,带未保存标记 知识库 是 #388 T1
x1-setup-leave 设定页改一句点「下一步」,保存卡住时回书房,放行后仍在书房 书房 否 #380 C4
x1-settings-section 写作 Skills 填地址不保存:Ctrl K「设置」先确认,继续编辑留在原页、输入还在;作品菜单「项目备份」确认放弃后到项目备份 项目备份 否 #380 C1
x1-write-switch 一致性预检里保存安排、回复卡住时回书房用 Ctrl K 打开港口(作品条目只在书房的 Ctrl K 里),放行后港口里没有写作的启动调用,模型没收到正文请求 港口 是 #387 C1
x1-waive-all 第 4 章 AI 审稿(复验周期由审稿写回建立,才有「不修改此项」),侧页每条都选「不修改此项」:主按钮变成「确认不修改」,确认后提示已确认;换到第 3 章再回来仍是已确认(读自数据库) 第 4 章 是 #392 T1
x1-cleanup-retry 第 3 章另有草稿 v1;把 v2 定稿(真实后处理写出正文文件),另起 PowerShell 进程只共享读地占住正文 txt(按 PID 结束),删除正文:落在 v1 的单章视图上,有「删除正文后的清理没有完成」且原因是 EBUSY;放开文件后点重试清理,提示消失、文件已删 v1 单章视图 是 #392 T2
x1-run-recovery failProse 后写下一章:运行失败,运行侧页「可恢复的内容」立即列出第 3 章候选 运行侧页 是 #381 C1
x1-waiver-switch 第 4 章 AI 审稿后每条都选「不修改此项」,点「确认不修改」时读审稿原文卡住;回书房用 Ctrl K 打开港口并打开运行侧页,放行后运行侧页还开着,没有被换成灯塔那一稿的审稿侧页 港口运行侧页 是 #405 r2 C1
x1-setup-save-remount 设定页改一句按 Ctrl S,保存卡住时切到第 3 章标签再切回:下一步仍不可点,再按 Ctrl S 也不重发,放行后主进程只收到 1 次保存 设定 否 #405 r2 复验低项 7
x1-generate-slow-warning 规划 16 章,生成第 13~16 章蓝图时读架构(db:project-core-get)卡 4.5 秒:「架构还不完整」晚于 3 秒出现,generateRange 仍点继续生成,运行侧页展开 运行侧页 是 #405 r2 O8
x1-generate-no-warning 同上但主进程读架构时补上角色名单:没有警告,generateRange 在运行侧页展开时返回,记下耗时(旧写法固定多等 3 秒) 运行侧页 是 #405 r2 O8
x1-review-sheet-switch 灯塔第 3 章审稿侧页开着时回书房用 Ctrl K 打开港口,再开港口同 id 的已定稿第 3 章:审稿侧页不展开 港口第 3 章 否 #399 §1
x1-import-settings 书房里导入旧项目副本(对话框与复制打桩,复制卡住),期间在设置页填地址;复制完成要打开作品时先确认,继续编辑后设置页与输入都在,作品没有打开 设置页 否 #404 第 1 项
x1-open-folder-order 设置页有没保存的输入时 Ctrl O、作品菜单「打开其他作品…」先确认,确认框出现时还没有弹选文件夹,继续编辑后也不弹 设置页 否 #404 第 2 项
x1-open-folder-cancel 选文件夹打桩成取消。设置页有没保存的输入时 Ctrl O、作品菜单「打开其他作品…」(问放弃就选放弃修改),再清空输入后 Ctrl O:三次之后设置页都还开着,输入还在。RD-V 栈顶上也应通过(它先选文件夹),上一轮 45656084 上失败 设置页 否 #405 r1-1
x1-import-overlap 同 x1-import-settings 到确认框出现,再按 Ctrl N:出现提示「请先处理『放弃未保存的修改?』」;选继续编辑:没有弹新建,输入还在,回书房后「导入旧项目副本…」可点。RD-V 栈顶没有这个确认框,不适用;上一轮 45656084 上导入入口一直禁用 书房导入菜单 否 #405 r1-2
x1-open-folder-pick 只替换 Electron 的选文件夹对话框(选到港口,授权照常签发)。灯塔设置页有没保存的输入时 Ctrl O:确认框出现前没弹选文件夹,选放弃修改后弹一次,设置页收起、打开港口,不再问。RD-V 栈顶先选文件夹,失败 港口 否 #405 r1-1
x1-library-return 先回一次书房,再从书房 Ctrl K 重新打开灯塔,读文件树卡住时进作品又回书房,放行后仍在书房(落点晚到的版本只比较提交前后的布局,两次都是作者亲手回的书房) 书房 否 #403
x1-run-sheet-keep 从书房打开灯塔,读文件树卡住时打开运行侧页,放行后侧页仍开着 运行侧页 否 #395

外部审查修复(RD-X2)

场景在 scripts/redesign/x2-scenarios.mjs,都走新外壳,复用 RD-X1 的 holdChannel、untilHeld、releaseChannel 与 seedHarbor。每个场景把作者看到的值收进 measured 最后一次断言,对 RD-X1 栈顶的构建(--app-root)跑一次应失败,失败消息里能看到每一项的值。假模型另有 fake.replyReview(json):之后的审稿(含合并后的复验)回这份 JSON;复验只覆盖带正文证据区间的本章目标意见,默认审稿只有文学类意见,合并后不会复验。主进程没有默认检索模型时退回默认生成模型,所以要演示「没有检索模型」得先删掉生成模型。

名称 检查 截图停在 夹具模型 对应
x2-landing 「荒岛」只有架构(大纲分批写到第 6 章)、「北堤」再加三章蓝图、「南湾」只有第 1 章定稿没有蓝图、「空港」只有一份空的草稿、灯塔(同样的大纲)有蓝图与正文、第 3、4 章都在写:书房依次打开分别落在架构、正文第 1 章、正文第 1 章、架构(空稿不算开始)、正文第 4 章(最后一章在写的);再从书房「打开作品」选文件夹打开灯塔,仍落在第 4 章;点第 1 章再点「正文」回到第 4 章;回书房后主按钮是「继续写作 · 第 4 章 · 待审稿」 书房概览 否 #394 §6、#407 第 2 轮第 1、2 条
x2-outline 大纲带分批尾标但末尾多一个换行:徽标「不完整」、页头 3 / 4、下一步不可点;生成对话框选 1–12 章标「范围无效」、提交不可点 架构页 否 #394 §1、§2
x2-library-overview 书房预览港口后点「回到《灯塔》」,概览不再是读取中、显示摘录;再预览港口并从最近项目移除它,灯塔概览照常 书房 否 #380 C3、O23
x2-history 版本历史再点第 3 章各稿还在;读第 4 章各稿卡住时显示「正在读取…」;版本历史与单章版本切换器的时间等于库里 UTC 时刻换成本地时间 第 3 章 否 #388 T2、T12、T8
x2-index-model 有检索模型并导入资料后去掉生成模型,在设置「检索模型」页删掉检索模型:索引区回到「配置并启用检索模型后…」,没有重建按钮 检索模型页 是 #388 T3
x2-kb-limit 查找「守塔人」后在框里改字不提交,「最多显示」改成 5:主进程收到 [守塔人,10]、[守塔人,5] 两次查找 知识库 是 #388 T15
x2-cast 角色档案三个视图里只有基础设定有头像按钮;粘贴角色卡的全文框至少 9 行高 角色名单 否 #389 X1、O#2
x2-recheck replyReview 让审稿回第 4 章关键事件未完成(带证据);审稿、按意见修稿、全部用修稿合并,自动复验跑完:提示「复验完成:x / y 项意见已解决」,审稿报告逐项标复验结果 审稿报告 是 #392 T3
x2-blueprint-save 蓝图页改第 5 章标题并「保存此章」,流程脊第 5 章显示新标题 第 3 章 否 #377 R1
x2-open-chapter 读第 4 章正文卡住时点流程脊「设定」,放行后仍在设定 设定页 否 #377 R2

外部审查修复(RD-X3)

场景在 scripts/redesign/rdx3-scenarios.mjs,都走新外壳。要看修复前的样子,用 --app-root 指向 RD-V 栈顶(87097dbb)的构建再跑一次:这些场景在那边应当失败。

名称 检查 截图停在 夹具模型
rdx3-popover-1280、rdx3-popover-1024 视口设成 1280×720 或 1024×640,第 3 章出场三人,主进程的 db:continuity-list-before 换成三人都已死的事实:写作弹层出三条预检提醒,停在视口内(下沿留 8px)并在内部滚动,滚到底「仅本次忽略」在视口内点得到,内部滚动不关弹层;中途拍 -top,after 换回原处理函数并按 Esc 滚到底的写作弹层 是
rdx3-keyboard 按 Tab 走到流程脊当前阶段行、激活的内容标签、拆分主按钮两半、运行侧页分段页签的选中项,各自 :focus-visible 且 box-shadow 含强调色,逐个截图;measured 是五处的 box-shadow 运行侧页的分段页签 否
rdx3-import-dialog 作品菜单「小说拆解与仿写…」:对话框里只有一个 .pi-btn--primary,带 aria-pressed 的切换按钮都是次按钮;after 按 Esc 拆解对话框 否
rdx3-toast-resize 推入 11 条常驻出错通知(推入函数的找法同 rdv-toast-flood),1440×900 下不溢出;视口缩到 1100×640 后栈标 data-overflow、最新一条露在栈底、卡片右缘到窗口右缘的距离不变。measured.shiftWithoutCompensation 是去掉滚动条补偿时卡片会左移的像素 缩窗后的满栈 否
rdx3-long-title 主进程把 project:open 返回的作品名换成 80 个字(项目文件夹不能这么长),视口 1024×640:顶栏作品名以省略号收尾,关闭按钮右缘在窗口内 顶栏 否
rdx3-inline-confirm-focus 写一章让诊断分页有日志:「清空日志…」的确认条用鼠标点「保留」、按 Esc、键盘打开后 Esc 与回车「保留」,恢复候选「放弃…」的确认条点「保留」与按 Esc,每次焦点都回到打开它的按钮。measured.focusLog 是页面里记下的每次焦点移动 诊断分页 是
rdx3-plan-ring 蓝图页选中第 5 章,当前章行与第 6 章行各按 Tab 聚焦:截行四周的图数强调色像素,聚焦比不聚焦多出一整圈 2px 环(不少于 4 ×(宽 + 高)× 0.8),只选中的当前章没有这圈环;withoutContainment 是去掉列表项 content-visibility 后的同一计数,与聚焦时相等说明环没被裁。像素解码在 png.mjs,与 pixel-diff.mjs 共用 第 6 章行聚焦 否
rdx3-work-menu-focus 作品菜单「导出…」「小说拆解与仿写…」「清除生成内容…」打开的对话框,按 Esc、点「取消」或「关闭」关掉后焦点都回到作品菜单按钮 回到作品菜单按钮后 否
rdx3-toast-wheel 作品菜单「清除生成内容…」开着(Radix 模态)时推入 24 条常驻出错通知:栈可滚动、滚动条 6px,鼠标停在栈上真滚轮往上滚超过 100px 滚上去的满栈 否
rdx3-write-after-discard 开着「定稿后打开下一章」,第 3 章定稿后扣住第 4 章的读取,期间在设置页改出未保存的模型名;放行后弹「放弃未保存的修改?」,点「放弃修改」:第 4 章自动弹出的写作弹层还开着、焦点在弹层里,弹层打开后焦点没有落到弹层外。measured.log 是页面里按时间记下的弹层开合与焦点移动 写作弹层 是
rdx3-write-after-discard-sheet 同上,但放弃确认弹出前点过运行侧页的「历史」页签:确认关掉后的还焦点不抢走写作弹层的焦点。两者先后不定,只断言「历史」若拿到焦点是在弹层打开之前 写作弹层 是
rdx3-prompt-over-exit 设定里改出未保存的输入后只勾蓝图清除生成内容,主进程扣住 db:project-clear-generated-data(原处理在 after 里放回);期间从主进程关窗弹出退出确认,再放行一个失败:「清除失败」提示画在退出确认之上(isTopmost),退出确认露在提示外的上沿命中提示的遮罩、截图亮度比提示纸面暗至少 10(exposedEdge,无重影),「确定」点得到,确定后退出确认还在且在最上层 退出确认 否
rdx3-exit-over-prompt 同上但反过来:先放行一个说明很长的失败,「清除失败」提示比退出确认高;提示开着时关窗,退出确认在最上层、焦点在它里面,提示露在外的上下沿命中退出确认的遮罩并被压暗;取消退出确认后提示在最上层、「确定」点得到 退出确认 否
rdx3-candidates-en 夹具模型的角色提取只回一张卡;从「角色」粘贴一张角色卡,运行侧页出确认卡后在设置的外观页把界面语言切成英文,确认卡写「1 character candidate」(不是 candidates);after 切回中文,再等批次就绪、把守塔人按新建确认,走完这次待确认的运行,退出时不再弹「创作任务仍在运行」 运行侧页 是
rdx3-prose-keys 打开第 4 章草稿(新外壳单章视图或旧外壳草稿编辑器,--shell 选),末尾输入「※※※」「——他说,钟声提前了。」「◇◆◇」三段:新外壳纸面上两行分节符不缩进、对白缩进 36px(旧外壳编辑器本来不缩进,不查);Tab 插两个 em 空格,Esc 后停 2.5 秒再按 Tab 焦点移出编辑区、不插空格,Esc 后按了方向键 Tab 又插空格。两种外壳各跑一次 焦点移出编辑区后 否
rdx3-hover-focus 书房里鼠标停在「新建作品」卡上再按 Tab 聚焦它,box-shadow 是焦点环(悬停样式不盖掉它);打开作品后键盘打开作品菜单,首项、方向键下一项、End 末项的 box-shadow 都是菜单自己的 2px 内侧环,不是外壳的外圈;中途拍 -start、-menu-first、-menu-last 菜单末项聚焦 否

切换默认外壳(RD-10)

场景在 scripts/redesign/rd10-scenarios.mjs,对应计划 RD-10 的实机 lane 与功能保全矩阵的验证截图。被测构建是 RD-10 之后的纸墨外壳,--app-root 指向最终安装包的构建树。

名称 检查 截图停在 夹具模型 对应计划
rd10-keyboard 只用键盘:Ctrl K 去蓝图,Tab 到下一章的「写第 N 章」(样例里是第 3 章)回车开写,写完 Tab 进正文补一句、Ctrl S 保存,再按 Esc、Tab 离开编辑区。每一步记下焦点落点与焦点环(:focus-visible 且 box-shadow 或 outline 含强调色;正文编辑区以插入点为标记),measured.missingRing 为空 保存后离开编辑区 是 lane 7
rd10-esc-after-typing 第 4 章正文里分别用逐键按键、insertText、CDP 模拟的输入法组字(imeSetComposition 再 insertText)各打几个字,每次打完立刻按 Esc、Tab:焦点离开编辑区,正文里不多出全角空格(measured.results 三项都 left: true、emSpacesAdded: 0) 最后一次 Tab 之后 否 lane 7
rd10-en 界面语言切成英文后走书房、四个阶段、角色名单、第 3 章与第 1 章、运行侧页、三个作品资料页、导出与清除对话框、设置各页;每页的可见文字与可访问名称去掉作品内容后不剩汉字,measured.untranslated 为空 设置的外观页 否 lane 6
rd10-widths 1280×900 与 1920×1080 下依次截第 3 章、角色名单、蓝图、书房(rd10-widths-<宽>-<页>),文档与外壳都没有横向溢出。浅色、深色各跑一次(--theme) 1920 宽的书房 否 lane 10
rd10-knowledge-narrow 1280×900 下打开知识库再展开运行侧页(资料栏只剩约 200px),中文、英文各一次:资料栏里每个按钮留在所在的框里、文字不伸出按钮,分段两项不折行,资料栏没有横向溢出(measured.<语言>.problems 为空) 英文界面的窄资料栏 否 lane 10、F27
rd10-tab-menu 打开设定与蓝图共三个标签,展开「标签操作」:已打开的页面与关闭当前、其他、右侧、全部四个动作 标签操作菜单 否 F-183、F-184
rd10-tab-overflow 1280×900 下开着运行侧页,打开作品资料各页与几章直到标签条横向滚动,最后打开的标签在最右端激活:「标签操作」按钮中心那一点上是按钮本身,在那里真实点一下打开菜单,标签一个不少 打开的标签菜单 否 F-183、F-184
rd10-candidate-page 运行侧页可恢复的正文候选「继续编辑」打开纸墨正文页,候选正文在纸面上 恢复候选正文页 否 F-072
rd10-tour 评审视频(配 --video,约 45 秒):书房概览、打开作品走四个阶段与角色名单、正文第 3 章,设置的外观只有浅色与深色两套(没有皮肤与界面布局),切到深色再切回,回书房 书房 否 Review gate

Version History

  • bb4affb Current 2026-10-18 19:05

Metadata

Files
0
Version
bb4affb
Hash
fca18ec5
Indexed
2026-10-18 19:05

홈 - 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-28 11:25
浙ICP备14020137号-1