@beyondwork/docx-react-component 1.0.67 → 1.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -932
- 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 -4797
- 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,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — `runtime.document` family.
|
|
3
|
+
*
|
|
4
|
+
* See docs/reference/public-api.md § runtime.document. Three functions:
|
|
5
|
+
* `load` (partial — runtime pre-load is the caller's responsibility; v3
|
|
6
|
+
* exposes a re-mount semantic later), `export` (live; delegates to
|
|
7
|
+
* `runtime.exportDocx`), `validate` (partial; read live, write mock).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
11
|
+
import type {
|
|
12
|
+
EditorError,
|
|
13
|
+
ExportDocxOptions,
|
|
14
|
+
ExportResult,
|
|
15
|
+
PersistedEditorSnapshot,
|
|
16
|
+
} from "../../public-types.ts";
|
|
17
|
+
import { mockPayload } from "../_mocks.ts";
|
|
18
|
+
import type { ApiV3FnMetadata, MockPayload } from "../_layer-metadata.ts";
|
|
19
|
+
import { emitUxResponse } from "../_ux-response.ts";
|
|
20
|
+
import { loadDocxSessionAsync } from "../../../session/import/loader.ts";
|
|
21
|
+
import { createLoadScheduler } from "../../../io/load-scheduler.ts";
|
|
22
|
+
|
|
23
|
+
/* ================================================================== */
|
|
24
|
+
/* load */
|
|
25
|
+
/* ================================================================== */
|
|
26
|
+
|
|
27
|
+
export interface LoadInput {
|
|
28
|
+
readonly bytes: Uint8Array | ArrayBuffer;
|
|
29
|
+
/**
|
|
30
|
+
* Document identity for the newly-loaded session. Required by
|
|
31
|
+
* `loadDocxSessionAsync` — when omitted, v3 synthesizes a stable
|
|
32
|
+
* `v3-load-<timestamp>` id so agents calling without host-assigned
|
|
33
|
+
* ids still get deterministic-enough output.
|
|
34
|
+
*/
|
|
35
|
+
readonly documentId?: string;
|
|
36
|
+
readonly sourceLabel?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Live result of loading a DOCX package via the session-layer loader
|
|
41
|
+
* (`src/session/import/loader.ts::loadDocxSessionAsync`). Under the
|
|
42
|
+
* L07 Option-B contract (arch §R8) v3 does NOT construct a new
|
|
43
|
+
* `DocumentRuntime` — `createDocumentRuntime` stays synchronous and
|
|
44
|
+
* requires a fully-loaded `EditorSessionState`. The v3 `load()`
|
|
45
|
+
* returns the serializable `snapshot` + status so callers can mount
|
|
46
|
+
* a new runtime themselves or persist / rehydrate via
|
|
47
|
+
* `DocxSession.reopenFromSnapshot` (L01 coord §2).
|
|
48
|
+
*
|
|
49
|
+
* Every field is live from the actual parse:
|
|
50
|
+
* - `documentId` — echoes the input (or synthesized default).
|
|
51
|
+
* - `bytes` — byte-length of the source package.
|
|
52
|
+
* - `readOnly` — protection state the loader detected.
|
|
53
|
+
* - `embeddedDocumentsCount` — count of embedded sub-documents
|
|
54
|
+
* discovered via P8 embedded-document discovery.
|
|
55
|
+
* - `snapshot` — the `PersistedEditorSnapshot` the loader produced.
|
|
56
|
+
* - `fatalError` — present when `status === "fatal"`.
|
|
57
|
+
* - `status` — `"loaded"` on success, `"fatal"` when the package
|
|
58
|
+
* couldn't be parsed (corrupt bytes, unsupported schema, etc.).
|
|
59
|
+
*/
|
|
60
|
+
export interface LoadResult {
|
|
61
|
+
readonly documentId: string;
|
|
62
|
+
readonly bytes: number;
|
|
63
|
+
readonly readOnly: boolean;
|
|
64
|
+
readonly embeddedDocumentsCount: number;
|
|
65
|
+
readonly snapshot: PersistedEditorSnapshot;
|
|
66
|
+
readonly fatalError?: EditorError;
|
|
67
|
+
readonly status: "loaded" | "fatal";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const loadMetadata: ApiV3FnMetadata = {
|
|
71
|
+
name: "runtime.document.load",
|
|
72
|
+
status: "live",
|
|
73
|
+
sourceLayer: "package-session",
|
|
74
|
+
// Full live — direct delegation to loadDocxSessionAsync. No adapter
|
|
75
|
+
// debt: v3 doesn't construct a runtime (Option B contract, §R8),
|
|
76
|
+
// but the parse itself is the shipped session-layer contract.
|
|
77
|
+
// Returns the serializable snapshot + fatalError + readOnly fields
|
|
78
|
+
// the loader produced; v3 is a thin shape-projection over that.
|
|
79
|
+
liveEvidence: {
|
|
80
|
+
runnerTest: "test/api/v3/live-parity.test.ts",
|
|
81
|
+
commit: "refactor-07-document-load-live-post-eb7d14fa",
|
|
82
|
+
},
|
|
83
|
+
uxIntent: { uiVisible: true, expectsUxResponse: "surface-refresh", expectedDelta: "editor surface replaces with newly-loaded document" },
|
|
84
|
+
agentMetadata: { readOrMutate: "compound", boundedScope: "session", auditCategory: "document-load" },
|
|
85
|
+
stateClass: "A-canonical",
|
|
86
|
+
persistsTo: "canonical",
|
|
87
|
+
rwdReference:
|
|
88
|
+
"§Runtime API § runtime.document.load. Graduation (2026-04-22, post-eb7d14fa): `live` via direct delegation to `loadDocxSessionAsync` (src/session/import/loader.ts). Returns a PersistedEditorSnapshot the caller can pass to DocxSession.reopenFromSnapshot or persist for later rehydrate. Note per arch §R8 Option B: v3 does NOT construct the receiving DocumentRuntime — that's the caller's job via createDocumentRuntime(initialSessionState).",
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/* ================================================================== */
|
|
92
|
+
/* export */
|
|
93
|
+
/* ================================================================== */
|
|
94
|
+
|
|
95
|
+
export const exportMetadata: ApiV3FnMetadata = {
|
|
96
|
+
name: "runtime.document.export",
|
|
97
|
+
status: "live",
|
|
98
|
+
sourceLayer: "package-session",
|
|
99
|
+
liveEvidence: {
|
|
100
|
+
runnerTest: "services/debug/lib/session-manager.test.ts",
|
|
101
|
+
probeScript: "services/debug/scripts/probe-channel-emissions.ts",
|
|
102
|
+
commit: "6aca0666",
|
|
103
|
+
},
|
|
104
|
+
uxIntent: { uiVisible: true, expectsUxResponse: "toast", expectedDelta: "toast shows export bytes size + completion" },
|
|
105
|
+
agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "document-export" },
|
|
106
|
+
stateClass: "A-canonical",
|
|
107
|
+
persistsTo: "canonical",
|
|
108
|
+
rwdReference: "§Runtime API § runtime.document.export",
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/* ================================================================== */
|
|
112
|
+
/* validate */
|
|
113
|
+
/* ================================================================== */
|
|
114
|
+
|
|
115
|
+
export interface ValidateResult {
|
|
116
|
+
readonly reportVersion: "compatibility-report/1";
|
|
117
|
+
readonly blockExport: boolean;
|
|
118
|
+
readonly warningCount: number;
|
|
119
|
+
readonly errorCount: number;
|
|
120
|
+
readonly featureEntriesCount: number;
|
|
121
|
+
readonly interactionGuard: {
|
|
122
|
+
readonly mode: string;
|
|
123
|
+
readonly readOnly: boolean;
|
|
124
|
+
};
|
|
125
|
+
readonly __mock?: true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const validateMetadata: ApiV3FnMetadata = {
|
|
129
|
+
name: "runtime.document.validate",
|
|
130
|
+
status: "live-with-adapter",
|
|
131
|
+
sourceLayer: "package-session",
|
|
132
|
+
liveEvidence: {
|
|
133
|
+
runnerTest: "test/api/v3/live-parity.test.ts",
|
|
134
|
+
commit: "phase-p-prime",
|
|
135
|
+
},
|
|
136
|
+
mockShape: {
|
|
137
|
+
deterministic: true,
|
|
138
|
+
seededFrom: "hash",
|
|
139
|
+
shapeDescription: "Fallback ValidateResult with zeroed counts when any of the three runtime reads is unavailable; never returned on a healthy runtime.",
|
|
140
|
+
carriesMockFlag: true,
|
|
141
|
+
},
|
|
142
|
+
uxIntent: { uiVisible: true, expectsUxResponse: "warning-added", expectedDelta: "compatibility drawer summary updates" },
|
|
143
|
+
agentMetadata: { readOrMutate: "read", boundedScope: "document", auditCategory: "document-validate" },
|
|
144
|
+
stateClass: "A-canonical",
|
|
145
|
+
persistsTo: "canonical",
|
|
146
|
+
rwdReference:
|
|
147
|
+
"§Runtime API § runtime.document.validate. Adapter composes three shipped runtime reads — getCompatibilityReport() + getWarnings() + getInteractionGuardSnapshot() — into one bundled ValidateResult. Promotes to `live` when a first-class runtime.validate() lands.",
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/* ================================================================== */
|
|
151
|
+
/* family factory */
|
|
152
|
+
/* ================================================================== */
|
|
153
|
+
|
|
154
|
+
export function createDocumentFamily(runtime: RuntimeApiHandle) {
|
|
155
|
+
return {
|
|
156
|
+
async load(input: LoadInput): Promise<LoadResult> {
|
|
157
|
+
// @endStateApi — live. Delegates directly to the session-layer
|
|
158
|
+
// loader `loadDocxSessionAsync`. v3 projects the returned
|
|
159
|
+
// `LoadedDocxEditorSession` into the serializable `LoadResult`
|
|
160
|
+
// shape — drops the `exportDocx` closure (R5: no runtime-
|
|
161
|
+
// instance leakage) and surfaces `snapshot` + fatalError + read-
|
|
162
|
+
// only for callers that mount via `createDocumentRuntime(
|
|
163
|
+
// initialSessionState)` themselves (Option B, §R8) or rehydrate
|
|
164
|
+
// via `DocxSession.reopenFromSnapshot(snapshot)` (L01 coord §2).
|
|
165
|
+
const byteLength = input.bytes instanceof Uint8Array
|
|
166
|
+
? input.bytes.byteLength
|
|
167
|
+
: input.bytes.byteLength;
|
|
168
|
+
const documentId = input.documentId ?? `v3-load-${Date.now()}`;
|
|
169
|
+
const loaded = await loadDocxSessionAsync({
|
|
170
|
+
bytes: input.bytes,
|
|
171
|
+
documentId,
|
|
172
|
+
...(input.sourceLabel ? { sourceLabel: input.sourceLabel } : {}),
|
|
173
|
+
scheduler: createLoadScheduler(),
|
|
174
|
+
telemetryBus: runtime.debug.bus,
|
|
175
|
+
});
|
|
176
|
+
const result: LoadResult = {
|
|
177
|
+
documentId,
|
|
178
|
+
bytes: byteLength,
|
|
179
|
+
readOnly: loaded.readOnly,
|
|
180
|
+
embeddedDocumentsCount: loaded.embeddedDocumentManifests?.length ?? 0,
|
|
181
|
+
snapshot: loaded.initialSnapshot,
|
|
182
|
+
status: loaded.fatalError ? "fatal" : "loaded",
|
|
183
|
+
...(loaded.fatalError ? { fatalError: loaded.fatalError } : {}),
|
|
184
|
+
};
|
|
185
|
+
emitUxResponse(runtime, {
|
|
186
|
+
apiFn: loadMetadata.name,
|
|
187
|
+
intent: loadMetadata.uxIntent.expectedDelta ?? "",
|
|
188
|
+
mockOrLive: "live",
|
|
189
|
+
uiVisible: true,
|
|
190
|
+
expectedDelta: loadMetadata.uxIntent.expectedDelta,
|
|
191
|
+
actualDelta: {
|
|
192
|
+
kind: "surface-refresh",
|
|
193
|
+
payload: { documentId: result.documentId, bytes: result.bytes, status: result.status },
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
return result;
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
async export(options?: ExportDocxOptions): Promise<ExportResult> {
|
|
200
|
+
// @endStateApi — live. Delegates to the shipped runtime export path.
|
|
201
|
+
const result = await runtime.exportDocx(options);
|
|
202
|
+
emitUxResponse(runtime, {
|
|
203
|
+
apiFn: exportMetadata.name,
|
|
204
|
+
intent: exportMetadata.uxIntent.expectedDelta ?? "",
|
|
205
|
+
mockOrLive: "live",
|
|
206
|
+
uiVisible: true,
|
|
207
|
+
expectedDelta: exportMetadata.uxIntent.expectedDelta,
|
|
208
|
+
actualDelta: { kind: "toast", payload: { bytes: result.bytes?.byteLength ?? 0 } },
|
|
209
|
+
});
|
|
210
|
+
return result;
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
validate(): ValidateResult & Partial<MockPayload> {
|
|
214
|
+
// @endStateApi — live-with-adapter. Composes three shipped runtime
|
|
215
|
+
// reads into a bundled ValidateResult:
|
|
216
|
+
// - getCompatibilityReport() for blockExport + counts + feature entries
|
|
217
|
+
// (with getRenderSnapshot().compatibility as a secondary fallback)
|
|
218
|
+
// - getWarnings() augments the warning count with runtime-emitted ones
|
|
219
|
+
// - getInteractionGuardSnapshot() for mode + readOnly
|
|
220
|
+
// Falls back to a mock-flagged shape only when both the compat read
|
|
221
|
+
// and the guard read are unavailable (e.g. pre-mount). The adapter
|
|
222
|
+
// promotes to `live` when a first-class runtime.validate() surfaces.
|
|
223
|
+
const report = runtime.getCompatibilityReport() as
|
|
224
|
+
| {
|
|
225
|
+
blockExport?: boolean;
|
|
226
|
+
warningCount?: number;
|
|
227
|
+
errorCount?: number;
|
|
228
|
+
featureEntries?: ReadonlyArray<unknown>;
|
|
229
|
+
}
|
|
230
|
+
| undefined
|
|
231
|
+
| null;
|
|
232
|
+
const snapshotCompat = runtime.getRenderSnapshot().compatibility;
|
|
233
|
+
const bundledReport = report ?? snapshotCompat;
|
|
234
|
+
const warnings = runtime.getWarnings();
|
|
235
|
+
const guard = runtime.getInteractionGuardSnapshot() as
|
|
236
|
+
| { mode?: string; readOnly?: boolean }
|
|
237
|
+
| undefined
|
|
238
|
+
| null;
|
|
239
|
+
if (!bundledReport && !guard) {
|
|
240
|
+
const fallback = mockPayload(
|
|
241
|
+
"no compatibility report or interaction guard available (pre-mount or test double)",
|
|
242
|
+
"ValidateResult",
|
|
243
|
+
{
|
|
244
|
+
reportVersion: "compatibility-report/1" as const,
|
|
245
|
+
blockExport: false,
|
|
246
|
+
warningCount: 0,
|
|
247
|
+
errorCount: 0,
|
|
248
|
+
featureEntriesCount: 0,
|
|
249
|
+
interactionGuard: { mode: "unknown", readOnly: false },
|
|
250
|
+
},
|
|
251
|
+
);
|
|
252
|
+
emitUxResponse(runtime, {
|
|
253
|
+
apiFn: validateMetadata.name,
|
|
254
|
+
intent: validateMetadata.uxIntent.expectedDelta ?? "",
|
|
255
|
+
mockOrLive: "mock",
|
|
256
|
+
uiVisible: true,
|
|
257
|
+
expectedDelta: validateMetadata.uxIntent.expectedDelta,
|
|
258
|
+
});
|
|
259
|
+
return fallback;
|
|
260
|
+
}
|
|
261
|
+
const result: ValidateResult = {
|
|
262
|
+
reportVersion: "compatibility-report/1",
|
|
263
|
+
blockExport: bundledReport?.blockExport ?? false,
|
|
264
|
+
warningCount: (bundledReport?.warningCount ?? 0) + warnings.length,
|
|
265
|
+
errorCount: bundledReport?.errorCount ?? 0,
|
|
266
|
+
featureEntriesCount: bundledReport?.featureEntries?.length ?? 0,
|
|
267
|
+
interactionGuard: {
|
|
268
|
+
mode: guard?.mode ?? "unknown",
|
|
269
|
+
readOnly: guard?.readOnly ?? false,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
emitUxResponse(runtime, {
|
|
273
|
+
apiFn: validateMetadata.name,
|
|
274
|
+
intent: validateMetadata.uxIntent.expectedDelta ?? "",
|
|
275
|
+
mockOrLive: "live-with-adapter",
|
|
276
|
+
uiVisible: true,
|
|
277
|
+
expectedDelta: validateMetadata.uxIntent.expectedDelta,
|
|
278
|
+
});
|
|
279
|
+
return result;
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — `runtime.formatting` family.
|
|
3
|
+
*
|
|
4
|
+
* getEffective (live) / resolveRunWithProvenance (live). Adapter delegates
|
|
5
|
+
* to Layer-03's `resolveEffectiveFormatting` façade + `FormattingContext`
|
|
6
|
+
* provenance path. No new logic lives here — the adapter only routes
|
|
7
|
+
* nodeRefs from the public API surface to the already-shipped L03 entry
|
|
8
|
+
* points.
|
|
9
|
+
*
|
|
10
|
+
* Cross-layer-coord reference: `docs/plans/cross-layer-coord-03.md` §2
|
|
11
|
+
* (L07 runtime.formatting.* public surface).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
15
|
+
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
16
|
+
import {
|
|
17
|
+
resolveEffectiveFormatting,
|
|
18
|
+
createFormattingContext,
|
|
19
|
+
type EffectiveFormatting,
|
|
20
|
+
type RunProvenance,
|
|
21
|
+
} from "../../../runtime/formatting/index.ts";
|
|
22
|
+
import {
|
|
23
|
+
findParagraphByBlockId,
|
|
24
|
+
resolveDirectRunFormattingAtSegment,
|
|
25
|
+
} from "../../../runtime/formatting/document-lookup.ts";
|
|
26
|
+
import type { RuntimeTelemetryEvent } from "../../../runtime/debug/types.ts";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Public nodeRef shape for `runtime.formatting.getEffective`. Structurally
|
|
30
|
+
* a subset of L03's internal `NodeRef` — the `field` kind's optional
|
|
31
|
+
* `pageGraph` is omitted from the public surface because threading the
|
|
32
|
+
* layout page-graph through is a separate integration tracked in the
|
|
33
|
+
* cross-layer-coord doc. Callers passing `{ kind: "field", ... }` get a
|
|
34
|
+
* `refreshStatus: "unresolved"` result, which is honest for now.
|
|
35
|
+
*/
|
|
36
|
+
export type FormattingNodeRef =
|
|
37
|
+
| { readonly kind: "paragraph"; readonly blockId: string }
|
|
38
|
+
| { readonly kind: "run"; readonly blockId: string; readonly runId: string }
|
|
39
|
+
| { readonly kind: "table"; readonly blockId: string }
|
|
40
|
+
| {
|
|
41
|
+
readonly kind: "table-cell";
|
|
42
|
+
readonly blockId: string;
|
|
43
|
+
readonly rowIndex: number;
|
|
44
|
+
readonly cellIndex: number;
|
|
45
|
+
}
|
|
46
|
+
| { readonly kind: "field"; readonly blockId: string; readonly runId: string }
|
|
47
|
+
| {
|
|
48
|
+
readonly kind: "drawing-frame";
|
|
49
|
+
readonly blockId: string;
|
|
50
|
+
readonly inlineId: string;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export interface FormattingGetEffectiveOpts {
|
|
54
|
+
readonly revisionMarkupMode?: "clean" | "simple" | "all";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const getEffectiveMetadata: ApiV3FnMetadata = {
|
|
58
|
+
name: "runtime.formatting.getEffective",
|
|
59
|
+
status: "live",
|
|
60
|
+
sourceLayer: "formatting-semantics",
|
|
61
|
+
// Direct delegation to `resolveEffectiveFormatting` — the Layer-03
|
|
62
|
+
// external façade. L03's cascade-parity + entry-delegation tests prove
|
|
63
|
+
// behavioral parity with the production hot path (`FormattingContext`).
|
|
64
|
+
liveEvidence: {
|
|
65
|
+
runnerTest:
|
|
66
|
+
"test/runtime/formatting/entry-delegation.test.ts,test/runtime/formatting/cascade-parity.test.ts,test/api/v3/runtime/formatting-adapter.test.ts",
|
|
67
|
+
commit: "refactor-03-runtime-formatting-adapter-2026-04-22",
|
|
68
|
+
},
|
|
69
|
+
// State-classes (Slice X2, f6051c07). Formatting output is derived
|
|
70
|
+
// from the canonical document (styles + revisions + theme etc.); it
|
|
71
|
+
// lives in the canonical tree and has no session-shared or local-pref
|
|
72
|
+
// surface. Derived read → no broadcastsVia.
|
|
73
|
+
stateClass: "A-canonical",
|
|
74
|
+
persistsTo: "canonical",
|
|
75
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
76
|
+
agentMetadata: {
|
|
77
|
+
readOrMutate: "read",
|
|
78
|
+
boundedScope: "scope",
|
|
79
|
+
auditCategory: "formatting-read",
|
|
80
|
+
},
|
|
81
|
+
rwdReference:
|
|
82
|
+
"§Runtime API § runtime.formatting.getEffective. Adapter over Layer-03's resolveEffectiveFormatting façade — same code path the production hot path (FormattingContext) exercises.",
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const subscribeTelemetryMetadata: ApiV3FnMetadata = {
|
|
86
|
+
name: "runtime.formatting.subscribeTelemetry",
|
|
87
|
+
status: "live",
|
|
88
|
+
sourceLayer: "formatting-semantics",
|
|
89
|
+
liveEvidence: {
|
|
90
|
+
runnerTest: "test/api/v3/runtime/formatting-adapter.test.ts",
|
|
91
|
+
commit: "refactor-07-coord-03-formatting-subscribe-2026-04-22",
|
|
92
|
+
},
|
|
93
|
+
// Derived from canonical document (cascade resolution). Subscribe is
|
|
94
|
+
// a pass-through to the telemetry bus's `formatting` channel —
|
|
95
|
+
// consumers observe cache-miss / cascade-resolve events without
|
|
96
|
+
// importing the bus directly. The channel itself exists on the bus;
|
|
97
|
+
// L07 owns the v3 surface that gates access to it per the R-exposed
|
|
98
|
+
// patterns.
|
|
99
|
+
stateClass: "A-canonical",
|
|
100
|
+
persistsTo: "canonical",
|
|
101
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
102
|
+
agentMetadata: {
|
|
103
|
+
readOrMutate: "read",
|
|
104
|
+
boundedScope: "document",
|
|
105
|
+
auditCategory: "formatting-subscribe",
|
|
106
|
+
},
|
|
107
|
+
rwdReference:
|
|
108
|
+
"§Runtime API § runtime.formatting.subscribeTelemetry. Pass-through to handle.debug.bus — enables the 'formatting' channel and forwards events to the listener. Returned closure unsubscribes. Used by L10 debug pane + agent-facing observers without reaching into the bus module directly.",
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const resolveRunWithProvenanceMetadata: ApiV3FnMetadata = {
|
|
112
|
+
name: "runtime.formatting.resolveRunWithProvenance",
|
|
113
|
+
status: "live",
|
|
114
|
+
sourceLayer: "formatting-semantics",
|
|
115
|
+
// Live delegation to FormattingContext.resolveRunWithProvenance. L03
|
|
116
|
+
// provenance test pins the per-field source map across the four
|
|
117
|
+
// cascade tiers (direct / characterStyle / style / docDefaults).
|
|
118
|
+
liveEvidence: {
|
|
119
|
+
runnerTest:
|
|
120
|
+
"test/runtime/formatting/provenance.test.ts,test/api/v3/runtime/formatting-adapter.test.ts",
|
|
121
|
+
commit: "refactor-03-runtime-formatting-adapter-2026-04-22",
|
|
122
|
+
},
|
|
123
|
+
stateClass: "A-canonical",
|
|
124
|
+
persistsTo: "canonical",
|
|
125
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
126
|
+
agentMetadata: {
|
|
127
|
+
readOrMutate: "read",
|
|
128
|
+
boundedScope: "scope",
|
|
129
|
+
auditCategory: "formatting-read",
|
|
130
|
+
},
|
|
131
|
+
rwdReference:
|
|
132
|
+
"§Runtime API § runtime.formatting.resolveRunWithProvenance. Agent-facing provenance view — `source ∈ {direct, characterStyle, style, docDefaults}` plus `sourceId` for style tiers. Substrate for ai.explainFormatting (L09).",
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export function createFormattingFamily(runtime: RuntimeApiHandle) {
|
|
136
|
+
return {
|
|
137
|
+
getEffective(
|
|
138
|
+
nodeRef: FormattingNodeRef,
|
|
139
|
+
opts?: FormattingGetEffectiveOpts,
|
|
140
|
+
): EffectiveFormatting {
|
|
141
|
+
// @endStateApi — live. Delegates to L03's external façade against
|
|
142
|
+
// the current canonical document. Read-only; no side effects.
|
|
143
|
+
const doc = runtime.getCanonicalDocument();
|
|
144
|
+
return resolveEffectiveFormatting(doc, nodeRef, {
|
|
145
|
+
...(opts?.revisionMarkupMode ? { revisionMarkupMode: opts.revisionMarkupMode } : {}),
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
subscribeTelemetry(
|
|
150
|
+
channel: "formatting",
|
|
151
|
+
listener: (event: RuntimeTelemetryEvent) => void,
|
|
152
|
+
): () => void {
|
|
153
|
+
// @endStateApi — live. Pass-through to the runtime's telemetry bus.
|
|
154
|
+
// Enables the channel if it's off (otherwise the subscription
|
|
155
|
+
// attaches but never fires). Returns the bus's own unsubscribe
|
|
156
|
+
// closure — callers must retain + invoke it.
|
|
157
|
+
const bus = runtime.debug.bus;
|
|
158
|
+
if (!bus.isEnabled(channel)) {
|
|
159
|
+
bus.enable(channel);
|
|
160
|
+
}
|
|
161
|
+
return bus.subscribe([channel], listener);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
resolveRunWithProvenance(input: {
|
|
165
|
+
readonly blockId: string;
|
|
166
|
+
readonly runId: string;
|
|
167
|
+
}): RunProvenance | null {
|
|
168
|
+
// @endStateApi — live. Looks up the canonical paragraph + inline
|
|
169
|
+
// at (blockId, runId), then calls FormattingContext.resolveRun
|
|
170
|
+
// WithProvenance to get the { run, properties } map. Returns null
|
|
171
|
+
// when the lookup misses (unknown blockId or segment out of range)
|
|
172
|
+
// — callers differentiate that from a real resolution with no
|
|
173
|
+
// populated fields.
|
|
174
|
+
const doc = runtime.getCanonicalDocument();
|
|
175
|
+
const foundPara = findParagraphByBlockId(doc, input.blockId);
|
|
176
|
+
if (!foundPara) return null;
|
|
177
|
+
const direct = resolveDirectRunFormattingAtSegment(foundPara.paragraph, input.runId);
|
|
178
|
+
const ctx = createFormattingContext(doc);
|
|
179
|
+
return ctx.resolveRunWithProvenance({
|
|
180
|
+
paragraphStyleId: foundPara.paragraph.styleId,
|
|
181
|
+
characterStyleId: direct?.characterStyleId,
|
|
182
|
+
direct,
|
|
183
|
+
});
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|