@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.
- package/README.md +75 -931
- package/package.json +26 -27
- package/src/api/anchor-conversion.ts +43 -0
- package/src/api/editor-state-types.ts +2 -1
- package/src/api/public-types.ts +504 -101
- package/src/api/session-state.ts +4 -0
- package/src/api/v3/README.md +91 -0
- package/src/api/v3/_create.ts +146 -0
- package/src/api/v3/_layer-metadata.ts +362 -0
- package/src/api/v3/_mocks.ts +84 -0
- package/src/api/v3/_runtime-handle.ts +162 -0
- package/src/api/v3/_ux-response.ts +73 -0
- package/src/api/v3/ai/_metadata-audit.ts +225 -0
- package/src/api/v3/ai/attach.ts +235 -0
- package/src/api/v3/ai/bundle.ts +132 -0
- package/src/api/v3/ai/explain.ts +144 -0
- package/src/api/v3/ai/export.ts +54 -0
- package/src/api/v3/ai/inspect.ts +118 -0
- package/src/api/v3/ai/policy.ts +77 -0
- package/src/api/v3/ai/replacement.ts +341 -0
- package/src/api/v3/ai/resolve.ts +133 -0
- package/src/api/v3/index.ts +79 -0
- package/src/api/v3/runtime/chart.ts +310 -0
- package/src/api/v3/runtime/clipboard.ts +81 -0
- package/src/api/v3/runtime/collab.ts +331 -0
- package/src/api/v3/runtime/content.ts +236 -0
- package/src/api/v3/runtime/document.ts +282 -0
- package/src/api/v3/runtime/formatting.ts +186 -0
- package/src/api/v3/runtime/geometry.ts +349 -0
- package/src/api/v3/runtime/layout.ts +108 -0
- package/src/api/v3/runtime/review.ts +129 -0
- package/src/api/v3/runtime/search.ts +74 -0
- package/src/api/v3/runtime/table.ts +63 -0
- package/src/api/v3/runtime/workflow.ts +434 -0
- package/src/api/v3/ui/_context.ts +86 -0
- package/src/api/v3/ui/_create.ts +65 -0
- package/src/api/v3/ui/_types.ts +520 -0
- package/src/api/v3/ui/chrome-composition.ts +342 -0
- package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
- package/src/api/v3/ui/chrome.ts +476 -0
- package/src/api/v3/ui/debug.ts +124 -0
- package/src/api/v3/ui/index.ts +64 -0
- package/src/api/v3/ui/overlays-visibility.ts +170 -0
- package/src/api/v3/ui/overlays.ts +427 -0
- package/src/api/v3/ui/scope.ts +71 -0
- package/src/api/v3/ui/session.ts +100 -0
- package/src/api/v3/ui/surface.ts +170 -0
- package/src/api/v3/ui/viewport.ts +303 -0
- package/src/core/commands/index.ts +28 -6
- package/src/core/commands/list-commands.ts +3 -2
- package/src/core/commands/section-layout-commands.ts +9 -8
- package/src/core/schema/text-schema.ts +16 -0
- package/src/core/selection/mapping.ts +33 -72
- package/src/core/state/editor-state.ts +96 -189
- package/src/index.ts +23 -4
- package/src/io/chart-preview-resolver.ts +1 -1
- package/src/io/docx-session.ts +36 -4795
- package/src/io/export/build-app-properties-xml.ts +1 -1
- package/src/io/export/serialize-comments.ts +1 -1
- package/src/io/export/serialize-headers-footers.ts +6 -1
- package/src/io/export/serialize-main-document.ts +45 -0
- package/src/io/export/serialize-run-formatting.ts +17 -2
- package/src/io/export/twip.ts +1 -1
- package/src/io/normalize/normalize-text.ts +27 -20
- package/src/io/ooxml/chart/parse-series.ts +1 -1
- package/src/io/ooxml/chart/resolve-color.ts +2 -2
- package/src/io/ooxml/chart/types.ts +1 -1
- package/src/io/ooxml/classify-embedding.ts +83 -33
- package/src/io/ooxml/parse-fill.ts +1 -1
- package/src/io/ooxml/parse-main-document.ts +71 -1
- package/src/io/ooxml/parse-object.ts +14 -10
- package/src/io/ooxml/parse-run-formatting.ts +47 -1
- package/src/io/ooxml/property-grab-bag.ts +2 -2
- package/src/io/ooxml/units.ts +11 -0
- package/src/io/ooxml/workflow-payload.ts +282 -7
- package/src/model/anchor.ts +85 -0
- package/src/model/canonical-document.ts +351 -15
- package/src/model/chart-types.ts +1 -1
- package/src/model/layout/index.ts +83 -0
- package/src/model/layout/page-graph-types.ts +181 -0
- package/src/model/layout/page-layout-snapshot.ts +105 -0
- package/src/model/layout/resolved-layout-types.ts +47 -0
- package/src/model/layout/runtime-page-graph-types.ts +102 -0
- package/src/model/paragraph-scope-ids.ts +72 -0
- package/src/model/review/comment-types.ts +112 -0
- package/src/model/review/index.ts +2 -0
- package/src/model/review/revision-types.ts +215 -0
- package/src/model/snapshot.ts +32 -0
- package/src/review/store/comment-store.ts +21 -47
- package/src/review/store/revision-types.ts +40 -198
- package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
- package/src/runtime/collab/runtime-collab-sync.ts +13 -3
- package/src/runtime/collab-session.ts +1 -1
- package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
- package/src/runtime/debug/event-ring-buffer.ts +64 -0
- package/src/runtime/debug/probability-sampler.ts +18 -0
- package/src/runtime/debug/runtime-debug-facet.ts +67 -0
- package/src/runtime/debug/stage-tokens.ts +31 -0
- package/src/runtime/debug/telemetry-bus.ts +271 -0
- package/src/runtime/debug/types.ts +275 -0
- package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
- package/src/runtime/document-layout.ts +8 -6
- package/src/runtime/document-runtime.ts +843 -1141
- package/src/runtime/document-search.ts +1 -1
- package/src/runtime/edit-ops/index.ts +1 -1
- package/src/runtime/external-send-runtime.ts +1 -1
- package/src/runtime/formatting/document-lookup.ts +235 -0
- package/src/runtime/formatting/field/registry.ts +41 -0
- package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
- package/src/runtime/formatting/font-resolution.ts +83 -0
- package/src/runtime/formatting/formatting-context.ts +903 -0
- package/src/runtime/formatting/formatting-types.ts +157 -0
- package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
- package/src/runtime/formatting/index.ts +125 -0
- package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
- package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
- package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
- package/src/runtime/formatting/projector.ts +75 -0
- package/src/runtime/formatting/resolve-effective.ts +407 -0
- package/src/runtime/formatting/revision-display.ts +105 -0
- package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
- package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
- package/src/runtime/formatting/telemetry-bridge.ts +106 -0
- package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
- package/src/runtime/geometry/caret-geometry.ts +164 -0
- package/src/runtime/geometry/geometry-facet.ts +364 -0
- package/src/runtime/geometry/geometry-types.ts +256 -0
- package/src/runtime/geometry/hit-test.ts +125 -0
- package/src/runtime/geometry/index.ts +71 -0
- package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
- package/src/runtime/geometry/invalidation.ts +35 -0
- package/src/runtime/geometry/object-handles.ts +77 -0
- package/src/runtime/geometry/overlay-rects.ts +85 -0
- package/src/runtime/geometry/project-anchors.ts +100 -0
- package/src/runtime/geometry/project-fragments.ts +216 -0
- package/src/runtime/geometry/projector.ts +129 -0
- package/src/runtime/geometry/replacement-envelope.ts +130 -0
- package/src/runtime/geometry/viewport.ts +218 -0
- package/src/runtime/layout/compat-input-ledger.ts +211 -0
- package/src/runtime/layout/index.ts +6 -1
- package/src/runtime/layout/inert-layout-facet.ts +12 -7
- package/src/runtime/layout/layout-engine-instance.ts +189 -11
- package/src/runtime/layout/layout-engine-version.ts +450 -1
- package/src/runtime/layout/layout-facet-types.ts +60 -0
- package/src/runtime/layout/layout-measurement-provider.ts +13 -0
- package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
- package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
- package/src/runtime/layout/page-graph.ts +62 -209
- package/src/runtime/layout/page-story-resolver.ts +7 -12
- package/src/runtime/layout/paginated-layout-engine.ts +186 -11
- package/src/runtime/layout/project-block-fragments.ts +11 -0
- package/src/runtime/layout/projector.ts +90 -0
- package/src/runtime/layout/public-facet.ts +187 -442
- package/src/runtime/layout/resolved-formatting-state.ts +158 -26
- package/src/runtime/layout/table-render-plan.ts +1 -1
- package/src/runtime/prerender/cache-envelope.ts +6 -1
- package/src/runtime/prerender/prerender-document.ts +18 -23
- package/src/runtime/render/decoration-resolver.ts +1 -1
- package/src/runtime/render/render-frame-types.ts +20 -0
- package/src/runtime/render/render-kernel.ts +94 -25
- package/src/runtime/scopes/_formatting-seam.ts +262 -0
- package/src/runtime/scopes/_scope-dependencies.ts +49 -0
- package/src/runtime/scopes/action-validation.ts +356 -0
- package/src/runtime/scopes/attach-explanation.ts +102 -0
- package/src/runtime/scopes/audit-bundle.ts +71 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
- package/src/runtime/scopes/compile-scope.ts +262 -0
- package/src/runtime/scopes/compiler-service.ts +431 -0
- package/src/runtime/scopes/create-issue.ts +107 -0
- package/src/runtime/scopes/enumerate-scopes.ts +543 -0
- package/src/runtime/scopes/evidence.ts +233 -0
- package/src/runtime/scopes/index.ts +150 -0
- package/src/runtime/scopes/position-map.ts +214 -0
- package/src/runtime/scopes/preservation-boundary.ts +91 -0
- package/src/runtime/scopes/projector.ts +49 -0
- package/src/runtime/scopes/replaceability.ts +87 -0
- package/src/runtime/scopes/replacement/apply.ts +228 -0
- package/src/runtime/scopes/replacement/compile.ts +59 -0
- package/src/runtime/scopes/replacement/propose.ts +42 -0
- package/src/runtime/scopes/resolve-reference.ts +347 -0
- package/src/runtime/scopes/review-bundle.ts +141 -0
- package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
- package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
- package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
- package/src/runtime/scopes/scope-kinds/field.ts +65 -0
- package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
- package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
- package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
- package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
- package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
- package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
- package/src/runtime/scopes/scope-kinds/table.ts +55 -0
- package/src/runtime/scopes/scope-range.ts +208 -0
- package/src/runtime/scopes/semantic-scope-types.ts +454 -0
- package/src/runtime/scopes/workflow-overlap.ts +92 -0
- package/src/runtime/selection/index.ts +1 -1
- package/src/runtime/structure-ops/fragment-insert.ts +1 -1
- package/src/runtime/structure-ops/index.ts +1 -1
- package/src/runtime/surface-projection.ts +232 -262
- package/src/runtime/units.ts +4 -2
- package/src/runtime/workflow/coordinator.ts +1348 -0
- package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
- package/src/runtime/workflow/index.ts +25 -0
- package/src/runtime/workflow/markup-mode-policy.ts +98 -0
- package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
- package/src/runtime/workflow/metadata-persistence.ts +306 -0
- package/src/runtime/workflow/metadata-writer.ts +123 -0
- package/src/runtime/workflow/overlay-store.ts +690 -0
- package/src/runtime/workflow/projector.ts +127 -0
- package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
- package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
- package/src/runtime/workflow/rail/types.ts +198 -0
- package/src/runtime/workflow/scope-rail-composer.ts +39 -0
- package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
- package/src/runtime/workflow/scope-writer.ts +188 -0
- package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
- package/src/runtime/workflow/visibility-policy.ts +129 -0
- package/src/session/_sync-legacy.ts +66 -0
- package/src/session/export/embedded-reconstitute.ts +104 -0
- package/src/session/export/export-diagnostics.ts +85 -0
- package/src/session/export/export-validation.ts +110 -0
- package/src/session/export/index.ts +34 -0
- package/src/session/export/preservation-reattach.ts +30 -0
- package/src/session/export/serialize-dispatch.ts +165 -0
- package/src/session/export/stateful-export-pipeline.ts +432 -0
- package/src/session/export/stateful-export.ts +684 -0
- package/src/session/import/canonical-assembly.ts +227 -0
- package/src/session/import/diagnostics-session.ts +54 -0
- package/src/session/import/embedded-discovery.ts +225 -0
- package/src/session/import/embedded-offload.ts +337 -0
- package/src/session/import/import-diagnostics.ts +69 -0
- package/src/session/import/loader-types.ts +313 -0
- package/src/session/import/loader.ts +1834 -0
- package/src/session/import/normalize.ts +195 -0
- package/src/session/import/package-parts.ts +217 -0
- package/src/session/import/package-read.ts +195 -0
- package/src/session/import/parse-orchestration.ts +105 -0
- package/src/session/import/part-constants.ts +70 -0
- package/src/session/import/part-discovery.ts +94 -0
- package/src/session/import/preservation-index.ts +46 -0
- package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
- package/src/session/import/review-import.ts +508 -0
- package/src/session/import/styles-consolidation.ts +281 -0
- package/src/session/import/workflow-scope-import.ts +256 -0
- package/src/session/index.ts +37 -0
- package/src/session/session-state.ts +69 -0
- package/src/session/session.ts +532 -0
- package/src/session/shared/protection.ts +228 -0
- package/src/session/shared/session-utils.ts +82 -0
- package/src/session/types.ts +499 -0
- package/src/shell/chart-snapshots.ts +96 -0
- package/src/shell/media-previews.ts +85 -0
- package/src/shell/overlay-anchor-bridge.ts +53 -0
- package/src/shell/paste-adapter.ts +23 -0
- package/src/shell/ref-commands.ts +1697 -0
- package/src/shell/ref-utilities.ts +48 -0
- package/src/shell/search.ts +51 -0
- package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
- package/src/shell/ui-subscriber-channels.ts +81 -0
- package/src/shell/use-collab-sync.ts +116 -0
- package/src/ui/WordReviewEditor.tsx +496 -2051
- package/src/ui/editor-shell-view.tsx +30 -1
- package/src/ui/editor-surface-controller.tsx +49 -1
- package/src/ui/headless/revision-decoration-model.ts +83 -0
- package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
- package/src/ui/headless/scoped-chrome-policy.ts +2 -2
- package/src/ui/headless/selection-tool-context.ts +1 -1
- package/src/ui/headless/selection-tool-resolver.ts +1 -1
- package/src/ui/runtime-shortcut-dispatch.ts +46 -1
- package/src/ui/ui-controller-factory.ts +221 -0
- package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
- package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
- package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
- package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
- package/src/ui-tailwind/chart/render/area.tsx +3 -3
- package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
- package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
- package/src/ui-tailwind/chart/render/combo.tsx +2 -2
- package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
- package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
- package/src/ui-tailwind/chart/render/line.tsx +3 -3
- package/src/ui-tailwind/chart/render/pie.tsx +6 -6
- package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
- package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
- package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
- package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
- package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
- package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
- package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
- package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
- package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
- package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
- package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
- package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
- package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
- package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
- package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
- package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
- package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
- package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
- package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
- package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
- package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
- package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
- package/src/ui-tailwind/debug/README.md +57 -0
- package/src/ui-tailwind/debug/index.ts +3 -0
- package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
- package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
- package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
- package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
- package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
- package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
- package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
- package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
- package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
- package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
- package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
- package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
- package/src/ui-tailwind/index.ts +0 -5
- package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
- package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
- package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
- package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
- package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
- package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
- package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
- package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
- package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
- package/src/ui-tailwind/review-workspace/types.ts +408 -0
- package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
- package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
- package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
- package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
- package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
- package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
- package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
- package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
- package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
- package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
- package/src/ui-tailwind/theme/editor-theme.css +25 -0
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
- package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
- package/src/ui-tailwind/ui-api-context.tsx +43 -0
- package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
- package/src/validation/compatibility-engine.ts +6 -6
- package/src/runtime/styles-cascade.ts +0 -33
- package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
- /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
- /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
- /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
|
+
}
|