@beyondwork/docx-react-component 1.0.67 → 1.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/README.md +75 -932
  2. package/package.json +26 -27
  3. package/src/api/anchor-conversion.ts +43 -0
  4. package/src/api/editor-state-types.ts +2 -1
  5. package/src/api/public-types.ts +504 -101
  6. package/src/api/session-state.ts +4 -0
  7. package/src/api/v3/README.md +91 -0
  8. package/src/api/v3/_create.ts +146 -0
  9. package/src/api/v3/_layer-metadata.ts +362 -0
  10. package/src/api/v3/_mocks.ts +84 -0
  11. package/src/api/v3/_runtime-handle.ts +162 -0
  12. package/src/api/v3/_ux-response.ts +73 -0
  13. package/src/api/v3/ai/_metadata-audit.ts +225 -0
  14. package/src/api/v3/ai/attach.ts +235 -0
  15. package/src/api/v3/ai/bundle.ts +132 -0
  16. package/src/api/v3/ai/explain.ts +144 -0
  17. package/src/api/v3/ai/export.ts +54 -0
  18. package/src/api/v3/ai/inspect.ts +118 -0
  19. package/src/api/v3/ai/policy.ts +77 -0
  20. package/src/api/v3/ai/replacement.ts +341 -0
  21. package/src/api/v3/ai/resolve.ts +133 -0
  22. package/src/api/v3/index.ts +79 -0
  23. package/src/api/v3/runtime/chart.ts +310 -0
  24. package/src/api/v3/runtime/clipboard.ts +81 -0
  25. package/src/api/v3/runtime/collab.ts +331 -0
  26. package/src/api/v3/runtime/content.ts +236 -0
  27. package/src/api/v3/runtime/document.ts +282 -0
  28. package/src/api/v3/runtime/formatting.ts +186 -0
  29. package/src/api/v3/runtime/geometry.ts +349 -0
  30. package/src/api/v3/runtime/layout.ts +108 -0
  31. package/src/api/v3/runtime/review.ts +129 -0
  32. package/src/api/v3/runtime/search.ts +74 -0
  33. package/src/api/v3/runtime/table.ts +63 -0
  34. package/src/api/v3/runtime/workflow.ts +434 -0
  35. package/src/api/v3/ui/_context.ts +86 -0
  36. package/src/api/v3/ui/_create.ts +65 -0
  37. package/src/api/v3/ui/_types.ts +520 -0
  38. package/src/api/v3/ui/chrome-composition.ts +342 -0
  39. package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
  40. package/src/api/v3/ui/chrome.ts +476 -0
  41. package/src/api/v3/ui/debug.ts +124 -0
  42. package/src/api/v3/ui/index.ts +64 -0
  43. package/src/api/v3/ui/overlays-visibility.ts +170 -0
  44. package/src/api/v3/ui/overlays.ts +427 -0
  45. package/src/api/v3/ui/scope.ts +71 -0
  46. package/src/api/v3/ui/session.ts +100 -0
  47. package/src/api/v3/ui/surface.ts +170 -0
  48. package/src/api/v3/ui/viewport.ts +303 -0
  49. package/src/core/commands/index.ts +28 -6
  50. package/src/core/commands/list-commands.ts +3 -2
  51. package/src/core/commands/section-layout-commands.ts +9 -8
  52. package/src/core/schema/text-schema.ts +16 -0
  53. package/src/core/selection/mapping.ts +33 -72
  54. package/src/core/state/editor-state.ts +96 -189
  55. package/src/index.ts +23 -4
  56. package/src/io/chart-preview-resolver.ts +1 -1
  57. package/src/io/docx-session.ts +36 -4797
  58. package/src/io/export/build-app-properties-xml.ts +1 -1
  59. package/src/io/export/serialize-comments.ts +1 -1
  60. package/src/io/export/serialize-headers-footers.ts +6 -1
  61. package/src/io/export/serialize-main-document.ts +45 -0
  62. package/src/io/export/serialize-run-formatting.ts +17 -2
  63. package/src/io/export/twip.ts +1 -1
  64. package/src/io/normalize/normalize-text.ts +27 -20
  65. package/src/io/ooxml/chart/parse-series.ts +1 -1
  66. package/src/io/ooxml/chart/resolve-color.ts +2 -2
  67. package/src/io/ooxml/chart/types.ts +1 -1
  68. package/src/io/ooxml/classify-embedding.ts +83 -33
  69. package/src/io/ooxml/parse-fill.ts +1 -1
  70. package/src/io/ooxml/parse-main-document.ts +71 -1
  71. package/src/io/ooxml/parse-object.ts +14 -10
  72. package/src/io/ooxml/parse-run-formatting.ts +47 -1
  73. package/src/io/ooxml/property-grab-bag.ts +2 -2
  74. package/src/io/ooxml/units.ts +11 -0
  75. package/src/io/ooxml/workflow-payload.ts +282 -7
  76. package/src/model/anchor.ts +85 -0
  77. package/src/model/canonical-document.ts +351 -15
  78. package/src/model/chart-types.ts +1 -1
  79. package/src/model/layout/index.ts +83 -0
  80. package/src/model/layout/page-graph-types.ts +181 -0
  81. package/src/model/layout/page-layout-snapshot.ts +105 -0
  82. package/src/model/layout/resolved-layout-types.ts +47 -0
  83. package/src/model/layout/runtime-page-graph-types.ts +102 -0
  84. package/src/model/paragraph-scope-ids.ts +72 -0
  85. package/src/model/review/comment-types.ts +112 -0
  86. package/src/model/review/index.ts +2 -0
  87. package/src/model/review/revision-types.ts +215 -0
  88. package/src/model/snapshot.ts +32 -0
  89. package/src/review/store/comment-store.ts +21 -47
  90. package/src/review/store/revision-types.ts +40 -198
  91. package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
  92. package/src/runtime/collab/runtime-collab-sync.ts +13 -3
  93. package/src/runtime/collab-session.ts +1 -1
  94. package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
  95. package/src/runtime/debug/event-ring-buffer.ts +64 -0
  96. package/src/runtime/debug/probability-sampler.ts +18 -0
  97. package/src/runtime/debug/runtime-debug-facet.ts +67 -0
  98. package/src/runtime/debug/stage-tokens.ts +31 -0
  99. package/src/runtime/debug/telemetry-bus.ts +271 -0
  100. package/src/runtime/debug/types.ts +275 -0
  101. package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
  102. package/src/runtime/document-layout.ts +8 -6
  103. package/src/runtime/document-runtime.ts +843 -1141
  104. package/src/runtime/document-search.ts +1 -1
  105. package/src/runtime/edit-ops/index.ts +1 -1
  106. package/src/runtime/external-send-runtime.ts +1 -1
  107. package/src/runtime/formatting/document-lookup.ts +235 -0
  108. package/src/runtime/formatting/field/registry.ts +41 -0
  109. package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
  110. package/src/runtime/formatting/font-resolution.ts +83 -0
  111. package/src/runtime/formatting/formatting-context.ts +903 -0
  112. package/src/runtime/formatting/formatting-types.ts +157 -0
  113. package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
  114. package/src/runtime/formatting/index.ts +125 -0
  115. package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
  116. package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
  117. package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
  118. package/src/runtime/formatting/projector.ts +75 -0
  119. package/src/runtime/formatting/resolve-effective.ts +407 -0
  120. package/src/runtime/formatting/revision-display.ts +105 -0
  121. package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
  122. package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
  123. package/src/runtime/formatting/telemetry-bridge.ts +106 -0
  124. package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
  125. package/src/runtime/geometry/caret-geometry.ts +164 -0
  126. package/src/runtime/geometry/geometry-facet.ts +364 -0
  127. package/src/runtime/geometry/geometry-types.ts +256 -0
  128. package/src/runtime/geometry/hit-test.ts +125 -0
  129. package/src/runtime/geometry/index.ts +71 -0
  130. package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
  131. package/src/runtime/geometry/invalidation.ts +35 -0
  132. package/src/runtime/geometry/object-handles.ts +77 -0
  133. package/src/runtime/geometry/overlay-rects.ts +85 -0
  134. package/src/runtime/geometry/project-anchors.ts +100 -0
  135. package/src/runtime/geometry/project-fragments.ts +216 -0
  136. package/src/runtime/geometry/projector.ts +129 -0
  137. package/src/runtime/geometry/replacement-envelope.ts +130 -0
  138. package/src/runtime/geometry/viewport.ts +218 -0
  139. package/src/runtime/layout/compat-input-ledger.ts +211 -0
  140. package/src/runtime/layout/index.ts +6 -1
  141. package/src/runtime/layout/inert-layout-facet.ts +12 -7
  142. package/src/runtime/layout/layout-engine-instance.ts +189 -11
  143. package/src/runtime/layout/layout-engine-version.ts +450 -1
  144. package/src/runtime/layout/layout-facet-types.ts +60 -0
  145. package/src/runtime/layout/layout-measurement-provider.ts +13 -0
  146. package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
  147. package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
  148. package/src/runtime/layout/page-graph.ts +62 -209
  149. package/src/runtime/layout/page-story-resolver.ts +7 -12
  150. package/src/runtime/layout/paginated-layout-engine.ts +186 -11
  151. package/src/runtime/layout/project-block-fragments.ts +11 -0
  152. package/src/runtime/layout/projector.ts +90 -0
  153. package/src/runtime/layout/public-facet.ts +187 -442
  154. package/src/runtime/layout/resolved-formatting-state.ts +158 -26
  155. package/src/runtime/layout/table-render-plan.ts +1 -1
  156. package/src/runtime/prerender/cache-envelope.ts +6 -1
  157. package/src/runtime/prerender/prerender-document.ts +18 -23
  158. package/src/runtime/render/decoration-resolver.ts +1 -1
  159. package/src/runtime/render/render-frame-types.ts +20 -0
  160. package/src/runtime/render/render-kernel.ts +94 -25
  161. package/src/runtime/scopes/_formatting-seam.ts +262 -0
  162. package/src/runtime/scopes/_scope-dependencies.ts +49 -0
  163. package/src/runtime/scopes/action-validation.ts +356 -0
  164. package/src/runtime/scopes/attach-explanation.ts +102 -0
  165. package/src/runtime/scopes/audit-bundle.ts +71 -0
  166. package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
  167. package/src/runtime/scopes/compile-scope.ts +262 -0
  168. package/src/runtime/scopes/compiler-service.ts +431 -0
  169. package/src/runtime/scopes/create-issue.ts +107 -0
  170. package/src/runtime/scopes/enumerate-scopes.ts +543 -0
  171. package/src/runtime/scopes/evidence.ts +233 -0
  172. package/src/runtime/scopes/index.ts +150 -0
  173. package/src/runtime/scopes/position-map.ts +214 -0
  174. package/src/runtime/scopes/preservation-boundary.ts +91 -0
  175. package/src/runtime/scopes/projector.ts +49 -0
  176. package/src/runtime/scopes/replaceability.ts +87 -0
  177. package/src/runtime/scopes/replacement/apply.ts +228 -0
  178. package/src/runtime/scopes/replacement/compile.ts +59 -0
  179. package/src/runtime/scopes/replacement/propose.ts +42 -0
  180. package/src/runtime/scopes/resolve-reference.ts +347 -0
  181. package/src/runtime/scopes/review-bundle.ts +141 -0
  182. package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
  183. package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
  184. package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
  185. package/src/runtime/scopes/scope-kinds/field.ts +65 -0
  186. package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
  187. package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
  188. package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
  189. package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
  190. package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
  191. package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
  192. package/src/runtime/scopes/scope-kinds/table.ts +55 -0
  193. package/src/runtime/scopes/scope-range.ts +208 -0
  194. package/src/runtime/scopes/semantic-scope-types.ts +454 -0
  195. package/src/runtime/scopes/workflow-overlap.ts +92 -0
  196. package/src/runtime/selection/index.ts +1 -1
  197. package/src/runtime/structure-ops/fragment-insert.ts +1 -1
  198. package/src/runtime/structure-ops/index.ts +1 -1
  199. package/src/runtime/surface-projection.ts +232 -262
  200. package/src/runtime/units.ts +4 -2
  201. package/src/runtime/workflow/coordinator.ts +1348 -0
  202. package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
  203. package/src/runtime/workflow/index.ts +25 -0
  204. package/src/runtime/workflow/markup-mode-policy.ts +98 -0
  205. package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
  206. package/src/runtime/workflow/metadata-persistence.ts +306 -0
  207. package/src/runtime/workflow/metadata-writer.ts +123 -0
  208. package/src/runtime/workflow/overlay-store.ts +690 -0
  209. package/src/runtime/workflow/projector.ts +127 -0
  210. package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
  211. package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
  212. package/src/runtime/workflow/rail/types.ts +198 -0
  213. package/src/runtime/workflow/scope-rail-composer.ts +39 -0
  214. package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
  215. package/src/runtime/workflow/scope-writer.ts +188 -0
  216. package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
  217. package/src/runtime/workflow/visibility-policy.ts +129 -0
  218. package/src/session/_sync-legacy.ts +66 -0
  219. package/src/session/export/embedded-reconstitute.ts +104 -0
  220. package/src/session/export/export-diagnostics.ts +85 -0
  221. package/src/session/export/export-validation.ts +110 -0
  222. package/src/session/export/index.ts +34 -0
  223. package/src/session/export/preservation-reattach.ts +30 -0
  224. package/src/session/export/serialize-dispatch.ts +165 -0
  225. package/src/session/export/stateful-export-pipeline.ts +432 -0
  226. package/src/session/export/stateful-export.ts +684 -0
  227. package/src/session/import/canonical-assembly.ts +227 -0
  228. package/src/session/import/diagnostics-session.ts +54 -0
  229. package/src/session/import/embedded-discovery.ts +225 -0
  230. package/src/session/import/embedded-offload.ts +337 -0
  231. package/src/session/import/import-diagnostics.ts +69 -0
  232. package/src/session/import/loader-types.ts +313 -0
  233. package/src/session/import/loader.ts +1834 -0
  234. package/src/session/import/normalize.ts +195 -0
  235. package/src/session/import/package-parts.ts +217 -0
  236. package/src/session/import/package-read.ts +195 -0
  237. package/src/session/import/parse-orchestration.ts +105 -0
  238. package/src/session/import/part-constants.ts +70 -0
  239. package/src/session/import/part-discovery.ts +94 -0
  240. package/src/session/import/preservation-index.ts +46 -0
  241. package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
  242. package/src/session/import/review-import.ts +508 -0
  243. package/src/session/import/styles-consolidation.ts +281 -0
  244. package/src/session/import/workflow-scope-import.ts +256 -0
  245. package/src/session/index.ts +37 -0
  246. package/src/session/session-state.ts +69 -0
  247. package/src/session/session.ts +532 -0
  248. package/src/session/shared/protection.ts +228 -0
  249. package/src/session/shared/session-utils.ts +82 -0
  250. package/src/session/types.ts +499 -0
  251. package/src/shell/chart-snapshots.ts +96 -0
  252. package/src/shell/media-previews.ts +85 -0
  253. package/src/shell/overlay-anchor-bridge.ts +53 -0
  254. package/src/shell/paste-adapter.ts +23 -0
  255. package/src/shell/ref-commands.ts +1697 -0
  256. package/src/shell/ref-utilities.ts +48 -0
  257. package/src/shell/search.ts +51 -0
  258. package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
  259. package/src/shell/ui-subscriber-channels.ts +81 -0
  260. package/src/shell/use-collab-sync.ts +116 -0
  261. package/src/ui/WordReviewEditor.tsx +496 -2051
  262. package/src/ui/editor-shell-view.tsx +30 -1
  263. package/src/ui/editor-surface-controller.tsx +49 -1
  264. package/src/ui/headless/revision-decoration-model.ts +83 -0
  265. package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
  266. package/src/ui/headless/scoped-chrome-policy.ts +2 -2
  267. package/src/ui/headless/selection-tool-context.ts +1 -1
  268. package/src/ui/headless/selection-tool-resolver.ts +1 -1
  269. package/src/ui/runtime-shortcut-dispatch.ts +46 -1
  270. package/src/ui/ui-controller-factory.ts +221 -0
  271. package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
  272. package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
  273. package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
  274. package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
  275. package/src/ui-tailwind/chart/render/area.tsx +3 -3
  276. package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
  277. package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
  278. package/src/ui-tailwind/chart/render/combo.tsx +2 -2
  279. package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
  280. package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
  281. package/src/ui-tailwind/chart/render/line.tsx +3 -3
  282. package/src/ui-tailwind/chart/render/pie.tsx +6 -6
  283. package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
  284. package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
  285. package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
  286. package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
  287. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
  288. package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
  289. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
  290. package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
  291. package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
  292. package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
  293. package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
  294. package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
  295. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
  296. package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
  297. package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
  298. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
  299. package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
  300. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
  301. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
  302. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
  303. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
  304. package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
  305. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
  306. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
  307. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
  308. package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
  309. package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
  310. package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
  311. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
  312. package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
  313. package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
  314. package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
  315. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
  316. package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
  317. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
  318. package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
  319. package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
  320. package/src/ui-tailwind/debug/README.md +57 -0
  321. package/src/ui-tailwind/debug/index.ts +3 -0
  322. package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
  323. package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
  324. package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
  325. package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
  326. package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
  327. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
  328. package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
  329. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
  330. package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
  331. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
  332. package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
  333. package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
  334. package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
  335. package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
  336. package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
  337. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
  338. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
  339. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
  340. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
  341. package/src/ui-tailwind/index.ts +0 -5
  342. package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
  343. package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
  344. package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
  345. package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
  346. package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
  347. package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
  348. package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
  349. package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
  350. package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
  351. package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
  352. package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
  353. package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
  354. package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
  355. package/src/ui-tailwind/review-workspace/types.ts +408 -0
  356. package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
  357. package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
  358. package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
  359. package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
  360. package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
  361. package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
  362. package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
  363. package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
  364. package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
  365. package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
  366. package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
  367. package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
  368. package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
  369. package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
  370. package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
  371. package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
  372. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
  373. package/src/ui-tailwind/theme/editor-theme.css +25 -0
  374. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
  375. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
  376. package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
  377. package/src/ui-tailwind/ui-api-context.tsx +43 -0
  378. package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
  379. package/src/validation/compatibility-engine.ts +6 -6
  380. package/src/runtime/styles-cascade.ts +0 -33
  381. package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
  382. /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
  383. /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
  384. /package/src/runtime/{scope-tag-registry.ts → workflow/scope-tag-registry.ts} +0 -0
package/README.md CHANGED
@@ -11,993 +11,136 @@ canonical: true
11
11
 
12
12
  [![CI](https://github.com/bwllaming/React-OOXML-Office/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bwllaming/React-OOXML-Office/actions/workflows/ci.yml)
13
13
 
14
- This repository builds **backoffice work components** for the [Beyond Work](https://beyondwork.ai) runtime — embeddable, composable modules that handle document editing, review workflows, data processing, and task automation inside enterprise workspaces.
14
+ Embeddable backoffice components for the [Beyond Work](https://beyondwork.ai) runtime. This repository ships **`@beyondwork/docx-react-component`** a fidelity-first React `.docx` editor for legal review, contract negotiation, and any workflow where documents round-trip through Microsoft Word without damage.
15
15
 
16
- The design principle across every component: **advanced tasks should be equally easy for AI agents and human users.** Every capability exposed through the UI is also available through a structured API. Every API is designed so an agent can inspect state, reason about it, and act on it without special accommodation. Humans and agents share the same runtime, the same commands, the same read models, and the same fidelity guarantees.
16
+ **Design principle human-AI parity.** Every capability in the UI has an equivalent, structured API. The agent and the user operate on the same runtime, the same commands, the same read models. There is no "agent-only" shortcut and no "human-only" feature.
17
17
 
18
- ## Use This README For
19
-
20
- - confirming what is shipped today
21
- - installing the package
22
- - finding the right documentation lane quickly
23
-
24
- Do not use this README as the full package contract. The canonical consumer path starts in `docs/README.md`, [`docs/reference/public-api.md`](docs/reference/public-api.md), and [`docs/reference/integration-guide.md`](docs/reference/integration-guide.md).
25
-
26
- ## Components
27
-
28
- ### Document Editor (`@beyondwork/docx-react-component`)
29
-
30
- A fidelity-first React `.docx` editor centered on `WordReviewEditor`. Built for legal review, contract negotiation, and any workflow where documents need to survive a round-trip through Microsoft Word without damage.
31
-
32
- **Capabilities:**
33
- - Full tracked-change and comment support (add, resolve, accept, reject)
34
- - Suggesting mode where every edit automatically becomes a tracked change
35
- - Round-trip OOXML preservation — open, edit, export, reopen in Word without repair prompts
36
- - Workflow overlays with scope-based editing constraints
37
- - Runtime-backed read models for document structure, review state, selection, compatibility, and fields
38
- - Document comparison with LCS-based diffing and redline export
39
- - Legal document analysis (bookmarks, cross-references, defined terms, signature blocks)
40
- - Real-time collaboration via Yjs
41
-
42
- **Human-AI parity in practice:**
43
- - The human clicks "Add Comment" on selected text; the agent calls `addComment({ anchor, body })` on the same selection
44
- - The human reviews tracked changes in the sidebar; the agent reads `getTrackedChanges()` and makes the same accept/reject decisions
45
- - The human exports via toolbar; the agent calls `exportDocx()` after the same `getCompatibilityReport()` check
46
- - Workflow overlays constrain both humans and agents identically — `getInteractionGuardSnapshot()` is the single source of posture truth
47
- - The AI action policy module gates 37 discrete agent operations with risk classification and context validation
48
-
49
- ### Workblocks
50
-
51
- Composable task modules that automate business processes. Each workblock is a self-contained package of Python backend logic, React UI components, and a declarative task graph defined in `manifest.yaml`. They execute on the Beyond Work platform via Temporal workflows.
52
-
53
- **Categories:**
54
- - **Document processing** — invoice extraction, PDF template OCR, bulk processing, email-to-action
55
- - **AI agents** — explore, flow debugging, data querying, task launching, authoring
56
- - **Analytics** — execution history, company insights, timeline queries
57
- - **Learning** — human correction capture, learning set curation, embedding management
58
- - **Infrastructure** — registry, health checks, credential management (9 types)
59
-
60
- **Human-AI parity in practice:**
61
- - Users create workblocks through VS Code Studio with prompts and visual editing; authoring agents create them through the same manifest schema and file tools
62
- - Users validate invoice fields in a React form; agents validate the same fields through typed task inputs/outputs
63
- - Both humans and agents operate within the same workblock execution engine — same task graph, same data flow, same error handling
64
-
65
- ## The Beyond Work Runtime
66
-
67
- These components plug into a four-layer platform:
68
-
69
- ```
70
- User-Facing (Layer 4)
71
- neui (Next.js 15), bport (BFF), MCP server, VS Code extension
72
- |
73
- Workblocks (Layer 3)
74
- 20+ composable task modules: agents, data processing, credentials
75
- |
76
- Platform Services (Layer 2)
77
- bworker (Go), modelproxy (LiteLLM), registry, pythonworker, Temporal
78
- |
79
- AWS Infrastructure (Layer 1)
80
- EKS, Crossplane, Terraform, PostgreSQL, Redis, Qdrant, S3, SQS
81
- ```
82
-
83
- The document editor lives at Layer 4 as an embeddable surface. Workblocks live at Layer 3 and are orchestrated by the platform. Both expose their capabilities symmetrically to human UIs and agent APIs.
84
-
85
- ## Current Package Reality
86
-
87
- The shipped contract today is docx-first:
88
-
89
- - `docx` is the only implemented and shipped runtime contract
90
- - `xlsx` is planned work, not part of the current package contract
91
- - `pdf` remains future work outside the current package boundary
18
+ ---
92
19
 
93
20
  ## Install
94
21
 
95
22
  ```bash
96
- pnpm add @beyondwork/docx-react-component react react-dom tailwindcss \
97
- prosemirror-commands prosemirror-keymap prosemirror-model \
98
- prosemirror-state prosemirror-tables prosemirror-transform prosemirror-view
99
- ```
100
-
101
- Current packaging truth:
102
-
103
- - the package is ESM-only
104
- - exports point at shipped TypeScript source entry points
105
- - `types` and subpath `types` entries resolve to the shipped source-backed TypeScript contracts
106
- - consumers need a bundler or runtime that can resolve `.ts` and `.tsx` ESM imports
107
- - consumers should import `@beyondwork/docx-react-component/ui-tailwind/theme/editor-theme.css` once and provide a Tailwind v4 CSS pipeline for it
108
- - package and source identifiers remain docx-first until a deliberate rename lands
109
-
110
- ## Shipped Product
111
-
112
- The primary shipped surface is:
113
-
114
- ```tsx
115
- import { WordReviewEditor } from "@beyondwork/docx-react-component";
116
-
117
- <WordReviewEditor />
118
- ```
119
-
120
- `WordReviewEditor` remains uncontrolled by default:
121
-
122
- - host passes `initialDocx`, `initialSessionState`, or `initialSnapshot`, or provides `hostAdapter.load()` / `datastore.load()`
123
- - runtime owns the live working session
124
- - host receives events, warnings, errors, session state, compatibility snapshots, and exported artifacts
125
-
126
- Persistence direction:
127
-
128
- - `EditorSessionState` is the canonical host-facing live-session contract
129
- - `EditorHostAdapter` is the preferred persistence boundary for `load`, `saveSession`, `saveExport`, and telemetry
130
- - `EditorDatastoreAdapter` remains the legacy snapshot bridge for hosts that still persist `PersistedEditorSnapshot`
131
-
132
- Snapshot/export note:
133
-
134
- - when a session starts from a real `.docx`, persisted snapshots now carry embedded source-package provenance so later snapshot-origin `.docx` export can use the same package-backed exporter
135
- - legacy snapshots without that provenance still load, but `.docx` export is intentionally blocked rather than falling back to a lossy minimal package
136
-
137
- The current shipped ESM exports include:
138
-
139
- - stable default entrypoints:
140
- - `@beyondwork/docx-react-component`
141
- - `@beyondwork/docx-react-component/public-types`
142
- - `@beyondwork/docx-react-component/ui-tailwind`
143
- - `@beyondwork/docx-react-component/legal`
144
- - `@beyondwork/docx-react-component/compare`
145
- - `@beyondwork/docx-react-component/ui-tailwind/theme/editor-theme.css`
146
- - advanced-supported subpaths for wrapper teams and package-adjacent integrations:
147
- - `@beyondwork/docx-react-component/runtime/document-runtime`
148
- - `@beyondwork/docx-react-component/io/docx-session`
149
- - `@beyondwork/docx-react-component/core/commands/*`
150
- - `@beyondwork/docx-react-component/core/selection/mapping`
151
- - `@beyondwork/docx-react-component/core/state/editor-state`
152
- - `@beyondwork/docx-react-component/ui-tailwind/editor-surface/search-plugin`
153
- - alias subpaths:
154
- - `@beyondwork/docx-react-component/tailwind`
155
- - `@beyondwork/docx-react-component/api/public-types`
156
-
157
- Use [`docs/reference/public-api.md`](docs/reference/public-api.md) and `docs/reference/public-api.manifest.json` for the current contract inventory and stability guidance.
158
-
159
- ## Product Contract
160
-
161
- For every component this repo ships, the standard is:
162
-
163
- > Open -> edit -> save -> reopen in the host application without damage.
164
-
165
- For the current shipped `docx` implementation, that specifically means:
166
-
167
- - open in recent Microsoft Word without repair prompts
168
- - preserve supported content and review structures
169
- - preserve unsupported but preservable OOXML
170
- - remain editable in Word after export
171
-
172
- For the normative API and host contract, use:
173
-
174
- - [`docs/reference/public-api.md`](docs/reference/public-api.md)
175
- - [`docs/reference/integration-guide.md`](docs/reference/integration-guide.md)
176
- - [`docs/reference/ooxml-compliance.md`](docs/reference/ooxml-compliance.md)
177
-
178
- ## Documentation Map
179
-
180
- ### Start Here
181
-
182
- - [`docs/README.md`](docs/README.md)
183
-
184
- ### Main Consumer Path
185
-
186
- - [`docs/reference/quick-start.md`](docs/reference/quick-start.md)
187
- - [`docs/reference/consumer-matrix.md`](docs/reference/consumer-matrix.md)
188
- - [`docs/reference/public-api.md`](docs/reference/public-api.md)
189
- - [`docs/reference/integration-guide.md`](docs/reference/integration-guide.md)
190
- - [`docs/reference/glossary.md`](docs/reference/glossary.md)
191
-
192
- ### Wrapper And Agent Path
193
-
194
- - [`docs/reference/consumer-matrix.md`](docs/reference/consumer-matrix.md)
195
- - [`docs/reference/agent-integration-guide.md`](docs/reference/agent-integration-guide.md)
196
- - [`docs/reference/public-api.md`](docs/reference/public-api.md)
197
- - [`docs/reference/service-wrapper-guidance.md`](docs/reference/service-wrapper-guidance.md)
198
- - [`docs/reference/agent-capability-map.md`](docs/reference/agent-capability-map.md)
199
- - [`docs/reference/agent-read-models-and-snapshots.md`](docs/reference/agent-read-models-and-snapshots.md)
200
- - [`docs/reference/agent-workflow-and-suggestions.md`](docs/reference/agent-workflow-and-suggestions.md)
201
- - [`docs/reference/scope-aware-selection-tooling.md`](docs/reference/scope-aware-selection-tooling.md)
202
- - [`docs/reference/glossary.md`](docs/reference/glossary.md)
203
- - [`docs/reference/editor-integration-style.md`](docs/reference/editor-integration-style.md)
204
- - [`docs/reference/ui-theming-and-styling.md`](docs/reference/ui-theming-and-styling.md)
205
- - [`docs/reference/beyondwork-runtime-environment.md`](docs/reference/beyondwork-runtime-environment.md)
206
-
207
- Wrapper and agent docs stay on `main`, but they are downstream integration guidance rather than the canonical package contract.
208
-
209
- Current integration honesty:
210
-
211
- - the shipped React host surface is still `WordReviewEditor`
212
- - `showReviewPanel={false}` only hides the bundled review rail
213
- - a distinct public chromeless React surface is not yet shipped
214
-
215
- ### Maintainer Path
216
-
217
- - [`docs/maintainers/README.md`](docs/maintainers/README.md)
218
- - [`docs/ccep-contract-templates/README.md`](docs/ccep-contract-templates/README.md)
219
- - [`docs/plans/README.md`](docs/plans/README.md) — active development lanes + open-issues register
220
-
221
- The CCEP corpus is kept on `main` as a maintainer-safe smoke-doc source set for agreement-heavy validation and wrapper or agent benchmarking.
222
-
223
- ### Active Development Lanes
224
-
225
- Engineering work is organized into 9 lanes (5 active now + 2 later polish + 2 final) — full plan index, status, and worktree map at [`docs/plans/README.md`](docs/plans/README.md). Each lane has a single self-contained doc at `docs/plans/lane-N-<name>.md`:
226
-
227
- **Progress snapshot — 2026-04-19 (post PR #189 + #190 + #191 + #192 merged to `main`; Lane 3 split into 3a + 3b on 2026-04-19 deep evening):**
228
-
229
- | # | Lane | % to goal | Status summary |
230
- |---|---|---|---|
231
- | 1 | [**Editing Foundation**](docs/plans/lane-1-editing-foundation.md) | **65%** | I1–I6 + I3 widening + I4 + S1 + X3 + I8 shipped; I2B / I7 / R.1–R.5 backlog |
232
- | 2 | [**Render Performance**](docs/plans/lane-2-render-performance.md) | **85%** | All Phases 1.x + 2.2 + 2.4b + 2.5 (A+B) + 2.9 shipped; Tasks 2.1 / 2.3 left |
233
- | 3a | [**Layout & Render Engine**](docs/plans/lane-3a-layout-render-engine.md) | **45%** | P1–P6 + P8 + P14.a/b/e shipped; P9 (now unblocked) + P10 + P11 + P12 + P14.c/d backlog |
234
- | 3b | [**OOXML Fidelity & Round-Trip**](docs/plans/lane-3b-ooxml-fidelity.md) | **55%** | V1 + O3 + O4 + O2 (all 4 slices) + V7 closed; 🚨 O8 + L2.c + V6 + V2a/b/c + R3–R5 backlog |
235
- | 4 | [**Collab + CLM/Vallor**](docs/plans/lane-4-collab-clm-vallor.md) | **80%** | P1–P14 + all P11 sub-bullets + P12 + perf-parity + P13 A/B/C shipped; P15 / P16 / P17 left |
236
- | 5 | [**Charts (independent)**](docs/plans/lane-5-charts.md) | **30%** | Stages 0–2 shipped (parsers + theme); Stages 3–7 (SVG renderers + pixel-diff) left |
237
- | 6a | [**Tokens & Theme Foundation**](docs/plans/lane-6a-tokens-theme-foundation.md) | **~25%** | Active (no gate) — canonical token substrate: brand-accent flip, semantic families, scope-tint tokens, chart palette, hex eviction, density + reduced-motion plumbing |
238
- | 6b | [**Shell & Workspace Chrome**](docs/plans/lane-6b-shell-workspace-chrome.md) | **~15%** | Gated on 6a.S1+S2 — shell header + toolbar + status + alert banner + unsaved modal + collab chrome restyle; mode-dock decommission; TwCommandPalette |
239
- | 6c | [**Context & Review Surfaces**](docs/plans/lane-6c-context-review-surfaces.md) | **~15%** | Gated on 6a.S1+S2 — selection toolbar + suggestion card + rail + scope + context toolbars + health panel restyle; TwCommentPreview / TwEmptyState / TwShortcutHint |
240
- | 6d | [**Visual Fidelity**](docs/plans/lane-6d-visual-fidelity.md) | **~20%** | Gated on 6a.S1+S2 + external-lane deps — L8 A/B/C shipped; L8 Phase D + P11 overlays + P7 + P12 + P14 next |
241
- | 7a | [**Visual Fidelity Register**](docs/plans/lane-7a-visual-fidelity-register.md) | **0%** | LATER (gated on 6a–6d) — V5 covers, V6 REF/PAGEREF, V7 cascade audit |
242
- | 7b | [**Revision & Redline Completion**](docs/plans/lane-prompts/lane-7b-revision-redline-completion.md) | **✅ CLOSED** | Phases A–N shipped on `lane-7b-revision-redline` (17 commits) — full X4.a parse (container + range markers), X4.b complete (cellIns accept + reject + row-ins/row-del accept + reject), move-promotion (linked-pair atomic accept/reject). Trigger-gated: X4.c + X5 + nested-table row-insertion scope limit. Validator pass handed off to coordinator |
243
- | 7c | [**Preservation & Format Coverage**](docs/plans/lane-7c-preservation-format-coverage.md) | **0%** | LATER (gated on 6a–6d) — O6 Strict, OLE preserve-only, picture-SDT, w14/kern/VML defer |
244
- | 7d | [**Platform Hardening & Hygiene**](docs/plans/lane-7d-platform-hardening-hygiene.md) | **0%** | LATER (gated on 6a–6d) — harness-crash-hardening, fastload activation, worktree consolidation |
245
- | 8 | [**API Ergonomics / Errors / BC**](docs/plans/lane-8-api-ergonomics.md) | **40%** | LATER — Tracks A+C shipped (error catalog + ergonomics fixes); Tracks B+D+E + public-api.md end-to-end refactor remain |
246
- | 9 | [**Shipping (v2.0.0)**](docs/plans/lane-9-shipping.md) | **0%** | FINAL — API freeze, semver discipline, changelog, telemetry, customer migration guides, doc completeness audit |
247
-
248
- **Aggregate v2.0.0 readiness:** ~70% — long poles are Lane 3 O8 + P9/P10, Lane 4 P15/P16/P17, Lane 1 R.1–R.5, Lane 5 Stage 4 SVG renderers (Lane 5 ships on independent v2.x cadence). Detailed task-completeness factor + per-lane backlog inventory in [`docs/plans/coordination-prompt.md`](docs/plans/coordination-prompt.md).
249
-
250
- ### Technical Wiki
251
-
252
- - [`docs/wiki/`](docs/wiki/) — Feature-by-feature technical documentation (25+ topics covering OOXML, ProseMirror, runtime, and platform)
253
-
254
- ## Agent Integration
255
-
256
- Agents consume the editor through a consistent pipeline:
257
-
258
- ```
259
- inspect --> locate --> mutate --> validate --> export
260
- ```
261
-
262
- Beyond Work platform agents extend this with propose/approve gates:
263
-
264
- ```
265
- inspect --> locate --> propose --> approve --> mutate --> validate --> export
23
+ pnpm add @beyondwork/docx-react-component
266
24
  ```
267
25
 
268
- The package exposes purpose-built read models not a monolithic state dump:
269
-
270
- | Read model | Getter | Purpose |
271
- |---|---|---|
272
- | Document surface | `getRenderSnapshot()` | Structure, blocks, text, selection |
273
- | Comments | `getComments()` | Thread state, resolution, anchors |
274
- | Tracked changes | `getTrackedChanges()` | Revision inventory, actionability |
275
- | Workflow scope | `getWorkflowScopeSnapshot()` | Scope boundaries, work items, mode |
276
- | Interaction guard | `getInteractionGuardSnapshot()` | Effective mode, blocked reasons |
277
- | Compatibility | `getCompatibilityReport()` | Export risk assessment |
278
- | Warnings | `getWarnings()` | Active fidelity or mutation warnings |
279
- | Fields | `getFieldSnapshot()` | Field posture and refresh state |
280
-
281
- Agents should read the narrow snapshot that answers the next question, not pull the full render snapshot for every decision.
282
-
283
- ## Packaging And Release
284
-
285
- - `.github/workflows/publish.yml` publishes on `v*` tags after verifying the tag matches `package.json`
286
- - `pnpm pack --dry-run` is the baseline package proof
287
- - npm provenance is enabled in `publishConfig` and in the publish workflow invocation
288
- - the published package currently ships source ESM entry points plus TypeScript source-backed `types` exports
289
- - the Microsoft Open XML SDK remains CI/internal-service only, never part of the shipped browser runtime
290
-
291
- ## Contribution Rules
292
-
293
- - respect the runtime-owned state model
294
- - do not bypass commands and transactions
295
- - do not treat the DOM as canonical state
296
- - do not silently drop unknown OOXML
297
- - keep docs honest about shipped versus planned behavior
298
- - add or extend fixtures for compatibility-critical changes
299
- - `bash scripts/validate-fixtures.sh` now uses the Railway validator service and requires `OPENXML_VALIDATOR_AUTH_TOKEN` when hitting the public domain
300
- - `node scripts/validate-docs-navigation.mjs` enforces the core docs catalog, required indexes, and frontmatter contract
301
-
302
- ## Guiding Principle
303
-
304
- This repo builds backoffice work components where humans and AI agents are first-class peers. Every capability is designed for both audiences from the start — not bolted on for one after the other. The result is tools that are powerful enough for complex enterprise workflows and structured enough that an agent can operate them safely and predictably.
305
-
306
- ## Using the package
307
-
308
- ### WordReviewEditor
309
-
310
- `WordReviewEditor` is a React component for loading, editing, and exporting `.docx` files with full comment and tracked-change (redline) support. It is exported from `@beyondwork/docx-react-component`.
311
-
312
- ### Installation
313
-
314
- ```tsx
315
- import {
316
- WordReviewEditor,
317
- type WordReviewEditorRef,
318
- type WordReviewEditorProps,
319
- type WordReviewEditorEvent,
320
- } from "@beyondwork/docx-react-component";
321
- ```
26
+ Peer dependencies: `react` ≥ 19.2, `react-dom` 19.2, the ProseMirror family (`prosemirror-state`, `prosemirror-view`, `prosemirror-model`, `prosemirror-transform`, `prosemirror-keymap`, `prosemirror-commands`, `prosemirror-schema-basic`), `tailwindcss` ≥ 4.2, and `yjs` + `y-protocols` for collaboration. See `package.json > peerDependencies`.
322
27
 
323
- ### Basic mount
28
+ ## Quick start — mount the editor
324
29
 
325
30
  ```tsx
326
- import { useRef } from "react";
327
- import { WordReviewEditor, type WordReviewEditorRef } from "@beyondwork/docx-react-component";
328
-
329
- export function MyEditor({ docxBytes }: { docxBytes: Uint8Array }) {
330
- const editorRef = useRef<WordReviewEditorRef>(null);
31
+ import { WordReviewEditor } from "@beyondwork/docx-react-component/ui-tailwind";
32
+ import "@beyondwork/docx-react-component/ui-tailwind/theme/editor-theme.css";
331
33
 
34
+ export function App() {
332
35
  return (
333
36
  <WordReviewEditor
334
- ref={editorRef}
335
- documentId="doc-001"
336
- currentUser={{ userId: "u1", displayName: "Alice" }}
337
- initialDocx={docxBytes}
338
- onEvent={(event) => console.log(event)}
37
+ initialDocument={docxBytes}
38
+ onExport={(bytes) => /* persist */}
339
39
  />
340
40
  );
341
41
  }
342
42
  ```
343
43
 
344
- ---
345
-
346
- ### Props reference
347
-
348
- | Prop | Type | Description |
349
- |---|---|---|
350
- | `documentId` | `string` | **Required.** Stable identifier for this document. |
351
- | `currentUser` | `EditorUser` | **Required.** The user performing edits and adding comments. |
352
- | `initialDocx` | `Uint8Array \| ArrayBuffer` | Raw `.docx` bytes to load on first mount. |
353
- | `initialSessionState` | `EditorSessionState` | Previously saved session state to restore. |
354
- | `initialSnapshot` | `PersistedEditorSnapshot` | Previously saved snapshot to restore. |
355
- | `externalDocSource` | `ExternalDocumentSource` | Alternative source with explicit `kind` (`"docx"`, `"session"`, `"snapshot"`). |
356
- | `readOnly` | `boolean` | When `true`, all editing commands are disabled. |
357
- | `reviewMode` | `"editing" \| "review"` | Shell layout hint — affects toolbar/panel arrangement but not editing authority. |
358
- | `markupDisplay` | `"clean" \| "simple" \| "all"` | Controls tracked-change visibility. |
359
- | `showReviewPanel` | `boolean` | Shows or hides the right-side comment and tracked-change panel. |
360
- | `autosave` | `AutosaveConfig` | Enables automatic saving. |
361
- | `hostAdapter` | `EditorHostAdapter` | Callbacks for `load`, `saveSession`, `saveExport`. |
362
- | `datastore` | `EditorDatastoreAdapter` | Alternative persistence adapter with `load`, `saveSnapshot`. |
363
- | `onEvent` | `(event: WordReviewEditorEvent) => void` | Unified event handler (see [Events](#events)). |
364
- | `onWarning` | `(warning: EditorWarning) => void` | Fired for non-fatal warnings. |
365
- | `onError` | `(error: EditorError) => void` | Fired for fatal errors. |
366
-
367
- #### EditorUser
368
-
369
- ```ts
370
- interface EditorUser {
371
- userId: string;
372
- displayName: string;
373
- email?: string;
374
- avatarUrl?: string;
375
- }
376
- ```
377
-
378
- #### AutosaveConfig
44
+ ## Quick start — headless / stateless service
379
45
 
380
46
  ```ts
381
- interface AutosaveConfig {
382
- enabled?: boolean;
383
- debounceMs?: number; // default: 2000
384
- }
385
- ```
386
-
387
- ---
388
-
389
- ### Show / hide UI regions
390
-
391
- #### Review panel
392
-
393
- The right-side panel lists comment threads and tracked changes.
394
-
395
- ```tsx
396
- <WordReviewEditor showReviewPanel={false} ... /> // hide panel
397
- <WordReviewEditor showReviewPanel={true} ... /> // show panel (default)
398
- ```
399
-
400
- #### Tracked-change display mode
401
-
402
- `markupDisplay` controls how tracked changes appear in the document body.
403
-
404
- | Value | Behaviour |
405
- |---|---|
406
- | `"clean"` | Show the accepted version — insertions visible, deletions hidden. |
407
- | `"simple"` | Show a simplified view of changes without inline markup. |
408
- | `"all"` | Show all insertion and deletion marks inline (Word's "Show Markup" mode). |
409
-
410
- ```tsx
411
- <WordReviewEditor markupDisplay="clean" ... />
412
- ```
413
-
414
- You can also change the display mode at runtime:
415
-
416
- ```ts
417
- // no ref method for markupDisplay — pass as a prop; React re-renders propagate the change.
418
- ```
419
-
420
- #### Document mode
421
-
422
- `DocumentMode` controls editing authority, not just appearance.
423
-
424
- | Mode | Effect |
425
- |---|---|
426
- | `"editing"` | Edits are applied directly (no tracking). |
427
- | `"suggesting"` | Every edit is automatically wrapped in a tracked change. |
428
- | `"viewing"` | Document is read-only regardless of the `readOnly` prop. |
429
-
430
- Set via ref:
431
-
432
- ```ts
433
- editorRef.current.setDocumentMode("suggesting");
434
- ```
435
-
436
- Or pass `reviewMode="review"` as a prop to start in a review-friendly shell layout (the component internally maps this to `"suggesting"` document mode).
437
-
438
- #### Read-only mode
439
-
440
- ```tsx
441
- <WordReviewEditor readOnly={true} ... />
442
- ```
443
-
444
- All editing, commenting, and tracked-change commands are blocked. The toolbar is still rendered but all buttons are disabled.
47
+ import { DocxSession } from "@beyondwork/docx-react-component/session";
48
+ import { createApiV3 } from "@beyondwork/docx-react-component/api/v3";
445
49
 
446
- #### Workspace layout
50
+ const session = await DocxSession.open(docxBytes);
51
+ const api = createApiV3(session.runtime);
447
52
 
448
- ```ts
449
- editorRef.current.setWorkspaceMode("canvas"); // continuous scroll
450
- editorRef.current.setWorkspaceMode("page"); // paginated view
53
+ const outline = await api.runtime.document.getOutline();
54
+ const issues = await api.runtime.review.getChanges();
55
+ const bytes = await api.runtime.document.export();
451
56
  ```
452
57
 
453
- ---
454
-
455
- ### Imperative ref
456
-
457
- Obtain the ref via `useRef<WordReviewEditorRef>()`:
458
-
459
- ```tsx
460
- const editorRef = useRef<WordReviewEditorRef>(null);
461
- <WordReviewEditor ref={editorRef} ... />
462
-
463
- // then:
464
- editorRef.current?.addComment({ body: "Needs revision" });
465
- ```
58
+ See [`examples/headless-service/`](examples/headless-service/) for a full stateless consumer.
466
59
 
467
60
  ---
468
61
 
469
- ### Comment operations
62
+ ## What's shipped
470
63
 
471
- #### Add a comment
64
+ **Editing & review**
65
+ - Tracked changes (add, accept, reject, resolve) incl. container + range markers and move-promotion
66
+ - Suggesting mode — every edit automatically becomes a tracked change
67
+ - Comments — anchored, threaded, mention-aware, with presentation/negotiation layer
68
+ - Workflow overlays and scope-based editing guards
69
+ - Document comparison (LCS-backed diffing + redline export)
472
70
 
473
- ```ts
474
- addComment(params: AddCommentParams): string
475
- // returns the new commentId
476
- ```
71
+ **Fidelity**
72
+ - OOXML round-trip — open, edit, export, reopen in Word without repair prompts
73
+ - Preserve-first handling for unknown fragments (opaque preservation)
74
+ - Layout engine — **97.77 %** external layout-structure truth and **96.34 %** rendered-word geometry on the CCEP contract corpus
75
+ - Charts v1 — native SVG renderer for 7 chart families, progressive time-sliced
477
76
 
478
- ```ts
479
- interface AddCommentParams {
480
- anchor?: EditorAnchorProjection; // defaults to the current selection
481
- body?: string;
482
- authorId?: string; // defaults to currentUser.userId
483
- }
484
- ```
485
-
486
- **Important**: if you want the comment to land on a specific text selection, capture the anchor *before* opening any draft UI (e.g. a modal or popover), because opening a modal typically collapses the editor selection.
487
-
488
- ```ts
489
- // 1. Capture anchor while text is still selected
490
- const snapshot = editorRef.current.getRenderSnapshot();
491
- const anchor = snapshot.selection.activeRange;
77
+ **Collaboration**
78
+ - Yjs transport with HMAC-signed awareness, tamper-gating, external-custody round-trip
79
+ - Prerender cache (`prerenderDocument()`) for cold-open parity
492
80
 
493
- // 2. Open your draft UI, let user type a message...
494
- // 3. On submit:
495
- const commentId = editorRef.current.addComment({ anchor, body: draftText });
496
- ```
81
+ **Automation surface**
82
+ - **V1/V2 ref-method API** — stable React imperative surface on `WordReviewEditorRef`
83
+ - **V3 stateless API** — `createApiV3(runtime)` exposes Runtime + AI families under a `live` / `live-with-adapter` / `partial` / `mock` taxonomy
84
+ - AI action policy — risk-classified gating for 37 discrete agent operations
85
+ - Every `uiVisible` V3 function emits exactly one `UxResponse` on the `api` telemetry channel — the stream the debug surfaces consume
497
86
 
498
- #### Resolve a comment
87
+ **Accessibility**
88
+ - Keyboard-first, reduced-motion respected, WCAG-audited (audit harness lives outside the shipping snapshot)
499
89
 
500
- ```ts
501
- editorRef.current.resolveComment(commentId);
502
- ```
503
-
504
- Marks the thread as resolved. The comment remains in the document and can be exported; it is moved to the resolved list in the sidebar.
505
-
506
- #### Reopen a resolved comment
507
-
508
- ```ts
509
- editorRef.current.reopenComment(commentId);
510
- ```
511
-
512
- #### Delete a comment permanently
513
-
514
- ```ts
515
- editorRef.current.deleteComment(commentId);
516
- ```
517
-
518
- Removes the comment entirely. Use this to clean up failed or unwanted drafts.
519
-
520
- #### Add a reply to an existing thread
521
-
522
- ```ts
523
- editorRef.current.addCommentReply(commentId, "Reply text here");
524
- ```
525
-
526
- #### Edit a comment body
527
-
528
- ```ts
529
- editorRef.current.editCommentBody(commentId, "Updated text");
530
- ```
531
-
532
- #### Scroll to a comment
533
-
534
- ```ts
535
- editorRef.current.scrollToComment(commentId);
536
- ```
537
-
538
- #### Open (focus) a comment in the sidebar
539
-
540
- ```ts
541
- editorRef.current.openComment(commentId);
542
- ```
543
-
544
- #### Get all comments
545
-
546
- ```ts
547
- const sidebar: CommentSidebarSnapshot = editorRef.current.getComments();
548
- ```
549
-
550
- ```ts
551
- interface CommentSidebarSnapshot {
552
- activeCommentId?: string;
553
- openCommentIds: string[];
554
- resolvedCommentIds: string[];
555
- detachedCommentIds: string[];
556
- totalCount: number;
557
- threads: CommentSidebarThreadSnapshot[];
558
- }
559
-
560
- interface CommentSidebarThreadSnapshot {
561
- commentId: string;
562
- status: "open" | "resolved" | "detached";
563
- anchor: EditorAnchorProjection;
564
- excerpt: string; // the anchored text snippet
565
- entries: CommentSidebarThreadEntrySnapshot[];
566
- entryCount: number;
567
- createdAt: string; // ISO 8601
568
- createdBy: string; // userId
569
- resolvedAt?: string;
570
- resolvedBy?: string;
571
- }
572
- ```
573
-
574
- #### Detached comments
575
-
576
- A comment becomes **detached** when the text it was anchored to is deleted. Detached comments:
577
-
578
- - Still appear in `sidebar.detachedCommentIds` and have `status: "detached"`.
579
- - Have `anchor.kind === "detached"` with a `lastKnownRange` and a `reason` (`"deleted"`, `"invalidatedByStructureChange"`, or `"importAmbiguity"`).
580
- - Do **not** block DOCX export.
581
- - Can be resolved, reopened, or deleted via the same methods above.
90
+ Feature-level status + known gaps: [`KNOWN-ISSUES.md`](KNOWN-ISSUES.md), [`KNOWN_ISSUES.md`](KNOWN_ISSUES.md), [`KNOWN-ISSUES-VISUAL.md`](KNOWN-ISSUES-VISUAL.md).
582
91
 
583
92
  ---
584
93
 
585
- ### Tracked-change operations
94
+ ## Architecture
586
95
 
587
- #### Get all tracked changes
96
+ The editor runs ProseMirror in an **inverted model**: PM is a view surface, the runtime owns every mutation, and the canonical truth order is
588
97
 
589
- ```ts
590
- const changes: TrackedChangesSnapshot = editorRef.current.getTrackedChanges();
591
- ```
98
+ 1. OOXML package bytes
99
+ 2. `CanonicalDocument`
100
+ 3. `DocumentRuntime` derived state (formatting, layout, geometry, scopes, review)
101
+ 4. `EditorSurfaceSnapshot` + PM state + DOM
592
102
 
593
- ```ts
594
- interface TrackedChangesSnapshot {
595
- pendingChangeIds: string[];
596
- acceptedChangeIds: string[];
597
- rejectedChangeIds: string[];
598
- detachedChangeIds: string[];
599
- actionableChangeIds: string[];
600
- preserveOnlyChangeIds: string[];
601
- totalCount: number;
602
- revisions: TrackedChangeEntrySnapshot[];
603
- }
103
+ Higher layers are projections of lower layers. Reading the DOM or PM state as truth is a bug.
604
104
 
605
- interface TrackedChangeEntrySnapshot {
606
- revisionId: string;
607
- kind: "insertion" | "deletion" | "formatting" | "move" | "property-change";
608
- status: "active" | "accepted" | "rejected" | "detached";
609
- actionability: "actionable" | "preserve-only";
610
- canAccept: boolean;
611
- canReject: boolean;
612
- anchor: EditorAnchorProjection;
613
- anchorLabel: string;
614
- excerpt?: string;
615
- detail?: string;
616
- authorId: string;
617
- createdAt: string;
618
- }
619
- ```
620
-
621
- `preserve-only` revisions (`formatting`, `move`) can be displayed but cannot be individually accepted or rejected through the API.
622
-
623
- #### Accept a single change
624
-
625
- ```ts
626
- editorRef.current.acceptChange(revisionId);
627
- ```
628
-
629
- #### Reject a single change
630
-
631
- ```ts
632
- editorRef.current.rejectChange(revisionId);
633
- ```
634
-
635
- #### Accept all pending changes
636
-
637
- ```ts
638
- editorRef.current.acceptAllChanges();
639
- ```
640
-
641
- #### Reject all pending changes
642
-
643
- ```ts
644
- editorRef.current.rejectAllChanges();
645
- ```
646
-
647
- #### Scroll to a tracked change
648
-
649
- ```ts
650
- editorRef.current.scrollToRevision(revisionId);
651
- ```
105
+ The 11-layer target architecture — session, canonical document, formatting, layout, geometry, workflow, runtime API, semantic scope compiler, AI API, UI API, presentation — is documented in [`docs/architecture/00-overview.md`](docs/architecture/00-overview.md), with per-layer canonical specs in [`docs/architecture/01-package-session.md`](docs/architecture/01-package-session.md) … [`11-presentation-surfaces.md`](docs/architecture/11-presentation-surfaces.md).
652
106
 
653
107
  ---
654
108
 
655
- ### Export
109
+ ## Documentation lanes
656
110
 
657
- ```ts
658
- const result = await editorRef.current.exportDocx({ fileName: "output.docx" });
659
- // result.bytes is the Uint8Array of the .docx file
660
- ```
661
-
662
- Export will throw if any non-detached comment no longer maps to a serializable range in the document. To diagnose, check `getComments().threads` for entries where `status !== "detached"` but whose `anchor.kind` is unexpected.
111
+ | Lane | Path | When to start here |
112
+ |---|---|---|
113
+ | Router | [`docs/README.md`](docs/README.md) | Any time triage into the right lane |
114
+ | Architecture | [`docs/architecture/00-overview.md`](docs/architecture/00-overview.md) | Canonical per-layer target design for the 11-layer stack |
115
+ | Wiki (feature deep-dives) | [`docs/wiki/`](docs/wiki/) | Topic-organized narrative connecting OOXML + PM + implementation + testing |
116
+ | Migration | [`MIGRATION.md`](MIGRATION.md) | Upgrading across major versions |
117
+ | Known issues | [`KNOWN-ISSUES.md`](KNOWN-ISSUES.md), [`KNOWN_ISSUES.md`](KNOWN_ISSUES.md), [`KNOWN-ISSUES-VISUAL.md`](KNOWN-ISSUES-VISUAL.md) | Preview caveats + visual-fidelity gap inventory |
118
+ | Changelog | [`CHANGELOG.md`](CHANGELOG.md) | Release notes |
663
119
 
664
120
  ---
665
121
 
666
- ### Events
667
-
668
- All events are dispatched through the single `onEvent` prop. The `type` discriminator narrows the payload.
122
+ ## Development
669
123
 
670
- ```tsx
671
- <WordReviewEditor
672
- onEvent={(event) => {
673
- if (event.type === "comment_added") {
674
- console.log("New comment:", event.commentId);
675
- }
676
- }}
677
- />
678
- ```
679
-
680
- #### `ready`
681
-
682
- Fired once after the document finishes loading and the editor is interactive.
683
-
684
- ```ts
685
- {
686
- type: "ready";
687
- documentId: string;
688
- sessionId: string;
689
- source: "docx" | "session" | "snapshot";
690
- stats: DocumentStats; // storyLength, commentCount, revisionCount
691
- compatibility: CompatibilityReport;
692
- comments: CommentSidebarSnapshot;
693
- trackedChanges: TrackedChangesSnapshot;
694
- }
695
- ```
696
-
697
- #### `comment_added`
698
-
699
- Fired when a new comment thread is created (via `addComment` or the toolbar).
700
-
701
- ```ts
702
- {
703
- type: "comment_added";
704
- documentId: string;
705
- commentId: string;
706
- anchor: EditorAnchorProjection;
707
- }
708
- ```
709
-
710
- #### `comment_resolved`
711
-
712
- Fired when a comment is resolved (via `resolveComment` or the sidebar).
713
-
714
- ```ts
715
- {
716
- type: "comment_resolved";
717
- documentId: string;
718
- commentId: string;
719
- }
720
- ```
721
-
722
- For a general-purpose "something about comments changed" signal (covering deletions, reply appends, body edits, reopen, and every other mutation — including Yjs-driven mutations that route through the editor's imperative ref), subscribe to `comments_changed`.
723
-
724
- #### `comments_changed`
725
-
726
- Fired once per commit whenever the runtime's comment snapshot differs from the previous commit. Use this when you render comments in a sibling component and need to know when to re-fetch via `editorRef.current.getComments()`.
727
-
728
- ```ts
729
- {
730
- type: "comments_changed";
731
- documentId: string;
732
- changedCommentIds: string[]; // always non-empty
733
- }
734
- ```
735
-
736
- Covers: `addComment`, `deleteComment`, `resolveComment`, `reopenComment`, `addCommentReply`, `editCommentBody`, and any remote-origin mutation that funnels through the same runtime APIs. Does NOT fire on selection/focus changes.
737
-
738
- #### `change_accepted`
739
-
740
- Fired when a tracked change is accepted.
741
-
742
- ```ts
743
- {
744
- type: "change_accepted";
745
- documentId: string;
746
- changeId: string;
747
- }
748
- ```
749
-
750
- #### `change_rejected`
751
-
752
- Fired when a tracked change is rejected.
753
-
754
- ```ts
755
- {
756
- type: "change_rejected";
757
- documentId: string;
758
- changeId: string;
759
- }
760
- ```
761
-
762
- #### `selection_changed`
763
-
764
- Fired whenever the editor cursor or selection changes.
765
-
766
- ```ts
767
- {
768
- type: "selection_changed";
769
- documentId: string;
770
- selection: SelectionSnapshot;
771
- }
772
-
773
- interface SelectionSnapshot {
774
- anchor: number;
775
- head: number;
776
- isCollapsed: boolean;
777
- activeRange: EditorAnchorProjection;
778
- storyTarget?: EditorStoryTarget;
779
- }
780
- ```
781
-
782
- Use `selection.activeRange` as the `anchor` argument to `addComment` — but capture it *before* opening any modal UI.
783
-
784
- #### `dirty_changed`
785
-
786
- Fired when the document transitions between clean and dirty (unsaved) states.
787
-
788
- ```ts
789
- {
790
- type: "dirty_changed";
791
- documentId: string;
792
- isDirty: boolean;
793
- }
794
- ```
795
-
796
- #### `story_changed`
797
-
798
- Fired when the user navigates between document stories (e.g. main body -> header/footer).
799
-
800
- ```ts
801
- {
802
- type: "story_changed";
803
- documentId: string;
804
- activeStory: EditorStoryTarget;
805
- }
806
- ```
807
-
808
- #### `export_completed`
809
-
810
- Fired after a successful `exportDocx` call, after the host `saveExport` callback (if any) has resolved.
811
-
812
- ```ts
813
- {
814
- type: "export_completed";
815
- documentId: string;
816
- result: ExportResult; // result.bytes, result.fileName, result.mimeType
817
- }
818
- ```
819
-
820
- #### `session_saved`
821
-
822
- Fired after the host `saveSession` callback resolves.
823
-
824
- ```ts
825
- {
826
- type: "session_saved";
827
- documentId: string;
828
- sessionState: EditorSessionState;
829
- savedAt: string;
830
- isAutosave: boolean;
831
- }
832
- ```
833
-
834
- #### `snapshot_saved`
835
-
836
- Fired after the datastore `saveSnapshot` callback resolves.
837
-
838
- ```ts
839
- {
840
- type: "snapshot_saved";
841
- documentId: string;
842
- snapshot: PersistedEditorSnapshot;
843
- isAutosave: boolean;
844
- }
845
- ```
846
-
847
- #### `autosave_state`
848
-
849
- Fired when the autosave lifecycle transitions.
850
-
851
- ```ts
852
- {
853
- type: "autosave_state";
854
- documentId: string;
855
- state: "idle" | "pending" | "saving" | "saved" | "error";
856
- }
857
- ```
858
-
859
- #### `warning_added` / `warning_cleared`
860
-
861
- Non-fatal import or rendering warnings.
862
-
863
- ```ts
864
- { type: "warning_added"; documentId: string; warning: EditorWarning; }
865
- { type: "warning_cleared"; documentId: string; warningId: string; code: EditorWarningCode; }
866
- ```
867
-
868
- #### `error`
869
-
870
- Fatal editor error. The editor may be in an unrecoverable state after this event.
871
-
872
- ```ts
873
- {
874
- type: "error";
875
- documentId: string;
876
- error: EditorError; // error.code, error.message, error.isFatal
877
- }
878
- ```
879
-
880
- #### Workflow events
881
-
882
- These events relate to the optional workflow overlay feature.
124
+ | Command | Purpose |
125
+ |---|---|
126
+ | `pnpm run lint:tsgo` | TypeScript type check |
127
+ | `pnpm test:repo` | Contract + validation test suite |
128
+ | `pnpm run build` | Build the shipped package |
883
129
 
884
- ```ts
885
- { type: "workflow_overlay_changed"; documentId: string; snapshot: WorkflowScopeSnapshot; }
886
- { type: "workflow_active_work_item_changed"; documentId: string; activeWorkItemId: string | null; }
887
- { type: "command_blocked"; documentId: string; command: string; reasons: WorkflowBlockedCommandReason[]; }
888
- ```
130
+ Agent onboarding: [`CLAUDE.md`](CLAUDE.md), [`AGENTS.md`](AGENTS.md).
131
+ Product charters: [`DESIGN-EDITOR.md`](DESIGN-EDITOR.md), [`DESIGN-WORKBLOCK.md`](DESIGN-WORKBLOCK.md).
132
+ Findings log: [`SHIP-LOG.md`](SHIP-LOG.md).
889
133
 
890
134
  ---
891
135
 
892
- ### Key types
893
-
894
- #### EditorAnchorProjection
895
-
896
- Describes a position or range in the document. Returned by `selection.activeRange` and stored on comments/revisions.
897
-
898
- ```ts
899
- type EditorAnchorProjection =
900
- | { kind: "range"; from: number; to: number; assoc: { start: -1|1; end: -1|1 } }
901
- | { kind: "node"; at: number; assoc: -1|1 }
902
- | { kind: "detached"; lastKnownRange: { from: number; to: number };
903
- reason: "deleted" | "invalidatedByStructureChange" | "importAmbiguity" };
904
- ```
905
-
906
- A `"range"` anchor is required for `addComment` if the document contains tables or the selection spans multiple characters. The `from`/`to` positions are in the editor's internal runtime coordinate space — always capture them from `getRenderSnapshot().selection.activeRange`, never construct them manually.
907
-
908
- #### DocumentMode
909
-
910
- ```ts
911
- type DocumentMode = "editing" | "suggesting" | "viewing";
912
- ```
913
-
914
- #### WorkspaceMode
136
+ ## Browser / runtime support
915
137
 
916
- ```ts
917
- type WorkspaceMode = "canvas" | "page";
918
- ```
138
+ - Modern evergreen browsers (Chrome, Firefox, Safari, Edge)
139
+ - React 19.2+, Node 22+ for server-side usage
140
+ - No web workers — all time-slicing via `scheduler.yield` / `requestIdleCallback` on the main thread
919
141
 
920
142
  ---
921
143
 
922
- ### Common patterns
923
-
924
- #### Full add-comment flow with custom UI
925
-
926
- ```tsx
927
- function CommentButton({ editorRef }: { editorRef: React.RefObject<WordReviewEditorRef> }) {
928
- const [draft, setDraft] = useState<{ anchor: EditorAnchorProjection; text: string } | null>(null);
929
-
930
- function openDraft() {
931
- // Capture anchor BEFORE the modal steals focus from the editor
932
- const snapshot = editorRef.current?.getRenderSnapshot();
933
- if (!snapshot) return;
934
- const anchor = snapshot.selection.activeRange;
935
- if (anchor.kind !== "range" || anchor.from === anchor.to) return;
936
- setDraft({ anchor, text: "" });
937
- }
938
-
939
- function submit() {
940
- if (!draft) return;
941
- editorRef.current?.addComment({ anchor: draft.anchor, body: draft.text });
942
- setDraft(null);
943
- }
944
-
945
- return (
946
- <>
947
- <button onClick={openDraft}>Comment</button>
948
- {draft && (
949
- <dialog open>
950
- <textarea value={draft.text} onChange={(e) => setDraft({ ...draft, text: e.target.value })} />
951
- <button onClick={submit}>Add</button>
952
- <button onClick={() => setDraft(null)}>Cancel</button>
953
- </dialog>
954
- )}
955
- </>
956
- );
957
- }
958
- ```
959
-
960
- #### Listen for comment and review-change events
144
+ ## License
961
145
 
962
- ```tsx
963
- <WordReviewEditor
964
- onEvent={(event) => {
965
- switch (event.type) {
966
- case "comment_added":
967
- console.log("comment added:", event.commentId, event.anchor);
968
- break;
969
- case "comment_resolved":
970
- console.log("comment resolved:", event.commentId);
971
- break;
972
- case "comments_changed":
973
- console.log("comments changed:", event.changedCommentIds);
974
- break;
975
- case "change_accepted":
976
- console.log("change accepted:", event.changeId);
977
- break;
978
- case "change_rejected":
979
- console.log("change rejected:", event.changeId);
980
- break;
981
- }
982
- }}
983
- />
984
- ```
985
-
986
- #### Resolve all open comments programmatically
987
-
988
- ```ts
989
- const { threads } = editorRef.current.getComments();
990
- for (const thread of threads) {
991
- if (thread.status === "open") {
992
- editorRef.current.resolveComment(thread.commentId);
993
- }
994
- }
995
- ```
996
-
997
- #### Accept or reject all actionable changes
998
-
999
- ```ts
1000
- editorRef.current.acceptAllChanges();
1001
- // or
1002
- editorRef.current.rejectAllChanges();
1003
- ```
146
+ See [`LICENSE.md`](LICENSE.md). The package is published under the Beyond Work license for use inside the Beyond Work platform and its authorized integrations.