Skip to content

feat(editor): 修订显示三态切换(全部修订 / 简洁标记 / 最终稿)+ AI 命令按页边语义执行的守卫(dev-board#368) - #707

Merged
zeweihan merged 1 commit into
masterfrom
worktree-agent-a4d3cf3b00f5429c4
Sep 2, 2026
Merged

feat(editor): 修订显示三态切换(全部修订 / 简洁标记 / 最终稿)+ AI 命令按页边语义执行的守卫(dev-board#368)#707
zeweihan merged 1 commit into
masterfrom
worktree-agent-a4d3cf3b00f5429c4

Conversation

@zeweihan

@zeweihan zeweihan commented Sep 2, 2026

Copy link
Copy Markdown
Owner

dev-board#368:编辑器工具栏加 Word 式修订视图快捷切换。

引擎实测(LO 24.2.8 r4):三态都能做。页边 = ViewSettings.ShowChangesInMargin;最终稿不能写 ShowChanges(静默空写),要写 RedlineDisplayType(带类型 Any),判据一律读 ShowChanges。

改动:

  • 新原语 set_revision_view + get_ui_state 回真实三态;EDITOR_ACTIONS 白名单;EditorToolbar 右侧下拉(两套 locales);换文档复位到默认。
  • 默认保持页边(DEFAULT_REVISION_VIEW = 'margin'):理由是 AI 文本读取契约而非观感——内联态下 worker 正文含删除文字、find_text_locations 计数含删除匹配(fix(network): 本地代理端口漂移自愈,不再需要重启后端 #369 用例已钉住)。曾按对齐 Word 改成内联,正是撞在这上面被推翻。
  • 守卫 runAgentCommandInMarginView:带 __agent 的命令若当前是内联态,执行前临时切页边 + refresh,执行完恢复;不带标记的读取仍按用户所选语义。
  • 内联态下审阅面板处置删除型修订原摆位(塌陷到区间起点)打空,selectRedlineRange 按模式分支:只有页边才塌陷。
  • withMarginOff 升级为 withInlineMarkupForExport:页边/最终稿导出期间都拉平成全显再导,导完还原;非 Writer 文档直通(Impress 上读该属性会让后续 pptx 装载崩,五跑五中)。
  • 最终稿导出实测:docx 里 w:ins/w:del 与内联导出一条不少,settings.xml 不写 revisionView。
  • 组 30 像素断言改整幅对比(定点取样会被显示模式挪掉)。

验证:lowa-e2e 530/530(真引擎)、test:revision-view 12/12、check:locales / check:emits 通过。子 agent 摘守卫复现 3 红。主会话在 dist 上同时短路守卫与导出包装 → 7 红(导出错位 2、守卫 3、连带 2),恢复后全绿。

未做:最终稿下插入痕迹是否不可见没做像素级断言;desktop-e2e / app-e2e 未跑。

🤖 Generated with Claude Code

工具栏右侧「修订显示方式」下拉,Word 式一键切换:全部修订(正文内联标记)/
简洁标记(删除挪页边)/ 最终稿(痕迹全隐)。只切显示,不改内容、不动
RecordChanges、不处置任何 redline。

默认仍是页边,理由是 AI 文本读取契约不是观感
- 页边模式把删除的文字移出正文流,get_document_text / get_paragraph 读到的正文
  才是「改后的样子」,find_text_locations / replace_nth_match 的 matchIndex 才
  只数可见匹配(dev-board#369 的用例明写这条靠页边成立)。默认换成内联会让 AI
  多轮改稿读到混着旧字的正文、按可见匹配的计数错位——是 AI 编辑契约的回归。
- 用户可以自己把视图切成内联或最终稿;AI 命令由新守卫兜住(见下),所以切了也
  不会把 AI 带偏。

worker(office_thread.js)
- 新原语 set_revision_view {mode: all|margin|final},不带 mode = 只读查询;返回
  读回来的真实状态(另带 requested/warnings),不把入参抄回去。get_ui_state 的
  view 段带回同一组字段——工具栏高亮读它,不本地记一份猜。
- showDeletionsInMargin() 并入 resetRevisionView():boot 与 load_document
  retarget 都调它,把上一份文档留下的「最终稿」隐藏态显式打回来(保活池里一个
  worker 连开好几份文档,不复位就是「上一份设了最终稿、下一份打开痕迹默默不见」)。
- **runAgentCommandInMarginView**:execCommand 里凡带 __agent 的命令,若当前视图
  是内联 all,执行前临时切页边 + refresh,执行完切回用户所选的态 + refresh;页边
  与最终稿态正文本来就不含删除文字,直接放行零开销(默认路径无任何额外成本)。
  豁免 set_revision_view / export_document / load_document;非 Writer 一个属性都
  不碰;async 原语等 settle 后再还原,同步抛异常也还原。
- selectRedlineRange 的摆位跟着显示模式分支:删除型在页边模式下塌陷到区间起点,
  内联模式下必须跨选整段区间(用户切到内联后审阅面板走的就是这一支)。
- withMarginOff 升级成 withInlineMarkupForExport(合流 dev-board#367):导出期间
  强制切成内联全显,导完恢复原态并重排;**函数头 isWriterDoc() 守卫**——早期版本
  对每次导出都问模型要 ShowChanges,在 Impress 模型上这一问会把引擎搞坏(后续
  pptx 重开要么超 180s 预算超时,要么抛 emscripten 的 operation does not support
  unaligned accesses,组 23 五跑五中)。

真机实证的引擎地雷(e2e 锁住)
- ShowChanges 属性读得回但写不进去(静默空写):隐藏修订唯一可用路线是
  RedlineDisplayType,且必须 shortAny() 带类型 Any。
- 写 NONE(0) 后 RedlineDisplayType 读回是 INSERTED(1)(引擎自己归一),判据一律
  用 ShowChanges 的读回值,不能拿 rdt 自证。

前端
- EditorToolbar 加「修订显示方式」下拉(fixed 定位,照 dev-board#245 那套);引擎
  读不到 ShowChangesInMargin 时中间项自动摘掉退成两态;非 Writer 不渲染。
- set_revision_view 入 EDITOR_ACTIONS 白名单;zh-CN / en-US 两套文案。
- loadDocument 成功后 uiRefreshKey++,换文档时工具栏跟着复位后的引擎态刷新。

测试
- 新增 npm run test:revision-view(12 例:白名单 / 三态命令序列 / 高亮跟引擎读回
  不本地置位 / 两态退化 / 换文档复位 / 导出包装契约 / __agent 守卫契约)。
- lowa-e2e 新增组 32:三态开关直读复核(debug_revision_view_raw 绕开原语自证)、
  正文随三态进出正文流、redline 一条不少、换文档复位、内联态逐条处置命中、
  最终稿导出解包断言 w:ins/w:del 与内联导出一条不差且 settings.xml 无
  w:revisionView、以及 __agent 守卫段(内联态下 AI 读正文不含被删的字、只计可见
  匹配、matchIndex 仍 0 起、命令跑完视图仍是用户选的内联)。守卫段先红后绿:
  摘掉守卫后正文读回「甲方一、甲方二、甲方三。」、匹配数 3 而非 2,装回即绿。
- 组 1/2/11/13/14 与 #365/#369 的用例块保持 master 原样(页边语义),一个字没动。
- 组 30 的像素断言从定点取样改成整幅前后对比(显示模式会挪动纸的落位,定点取样
  会取到纸上);探针 debug_fresh_document 顺手关掉上一份文档。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@zeweihan
zeweihan enabled auto-merge (squash) September 2, 2026 02:04
@zeweihan
zeweihan merged commit b07b3b8 into master Sep 2, 2026
6 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant