@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
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @endStateApi v3 — `runtime.table` family.
3
+ *
4
+ * Single function: `getSelectionDescriptor(state)`. Read-only projection
5
+ * that inspects the current PM `EditorState` and returns a typed
6
+ * descriptor (`TableSelectionDescriptor`) when the selection is inside
7
+ * a table — block index, cell coords, rect bounds — or null otherwise.
8
+ * Thin pass-through over `getTableSelectionDescriptor` from
9
+ * `src/runtime/table-commands.ts` so L11's PM surface can migrate to
10
+ * the v3 seam (coord-11 §4.3).
11
+ *
12
+ * PM-command exports (addRowBefore/After, deleteRow, addColumnBefore/
13
+ * After, deleteColumn, mergeCells, splitCell, toggleHeader*) stay on
14
+ * the runtime module for now — they are PM-native `Command` values
15
+ * that the editor's keymap dispatches, not agent-callable functions.
16
+ * Exposing them via v3 is out of scope for this slice; the one L11
17
+ * import this family retires is the `getTableSelectionDescriptor` +
18
+ * type import on `tw-prosemirror-surface.tsx`.
19
+ *
20
+ * Pure-function read — `stateClass: "C-local"` + `persistsTo: "none"`.
21
+ * No UxResponse emission.
22
+ */
23
+
24
+ import type { EditorState } from "prosemirror-state";
25
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
26
+ import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
27
+ import {
28
+ getTableSelectionDescriptor,
29
+ type TableSelectionDescriptor,
30
+ } from "../../../runtime/table-commands.ts";
31
+
32
+ // Re-export so L11 consumers don't peek into `src/runtime/table-commands.ts`
33
+ // for the type either.
34
+ export type { TableSelectionDescriptor };
35
+
36
+ export const getSelectionDescriptorMetadata: ApiV3FnMetadata = {
37
+ name: "runtime.table.getSelectionDescriptor",
38
+ status: "live",
39
+ sourceLayer: "runtime-core",
40
+ liveEvidence: {
41
+ runnerTest: "test/api/v3/live-parity.test.ts",
42
+ commit: "refactor-07-table-family-2026-04-23",
43
+ },
44
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
45
+ agentMetadata: {
46
+ readOrMutate: "read",
47
+ boundedScope: "document",
48
+ auditCategory: "table-selection-read",
49
+ },
50
+ stateClass: "C-local",
51
+ persistsTo: "none",
52
+ rwdReference:
53
+ "§Runtime API § runtime.table.getSelectionDescriptor. Direct delegation to getTableSelectionDescriptor (src/runtime/table-commands.ts). Inspects the PM EditorState and returns a typed descriptor when the selection resolves inside a table, or null otherwise.",
54
+ };
55
+
56
+ export function createTableFamily(_runtime: RuntimeApiHandle) {
57
+ return {
58
+ getSelectionDescriptor(state: EditorState): TableSelectionDescriptor | null {
59
+ // @endStateApi — live.
60
+ return getTableSelectionDescriptor(state);
61
+ },
62
+ };
63
+ }
@@ -0,0 +1,434 @@
1
+ /**
2
+ * @endStateApi v3 — `runtime.workflow` family.
3
+ *
4
+ * queryScopes (live) / getMarkup (live) / getGuard (live) /
5
+ * createScope (live-with-adapter) / attachMetadata (live-with-adapter) /
6
+ * getVisibilityPolicy · getVisibilityPolicies · setVisibilityPolicy ·
7
+ * clearVisibilityPolicy (live — W10 state-classes X1).
8
+ */
9
+
10
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
11
+ import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
12
+ import type {
13
+ OverlayKind,
14
+ OverlayVisibilityPolicy,
15
+ WorkflowMarkupModePolicy,
16
+ } from "../../public-types.ts";
17
+ import { emitUxResponse } from "../_ux-response.ts";
18
+ import { createScopeFromBlockId } from "../../../runtime/workflow/scope-writer.ts";
19
+ import { attachScopeMetadata } from "../../../runtime/workflow/metadata-writer.ts";
20
+
21
+ export const queryScopesMetadata: ApiV3FnMetadata = {
22
+ name: "runtime.workflow.queryScopes",
23
+ status: "live",
24
+ sourceLayer: "workflow-review",
25
+ liveEvidence: { runnerTest: "test/runtime/debug/build-debug-inspector-snapshot.test.ts", commit: "6aca0666" },
26
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
27
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "scope-list" },
28
+ stateClass: "A-canonical",
29
+ persistsTo: "customXml",
30
+ broadcastsVia: "crdt",
31
+ rwdReference: "§Runtime API § runtime.workflow.queryScopes",
32
+ };
33
+
34
+ export const getMarkupMetadata: ApiV3FnMetadata = {
35
+ name: "runtime.workflow.getMarkup",
36
+ status: "live",
37
+ sourceLayer: "workflow-review",
38
+ liveEvidence: {
39
+ runnerTest: "test/api/v3/live-parity.test.ts",
40
+ commit: "phase-p-prime",
41
+ },
42
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
43
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "markup-read" },
44
+ stateClass: "A-canonical",
45
+ persistsTo: "customXml",
46
+ broadcastsVia: "crdt",
47
+ rwdReference: "§Runtime API § runtime.workflow.getMarkup",
48
+ };
49
+
50
+ export const getGuardMetadata: ApiV3FnMetadata = {
51
+ name: "runtime.workflow.getGuard",
52
+ status: "live",
53
+ sourceLayer: "workflow-review",
54
+ liveEvidence: {
55
+ // Direct parity test — asserts v3.getGuard delegates to
56
+ // handle.getInteractionGuardSnapshot() and returns the exact
57
+ // InteractionGuardSnapshot shape (effectiveMode + blockedReasons).
58
+ runnerTest: "test/api/v3/behavioral-coverage.test.ts",
59
+ commit: "refactor-07-adversarial-closure-2026-04-22",
60
+ },
61
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
62
+ agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "guard-read" },
63
+ stateClass: "A-canonical",
64
+ persistsTo: "customXml",
65
+ broadcastsVia: "crdt",
66
+ rwdReference: "§Runtime API § runtime.workflow.getGuard",
67
+ };
68
+
69
+ export interface CreateScopeInput {
70
+ readonly blockId: string;
71
+ readonly mode?: "edit" | "suggest" | "comment" | "view";
72
+ readonly label?: string;
73
+ /**
74
+ * Coord-06 §13d — per-scope edge stickiness. Defaults to
75
+ * `{ start: 1, end: -1 }` (greedy — absorbs boundary inserts, the
76
+ * pre-§13d shipped shape). Use `{ start: -1, end: 1 }` for a
77
+ * fixed-position anchor (signature-block / template-slot / system-
78
+ * paragraph semantics — rejects boundary inserts; cursor work doesn't
79
+ * leak in). Agents pick per scope family per coord-09 §1.14.
80
+ */
81
+ readonly assoc?: { readonly start: -1 | 1; readonly end: -1 | 1 };
82
+ }
83
+
84
+ export interface CreateScopeResult {
85
+ readonly scopeId: string;
86
+ readonly status: "created" | "block-not-found";
87
+ }
88
+
89
+ export const createScopeMetadata: ApiV3FnMetadata = {
90
+ name: "runtime.workflow.createScope",
91
+ status: "live-with-adapter",
92
+ sourceLayer: "workflow-review",
93
+ liveEvidence: {
94
+ runnerTest: "test/api/v3/workflow-create-scope-live.test.ts",
95
+ commit: "609ffec2",
96
+ },
97
+ uxIntent: { uiVisible: true, expectsUxResponse: "scope-created", expectedDelta: "rail shows new scope chip; editor surface refreshes" },
98
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "selection", auditCategory: "scope-creation" },
99
+ stateClass: "A-canonical",
100
+ persistsTo: "customXml",
101
+ broadcastsVia: "crdt",
102
+ rwdReference: "§Runtime API § runtime.workflow.createScope",
103
+ };
104
+
105
+ export interface AttachMetadataInput {
106
+ readonly scopeId: string;
107
+ readonly metadataId: string;
108
+ readonly value?: Record<string, unknown>;
109
+ }
110
+
111
+ export interface AttachMetadataResult {
112
+ readonly status: "attached" | "scope-not-found";
113
+ readonly entryId?: string;
114
+ }
115
+
116
+ export const attachMetadataMetadata: ApiV3FnMetadata = {
117
+ name: "runtime.workflow.attachMetadata",
118
+ status: "live-with-adapter",
119
+ sourceLayer: "workflow-review",
120
+ liveEvidence: {
121
+ runnerTest: "test/api/v3/workflow-attach-metadata-live.test.ts",
122
+ commit: "609ffec2",
123
+ },
124
+ uxIntent: { uiVisible: true, expectsUxResponse: "inline-change", expectedDelta: "scope card shows new metadata field" },
125
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "scope", auditCategory: "metadata-write" },
126
+ stateClass: "A-canonical",
127
+ persistsTo: "customXml",
128
+ broadcastsVia: "crdt",
129
+ rwdReference: "§Runtime API § runtime.workflow.attachMetadata",
130
+ };
131
+
132
+ export const getVisibilityPolicyMetadata: ApiV3FnMetadata = {
133
+ name: "runtime.workflow.getVisibilityPolicy",
134
+ status: "live",
135
+ sourceLayer: "workflow-review",
136
+ liveEvidence: {
137
+ runnerTest: "test/runtime/workflow/visibility-policy-roundtrip.test.ts",
138
+ commit: "state-classes-x1",
139
+ },
140
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
141
+ agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "policy-read" },
142
+ stateClass: "A-canonical",
143
+ persistsTo: "customXml",
144
+ broadcastsVia: "crdt",
145
+ rwdReference: "§Runtime API § runtime.workflow.getVisibilityPolicy",
146
+ };
147
+
148
+ export const getVisibilityPoliciesMetadata: ApiV3FnMetadata = {
149
+ name: "runtime.workflow.getVisibilityPolicies",
150
+ status: "live",
151
+ sourceLayer: "workflow-review",
152
+ liveEvidence: {
153
+ runnerTest: "test/runtime/workflow/visibility-policy-roundtrip.test.ts",
154
+ commit: "state-classes-x1",
155
+ },
156
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
157
+ agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "policy-read" },
158
+ stateClass: "A-canonical",
159
+ persistsTo: "customXml",
160
+ broadcastsVia: "crdt",
161
+ rwdReference: "§Runtime API § runtime.workflow.getVisibilityPolicies",
162
+ };
163
+
164
+ export const setVisibilityPolicyMetadata: ApiV3FnMetadata = {
165
+ name: "runtime.workflow.setVisibilityPolicy",
166
+ status: "live",
167
+ sourceLayer: "workflow-review",
168
+ liveEvidence: {
169
+ runnerTest: "test/runtime/workflow/visibility-policy-roundtrip.test.ts",
170
+ commit: "state-classes-x1",
171
+ },
172
+ uxIntent: {
173
+ uiVisible: true,
174
+ expectsUxResponse: "inline-change",
175
+ expectedDelta: "overlay visibility follows authored policy on all subscribed surfaces",
176
+ },
177
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "document", auditCategory: "policy-write" },
178
+ stateClass: "A-canonical",
179
+ persistsTo: "customXml",
180
+ broadcastsVia: "crdt",
181
+ rwdReference: "§Runtime API § runtime.workflow.setVisibilityPolicy",
182
+ };
183
+
184
+ export const subscribeVisibilityPolicyMetadata: ApiV3FnMetadata = {
185
+ name: "runtime.workflow.subscribeVisibilityPolicy",
186
+ status: "live",
187
+ sourceLayer: "workflow-review",
188
+ liveEvidence: {
189
+ runnerTest: "test/runtime/workflow/visibility-policy-subscribe.test.ts",
190
+ commit: "state-classes-x1-subscribe",
191
+ },
192
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
193
+ agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "policy-read" },
194
+ stateClass: "A-canonical",
195
+ persistsTo: "customXml",
196
+ broadcastsVia: "crdt",
197
+ rwdReference: "§Runtime API § runtime.workflow.subscribeVisibilityPolicy",
198
+ };
199
+
200
+ export const clearVisibilityPolicyMetadata: ApiV3FnMetadata = {
201
+ name: "runtime.workflow.clearVisibilityPolicy",
202
+ status: "live",
203
+ sourceLayer: "workflow-review",
204
+ liveEvidence: {
205
+ runnerTest: "test/runtime/workflow/visibility-policy-roundtrip.test.ts",
206
+ commit: "state-classes-x1",
207
+ },
208
+ uxIntent: {
209
+ uiVisible: true,
210
+ expectsUxResponse: "inline-change",
211
+ expectedDelta: "overlay visibility reverts to class-C local default",
212
+ },
213
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "document", auditCategory: "policy-write" },
214
+ stateClass: "A-canonical",
215
+ persistsTo: "customXml",
216
+ broadcastsVia: "crdt",
217
+ rwdReference: "§Runtime API § runtime.workflow.clearVisibilityPolicy",
218
+ };
219
+
220
+ // ---------------------------------------------------------------------------
221
+ // X5 · markup-mode policy metadata
222
+ // ---------------------------------------------------------------------------
223
+
224
+ export const getMarkupModePolicyMetadata: ApiV3FnMetadata = {
225
+ name: "runtime.workflow.getMarkupModePolicy",
226
+ status: "live",
227
+ sourceLayer: "workflow-review",
228
+ liveEvidence: {
229
+ runnerTest: "test/runtime/workflow/markup-mode-policy-roundtrip.test.ts",
230
+ commit: "state-classes-x5",
231
+ },
232
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
233
+ agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "policy-read" },
234
+ stateClass: "A-canonical",
235
+ persistsTo: "customXml",
236
+ broadcastsVia: "crdt",
237
+ rwdReference: "§Runtime API § runtime.workflow.getMarkupModePolicy",
238
+ };
239
+
240
+ export const setMarkupModePolicyMetadata: ApiV3FnMetadata = {
241
+ name: "runtime.workflow.setMarkupModePolicy",
242
+ status: "live",
243
+ sourceLayer: "workflow-review",
244
+ liveEvidence: {
245
+ runnerTest: "test/runtime/workflow/markup-mode-policy-roundtrip.test.ts",
246
+ commit: "state-classes-x5",
247
+ },
248
+ uxIntent: {
249
+ uiVisible: true,
250
+ expectsUxResponse: "inline-change",
251
+ expectedDelta: "revision markup surfaces switch to the authored mode on all subscribed surfaces",
252
+ },
253
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "document", auditCategory: "policy-write" },
254
+ stateClass: "A-canonical",
255
+ persistsTo: "customXml",
256
+ broadcastsVia: "crdt",
257
+ rwdReference: "§Runtime API § runtime.workflow.setMarkupModePolicy",
258
+ };
259
+
260
+ export const subscribeMarkupModePolicyMetadata: ApiV3FnMetadata = {
261
+ name: "runtime.workflow.subscribeMarkupModePolicy",
262
+ status: "live",
263
+ sourceLayer: "workflow-review",
264
+ liveEvidence: {
265
+ runnerTest: "test/runtime/workflow/markup-mode-policy-roundtrip.test.ts",
266
+ commit: "state-classes-x5",
267
+ },
268
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
269
+ agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "policy-read" },
270
+ stateClass: "A-canonical",
271
+ persistsTo: "customXml",
272
+ broadcastsVia: "crdt",
273
+ rwdReference: "§Runtime API § runtime.workflow.subscribeMarkupModePolicy",
274
+ };
275
+
276
+ export function createWorkflowFamily(runtime: RuntimeApiHandle) {
277
+ return {
278
+ queryScopes(filter?: unknown) {
279
+ // @endStateApi — live.
280
+ return runtime.queryScopes(filter as never);
281
+ },
282
+
283
+ getMarkup() {
284
+ // @endStateApi — live. Delegates to the workflow markup snapshot
285
+ // (separate from getWorkflowOverlay(), which returns overlay state).
286
+ return runtime.getWorkflowMarkupSnapshot();
287
+ },
288
+
289
+ getGuard() {
290
+ // @endStateApi — live.
291
+ return runtime.getInteractionGuardSnapshot();
292
+ },
293
+
294
+ createScope(input: CreateScopeInput): CreateScopeResult {
295
+ // @endStateApi — live-with-adapter. Resolves blockId → anchor via the
296
+ // surface snapshot then delegates to runtime.addScope (layer-06
297
+ // scope-writer). Status discriminator surfaces "block-not-found" /
298
+ // "no-surface" instead of inventing an anchor.
299
+ const adapterResult = createScopeFromBlockId(runtime, {
300
+ blockId: input.blockId,
301
+ mode: input.mode,
302
+ label: input.label,
303
+ ...(input.assoc ? { assoc: input.assoc } : {}),
304
+ });
305
+ emitUxResponse(runtime, {
306
+ apiFn: createScopeMetadata.name,
307
+ intent: createScopeMetadata.uxIntent.expectedDelta ?? "",
308
+ mockOrLive: "live",
309
+ uiVisible: true,
310
+ expectedDelta: createScopeMetadata.uxIntent.expectedDelta,
311
+ actualDelta:
312
+ adapterResult.status === "created"
313
+ ? { kind: "inline-change", payload: { scopeId: adapterResult.scopeId } }
314
+ : undefined,
315
+ });
316
+ if (adapterResult.status !== "created") {
317
+ return { scopeId: "", status: adapterResult.status };
318
+ }
319
+ return { scopeId: adapterResult.scopeId, status: "created" };
320
+ },
321
+
322
+ getVisibilityPolicy(kind: OverlayKind): OverlayVisibilityPolicy | null {
323
+ // @endStateApi — live. Class-A policy read; composition with
324
+ // class-C local preference lives in L10 (`ui.overlays.getVisibility`).
325
+ return runtime.getVisibilityPolicy(kind);
326
+ },
327
+
328
+ getVisibilityPolicies(): readonly OverlayVisibilityPolicy[] {
329
+ // @endStateApi — live.
330
+ return runtime.getVisibilityPolicies();
331
+ },
332
+
333
+ setVisibilityPolicy(policy: OverlayVisibilityPolicy): { changed: boolean } {
334
+ // @endStateApi — live. Author a class-A policy; persists on next
335
+ // exportDocx via `customXml/item1.xml` (bw:overlayVisibility) and
336
+ // broadcasts via CRDT when collab is attached.
337
+ const changed = runtime.setVisibilityPolicy(policy);
338
+ if (changed) {
339
+ emitUxResponse(runtime, {
340
+ apiFn: setVisibilityPolicyMetadata.name,
341
+ intent: setVisibilityPolicyMetadata.uxIntent.expectedDelta ?? "",
342
+ mockOrLive: "live",
343
+ uiVisible: true,
344
+ expectedDelta: setVisibilityPolicyMetadata.uxIntent.expectedDelta,
345
+ actualDelta: { kind: "inline-change", payload: { kind: policy.kind } },
346
+ });
347
+ }
348
+ return { changed };
349
+ },
350
+
351
+ subscribeVisibilityPolicy(listener: () => void): () => void {
352
+ // @endStateApi — live. Fires after set/clear/replace policy mutations.
353
+ // Chained by L10 X3's ui.overlays.subscribeVisibility so UI surfaces
354
+ // re-fire when authoring tools mutate policy mid-session.
355
+ return runtime.subscribeVisibilityPolicy(listener);
356
+ },
357
+
358
+ getMarkupModePolicy(): WorkflowMarkupModePolicy | null {
359
+ // @endStateApi — live. Class-A markup-mode policy read; composition
360
+ // with class-C local preference lives in L10 X5.
361
+ return runtime.getMarkupModePolicy();
362
+ },
363
+
364
+ setMarkupModePolicy(
365
+ policy: WorkflowMarkupModePolicy | null,
366
+ ): { changed: boolean } {
367
+ // @endStateApi — live. Authors (or clears) the class-A policy;
368
+ // persists on next exportDocx via customXml/item1.xml (bw:markupModePolicy).
369
+ const changed = runtime.setMarkupModePolicy(policy);
370
+ if (changed) {
371
+ emitUxResponse(runtime, {
372
+ apiFn: setMarkupModePolicyMetadata.name,
373
+ intent: setMarkupModePolicyMetadata.uxIntent.expectedDelta ?? "",
374
+ mockOrLive: "live",
375
+ uiVisible: true,
376
+ expectedDelta: setMarkupModePolicyMetadata.uxIntent.expectedDelta,
377
+ actualDelta: {
378
+ kind: "inline-change",
379
+ payload: { mode: policy?.mode ?? null, enforcement: policy?.enforcement ?? null },
380
+ },
381
+ });
382
+ }
383
+ return { changed };
384
+ },
385
+
386
+ subscribeMarkupModePolicy(listener: () => void): () => void {
387
+ // @endStateApi — live. Fires after setMarkupModePolicy mutations.
388
+ return runtime.subscribeMarkupModePolicy(listener);
389
+ },
390
+
391
+ clearVisibilityPolicy(kind: OverlayKind): { changed: boolean } {
392
+ // @endStateApi — live.
393
+ const changed = runtime.clearVisibilityPolicy(kind);
394
+ if (changed) {
395
+ emitUxResponse(runtime, {
396
+ apiFn: clearVisibilityPolicyMetadata.name,
397
+ intent: clearVisibilityPolicyMetadata.uxIntent.expectedDelta ?? "",
398
+ mockOrLive: "live",
399
+ uiVisible: true,
400
+ expectedDelta: clearVisibilityPolicyMetadata.uxIntent.expectedDelta,
401
+ actualDelta: { kind: "inline-change", payload: { kind } },
402
+ });
403
+ }
404
+ return { changed };
405
+ },
406
+
407
+ attachMetadata(input: AttachMetadataInput): AttachMetadataResult {
408
+ // @endStateApi — live-with-adapter. Reuses the target scope's anchor
409
+ // and dispatches through runtime.setWorkflowMetadataEntries (layer-06
410
+ // metadata-writer). Status discriminator surfaces "scope-not-found"
411
+ // when the scopeId is absent from the overlay.
412
+ const adapterResult = attachScopeMetadata(runtime, {
413
+ scopeId: input.scopeId,
414
+ metadataId: input.metadataId,
415
+ value: input.value,
416
+ });
417
+ emitUxResponse(runtime, {
418
+ apiFn: attachMetadataMetadata.name,
419
+ intent: attachMetadataMetadata.uxIntent.expectedDelta ?? "",
420
+ mockOrLive: "live",
421
+ uiVisible: true,
422
+ expectedDelta: attachMetadataMetadata.uxIntent.expectedDelta,
423
+ actualDelta:
424
+ adapterResult.status === "attached"
425
+ ? { kind: "inline-change", payload: { entryId: adapterResult.entryId } }
426
+ : undefined,
427
+ });
428
+ if (adapterResult.status === "attached") {
429
+ return { status: "attached", entryId: adapterResult.entryId };
430
+ }
431
+ return { status: "scope-not-found" };
432
+ },
433
+ };
434
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Internal — shared UI API instance state.
3
+ *
4
+ * Every family factory (session / surface / viewport / overlays / chrome /
5
+ * debug) closes over one `UiApiContext` so bind/release lifecycle mutations
6
+ * observed in `ui.session` are visible to the rest of the surface. The
7
+ * context itself is NOT exported from the barrel — consumers reach state
8
+ * through the public methods (U8: no internal controllers cross the
9
+ * boundary).
10
+ */
11
+
12
+ import type { MockPayload } from "../_layer-metadata.ts";
13
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
14
+ import type { UiController, ViewportState } from "./_types.ts";
15
+
16
+ export interface BindingState {
17
+ controller: UiController;
18
+ released: boolean;
19
+ }
20
+
21
+ export interface UiApiContext {
22
+ readonly handle: RuntimeApiHandle;
23
+ binding: BindingState | null;
24
+ }
25
+
26
+ export function createUiApiContext(handle: RuntimeApiHandle): UiApiContext {
27
+ return {
28
+ handle,
29
+ binding: null,
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Mock-flagged zeroed ViewportState used by `ui.viewport.get` and
35
+ * `ui.surface.getViewport` when neither `handle.geometry.getViewport()`
36
+ * nor `controller.getViewport()` produces a value (headless / pre-paint).
37
+ * Single definition so both families agree on the fallback shape.
38
+ */
39
+ export const DEFAULT_VIEWPORT: ViewportState & MockPayload = Object.freeze({
40
+ __mock: true,
41
+ reason: "neither handle.geometry nor controller.getViewport hook produced a value; pre-paint / headless default.",
42
+ shape: "ViewportState",
43
+ scrollTop: 0,
44
+ scrollLeft: 0,
45
+ width: 0,
46
+ height: 0,
47
+ zoom: 1,
48
+ devicePixelRatio: 1,
49
+ } as const);
50
+
51
+ /**
52
+ * Shared viewport composition — reads scroll / dpr / zoom from
53
+ * `handle.geometry.getViewport()` and layers controller-provided
54
+ * width / height on top. Used by both `ui.viewport.get` and
55
+ * `ui.surface.getViewport` so the two families agree on one source of
56
+ * truth.
57
+ *
58
+ * Per DS §8.3 (runtime owns truth), we trust `handle.geometry`'s
59
+ * contract — optional chaining handles absent accessors; a thrown
60
+ * `getViewport()` is a real runtime regression and is allowed to
61
+ * propagate. This mirrors the discipline applied to
62
+ * `ui.chrome.getPosture` by Slice 12.
63
+ *
64
+ * NOTE on zoom units: `ViewportState.zoom` is currently the
65
+ * `pxPerTwip` density from the geometry facet (physical pixels per
66
+ * OOXML twip, ~0.0667 at 100% zoom / 96 dpi) — NOT a 1.0-is-100%
67
+ * ratio. No consumer reads this semantically yet; when one does, this
68
+ * field either renames to `pxPerTwip` or divides by a baseline. Flagged
69
+ * as drift in review M1.
70
+ */
71
+ export function readComposedViewport(ctx: UiApiContext): ViewportState {
72
+ const hook = ctx.binding?.controller.getViewport;
73
+ const fromController = hook ? hook() : null;
74
+ const fromGeometry = ctx.handle.geometry?.getViewport?.() ?? null;
75
+
76
+ if (!fromGeometry && !fromController) return DEFAULT_VIEWPORT;
77
+
78
+ return {
79
+ scrollTop: fromGeometry?.scrollTopPx ?? fromController?.scrollTop ?? 0,
80
+ scrollLeft: fromGeometry?.scrollLeftPx ?? fromController?.scrollLeft ?? 0,
81
+ width: fromController?.width ?? 0,
82
+ height: fromController?.height ?? 0,
83
+ zoom: fromGeometry?.pxPerTwip ?? fromController?.zoom ?? 1,
84
+ devicePixelRatio: fromGeometry?.dpr ?? fromController?.devicePixelRatio ?? 1,
85
+ };
86
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @endStateApi v3 — `createUiApi(handle, factory)` entry point.
3
+ *
4
+ * The UI API (layer 10) is the first-class mounted-surface contract —
5
+ * session binding, selection/viewport hooks, geometry-backed overlay
6
+ * primitives, chrome posture composition, debug-service attachment.
7
+ *
8
+ * Slice 2 (current) — session + surface live. Slice 3 wires viewport +
9
+ * overlays through the geometry facet; Slice 4 composes chrome posture;
10
+ * Slice 5 ships the debug attachment + Phase Q UX.
11
+ *
12
+ * This factory is standalone today. Refactor/07 Slice 2 extends
13
+ * `createApiV3` to accept a `UiControllerFactory` and compose the UI
14
+ * namespace into the root API — the staircase in master plan §2 is
15
+ * `/07 Slice 1` (RuntimeApiHandle) → `/10 Slice 1` (reservation) →
16
+ * `/07 Slice 2` (createApiV3 extension).
17
+ */
18
+
19
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
20
+ import type { ApiV3Ui, UiControllerFactory } from "./_types.ts";
21
+ import { createUiApiContext } from "./_context.ts";
22
+ import { createSessionFamily } from "./session.ts";
23
+ import { createSurfaceFamily } from "./surface.ts";
24
+ import { createViewportFamily } from "./viewport.ts";
25
+ import { createOverlaysFamily } from "./overlays.ts";
26
+ import { createChromeFamily } from "./chrome.ts";
27
+ import { createDebugFamily } from "./debug.ts";
28
+ import { createScopeFamily } from "./scope.ts";
29
+
30
+ /**
31
+ * @endStateApi
32
+ * Construct the UI API surface. The optional `factory` runs exactly once
33
+ * to produce the initial controller if the caller wants the binding wired
34
+ * eagerly. Most callers pass no factory and use `api.session.bind(...)`
35
+ * themselves after the handle's runtime reaches a mountable state.
36
+ */
37
+ export function createUiApi(
38
+ handle: RuntimeApiHandle,
39
+ factory?: UiControllerFactory,
40
+ ): ApiV3Ui {
41
+ const ctx = createUiApiContext(handle);
42
+
43
+ if (factory) {
44
+ const controller = factory(handle);
45
+ ctx.binding = { controller, released: false };
46
+ }
47
+
48
+ const api: ApiV3Ui = {
49
+ session: createSessionFamily(ctx),
50
+ surface: createSurfaceFamily(ctx),
51
+ viewport: createViewportFamily(ctx),
52
+ overlays: createOverlaysFamily(ctx),
53
+ chrome: createChromeFamily(ctx),
54
+ debug: createDebugFamily(ctx),
55
+ scope: createScopeFamily(ctx),
56
+ };
57
+ Object.freeze(api.session);
58
+ Object.freeze(api.surface);
59
+ Object.freeze(api.viewport);
60
+ Object.freeze(api.overlays);
61
+ Object.freeze(api.chrome);
62
+ Object.freeze(api.debug);
63
+ Object.freeze(api.scope);
64
+ return Object.freeze(api);
65
+ }