@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,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope-compiler debug projector — Slice 1.
|
|
3
|
+
*
|
|
4
|
+
* Given a compiled `SemanticScope`, produce a `ScopeCompilerDebugEntry` that
|
|
5
|
+
* summarises which projection fields carry data. Intended for consumption
|
|
6
|
+
* from `DebugInspectorSnapshot.scopes.compilerView` (the snapshot-side
|
|
7
|
+
* wiring lands in a cross-surface follow-up commit; Slice 1 ships the
|
|
8
|
+
* producer in isolation so runtime code can consume it without a circular
|
|
9
|
+
* edit against `src/runtime/debug/types.ts`).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
ScopeCompilerDebugEntry,
|
|
14
|
+
SemanticScope,
|
|
15
|
+
} from "./semantic-scope-types.ts";
|
|
16
|
+
|
|
17
|
+
export interface ProjectScopeOptions {
|
|
18
|
+
readonly nowUtc: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function hasValue(obj: object): boolean {
|
|
22
|
+
for (const key in obj) {
|
|
23
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
24
|
+
const v = (obj as Record<string, unknown>)[key];
|
|
25
|
+
if (v !== undefined) return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function projectScopeDebugEntry(
|
|
32
|
+
scope: SemanticScope,
|
|
33
|
+
options: ProjectScopeOptions,
|
|
34
|
+
): ScopeCompilerDebugEntry {
|
|
35
|
+
return {
|
|
36
|
+
scopeId: scope.handle.scopeId,
|
|
37
|
+
kind: scope.kind,
|
|
38
|
+
provenance: scope.handle.provenance,
|
|
39
|
+
partial: scope.partial === true,
|
|
40
|
+
projectionFields: {
|
|
41
|
+
content: scope.content.text.length > 0,
|
|
42
|
+
formatting: hasValue(scope.formatting),
|
|
43
|
+
layout: hasValue(scope.layout),
|
|
44
|
+
geometry: hasValue(scope.geometry),
|
|
45
|
+
workflow: scope.workflow.scopeIds.length > 0,
|
|
46
|
+
},
|
|
47
|
+
compiledAtUtc: options.nowUtc,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replaceability — structural + provenance driven.
|
|
3
|
+
*
|
|
4
|
+
* Returns a `{ level, reason }` pair purely from the scope's kind +
|
|
5
|
+
* provenance — no vertical vocabulary. Domain-specific replacement
|
|
6
|
+
* constraints (e.g. "a legal clause must preserve its defined terms
|
|
7
|
+
* section") are host policy concerns surfaced via the workflow overlay,
|
|
8
|
+
* NOT hardcoded into the compiler.
|
|
9
|
+
*
|
|
10
|
+
* The key structural rule: **marker-backed scopes default to `text-only`**
|
|
11
|
+
* because replacing beyond the marker boundaries would destroy the
|
|
12
|
+
* markers themselves. That applies uniformly whether the marker is a
|
|
13
|
+
* CLM clause, a compliance annotation, or any other host-defined
|
|
14
|
+
* semantic region.
|
|
15
|
+
*
|
|
16
|
+
* Slice 4's `composeScopeValidation` composes this baseline with
|
|
17
|
+
* workflow guard + preservation + compatibility + AI policy at
|
|
18
|
+
* validate-time; the replaceability field here is the static baseline
|
|
19
|
+
* consumers read from the compiled scope.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type {
|
|
23
|
+
Replaceability,
|
|
24
|
+
SemanticScopeKind,
|
|
25
|
+
ScopeProvenance,
|
|
26
|
+
} from "./semantic-scope-types.ts";
|
|
27
|
+
|
|
28
|
+
export function deriveReplaceability(
|
|
29
|
+
kind: SemanticScopeKind,
|
|
30
|
+
provenance: ScopeProvenance,
|
|
31
|
+
): Replaceability {
|
|
32
|
+
if (provenance === "detached") {
|
|
33
|
+
return {
|
|
34
|
+
level: "blocked",
|
|
35
|
+
reason: "scope-detached-requires-rebind",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Marker-backed paragraph-like scopes — the marker pair brackets the
|
|
39
|
+
// scope's identity; a full replace would destroy the markers.
|
|
40
|
+
// Text-only replacement preserves them.
|
|
41
|
+
if (
|
|
42
|
+
provenance === "marker-backed" &&
|
|
43
|
+
(kind === "paragraph" || kind === "heading" || kind === "list-item")
|
|
44
|
+
) {
|
|
45
|
+
return {
|
|
46
|
+
level: "text-only",
|
|
47
|
+
reason: "marker-backed-preserves-anchor",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
switch (kind) {
|
|
51
|
+
case "paragraph":
|
|
52
|
+
return { level: "full", reason: "derived-default" };
|
|
53
|
+
case "heading":
|
|
54
|
+
return { level: "text-only", reason: "heading-preserves-outline" };
|
|
55
|
+
case "list-item":
|
|
56
|
+
return { level: "text-only", reason: "list-item-preserves-numbering" };
|
|
57
|
+
case "table-cell":
|
|
58
|
+
return { level: "text-only", reason: "table-cell-preserves-structure" };
|
|
59
|
+
case "table":
|
|
60
|
+
return {
|
|
61
|
+
level: "blocked",
|
|
62
|
+
reason: "table-replacement-not-yet-implemented",
|
|
63
|
+
};
|
|
64
|
+
case "table-row":
|
|
65
|
+
return {
|
|
66
|
+
level: "blocked",
|
|
67
|
+
reason: "table-row-replacement-not-yet-implemented",
|
|
68
|
+
};
|
|
69
|
+
case "field":
|
|
70
|
+
return {
|
|
71
|
+
level: "preserve-only",
|
|
72
|
+
reason: "field-result-is-computed-preserve-only",
|
|
73
|
+
};
|
|
74
|
+
case "comment-thread":
|
|
75
|
+
return {
|
|
76
|
+
level: "preserve-only",
|
|
77
|
+
reason: "comment-thread-is-review-artifact",
|
|
78
|
+
};
|
|
79
|
+
case "revision":
|
|
80
|
+
return {
|
|
81
|
+
level: "preserve-only",
|
|
82
|
+
reason: "revision-open-preserve-only",
|
|
83
|
+
};
|
|
84
|
+
default:
|
|
85
|
+
return { level: "blocked", reason: "kind-not-yet-implemented" };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 5 — replacement apply pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Composition (honouring §7 of the Slice-5 handover):
|
|
5
|
+
* 1. Re-resolve + re-compile the target scope against live state.
|
|
6
|
+
* 2. Re-run `composeScopeValidation` — never trust a propose-time
|
|
7
|
+
* verdict; Yjs remote or local edits may have moved since propose.
|
|
8
|
+
* 3. When `validation.safe === false`, refuse with a typed result and
|
|
9
|
+
* do NOT dispatch anything.
|
|
10
|
+
* 4. Compile the per-kind `RuntimeOperationPlan` (no-op kinds land as
|
|
11
|
+
* `compile-refused:<kind>` blockers).
|
|
12
|
+
* 5. Dispatch through `runtimeSink.applyScopeReplacement(plan)`.
|
|
13
|
+
* 6. Emit exactly one `ScopeActionAudit` on the `scope` telemetry
|
|
14
|
+
* channel (S5).
|
|
15
|
+
*
|
|
16
|
+
* The "runtimeSink" parameter is a narrow interface rather than
|
|
17
|
+
* `DocumentRuntime` so the apply pipeline stays testable and doesn't
|
|
18
|
+
* drag the full runtime surface into the compiler.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { TelemetryBus } from "../../debug/telemetry-bus.ts";
|
|
22
|
+
import type { AIAction } from "../../workflow/ai-action-policy.ts";
|
|
23
|
+
import type {
|
|
24
|
+
CompatibilityReport,
|
|
25
|
+
InteractionGuardSnapshot,
|
|
26
|
+
WorkflowOverlay,
|
|
27
|
+
} from "../_scope-dependencies.ts";
|
|
28
|
+
import type { CanonicalDocumentEnvelope } from "../../../core/state/editor-state.ts";
|
|
29
|
+
|
|
30
|
+
import { composeScopeValidation } from "../action-validation.ts";
|
|
31
|
+
import { buildParagraphIndexMap, compileScope } from "../compile-scope.ts";
|
|
32
|
+
import { enumerateScopes } from "../enumerate-scopes.ts";
|
|
33
|
+
import type { EnumeratedScope } from "../enumerate-scopes.ts";
|
|
34
|
+
import { emitScopeActionAudit } from "../audit-bundle.ts";
|
|
35
|
+
import { compileReplacement } from "./compile.ts";
|
|
36
|
+
import type {
|
|
37
|
+
ReplacementScope,
|
|
38
|
+
RuntimeOperationPlan,
|
|
39
|
+
ScopeActionAudit,
|
|
40
|
+
SemanticScope,
|
|
41
|
+
ValidationResult,
|
|
42
|
+
} from "../semantic-scope-types.ts";
|
|
43
|
+
|
|
44
|
+
export interface ApplyScopeReplacementSink {
|
|
45
|
+
readonly getCanonicalDocument: () => CanonicalDocumentEnvelope;
|
|
46
|
+
readonly getWorkflowOverlay: () => WorkflowOverlay | null;
|
|
47
|
+
readonly getInteractionGuardSnapshot: () => InteractionGuardSnapshot;
|
|
48
|
+
readonly getCompatibilityReport: () => CompatibilityReport;
|
|
49
|
+
readonly applyScopeReplacement: (plan: RuntimeOperationPlan) => void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ApplyScopeReplacementInputs {
|
|
53
|
+
readonly sink: ApplyScopeReplacementSink;
|
|
54
|
+
readonly proposed: ReplacementScope;
|
|
55
|
+
readonly actionId?: AIAction;
|
|
56
|
+
readonly actorId: string;
|
|
57
|
+
readonly origin: "ui" | "agent" | "host";
|
|
58
|
+
readonly emittedAtUtc: string;
|
|
59
|
+
readonly bus?: TelemetryBus;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ApplyScopeReplacementResult {
|
|
63
|
+
readonly applied: boolean;
|
|
64
|
+
readonly reason?: string;
|
|
65
|
+
readonly validation: ValidationResult;
|
|
66
|
+
readonly audit?: ScopeActionAudit;
|
|
67
|
+
readonly plan?: RuntimeOperationPlan;
|
|
68
|
+
readonly scope?: SemanticScope;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function documentHash(doc: CanonicalDocumentEnvelope): string {
|
|
72
|
+
// Cheap structural hash — block-count + total text length. Good enough
|
|
73
|
+
// for the audit's "something changed" signal; later slices can swap in
|
|
74
|
+
// a canonical serializer-backed content hash.
|
|
75
|
+
const root = doc.content;
|
|
76
|
+
let textLength = 0;
|
|
77
|
+
for (const block of root.children) {
|
|
78
|
+
if (block.type === "paragraph") {
|
|
79
|
+
for (const child of block.children) {
|
|
80
|
+
if (child.type === "text") textLength += child.text.length;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return `blocks:${root.children.length}|text:${textLength}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function applyScopeReplacement(
|
|
88
|
+
inputs: ApplyScopeReplacementInputs,
|
|
89
|
+
): ApplyScopeReplacementResult {
|
|
90
|
+
const proposed = inputs.proposed;
|
|
91
|
+
const docBefore = inputs.sink.getCanonicalDocument();
|
|
92
|
+
const overlay = inputs.sink.getWorkflowOverlay() ?? undefined;
|
|
93
|
+
|
|
94
|
+
const paragraphIndexByBlockIndex = buildParagraphIndexMap(docBefore);
|
|
95
|
+
let resolvedScope: SemanticScope | null = null;
|
|
96
|
+
let resolvedEnumerated: EnumeratedScope | null = null;
|
|
97
|
+
const enumerateInputs = overlay ? { overlay } : {};
|
|
98
|
+
for (const entry of enumerateScopes(docBefore, enumerateInputs)) {
|
|
99
|
+
if (entry.handle.scopeId !== proposed.targetHandle.scopeId) continue;
|
|
100
|
+
const compiled = compileScope(entry, {
|
|
101
|
+
document: docBefore,
|
|
102
|
+
...(overlay ? { overlay } : {}),
|
|
103
|
+
paragraphIndexByBlockIndex,
|
|
104
|
+
});
|
|
105
|
+
if (compiled) {
|
|
106
|
+
resolvedScope = compiled;
|
|
107
|
+
resolvedEnumerated = entry;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!resolvedScope || !resolvedEnumerated) {
|
|
113
|
+
const validation: ValidationResult = {
|
|
114
|
+
safe: false,
|
|
115
|
+
blockedReasons: Object.freeze([
|
|
116
|
+
`scope-not-resolvable:${proposed.targetHandle.scopeId}`,
|
|
117
|
+
]),
|
|
118
|
+
warnings: Object.freeze([]),
|
|
119
|
+
};
|
|
120
|
+
return { applied: false, reason: "scope-not-resolvable", validation };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const verdict = composeScopeValidation({
|
|
124
|
+
scope: resolvedScope,
|
|
125
|
+
operation: proposed.operation,
|
|
126
|
+
proposedContent: proposed.proposedContent,
|
|
127
|
+
runtime: {
|
|
128
|
+
getInteractionGuardSnapshot: () => inputs.sink.getInteractionGuardSnapshot(),
|
|
129
|
+
getCompatibilityReport: () => inputs.sink.getCompatibilityReport(),
|
|
130
|
+
},
|
|
131
|
+
document: docBefore,
|
|
132
|
+
enumeratedScope: resolvedEnumerated,
|
|
133
|
+
...(inputs.actionId ? { actionId: inputs.actionId } : {}),
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
if (!verdict.safe) {
|
|
137
|
+
return {
|
|
138
|
+
applied: false,
|
|
139
|
+
reason: "validation-blocked",
|
|
140
|
+
validation: verdict,
|
|
141
|
+
scope: resolvedScope,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Suggest-mode guard: the composer tags suggest-mode sessions with a
|
|
146
|
+
// `guard:suggest-mode` warning; the apply pipeline branches the plan's
|
|
147
|
+
// posture on that signal.
|
|
148
|
+
const posture: "direct-edit" | "suggest-mode" =
|
|
149
|
+
verdict.warnings.some((w) => w.code === "guard:suggest-mode")
|
|
150
|
+
? "suggest-mode"
|
|
151
|
+
: "direct-edit";
|
|
152
|
+
|
|
153
|
+
const plan = compileReplacement({
|
|
154
|
+
scope: resolvedScope,
|
|
155
|
+
enumeratedScope: resolvedEnumerated,
|
|
156
|
+
proposed,
|
|
157
|
+
document: docBefore,
|
|
158
|
+
posture,
|
|
159
|
+
});
|
|
160
|
+
if (!plan) {
|
|
161
|
+
// Coord-08 §10 — disambiguate the refusal taxonomy. A `null` plan
|
|
162
|
+
// has two distinct causes that callers (especially CLM agents)
|
|
163
|
+
// treat differently:
|
|
164
|
+
//
|
|
165
|
+
// (A) The scope kind dispatches nothing at all (e.g. table-cell
|
|
166
|
+
// has no flat-range text-replace lowering). Bare suffix:
|
|
167
|
+
// `compile-refused:<kind>`. Caller must fall back to
|
|
168
|
+
// `attach_explanation`.
|
|
169
|
+
// (B) The scope kind IS dispatched but the requested operation
|
|
170
|
+
// variant is not implemented on that kind (e.g. paragraph +
|
|
171
|
+
// "insert-before" — only "replace" is wired). Suffix:
|
|
172
|
+
// `compile-refused:<kind>:operation-not-implemented:<op>`.
|
|
173
|
+
// Caller can potentially retry with `operation: "replace"`.
|
|
174
|
+
//
|
|
175
|
+
// We can disambiguate on paragraph-like kinds without introspecting
|
|
176
|
+
// the compiler because we know the operation is the only
|
|
177
|
+
// non-"replace" refusal arm there. Other kinds (table-cell, field,
|
|
178
|
+
// …) may reintroduce this disambiguation when they gain per-op
|
|
179
|
+
// branching.
|
|
180
|
+
const paragraphLike =
|
|
181
|
+
resolvedScope.kind === "paragraph" ||
|
|
182
|
+
resolvedScope.kind === "heading" ||
|
|
183
|
+
resolvedScope.kind === "list-item";
|
|
184
|
+
const blocker =
|
|
185
|
+
paragraphLike && proposed.operation !== "replace"
|
|
186
|
+
? `compile-refused:${resolvedScope.kind}:operation-not-implemented:${proposed.operation}`
|
|
187
|
+
: `compile-refused:${resolvedScope.kind}`;
|
|
188
|
+
const refused: ValidationResult = {
|
|
189
|
+
safe: false,
|
|
190
|
+
blockedReasons: Object.freeze([blocker]),
|
|
191
|
+
warnings: verdict.warnings,
|
|
192
|
+
};
|
|
193
|
+
return {
|
|
194
|
+
applied: false,
|
|
195
|
+
reason: "compile-refused",
|
|
196
|
+
validation: refused,
|
|
197
|
+
scope: resolvedScope,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const documentHashBefore = documentHash(docBefore);
|
|
202
|
+
|
|
203
|
+
inputs.sink.applyScopeReplacement(plan);
|
|
204
|
+
|
|
205
|
+
const documentHashAfter = documentHash(inputs.sink.getCanonicalDocument());
|
|
206
|
+
|
|
207
|
+
const audit = emitScopeActionAudit({
|
|
208
|
+
actionId: inputs.actionId ?? "replacement",
|
|
209
|
+
actorId: inputs.actorId,
|
|
210
|
+
origin: inputs.origin,
|
|
211
|
+
documentHashBefore,
|
|
212
|
+
documentHashAfter,
|
|
213
|
+
targetScopeSnapshot: resolvedScope,
|
|
214
|
+
proposed,
|
|
215
|
+
plan,
|
|
216
|
+
validation: verdict,
|
|
217
|
+
emittedAtUtc: inputs.emittedAtUtc,
|
|
218
|
+
...(inputs.bus ? { bus: inputs.bus } : {}),
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
applied: true,
|
|
223
|
+
validation: verdict,
|
|
224
|
+
audit,
|
|
225
|
+
plan,
|
|
226
|
+
scope: resolvedScope,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 5 — replacement compilation dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* Lowers a `ReplacementScope` proposal against a compiled
|
|
5
|
+
* `SemanticScope` into a `RuntimeOperationPlan` that the runtime's
|
|
6
|
+
* `applyScopeReplacement(plan)` can dispatch. Each scope-kind owns its
|
|
7
|
+
* own lowering (`compile<Kind>Replacement`); this dispatcher routes on
|
|
8
|
+
* `scope.kind`. Unknown or unsupported kinds return `null` — the apply
|
|
9
|
+
* pipeline surfaces that as a `compile-refused:<kind>` blocker.
|
|
10
|
+
*
|
|
11
|
+
* S3 determinism: pure function of (enumerated scope, proposed, document,
|
|
12
|
+
* posture). No clock, no random.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { CanonicalDocumentEnvelope } from "../../../core/state/editor-state.ts";
|
|
16
|
+
import type { EnumeratedScope } from "../enumerate-scopes.ts";
|
|
17
|
+
import type {
|
|
18
|
+
ReplacementScope,
|
|
19
|
+
RuntimeOperationPlan,
|
|
20
|
+
SemanticScope,
|
|
21
|
+
} from "../semantic-scope-types.ts";
|
|
22
|
+
import { compileParagraphReplacement } from "../scope-kinds/paragraph.ts";
|
|
23
|
+
|
|
24
|
+
export interface CompileReplacementInputs {
|
|
25
|
+
readonly scope: SemanticScope;
|
|
26
|
+
readonly enumeratedScope: EnumeratedScope;
|
|
27
|
+
readonly proposed: ReplacementScope;
|
|
28
|
+
readonly document: CanonicalDocumentEnvelope;
|
|
29
|
+
readonly posture: "direct-edit" | "suggest-mode";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function compileReplacement(
|
|
33
|
+
inputs: CompileReplacementInputs,
|
|
34
|
+
): RuntimeOperationPlan | null {
|
|
35
|
+
switch (inputs.scope.kind) {
|
|
36
|
+
case "paragraph":
|
|
37
|
+
case "heading":
|
|
38
|
+
case "list-item": {
|
|
39
|
+
// Paragraph-like kinds all delegate to the paragraph replacement
|
|
40
|
+
// compiler — the canonical block range projection is the same.
|
|
41
|
+
if (
|
|
42
|
+
inputs.enumeratedScope.kind === "paragraph" ||
|
|
43
|
+
inputs.enumeratedScope.kind === "heading" ||
|
|
44
|
+
inputs.enumeratedScope.kind === "list-item"
|
|
45
|
+
) {
|
|
46
|
+
return compileParagraphReplacement(inputs.enumeratedScope, inputs.proposed, {
|
|
47
|
+
document: inputs.document,
|
|
48
|
+
posture: inputs.posture,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
// Other kinds land in follow-up steps of Slice 5 (structured,
|
|
55
|
+
// table-cell, field inline, …). Returning null lets `apply` surface
|
|
56
|
+
// a typed `compile-refused:<kind>` blocker.
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 5 — replacement proposal.
|
|
3
|
+
*
|
|
4
|
+
* Projects a caller-shaped proposal (targetScopeId + operation +
|
|
5
|
+
* proposed content) into the compiler's `ReplacementScope` plain value.
|
|
6
|
+
* Pure: no runtime lookup, no document read — the proposed `ScopeHandle`
|
|
7
|
+
* is supplied by the caller (who has already resolved it).
|
|
8
|
+
*
|
|
9
|
+
* Slice-5 note: the `proposedAtUtc` field is caller-supplied rather than
|
|
10
|
+
* generated here so the compiler stays deterministic (S3). Callers with
|
|
11
|
+
* a clock should pass their clock reading; callers without one pass the
|
|
12
|
+
* reference instant they want audited.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type {
|
|
16
|
+
ReplacementOperationKind,
|
|
17
|
+
ReplacementPreservePolicy,
|
|
18
|
+
ReplacementScope,
|
|
19
|
+
ScopeHandle,
|
|
20
|
+
} from "../semantic-scope-types.ts";
|
|
21
|
+
|
|
22
|
+
export interface ReplacementProposalInput {
|
|
23
|
+
readonly targetHandle: ScopeHandle;
|
|
24
|
+
readonly operation: ReplacementOperationKind;
|
|
25
|
+
readonly proposedContent: ReplacementScope["proposedContent"];
|
|
26
|
+
readonly preserve?: ReplacementPreservePolicy;
|
|
27
|
+
readonly reason?: string;
|
|
28
|
+
readonly proposedAtUtc: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function proposeReplacement(
|
|
32
|
+
input: ReplacementProposalInput,
|
|
33
|
+
): ReplacementScope {
|
|
34
|
+
return {
|
|
35
|
+
targetHandle: input.targetHandle,
|
|
36
|
+
operation: input.operation,
|
|
37
|
+
proposedContent: input.proposedContent,
|
|
38
|
+
...(input.preserve ? { preserve: input.preserve } : {}),
|
|
39
|
+
...(input.reason ? { reason: input.reason } : {}),
|
|
40
|
+
proposedAtUtc: input.proposedAtUtc,
|
|
41
|
+
};
|
|
42
|
+
}
|