@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
package/src/api/session-state.ts
CHANGED
|
@@ -39,6 +39,8 @@ export function editorSessionStateFromPersistedSnapshot(
|
|
|
39
39
|
sourcePackage: snapshot.sourcePackage,
|
|
40
40
|
workflowOverlay: snapshot.workflowOverlay,
|
|
41
41
|
workflowMetadata: snapshot.workflowMetadata,
|
|
42
|
+
visibilityPolicies: snapshot.visibilityPolicies,
|
|
43
|
+
markupModePolicy: snapshot.markupModePolicy,
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -64,6 +66,8 @@ export function persistedSnapshotFromEditorSessionState(
|
|
|
64
66
|
sourcePackage: sessionState.sourcePackage,
|
|
65
67
|
workflowOverlay: sessionState.workflowOverlay,
|
|
66
68
|
workflowMetadata: sessionState.workflowMetadata,
|
|
69
|
+
visibilityPolicies: sessionState.visibilityPolicies,
|
|
70
|
+
markupModePolicy: sessionState.markupModePolicy,
|
|
67
71
|
});
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# `src/api/v3/` — End-state public API surface
|
|
2
|
+
|
|
3
|
+
> **@endStateApi v3** — the canonical Beyond Work build-team contract.
|
|
4
|
+
> Do NOT treat this as a rename of `WordReviewEditorRef`. It is a
|
|
5
|
+
> separate, additive API that mirrors the target architecture in
|
|
6
|
+
> [`docs/architecture/00-overview.md`](../../../docs/architecture/00-overview.md)
|
|
7
|
+
> (Runtime API + AI API split per §9 + §10).
|
|
8
|
+
|
|
9
|
+
## What this directory is
|
|
10
|
+
|
|
11
|
+
- The shape every new Beyond Work consumer builds against, today.
|
|
12
|
+
- Each function carries `ApiV3FnMetadata` declaring
|
|
13
|
+
`status: "mock" | "partial" | "live-with-adapter" | "live"`, its
|
|
14
|
+
target layer, UX intent, and agent metadata.
|
|
15
|
+
- Every UX-visible function emits one `UxResponse` event on the
|
|
16
|
+
`api` telemetry channel per invocation so the future debug UX
|
|
17
|
+
(Phase Q) and agent-facing audit can observe it identically in
|
|
18
|
+
mock and live modes.
|
|
19
|
+
|
|
20
|
+
### Four-status taxonomy (Phase P')
|
|
21
|
+
|
|
22
|
+
| Status | Meaning |
|
|
23
|
+
|---|---|
|
|
24
|
+
| `mock` | No live path attempted; returns a `mockPayload(...)` / `mockArray(...)` carrying `__mock: true`. |
|
|
25
|
+
| `partial` | Live path attempted; falls back to a mock-shaped payload when the runtime cannot satisfy it. `mockShape` is required. |
|
|
26
|
+
| `live-with-adapter` | Delegates to a real runtime/facet method through a nontrivial adapter or composition layer. `mockShape` optional. |
|
|
27
|
+
| `live` | Direct delegation to a single runtime/facet method. `mockShape` is forbidden. |
|
|
28
|
+
|
|
29
|
+
The current distribution (as reported by the authoritative
|
|
30
|
+
`test/runtime/debug/api-contract.test.ts` runner) is `9 live / 18
|
|
31
|
+
live-with-adapter / 1 partial / 7 mock / 35 total`. See the Changelog
|
|
32
|
+
in [`docs/reference/public-api.md`](../../../docs/reference/public-api.md)
|
|
33
|
+
for the latest entry.
|
|
34
|
+
|
|
35
|
+
## What this directory is NOT
|
|
36
|
+
|
|
37
|
+
- NOT a re-export of the existing `WordReviewEditorRef`. The two CI
|
|
38
|
+
guards `scripts/ci-check-api-v3-no-ref-reexport.mjs` and
|
|
39
|
+
`scripts/ci-check-api-v3-metadata.mjs` enforce this. Adding a
|
|
40
|
+
convenience re-export of a ref method trips the guard.
|
|
41
|
+
- NOT the place for internal runtime refactoring (`src/session/`,
|
|
42
|
+
`src/runtime/formatting/`, etc.). That work lands behind this
|
|
43
|
+
surface — v3 stays stable while internals move.
|
|
44
|
+
- NOT a sandbox. `status: "live"` functions MUST parity-match the
|
|
45
|
+
underlying runtime behavior (asserted in per-family tests).
|
|
46
|
+
|
|
47
|
+
## Consumers
|
|
48
|
+
|
|
49
|
+
- **Beyond Work build team** (canonical). Import via
|
|
50
|
+
`import { createApiV3 } from "@beyondwork/docx-react-component/api/v3"`.
|
|
51
|
+
- **Debug UX (Phase Q)**. Uses `UxResponse` events to render mock-or-live
|
|
52
|
+
visualizations.
|
|
53
|
+
- **Phase D runners** (Layer-level validators). Use `createApiV3` as the
|
|
54
|
+
single entry point so runners don't depend on internal runtime shape.
|
|
55
|
+
|
|
56
|
+
## Graduating a function's status
|
|
57
|
+
|
|
58
|
+
The intended progression is `mock → partial → live-with-adapter → live`.
|
|
59
|
+
Skipping a stage is allowed when justified, but each flip requires
|
|
60
|
+
evidence:
|
|
61
|
+
|
|
62
|
+
1. Implement the live path (delegate to the appropriate runtime
|
|
63
|
+
facet or layer extractor). For `live-with-adapter`, write the
|
|
64
|
+
adapter/composition in the family file; for `live`, the body
|
|
65
|
+
must be a single delegation call.
|
|
66
|
+
2. Add a validator log entry under `services/debug/docs/` with the
|
|
67
|
+
new evidence.
|
|
68
|
+
3. Update the function's `<fnName>Metadata.liveEvidence` field to
|
|
69
|
+
point at the log + the commit SHA; update `mockShape` per the
|
|
70
|
+
taxonomy rules above (required for `mock` and `partial`, optional
|
|
71
|
+
for `live-with-adapter`, forbidden for `live`).
|
|
72
|
+
4. Update the per-family test's parity assertion and the matching
|
|
73
|
+
inline `// @endStateApi — <status>.` comment on the function
|
|
74
|
+
body so the status-drift canary stays green.
|
|
75
|
+
|
|
76
|
+
Silent flips — changing `status` without updating `liveEvidence` or
|
|
77
|
+
the inline annotation — are a review-time reject.
|
|
78
|
+
|
|
79
|
+
## Canonical reference doc
|
|
80
|
+
|
|
81
|
+
[`docs/reference/public-api.md`](../../../docs/reference/public-api.md).
|
|
82
|
+
That's the URL the BW team bookmarks. This README is the in-repo
|
|
83
|
+
maintainer-facing companion.
|
|
84
|
+
|
|
85
|
+
## Phase Q (debug UX refactor) dependency
|
|
86
|
+
|
|
87
|
+
Phase Q ships a runtime-embedded debug UX (`src/ui-tailwind/debug/**`)
|
|
88
|
+
that subscribes to the `UxResponse` event stream emitted from this
|
|
89
|
+
directory. Phase Q does NOT re-import the existing harness debug
|
|
90
|
+
panel — it renders against `UxResponse` + `runtime.debug.getSnapshot`
|
|
91
|
+
directly. See the Phase P plan for the full Phase Q spec.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — `createApiV3(runtime)` entry point.
|
|
3
|
+
*
|
|
4
|
+
* Single binding point. Every v3 family is a record of functions bound to
|
|
5
|
+
* the runtime supplied here. Consumers get one value with typed sub-namespaces:
|
|
6
|
+
*
|
|
7
|
+
* const api = createApiV3(runtime);
|
|
8
|
+
* await api.runtime.review.getComments();
|
|
9
|
+
* await api.ai.inspectDocument();
|
|
10
|
+
*
|
|
11
|
+
* No other import path is supported. The family modules under `runtime/**`
|
|
12
|
+
* and `ai/**` export `createXxxFamily(runtime)` factories; this file wires
|
|
13
|
+
* them. The resulting object is frozen to prevent monkey-patching.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { RuntimeApiHandle } from "./_runtime-handle.ts";
|
|
17
|
+
|
|
18
|
+
import { createDocumentFamily } from "./runtime/document.ts";
|
|
19
|
+
import { createContentFamily } from "./runtime/content.ts";
|
|
20
|
+
import { createReviewFamily } from "./runtime/review.ts";
|
|
21
|
+
import { createWorkflowFamily } from "./runtime/workflow.ts";
|
|
22
|
+
import { createLayoutFamily } from "./runtime/layout.ts";
|
|
23
|
+
import { createGeometryFamily } from "./runtime/geometry.ts";
|
|
24
|
+
import { createCollabFamily } from "./runtime/collab.ts";
|
|
25
|
+
import { createFormattingFamily } from "./runtime/formatting.ts";
|
|
26
|
+
import { createClipboardFamily } from "./runtime/clipboard.ts";
|
|
27
|
+
import { createChartFamily } from "./runtime/chart.ts";
|
|
28
|
+
import { createSearchFamily } from "./runtime/search.ts";
|
|
29
|
+
import { createTableFamily } from "./runtime/table.ts";
|
|
30
|
+
|
|
31
|
+
import { createInspectFamily } from "./ai/inspect.ts";
|
|
32
|
+
import { createResolveFamily } from "./ai/resolve.ts";
|
|
33
|
+
import { createBundleFamily } from "./ai/bundle.ts";
|
|
34
|
+
import { createReplacementFamily } from "./ai/replacement.ts";
|
|
35
|
+
import { createAttachFamily } from "./ai/attach.ts";
|
|
36
|
+
import { createExportFamily } from "./ai/export.ts";
|
|
37
|
+
import { createExplainFamily } from "./ai/explain.ts";
|
|
38
|
+
import { createPolicyFamily } from "./ai/policy.ts";
|
|
39
|
+
|
|
40
|
+
import { createUiApi } from "./ui/_create.ts";
|
|
41
|
+
import type { ApiV3Ui, UiControllerFactory } from "./ui/_types.ts";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @endStateApi
|
|
45
|
+
* End-state v3 API surface. See `docs/reference/public-api.md`.
|
|
46
|
+
*
|
|
47
|
+
* Shape mirrors `docs/architecture/00-overview.md §Runtime API vs AI API`:
|
|
48
|
+
* runtime.* is sub-grouped (document/content/review/workflow/layout/geometry);
|
|
49
|
+
* ai.* is intentionally flat (inspectDocument / resolveReference / etc.) so
|
|
50
|
+
* agents call them as single-level tools without sub-namespace stitching.
|
|
51
|
+
*/
|
|
52
|
+
export type ApiV3Runtime = {
|
|
53
|
+
readonly document: ReturnType<typeof createDocumentFamily>;
|
|
54
|
+
readonly content: ReturnType<typeof createContentFamily>;
|
|
55
|
+
readonly review: ReturnType<typeof createReviewFamily>;
|
|
56
|
+
readonly workflow: ReturnType<typeof createWorkflowFamily>;
|
|
57
|
+
readonly layout: ReturnType<typeof createLayoutFamily>;
|
|
58
|
+
readonly geometry: ReturnType<typeof createGeometryFamily>;
|
|
59
|
+
readonly collab: ReturnType<typeof createCollabFamily>;
|
|
60
|
+
readonly formatting: ReturnType<typeof createFormattingFamily>;
|
|
61
|
+
readonly clipboard: ReturnType<typeof createClipboardFamily>;
|
|
62
|
+
readonly chart: ReturnType<typeof createChartFamily>;
|
|
63
|
+
readonly search: ReturnType<typeof createSearchFamily>;
|
|
64
|
+
readonly table: ReturnType<typeof createTableFamily>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type ApiV3Ai = ReturnType<typeof createInspectFamily>
|
|
68
|
+
& ReturnType<typeof createResolveFamily>
|
|
69
|
+
& ReturnType<typeof createBundleFamily>
|
|
70
|
+
& ReturnType<typeof createReplacementFamily>
|
|
71
|
+
& ReturnType<typeof createAttachFamily>
|
|
72
|
+
& ReturnType<typeof createExportFamily>
|
|
73
|
+
& ReturnType<typeof createExplainFamily>
|
|
74
|
+
& ReturnType<typeof createPolicyFamily>;
|
|
75
|
+
|
|
76
|
+
export interface ApiV3 {
|
|
77
|
+
readonly runtime: ApiV3Runtime;
|
|
78
|
+
readonly ai: ApiV3Ai;
|
|
79
|
+
/**
|
|
80
|
+
* UI API namespace. Present iff the caller passed
|
|
81
|
+
* `createApiV3(handle, { ui: factory })`. Hosts that do not mount a
|
|
82
|
+
* React surface (services/debug, headless tests, stateless agents)
|
|
83
|
+
* omit the factory and get `{ runtime, ai }` only.
|
|
84
|
+
*/
|
|
85
|
+
readonly ui?: ApiV3Ui;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @endStateApi
|
|
90
|
+
* Optional construction options. Currently only `ui` — a
|
|
91
|
+
* `UiControllerFactory` that the UI API consumes to wire mounted-surface
|
|
92
|
+
* dispatch + subscription hooks. Additive; hosts that only need runtime
|
|
93
|
+
* + AI drop the options argument entirely.
|
|
94
|
+
*
|
|
95
|
+
* Per the staircase in `docs/plans/refactor-master-plan.md §2`:
|
|
96
|
+
* /07 Slice 1 (RuntimeApiHandle) → /10 Slice 1 (src/api/v3/ui/**) →
|
|
97
|
+
* /07 Slice 2 (this extension).
|
|
98
|
+
*/
|
|
99
|
+
export interface CreateApiV3Opts {
|
|
100
|
+
readonly ui?: UiControllerFactory;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @endStateApi
|
|
105
|
+
* Single entry point. Returns a frozen `ApiV3` bound to the handle. Back-
|
|
106
|
+
* compat: `createApiV3(handle)` still returns `{ runtime, ai }` without a
|
|
107
|
+
* `ui` property so existing callers (services/debug, headless drivers)
|
|
108
|
+
* stay green.
|
|
109
|
+
*/
|
|
110
|
+
export function createApiV3(handle: RuntimeApiHandle, opts?: CreateApiV3Opts): ApiV3 {
|
|
111
|
+
const ai: ApiV3Ai = {
|
|
112
|
+
...createInspectFamily(handle),
|
|
113
|
+
...createResolveFamily(handle),
|
|
114
|
+
...createBundleFamily(handle),
|
|
115
|
+
...createReplacementFamily(handle),
|
|
116
|
+
...createAttachFamily(handle),
|
|
117
|
+
...createExportFamily(handle),
|
|
118
|
+
...createExplainFamily(handle),
|
|
119
|
+
...createPolicyFamily(handle),
|
|
120
|
+
};
|
|
121
|
+
const runtime: ApiV3Runtime = {
|
|
122
|
+
document: createDocumentFamily(handle),
|
|
123
|
+
content: createContentFamily(handle),
|
|
124
|
+
review: createReviewFamily(handle),
|
|
125
|
+
workflow: createWorkflowFamily(handle),
|
|
126
|
+
layout: createLayoutFamily(handle),
|
|
127
|
+
geometry: createGeometryFamily(handle),
|
|
128
|
+
collab: createCollabFamily(handle),
|
|
129
|
+
formatting: createFormattingFamily(handle),
|
|
130
|
+
clipboard: createClipboardFamily(handle),
|
|
131
|
+
chart: createChartFamily(handle),
|
|
132
|
+
search: createSearchFamily(handle),
|
|
133
|
+
table: createTableFamily(handle),
|
|
134
|
+
};
|
|
135
|
+
// Construct the UI namespace only when a factory is supplied.
|
|
136
|
+
// `ui` remains `undefined` otherwise — the shape in ApiV3 is optional
|
|
137
|
+
// so consumer snapshot tests that already assert `{ runtime, ai }`
|
|
138
|
+
// continue to match.
|
|
139
|
+
const ui: ApiV3Ui | undefined = opts?.ui ? createUiApi(handle, opts.ui) : undefined;
|
|
140
|
+
|
|
141
|
+
const api: ApiV3 = ui ? { runtime, ai, ui } : { runtime, ai };
|
|
142
|
+
Object.freeze(api.runtime);
|
|
143
|
+
Object.freeze(api.ai);
|
|
144
|
+
// api.ui is already frozen by createUiApi.
|
|
145
|
+
return Object.freeze(api);
|
|
146
|
+
}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @endStateApi v3 — metadata primitives. See docs/reference/public-api.md.
|
|
3
|
+
*
|
|
4
|
+
* Every exported v3 function has a sibling `<fnName>Metadata: ApiV3FnMetadata`
|
|
5
|
+
* export. The two CI guards under `scripts/ci-check-api-v3-*.mjs` enforce this.
|
|
6
|
+
* Replacing a mock with a live implementation requires updating `liveEvidence`
|
|
7
|
+
* with a validator log + commit SHA.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @endStateApi
|
|
12
|
+
* 4-status discriminator (Phase P' taxonomy).
|
|
13
|
+
*
|
|
14
|
+
* - `mock` — no valid runtime-backed path yet; deterministic mock only.
|
|
15
|
+
* - `partial` — some behavior is real and some is still mocked (e.g. read
|
|
16
|
+
* path live, write path mocked; or only a subset of the contract
|
|
17
|
+
* satisfied).
|
|
18
|
+
* - `live-with-adapter` — a valid shipped runtime/facet/debug candidate
|
|
19
|
+
* exists and the contract is semantically supportable now, but only
|
|
20
|
+
* through a nontrivial adapter / rebinding / composition layer rather
|
|
21
|
+
* than direct 1:1 delegation. Stays visible in metadata until the
|
|
22
|
+
* adapter is promoted to a first-class surface or replaced by a
|
|
23
|
+
* cleaner underlying contract.
|
|
24
|
+
* - `live` — direct delegation to a shipped runtime contract (no
|
|
25
|
+
* meaningful adapter debt).
|
|
26
|
+
*/
|
|
27
|
+
export type ApiStatus = "mock" | "partial" | "live-with-adapter" | "live";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @endStateApi
|
|
31
|
+
* 11-layer taxonomy from `docs/architecture/00-overview.md § Target End-State
|
|
32
|
+
* Stack`. Each v3 function declares which layer it belongs to so future
|
|
33
|
+
* layer-extraction refactors can move the implementation behind the surface
|
|
34
|
+
* without breaking consumers.
|
|
35
|
+
*/
|
|
36
|
+
export type SourceLayer =
|
|
37
|
+
| "beyond-work-substrate"
|
|
38
|
+
| "package-session"
|
|
39
|
+
| "canonical"
|
|
40
|
+
| "formatting-semantics"
|
|
41
|
+
| "layout-semantics"
|
|
42
|
+
| "geometry-projection"
|
|
43
|
+
| "workflow-review"
|
|
44
|
+
| "runtime-core"
|
|
45
|
+
| "semantic-scope-compiler"
|
|
46
|
+
| "ai"
|
|
47
|
+
| "presentation";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @endStateApi
|
|
51
|
+
* Pointers to the evidence that backs a `live` or `partial` claim. At least
|
|
52
|
+
* one of these fields is required for a non-mock function; mock functions
|
|
53
|
+
* leave this undefined.
|
|
54
|
+
*/
|
|
55
|
+
export interface LiveEvidence {
|
|
56
|
+
readonly validatorLog?: string;
|
|
57
|
+
readonly runnerTest?: string;
|
|
58
|
+
readonly probeScript?: string;
|
|
59
|
+
readonly commit?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @endStateApi
|
|
64
|
+
* Shape declaration for mock-returning functions. Every mock payload carries
|
|
65
|
+
* `__mock: true` so consumer tests can snapshot against it without
|
|
66
|
+
* accidentally depending on mock-specific fields in production code.
|
|
67
|
+
*/
|
|
68
|
+
export interface MockShape {
|
|
69
|
+
readonly deterministic: boolean;
|
|
70
|
+
readonly seededFrom?: "documentId" | "hash" | "fixed" | "counter";
|
|
71
|
+
readonly shapeDescription: string;
|
|
72
|
+
readonly carriesMockFlag: true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @endStateApi
|
|
77
|
+
* UX expectation. Functions with `uiVisible: true` MUST emit exactly one
|
|
78
|
+
* UxResponse event on the `api` channel per invocation. Asserted in tests.
|
|
79
|
+
*/
|
|
80
|
+
export interface UxIntent {
|
|
81
|
+
readonly uiVisible: boolean;
|
|
82
|
+
readonly expectsUxResponse?:
|
|
83
|
+
| "toast"
|
|
84
|
+
| "overlay"
|
|
85
|
+
| "inline-change"
|
|
86
|
+
| "surface-refresh"
|
|
87
|
+
| "selection-change"
|
|
88
|
+
| "warning-added"
|
|
89
|
+
| "scope-created"
|
|
90
|
+
| "none";
|
|
91
|
+
readonly expectedDelta?: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @endStateApi
|
|
96
|
+
* Agent-facing metadata. Drives prompt-context inclusion, audit categorization,
|
|
97
|
+
* and policy hinting in the future Beyond Work agent surface.
|
|
98
|
+
*/
|
|
99
|
+
export interface AgentMetadata {
|
|
100
|
+
readonly readOrMutate: "read" | "mutate" | "compound";
|
|
101
|
+
readonly boundedScope?: "document" | "scope" | "selection" | "session";
|
|
102
|
+
readonly auditCategory?: string;
|
|
103
|
+
readonly policyHints?: readonly string[];
|
|
104
|
+
readonly contextPromptShape?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @endStateApi
|
|
109
|
+
* Shape contract for UI-API subscription-style channels. When a
|
|
110
|
+
* `bidirectional: true` function produces an ongoing stream rather
|
|
111
|
+
* than a single request/response (e.g. `ui.viewport.subscribe`), its
|
|
112
|
+
* metadata carries this record so consumers can reason about the
|
|
113
|
+
* payload and coalescing discipline without reading the implementation.
|
|
114
|
+
*
|
|
115
|
+
* - `eventType` — the `ux.response.<fn>.subscribed` event emitted once
|
|
116
|
+
* per subscribe call (the seam acknowledgement) AND the ongoing
|
|
117
|
+
* event type the bind-side pushes per coalesced tick.
|
|
118
|
+
* - `payloadType` — a human-readable name for the payload shape
|
|
119
|
+
* (matches an exported TS type name like `"ViewportState"`).
|
|
120
|
+
* - `coalescing` — how the bind-side batches upstream events before
|
|
121
|
+
* firing the listener. `"raf"` is the default for viewport /
|
|
122
|
+
* overlay channels; `"microtask"` for state-store-backed posture;
|
|
123
|
+
* `"immediate"` only when the upstream already throttles.
|
|
124
|
+
*/
|
|
125
|
+
export interface SubscriptionShape {
|
|
126
|
+
readonly eventType: string;
|
|
127
|
+
readonly payloadType: string;
|
|
128
|
+
readonly coalescing: "raf" | "microtask" | "immediate";
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @endStateApi
|
|
133
|
+
* Complete metadata record. `liveEvidence` is required when `status !==
|
|
134
|
+
* "mock"`; `mockShape` is required when `status !== "live"`. A function can
|
|
135
|
+
* be both (partial: both live and mock in different paths).
|
|
136
|
+
*
|
|
137
|
+
* `bidirectional` + `subscriptionShape` are UI-API specific fields added
|
|
138
|
+
* by refactor/07 Slice 2. A function is `bidirectional: true` when it
|
|
139
|
+
* carries data across the runtime ↔ UI seam in both directions — either
|
|
140
|
+
* as a dispatch/echo pair (`ui.surface.setSelection` requests, runtime
|
|
141
|
+
* emits `selection.changed`) or as a subscribe/stream pair (the
|
|
142
|
+
* subscribe call establishes the channel, the runtime pushes events).
|
|
143
|
+
* The invariant asserted by `validateApiV3Metadata` is:
|
|
144
|
+
* bidirectional: true ⇒ uxIntent.uiVisible: true
|
|
145
|
+
* ∧ (dispatch form: expectsUxResponse != "none")
|
|
146
|
+
* ∨ (stream form: subscriptionShape present)
|
|
147
|
+
* Dispatch-form functions (no `subscriptionShape`) must emit exactly one
|
|
148
|
+
* `ux.response.<fn>` event per invocation; stream-form functions
|
|
149
|
+
* (`subscriptionShape` present) emit exactly one
|
|
150
|
+
* `ux.response.<fn>.subscribed` event on the establishing call, then
|
|
151
|
+
* deliver events through the subscription.
|
|
152
|
+
*/
|
|
153
|
+
/**
|
|
154
|
+
* @endStateApi
|
|
155
|
+
* Three-way state model classifier (per `docs/architecture/00-overview.md §9.1`
|
|
156
|
+
* + `07-runtime-api.md §R9`).
|
|
157
|
+
*
|
|
158
|
+
* - `A-canonical` — document-authored state. Lives in the canonical
|
|
159
|
+
* document or its overlay; persists across sessions; broadcasts via
|
|
160
|
+
* CRDT (Yjs). Examples: scope metadata, comments, tracked changes.
|
|
161
|
+
* - `B-session` — session-shared transient state. Present for the
|
|
162
|
+
* duration of a session, shared across tabs/peers in the same session
|
|
163
|
+
* via Awareness; does not persist beyond the session. Examples:
|
|
164
|
+
* presence, posture, cursor position.
|
|
165
|
+
* - `C-local` — local view preference. Never leaves the user's tab.
|
|
166
|
+
* Does not persist in the document or the session. Examples: UI
|
|
167
|
+
* overlay visibility, chrome posture, viewport scroll.
|
|
168
|
+
*/
|
|
169
|
+
export type StateClass = "A-canonical" | "B-session" | "C-local";
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @endStateApi
|
|
173
|
+
* Persistence target for a function's effect.
|
|
174
|
+
*
|
|
175
|
+
* - `canonical` — write lands in the canonical document structure
|
|
176
|
+
* (class-A mutation that rides a scope-scoped command).
|
|
177
|
+
* - `customXml` — write lands in the `bw:*` customXml overlay parts
|
|
178
|
+
* (class-A workflow mutation — scopes, metadata, visibility policy).
|
|
179
|
+
* - `none` — function does not persist (reads, local-view toggles,
|
|
180
|
+
* transient session-shared broadcasts).
|
|
181
|
+
*/
|
|
182
|
+
export type PersistsTo = "canonical" | "customXml" | "none";
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @endStateApi
|
|
186
|
+
* Transport for class-A or class-B broadcasts.
|
|
187
|
+
*
|
|
188
|
+
* - `crdt` — Yjs document broadcast. Eventually-consistent with
|
|
189
|
+
* deterministic merge. Used by class-A mutations.
|
|
190
|
+
* - `awareness` — Y.Awareness ephemeral broadcast. Last-writer-wins,
|
|
191
|
+
* bounded per-peer. Used by class-B session-shared state.
|
|
192
|
+
*
|
|
193
|
+
* Omit for class-C (local-only) functions.
|
|
194
|
+
*/
|
|
195
|
+
export type BroadcastsVia = "crdt" | "awareness";
|
|
196
|
+
|
|
197
|
+
export interface ApiV3FnMetadata {
|
|
198
|
+
readonly name: string;
|
|
199
|
+
readonly status: ApiStatus;
|
|
200
|
+
readonly sourceLayer: SourceLayer;
|
|
201
|
+
readonly liveEvidence?: LiveEvidence;
|
|
202
|
+
readonly mockShape?: MockShape;
|
|
203
|
+
readonly uxIntent: UxIntent;
|
|
204
|
+
readonly agentMetadata: AgentMetadata;
|
|
205
|
+
readonly rwdReference?: string;
|
|
206
|
+
readonly bidirectional?: boolean;
|
|
207
|
+
readonly subscriptionShape?: SubscriptionShape;
|
|
208
|
+
/**
|
|
209
|
+
* @endStateApi
|
|
210
|
+
* Three-way state class (§R9 / §9.1). Required on every metadata
|
|
211
|
+
* record. CI-guard-enforced with namespace-class coherence rules:
|
|
212
|
+
*
|
|
213
|
+
* - `ui.*` → `C-local`
|
|
214
|
+
* - `runtime.collab.*` → `B-session`
|
|
215
|
+
* - `runtime.workflow.*` → `A-canonical`
|
|
216
|
+
* - Other `runtime.*` → `A-canonical` (per namespace rules below)
|
|
217
|
+
* - `ai.*` → follows the runtime function it delegates to
|
|
218
|
+
*/
|
|
219
|
+
readonly stateClass: StateClass;
|
|
220
|
+
/**
|
|
221
|
+
* @endStateApi
|
|
222
|
+
* Where a mutation's effect lands. Required on every metadata
|
|
223
|
+
* record. Rules:
|
|
224
|
+
*
|
|
225
|
+
* - `C-local` ⇒ `"none"`
|
|
226
|
+
* - `B-session` ⇒ `"none"`
|
|
227
|
+
* - `A-canonical` + read ⇒ `"none"`
|
|
228
|
+
* - `A-canonical` + runtime.workflow mutate ⇒ `"customXml"`
|
|
229
|
+
* - `A-canonical` + other runtime mutate ⇒ `"canonical"`
|
|
230
|
+
*/
|
|
231
|
+
readonly persistsTo: PersistsTo;
|
|
232
|
+
/**
|
|
233
|
+
* @endStateApi
|
|
234
|
+
* Broadcast transport. Required for class-B and for class-A
|
|
235
|
+
* mutations; forbidden for class-C.
|
|
236
|
+
*
|
|
237
|
+
* - `B-session` ⇒ `"awareness"`
|
|
238
|
+
* - `A-canonical` + runtime.workflow mutate ⇒ `"crdt"`
|
|
239
|
+
* - `A-canonical` + other ⇒ optional (`"crdt"` when the write
|
|
240
|
+
* broadcasts to peers; omit when it's purely local/read)
|
|
241
|
+
* - `C-local` ⇒ omit
|
|
242
|
+
*/
|
|
243
|
+
readonly broadcastsVia?: BroadcastsVia;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @endStateApi
|
|
248
|
+
* Marker type every mock payload uses. Consumer code can narrow on
|
|
249
|
+
* `__mock: true` to explicitly branch test doubles vs. real responses.
|
|
250
|
+
*/
|
|
251
|
+
export interface MockPayload {
|
|
252
|
+
readonly __mock: true;
|
|
253
|
+
readonly reason: string;
|
|
254
|
+
readonly shape: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @endStateApi
|
|
259
|
+
* Validate a metadata record. Used by CI guards + runtime tests. Returns
|
|
260
|
+
* null if valid; returns a human-readable error string otherwise.
|
|
261
|
+
*
|
|
262
|
+
* Contract (intentional asymmetry — do not "tighten"):
|
|
263
|
+
* - `liveEvidence` is required whenever status ≠ `mock` (live,
|
|
264
|
+
* live-with-adapter, partial all need evidence).
|
|
265
|
+
* - `mockShape` is required only for `mock` or `partial` — adapter-
|
|
266
|
+
* backed functions with a fallback branch SHOULD declare `mockShape`
|
|
267
|
+
* for the fallback, but bare `live-with-adapter` functions that
|
|
268
|
+
* return null instead of a mock-flagged payload are valid without it.
|
|
269
|
+
* `live` functions never carry `mockShape`.
|
|
270
|
+
*/
|
|
271
|
+
export function validateApiV3Metadata(m: ApiV3FnMetadata): string | null {
|
|
272
|
+
if (!m.name || typeof m.name !== "string") return "missing name";
|
|
273
|
+
if (!m.status) return "missing status";
|
|
274
|
+
if (!m.sourceLayer) return "missing sourceLayer";
|
|
275
|
+
if (!m.uxIntent) return "missing uxIntent";
|
|
276
|
+
if (typeof m.uxIntent.uiVisible !== "boolean") return "uxIntent.uiVisible must be boolean";
|
|
277
|
+
if (!m.agentMetadata) return "missing agentMetadata";
|
|
278
|
+
if (!m.agentMetadata.readOrMutate) return "missing agentMetadata.readOrMutate";
|
|
279
|
+
if (m.status !== "mock" && !m.liveEvidence) {
|
|
280
|
+
return `status "${m.status}" requires liveEvidence`;
|
|
281
|
+
}
|
|
282
|
+
const mockShapeRequired = m.status === "mock" || m.status === "partial";
|
|
283
|
+
if (mockShapeRequired && !m.mockShape) {
|
|
284
|
+
return `status "${m.status}" requires mockShape`;
|
|
285
|
+
}
|
|
286
|
+
if (m.mockShape && m.mockShape.carriesMockFlag !== true) {
|
|
287
|
+
return "mockShape.carriesMockFlag must be true";
|
|
288
|
+
}
|
|
289
|
+
if (m.bidirectional === true) {
|
|
290
|
+
if (m.uxIntent.uiVisible !== true) {
|
|
291
|
+
return "bidirectional: true requires uxIntent.uiVisible: true";
|
|
292
|
+
}
|
|
293
|
+
const hasStream = !!m.subscriptionShape;
|
|
294
|
+
const hasDispatch =
|
|
295
|
+
typeof m.uxIntent.expectsUxResponse === "string" &&
|
|
296
|
+
m.uxIntent.expectsUxResponse !== "none";
|
|
297
|
+
if (!hasStream && !hasDispatch) {
|
|
298
|
+
return (
|
|
299
|
+
"bidirectional: true requires either subscriptionShape (stream form) " +
|
|
300
|
+
"or uxIntent.expectsUxResponse != 'none' (dispatch form)"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (m.subscriptionShape) {
|
|
305
|
+
const s = m.subscriptionShape;
|
|
306
|
+
if (!s.eventType || typeof s.eventType !== "string") {
|
|
307
|
+
return "subscriptionShape.eventType must be a non-empty string";
|
|
308
|
+
}
|
|
309
|
+
if (!s.payloadType || typeof s.payloadType !== "string") {
|
|
310
|
+
return "subscriptionShape.payloadType must be a non-empty string";
|
|
311
|
+
}
|
|
312
|
+
if (s.coalescing !== "raf" && s.coalescing !== "microtask" && s.coalescing !== "immediate") {
|
|
313
|
+
return "subscriptionShape.coalescing must be 'raf' | 'microtask' | 'immediate'";
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Three-way state model checks (§R9). `stateClass` describes where the
|
|
317
|
+
// function's state LIVES; `persistsTo` and `broadcastsVia` describe the
|
|
318
|
+
// persistence home + broadcast transport of that state class (not the
|
|
319
|
+
// per-call effect). Reads and mutations of the same class share the same
|
|
320
|
+
// values. CI guard `scripts/ci-check-api-v3-metadata.mjs` runs the
|
|
321
|
+
// namespace-coherence rules (which names must declare which classes)
|
|
322
|
+
// over the file AST; this validator enforces the shape invariants that
|
|
323
|
+
// are independent of the function's name.
|
|
324
|
+
if (m.stateClass !== "A-canonical" && m.stateClass !== "B-session" && m.stateClass !== "C-local") {
|
|
325
|
+
return `stateClass must be "A-canonical" | "B-session" | "C-local"; got ${JSON.stringify(m.stateClass)}`;
|
|
326
|
+
}
|
|
327
|
+
if (m.persistsTo !== "canonical" && m.persistsTo !== "customXml" && m.persistsTo !== "none") {
|
|
328
|
+
return `persistsTo must be "canonical" | "customXml" | "none"; got ${JSON.stringify(m.persistsTo)}`;
|
|
329
|
+
}
|
|
330
|
+
if (m.broadcastsVia !== undefined && m.broadcastsVia !== "crdt" && m.broadcastsVia !== "awareness") {
|
|
331
|
+
return `broadcastsVia must be "crdt" | "awareness" (or omitted); got ${JSON.stringify(m.broadcastsVia)}`;
|
|
332
|
+
}
|
|
333
|
+
// Class-C: local-only. Never persists, never broadcasts.
|
|
334
|
+
if (m.stateClass === "C-local") {
|
|
335
|
+
if (m.persistsTo !== "none") {
|
|
336
|
+
return `stateClass "C-local" requires persistsTo "none"; got ${m.persistsTo}`;
|
|
337
|
+
}
|
|
338
|
+
if (m.broadcastsVia !== undefined) {
|
|
339
|
+
return `stateClass "C-local" must omit broadcastsVia; got ${m.broadcastsVia}`;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Class-B: session-shared via awareness. Does not persist.
|
|
343
|
+
if (m.stateClass === "B-session") {
|
|
344
|
+
if (m.persistsTo !== "none") {
|
|
345
|
+
return `stateClass "B-session" requires persistsTo "none"; got ${m.persistsTo}`;
|
|
346
|
+
}
|
|
347
|
+
if (m.broadcastsVia !== "awareness") {
|
|
348
|
+
return `stateClass "B-session" requires broadcastsVia "awareness"; got ${m.broadcastsVia}`;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Class-A: document-authored. Persists canonical or customXml; may
|
|
352
|
+
// broadcast crdt (required for workflow overlay writes).
|
|
353
|
+
if (m.stateClass === "A-canonical") {
|
|
354
|
+
if (m.persistsTo === "none") {
|
|
355
|
+
return `stateClass "A-canonical" ${m.name} must persist (canonical or customXml); got "none"`;
|
|
356
|
+
}
|
|
357
|
+
if (m.broadcastsVia === "awareness") {
|
|
358
|
+
return `stateClass "A-canonical" cannot broadcast via "awareness" (class-B transport); ${m.name}`;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return null;
|
|
362
|
+
}
|