@beyondwork/docx-react-component 1.0.66 → 1.0.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -931
- package/package.json +26 -27
- package/src/api/anchor-conversion.ts +43 -0
- package/src/api/editor-state-types.ts +2 -1
- package/src/api/public-types.ts +504 -101
- package/src/api/session-state.ts +4 -0
- package/src/api/v3/README.md +91 -0
- package/src/api/v3/_create.ts +146 -0
- package/src/api/v3/_layer-metadata.ts +362 -0
- package/src/api/v3/_mocks.ts +84 -0
- package/src/api/v3/_runtime-handle.ts +162 -0
- package/src/api/v3/_ux-response.ts +73 -0
- package/src/api/v3/ai/_metadata-audit.ts +225 -0
- package/src/api/v3/ai/attach.ts +235 -0
- package/src/api/v3/ai/bundle.ts +132 -0
- package/src/api/v3/ai/explain.ts +144 -0
- package/src/api/v3/ai/export.ts +54 -0
- package/src/api/v3/ai/inspect.ts +118 -0
- package/src/api/v3/ai/policy.ts +77 -0
- package/src/api/v3/ai/replacement.ts +341 -0
- package/src/api/v3/ai/resolve.ts +133 -0
- package/src/api/v3/index.ts +79 -0
- package/src/api/v3/runtime/chart.ts +310 -0
- package/src/api/v3/runtime/clipboard.ts +81 -0
- package/src/api/v3/runtime/collab.ts +331 -0
- package/src/api/v3/runtime/content.ts +236 -0
- package/src/api/v3/runtime/document.ts +282 -0
- package/src/api/v3/runtime/formatting.ts +186 -0
- package/src/api/v3/runtime/geometry.ts +349 -0
- package/src/api/v3/runtime/layout.ts +108 -0
- package/src/api/v3/runtime/review.ts +129 -0
- package/src/api/v3/runtime/search.ts +74 -0
- package/src/api/v3/runtime/table.ts +63 -0
- package/src/api/v3/runtime/workflow.ts +434 -0
- package/src/api/v3/ui/_context.ts +86 -0
- package/src/api/v3/ui/_create.ts +65 -0
- package/src/api/v3/ui/_types.ts +520 -0
- package/src/api/v3/ui/chrome-composition.ts +342 -0
- package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
- package/src/api/v3/ui/chrome.ts +476 -0
- package/src/api/v3/ui/debug.ts +124 -0
- package/src/api/v3/ui/index.ts +64 -0
- package/src/api/v3/ui/overlays-visibility.ts +170 -0
- package/src/api/v3/ui/overlays.ts +427 -0
- package/src/api/v3/ui/scope.ts +71 -0
- package/src/api/v3/ui/session.ts +100 -0
- package/src/api/v3/ui/surface.ts +170 -0
- package/src/api/v3/ui/viewport.ts +303 -0
- package/src/core/commands/index.ts +28 -6
- package/src/core/commands/list-commands.ts +3 -2
- package/src/core/commands/section-layout-commands.ts +9 -8
- package/src/core/schema/text-schema.ts +16 -0
- package/src/core/selection/mapping.ts +33 -72
- package/src/core/state/editor-state.ts +96 -189
- package/src/index.ts +23 -4
- package/src/io/chart-preview-resolver.ts +1 -1
- package/src/io/docx-session.ts +36 -4795
- package/src/io/export/build-app-properties-xml.ts +1 -1
- package/src/io/export/serialize-comments.ts +1 -1
- package/src/io/export/serialize-headers-footers.ts +6 -1
- package/src/io/export/serialize-main-document.ts +45 -0
- package/src/io/export/serialize-run-formatting.ts +17 -2
- package/src/io/export/twip.ts +1 -1
- package/src/io/normalize/normalize-text.ts +27 -20
- package/src/io/ooxml/chart/parse-series.ts +1 -1
- package/src/io/ooxml/chart/resolve-color.ts +2 -2
- package/src/io/ooxml/chart/types.ts +1 -1
- package/src/io/ooxml/classify-embedding.ts +83 -33
- package/src/io/ooxml/parse-fill.ts +1 -1
- package/src/io/ooxml/parse-main-document.ts +71 -1
- package/src/io/ooxml/parse-object.ts +14 -10
- package/src/io/ooxml/parse-run-formatting.ts +47 -1
- package/src/io/ooxml/property-grab-bag.ts +2 -2
- package/src/io/ooxml/units.ts +11 -0
- package/src/io/ooxml/workflow-payload.ts +282 -7
- package/src/model/anchor.ts +85 -0
- package/src/model/canonical-document.ts +351 -15
- package/src/model/chart-types.ts +1 -1
- package/src/model/layout/index.ts +83 -0
- package/src/model/layout/page-graph-types.ts +181 -0
- package/src/model/layout/page-layout-snapshot.ts +105 -0
- package/src/model/layout/resolved-layout-types.ts +47 -0
- package/src/model/layout/runtime-page-graph-types.ts +102 -0
- package/src/model/paragraph-scope-ids.ts +72 -0
- package/src/model/review/comment-types.ts +112 -0
- package/src/model/review/index.ts +2 -0
- package/src/model/review/revision-types.ts +215 -0
- package/src/model/snapshot.ts +32 -0
- package/src/review/store/comment-store.ts +21 -47
- package/src/review/store/revision-types.ts +40 -198
- package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
- package/src/runtime/collab/runtime-collab-sync.ts +13 -3
- package/src/runtime/collab-session.ts +1 -1
- package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
- package/src/runtime/debug/event-ring-buffer.ts +64 -0
- package/src/runtime/debug/probability-sampler.ts +18 -0
- package/src/runtime/debug/runtime-debug-facet.ts +67 -0
- package/src/runtime/debug/stage-tokens.ts +31 -0
- package/src/runtime/debug/telemetry-bus.ts +271 -0
- package/src/runtime/debug/types.ts +275 -0
- package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
- package/src/runtime/document-layout.ts +8 -6
- package/src/runtime/document-runtime.ts +843 -1141
- package/src/runtime/document-search.ts +1 -1
- package/src/runtime/edit-ops/index.ts +1 -1
- package/src/runtime/external-send-runtime.ts +1 -1
- package/src/runtime/formatting/document-lookup.ts +235 -0
- package/src/runtime/formatting/field/registry.ts +41 -0
- package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
- package/src/runtime/formatting/font-resolution.ts +83 -0
- package/src/runtime/formatting/formatting-context.ts +903 -0
- package/src/runtime/formatting/formatting-types.ts +157 -0
- package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
- package/src/runtime/formatting/index.ts +125 -0
- package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
- package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
- package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
- package/src/runtime/formatting/projector.ts +75 -0
- package/src/runtime/formatting/resolve-effective.ts +407 -0
- package/src/runtime/formatting/revision-display.ts +105 -0
- package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
- package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
- package/src/runtime/formatting/telemetry-bridge.ts +106 -0
- package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
- package/src/runtime/geometry/caret-geometry.ts +164 -0
- package/src/runtime/geometry/geometry-facet.ts +364 -0
- package/src/runtime/geometry/geometry-types.ts +256 -0
- package/src/runtime/geometry/hit-test.ts +125 -0
- package/src/runtime/geometry/index.ts +71 -0
- package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
- package/src/runtime/geometry/invalidation.ts +35 -0
- package/src/runtime/geometry/object-handles.ts +77 -0
- package/src/runtime/geometry/overlay-rects.ts +85 -0
- package/src/runtime/geometry/project-anchors.ts +100 -0
- package/src/runtime/geometry/project-fragments.ts +216 -0
- package/src/runtime/geometry/projector.ts +129 -0
- package/src/runtime/geometry/replacement-envelope.ts +130 -0
- package/src/runtime/geometry/viewport.ts +218 -0
- package/src/runtime/layout/compat-input-ledger.ts +211 -0
- package/src/runtime/layout/index.ts +6 -1
- package/src/runtime/layout/inert-layout-facet.ts +12 -7
- package/src/runtime/layout/layout-engine-instance.ts +189 -11
- package/src/runtime/layout/layout-engine-version.ts +450 -1
- package/src/runtime/layout/layout-facet-types.ts +60 -0
- package/src/runtime/layout/layout-measurement-provider.ts +13 -0
- package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
- package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
- package/src/runtime/layout/page-graph.ts +62 -209
- package/src/runtime/layout/page-story-resolver.ts +7 -12
- package/src/runtime/layout/paginated-layout-engine.ts +186 -11
- package/src/runtime/layout/project-block-fragments.ts +11 -0
- package/src/runtime/layout/projector.ts +90 -0
- package/src/runtime/layout/public-facet.ts +187 -442
- package/src/runtime/layout/resolved-formatting-state.ts +158 -26
- package/src/runtime/layout/table-render-plan.ts +1 -1
- package/src/runtime/prerender/cache-envelope.ts +6 -1
- package/src/runtime/prerender/prerender-document.ts +18 -23
- package/src/runtime/render/decoration-resolver.ts +1 -1
- package/src/runtime/render/render-frame-types.ts +20 -0
- package/src/runtime/render/render-kernel.ts +94 -25
- package/src/runtime/scopes/_formatting-seam.ts +262 -0
- package/src/runtime/scopes/_scope-dependencies.ts +49 -0
- package/src/runtime/scopes/action-validation.ts +356 -0
- package/src/runtime/scopes/attach-explanation.ts +102 -0
- package/src/runtime/scopes/audit-bundle.ts +71 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
- package/src/runtime/scopes/compile-scope.ts +262 -0
- package/src/runtime/scopes/compiler-service.ts +431 -0
- package/src/runtime/scopes/create-issue.ts +107 -0
- package/src/runtime/scopes/enumerate-scopes.ts +543 -0
- package/src/runtime/scopes/evidence.ts +233 -0
- package/src/runtime/scopes/index.ts +150 -0
- package/src/runtime/scopes/position-map.ts +214 -0
- package/src/runtime/scopes/preservation-boundary.ts +91 -0
- package/src/runtime/scopes/projector.ts +49 -0
- package/src/runtime/scopes/replaceability.ts +87 -0
- package/src/runtime/scopes/replacement/apply.ts +228 -0
- package/src/runtime/scopes/replacement/compile.ts +59 -0
- package/src/runtime/scopes/replacement/propose.ts +42 -0
- package/src/runtime/scopes/resolve-reference.ts +347 -0
- package/src/runtime/scopes/review-bundle.ts +141 -0
- package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
- package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
- package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
- package/src/runtime/scopes/scope-kinds/field.ts +65 -0
- package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
- package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
- package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
- package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
- package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
- package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
- package/src/runtime/scopes/scope-kinds/table.ts +55 -0
- package/src/runtime/scopes/scope-range.ts +208 -0
- package/src/runtime/scopes/semantic-scope-types.ts +454 -0
- package/src/runtime/scopes/workflow-overlap.ts +92 -0
- package/src/runtime/selection/index.ts +1 -1
- package/src/runtime/structure-ops/fragment-insert.ts +1 -1
- package/src/runtime/structure-ops/index.ts +1 -1
- package/src/runtime/surface-projection.ts +232 -262
- package/src/runtime/units.ts +4 -2
- package/src/runtime/workflow/coordinator.ts +1348 -0
- package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
- package/src/runtime/workflow/index.ts +25 -0
- package/src/runtime/workflow/markup-mode-policy.ts +98 -0
- package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
- package/src/runtime/workflow/metadata-persistence.ts +306 -0
- package/src/runtime/workflow/metadata-writer.ts +123 -0
- package/src/runtime/workflow/overlay-store.ts +690 -0
- package/src/runtime/workflow/projector.ts +127 -0
- package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
- package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
- package/src/runtime/workflow/rail/types.ts +198 -0
- package/src/runtime/workflow/scope-rail-composer.ts +39 -0
- package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
- package/src/runtime/workflow/scope-writer.ts +188 -0
- package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
- package/src/runtime/workflow/visibility-policy.ts +129 -0
- package/src/session/_sync-legacy.ts +66 -0
- package/src/session/export/embedded-reconstitute.ts +104 -0
- package/src/session/export/export-diagnostics.ts +85 -0
- package/src/session/export/export-validation.ts +110 -0
- package/src/session/export/index.ts +34 -0
- package/src/session/export/preservation-reattach.ts +30 -0
- package/src/session/export/serialize-dispatch.ts +165 -0
- package/src/session/export/stateful-export-pipeline.ts +432 -0
- package/src/session/export/stateful-export.ts +684 -0
- package/src/session/import/canonical-assembly.ts +227 -0
- package/src/session/import/diagnostics-session.ts +54 -0
- package/src/session/import/embedded-discovery.ts +225 -0
- package/src/session/import/embedded-offload.ts +337 -0
- package/src/session/import/import-diagnostics.ts +69 -0
- package/src/session/import/loader-types.ts +313 -0
- package/src/session/import/loader.ts +1834 -0
- package/src/session/import/normalize.ts +195 -0
- package/src/session/import/package-parts.ts +217 -0
- package/src/session/import/package-read.ts +195 -0
- package/src/session/import/parse-orchestration.ts +105 -0
- package/src/session/import/part-constants.ts +70 -0
- package/src/session/import/part-discovery.ts +94 -0
- package/src/session/import/preservation-index.ts +46 -0
- package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
- package/src/session/import/review-import.ts +508 -0
- package/src/session/import/styles-consolidation.ts +281 -0
- package/src/session/import/workflow-scope-import.ts +256 -0
- package/src/session/index.ts +37 -0
- package/src/session/session-state.ts +69 -0
- package/src/session/session.ts +532 -0
- package/src/session/shared/protection.ts +228 -0
- package/src/session/shared/session-utils.ts +82 -0
- package/src/session/types.ts +499 -0
- package/src/shell/chart-snapshots.ts +96 -0
- package/src/shell/media-previews.ts +85 -0
- package/src/shell/overlay-anchor-bridge.ts +53 -0
- package/src/shell/paste-adapter.ts +23 -0
- package/src/shell/ref-commands.ts +1697 -0
- package/src/shell/ref-utilities.ts +48 -0
- package/src/shell/search.ts +51 -0
- package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
- package/src/shell/ui-subscriber-channels.ts +81 -0
- package/src/shell/use-collab-sync.ts +116 -0
- package/src/ui/WordReviewEditor.tsx +496 -2051
- package/src/ui/editor-shell-view.tsx +30 -1
- package/src/ui/editor-surface-controller.tsx +49 -1
- package/src/ui/headless/revision-decoration-model.ts +83 -0
- package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
- package/src/ui/headless/scoped-chrome-policy.ts +2 -2
- package/src/ui/headless/selection-tool-context.ts +1 -1
- package/src/ui/headless/selection-tool-resolver.ts +1 -1
- package/src/ui/runtime-shortcut-dispatch.ts +46 -1
- package/src/ui/ui-controller-factory.ts +221 -0
- package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
- package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
- package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
- package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
- package/src/ui-tailwind/chart/render/area.tsx +3 -3
- package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
- package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
- package/src/ui-tailwind/chart/render/combo.tsx +2 -2
- package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
- package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
- package/src/ui-tailwind/chart/render/line.tsx +3 -3
- package/src/ui-tailwind/chart/render/pie.tsx +6 -6
- package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
- package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
- package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
- package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
- package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
- package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
- package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
- package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
- package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
- package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
- package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
- package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
- package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
- package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
- package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
- package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
- package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
- package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
- package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
- package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
- package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
- package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
- package/src/ui-tailwind/debug/README.md +57 -0
- package/src/ui-tailwind/debug/index.ts +3 -0
- package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
- package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
- package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
- package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
- package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
- package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
- package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
- package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
- package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
- package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
- package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
- package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
- package/src/ui-tailwind/index.ts +0 -5
- package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
- package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
- package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
- package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
- package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
- package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
- package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
- package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
- package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
- package/src/ui-tailwind/review-workspace/types.ts +408 -0
- package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
- package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
- package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
- package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
- package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
- package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
- package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
- package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
- package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
- package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
- package/src/ui-tailwind/theme/editor-theme.css +25 -0
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
- package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
- package/src/ui-tailwind/ui-api-context.tsx +43 -0
- package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
- package/src/validation/compatibility-engine.ts +6 -6
- package/src/runtime/styles-cascade.ts +0 -33
- package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
- /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
- /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
- /package/src/runtime/{scope-tag-registry.ts → workflow/scope-tag-registry.ts} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — `ai.policy` family.
|
|
3
|
+
*
|
|
4
|
+
* getPolicy — agent-facing view of the AI action policy matrix.
|
|
5
|
+
*
|
|
6
|
+
* Thin adapter over Layer-06's `src/runtime/workflow/ai-action-policy.ts`
|
|
7
|
+
* — the 23-operation matrix that gates AI mutations per capability +
|
|
8
|
+
* risk tier. Exposed on v3 so agents + workblocks can pre-check whether
|
|
9
|
+
* a given action requires confirmation / carries approval requirements /
|
|
10
|
+
* is blocked outright, without having to call
|
|
11
|
+
* `ai.validateReplacementScope` just to learn the policy state.
|
|
12
|
+
*
|
|
13
|
+
* `validateReplacementScope` still internally consumes the same policy
|
|
14
|
+
* matrix (through `composeScopeValidation` in /08); this function is a
|
|
15
|
+
* pre-flight read-only surface. A4 audit emission does NOT apply here —
|
|
16
|
+
* `readOrMutate: "read"`.
|
|
17
|
+
*
|
|
18
|
+
* Cross-layer-coord history: filed by /06 §7 "L09 expose AI action
|
|
19
|
+
* policy matrix" (2026-04-22). Closes that ask.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
23
|
+
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
24
|
+
import {
|
|
25
|
+
AI_ACTION_POLICIES,
|
|
26
|
+
getAIActionPolicy,
|
|
27
|
+
type AIAction,
|
|
28
|
+
type AIActionPolicy,
|
|
29
|
+
} from "../../../runtime/workflow/ai-action-policy.ts";
|
|
30
|
+
|
|
31
|
+
export interface GetPolicyInput {
|
|
32
|
+
/**
|
|
33
|
+
* When set, return the single policy for that action. When omitted,
|
|
34
|
+
* return the full matrix.
|
|
35
|
+
*/
|
|
36
|
+
readonly action?: AIAction;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type GetPolicyResult = AIActionPolicy | readonly AIActionPolicy[];
|
|
40
|
+
|
|
41
|
+
export const getPolicyMetadata: ApiV3FnMetadata = {
|
|
42
|
+
name: "ai.getPolicy",
|
|
43
|
+
status: "live-with-adapter",
|
|
44
|
+
sourceLayer: "workflow-review",
|
|
45
|
+
liveEvidence: {
|
|
46
|
+
runnerTest: "test/api/v3/ai/ai-get-policy.test.ts",
|
|
47
|
+
commit: "refactor-09-slice-6",
|
|
48
|
+
},
|
|
49
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
50
|
+
agentMetadata: {
|
|
51
|
+
readOrMutate: "read",
|
|
52
|
+
boundedScope: "document",
|
|
53
|
+
auditCategory: "policy-read",
|
|
54
|
+
contextPromptShape:
|
|
55
|
+
"Pre-flight view of the AI action policy matrix — for a given action: support tier (allowed / confirmation-required / blocked), risk tier (low / medium / high / critical), rationale, requirements (confirmation, preservation, validation, audit), constraints (scope, preservation respect, compatibility, undo), fallback. Omit action to get the full matrix.",
|
|
56
|
+
},
|
|
57
|
+
stateClass: "A-canonical",
|
|
58
|
+
persistsTo: "canonical",
|
|
59
|
+
rwdReference:
|
|
60
|
+
"§AI API § ai.getPolicy. Adapter: delegates to getAIActionPolicy(action) or surfaces AI_ACTION_POLICIES[] directly. Read-only; no audit emission (A4 applies to mutations). Closes cross-layer-coord-06.md §7 (L09 expose AI action policy matrix).",
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function createPolicyFamily(_runtime: RuntimeApiHandle) {
|
|
64
|
+
return {
|
|
65
|
+
getPolicy(input?: GetPolicyInput): GetPolicyResult {
|
|
66
|
+
// @endStateApi — live-with-adapter. Delegates to Layer-06's
|
|
67
|
+
// getAIActionPolicy(action) for single-action lookups or returns
|
|
68
|
+
// the frozen AI_ACTION_POLICIES matrix for bulk listing. The
|
|
69
|
+
// runtime handle is accepted for API-shape consistency but is
|
|
70
|
+
// not read — the policy matrix is process-wide static.
|
|
71
|
+
if (input?.action) {
|
|
72
|
+
return getAIActionPolicy(input.action);
|
|
73
|
+
}
|
|
74
|
+
return AI_ACTION_POLICIES;
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — `ai.replacement` family.
|
|
3
|
+
*
|
|
4
|
+
* - `proposeReplacementScope` / `applyReplacementScope` stay `mock` until
|
|
5
|
+
* refactor/08 Slice 5 ships the replacement lifecycle (propose →
|
|
6
|
+
* compile → apply + audit).
|
|
7
|
+
* - `validateReplacementScope` graduated to `live-with-adapter` in
|
|
8
|
+
* Slice 4: compiles the target scope fresh, runs
|
|
9
|
+
* `composeScopeValidation`, and projects the richer compiler verdict
|
|
10
|
+
* into the v3-facing `ValidationResult` shape.
|
|
11
|
+
*
|
|
12
|
+
* The v3 `ValidationResult` shape (`{ proposalId, safe, blockers? }`)
|
|
13
|
+
* stays narrow by design. The compiler-side `ValidationResult`
|
|
14
|
+
* (`{ safe, blockedReasons, warnings, approval }`) remains the authority
|
|
15
|
+
* for internal consumers; the v3 projection trades richness for a
|
|
16
|
+
* stable external contract. Slice 5's apply pipeline reads the
|
|
17
|
+
* compiler verdict directly rather than the v3 projection.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
21
|
+
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
22
|
+
import { mockId } from "../_mocks.ts";
|
|
23
|
+
import { emitUxResponse } from "../_ux-response.ts";
|
|
24
|
+
import {
|
|
25
|
+
composeScopeValidation,
|
|
26
|
+
createScopeCompilerService,
|
|
27
|
+
} from "../../../runtime/scopes/index.ts";
|
|
28
|
+
import type {
|
|
29
|
+
ReplacementOperationKind,
|
|
30
|
+
ReplacementPreservePolicy,
|
|
31
|
+
ValidationResult as CompilerValidationResult,
|
|
32
|
+
} from "../../../runtime/scopes/index.ts";
|
|
33
|
+
import type { AIAction } from "../../../runtime/workflow/ai-action-policy.ts";
|
|
34
|
+
|
|
35
|
+
export interface ReplacementProposalInput {
|
|
36
|
+
readonly targetScopeId: string;
|
|
37
|
+
readonly operation: ReplacementOperationKind;
|
|
38
|
+
readonly proposedText?: string;
|
|
39
|
+
readonly preserve?: ReplacementPreservePolicy;
|
|
40
|
+
readonly reason?: string;
|
|
41
|
+
readonly actionId?: AIAction;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated retained for back-compat with pre-Slice-5 callers;
|
|
46
|
+
* mirrors {@link ReplacementProposalInput} but without the broadened fields.
|
|
47
|
+
* @see ReplacementProposalInput
|
|
48
|
+
*/
|
|
49
|
+
export type ReplacementProposal = Pick<
|
|
50
|
+
ReplacementProposalInput,
|
|
51
|
+
"targetScopeId" | "operation" | "proposedText"
|
|
52
|
+
>;
|
|
53
|
+
|
|
54
|
+
export interface ProposalResult {
|
|
55
|
+
readonly proposalId: string;
|
|
56
|
+
readonly accepted: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const proposeReplacementScopeMetadata: ApiV3FnMetadata = {
|
|
60
|
+
name: "ai.proposeReplacementScope",
|
|
61
|
+
status: "live-with-adapter",
|
|
62
|
+
sourceLayer: "semantic-scope-compiler",
|
|
63
|
+
liveEvidence: {
|
|
64
|
+
runnerTest:
|
|
65
|
+
"test/runtime/scopes/replacement-text-only.test.ts,test/api/v3/ai/live-with-adapter-proof.test.ts",
|
|
66
|
+
commit: "refactor-08-slice-5",
|
|
67
|
+
},
|
|
68
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
69
|
+
agentMetadata: {
|
|
70
|
+
readOrMutate: "read",
|
|
71
|
+
boundedScope: "scope",
|
|
72
|
+
auditCategory: "replacement-propose",
|
|
73
|
+
contextPromptShape: "Propose scope-scoped replacement; returns a proposalId + accepted flag. No propose-cache persists — apply re-compiles fresh.",
|
|
74
|
+
},
|
|
75
|
+
stateClass: "A-canonical",
|
|
76
|
+
persistsTo: "canonical",
|
|
77
|
+
rwdReference:
|
|
78
|
+
"§AI API § ai.proposeReplacementScope. Adapter: resolves targetScopeId against live state; returns {proposalId, accepted: scope resolves successfully}.",
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* v3-facing validation result. Narrower than the compiler-side
|
|
83
|
+
* `ValidationResult` (`{safe, blockedReasons, warnings, approval}`) —
|
|
84
|
+
* Slice 4 projects the compiler verdict into this shape so external
|
|
85
|
+
* consumers (workblocks, MCP, BW agent surface) get a stable contract.
|
|
86
|
+
*/
|
|
87
|
+
export interface ValidationResult {
|
|
88
|
+
readonly proposalId: string;
|
|
89
|
+
readonly safe: boolean;
|
|
90
|
+
readonly blockers?: readonly string[];
|
|
91
|
+
readonly warnings?: readonly string[];
|
|
92
|
+
readonly approvalRequired?: boolean;
|
|
93
|
+
readonly approvalReason?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const validateReplacementScopeMetadata: ApiV3FnMetadata = {
|
|
97
|
+
name: "ai.validateReplacementScope",
|
|
98
|
+
status: "live-with-adapter",
|
|
99
|
+
sourceLayer: "semantic-scope-compiler",
|
|
100
|
+
liveEvidence: {
|
|
101
|
+
runnerTest:
|
|
102
|
+
"test/runtime/scopes/validation-all-green.test.ts,test/runtime/scopes/validation-guard-blocks.test.ts,test/runtime/scopes/validation-preserve-only.test.ts,test/runtime/scopes/validation-compat-risk.test.ts,test/runtime/scopes/validation-approval-required.test.ts,test/runtime/scopes/validation-source-tagging.test.ts,test/runtime/scopes/validation-determinism.test.ts,test/api/v3/ai-live-with-adapter-proof.test.ts",
|
|
103
|
+
commit: "refactor-08-slice-4",
|
|
104
|
+
},
|
|
105
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
106
|
+
agentMetadata: {
|
|
107
|
+
readOrMutate: "read",
|
|
108
|
+
boundedScope: "scope",
|
|
109
|
+
auditCategory: "replacement-validate",
|
|
110
|
+
contextPromptShape:
|
|
111
|
+
"Validate a scope-scoped replacement against workflow guard + preservation boundaries + compatibility report + AI action policy.",
|
|
112
|
+
},
|
|
113
|
+
stateClass: "A-canonical",
|
|
114
|
+
persistsTo: "canonical",
|
|
115
|
+
rwdReference: "§AI API § ai.validateReplacementScope",
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export interface ApplyResult {
|
|
119
|
+
readonly proposalId: string;
|
|
120
|
+
readonly applied: boolean;
|
|
121
|
+
readonly reason?: string;
|
|
122
|
+
readonly blockers?: readonly string[];
|
|
123
|
+
readonly auditHint?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ApplyReplacementScopeInput {
|
|
127
|
+
readonly targetScopeId: string;
|
|
128
|
+
readonly operation?: ReplacementOperationKind;
|
|
129
|
+
/**
|
|
130
|
+
* Flat text payload. Shorthand for
|
|
131
|
+
* `proposedContent: {kind: "text", text}`. Ignored when
|
|
132
|
+
* `proposedContent` is supplied.
|
|
133
|
+
*/
|
|
134
|
+
readonly proposedText?: string;
|
|
135
|
+
/**
|
|
136
|
+
* Structured-fragment payload (`kind: "structured"` with a
|
|
137
|
+
* `CanonicalDocumentFragment`-shaped value). Widens the v3 surface
|
|
138
|
+
* 2026-04-22 — v3 consumers can now pass a structured fragment
|
|
139
|
+
* end-to-end. Closes `cross-layer-coord-09.md §1.5` on the L08 side.
|
|
140
|
+
*/
|
|
141
|
+
readonly proposedContent?: {
|
|
142
|
+
readonly kind: "text" | "structured";
|
|
143
|
+
readonly text?: string;
|
|
144
|
+
readonly structured?: unknown;
|
|
145
|
+
};
|
|
146
|
+
readonly preserve?: ReplacementPreservePolicy;
|
|
147
|
+
readonly reason?: string;
|
|
148
|
+
readonly actionId?: AIAction;
|
|
149
|
+
readonly actorId?: string;
|
|
150
|
+
readonly origin?: "ui" | "agent" | "host";
|
|
151
|
+
readonly proposalId?: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const applyReplacementScopeMetadata: ApiV3FnMetadata = {
|
|
155
|
+
name: "ai.applyReplacementScope",
|
|
156
|
+
status: "live-with-adapter",
|
|
157
|
+
sourceLayer: "semantic-scope-compiler",
|
|
158
|
+
liveEvidence: {
|
|
159
|
+
runnerTest:
|
|
160
|
+
"test/runtime/scopes/replacement-text-only.test.ts,test/runtime/scopes/audit-bundle-shape.test.ts,test/runtime/scopes/replacement-validation-block.test.ts",
|
|
161
|
+
commit: "refactor-08-slice-5",
|
|
162
|
+
},
|
|
163
|
+
uxIntent: {
|
|
164
|
+
uiVisible: true,
|
|
165
|
+
expectsUxResponse: "inline-change",
|
|
166
|
+
expectedDelta: "text inside target scope changes",
|
|
167
|
+
},
|
|
168
|
+
agentMetadata: {
|
|
169
|
+
readOrMutate: "mutate",
|
|
170
|
+
boundedScope: "scope",
|
|
171
|
+
auditCategory: "replacement-apply",
|
|
172
|
+
policyHints: ["requires-approval-for-legal-hold"],
|
|
173
|
+
},
|
|
174
|
+
stateClass: "A-canonical",
|
|
175
|
+
persistsTo: "canonical",
|
|
176
|
+
broadcastsVia: "crdt",
|
|
177
|
+
rwdReference:
|
|
178
|
+
"§AI API § ai.applyReplacementScope. Adapter: widened to {targetScopeId, operation, proposedText?, preserve?, actionId?, proposalId?}; routes through applyScopeReplacement (re-validates live state, compiles per-kind plan, dispatches via DocumentRuntime.applyScopeReplacement, emits one ScopeActionAudit on the scope telemetry channel).",
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Input shape for `validateReplacementScope`. Slice 4 widens the input
|
|
183
|
+
* to carry enough information for a fresh compile + compose, since the
|
|
184
|
+
* propose-cache that Slice 5 introduces is not yet available. Legacy
|
|
185
|
+
* callers passing only `{ proposalId }` get a typed "propose-cache-not-
|
|
186
|
+
* available" response (no mutation, no false positives).
|
|
187
|
+
*/
|
|
188
|
+
export interface ValidateReplacementScopeInput {
|
|
189
|
+
readonly proposalId?: string;
|
|
190
|
+
readonly targetScopeId?: string;
|
|
191
|
+
readonly operation?: ReplacementOperationKind;
|
|
192
|
+
readonly proposedText?: string;
|
|
193
|
+
/** Optional action id override; composer derives a default otherwise. */
|
|
194
|
+
readonly actionId?: AIAction;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function projectValidationResult(
|
|
198
|
+
proposalId: string,
|
|
199
|
+
verdict: CompilerValidationResult,
|
|
200
|
+
): ValidationResult {
|
|
201
|
+
const blockers =
|
|
202
|
+
verdict.blockedReasons.length > 0
|
|
203
|
+
? Object.freeze([...verdict.blockedReasons])
|
|
204
|
+
: undefined;
|
|
205
|
+
const warnings =
|
|
206
|
+
verdict.warnings.length > 0
|
|
207
|
+
? Object.freeze(verdict.warnings.map((w) => w.code))
|
|
208
|
+
: undefined;
|
|
209
|
+
return {
|
|
210
|
+
proposalId,
|
|
211
|
+
safe: verdict.safe,
|
|
212
|
+
...(blockers ? { blockers } : {}),
|
|
213
|
+
...(warnings ? { warnings } : {}),
|
|
214
|
+
...(verdict.approval?.required ? { approvalRequired: true } : {}),
|
|
215
|
+
...(verdict.approval?.reason ? { approvalReason: verdict.approval.reason } : {}),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function createReplacementFamily(runtime: RuntimeApiHandle) {
|
|
220
|
+
const compiler = createScopeCompilerService(runtime);
|
|
221
|
+
return {
|
|
222
|
+
proposeReplacementScope(input: ReplacementProposalInput): ProposalResult {
|
|
223
|
+
// @endStateApi — live-with-adapter (Slice 5). Routes through the
|
|
224
|
+
// Layer-08 compiler-service facade.
|
|
225
|
+
const proposalId = mockId(
|
|
226
|
+
runtime.getSessionState().documentId,
|
|
227
|
+
`proposal-${input.targetScopeId}-${input.operation}`,
|
|
228
|
+
);
|
|
229
|
+
const compiled = compiler.compileScopeById(input.targetScopeId);
|
|
230
|
+
return { proposalId, accepted: compiled !== null };
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
validateReplacementScope(
|
|
234
|
+
input: ValidateReplacementScopeInput,
|
|
235
|
+
): ValidationResult {
|
|
236
|
+
// @endStateApi — live-with-adapter. Compiles via the facade and
|
|
237
|
+
// composes the verdict locally (v3 projects the compiler-side
|
|
238
|
+
// verdict into a narrower external shape).
|
|
239
|
+
const proposalId =
|
|
240
|
+
input.proposalId ??
|
|
241
|
+
(input.targetScopeId
|
|
242
|
+
? mockId(
|
|
243
|
+
runtime.getSessionState().documentId,
|
|
244
|
+
`validation-${input.targetScopeId}-${input.operation ?? "replace"}`,
|
|
245
|
+
)
|
|
246
|
+
: "unresolved-proposal");
|
|
247
|
+
|
|
248
|
+
if (!input.targetScopeId) {
|
|
249
|
+
return {
|
|
250
|
+
proposalId,
|
|
251
|
+
safe: false,
|
|
252
|
+
blockers: Object.freeze([
|
|
253
|
+
"legacy-proposalId-only:pass-targetScopeId-to-validate-now",
|
|
254
|
+
]),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const compiled = compiler.compileScopeById(input.targetScopeId);
|
|
259
|
+
if (!compiled) {
|
|
260
|
+
return {
|
|
261
|
+
proposalId,
|
|
262
|
+
safe: false,
|
|
263
|
+
blockers: Object.freeze([
|
|
264
|
+
`scope-not-resolvable:${input.targetScopeId}`,
|
|
265
|
+
]),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const operation: ReplacementOperationKind = input.operation ?? "replace";
|
|
270
|
+
const proposedContent =
|
|
271
|
+
typeof input.proposedText === "string"
|
|
272
|
+
? ({ kind: "text", text: input.proposedText } as const)
|
|
273
|
+
: ({ kind: "text", text: "" } as const);
|
|
274
|
+
|
|
275
|
+
const verdict = composeScopeValidation({
|
|
276
|
+
scope: compiled.scope,
|
|
277
|
+
operation,
|
|
278
|
+
proposedContent,
|
|
279
|
+
runtime: {
|
|
280
|
+
getInteractionGuardSnapshot: () => runtime.getInteractionGuardSnapshot(),
|
|
281
|
+
getCompatibilityReport: () => runtime.getCompatibilityReport(),
|
|
282
|
+
},
|
|
283
|
+
document: compiled.document,
|
|
284
|
+
...(input.actionId ? { actionId: input.actionId } : {}),
|
|
285
|
+
});
|
|
286
|
+
return projectValidationResult(proposalId, verdict);
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
applyReplacementScope(input: ApplyReplacementScopeInput): ApplyResult {
|
|
290
|
+
// @endStateApi — live-with-adapter (Slice 5). Routes through the
|
|
291
|
+
// compiler-service facade. The facade re-validates on live state,
|
|
292
|
+
// compiles the per-kind plan, dispatches via
|
|
293
|
+
// DocumentRuntime.applyScopeReplacement, and emits one
|
|
294
|
+
// ScopeActionAudit on the scope telemetry channel.
|
|
295
|
+
const proposalId =
|
|
296
|
+
input.proposalId ??
|
|
297
|
+
mockId(
|
|
298
|
+
runtime.getSessionState().documentId,
|
|
299
|
+
`apply-${input.targetScopeId}-${input.operation ?? "replace"}`,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
const result = compiler.applyReplacement({
|
|
303
|
+
targetScopeId: input.targetScopeId,
|
|
304
|
+
operation: input.operation ?? "replace",
|
|
305
|
+
...(input.proposedContent
|
|
306
|
+
? { proposedContent: input.proposedContent }
|
|
307
|
+
: input.proposedText !== undefined
|
|
308
|
+
? { proposedText: input.proposedText }
|
|
309
|
+
: {}),
|
|
310
|
+
...(input.preserve ? { preserve: input.preserve } : {}),
|
|
311
|
+
...(input.reason ? { reason: input.reason } : {}),
|
|
312
|
+
...(input.actionId ? { actionId: input.actionId } : {}),
|
|
313
|
+
actorId: input.actorId ?? "agent",
|
|
314
|
+
origin: input.origin ?? "agent",
|
|
315
|
+
emittedAtUtc: new Date(0).toISOString(),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
emitUxResponse(runtime, {
|
|
319
|
+
apiFn: applyReplacementScopeMetadata.name,
|
|
320
|
+
intent: applyReplacementScopeMetadata.uxIntent.expectedDelta ?? "",
|
|
321
|
+
mockOrLive: "live",
|
|
322
|
+
uiVisible: true,
|
|
323
|
+
expectedDelta: applyReplacementScopeMetadata.uxIntent.expectedDelta,
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
proposalId,
|
|
328
|
+
applied: result.applied,
|
|
329
|
+
...(result.reason ? { reason: result.reason } : {}),
|
|
330
|
+
...(result.validation.blockedReasons.length > 0
|
|
331
|
+
? { blockers: Object.freeze([...result.validation.blockedReasons]) }
|
|
332
|
+
: {}),
|
|
333
|
+
...(result.audit ? { auditHint: result.audit.actionId } : {}),
|
|
334
|
+
};
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Silence unused-import: ReplacementPreservePolicy is a public re-export
|
|
340
|
+
// for consumers of this module's input types.
|
|
341
|
+
export type { ReplacementPreservePolicy };
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — `ai.resolve` family.
|
|
3
|
+
*
|
|
4
|
+
* Slice 3 of refactor/08 graduates `resolveReference` to
|
|
5
|
+
* `live-with-adapter` for the FOUR DETERMINISTIC hint kinds: `scope-id`,
|
|
6
|
+
* `semantic-path`, `offset`, and `range`. Offset / range resolution now
|
|
7
|
+
* honors precise nested-kind ranges (fields, table rows, table cells)
|
|
8
|
+
* via the scope-compiler's specificity tie-breaker — see
|
|
9
|
+
* `docs/architecture/08-semantic-scope-compiler.md` §"Resolve-reference
|
|
10
|
+
* precision" for the specificity table.
|
|
11
|
+
*
|
|
12
|
+
* The `natural-language` hint remains **partial by design**. The live
|
|
13
|
+
* path is a deterministic substring matcher over:
|
|
14
|
+
* - `semanticPath.join("/")`
|
|
15
|
+
* - `scopeId`
|
|
16
|
+
* - `overlay.scopes[].label` (when the overlay is threaded)
|
|
17
|
+
* - a capped 200-char content excerpt
|
|
18
|
+
* Every successful NL resolution carries `confidence: "low"` — callers
|
|
19
|
+
* must surface that to a human before committing any mutating action
|
|
20
|
+
* keyed off the resolved handle. Richer NL resolution (embedding /
|
|
21
|
+
* domain-aware) is explicitly out of scope for this layer; the v3
|
|
22
|
+
* `resolveReference` adapter never promotes an NL match above `low`.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
26
|
+
import {
|
|
27
|
+
resolveReference,
|
|
28
|
+
type ResolveReferenceResult as RuntimeResolveResult,
|
|
29
|
+
type ScopeHandle,
|
|
30
|
+
type ScopeReference,
|
|
31
|
+
} from "../../../runtime/scopes/index.ts";
|
|
32
|
+
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
33
|
+
|
|
34
|
+
export type ResolveReferenceInput =
|
|
35
|
+
| { readonly hint: string }
|
|
36
|
+
| { readonly reference: ScopeReference };
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* v3 projection of the runtime resolver's result. Carries the FULL
|
|
40
|
+
* `ScopeHandle` (not just `scopeId`) so callers can round-trip
|
|
41
|
+
* `stableRef` / `semanticPath` / `parentScopeId` back into a follow-up
|
|
42
|
+
* `resolveReference` or `getScopeBundle` call.
|
|
43
|
+
*/
|
|
44
|
+
export interface ResolveReferenceResult {
|
|
45
|
+
readonly status: RuntimeResolveResult["status"];
|
|
46
|
+
readonly handle?: ScopeHandle;
|
|
47
|
+
/** Convenience mirror of `handle.scopeId`; also set on `detached`. */
|
|
48
|
+
readonly scopeId?: string;
|
|
49
|
+
readonly confidence: "high" | "medium" | "low" | "none";
|
|
50
|
+
readonly candidates?: readonly ScopeHandle[];
|
|
51
|
+
readonly reason?: string;
|
|
52
|
+
readonly lastKnownRange?: { readonly from: number; readonly to: number };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const resolveReferenceMetadata: ApiV3FnMetadata = {
|
|
56
|
+
name: "ai.resolveReference",
|
|
57
|
+
status: "live-with-adapter",
|
|
58
|
+
sourceLayer: "semantic-scope-compiler",
|
|
59
|
+
liveEvidence: {
|
|
60
|
+
runnerTest:
|
|
61
|
+
"test/runtime/scopes/resolve-reference.test.ts,test/runtime/scopes/resolve-reference-stale-scope.test.ts",
|
|
62
|
+
commit: "refactor-08-slice-3",
|
|
63
|
+
},
|
|
64
|
+
uxIntent: { uiVisible: false, expectsUxResponse: "none" },
|
|
65
|
+
agentMetadata: {
|
|
66
|
+
readOrMutate: "read",
|
|
67
|
+
boundedScope: "document",
|
|
68
|
+
auditCategory: "reference-resolve",
|
|
69
|
+
contextPromptShape:
|
|
70
|
+
"Resolve a natural-language hint or structured ScopeReference into a stable scopeId.",
|
|
71
|
+
},
|
|
72
|
+
stateClass: "A-canonical",
|
|
73
|
+
persistsTo: "canonical",
|
|
74
|
+
rwdReference: "§AI API § ai.resolveReference",
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
function asReference(input: ResolveReferenceInput): ScopeReference {
|
|
78
|
+
if ("reference" in input) return input.reference;
|
|
79
|
+
return { kind: "natural-language", hint: input.hint };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function projectResult(raw: RuntimeResolveResult): ResolveReferenceResult {
|
|
83
|
+
switch (raw.status) {
|
|
84
|
+
case "resolved":
|
|
85
|
+
return {
|
|
86
|
+
status: "resolved",
|
|
87
|
+
handle: raw.handle,
|
|
88
|
+
scopeId: raw.handle.scopeId,
|
|
89
|
+
confidence: raw.confidence,
|
|
90
|
+
};
|
|
91
|
+
case "ambiguous":
|
|
92
|
+
return {
|
|
93
|
+
status: "ambiguous",
|
|
94
|
+
confidence: "low",
|
|
95
|
+
candidates: raw.candidates,
|
|
96
|
+
};
|
|
97
|
+
case "detached":
|
|
98
|
+
return {
|
|
99
|
+
status: "detached",
|
|
100
|
+
scopeId: raw.scopeId,
|
|
101
|
+
confidence: "none",
|
|
102
|
+
reason: raw.reason,
|
|
103
|
+
...(raw.lastKnownRange
|
|
104
|
+
? {
|
|
105
|
+
lastKnownRange: {
|
|
106
|
+
from: raw.lastKnownRange.from,
|
|
107
|
+
to: raw.lastKnownRange.to,
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
: {}),
|
|
111
|
+
};
|
|
112
|
+
case "not-found":
|
|
113
|
+
return { status: "not-found", confidence: "none", reason: raw.reason };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function createResolveFamily(runtime: RuntimeApiHandle) {
|
|
118
|
+
return {
|
|
119
|
+
resolveReference(input: ResolveReferenceInput): ResolveReferenceResult {
|
|
120
|
+
// @endStateApi — live-with-adapter. Delegates to the scope-compiler
|
|
121
|
+
// `resolveReference` over the typed ScopeReference union; NL hints
|
|
122
|
+
// stay at confidence "low" per Slice 3.
|
|
123
|
+
const reference = asReference(input);
|
|
124
|
+
if (reference.kind === "natural-language" && reference.hint.trim().length === 0) {
|
|
125
|
+
return { status: "not-found", confidence: "none", reason: "empty hint" };
|
|
126
|
+
}
|
|
127
|
+
const document = runtime.getCanonicalDocument();
|
|
128
|
+
const overlay = runtime.getWorkflowOverlay();
|
|
129
|
+
const raw = resolveReference(reference, { document, overlay });
|
|
130
|
+
return projectResult(raw);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — public barrel.
|
|
3
|
+
*
|
|
4
|
+
* Consumers import ONLY `createApiV3` and the metadata primitives from this
|
|
5
|
+
* module. Family functions are NOT re-exported as bare names — the
|
|
6
|
+
* `ci-check-api-v3-no-ref-reexport` guard rejects any convenience barrel
|
|
7
|
+
* that exposes pre-v3 ref behavior through a v3-shaped name.
|
|
8
|
+
*
|
|
9
|
+
* Canonical consumer path:
|
|
10
|
+
*
|
|
11
|
+
* import { createApiV3 } from "@beyondwork/docx-react-component/api/v3";
|
|
12
|
+
* const api = createApiV3(runtime);
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export { createApiV3 } from "./_create.ts";
|
|
16
|
+
export type { ApiV3, CreateApiV3Opts } from "./_create.ts";
|
|
17
|
+
|
|
18
|
+
export type {
|
|
19
|
+
ApiStatus,
|
|
20
|
+
SourceLayer,
|
|
21
|
+
LiveEvidence,
|
|
22
|
+
MockShape,
|
|
23
|
+
UxIntent,
|
|
24
|
+
AgentMetadata,
|
|
25
|
+
ApiV3FnMetadata,
|
|
26
|
+
MockPayload,
|
|
27
|
+
SubscriptionShape,
|
|
28
|
+
StateClass,
|
|
29
|
+
PersistsTo,
|
|
30
|
+
BroadcastsVia,
|
|
31
|
+
} from "./_layer-metadata.ts";
|
|
32
|
+
export { validateApiV3Metadata } from "./_layer-metadata.ts";
|
|
33
|
+
export { isMock, mockPayload, mockArray, mockId } from "./_mocks.ts";
|
|
34
|
+
|
|
35
|
+
export type { UxResponse } from "./_ux-response.ts";
|
|
36
|
+
export { emitUxResponse } from "./_ux-response.ts";
|
|
37
|
+
|
|
38
|
+
// Layer 10 — UI API. `createApiV3(handle, { ui: factory })` is the
|
|
39
|
+
// production construction path (refactor/07 Slice 2). `createUiApi` is
|
|
40
|
+
// re-exported so callers that already hold a constructed runtime and
|
|
41
|
+
// want only the UI surface (e.g. a debug harness that built `api` first
|
|
42
|
+
// and needs to add UI later) can construct it standalone.
|
|
43
|
+
//
|
|
44
|
+
// Consumers that treat v3 as a runtime+AI seam (services/debug, headless
|
|
45
|
+
// agents) should keep using `createApiV3(handle)` — `ui` stays undefined.
|
|
46
|
+
// Consumers that mount a React surface pass `{ ui: factory }` and get a
|
|
47
|
+
// typed UI namespace on `api.ui`.
|
|
48
|
+
export { createUiApi } from "./ui/index.ts";
|
|
49
|
+
export type {
|
|
50
|
+
ApiV3Ui,
|
|
51
|
+
ApiV3UiSession,
|
|
52
|
+
ApiV3UiSurface,
|
|
53
|
+
ApiV3UiViewport,
|
|
54
|
+
ApiV3UiOverlays,
|
|
55
|
+
ApiV3UiChrome,
|
|
56
|
+
ApiV3UiDebug,
|
|
57
|
+
UiController,
|
|
58
|
+
UiControllerKind,
|
|
59
|
+
UiControllerFactory,
|
|
60
|
+
UiBinding,
|
|
61
|
+
UiListener,
|
|
62
|
+
UiUnsubscribe,
|
|
63
|
+
ViewportState,
|
|
64
|
+
ScrollTarget,
|
|
65
|
+
ScrollTargetBehavior,
|
|
66
|
+
SelectionRangeInput,
|
|
67
|
+
OverlayAnchorQuery,
|
|
68
|
+
ChromePosture,
|
|
69
|
+
ChromeHostPosture,
|
|
70
|
+
ChromeSurface,
|
|
71
|
+
ChromeSurfaceKind,
|
|
72
|
+
ChromeDocumentMode,
|
|
73
|
+
ChromeMarkupDisplay,
|
|
74
|
+
ChromeReviewMode,
|
|
75
|
+
ChromeDebugMode,
|
|
76
|
+
DebugSession,
|
|
77
|
+
DebugAttachment,
|
|
78
|
+
GeometryRect,
|
|
79
|
+
} from "./ui/index.ts";
|