@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,208 @@
1
+ /**
2
+ * Slice 3 — single source of truth for "what canonical range does this
3
+ * scope cover?" + "how specific is this kind for tie-breaking?".
4
+ *
5
+ * Used by three sites:
6
+ * - `resolve-reference.ts` — offset / range hints need each scope's
7
+ * live range to pick the innermost containing match.
8
+ * - `evidence.ts` — scope-bundle evidence composer needs the self-range
9
+ * to compute review + workflow overlap.
10
+ * - `review-bundle.ts` — per-scope review summary needs the same range.
11
+ *
12
+ * Keeping these three sites on one helper prevents the behavioural drift
13
+ * the independent code-review flagged at Slice 3 close. Adversarial-
14
+ * closure pass 2026-04-22: widened to precise inline ranges for fields +
15
+ * proportional sub-ranges for table rows/cells, plus a kind-specificity
16
+ * ordering so `innermostContaining` picks the deepest scope when ranges
17
+ * tie or nest.
18
+ */
19
+
20
+ import type {
21
+ CanonicalAnchor,
22
+ CanonicalDocument,
23
+ } from "../../model/canonical-document.ts";
24
+ import type { CanonicalDocumentEnvelope } from "../../core/state/editor-state.ts";
25
+
26
+ import type { EnumeratedScope } from "./enumerate-scopes.ts";
27
+ import {
28
+ buildScopePositionMap,
29
+ computeTableCellRange,
30
+ computeTableRowRange,
31
+ type ScopePositionMap,
32
+ type ScopePositionRange,
33
+ } from "./position-map.ts";
34
+ import type {
35
+ ScopeHandle,
36
+ SemanticScopeKind,
37
+ } from "./semantic-scope-types.ts";
38
+
39
+ function anchorToRange(anchor: CanonicalAnchor): ScopePositionRange | null {
40
+ switch (anchor.kind) {
41
+ case "range":
42
+ return { from: anchor.range.from, to: anchor.range.to };
43
+ case "node":
44
+ return { from: anchor.at, to: anchor.at };
45
+ case "detached":
46
+ return anchor.lastKnownRange;
47
+ default:
48
+ return null;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Kind-level specificity ranking. Higher = more specific (deeper / more
54
+ * narrowly-scoped). Used as a tie-breaker when multiple scopes contain the
55
+ * same offset or share identical canonical ranges (fields inside a
56
+ * paragraph, cells inside a row inside a table). Marker-backed scopes
57
+ * still win regardless of rank — the rank only matters among derived
58
+ * scopes whose canonical range is a coarser block-level projection of the
59
+ * structural truth.
60
+ *
61
+ * Values chosen so that:
62
+ * - paragraph-like kinds (paragraph / heading / list-item / clause)
63
+ * outrank the documentwide / composite scopes
64
+ * - table < table-row < table-cell (nested containment)
65
+ * - field outranks the enclosing paragraph (an inline hit should snap
66
+ * to the field, not the paragraph that contains it)
67
+ * - comment-thread / revision carry an anchor-based range and win over
68
+ * the enclosing paragraph when the caller asked for a review-scoped
69
+ * resolution
70
+ */
71
+ export function scopeSpecificity(kind: SemanticScopeKind): number {
72
+ switch (kind) {
73
+ case "composite":
74
+ return 0;
75
+ case "scope":
76
+ return 1;
77
+ case "paragraph":
78
+ case "heading":
79
+ case "list-item":
80
+ return 2;
81
+ case "table":
82
+ return 3;
83
+ case "table-row":
84
+ return 4;
85
+ case "table-cell":
86
+ return 5;
87
+ case "image":
88
+ case "note":
89
+ return 6;
90
+ case "field":
91
+ return 7;
92
+ case "comment-thread":
93
+ case "revision":
94
+ return 8;
95
+ default: {
96
+ const _never: never = kind;
97
+ void _never;
98
+ return 0;
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Resolve the canonical `{from,to}` range for any `EnumeratedScope` variant.
105
+ *
106
+ * Precision tiers:
107
+ * - paragraph / heading / list-item / clause : block range
108
+ * - table : block range (1-slot)
109
+ * - table-row : proportional sub-range
110
+ * of the table's 1-slot
111
+ * canonical range
112
+ * - table-cell : proportional sub-range
113
+ * of the row's sub-range
114
+ * - field : inline slot range
115
+ * `inlines[${blockIndex}:${inlineIndex}]`
116
+ * - comment-thread / revision : review-store anchor range
117
+ *
118
+ * Marker-backed scope handles always take precedence — the marker pair's
119
+ * precise range wins over the derived block/inline range so offset /
120
+ * overlap math stays tight on the shipped marker contract.
121
+ */
122
+ export function resolveScopeRange(
123
+ entry: EnumeratedScope,
124
+ handle: ScopeHandle,
125
+ positionMap: ScopePositionMap,
126
+ ): ScopePositionRange | null {
127
+ // Marker-backed scopes get their precise range from `scope-resolver`.
128
+ if (handle.stableRef.kind === "scope-id") {
129
+ const marker = positionMap.markerScopes.get(handle.stableRef.value);
130
+ if (marker) return marker;
131
+ }
132
+ switch (entry.kind) {
133
+ case "paragraph":
134
+ case "heading":
135
+ case "list-item":
136
+ return positionMap.blocks.get(entry.blockIndex) ?? null;
137
+ case "table":
138
+ return positionMap.blocks.get(entry.blockIndex) ?? null;
139
+ case "table-row": {
140
+ const tableRange = positionMap.blocks.get(entry.blockIndex);
141
+ if (!tableRange) return null;
142
+ return computeTableRowRange(entry.table, entry.rowIndex, tableRange);
143
+ }
144
+ case "table-cell": {
145
+ const tableRange = positionMap.blocks.get(entry.blockIndex);
146
+ if (!tableRange) return null;
147
+ const rowRange = computeTableRowRange(
148
+ entry.table,
149
+ entry.rowIndex,
150
+ tableRange,
151
+ );
152
+ return computeTableCellRange(entry.row, entry.cellIndex, rowRange);
153
+ }
154
+ case "field": {
155
+ const key = `${entry.blockIndex}:${entry.inlineIndex}`;
156
+ const inlineRange = positionMap.inlines.get(key);
157
+ if (inlineRange) return inlineRange;
158
+ // Fallback: the paragraph's block range. A field without a
159
+ // corresponding inline entry is a position-map bug, but returning
160
+ // null would drop the field from overlap/resolve entirely. Fall
161
+ // back rather than regress.
162
+ return positionMap.blocks.get(entry.blockIndex) ?? null;
163
+ }
164
+ case "comment-thread":
165
+ return anchorToRange(entry.thread.anchor);
166
+ case "revision":
167
+ return anchorToRange(entry.revision.anchor);
168
+ default: {
169
+ const never: never = entry;
170
+ void never;
171
+ return null;
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Inclusive-inclusive range overlap. Canonical positions treat marker pairs
178
+ * as closed intervals, so `[aFrom, aTo]` and `[bFrom, bTo]` overlap when
179
+ * `aHigh >= bLow && aLow <= bHigh`. The position-map computes block ranges
180
+ * with a `+1` gap between blocks (per `scope-resolver`), so adjacent
181
+ * block-range overlap is not an off-by-one hazard.
182
+ *
183
+ * Fractional ranges (table-row / table-cell synthesized subranges) are
184
+ * safe to compare with the same rule — the partition contract of
185
+ * `computeTableRowRange` / `computeTableCellRange` guarantees no two
186
+ * subranges share any interior point.
187
+ */
188
+ export function rangesOverlap(
189
+ a: ScopePositionRange,
190
+ b: ScopePositionRange,
191
+ ): boolean {
192
+ const aLow = Math.min(a.from, a.to);
193
+ const aHigh = Math.max(a.from, a.to);
194
+ const bLow = Math.min(b.from, b.to);
195
+ const bHigh = Math.max(b.from, b.to);
196
+ return aHigh >= bLow && aLow <= bHigh;
197
+ }
198
+
199
+ /**
200
+ * Convenience — build a position map once and resolve the scope's range.
201
+ */
202
+ export function resolveScopeRangeFromDoc(
203
+ entry: EnumeratedScope,
204
+ document: Pick<CanonicalDocument, "content"> | CanonicalDocumentEnvelope,
205
+ ): ScopePositionRange | null {
206
+ const positionMap = buildScopePositionMap(document);
207
+ return resolveScopeRange(entry, entry.handle, positionMap);
208
+ }
@@ -0,0 +1,454 @@
1
+ /**
2
+ * Layer 08 — Semantic Scope Compiler · public types.
3
+ *
4
+ * Target: `docs/architecture/08-semantic-scope-compiler.md` §"Core types".
5
+ *
6
+ * All shapes here are plain, structurally-cloneable, immutable values (S9).
7
+ * No runtime proxy references, no DOM nodes, no live session handles leak
8
+ * across this boundary.
9
+ *
10
+ * ## Taxonomy (13 kinds, all structural / OOXML-native)
11
+ *
12
+ * The compiler is a **generic substrate** — it does not encode any
13
+ * vertical / domain vocabulary (CLM, legal, compliance, etc.). Domain
14
+ * concepts like "clause", "issue", or "suggestion" flow through the
15
+ * generic `classifications: readonly string[]` field on every scope,
16
+ * populated from host metadata on the workflow overlay. Layer 08 reads
17
+ * those tags and surfaces them verbatim; it does not mint new kinds
18
+ * for them.
19
+ *
20
+ * See `docs/wiki/use-case-domains/clm/semantic-scope-usage.md` for the
21
+ * CLM example of how hosts tag scopes for domain workflows.
22
+ *
23
+ * Taxonomy is FROZEN. Renaming, splitting, or adding kinds is a
24
+ * compatibility event.
25
+ */
26
+
27
+ import type { EditorStoryTarget } from "./_scope-dependencies.ts";
28
+
29
+ /**
30
+ * 13-value kind taxonomy — purely structural.
31
+ */
32
+ export type SemanticScopeKind =
33
+ | "heading"
34
+ | "paragraph"
35
+ | "list-item"
36
+ | "table"
37
+ | "table-row"
38
+ | "table-cell"
39
+ | "note"
40
+ | "field"
41
+ | "image"
42
+ | "comment-thread"
43
+ | "revision"
44
+ | "scope"
45
+ | "composite";
46
+
47
+ /**
48
+ * Provenance of a scope (three-way classification from workflow scopes,
49
+ * extended with `derived` for scopes the compiler synthesizes from canonical
50
+ * structure without any marker / overlay backing).
51
+ */
52
+ export type ScopeProvenance =
53
+ | "marker-backed"
54
+ | "overlay-only"
55
+ | "detached"
56
+ | "derived";
57
+
58
+ /**
59
+ * Stable reference strategy encoded into a handle. Consumers pick the
60
+ * strongest available; the compiler picks the single authoritative strategy
61
+ * per scope (marker-backed scopes carry `scope-id`, bookmarked regions carry
62
+ * `bookmark`, purely structural scopes carry `semantic-path`).
63
+ */
64
+ export type ScopeStableRef =
65
+ | { readonly kind: "scope-id"; readonly value: string }
66
+ | { readonly kind: "bookmark"; readonly value: string }
67
+ | { readonly kind: "semantic-path"; readonly value: string }
68
+ | { readonly kind: "runtime-handle"; readonly value: string };
69
+
70
+ /**
71
+ * Discriminator on how precise the scope's canonical range is:
72
+ *
73
+ * - `"marker-backed"` — range derived from the scope's own marker pair;
74
+ * canonical offsets are exact. Safe for offset arithmetic + apply.
75
+ * - `"canonical"` — range taken from the canonical document structure
76
+ * (paragraph / heading / list-item / table / field inline slot).
77
+ * Canonical offsets are exact.
78
+ * - `"synthetic"` — range is a proportional subdivision of a containing
79
+ * canonical slot (table-row / table-cell today). Suitable for overlap
80
+ * ordering inside the containing slot but NOT for cross-document
81
+ * offset arithmetic. Consumers needing a precise replacement envelope
82
+ * must resolve via the layer-05 geometry facet instead of trusting
83
+ * this range.
84
+ */
85
+ export type ScopeRangePrecision = "marker-backed" | "canonical" | "synthetic";
86
+
87
+ /**
88
+ * Opaque reference handle that identifies one scope across sessions (S2).
89
+ * Plain value — serialize, transport over Yjs / gRPC, feed back into
90
+ * `resolveReference` later.
91
+ */
92
+ export interface ScopeHandle {
93
+ readonly scopeId: string;
94
+ readonly documentId: string;
95
+ readonly storyTarget: EditorStoryTarget;
96
+ readonly semanticPath: readonly string[];
97
+ readonly parentScopeId?: string;
98
+ readonly stableRef: ScopeStableRef;
99
+ readonly provenance: ScopeProvenance;
100
+ /**
101
+ * How precise the scope's canonical range is. Consumers reading range
102
+ * offsets (resolve-reference, apply pipelines, overlay positioning)
103
+ * must check this before trusting the range for anything beyond
104
+ * overlap ordering inside the containing slot.
105
+ *
106
+ * Optional for backwards compatibility with scopes constructed before
107
+ * the discriminator shipped; when absent, treat as `"canonical"`.
108
+ */
109
+ readonly rangePrecision?: ScopeRangePrecision;
110
+ }
111
+
112
+ export interface SemanticScopeContent {
113
+ readonly text: string;
114
+ readonly normalizedText?: string;
115
+ readonly excerpt?: string;
116
+ readonly childScopeIds?: readonly string[];
117
+ }
118
+
119
+ export interface SemanticScopeNumbering {
120
+ readonly numberingInstanceId: string;
121
+ readonly level: number;
122
+ readonly label?: string;
123
+ }
124
+
125
+ export interface SemanticScopeFormatting {
126
+ readonly paragraphStyleId?: string;
127
+ readonly numbering?: SemanticScopeNumbering;
128
+ readonly emphasis?: readonly string[];
129
+ readonly tableRole?: "header" | "body" | "footer";
130
+ readonly outlineLevel?: number;
131
+ }
132
+
133
+ export interface SemanticScopeLineSpan {
134
+ readonly start: number;
135
+ readonly end: number;
136
+ }
137
+
138
+ export interface SemanticScopeLayout {
139
+ readonly sectionIndex?: number;
140
+ readonly pageSpan?: { readonly start: number; readonly end: number };
141
+ readonly regionKind?: string;
142
+ readonly lineSpan?: SemanticScopeLineSpan;
143
+ readonly flowKind?: string;
144
+ }
145
+
146
+ export interface GeometryRect {
147
+ readonly x: number;
148
+ readonly y: number;
149
+ readonly width: number;
150
+ readonly height: number;
151
+ }
152
+
153
+ export interface SemanticScopeGeometry {
154
+ readonly anchorRect?: GeometryRect;
155
+ readonly scopeRects?: readonly GeometryRect[];
156
+ readonly attachPoint?: {
157
+ readonly x: number;
158
+ readonly y: number;
159
+ readonly side: "before" | "after" | "inside";
160
+ };
161
+ }
162
+
163
+ export interface SemanticScopeWorkflow {
164
+ readonly scopeIds: readonly string[];
165
+ readonly effectiveMode: "edit" | "suggest" | "comment" | "view" | "blocked";
166
+ readonly blockedReasons?: readonly string[];
167
+ readonly issueIds?: readonly string[];
168
+ readonly suggestionIds?: readonly string[];
169
+ }
170
+
171
+ export type ReplaceabilityLevel =
172
+ | "full"
173
+ | "text-only"
174
+ | "formatting-only"
175
+ | "preserve-only"
176
+ | "blocked";
177
+
178
+ export interface Replaceability {
179
+ readonly level: ReplaceabilityLevel;
180
+ readonly reason?: string;
181
+ }
182
+
183
+ export interface SemanticScopeAudit {
184
+ readonly source: "runtime" | "import" | "host" | "agent";
185
+ readonly derivedFrom?: readonly string[];
186
+ readonly confidence?: "high" | "medium" | "low";
187
+ }
188
+
189
+ /**
190
+ * A fully compiled semantic scope. All projection fields are derived from
191
+ * the runtime at compile time (S1 — scopes reference truth; they are not
192
+ * truth).
193
+ *
194
+ * `partial: true` indicates at least one projection field degraded because
195
+ * its upstream input (formatting seam, geometry envelope, layout graph) was
196
+ * unavailable at compile time. Consumers treat this as a read-useful /
197
+ * write-unsafe signal.
198
+ *
199
+ * `classifications` carries host-supplied domain tags for the scope (for
200
+ * example: CLM hosts supply `"clause"`, `"domain:legal"`, `"label:Liability"`
201
+ * as classifications on a paragraph marker-backed by a clause overlay
202
+ * scope). The compiler does not interpret classification strings — it
203
+ * only surfaces them. Consumers route / filter / render on them.
204
+ */
205
+ export interface SemanticScope {
206
+ readonly handle: ScopeHandle;
207
+ readonly kind: SemanticScopeKind;
208
+ readonly classifications: readonly string[];
209
+ readonly content: SemanticScopeContent;
210
+ readonly formatting: SemanticScopeFormatting;
211
+ readonly layout: SemanticScopeLayout;
212
+ readonly geometry: SemanticScopeGeometry;
213
+ readonly workflow: SemanticScopeWorkflow;
214
+ readonly replaceability: Replaceability;
215
+ readonly audit: SemanticScopeAudit;
216
+ readonly partial?: boolean;
217
+ }
218
+
219
+ /* -------------------------------------------------------------------------
220
+ * Bundle / replacement / validation / audit shapes
221
+ *
222
+ * Declared in Slice 1 so downstream layers (AI API, review-bundle) can
223
+ * reference the types without creating a churn point when later slices
224
+ * implement them. Implementation lands in Slice 3 (bundle), Slice 4
225
+ * (ValidationResult), Slice 5 (replacement + audit).
226
+ * ---------------------------------------------------------------------- */
227
+
228
+ export interface ScopeBundleNeighborhood {
229
+ readonly previousScopeId?: string;
230
+ readonly nextScopeId?: string;
231
+ readonly parentScopeId?: string;
232
+ readonly siblingScopeIds?: readonly string[];
233
+ }
234
+
235
+ /**
236
+ * Agent-authored explanation attached to a scope via
237
+ * `ai.attachExplanation`. Read back through `ScopeBundleEvidence` so the
238
+ * write-side + read-side stay symmetric (adversarial-close item 1).
239
+ */
240
+ export interface AIExplanationSummary {
241
+ readonly explanationId: string;
242
+ readonly text: string;
243
+ readonly createdAtUtc?: string;
244
+ }
245
+
246
+ /**
247
+ * Agent-authored issue attached to a scope via `ai.createIssue`. Same
248
+ * read-side-symmetry rationale as `AIExplanationSummary`.
249
+ */
250
+ export interface AIIssueSummary {
251
+ readonly issueId: string;
252
+ readonly summary: string;
253
+ readonly severity: "info" | "warning" | "error";
254
+ readonly status: "open" | "resolved";
255
+ readonly createdAtUtc?: string;
256
+ }
257
+
258
+ export interface ScopeBundleEvidence {
259
+ readonly formattingSummary?: string;
260
+ readonly reviewItemIds?: readonly string[];
261
+ readonly overlappingWorkflowScopeIds?: readonly string[];
262
+ readonly compatibilityFlags?: readonly string[];
263
+ /**
264
+ * Agent-authored explanations on this scope, read back from Layer-06
265
+ * metadata entries keyed by `metadataId: "ai.explanation"`. Adversarial-
266
+ * close 2026-04-22 read-side join: the compiler previously wrote
267
+ * explanations but did not surface them back through `getScopeBundle`.
268
+ */
269
+ readonly aiExplanations?: readonly AIExplanationSummary[];
270
+ /**
271
+ * Agent-authored issues on this scope, read back from Layer-06
272
+ * metadata entries keyed by `metadataId: "ai.issue"`. Same adversarial-
273
+ * close read-side-symmetry rationale.
274
+ */
275
+ readonly aiIssues?: readonly AIIssueSummary[];
276
+ }
277
+
278
+ export interface ScopeBundle {
279
+ readonly scope: SemanticScope;
280
+ readonly neighborhood: ScopeBundleNeighborhood;
281
+ readonly evidence: ScopeBundleEvidence;
282
+ readonly generatedAtUtc: string;
283
+ }
284
+
285
+ export type ReplacementOperationKind =
286
+ | "replace"
287
+ | "insert-before"
288
+ | "insert-after"
289
+ | "split"
290
+ | "annotate";
291
+
292
+ export interface ReplacementPreservePolicy {
293
+ readonly numbering?: boolean;
294
+ readonly paragraphStyle?: boolean;
295
+ readonly runFormatting?: boolean;
296
+ readonly comments?: boolean;
297
+ readonly revisions?: boolean;
298
+ readonly bookmarks?: boolean;
299
+ }
300
+
301
+ export interface ReplacementScope {
302
+ readonly targetHandle: ScopeHandle;
303
+ readonly operation: ReplacementOperationKind;
304
+ readonly proposedContent: {
305
+ readonly kind: "text" | "structured";
306
+ /** Present when `kind === "text"` — flat text replacement. */
307
+ readonly text?: string;
308
+ /**
309
+ * Present when `kind === "structured"`. Typed as `unknown` at the
310
+ * plain-value boundary because consumers that serialise a
311
+ * `ReplacementScope` across transports (Yjs / MCP / storage) don't
312
+ * need the full L02 `BlockNode` type graph at the use site. It also
313
+ * lets adjacent payloads (metadata-audit annotations, etc.) reuse
314
+ * the field. Runtime consumers (paragraph.compileReplacement,
315
+ * DocumentRuntime.applyScopeReplacement) narrow via
316
+ * `isStructuredReplacementContent` before trusting the shape as a
317
+ * `CanonicalDocumentFragment`.
318
+ */
319
+ readonly structured?: unknown;
320
+ };
321
+ readonly preserve?: ReplacementPreservePolicy;
322
+ readonly reason?: string;
323
+ readonly proposedAtUtc: string;
324
+ }
325
+
326
+ /**
327
+ * Structural guard for `proposedContent.structured` when it carries a
328
+ * fragment payload (L02's `CanonicalDocumentFragment`). Callers that
329
+ * need to dispatch the fragment through the runtime narrow via this
330
+ * predicate before trusting the shape.
331
+ */
332
+ export interface StructuredReplacementContent {
333
+ readonly blocks: ReadonlyArray<unknown>;
334
+ }
335
+
336
+ export function isStructuredReplacementContent(
337
+ value: unknown,
338
+ ): value is StructuredReplacementContent {
339
+ return (
340
+ typeof value === "object" &&
341
+ value !== null &&
342
+ Array.isArray((value as { blocks?: unknown }).blocks)
343
+ );
344
+ }
345
+
346
+ export interface ValidationIssue {
347
+ readonly code: string;
348
+ readonly message: string;
349
+ readonly source: "guard" | "preserve" | "compat" | "policy";
350
+ }
351
+
352
+ export interface ValidationApproval {
353
+ readonly required: boolean;
354
+ readonly reason?: string;
355
+ }
356
+
357
+ /**
358
+ * Composed verdict from workflow guard + preservation boundaries +
359
+ * compatibility posture + AI policy. Slice 4 implements the composer;
360
+ * Slice 5 consumes it before any apply.
361
+ */
362
+ export interface ValidationResult {
363
+ readonly safe: boolean;
364
+ readonly blockedReasons: readonly string[];
365
+ readonly warnings: readonly ValidationIssue[];
366
+ readonly approval?: ValidationApproval;
367
+ }
368
+
369
+ /**
370
+ * Plain-value description of the runtime operations a replacement
371
+ * lowers to. Produced by Slice 5's per-kind `compileReplacement(scope,
372
+ * proposed)` and consumed by `DocumentRuntime.applyScopeReplacement`.
373
+ * Kept narrow — one step per mutation — so the audit bundle's
374
+ * `compiledOperations` is a faithful ledger of what the runtime did.
375
+ */
376
+ export type RuntimeOperationStepKind =
377
+ | "text-replace"
378
+ | "text-insert-tracked"
379
+ | "text-delete-tracked"
380
+ | "fragment-replace";
381
+
382
+ export interface RuntimeOperationStep {
383
+ readonly kind: RuntimeOperationStepKind;
384
+ /** Human-readable one-line description; used in audit `compiledOperations`. */
385
+ readonly summary: string;
386
+ /**
387
+ * Document-coordinate range the step operates on. Absent for steps
388
+ * that target the scope as a whole.
389
+ */
390
+ readonly range?: {
391
+ readonly from: number;
392
+ readonly to: number;
393
+ };
394
+ /** New text for text-replace / text-insert-tracked. */
395
+ readonly text?: string;
396
+ /**
397
+ * `CanonicalDocumentFragment`-shaped payload for `fragment-replace`.
398
+ * Plain-value boundary (S9) — no live references; safe to serialise.
399
+ * Consumers narrow to `CanonicalDocumentFragment` at the runtime
400
+ * boundary (`DocumentRuntime.applyScopeReplacement`).
401
+ */
402
+ readonly fragment?: StructuredReplacementContent;
403
+ }
404
+
405
+ export interface RuntimeOperationPlan {
406
+ readonly scopeId: string;
407
+ readonly targetKind: SemanticScopeKind;
408
+ readonly operation: ReplacementOperationKind;
409
+ readonly steps: readonly RuntimeOperationStep[];
410
+ readonly preserve?: ReplacementPreservePolicy;
411
+ /** Posture the apply pipeline should dispatch under. */
412
+ readonly posture: "direct-edit" | "suggest-mode";
413
+ }
414
+
415
+ export interface ScopeActionAudit {
416
+ readonly actionId: string;
417
+ readonly actorId: string;
418
+ readonly origin: "ui" | "agent" | "host";
419
+ readonly documentHashBefore: string;
420
+ readonly documentHashAfter?: string;
421
+ readonly targetScopeSnapshot: SemanticScope;
422
+ readonly proposed: ReplacementScope;
423
+ readonly compiledOperations: readonly {
424
+ readonly kind: string;
425
+ readonly summary: string;
426
+ }[];
427
+ readonly validation: ValidationResult;
428
+ readonly emittedAtUtc: string;
429
+ }
430
+
431
+ /* -------------------------------------------------------------------------
432
+ * Debug projector
433
+ * ---------------------------------------------------------------------- */
434
+
435
+ /**
436
+ * Debug-channel projector entry produced per compiled scope. Consumed by
437
+ * the runtime `DebugInspectorSnapshot.scopes.compilerView` (wired in a
438
+ * follow-up slice — Slice 1 emits the entries; snapshot-side wiring is a
439
+ * cross-surface edit deferred to the next layer-local commit).
440
+ */
441
+ export interface ScopeCompilerDebugEntry {
442
+ readonly scopeId: string;
443
+ readonly kind: SemanticScopeKind;
444
+ readonly provenance: ScopeProvenance;
445
+ readonly partial: boolean;
446
+ readonly projectionFields: {
447
+ readonly content: boolean;
448
+ readonly formatting: boolean;
449
+ readonly layout: boolean;
450
+ readonly geometry: boolean;
451
+ readonly workflow: boolean;
452
+ };
453
+ readonly compiledAtUtc: string;
454
+ }