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