@beyondwork/docx-react-component 1.0.66 → 1.0.69

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 -931
  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 -4795
  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,349 @@
1
+ /**
2
+ * @endStateApi v3 — `runtime.geometry` family.
3
+ *
4
+ * Reads through `runtime.geometry` — the real Layer-05 `GeometryFacet`
5
+ * constructed by `src/runtime/document-runtime.ts`. Prior to the
6
+ * refactor/05 adversarial-closure pass this family adapted geometry
7
+ * through `runtime.layout` (`layout.getAnchorRects({kind:"block-id", ...})`
8
+ * + `layout.hitTest`), which named the layer correctly but kept the
9
+ * real seam in the layout facet. The current wiring reads the facet
10
+ * directly, so `runtime.geometry.*` is actually geometry-native rather
11
+ * than geometry-in-name-only.
12
+ */
13
+
14
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
15
+ import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
16
+ import { mockPayload } from "../_mocks.ts";
17
+ import type { MockPayload } from "../_layer-metadata.ts";
18
+
19
+ export interface BlockRectEntry {
20
+ readonly blockId: string;
21
+ readonly rects: ReadonlyArray<{ x: number; y: number; width: number; height: number; pageIndex?: number }>;
22
+ readonly alignmentKey?: string;
23
+ readonly __mock?: true;
24
+ }
25
+
26
+ export const getBlockRectsMetadata: ApiV3FnMetadata = {
27
+ name: "runtime.geometry.getBlockRects",
28
+ status: "live-with-adapter",
29
+ sourceLayer: "geometry-projection",
30
+ liveEvidence: {
31
+ runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
32
+ commit: "refactor-05-adversarial-closure",
33
+ },
34
+ mockShape: {
35
+ deterministic: true,
36
+ seededFrom: "documentId",
37
+ shapeDescription:
38
+ "BlockRectEntry[] with empty rects and a synthetic alignmentKey — emitted when the GeometryFacet is absent (headless tests, pre-paint). Live path walks `runtime.geometry.getBlockRects(blockId)`, which projects the render kernel's current frame through `getBlockRectsFromFrame`; BlockRectEntry.rects is populated per page the block spans with a stable alignmentKey.",
39
+ carriesMockFlag: true,
40
+ },
41
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
42
+ agentMetadata: { readOrMutate: "read", boundedScope: "scope", auditCategory: "geometry-read" },
43
+ stateClass: "A-canonical",
44
+ persistsTo: "canonical",
45
+ rwdReference:
46
+ "§Runtime API § runtime.geometry.getBlockRects. Adapter wraps `GeometryFacet.getBlockRects(blockId)` into BlockRectEntry.rects[]. Promotes to `live` when the v3 shape carries per-page indices (render-kernel per-run anchors slice adds pageIndex to GeometryRect).",
47
+ };
48
+
49
+ export interface HitTestInput {
50
+ readonly x: number;
51
+ readonly y: number;
52
+ readonly pageIndex?: number;
53
+ }
54
+
55
+ export interface HitTestResult {
56
+ readonly blockId?: string;
57
+ readonly __mock?: true;
58
+ }
59
+
60
+ /* ================================================================== */
61
+ /* getCaret — Slice-4 caret geometry (Slice X3 of §4 of coord-05) */
62
+ /* ================================================================== */
63
+
64
+ /**
65
+ * v3 projection of `CaretGeometry` from `src/runtime/geometry/geometry-types.ts`.
66
+ * Carries the caret rect + baseline + height + writing direction, rebased
67
+ * into the v3 `{x, y, width, height}` surface convention (no `space`
68
+ * discriminator — Layer-05 caret reads always return `space: "frame"`).
69
+ */
70
+ export interface V3CaretGeometry {
71
+ readonly rect: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };
72
+ readonly baseline: number;
73
+ readonly height: number;
74
+ readonly direction: "ltr" | "rtl";
75
+ }
76
+
77
+ export const getCaretMetadata: ApiV3FnMetadata = {
78
+ name: "runtime.geometry.getCaret",
79
+ status: "live-with-adapter",
80
+ sourceLayer: "geometry-projection",
81
+ liveEvidence: {
82
+ runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
83
+ commit: "refactor-07-coord-05-geometry-promotions",
84
+ },
85
+ mockShape: {
86
+ deterministic: true,
87
+ seededFrom: "fixed",
88
+ shapeDescription:
89
+ "null when the GeometryFacet is absent (headless pre-paint) or the offset does not resolve. Live path walks `runtime.geometry.getCaret(offset, story)` which composes per-line box + baseline metrics into a CaretGeometry projection.",
90
+ carriesMockFlag: true,
91
+ },
92
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
93
+ agentMetadata: { readOrMutate: "read", boundedScope: "selection", auditCategory: "geometry-read" },
94
+ stateClass: "A-canonical",
95
+ persistsTo: "canonical",
96
+ rwdReference:
97
+ "§Runtime API § runtime.geometry.getCaret. Adapter wraps GeometryFacet.getCaret(offset, story) → V3CaretGeometry. Substrate caveat (coord-05 §1): single-union-rect for bidi-mixed runs; per-run splitting lands in a later L05 slice.",
98
+ };
99
+
100
+ /* ================================================================== */
101
+ /* getSelectionRects */
102
+ /* ================================================================== */
103
+
104
+ export interface SelectionRectsInput {
105
+ readonly from: number;
106
+ readonly to: number;
107
+ readonly story?: import("../../public-types.ts").EditorStoryTarget;
108
+ }
109
+
110
+ export type V3GeometryRect = { readonly x: number; readonly y: number; readonly width: number; readonly height: number };
111
+
112
+ export const getSelectionRectsMetadata: ApiV3FnMetadata = {
113
+ name: "runtime.geometry.getSelectionRects",
114
+ status: "live-with-adapter",
115
+ sourceLayer: "geometry-projection",
116
+ liveEvidence: {
117
+ runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
118
+ commit: "refactor-07-coord-05-geometry-promotions",
119
+ },
120
+ mockShape: {
121
+ deterministic: true,
122
+ seededFrom: "fixed",
123
+ shapeDescription:
124
+ "Empty array when the GeometryFacet is absent or the range doesn't resolve. Live path walks `runtime.geometry.getSelectionRects({from, to, story})` and returns a per-line rect sequence.",
125
+ carriesMockFlag: true,
126
+ },
127
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
128
+ agentMetadata: { readOrMutate: "read", boundedScope: "selection", auditCategory: "geometry-read" },
129
+ stateClass: "A-canonical",
130
+ persistsTo: "canonical",
131
+ rwdReference:
132
+ "§Runtime API § runtime.geometry.getSelectionRects. Adapter wraps GeometryFacet.getSelectionRects({from, to, story}) → V3GeometryRect[]. Substrate caveat (coord-05 §1): single-union-rect for non-collapsed ranges until per-run anchors land.",
133
+ };
134
+
135
+ /* ================================================================== */
136
+ /* getReplacementEnvelope */
137
+ /* ================================================================== */
138
+
139
+ export interface V3EnvelopeBundle {
140
+ readonly scopeRects: readonly V3GeometryRect[];
141
+ readonly attachPoint: { readonly x: number; readonly y: number };
142
+ readonly confidence: "exact" | "medium" | "detached";
143
+ readonly linesCrossed: number;
144
+ }
145
+
146
+ export const getReplacementEnvelopeMetadata: ApiV3FnMetadata = {
147
+ name: "runtime.geometry.getReplacementEnvelope",
148
+ status: "live-with-adapter",
149
+ sourceLayer: "geometry-projection",
150
+ liveEvidence: {
151
+ runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
152
+ commit: "refactor-07-coord-05-geometry-promotions",
153
+ },
154
+ mockShape: {
155
+ deterministic: true,
156
+ seededFrom: "fixed",
157
+ shapeDescription:
158
+ "null when the GeometryFacet is absent or the scopeId doesn't resolve. Live path walks `runtime.geometry.getReplacementEnvelope(scopeId)` returning EnvelopeBundle with scopeRects + attachPoint + confidence.",
159
+ carriesMockFlag: true,
160
+ },
161
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
162
+ agentMetadata: { readOrMutate: "read", boundedScope: "scope", auditCategory: "geometry-read" },
163
+ stateClass: "A-canonical",
164
+ persistsTo: "canonical",
165
+ rwdReference:
166
+ "§Runtime API § runtime.geometry.getReplacementEnvelope. Adapter wraps GeometryFacet.getReplacementEnvelope(scopeId) → V3EnvelopeBundle. Substrate shipped fully — scopeRects is one union rect under today's per-range kernel.",
167
+ };
168
+
169
+ /* ================================================================== */
170
+ /* getObjectHandles */
171
+ /* ================================================================== */
172
+
173
+ export const getObjectHandlesMetadata: ApiV3FnMetadata = {
174
+ name: "runtime.geometry.getObjectHandles",
175
+ status: "live-with-adapter",
176
+ sourceLayer: "geometry-projection",
177
+ liveEvidence: {
178
+ runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
179
+ commit: "refactor-07-coord-05-geometry-promotions",
180
+ },
181
+ mockShape: {
182
+ deterministic: true,
183
+ seededFrom: "fixed",
184
+ shapeDescription:
185
+ "Empty array when the GeometryFacet is absent or the objectId doesn't resolve. Live path walks `runtime.geometry.getObjectHandles(objectId)` returning handle rects.",
186
+ carriesMockFlag: true,
187
+ },
188
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
189
+ agentMetadata: { readOrMutate: "read", boundedScope: "scope", auditCategory: "geometry-read" },
190
+ stateClass: "A-canonical",
191
+ persistsTo: "canonical",
192
+ rwdReference:
193
+ "§Runtime API § runtime.geometry.getObjectHandles. Adapter wraps GeometryFacet.getObjectHandles(objectId) → V3GeometryRect[]. Substrate caveat (coord-05 §1): addresses objects by blockId until the object-specific anchor index ships in a later L05 slice.",
194
+ };
195
+
196
+ export const hitTestMetadata: ApiV3FnMetadata = {
197
+ name: "runtime.geometry.hitTest",
198
+ status: "live-with-adapter",
199
+ sourceLayer: "geometry-projection",
200
+ liveEvidence: {
201
+ runnerTest: "test/api/v3/geometry-uses-geometry-handle.test.ts",
202
+ commit: "refactor-05-adversarial-closure",
203
+ },
204
+ mockShape: {
205
+ deterministic: true,
206
+ seededFrom: "fixed",
207
+ shapeDescription: "Empty HitTestResult when the GeometryFacet is unwired or the render kernel has not produced a frame (headless tests, pre-paint).",
208
+ carriesMockFlag: true,
209
+ },
210
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
211
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "hit-test" },
212
+ stateClass: "A-canonical",
213
+ persistsTo: "canonical",
214
+ rwdReference:
215
+ "§Runtime API § runtime.geometry.hitTest. Adapter wraps `GeometryFacet.hitTest({xPx,yPx,space:'frame'})` into the v3 HitTestResult shape. Promotes to `live` when the v3 shape matches HitTestResult 1:1.",
216
+ };
217
+
218
+ export function createGeometryFamily(runtime: RuntimeApiHandle) {
219
+ // Layer 05 seam. v3's geometry family reads through the real geometry
220
+ // facet — not through `runtime.layout`. When `runtime.geometry` is
221
+ // absent (headless harness shims, pre-paint, unwired kernel) each
222
+ // function falls back to the mock shape so consumers keep a stable
223
+ // contract.
224
+ const geometry = runtime.geometry;
225
+
226
+ return {
227
+ getBlockRects(blockIds: readonly string[]): ReadonlyArray<BlockRectEntry & Partial<MockPayload>> {
228
+ // @endStateApi — live-with-adapter. Routes directly through the
229
+ // Layer-05 GeometryFacet's `getBlockRects(blockId)`, which walks
230
+ // the render-kernel frame (`getBlockRectsFromFrame`). When the
231
+ // facet is absent (no runtime.geometry) or the kernel has not
232
+ // produced a frame, each entry falls back to the mock shape with
233
+ // the stable alignmentKey so consumers can still seed rwd seam-4
234
+ // comparisons.
235
+ const out: Array<BlockRectEntry & Partial<MockPayload>> = [];
236
+ for (const blockId of blockIds) {
237
+ const alignmentKey = `block::${blockId}`;
238
+ if (!geometry) {
239
+ out.push(
240
+ mockPayload(
241
+ "runtime.geometry unavailable; geometry-facet getBlockRects falls back to synthetic alignmentKey",
242
+ "BlockRectEntry",
243
+ { blockId, rects: [], alignmentKey },
244
+ ),
245
+ );
246
+ continue;
247
+ }
248
+ const raw = geometry.getBlockRects(blockId);
249
+ if (raw.length === 0) {
250
+ // No rects from the facet — the kernel has no frame yet, or
251
+ // the block is not in the current projection. Emit the mock
252
+ // shape so downstream consumers can still key on alignmentKey.
253
+ out.push(
254
+ mockPayload(
255
+ "geometry-facet returned no rects for blockId (pre-paint or unknown block)",
256
+ "BlockRectEntry",
257
+ { blockId, rects: [], alignmentKey },
258
+ ),
259
+ );
260
+ continue;
261
+ }
262
+ const rects = raw.map((r) => ({
263
+ x: r.leftPx,
264
+ y: r.topPx,
265
+ width: r.widthPx,
266
+ height: r.heightPx,
267
+ }));
268
+ out.push({ blockId, rects, alignmentKey });
269
+ }
270
+ return out;
271
+ },
272
+
273
+ getCaret(offset: number, story?: import("../../public-types.ts").EditorStoryTarget): V3CaretGeometry | null {
274
+ // @endStateApi — live-with-adapter. Reads through the GeometryFacet.
275
+ // Rebases the {leftPx,topPx,widthPx,heightPx,space} shape into the
276
+ // v3 `{x,y,width,height}` convention (drops the `space` field —
277
+ // Layer-05 caret reads always resolve to `space: "frame"`).
278
+ if (!geometry) return null;
279
+ const raw = geometry.getCaret(offset, story);
280
+ if (!raw) return null;
281
+ return {
282
+ rect: { x: raw.rect.leftPx, y: raw.rect.topPx, width: raw.rect.widthPx, height: raw.rect.heightPx },
283
+ baseline: raw.baseline,
284
+ height: raw.height,
285
+ direction: raw.direction,
286
+ };
287
+ },
288
+
289
+ getSelectionRects(input: SelectionRectsInput): readonly V3GeometryRect[] {
290
+ // @endStateApi — live-with-adapter. Reads through GeometryFacet.
291
+ // Returns an empty array when the facet is absent or the range
292
+ // does not resolve; callers can distinguish no-resolution from
293
+ // collapsed-range by checking `from === to`.
294
+ if (!geometry) return [];
295
+ const rects = geometry.getSelectionRects({ from: input.from, to: input.to, story: input.story });
296
+ return rects.map((r) => ({ x: r.leftPx, y: r.topPx, width: r.widthPx, height: r.heightPx }));
297
+ },
298
+
299
+ getReplacementEnvelope(scopeId: string): V3EnvelopeBundle | null {
300
+ // @endStateApi — live-with-adapter. Reads through GeometryFacet.
301
+ // Rebases scopeRects into the v3 {x,y,width,height} convention;
302
+ // attachPoint drops `space` since Layer-05 produces frame-space
303
+ // coordinates.
304
+ if (!geometry) return null;
305
+ const raw = geometry.getReplacementEnvelope(scopeId);
306
+ if (!raw) return null;
307
+ return {
308
+ scopeRects: raw.scopeRects.map((r) => ({ x: r.leftPx, y: r.topPx, width: r.widthPx, height: r.heightPx })),
309
+ attachPoint: { x: raw.attachPoint.xPx, y: raw.attachPoint.yPx },
310
+ confidence: raw.confidence,
311
+ linesCrossed: raw.linesCrossed,
312
+ };
313
+ },
314
+
315
+ getObjectHandles(objectId: string): readonly V3GeometryRect[] {
316
+ // @endStateApi — live-with-adapter. Reads through GeometryFacet.
317
+ // Substrate addresses objects by blockId via
318
+ // frame.anchorIndex.byBlockId — see metadata.rwdReference for the
319
+ // caveat.
320
+ if (!geometry) return [];
321
+ const rects = geometry.getObjectHandles(objectId);
322
+ return rects.map((r) => ({ x: r.leftPx, y: r.topPx, width: r.widthPx, height: r.heightPx }));
323
+ },
324
+
325
+ hitTest(input: HitTestInput): HitTestResult & Partial<MockPayload> {
326
+ // @endStateApi — live-with-adapter. Reads through the GeometryFacet
327
+ // so the v3 seam matches the runtime seam. The facet routes the
328
+ // point through `resolveHitTest` against the render kernel's
329
+ // current frame (Slice 2a); `space: "frame"` is the only coordinate
330
+ // space the kernel emits today (G5).
331
+ if (!geometry) {
332
+ return mockPayload(
333
+ "runtime.geometry unavailable",
334
+ "HitTestResult",
335
+ {} as { blockId?: string },
336
+ );
337
+ }
338
+ const result = geometry.hitTest({ xPx: input.x, yPx: input.y, space: "frame" });
339
+ if (!result) {
340
+ return mockPayload(
341
+ "geometry-facet hitTest returned null (out-of-frame point or no frame)",
342
+ "HitTestResult",
343
+ {} as { blockId?: string },
344
+ );
345
+ }
346
+ return { blockId: result.blockId };
347
+ },
348
+ };
349
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @endStateApi v3 — `runtime.layout` family.
3
+ *
4
+ * getPage (live-with-adapter) / getPageSpan (live-with-adapter) /
5
+ * getBlockLayout (live-with-adapter). Adapter delegation to the existing
6
+ * layout facet (`runtime.layout`).
7
+ */
8
+
9
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
10
+ import type { ApiV3FnMetadata, MockPayload } from "../_layer-metadata.ts";
11
+ import { mockPayload } from "../_mocks.ts";
12
+
13
+ export const getPageMetadata: ApiV3FnMetadata = {
14
+ name: "runtime.layout.getPage",
15
+ status: "live-with-adapter",
16
+ sourceLayer: "layout-semantics",
17
+ liveEvidence: {
18
+ runnerTest: "test/api/v3/live-parity.test.ts",
19
+ commit: "phase-p-prime",
20
+ },
21
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
22
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "layout-read" },
23
+ stateClass: "A-canonical",
24
+ persistsTo: "canonical",
25
+ rwdReference:
26
+ "§Runtime API § runtime.layout.getPage. Adapter wraps facet.getPage(pageIndex) to expose the v3-shaped PageNode; promotes to `live` when the v3 shape matches PublicPageNode 1:1.",
27
+ };
28
+
29
+ export const getPageSpanMetadata: ApiV3FnMetadata = {
30
+ name: "runtime.layout.getPageSpan",
31
+ status: "live-with-adapter",
32
+ sourceLayer: "layout-semantics",
33
+ liveEvidence: {
34
+ runnerTest: "test/api/v3/live-parity.test.ts",
35
+ commit: "phase-p-prime",
36
+ },
37
+ mockShape: {
38
+ deterministic: true,
39
+ seededFrom: "fixed",
40
+ shapeDescription: "Fallback PageSpan when the block has no measurement entry (pre-layout or unknown blockId); pageIndex=null, __mock:true.",
41
+ carriesMockFlag: true,
42
+ },
43
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
44
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "layout-read" },
45
+ stateClass: "A-canonical",
46
+ persistsTo: "canonical",
47
+ rwdReference:
48
+ "§Runtime API § runtime.layout.getPageSpan. Adapter composes facet.getMeasurement(blockId) into a {blockId, pageIndex} shape; promotes to `live` when the facet exposes getPageSpanForBlock directly.",
49
+ };
50
+
51
+ export const getBlockLayoutMetadata: ApiV3FnMetadata = {
52
+ name: "runtime.layout.getBlockLayout",
53
+ status: "live-with-adapter",
54
+ sourceLayer: "layout-semantics",
55
+ liveEvidence: {
56
+ runnerTest: "test/api/v3/live-parity.test.ts",
57
+ commit: "phase-p-prime",
58
+ },
59
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
60
+ agentMetadata: { readOrMutate: "read", boundedScope: "scope", auditCategory: "layout-read" },
61
+ stateClass: "A-canonical",
62
+ persistsTo: "canonical",
63
+ rwdReference:
64
+ "§Runtime API § runtime.layout.getBlockLayout. Adapter wraps facet.getMeasurement(blockId) → PublicBlockMeasurement; promotes to `live` when the v3 shape matches 1:1.",
65
+ };
66
+
67
+ export function createLayoutFamily(runtime: RuntimeApiHandle) {
68
+ // Public-facet shape — see src/runtime/layout/public-facet.ts:376+.
69
+ const layout = runtime.layout;
70
+
71
+ return {
72
+ getPage(pageIndex: number) {
73
+ // @endStateApi — live-with-adapter. Wraps the facet's
74
+ // getPage(pageIndex); promotes to `live` when the v3 shape matches
75
+ // PublicPageNode 1:1.
76
+ return layout?.getPage(pageIndex) ?? null;
77
+ },
78
+
79
+ getPageSpan(blockId: string): unknown | (unknown & MockPayload) {
80
+ // @endStateApi — live-with-adapter. The facet exposes no direct
81
+ // "span for block" read. Adapter composes getMeasurement(blockId)
82
+ // into {blockId, pageIndex}; returns a mock-flagged fallback when
83
+ // the measurement provider has not observed the block.
84
+ const measurement = layout?.getMeasurement(blockId) as
85
+ | { pageIndex?: number }
86
+ | null
87
+ | undefined;
88
+ if (!measurement) {
89
+ return mockPayload(
90
+ "layout facet has no getPageSpanForBlock; Phase 2 formalization needed",
91
+ "PageSpan",
92
+ { blockId, pageIndex: null as number | null },
93
+ );
94
+ }
95
+ return {
96
+ blockId,
97
+ pageIndex: measurement.pageIndex ?? null,
98
+ };
99
+ },
100
+
101
+ getBlockLayout(blockId: string) {
102
+ // @endStateApi — live-with-adapter. Wraps
103
+ // layout.getMeasurement(blockId) → PublicBlockMeasurement; promotes
104
+ // to `live` when the v3 shape matches 1:1.
105
+ return layout?.getMeasurement(blockId) ?? null;
106
+ },
107
+ };
108
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @endStateApi v3 — `runtime.review` family.
3
+ *
4
+ * getComments (live) / getChanges (live) / acceptChange (live) /
5
+ * resolveComment (live).
6
+ */
7
+
8
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
9
+ import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
10
+ import type {
11
+ CommentSidebarThreadSnapshot,
12
+ TrackedChangeEntrySnapshot,
13
+ } from "../../public-types.ts";
14
+ import { emitUxResponse } from "../_ux-response.ts";
15
+
16
+ export const getCommentsMetadata: ApiV3FnMetadata = {
17
+ name: "runtime.review.getComments",
18
+ status: "live",
19
+ sourceLayer: "workflow-review",
20
+ // Concrete, reviewable proof: L06 Slice-4F graduated this function to
21
+ // `live` by routing through `runtime.getRenderSnapshot().comments.threads`.
22
+ // The `review-full-snapshot` test covers F09 (non-empty comments) + F11
23
+ // (non-empty revisions) + the F01 empty-case negative test; L07 closure
24
+ // pass added behavioral-coverage + mutation-behavioral assertions.
25
+ // Reviewers can open the cited files to see the asserts.
26
+ liveEvidence: {
27
+ runnerTest:
28
+ "test/api/v3/review-full-snapshot.test.ts,test/api/v3/live-parity.test.ts,test/api/v3/behavioral-coverage.test.ts,test/api/v3/review-mutation-behavioral.test.ts",
29
+ commit: "refactor-06-slice-4f-2026-04-22",
30
+ },
31
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
32
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "review-read" },
33
+ stateClass: "A-canonical",
34
+ persistsTo: "canonical",
35
+ rwdReference: "§Runtime API § runtime.review.getComments",
36
+ };
37
+
38
+ export const getChangesMetadata: ApiV3FnMetadata = {
39
+ name: "runtime.review.getChanges",
40
+ status: "live",
41
+ sourceLayer: "workflow-review",
42
+ liveEvidence: {
43
+ runnerTest:
44
+ "test/api/v3/review-full-snapshot.test.ts,test/api/v3/live-parity.test.ts,test/api/v3/behavioral-coverage.test.ts,test/api/v3/review-mutation-behavioral.test.ts",
45
+ commit: "refactor-06-slice-4f-2026-04-22",
46
+ },
47
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
48
+ agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "review-read" },
49
+ stateClass: "A-canonical",
50
+ persistsTo: "canonical",
51
+ rwdReference: "§Runtime API § runtime.review.getChanges",
52
+ };
53
+
54
+ export const acceptChangeMetadata: ApiV3FnMetadata = {
55
+ name: "runtime.review.acceptChange",
56
+ status: "live",
57
+ sourceLayer: "workflow-review",
58
+ liveEvidence: {
59
+ // Direct mutation + UxResponse proof. The behavioral test asserts
60
+ // before/after snapshot parity via getReviewWorkSnapshot + one
61
+ // ux.response event emission per call (R4).
62
+ runnerTest: "test/api/v3/review-mutation-behavioral.test.ts",
63
+ commit: "refactor-07-adversarial-closure-2026-04-22",
64
+ },
65
+ uxIntent: { uiVisible: true, expectsUxResponse: "inline-change", expectedDelta: "change mark disappears and text merges" },
66
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "scope", auditCategory: "change-accept" },
67
+ stateClass: "A-canonical",
68
+ persistsTo: "canonical",
69
+ broadcastsVia: "crdt",
70
+ rwdReference: "§Runtime API § runtime.review.acceptChange",
71
+ };
72
+
73
+ export const resolveCommentMetadata: ApiV3FnMetadata = {
74
+ name: "runtime.review.resolveComment",
75
+ status: "live",
76
+ sourceLayer: "workflow-review",
77
+ liveEvidence: {
78
+ runnerTest: "test/api/v3/review-mutation-behavioral.test.ts",
79
+ commit: "refactor-07-adversarial-closure-2026-04-22",
80
+ },
81
+ uxIntent: { uiVisible: true, expectsUxResponse: "inline-change", expectedDelta: "comment thread collapses to resolved" },
82
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "scope", auditCategory: "comment-resolve" },
83
+ stateClass: "A-canonical",
84
+ persistsTo: "canonical",
85
+ broadcastsVia: "crdt",
86
+ rwdReference: "§Runtime API § runtime.review.resolveComment",
87
+ };
88
+
89
+ export function createReviewFamily(runtime: RuntimeApiHandle) {
90
+ return {
91
+ getComments(): readonly CommentSidebarThreadSnapshot[] {
92
+ // @endStateApi — live. Reads the full comment sidebar snapshot from
93
+ // the canonical render surface. Layer-06 Slice 3 graduation.
94
+ return runtime.getRenderSnapshot().comments.threads;
95
+ },
96
+
97
+ getChanges(): readonly TrackedChangeEntrySnapshot[] {
98
+ // @endStateApi — live. Reads the full tracked-changes revision list
99
+ // from the canonical render surface. Layer-06 Slice 3 graduation.
100
+ return runtime.getRenderSnapshot().trackedChanges.revisions;
101
+ },
102
+
103
+ acceptChange(changeId: string): void {
104
+ // @endStateApi — live. Delegates.
105
+ runtime.acceptChange(changeId);
106
+ emitUxResponse(runtime, {
107
+ apiFn: acceptChangeMetadata.name,
108
+ intent: acceptChangeMetadata.uxIntent.expectedDelta ?? "",
109
+ mockOrLive: "live",
110
+ uiVisible: true,
111
+ expectedDelta: acceptChangeMetadata.uxIntent.expectedDelta,
112
+ actualDelta: { kind: "inline-change", payload: { changeId } },
113
+ });
114
+ },
115
+
116
+ resolveComment(commentId: string): void {
117
+ // @endStateApi — live.
118
+ runtime.resolveComment(commentId);
119
+ emitUxResponse(runtime, {
120
+ apiFn: resolveCommentMetadata.name,
121
+ intent: resolveCommentMetadata.uxIntent.expectedDelta ?? "",
122
+ mockOrLive: "live",
123
+ uiVisible: true,
124
+ expectedDelta: resolveCommentMetadata.uxIntent.expectedDelta,
125
+ actualDelta: { kind: "inline-change", payload: { commentId } },
126
+ });
127
+ },
128
+ };
129
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @endStateApi v3 — `runtime.search` family.
3
+ *
4
+ * Single function: `searchDocument(...)`. Thin pass-through over the
5
+ * shipped compound search path `src/runtime/document-search.ts`.
6
+ *
7
+ * Distinct from `runtime.content.search(input)` — the content-family
8
+ * seam is a simple query + optional limit over `findAllText` returning
9
+ * `EditorAnchorProjection[]`. This family exposes the richer compound
10
+ * path: it takes the canonical document + selection + active story +
11
+ * navigation snapshot + options, and returns per-match excerpts with
12
+ * page/section metadata. Same inputs the PM surface
13
+ * (`tw-prosemirror-surface.tsx`) already holds — exposing it through v3
14
+ * lets L11 flip its `src/runtime/document-search.ts` import to the v3
15
+ * seam (coord-11 §4.3).
16
+ *
17
+ * Pure-function read — `stateClass: "C-local"` + `persistsTo: "none"`.
18
+ * No UxResponse emission.
19
+ */
20
+
21
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
22
+ import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
23
+ import type {
24
+ CanonicalDocumentEnvelope,
25
+ DocumentNavigationSnapshot,
26
+ EditorStoryTarget,
27
+ SearchOptions,
28
+ SearchResultSnapshot,
29
+ SelectionSnapshot,
30
+ } from "../../public-types.ts";
31
+ import { searchDocument as searchDocumentImpl } from "../../../runtime/document-search.ts";
32
+
33
+ export const searchDocumentMetadata: ApiV3FnMetadata = {
34
+ name: "runtime.search.searchDocument",
35
+ status: "live",
36
+ sourceLayer: "runtime-core",
37
+ liveEvidence: {
38
+ runnerTest: "test/api/v3/live-parity.test.ts",
39
+ commit: "refactor-07-search-family-2026-04-23",
40
+ },
41
+ uxIntent: { uiVisible: false, expectsUxResponse: "none" },
42
+ agentMetadata: {
43
+ readOrMutate: "read",
44
+ boundedScope: "document",
45
+ auditCategory: "search",
46
+ },
47
+ stateClass: "C-local",
48
+ persistsTo: "none",
49
+ rwdReference:
50
+ "§Runtime API § runtime.search.searchDocument. Direct delegation to searchDocument (src/runtime/document-search.ts). Compound search over canonical doc + selection + activeStory + navigation + query + options. Returns SearchResultSnapshot[] with per-match excerpts + page/section metadata. Complements the simpler runtime.content.search.",
51
+ };
52
+
53
+ export function createSearchFamily(_runtime: RuntimeApiHandle) {
54
+ return {
55
+ searchDocument(
56
+ document: CanonicalDocumentEnvelope,
57
+ selection: SelectionSnapshot,
58
+ activeStory: EditorStoryTarget,
59
+ navigation: DocumentNavigationSnapshot,
60
+ query: string,
61
+ options?: SearchOptions,
62
+ ): SearchResultSnapshot[] {
63
+ // @endStateApi — live.
64
+ return searchDocumentImpl(
65
+ document,
66
+ selection,
67
+ activeStory,
68
+ navigation,
69
+ query,
70
+ options,
71
+ );
72
+ },
73
+ };
74
+ }