@beyondwork/docx-react-component 1.0.106 → 1.0.108

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.
Files changed (190) hide show
  1. package/package.json +19 -5
  2. package/src/api/geometry-overlay-rects.ts +5 -0
  3. package/src/api/package-version.ts +1 -1
  4. package/src/api/page-anchor-id.ts +5 -0
  5. package/src/api/public-types.ts +16 -9
  6. package/src/api/table-node-specs.ts +6 -0
  7. package/src/api/v3/_create.ts +2 -1
  8. package/src/api/v3/_page-anchor-id.ts +52 -0
  9. package/src/api/v3/_runtime-handle.ts +92 -1
  10. package/src/api/v3/ai/_audit-time.ts +5 -0
  11. package/src/api/v3/ai/_pe2-evidence.ts +38 -0
  12. package/src/api/v3/ai/attach.ts +7 -2
  13. package/src/api/v3/ai/replacement.ts +101 -18
  14. package/src/api/v3/ai/resolve.ts +2 -2
  15. package/src/api/v3/ai/review.ts +177 -3
  16. package/src/api/v3/index.ts +1 -0
  17. package/src/api/v3/runtime/collab.ts +462 -0
  18. package/src/api/v3/runtime/document.ts +503 -20
  19. package/src/api/v3/runtime/geometry.ts +97 -0
  20. package/src/api/v3/runtime/layout.ts +744 -0
  21. package/src/api/v3/runtime/perf-probe.ts +14 -0
  22. package/src/api/v3/runtime/viewport.ts +9 -8
  23. package/src/api/v3/ui/_types.ts +149 -55
  24. package/src/api/v3/ui/chrome-preset-model.ts +5 -5
  25. package/src/api/v3/ui/debug.ts +115 -2
  26. package/src/api/v3/ui/index.ts +13 -0
  27. package/src/api/v3/ui/overlays.ts +0 -8
  28. package/src/api/v3/ui/surface.ts +56 -0
  29. package/src/api/v3/ui/viewport.ts +22 -9
  30. package/src/core/commands/image-commands.ts +1 -0
  31. package/src/core/commands/index.ts +6 -0
  32. package/src/core/schema/text-schema.ts +43 -5
  33. package/src/core/selection/mapping.ts +8 -1
  34. package/src/core/selection/review-anchors.ts +5 -1
  35. package/src/core/state/text-transaction.ts +8 -2
  36. package/src/io/export/serialize-revisions.ts +149 -1
  37. package/src/io/normalize/normalize-text.ts +6 -0
  38. package/src/io/ooxml/parse-bookmark-references.ts +55 -0
  39. package/src/io/ooxml/parse-fields.ts +24 -2
  40. package/src/io/ooxml/parse-headers-footers.ts +38 -5
  41. package/src/io/ooxml/parse-main-document.ts +153 -9
  42. package/src/io/ooxml/parse-numbering.ts +20 -0
  43. package/src/io/ooxml/parse-revisions.ts +19 -8
  44. package/src/io/opc/package-reader.ts +98 -8
  45. package/src/model/anchor.ts +4 -3
  46. package/src/model/canonical-document.ts +220 -2
  47. package/src/model/canonical-hash.ts +221 -0
  48. package/src/model/canonical-layout-inputs.ts +245 -6
  49. package/src/model/layout/index.ts +1 -0
  50. package/src/model/layout/page-graph-types.ts +118 -1
  51. package/src/model/review/revision-types.ts +14 -3
  52. package/src/preservation/store.ts +20 -4
  53. package/src/review/README.md +1 -1
  54. package/src/review/store/revision-actions.ts +14 -2
  55. package/src/runtime/collab/event-types.ts +67 -1
  56. package/src/runtime/collab/runtime-collab-sync.ts +177 -5
  57. package/src/runtime/diagnostics/layout-guard-warning.ts +18 -0
  58. package/src/runtime/document-heading-outline.ts +147 -0
  59. package/src/runtime/document-navigation.ts +8 -243
  60. package/src/runtime/document-runtime.ts +240 -97
  61. package/src/runtime/edit-dispatch/dispatch-text-command.ts +11 -0
  62. package/src/runtime/formatting/layout-inputs.ts +38 -5
  63. package/src/runtime/formatting/numbering/geometry.ts +28 -2
  64. package/src/runtime/geometry/adjacent-geometry-intake.ts +835 -0
  65. package/src/runtime/geometry/caret-geometry.ts +5 -6
  66. package/src/runtime/geometry/geometry-facet.ts +60 -10
  67. package/src/runtime/geometry/geometry-index.ts +591 -20
  68. package/src/runtime/geometry/geometry-types.ts +59 -0
  69. package/src/runtime/geometry/hit-test.ts +11 -1
  70. package/src/runtime/geometry/overlay-rects.ts +5 -3
  71. package/src/runtime/geometry/project-anchors.ts +1 -1
  72. package/src/runtime/geometry/word-layout-v2-line-intake.ts +323 -0
  73. package/src/runtime/layout/index.ts +6 -0
  74. package/src/runtime/layout/layout-engine-instance.ts +6 -1
  75. package/src/runtime/layout/layout-engine-version.ts +181 -16
  76. package/src/runtime/layout/layout-facet-types.ts +6 -0
  77. package/src/runtime/layout/page-graph.ts +21 -4
  78. package/src/runtime/layout/paginated-layout-engine.ts +139 -15
  79. package/src/runtime/layout/project-block-fragments.ts +265 -7
  80. package/src/runtime/layout/public-facet.ts +78 -24
  81. package/src/runtime/layout/table-row-continuation-contract.ts +107 -0
  82. package/src/runtime/layout/table-row-split.ts +92 -35
  83. package/src/runtime/prerender/cache-envelope.ts +2 -2
  84. package/src/runtime/prerender/cache-key.ts +5 -4
  85. package/src/runtime/prerender/customxml-cache.ts +0 -1
  86. package/src/runtime/render/render-kernel.ts +1 -1
  87. package/src/runtime/revision-runtime.ts +112 -10
  88. package/src/runtime/scopes/_scope-dependencies.ts +1 -0
  89. package/src/runtime/scopes/action-validation.ts +22 -2
  90. package/src/runtime/scopes/capabilities.ts +316 -0
  91. package/src/runtime/scopes/compile-scope-bundle.ts +14 -0
  92. package/src/runtime/scopes/compiler-service.ts +108 -4
  93. package/src/runtime/scopes/content-control-evidence.ts +79 -0
  94. package/src/runtime/scopes/create-issue.ts +5 -5
  95. package/src/runtime/scopes/evidence.ts +91 -0
  96. package/src/runtime/scopes/formatting/apply.ts +2 -0
  97. package/src/runtime/scopes/geometry-evidence.ts +130 -0
  98. package/src/runtime/scopes/index.ts +54 -0
  99. package/src/runtime/scopes/issue-lifecycle.ts +224 -0
  100. package/src/runtime/scopes/layout-evidence.ts +374 -0
  101. package/src/runtime/scopes/multi-paragraph-refusal.ts +37 -0
  102. package/src/runtime/scopes/preservation-boundary.ts +7 -1
  103. package/src/runtime/scopes/replacement/apply.ts +97 -34
  104. package/src/runtime/scopes/scope-kinds/paragraph.ts +108 -12
  105. package/src/runtime/scopes/semantic-scope-types.ts +242 -3
  106. package/src/runtime/scopes/visualization.ts +28 -0
  107. package/src/runtime/surface-projection.ts +44 -5
  108. package/src/runtime/telemetry/perf-probe.ts +216 -0
  109. package/src/runtime/virtualized-rendering.ts +36 -1
  110. package/src/runtime/workflow/ai-issue-lifecycle.ts +253 -0
  111. package/src/runtime/workflow/coordinator.ts +39 -11
  112. package/src/runtime/workflow/derived-scope-resolver.ts +63 -9
  113. package/src/runtime/workflow/index.ts +3 -0
  114. package/src/runtime/workflow/overlay-lane-types.ts +58 -0
  115. package/src/runtime/workflow/overlay-lanes.ts +168 -10
  116. package/src/runtime/workflow/overlay-store.ts +2 -2
  117. package/src/runtime/workflow/redline-posture-calibration.ts +257 -0
  118. package/src/runtime/workflow/word-field-matrix-calibration.ts +231 -0
  119. package/src/session/_sync-legacy.ts +17 -27
  120. package/src/session/import/loader.ts +6 -4
  121. package/src/session/import/source-package-evidence.ts +186 -2
  122. package/src/session/index.ts +5 -6
  123. package/src/session/session.ts +30 -56
  124. package/src/session/types.ts +8 -13
  125. package/src/shell/session-bootstrap.ts +155 -81
  126. package/src/ui/WordReviewEditor.tsx +520 -12
  127. package/src/ui/editor-shell-view.tsx +14 -4
  128. package/src/ui/editor-surface-controller.tsx +5 -3
  129. package/src/ui/headless/selection-tool-resolver.ts +1 -2
  130. package/src/ui/presence-overlay-lane.ts +0 -1
  131. package/src/ui/ui-controller-factory.ts +7 -0
  132. package/src/ui-tailwind/chrome/build-context-menu-entries.ts +5 -1
  133. package/src/ui-tailwind/chrome/editor-action-registry.ts +105 -5
  134. package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +7 -0
  135. package/src/ui-tailwind/chrome/layer-debug-contracts.ts +208 -0
  136. package/src/ui-tailwind/chrome/resolve-target-kind.ts +13 -0
  137. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +11 -3
  138. package/src/ui-tailwind/chrome/tw-command-palette.tsx +36 -6
  139. package/src/ui-tailwind/chrome/tw-context-menu.tsx +6 -1
  140. package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +42 -109
  141. package/src/ui-tailwind/chrome/tw-inline-find-bar.tsx +26 -6
  142. package/src/ui-tailwind/chrome/tw-navigation-command-bar.tsx +328 -0
  143. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +8 -4
  144. package/src/ui-tailwind/chrome/tw-runtime-repl-dialog.tsx +129 -1
  145. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +19 -5
  146. package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +5 -1
  147. package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +28 -12
  148. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +30 -3
  149. package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +116 -10
  150. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +223 -94
  151. package/src/ui-tailwind/chrome-overlay/tw-presence-overlay-lane.tsx +157 -0
  152. package/src/ui-tailwind/chrome-overlay/tw-review-overlay-lane-markers.tsx +259 -0
  153. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +5 -2
  154. package/src/ui-tailwind/chrome-overlay/tw-substrate-overlay-lanes.tsx +314 -0
  155. package/src/ui-tailwind/debug/README.md +4 -1
  156. package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +272 -0
  157. package/src/ui-tailwind/debug/layer11-word-field-matrix-evidence.ts +160 -0
  158. package/src/ui-tailwind/editor-surface/perf-probe.ts +14 -215
  159. package/src/ui-tailwind/editor-surface/pm-decorations.ts +42 -0
  160. package/src/ui-tailwind/editor-surface/pm-position-map.ts +38 -2
  161. package/src/ui-tailwind/editor-surface/pm-schema.ts +14 -4
  162. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +34 -5
  163. package/src/ui-tailwind/editor-surface/runtime-decoration-plugin.ts +9 -19
  164. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -2
  165. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +145 -0
  166. package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +16 -11
  167. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +8 -10
  168. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +3 -0
  169. package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +4 -2
  170. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +60 -20
  171. package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +16 -11
  172. package/src/ui-tailwind/review/tw-health-panel.tsx +36 -17
  173. package/src/ui-tailwind/review/tw-review-rail.tsx +7 -4
  174. package/src/ui-tailwind/review-workspace/diagnostics-visibility.ts +44 -0
  175. package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +11 -0
  176. package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +16 -1
  177. package/src/ui-tailwind/review-workspace/types.ts +26 -12
  178. package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +40 -11
  179. package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +2 -1
  180. package/src/ui-tailwind/review-workspace/use-page-markers.ts +15 -26
  181. package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +35 -18
  182. package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +41 -32
  183. package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +2 -1
  184. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +2 -1
  185. package/src/ui-tailwind/status/tw-status-bar.tsx +6 -5
  186. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +52 -80
  187. package/src/ui-tailwind/toolbar/tw-shell-header.tsx +12 -48
  188. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +9 -4
  189. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +328 -361
  190. package/src/ui-tailwind/tw-review-workspace.tsx +152 -286
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@beyondwork/docx-react-component",
3
3
  "publisher": "beyondwork",
4
- "version": "1.0.106",
4
+ "version": "1.0.108",
5
5
  "description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
6
6
  "type": "module",
7
7
  "sideEffects": [
@@ -35,7 +35,8 @@
35
35
  },
36
36
  "./api/v3": {
37
37
  "types": "./src/api/v3/index.ts",
38
- "import": "./src/api/v3/index.ts"
38
+ "import": "./src/api/v3/index.ts",
39
+ "require": "./src/api/v3/index.ts"
39
40
  },
40
41
  "./compare": {
41
42
  "types": "./src/compare/index.ts",
@@ -43,7 +44,8 @@
43
44
  },
44
45
  "./session": {
45
46
  "types": "./src/session/index.ts",
46
- "import": "./src/session/index.ts"
47
+ "import": "./src/session/index.ts",
48
+ "require": "./src/session/index.ts"
47
49
  },
48
50
  "./io/docx-session": {
49
51
  "types": "./src/io/docx-session.ts",
@@ -55,7 +57,8 @@
55
57
  },
56
58
  "./runtime/document-runtime": {
57
59
  "types": "./src/runtime/document-runtime.ts",
58
- "import": "./src/runtime/document-runtime.ts"
60
+ "import": "./src/runtime/document-runtime.ts",
61
+ "require": "./src/runtime/document-runtime.ts"
59
62
  },
60
63
  "./runtime/collab": {
61
64
  "types": "./src/runtime/collab/index.ts",
@@ -212,6 +215,17 @@
212
215
  "mcp:tool-runner:visual-smoke": "bash scripts/tool-runner-mcp.sh visual-smoke",
213
216
  "mcp:tool-runner:ooxml-validator": "bash scripts/tool-runner-mcp.sh ooxml-validator",
214
217
  "mcp:tool-runner:truth": "bash scripts/tool-runner-mcp.sh truth",
215
- "mcp:tool-runner:scope-calibration": "bash scripts/tool-runner-mcp.sh scope-calibration"
218
+ "mcp:tool-runner:scope-calibration": "bash scripts/tool-runner-mcp.sh scope-calibration",
219
+ "graph-oracle:build-static": "bash scripts/run-tool-workspace-command.sh node --import tsx services/truth-baseline/backends/word-graph-pdf/graph-oracle.ts build-static",
220
+ "graph-oracle": "bash scripts/run-tool-workspace-command.sh node --import tsx services/truth-baseline/backends/word-graph-pdf/graph-oracle.ts",
221
+ "graph-oracle:build-static:local": "node --import tsx services/truth-baseline/backends/word-graph-pdf/graph-oracle.ts build-static",
222
+ "graph-oracle:local": "node --import tsx services/truth-baseline/backends/word-graph-pdf/graph-oracle.ts",
223
+ "word-oracle:build-static": "bash scripts/run-tool-workspace-command.sh node --import tsx services/truth-baseline/backends/word-com/word-oracle.ts build-static",
224
+ "word-oracle": "bash scripts/run-tool-workspace-command.sh node --import tsx services/truth-baseline/backends/word-com/word-oracle.ts",
225
+ "word-oracle:build-static:local": "node --import tsx services/truth-baseline/backends/word-com/word-oracle.ts build-static",
226
+ "word-oracle:local": "node --import tsx services/truth-baseline/backends/word-com/word-oracle.ts",
227
+ "corpus-render:layout": "node scripts/organize-corpus-renders.mjs",
228
+ "corpus-render:assets": "bash scripts/run-corpus-render-assets.sh",
229
+ "corpus-render:assets:local": "node scripts/generate-corpus-render-assets.mjs"
216
230
  }
217
231
  }
@@ -0,0 +1,5 @@
1
+ export {
2
+ resolvePageOverlayRectsFromGeometry,
3
+ type PageOverlayRect,
4
+ type OverlayVisiblePageIndexRange,
5
+ } from "../runtime/geometry/index.ts";
@@ -10,4 +10,4 @@
10
10
  * the string is committed directly so the runtime works without a build
11
11
  * step for tests.
12
12
  */
13
- export const PACKAGE_VERSION = "1.0.55";
13
+ export const PACKAGE_VERSION = "1.0.56";
@@ -0,0 +1,5 @@
1
+ export {
2
+ buildPageAnchorAttributes,
3
+ buildPageAnchorElementId,
4
+ buildPageAnchorSelector,
5
+ } from "./v3/_page-anchor-id.ts";
@@ -182,6 +182,7 @@ export type {
182
182
  PublicNoteAllocation,
183
183
  PublicPageAnchor,
184
184
  PublicPageFrame,
185
+ PublicPageLocalStoryInstance,
185
186
  PublicPageNode,
186
187
  PublicPageRegion,
187
188
  PublicPageRegions,
@@ -189,9 +190,11 @@ export type {
189
190
  PublicRegionBlock,
190
191
  PublicRegionKind,
191
192
  PublicResolvedPageStories,
193
+ PublicResolvedStoryField,
192
194
  PublicResolvedParagraphFormatting,
193
195
  PublicResolvedRunFormatting,
194
196
  PublicSectionNode,
197
+ PublicStoryAnchoredObject,
195
198
  PublicTwipsRect,
196
199
  // R0.5: named page-format + margin-preset catalogs
197
200
  PageFormatDefinition,
@@ -1662,11 +1665,15 @@ export type SurfaceBlockSnapshot =
1662
1665
  alias?: string;
1663
1666
  tag?: string;
1664
1667
  lock?: string;
1668
+ blockedReasonCode?: "workflow_preserve_only" | "workflow_blocked_import";
1665
1669
  checkboxChecked?: boolean;
1666
1670
  dateValue?: string;
1667
1671
  dropdownItems?: Array<{ displayText?: string; value: string }>;
1668
1672
  comboBoxItems?: Array<{ displayText?: string; value: string }>;
1669
1673
  showingPlcHdr?: boolean;
1674
+ label?: string;
1675
+ detail?: string;
1676
+ featureKey?: string;
1670
1677
  children: SurfaceBlockSnapshot[];
1671
1678
  }
1672
1679
  | {
@@ -4856,9 +4863,9 @@ export interface WordReviewEditorRef {
4856
4863
  getCommentSidebarSnapshot(): CommentSidebarSnapshot;
4857
4864
  getTrackedChangesSnapshot(): TrackedChangesSnapshot;
4858
4865
  getSuggestionsSnapshot(): SuggestionsSnapshot;
4859
- /** @deprecated Use {@link getCommentSidebarSnapshot} instead. */
4866
+ /** @deprecated Use {@link getCommentSidebarSnapshot} instead; remove after the next published API pin refresh. */
4860
4867
  getComments(): CommentSidebarSnapshot;
4861
- /** @deprecated Use {@link getTrackedChangesSnapshot} instead. */
4868
+ /** @deprecated Use {@link getTrackedChangesSnapshot} instead; remove after the next published API pin refresh. */
4862
4869
  getTrackedChanges(): TrackedChangesSnapshot;
4863
4870
  isDirty(): boolean;
4864
4871
  getFormattingState(): FormattingStateSnapshot;
@@ -5081,7 +5088,10 @@ export interface WordReviewEditorRef {
5081
5088
  getWorkflowMarkupSnapshot(): WorkflowMarkupSnapshot;
5082
5089
  setWorkflowMetadataDefinitions(definitions: WorkflowMetadataDefinition[]): void;
5083
5090
  clearWorkflowMetadataDefinitions(): void;
5084
- setWorkflowMetadataEntries(entries: WorkflowMetadataEntry[]): void;
5091
+ setWorkflowMetadataEntries(
5092
+ entries: WorkflowMetadataEntry[],
5093
+ origin?: WorkflowEventOrigin,
5094
+ ): void;
5085
5095
  clearWorkflowMetadataEntries(): void;
5086
5096
  getWorkflowMetadataSnapshot(): WorkflowMetadataSnapshot;
5087
5097
  /**
@@ -5911,12 +5921,9 @@ export interface WordReviewEditorChromeVisibility {
5911
5921
  statusBar: boolean;
5912
5922
  reviewRail: boolean;
5913
5923
  /**
5914
- * TwShellHeader (Edit / Review / Workflow / More mode tabs) at the top
5915
- * of the workspace. Defaults to `true` on every preset EXCEPT
5916
- * `selection`, which is intended for minimal embeds and should not paint
5917
- * a workspace chrome header. coord-11 §21 — regressing this default has
5918
- * history, particularly for visual-fidelity captures that expect a
5919
- * truly chrome-less `chrome=none` embed.
5924
+ * Optional host-supplied shell/header slot above the toolbar. Defaults to
5925
+ * `false` for product presets; role switching lives in the main toolbar.
5926
+ * Harness/operator shells must opt in explicitly.
5920
5927
  */
5921
5928
  shellHeader: boolean;
5922
5929
  }
@@ -0,0 +1,6 @@
1
+ export {
2
+ tableNodeSpec,
3
+ tableRowNodeSpec,
4
+ tableCellNodeSpec,
5
+ tableHeaderCellNodeSpec,
6
+ } from "../runtime/table-schema.ts";
@@ -111,7 +111,8 @@ export interface CreateApiV3Opts {
111
111
  readonly ui?: UiControllerFactory;
112
112
  /**
113
113
  * Optional PE2 evidence bridge. Hosts/debug services that already have
114
- * truth-oracle run metadata can inject it here; omitted means AI reads
114
+ * truth-oracle run metadata or Graph-PDF lookup records can inject them
115
+ * here; omitted means AI reads
115
116
  * report `pe2Evidence.oracle.status: "not-wired"`.
116
117
  */
117
118
  readonly pe2Evidence?: AiPe2EvidenceOptions;
@@ -0,0 +1,52 @@
1
+ export function buildPageAnchorElementId(
2
+ pageId: string | null | undefined,
3
+ pageIndex: number,
4
+ ): string {
5
+ const stablePageId = normalizePageAnchorId(pageId, pageIndex);
6
+ return `wre-page-anchor-${pageIndex}-${toDomIdToken(stablePageId)}`;
7
+ }
8
+
9
+ export function buildPageAnchorSelector(pageIndex: number): string {
10
+ const stablePageIndex = normalizePageIndex(pageIndex);
11
+ return `[data-page-anchor="true"][data-page-index="${stablePageIndex}"]`;
12
+ }
13
+
14
+ export function buildPageAnchorAttributes(
15
+ pageId: string | null | undefined,
16
+ pageIndex: number,
17
+ ): {
18
+ readonly id: string;
19
+ readonly "data-page-anchor": "true";
20
+ readonly "data-page-index": string;
21
+ readonly "data-page-id": string;
22
+ } {
23
+ const stablePageIndex = normalizePageIndex(pageIndex);
24
+ const stablePageId = normalizePageAnchorId(pageId, stablePageIndex);
25
+ return {
26
+ id: buildPageAnchorElementId(stablePageId, stablePageIndex),
27
+ "data-page-anchor": "true",
28
+ "data-page-index": String(stablePageIndex),
29
+ "data-page-id": stablePageId,
30
+ };
31
+ }
32
+
33
+ function normalizePageAnchorId(
34
+ pageId: string | null | undefined,
35
+ pageIndex: number,
36
+ ): string {
37
+ return pageId && pageId.trim().length > 0 ? pageId : `page-${pageIndex}`;
38
+ }
39
+
40
+ function normalizePageIndex(pageIndex: number): number {
41
+ return Number.isFinite(pageIndex) && pageIndex >= 0
42
+ ? Math.floor(pageIndex)
43
+ : 0;
44
+ }
45
+
46
+ function toDomIdToken(value: string): string {
47
+ const token = value
48
+ .trim()
49
+ .replace(/[^A-Za-z0-9_-]+/g, "-")
50
+ .replace(/^-+|-+$/g, "");
51
+ return token.length > 0 ? token : "page";
52
+ }
@@ -27,6 +27,80 @@
27
27
 
28
28
  import type { DocumentRuntime } from "../../runtime/document-runtime.ts";
29
29
  import type { CollabSession } from "../../runtime/collab-session.ts";
30
+ import type { RuntimeCollabSyncHandle } from "../../runtime/collab/runtime-collab-sync.ts";
31
+
32
+ export type RuntimeWordFieldMatrixOwner =
33
+ | "L01"
34
+ | "L02"
35
+ | "L03"
36
+ | "L04"
37
+ | "L05"
38
+ | "L06"
39
+ | "L08"
40
+ | "L11";
41
+
42
+ export type RuntimeWordFieldMatrixGroup =
43
+ | "structuralSummary"
44
+ | "pageGeometry"
45
+ | "tableContinuations"
46
+ | "fields"
47
+ | "legalNumberingSamples"
48
+ | "anchorsAndObjects"
49
+ | "packagePreservation"
50
+ | "reviewMarkup";
51
+
52
+ export type RuntimeWordFieldAvailability = "available" | "partial" | "missing";
53
+
54
+ export interface RuntimeWordFieldMatrixComparisonLane {
55
+ readonly status: RuntimeWordFieldAvailability | "not-applicable";
56
+ readonly evidencePath?: string;
57
+ readonly note?: string;
58
+ }
59
+
60
+ export interface RuntimeWordFieldMatrixRow {
61
+ readonly group: RuntimeWordFieldMatrixGroup;
62
+ readonly field: string;
63
+ readonly primaryOwner: RuntimeWordFieldMatrixOwner;
64
+ readonly wordStatus: RuntimeWordFieldAvailability;
65
+ readonly wordEvidencePath: string;
66
+ readonly comparison: {
67
+ readonly libreOffice?: RuntimeWordFieldMatrixComparisonLane;
68
+ readonly sourcePackage?: RuntimeWordFieldMatrixComparisonLane;
69
+ readonly graphPdf?: RuntimeWordFieldMatrixComparisonLane;
70
+ };
71
+ readonly routingNote: string;
72
+ }
73
+
74
+ export interface RuntimeWordFieldMatrixArtifact {
75
+ readonly schemaVersion: "pe2-word-field-matrix/v0";
76
+ readonly artifactKind: "pe2.word-field-matrix";
77
+ readonly doc: {
78
+ readonly docId: string;
79
+ readonly corpusLane: string;
80
+ readonly sourceSha256?: string;
81
+ };
82
+ readonly generatedAtUtc: string;
83
+ readonly word: {
84
+ readonly status: string;
85
+ readonly oracleName?: string;
86
+ readonly backend?: string;
87
+ readonly recordPath?: string;
88
+ readonly unavailableReason?: string;
89
+ };
90
+ readonly summary: {
91
+ readonly rowCount: number;
92
+ readonly available: number;
93
+ readonly partial: number;
94
+ readonly missing: number;
95
+ readonly byOwner: Readonly<Record<RuntimeWordFieldMatrixOwner, number>>;
96
+ readonly byGroup: Readonly<Record<RuntimeWordFieldMatrixGroup, number>>;
97
+ };
98
+ readonly rows: readonly RuntimeWordFieldMatrixRow[];
99
+ }
100
+
101
+ export interface RuntimeWordFieldMatrixProvider {
102
+ getWordFieldMatrix(): RuntimeWordFieldMatrixArtifact | null | undefined;
103
+ }
30
104
 
31
105
  /**
32
106
  * @endStateApi
@@ -35,13 +109,14 @@ import type { CollabSession } from "../../runtime/collab-session.ts";
35
109
  *
36
110
  * Optional members (declared via intersection after the Pick) expose
37
111
  * surfaces the runtime does not own directly but hosts can wire in —
38
- * `collabSession` is the first such member, letting v3's
112
+ * `collabSession` and `collabSync` are the first such members, letting v3's
39
113
  * `runtime.collab.*` family graduate its live path when hosts supply it
40
114
  * and fall back to deterministic mocks when they don't.
41
115
  */
42
116
  export type RuntimeApiHandle = Pick<
43
117
  DocumentRuntime,
44
118
  // Session + export (runtime.document family)
119
+ | "now"
45
120
  | "getSessionState"
46
121
  | "setDocumentMode"
47
122
  | "exportDocx"
@@ -135,6 +210,19 @@ export type RuntimeApiHandle = Pick<
135
210
  * deterministic mock snapshots (peers: [], posture: unattached).
136
211
  */
137
212
  readonly collabSession?: CollabSession;
213
+ /**
214
+ * Optional runtime command-event sync handle. Hosts that wire the
215
+ * Y.Array-backed command event transport pass it here so
216
+ * `runtime.collab.getRemoteReplayState()` can expose replay guard
217
+ * posture without leaking Yjs or the sync object.
218
+ */
219
+ readonly collabSync?: RuntimeCollabSyncHandle;
220
+ /**
221
+ * Optional Word-first PE2 field matrix provider. Debug/agent hosts can
222
+ * wire the artifact produced by `services/debug/lib/pe2-word-field-matrix.ts`;
223
+ * product runtime does not build or fetch Word COM evidence itself.
224
+ */
225
+ readonly wordFieldMatrix?: RuntimeWordFieldMatrixProvider;
138
226
  };
139
227
 
140
228
  /**
@@ -150,6 +238,7 @@ export type RuntimeApiHandle = Pick<
150
238
  * (this file, via tsgo) and audit-list drift (the test, via node:test).
151
239
  */
152
240
  export const RUNTIME_API_HANDLE_SHAPE_CHECK: Record<keyof RuntimeApiHandle, true> = {
241
+ now: true,
153
242
  getSessionState: true,
154
243
  setDocumentMode: true,
155
244
  exportDocx: true,
@@ -202,4 +291,6 @@ export const RUNTIME_API_HANDLE_SHAPE_CHECK: Record<keyof RuntimeApiHandle, true
202
291
  // fail `Record<keyof ...>`. Included explicitly so additions are
203
292
  // visible in this single audit roster.
204
293
  collabSession: true,
294
+ collabSync: true,
295
+ wordFieldMatrix: true,
205
296
  };
@@ -0,0 +1,5 @@
1
+ import type { RuntimeApiHandle } from "../_runtime-handle.ts";
2
+
3
+ export function currentAuditTimestamp(runtime: RuntimeApiHandle): string {
4
+ return runtime.now();
5
+ }
@@ -73,6 +73,7 @@ export interface AiPe2LayoutDivergenceEvidence {
73
73
  readonly message: string;
74
74
  readonly regionKinds?: readonly string[];
75
75
  readonly fragmentIds?: readonly string[];
76
+ readonly objectIds?: readonly string[];
76
77
  }
77
78
 
78
79
  export interface AiPe2LayoutEvidence {
@@ -93,10 +94,23 @@ export type AiPe2OracleVerdict =
93
94
  | "runtime-projection-not-wired"
94
95
  | "not-compared";
95
96
 
97
+ export interface AiPe2GraphOracleReference {
98
+ readonly mode: "static" | "live";
99
+ readonly cacheKey: string;
100
+ readonly lane?: string;
101
+ readonly docId?: string;
102
+ readonly pageCount?: number;
103
+ readonly paragraphCount?: number;
104
+ readonly pdfSha256?: string;
105
+ readonly sourceSha256?: string;
106
+ readonly backendIdentityTag?: string;
107
+ }
108
+
96
109
  export interface AiPe2OracleEvidence {
97
110
  readonly status: "available" | "not-wired";
98
111
  readonly runIds: readonly string[];
99
112
  readonly divergenceIds: readonly string[];
113
+ readonly graphOracleReferences?: readonly AiPe2GraphOracleReference[];
100
114
  readonly verdict?: AiPe2OracleVerdict;
101
115
  readonly reason?: "truth-adapter-unavailable" | "truth-adapter-error";
102
116
  }
@@ -172,6 +186,27 @@ function copyLayoutDivergence(
172
186
  message: divergence.message,
173
187
  ...(divergence.regionKinds ? { regionKinds: [...divergence.regionKinds] } : {}),
174
188
  ...(divergence.fragmentIds ? { fragmentIds: [...divergence.fragmentIds] } : {}),
189
+ ...(divergence.objectIds ? { objectIds: [...divergence.objectIds] } : {}),
190
+ };
191
+ }
192
+
193
+ function copyGraphOracleReference(
194
+ reference: AiPe2GraphOracleReference,
195
+ ): AiPe2GraphOracleReference {
196
+ return {
197
+ mode: reference.mode,
198
+ cacheKey: reference.cacheKey,
199
+ ...(reference.lane ? { lane: reference.lane } : {}),
200
+ ...(reference.docId ? { docId: reference.docId } : {}),
201
+ ...(reference.pageCount !== undefined ? { pageCount: reference.pageCount } : {}),
202
+ ...(reference.paragraphCount !== undefined
203
+ ? { paragraphCount: reference.paragraphCount }
204
+ : {}),
205
+ ...(reference.pdfSha256 ? { pdfSha256: reference.pdfSha256 } : {}),
206
+ ...(reference.sourceSha256 ? { sourceSha256: reference.sourceSha256 } : {}),
207
+ ...(reference.backendIdentityTag
208
+ ? { backendIdentityTag: reference.backendIdentityTag }
209
+ : {}),
175
210
  };
176
211
  }
177
212
 
@@ -232,6 +267,9 @@ function copyOracleEvidence(evidence: AiPe2OracleEvidence): AiPe2OracleEvidence
232
267
  status: evidence.status,
233
268
  runIds: [...evidence.runIds],
234
269
  divergenceIds: [...evidence.divergenceIds],
270
+ ...(evidence.graphOracleReferences
271
+ ? { graphOracleReferences: evidence.graphOracleReferences.map(copyGraphOracleReference) }
272
+ : {}),
235
273
  ...(evidence.verdict ? { verdict: evidence.verdict } : {}),
236
274
  ...(evidence.reason ? { reason: evidence.reason } : {}),
237
275
  };
@@ -41,6 +41,7 @@ import {
41
41
  projectAuditReference,
42
42
  type AiActionAuditReference,
43
43
  } from "./_audit-reference.ts";
44
+ import { currentAuditTimestamp } from "./_audit-time.ts";
44
45
 
45
46
  export interface AttachExplanationInput {
46
47
  readonly scopeId: string;
@@ -146,10 +147,12 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
146
147
  );
147
148
  const preScope = captureScopeSnapshot(runtime, input.scopeId);
148
149
  const documentHashBefore = snapshotDocumentHash(runtime);
150
+ const emittedAtUtc = currentAuditTimestamp(runtime);
149
151
  const primitiveResult = compiler.attachExplanation({
150
152
  scopeId: input.scopeId,
151
153
  explanation: input.explanation,
152
154
  explanationId,
155
+ createdAtUtc: emittedAtUtc,
153
156
  });
154
157
  let auditReference: AiActionAuditReference | undefined;
155
158
  if (primitiveResult.attached && preScope) {
@@ -169,7 +172,7 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
169
172
  },
170
173
  compiledOperationKind: "metadata-attach-explanation",
171
174
  compiledOperationSummary: `attach explanation ${primitiveResult.explanationId} to scope ${input.scopeId}`,
172
- emittedAtUtc: new Date(0).toISOString(),
175
+ emittedAtUtc,
173
176
  documentHashBefore,
174
177
  });
175
178
  auditReference = projectAuditReference(audit);
@@ -206,11 +209,13 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
206
209
  );
207
210
  const preScope = captureScopeSnapshot(runtime, input.scopeId);
208
211
  const documentHashBefore = snapshotDocumentHash(runtime);
212
+ const emittedAtUtc = currentAuditTimestamp(runtime);
209
213
  const primitiveResult = compiler.createIssue({
210
214
  scopeId: input.scopeId,
211
215
  summary: input.summary,
212
216
  ...(input.severity ? { severity: input.severity } : {}),
213
217
  issueId,
218
+ createdAtUtc: emittedAtUtc,
214
219
  });
215
220
  let auditReference: AiActionAuditReference | undefined;
216
221
  if (primitiveResult.created && preScope) {
@@ -231,7 +236,7 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
231
236
  },
232
237
  compiledOperationKind: "metadata-attach-issue",
233
238
  compiledOperationSummary: `create issue ${primitiveResult.issueId} on scope ${input.scopeId}`,
234
- emittedAtUtc: new Date(0).toISOString(),
239
+ emittedAtUtc,
235
240
  documentHashBefore,
236
241
  });
237
242
  auditReference = projectAuditReference(audit);