@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,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 7 adversarial-closure pass — Layer 8 compiler-service facade.
|
|
3
|
+
*
|
|
4
|
+
* A single runtime-side entry point for compiler orchestration. Before
|
|
5
|
+
* this module, v3 adapters each reconstructed the enumerate + compile
|
|
6
|
+
* + position-map dance in isolation:
|
|
7
|
+
*
|
|
8
|
+
* const doc = runtime.getCanonicalDocument();
|
|
9
|
+
* const overlay = runtime.getWorkflowOverlay();
|
|
10
|
+
* const paragraphIndexByBlockIndex = buildParagraphIndexMap(doc);
|
|
11
|
+
* for (const entry of enumerateScopes(doc, { overlay })) {
|
|
12
|
+
* const scope = compileScope(entry, {...});
|
|
13
|
+
* ...
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* The duplication drifted easily — different files rebuilt the setup
|
|
17
|
+
* with subtly different option threading, and "boundary" was a
|
|
18
|
+
* maintenance claim more than a shape.
|
|
19
|
+
*
|
|
20
|
+
* The compiler-service consolidates that orchestration. v3 adapters
|
|
21
|
+
* call `createScopeCompilerService(runtime).{compileAllScopes, compileScopeById,
|
|
22
|
+
* compileBundleById, applyReplacement, attachExplanation, createIssue}`.
|
|
23
|
+
* Each call is a fresh compile — no caching across calls (S3
|
|
24
|
+
* determinism). Within a single call, the paragraph-index-map is
|
|
25
|
+
* built once and threaded to every `compileScope` invocation.
|
|
26
|
+
*
|
|
27
|
+
* The runtime interface is declared narrowly (`CompilerServiceRuntime`)
|
|
28
|
+
* rather than depending on the full `RuntimeApiHandle`, so the facade
|
|
29
|
+
* is unit-testable with a plain object and the compiler layer stays
|
|
30
|
+
* free of upward imports it does not need.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type {
|
|
34
|
+
CompatibilityReport,
|
|
35
|
+
InteractionGuardSnapshot,
|
|
36
|
+
ScopeSessionState,
|
|
37
|
+
WorkflowMetadataEntry,
|
|
38
|
+
WorkflowMetadataSnapshot,
|
|
39
|
+
WorkflowOverlay,
|
|
40
|
+
} from "./_scope-dependencies.ts";
|
|
41
|
+
import type { CanonicalDocumentEnvelope } from "../../core/state/editor-state.ts";
|
|
42
|
+
import type { TelemetryBus } from "../debug/telemetry-bus.ts";
|
|
43
|
+
import type { AIAction } from "../workflow/ai-action-policy.ts";
|
|
44
|
+
|
|
45
|
+
import {
|
|
46
|
+
buildParagraphIndexMap,
|
|
47
|
+
buildSectionIndexByBlockIndex,
|
|
48
|
+
compileScope,
|
|
49
|
+
} from "./compile-scope.ts";
|
|
50
|
+
import { compileScopeBundleById } from "./compile-scope-bundle.ts";
|
|
51
|
+
import { enumerateScopes, type EnumeratedScope } from "./enumerate-scopes.ts";
|
|
52
|
+
import {
|
|
53
|
+
attachExplanation,
|
|
54
|
+
type AttachExplanationResult,
|
|
55
|
+
} from "./attach-explanation.ts";
|
|
56
|
+
import {
|
|
57
|
+
createIssue,
|
|
58
|
+
type CreateIssueResult,
|
|
59
|
+
type IssueSeverity,
|
|
60
|
+
type IssueStatus,
|
|
61
|
+
} from "./create-issue.ts";
|
|
62
|
+
import {
|
|
63
|
+
applyScopeReplacement,
|
|
64
|
+
type ApplyScopeReplacementResult,
|
|
65
|
+
} from "./replacement/apply.ts";
|
|
66
|
+
import { proposeReplacement } from "./replacement/propose.ts";
|
|
67
|
+
import type {
|
|
68
|
+
ReplacementOperationKind,
|
|
69
|
+
ReplacementPreservePolicy,
|
|
70
|
+
ReplacementScope,
|
|
71
|
+
RuntimeOperationPlan,
|
|
72
|
+
ScopeBundle,
|
|
73
|
+
ScopeHandle,
|
|
74
|
+
SemanticScope,
|
|
75
|
+
} from "./semantic-scope-types.ts";
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Narrow runtime-side interface the compiler-service reads + dispatches
|
|
79
|
+
* through. Declared inline rather than importing the v3 `RuntimeApiHandle`
|
|
80
|
+
* because:
|
|
81
|
+
*
|
|
82
|
+
* 1. `src/runtime/scopes/` must not import from `src/api/v3/**` (purity
|
|
83
|
+
* guard); declaring the shape here keeps the dependency downward.
|
|
84
|
+
* 2. Unit tests can satisfy this with a plain object — no full runtime
|
|
85
|
+
* needed.
|
|
86
|
+
* 3. Any real `DocumentRuntime` structurally satisfies it because its
|
|
87
|
+
* methods carry the same public-types shapes.
|
|
88
|
+
*/
|
|
89
|
+
export interface CompilerServiceRuntime {
|
|
90
|
+
getCanonicalDocument(): CanonicalDocumentEnvelope;
|
|
91
|
+
getWorkflowOverlay(): WorkflowOverlay | null;
|
|
92
|
+
getInteractionGuardSnapshot(): InteractionGuardSnapshot;
|
|
93
|
+
getCompatibilityReport(): CompatibilityReport;
|
|
94
|
+
getWorkflowMetadataSnapshot(): WorkflowMetadataSnapshot;
|
|
95
|
+
setWorkflowMetadataEntries(entries: readonly WorkflowMetadataEntry[]): void;
|
|
96
|
+
getSessionState(): ScopeSessionState;
|
|
97
|
+
applyScopeReplacement(plan: RuntimeOperationPlan): void;
|
|
98
|
+
debug?: { bus: TelemetryBus };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface CompileScopeByIdResult {
|
|
102
|
+
readonly scope: SemanticScope;
|
|
103
|
+
readonly document: CanonicalDocumentEnvelope;
|
|
104
|
+
readonly enumerated: EnumeratedScope;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface ApplyReplacementRequest {
|
|
108
|
+
readonly targetScopeId: string;
|
|
109
|
+
readonly operation: ReplacementOperationKind;
|
|
110
|
+
/**
|
|
111
|
+
* Flat text payload. Shorthand for
|
|
112
|
+
* `proposedContent: {kind: "text", text}`. Ignored when
|
|
113
|
+
* `proposedContent` is supplied.
|
|
114
|
+
*/
|
|
115
|
+
readonly proposedText?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Full proposed-content shape. Use this for structured-fragment
|
|
118
|
+
* replacement (`kind: "structured"` with a
|
|
119
|
+
* `CanonicalDocumentFragment`-shaped payload). Unblocks /09
|
|
120
|
+
* `cross-layer-coord-09.md §1.5`: v3 consumers that need to pass a
|
|
121
|
+
* structured fragment through `ai.applyReplacementScope` supply it
|
|
122
|
+
* here. Widened 2026-04-22 after L08's structured-fragment runtime
|
|
123
|
+
* dispatch shipped (see `cross-layer-coord-08.md §8`).
|
|
124
|
+
*/
|
|
125
|
+
readonly proposedContent?: ReplacementScope["proposedContent"];
|
|
126
|
+
readonly preserve?: ReplacementPreservePolicy;
|
|
127
|
+
readonly reason?: string;
|
|
128
|
+
readonly actionId?: AIAction;
|
|
129
|
+
readonly actorId: string;
|
|
130
|
+
readonly origin: "ui" | "agent" | "host";
|
|
131
|
+
readonly emittedAtUtc: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface AttachExplanationRequest {
|
|
135
|
+
readonly scopeId: string;
|
|
136
|
+
readonly explanation: string;
|
|
137
|
+
readonly explanationId?: string;
|
|
138
|
+
readonly createdAtUtc?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface CreateIssueRequest {
|
|
142
|
+
readonly scopeId: string;
|
|
143
|
+
readonly summary: string;
|
|
144
|
+
readonly severity?: IssueSeverity;
|
|
145
|
+
readonly issueId?: string;
|
|
146
|
+
readonly createdAtUtc?: string;
|
|
147
|
+
readonly status?: IssueStatus;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface ScopeCompilerService {
|
|
151
|
+
/**
|
|
152
|
+
* Enumerate + compile every live scope in the document. Per-call the
|
|
153
|
+
* paragraph-index-map is built once and shared across every compile.
|
|
154
|
+
* Callers filter / limit on the returned array.
|
|
155
|
+
*/
|
|
156
|
+
compileAllScopes(): SemanticScope[];
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Resolve a scopeId against the live enumeration + compile it. Returns
|
|
160
|
+
* null when the id does not enumerate. Also surfaces the raw
|
|
161
|
+
* `EnumeratedScope` + `document` so callers that need to compose a
|
|
162
|
+
* downstream operation (e.g. per-kind replacement compile) do not have
|
|
163
|
+
* to re-enumerate.
|
|
164
|
+
*/
|
|
165
|
+
compileScopeById(scopeId: string): CompileScopeByIdResult | null;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Compile a `ScopeBundle` keyed by id. Delegates to
|
|
169
|
+
* `compileScopeBundleById`; `nowUtc` is caller-supplied per S3
|
|
170
|
+
* (determinism) — no `new Date()` fallback.
|
|
171
|
+
*/
|
|
172
|
+
compileBundleById(scopeId: string, nowUtc: string): ScopeBundle | null;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Build a `ReplacementScope` from a plain request + the resolved
|
|
176
|
+
* handle. The `proposedAtUtc` stamp is caller-supplied; pass a fixed
|
|
177
|
+
* reference instant in tests.
|
|
178
|
+
*/
|
|
179
|
+
buildReplacementScope(
|
|
180
|
+
targetHandle: ScopeHandle,
|
|
181
|
+
input: {
|
|
182
|
+
readonly operation: ReplacementOperationKind;
|
|
183
|
+
readonly proposedText?: string;
|
|
184
|
+
readonly preserve?: ReplacementPreservePolicy;
|
|
185
|
+
readonly reason?: string;
|
|
186
|
+
readonly proposedAtUtc: string;
|
|
187
|
+
},
|
|
188
|
+
): ReplacementScope;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Run the full propose → re-validate → compile → apply pipeline and
|
|
192
|
+
* emit exactly one `ScopeActionAudit` on the `scope` telemetry
|
|
193
|
+
* channel. Refuses with a typed `ApplyScopeReplacementResult` when
|
|
194
|
+
* validation is unsafe or compile refuses the kind; no dispatch
|
|
195
|
+
* happens in those cases.
|
|
196
|
+
*/
|
|
197
|
+
applyReplacement(request: ApplyReplacementRequest): ApplyScopeReplacementResult;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Attach an agent-authored explanation via the Layer-06
|
|
201
|
+
* `attachScopeMetadata` writer. Resolves against the workflow
|
|
202
|
+
* overlay first, then falls back to a paragraph/heading/list-item
|
|
203
|
+
* derived-scope resolver (coord-06 §13c). Returns
|
|
204
|
+
* `{attached: false, reason: "scope-not-resolvable:…"}` for
|
|
205
|
+
* scopeIds neither path can resolve (e.g. `table:*`, `field:*`,
|
|
206
|
+
* arbitrary host strings).
|
|
207
|
+
*/
|
|
208
|
+
attachExplanation(request: AttachExplanationRequest): AttachExplanationResult;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Create an agent-authored issue on an overlay scope. Same
|
|
212
|
+
* overlay-only constraint as `attachExplanation`.
|
|
213
|
+
*/
|
|
214
|
+
createIssue(request: CreateIssueRequest): CreateIssueResult;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Factory for the Layer-08 compiler-service facade.
|
|
219
|
+
*
|
|
220
|
+
* Stateless — every call enumerates + compiles fresh. Callers pay the
|
|
221
|
+
* cost per call; callers that compile the same document repeatedly
|
|
222
|
+
* within a tight loop should hoist the `compileAllScopes()` result
|
|
223
|
+
* themselves (the compiler does not internally cache).
|
|
224
|
+
*/
|
|
225
|
+
export function createScopeCompilerService(
|
|
226
|
+
runtime: CompilerServiceRuntime,
|
|
227
|
+
): ScopeCompilerService {
|
|
228
|
+
function allEnumerated(): {
|
|
229
|
+
readonly document: CanonicalDocumentEnvelope;
|
|
230
|
+
readonly overlay: WorkflowOverlay | null;
|
|
231
|
+
readonly paragraphIndexByBlockIndex: ReturnType<typeof buildParagraphIndexMap>;
|
|
232
|
+
readonly sectionIndexByBlockIndex: ReturnType<typeof buildSectionIndexByBlockIndex>;
|
|
233
|
+
readonly entries: readonly EnumeratedScope[];
|
|
234
|
+
} {
|
|
235
|
+
const document = runtime.getCanonicalDocument();
|
|
236
|
+
const overlay = runtime.getWorkflowOverlay();
|
|
237
|
+
const paragraphIndexByBlockIndex = buildParagraphIndexMap(document);
|
|
238
|
+
const sectionIndexByBlockIndex = buildSectionIndexByBlockIndex(document);
|
|
239
|
+
const enumerateInputs = overlay ? { overlay } : {};
|
|
240
|
+
const entries = [...enumerateScopes(document, enumerateInputs)];
|
|
241
|
+
return {
|
|
242
|
+
document,
|
|
243
|
+
overlay,
|
|
244
|
+
paragraphIndexByBlockIndex,
|
|
245
|
+
sectionIndexByBlockIndex,
|
|
246
|
+
entries,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
compileAllScopes(): SemanticScope[] {
|
|
252
|
+
const {
|
|
253
|
+
document,
|
|
254
|
+
overlay,
|
|
255
|
+
paragraphIndexByBlockIndex,
|
|
256
|
+
sectionIndexByBlockIndex,
|
|
257
|
+
entries,
|
|
258
|
+
} = allEnumerated();
|
|
259
|
+
const out: SemanticScope[] = [];
|
|
260
|
+
for (const entry of entries) {
|
|
261
|
+
const compiled = compileScope(entry, {
|
|
262
|
+
document,
|
|
263
|
+
...(overlay ? { overlay } : {}),
|
|
264
|
+
paragraphIndexByBlockIndex,
|
|
265
|
+
sectionIndexByBlockIndex,
|
|
266
|
+
});
|
|
267
|
+
if (compiled) out.push(compiled);
|
|
268
|
+
}
|
|
269
|
+
return out;
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
compileScopeById(scopeId: string): CompileScopeByIdResult | null {
|
|
273
|
+
const {
|
|
274
|
+
document,
|
|
275
|
+
overlay,
|
|
276
|
+
paragraphIndexByBlockIndex,
|
|
277
|
+
sectionIndexByBlockIndex,
|
|
278
|
+
entries,
|
|
279
|
+
} = allEnumerated();
|
|
280
|
+
for (const entry of entries) {
|
|
281
|
+
if (entry.handle.scopeId !== scopeId) continue;
|
|
282
|
+
const scope = compileScope(entry, {
|
|
283
|
+
document,
|
|
284
|
+
...(overlay ? { overlay } : {}),
|
|
285
|
+
paragraphIndexByBlockIndex,
|
|
286
|
+
sectionIndexByBlockIndex,
|
|
287
|
+
});
|
|
288
|
+
if (scope) return { scope, document, enumerated: entry };
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
compileBundleById(scopeId: string, nowUtc: string): ScopeBundle | null {
|
|
294
|
+
const document = runtime.getCanonicalDocument();
|
|
295
|
+
const overlay = runtime.getWorkflowOverlay();
|
|
296
|
+
// Read-side join — thread metadata entries through so the bundle's
|
|
297
|
+
// evidence surfaces ai.explanation / ai.issue entries. Write
|
|
298
|
+
// operations go through `attachScopeMetadata` via this same
|
|
299
|
+
// runtime surface, so the snapshot is always fresh here.
|
|
300
|
+
const workflowMetadataEntries = runtime.getWorkflowMetadataSnapshot().entries;
|
|
301
|
+
return compileScopeBundleById(scopeId, {
|
|
302
|
+
document,
|
|
303
|
+
...(overlay ? { overlay } : {}),
|
|
304
|
+
nowUtc,
|
|
305
|
+
catalog: document.styles,
|
|
306
|
+
workflowMetadataEntries,
|
|
307
|
+
});
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
buildReplacementScope(targetHandle, input) {
|
|
311
|
+
return proposeReplacement({
|
|
312
|
+
targetHandle,
|
|
313
|
+
operation: input.operation,
|
|
314
|
+
proposedContent:
|
|
315
|
+
typeof input.proposedText === "string"
|
|
316
|
+
? { kind: "text", text: input.proposedText }
|
|
317
|
+
: { kind: "text", text: "" },
|
|
318
|
+
...(input.preserve ? { preserve: input.preserve } : {}),
|
|
319
|
+
...(input.reason ? { reason: input.reason } : {}),
|
|
320
|
+
proposedAtUtc: input.proposedAtUtc,
|
|
321
|
+
});
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
applyReplacement(
|
|
325
|
+
request: ApplyReplacementRequest,
|
|
326
|
+
): ApplyScopeReplacementResult {
|
|
327
|
+
// Resolve + build the ReplacementScope fresh. `applyScopeReplacement`
|
|
328
|
+
// re-enumerates + re-compiles + re-validates on live state (§7 trap
|
|
329
|
+
// 2 — never trust a propose-time verdict).
|
|
330
|
+
const compiled = this.compileScopeById(request.targetScopeId);
|
|
331
|
+
if (!compiled) {
|
|
332
|
+
return {
|
|
333
|
+
applied: false,
|
|
334
|
+
reason: "scope-not-resolvable",
|
|
335
|
+
validation: {
|
|
336
|
+
safe: false,
|
|
337
|
+
blockedReasons: Object.freeze([
|
|
338
|
+
`scope-not-resolvable:${request.targetScopeId}`,
|
|
339
|
+
]),
|
|
340
|
+
warnings: Object.freeze([]),
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
// Caller-supplied proposedContent takes precedence (structured-
|
|
345
|
+
// fragment path); otherwise we fall back to the flat-text
|
|
346
|
+
// shorthand via proposedText.
|
|
347
|
+
const proposed = request.proposedContent
|
|
348
|
+
? proposeReplacement({
|
|
349
|
+
targetHandle: compiled.scope.handle,
|
|
350
|
+
operation: request.operation,
|
|
351
|
+
proposedContent: request.proposedContent,
|
|
352
|
+
...(request.preserve ? { preserve: request.preserve } : {}),
|
|
353
|
+
...(request.reason ? { reason: request.reason } : {}),
|
|
354
|
+
proposedAtUtc: request.emittedAtUtc,
|
|
355
|
+
})
|
|
356
|
+
: this.buildReplacementScope(compiled.scope.handle, {
|
|
357
|
+
operation: request.operation,
|
|
358
|
+
...(request.proposedText !== undefined
|
|
359
|
+
? { proposedText: request.proposedText }
|
|
360
|
+
: {}),
|
|
361
|
+
...(request.preserve ? { preserve: request.preserve } : {}),
|
|
362
|
+
...(request.reason ? { reason: request.reason } : {}),
|
|
363
|
+
proposedAtUtc: request.emittedAtUtc,
|
|
364
|
+
});
|
|
365
|
+
return applyScopeReplacement({
|
|
366
|
+
sink: {
|
|
367
|
+
getCanonicalDocument: () => runtime.getCanonicalDocument(),
|
|
368
|
+
getWorkflowOverlay: () => runtime.getWorkflowOverlay(),
|
|
369
|
+
getInteractionGuardSnapshot: () =>
|
|
370
|
+
runtime.getInteractionGuardSnapshot(),
|
|
371
|
+
getCompatibilityReport: () => runtime.getCompatibilityReport(),
|
|
372
|
+
applyScopeReplacement: (plan) => runtime.applyScopeReplacement(plan),
|
|
373
|
+
},
|
|
374
|
+
proposed,
|
|
375
|
+
...(request.actionId ? { actionId: request.actionId } : {}),
|
|
376
|
+
actorId: request.actorId,
|
|
377
|
+
origin: request.origin,
|
|
378
|
+
emittedAtUtc: request.emittedAtUtc,
|
|
379
|
+
...(runtime.debug?.bus ? { bus: runtime.debug.bus } : {}),
|
|
380
|
+
});
|
|
381
|
+
},
|
|
382
|
+
|
|
383
|
+
attachExplanation(
|
|
384
|
+
request: AttachExplanationRequest,
|
|
385
|
+
): AttachExplanationResult {
|
|
386
|
+
return attachExplanation(
|
|
387
|
+
{
|
|
388
|
+
getWorkflowOverlay: () => runtime.getWorkflowOverlay(),
|
|
389
|
+
getWorkflowMetadataSnapshot: () =>
|
|
390
|
+
runtime.getWorkflowMetadataSnapshot(),
|
|
391
|
+
setWorkflowMetadataEntries: (entries) =>
|
|
392
|
+
runtime.setWorkflowMetadataEntries([...entries]),
|
|
393
|
+
getCanonicalDocument: () => runtime.getCanonicalDocument(),
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
scopeId: request.scopeId,
|
|
397
|
+
explanation: request.explanation,
|
|
398
|
+
...(request.explanationId
|
|
399
|
+
? { explanationId: request.explanationId }
|
|
400
|
+
: {}),
|
|
401
|
+
...(request.createdAtUtc
|
|
402
|
+
? { createdAtUtc: request.createdAtUtc }
|
|
403
|
+
: {}),
|
|
404
|
+
},
|
|
405
|
+
);
|
|
406
|
+
},
|
|
407
|
+
|
|
408
|
+
createIssue(request: CreateIssueRequest): CreateIssueResult {
|
|
409
|
+
return createIssue(
|
|
410
|
+
{
|
|
411
|
+
getWorkflowOverlay: () => runtime.getWorkflowOverlay(),
|
|
412
|
+
getWorkflowMetadataSnapshot: () =>
|
|
413
|
+
runtime.getWorkflowMetadataSnapshot(),
|
|
414
|
+
setWorkflowMetadataEntries: (entries) =>
|
|
415
|
+
runtime.setWorkflowMetadataEntries([...entries]),
|
|
416
|
+
getCanonicalDocument: () => runtime.getCanonicalDocument(),
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
scopeId: request.scopeId,
|
|
420
|
+
summary: request.summary,
|
|
421
|
+
...(request.severity ? { severity: request.severity } : {}),
|
|
422
|
+
...(request.issueId ? { issueId: request.issueId } : {}),
|
|
423
|
+
...(request.createdAtUtc
|
|
424
|
+
? { createdAtUtc: request.createdAtUtc }
|
|
425
|
+
: {}),
|
|
426
|
+
...(request.status ? { status: request.status } : {}),
|
|
427
|
+
},
|
|
428
|
+
);
|
|
429
|
+
},
|
|
430
|
+
};
|
|
431
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 6 — `ai.createIssue` live-with-adapter primitive.
|
|
3
|
+
*
|
|
4
|
+
* Creates an agent-authored issue record scoped to a handle by routing
|
|
5
|
+
* through Layer-06's `attachScopeMetadata` writer. The issue persists
|
|
6
|
+
* as a `WorkflowMetadataEntry` with `metadataId: "ai.issue"` and
|
|
7
|
+
* `value: {issueId, summary, severity, status, createdAtUtc}`.
|
|
8
|
+
*
|
|
9
|
+
* Issues are metadata records rather than a dedicated overlay section
|
|
10
|
+
* in this slice — matches the Slice-6 plan's "issue store is a new
|
|
11
|
+
* section on the workflow overlay" intent without requiring an
|
|
12
|
+
* overlay-schema minor bump. When CLM workblocks need richer lifecycle
|
|
13
|
+
* (resolve/reopen transitions, assigned owners), a follow-up sub-slice
|
|
14
|
+
* promotes issues to a first-class overlay kind and the storage
|
|
15
|
+
* migrates — the metadataId stays stable so callers don't break.
|
|
16
|
+
*
|
|
17
|
+
* Scope coverage (coord-06 §13c shipped 2026-04-23): both overlay
|
|
18
|
+
* (workflow) scopes AND derived paragraph / heading / list-item
|
|
19
|
+
* scopes are valid targets. Derived scopeIds resolve against the
|
|
20
|
+
* canonical document and produce an `ai.issue` entry whose anchor is
|
|
21
|
+
* the resolver's range output; the result carries
|
|
22
|
+
* `resolvedFrom: "derived"`. Non-paragraph-like scopeIds still
|
|
23
|
+
* return `created: false`.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import type {
|
|
27
|
+
AttachScopeMetadataResult,
|
|
28
|
+
MetadataWriterRuntime,
|
|
29
|
+
} from "../workflow/metadata-writer.ts";
|
|
30
|
+
import { attachScopeMetadata } from "../workflow/metadata-writer.ts";
|
|
31
|
+
|
|
32
|
+
/** Stable metadataId for AI-authored issues. */
|
|
33
|
+
export const AI_ISSUE_METADATA_ID = "ai.issue" as const;
|
|
34
|
+
|
|
35
|
+
export type IssueSeverity = "info" | "warning" | "error";
|
|
36
|
+
export type IssueStatus = "open" | "resolved";
|
|
37
|
+
|
|
38
|
+
export interface CreateIssueInput {
|
|
39
|
+
readonly scopeId: string;
|
|
40
|
+
readonly summary: string;
|
|
41
|
+
readonly severity?: IssueSeverity;
|
|
42
|
+
readonly issueId?: string;
|
|
43
|
+
readonly createdAtUtc?: string;
|
|
44
|
+
readonly status?: IssueStatus;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type CreateIssueResult =
|
|
48
|
+
| {
|
|
49
|
+
readonly created: true;
|
|
50
|
+
readonly issueId: string;
|
|
51
|
+
readonly entryId: string;
|
|
52
|
+
/**
|
|
53
|
+
* Coord-06 §13c — `"overlay"` when the scope was on the workflow
|
|
54
|
+
* overlay, `"derived"` when it was a paragraph / heading /
|
|
55
|
+
* list-item scopeId resolved from the canonical document.
|
|
56
|
+
*/
|
|
57
|
+
readonly resolvedFrom: "overlay" | "derived";
|
|
58
|
+
}
|
|
59
|
+
| {
|
|
60
|
+
readonly created: false;
|
|
61
|
+
readonly issueId: string;
|
|
62
|
+
/**
|
|
63
|
+
* `scope-not-resolvable:<scopeId>` — the scopeId is neither on
|
|
64
|
+
* the workflow overlay nor a paragraph-like derived id the
|
|
65
|
+
* canonical walk can resolve. Pre-§13c this was always
|
|
66
|
+
* `scope-not-in-overlay`.
|
|
67
|
+
*/
|
|
68
|
+
readonly reason: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export function createIssue(
|
|
72
|
+
runtime: MetadataWriterRuntime,
|
|
73
|
+
input: CreateIssueInput,
|
|
74
|
+
): CreateIssueResult {
|
|
75
|
+
const issueId = input.issueId ?? `issue-${input.scopeId}`;
|
|
76
|
+
const createdAtUtc = input.createdAtUtc ?? new Date(0).toISOString();
|
|
77
|
+
const severity: IssueSeverity = input.severity ?? "info";
|
|
78
|
+
const status: IssueStatus = input.status ?? "open";
|
|
79
|
+
const writerResult: AttachScopeMetadataResult = attachScopeMetadata(runtime, {
|
|
80
|
+
scopeId: input.scopeId,
|
|
81
|
+
metadataId: AI_ISSUE_METADATA_ID,
|
|
82
|
+
// Entry id is issueId-scoped so multiple issues can co-exist on
|
|
83
|
+
// one scope (the default attachScopeMetadata entryId would
|
|
84
|
+
// collide on `${scopeId}::ai.issue`).
|
|
85
|
+
entryId: `${input.scopeId}::${AI_ISSUE_METADATA_ID}::${issueId}`,
|
|
86
|
+
value: {
|
|
87
|
+
issueId,
|
|
88
|
+
summary: input.summary,
|
|
89
|
+
severity,
|
|
90
|
+
status,
|
|
91
|
+
createdAtUtc,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
if (writerResult.status === "attached") {
|
|
95
|
+
return {
|
|
96
|
+
created: true,
|
|
97
|
+
issueId,
|
|
98
|
+
entryId: writerResult.entryId,
|
|
99
|
+
resolvedFrom: writerResult.resolvedFrom,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
created: false,
|
|
104
|
+
issueId,
|
|
105
|
+
reason: `scope-not-resolvable:${writerResult.scopeId}`,
|
|
106
|
+
};
|
|
107
|
+
}
|