@beyondwork/docx-react-component 1.0.105 → 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 (193) 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 +10 -2
  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-reference.ts +28 -0
  11. package/src/api/v3/ai/_audit-time.ts +5 -0
  12. package/src/api/v3/ai/_pe2-evidence.ts +310 -6
  13. package/src/api/v3/ai/attach.ts +29 -4
  14. package/src/api/v3/ai/bundle.ts +6 -2
  15. package/src/api/v3/ai/inspect.ts +6 -2
  16. package/src/api/v3/ai/replacement.ts +112 -18
  17. package/src/api/v3/ai/resolve.ts +2 -2
  18. package/src/api/v3/ai/review.ts +177 -3
  19. package/src/api/v3/index.ts +8 -0
  20. package/src/api/v3/runtime/collab.ts +462 -0
  21. package/src/api/v3/runtime/document.ts +503 -20
  22. package/src/api/v3/runtime/geometry.ts +97 -0
  23. package/src/api/v3/runtime/layout.ts +744 -0
  24. package/src/api/v3/runtime/perf-probe.ts +14 -0
  25. package/src/api/v3/runtime/viewport.ts +9 -8
  26. package/src/api/v3/ui/_types.ts +202 -55
  27. package/src/api/v3/ui/chrome-preset-model.ts +5 -5
  28. package/src/api/v3/ui/debug.ts +115 -2
  29. package/src/api/v3/ui/index.ts +17 -0
  30. package/src/api/v3/ui/overlays.ts +0 -8
  31. package/src/api/v3/ui/surface.ts +56 -0
  32. package/src/api/v3/ui/viewport.ts +119 -9
  33. package/src/core/commands/image-commands.ts +1 -0
  34. package/src/core/commands/index.ts +6 -0
  35. package/src/core/schema/text-schema.ts +43 -5
  36. package/src/core/selection/mapping.ts +8 -1
  37. package/src/core/selection/review-anchors.ts +5 -1
  38. package/src/core/state/text-transaction.ts +8 -2
  39. package/src/io/export/serialize-revisions.ts +149 -1
  40. package/src/io/normalize/normalize-text.ts +6 -0
  41. package/src/io/ooxml/parse-bookmark-references.ts +55 -0
  42. package/src/io/ooxml/parse-fields.ts +24 -2
  43. package/src/io/ooxml/parse-headers-footers.ts +38 -5
  44. package/src/io/ooxml/parse-main-document.ts +153 -9
  45. package/src/io/ooxml/parse-numbering.ts +20 -0
  46. package/src/io/ooxml/parse-revisions.ts +19 -8
  47. package/src/io/opc/package-reader.ts +98 -8
  48. package/src/model/anchor.ts +4 -3
  49. package/src/model/canonical-document.ts +220 -2
  50. package/src/model/canonical-hash.ts +221 -0
  51. package/src/model/canonical-layout-inputs.ts +245 -6
  52. package/src/model/layout/index.ts +1 -0
  53. package/src/model/layout/page-graph-types.ts +147 -1
  54. package/src/model/review/revision-types.ts +14 -3
  55. package/src/preservation/store.ts +20 -4
  56. package/src/review/README.md +1 -1
  57. package/src/review/store/revision-actions.ts +14 -2
  58. package/src/runtime/collab/event-types.ts +67 -1
  59. package/src/runtime/collab/runtime-collab-sync.ts +177 -5
  60. package/src/runtime/diagnostics/layout-guard-warning.ts +18 -0
  61. package/src/runtime/document-heading-outline.ts +147 -0
  62. package/src/runtime/document-navigation.ts +8 -243
  63. package/src/runtime/document-runtime.ts +279 -115
  64. package/src/runtime/edit-dispatch/dispatch-text-command.ts +11 -0
  65. package/src/runtime/formatting/layout-inputs.ts +38 -5
  66. package/src/runtime/formatting/numbering/geometry.ts +28 -2
  67. package/src/runtime/geometry/adjacent-geometry-intake.ts +835 -0
  68. package/src/runtime/geometry/caret-geometry.ts +5 -6
  69. package/src/runtime/geometry/geometry-facet.ts +60 -10
  70. package/src/runtime/geometry/geometry-index.ts +661 -16
  71. package/src/runtime/geometry/geometry-types.ts +59 -0
  72. package/src/runtime/geometry/hit-test.ts +11 -1
  73. package/src/runtime/geometry/overlay-rects.ts +5 -3
  74. package/src/runtime/geometry/project-anchors.ts +1 -1
  75. package/src/runtime/geometry/word-layout-v2-line-intake.ts +323 -0
  76. package/src/runtime/layout/index.ts +6 -0
  77. package/src/runtime/layout/layout-engine-instance.ts +6 -1
  78. package/src/runtime/layout/layout-engine-version.ts +188 -16
  79. package/src/runtime/layout/layout-facet-types.ts +6 -0
  80. package/src/runtime/layout/page-graph.ts +23 -4
  81. package/src/runtime/layout/paginated-layout-engine.ts +149 -15
  82. package/src/runtime/layout/project-block-fragments.ts +351 -14
  83. package/src/runtime/layout/public-facet.ts +162 -24
  84. package/src/runtime/layout/table-row-continuation-contract.ts +107 -0
  85. package/src/runtime/layout/table-row-split.ts +92 -35
  86. package/src/runtime/prerender/cache-envelope.ts +2 -2
  87. package/src/runtime/prerender/cache-key.ts +5 -4
  88. package/src/runtime/prerender/customxml-cache.ts +0 -1
  89. package/src/runtime/render/render-kernel.ts +1 -1
  90. package/src/runtime/revision-runtime.ts +112 -10
  91. package/src/runtime/scopes/_scope-dependencies.ts +1 -0
  92. package/src/runtime/scopes/action-validation.ts +22 -2
  93. package/src/runtime/scopes/capabilities.ts +316 -0
  94. package/src/runtime/scopes/compile-scope-bundle.ts +14 -0
  95. package/src/runtime/scopes/compiler-service.ts +108 -4
  96. package/src/runtime/scopes/content-control-evidence.ts +79 -0
  97. package/src/runtime/scopes/create-issue.ts +5 -5
  98. package/src/runtime/scopes/evidence.ts +91 -0
  99. package/src/runtime/scopes/formatting/apply.ts +2 -0
  100. package/src/runtime/scopes/geometry-evidence.ts +130 -0
  101. package/src/runtime/scopes/index.ts +54 -0
  102. package/src/runtime/scopes/issue-lifecycle.ts +224 -0
  103. package/src/runtime/scopes/layout-evidence.ts +374 -0
  104. package/src/runtime/scopes/multi-paragraph-refusal.ts +37 -0
  105. package/src/runtime/scopes/preservation-boundary.ts +7 -1
  106. package/src/runtime/scopes/replacement/apply.ts +97 -34
  107. package/src/runtime/scopes/scope-kinds/paragraph.ts +108 -12
  108. package/src/runtime/scopes/semantic-scope-types.ts +242 -3
  109. package/src/runtime/scopes/visualization.ts +28 -0
  110. package/src/runtime/surface-projection.ts +44 -5
  111. package/src/runtime/telemetry/perf-probe.ts +216 -0
  112. package/src/runtime/virtualized-rendering.ts +36 -1
  113. package/src/runtime/workflow/ai-issue-lifecycle.ts +253 -0
  114. package/src/runtime/workflow/coordinator.ts +39 -11
  115. package/src/runtime/workflow/derived-scope-resolver.ts +63 -9
  116. package/src/runtime/workflow/index.ts +4 -0
  117. package/src/runtime/workflow/overlay-lane-types.ts +58 -0
  118. package/src/runtime/workflow/overlay-lanes.ts +386 -0
  119. package/src/runtime/workflow/overlay-store.ts +2 -2
  120. package/src/runtime/workflow/redline-posture-calibration.ts +257 -0
  121. package/src/runtime/workflow/word-field-matrix-calibration.ts +231 -0
  122. package/src/session/_sync-legacy.ts +17 -27
  123. package/src/session/import/loader.ts +6 -4
  124. package/src/session/import/source-package-evidence.ts +186 -2
  125. package/src/session/index.ts +5 -6
  126. package/src/session/session.ts +30 -56
  127. package/src/session/types.ts +8 -13
  128. package/src/shell/session-bootstrap.ts +155 -81
  129. package/src/ui/WordReviewEditor.tsx +520 -12
  130. package/src/ui/editor-shell-view.tsx +14 -4
  131. package/src/ui/editor-surface-controller.tsx +5 -3
  132. package/src/ui/headless/selection-tool-resolver.ts +1 -2
  133. package/src/ui/presence-overlay-lane.ts +130 -0
  134. package/src/ui/ui-controller-factory.ts +17 -0
  135. package/src/ui-tailwind/chrome/build-context-menu-entries.ts +5 -1
  136. package/src/ui-tailwind/chrome/editor-action-registry.ts +105 -5
  137. package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +7 -0
  138. package/src/ui-tailwind/chrome/layer-debug-contracts.ts +208 -0
  139. package/src/ui-tailwind/chrome/resolve-target-kind.ts +13 -0
  140. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +11 -3
  141. package/src/ui-tailwind/chrome/tw-command-palette.tsx +36 -6
  142. package/src/ui-tailwind/chrome/tw-context-menu.tsx +6 -1
  143. package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +42 -109
  144. package/src/ui-tailwind/chrome/tw-inline-find-bar.tsx +26 -6
  145. package/src/ui-tailwind/chrome/tw-navigation-command-bar.tsx +328 -0
  146. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +8 -4
  147. package/src/ui-tailwind/chrome/tw-runtime-repl-dialog.tsx +129 -1
  148. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +19 -5
  149. package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +5 -1
  150. package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +28 -12
  151. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +30 -3
  152. package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +116 -10
  153. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +223 -94
  154. package/src/ui-tailwind/chrome-overlay/tw-presence-overlay-lane.tsx +157 -0
  155. package/src/ui-tailwind/chrome-overlay/tw-review-overlay-lane-markers.tsx +259 -0
  156. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +5 -2
  157. package/src/ui-tailwind/chrome-overlay/tw-substrate-overlay-lanes.tsx +314 -0
  158. package/src/ui-tailwind/debug/README.md +4 -1
  159. package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +272 -0
  160. package/src/ui-tailwind/debug/layer11-word-field-matrix-evidence.ts +160 -0
  161. package/src/ui-tailwind/editor-surface/perf-probe.ts +14 -215
  162. package/src/ui-tailwind/editor-surface/pm-decorations.ts +42 -0
  163. package/src/ui-tailwind/editor-surface/pm-position-map.ts +38 -2
  164. package/src/ui-tailwind/editor-surface/pm-schema.ts +14 -4
  165. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +34 -5
  166. package/src/ui-tailwind/editor-surface/runtime-decoration-plugin.ts +9 -19
  167. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -2
  168. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +145 -0
  169. package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +16 -11
  170. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +8 -10
  171. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +3 -0
  172. package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +4 -2
  173. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +60 -20
  174. package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +16 -11
  175. package/src/ui-tailwind/review/tw-health-panel.tsx +36 -17
  176. package/src/ui-tailwind/review/tw-review-rail.tsx +7 -4
  177. package/src/ui-tailwind/review-workspace/diagnostics-visibility.ts +44 -0
  178. package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +11 -0
  179. package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +16 -1
  180. package/src/ui-tailwind/review-workspace/types.ts +26 -12
  181. package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +40 -11
  182. package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +2 -1
  183. package/src/ui-tailwind/review-workspace/use-page-markers.ts +15 -26
  184. package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +35 -18
  185. package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +41 -32
  186. package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +2 -1
  187. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +2 -1
  188. package/src/ui-tailwind/status/tw-status-bar.tsx +6 -5
  189. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +52 -80
  190. package/src/ui-tailwind/toolbar/tw-shell-header.tsx +12 -48
  191. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +9 -4
  192. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +328 -361
  193. package/src/ui-tailwind/tw-review-workspace.tsx +152 -286
@@ -0,0 +1,14 @@
1
+ export {
2
+ finishPerfProbe,
3
+ getLatestPerfSummary,
4
+ incrementInvalidationCounter,
5
+ PREDICTED_LANE_COUNTERS,
6
+ recordPerfSample,
7
+ resetPerfProbeState,
8
+ startPerfProbe,
9
+ } from "../../../runtime/telemetry/perf-probe.ts";
10
+ export type {
11
+ PerfProbeKind,
12
+ PerfProbeSample,
13
+ PerfProbeSummary,
14
+ } from "../../../runtime/telemetry/perf-probe.ts";
@@ -21,21 +21,22 @@
21
21
  * reads; `stateClass: "A-canonical"` + `persistsTo: "canonical"` — the
22
22
  * layout facet is derived canonical state.
23
23
  *
24
- * `elementId` stays `null` until L11's per-page content wrapper (coord-11
25
- * §19 / §P) lands with a stable `data-page-frame-start="page-<section>-<page>"`
26
- * id. Until then callers rely on `scrollY` / `pageRect` for positioning.
24
+ * `elementId` matches the stable per-page card anchor id that L11 paints on the
25
+ * page-card layer. Callers can prefer the element when mounted and fall back to
26
+ * `scrollY` / `pageRect` in headless or prerender paths.
27
27
  */
28
28
 
29
29
  import type { RuntimeApiHandle } from "../_runtime-handle.ts";
30
30
  import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
31
31
  import { DEFAULT_PX_PER_TWIP } from "../../public-types.ts";
32
+ import { buildPageAnchorElementId } from "../_page-anchor-id.ts";
32
33
 
33
34
  /**
34
35
  * Resolves a 1-based page number to a stable scroll target.
35
36
  *
36
- * - `elementId`: DOM id L11 populates on the per-page content wrapper.
37
- * Returns `null` while the L11 wrapper contract (coord-11 §19 / §P)
38
- * is still in flight — callers fall back to `scrollY`.
37
+ * - `elementId`: DOM id L11 populates on the per-page card anchor.
38
+ * Mounted callers can scroll/focus by element; headless callers still use
39
+ * `scrollY`.
39
40
  * - `scrollY`: scroll-container-relative Y offset of the page's top
40
41
  * edge in CSS px. Computed as the sum of prior pages' heights via
41
42
  * the layout facet's page graph.
@@ -94,7 +95,7 @@ export const getPageAnchorMetadata: ApiV3FnMetadata = {
94
95
  stateClass: "A-canonical",
95
96
  persistsTo: "canonical",
96
97
  rwdReference:
97
- "§Runtime API § runtime.viewport.getPageAnchor. Reads the kernel-authoritative page frame from `handle.geometry.getPage(index).frame` — same source `ui.viewport.scrollToPage(n)` consumes (coord-10 §γ shipment `b8116b97`), so values stay consistent across the two surfaces. `elementId` stays null until L11's per-page content wrapper (coord-11 §19 / §P) lands; until then callers position off `scrollY` / `pageRect`. Promotes to `live` when the geometry facet surfaces a direct `getPageAnchor(pageNumber)` reader or when elementId is populated.",
98
+ "§Runtime API § runtime.viewport.getPageAnchor. Reads the kernel-authoritative page frame from `handle.geometry.getPage(index).frame` — same source `ui.viewport.scrollToPage(n)` consumes (coord-10 §γ shipment `b8116b97`), so values stay consistent across the two surfaces. `elementId` is the stable L11 page-card anchor id; mounted callers can resolve it when the page-card layer is present and fall back to `scrollY` / `pageRect` otherwise. Promotes to `live` when the geometry facet surfaces a direct `getPageAnchor(pageNumber)` reader.",
98
99
  };
99
100
 
100
101
  /* ================================================================== */
@@ -145,7 +146,7 @@ export function createViewportFamily(runtime: RuntimeApiHandle) {
145
146
  const page = geometry?.getPage(pageIndex);
146
147
  if (!page) return null;
147
148
  return {
148
- elementId: null,
149
+ elementId: buildPageAnchorElementId(page.pageId, pageIndex),
149
150
  scrollY: page.frame.topPx,
150
151
  pageRect: {
151
152
  left: page.frame.leftPx,
@@ -35,6 +35,14 @@ import type {
35
35
  WorkflowMarkupMode,
36
36
  } from "../../public-types.ts";
37
37
  import type { GeometryRect } from "../../../runtime/geometry/geometry-types.ts";
38
+ import type {
39
+ WorkflowOverlayAnchorQuery,
40
+ WorkflowOverlayLaneEntry,
41
+ WorkflowOverlayLaneKind,
42
+ WorkflowOverlayLaneSnapshot,
43
+ WorkflowOverlayLaneSource,
44
+ WorkflowOverlayLaneStatus,
45
+ } from "../../../runtime/workflow/overlay-lane-types.ts";
38
46
  import type {
39
47
  ChromeComposition,
40
48
  ChromeCompositionInput,
@@ -104,6 +112,15 @@ export interface UiController {
104
112
  * the scroll settles (or immediately for `behavior: "instant"`).
105
113
  */
106
114
  readonly dispatchScroll?: (target: ScrollTarget) => Promise<void>;
115
+ /**
116
+ * Object-drag lifecycle for mounted object handles. The bind-side owns the
117
+ * concrete mutation path (image resize/reposition today) and returns a
118
+ * session object with update/commit/cancel methods. Missing hook means the
119
+ * mounted surface has not wired object drag.
120
+ */
121
+ readonly beginObjectDrag?: (
122
+ input: UiObjectDragStartInput,
123
+ ) => UiObjectDragSession;
107
124
  /**
108
125
  * Viewport provider. Optional. Slice 2 reads viewport through this when
109
126
  * present; a geometry-backed path lands when `RuntimeApiHandle` gains a
@@ -118,6 +135,21 @@ export interface UiController {
118
135
  * error rather than silently no-op.
119
136
  */
120
137
  readonly subscribeViewport?: (listener: UiListener<ViewportState>) => UiUnsubscribe;
138
+ /**
139
+ * PE2 page-residency policy read. L10 owns the observable residency
140
+ * shape; L11 owns realized DOM/PM attachment and L05 owns geometry
141
+ * caches. Omitting the hook makes `ui.viewport.getPageResidency`
142
+ * return an explicit unavailable snapshot.
143
+ */
144
+ readonly getPageResidency?: (pageIndex: number) => PageResidencySnapshot;
145
+ /**
146
+ * Page-residency subscription. Fires when the mounted surface changes
147
+ * whether a page is realized, cold, or evicted.
148
+ */
149
+ readonly subscribePageResidency?: (
150
+ pageIndex: number,
151
+ listener: UiListener<PageResidencySnapshot>,
152
+ ) => UiUnsubscribe;
121
153
  /**
122
154
  * Overlay invalidation subscription. Fires when geometry invalidation
123
155
  * ranges overlap attached overlay queries (U7). `ui.overlays.subscribe`
@@ -187,6 +219,23 @@ export interface UiController {
187
219
  readonly subscribeChrome?: (
188
220
  listener: UiListener<ChromePosture>,
189
221
  ) => UiUnsubscribe;
222
+ /**
223
+ * KI-010 debug-inspector evidence lane read. Debug infra owns the
224
+ * evidence adapters; L10 owns the mounted UI API seam that exposes
225
+ * their plain snapshots without layout/cache ownership.
226
+ */
227
+ readonly getDebugEvidenceLane?: (
228
+ kind: UiDebugEvidenceLaneKind,
229
+ ) => UiDebugEvidenceLaneSnapshot;
230
+ /**
231
+ * KI-010 debug-inspector evidence lane subscription. Fan-out is UI
232
+ * state only; bind-side implementations must not dispatch PM
233
+ * transactions or invalidate L04 layout.
234
+ */
235
+ readonly subscribeDebugEvidenceLane?: (
236
+ kind: UiDebugEvidenceLaneKind,
237
+ listener: UiListener<UiDebugEvidenceLaneSnapshot>,
238
+ ) => UiUnsubscribe;
190
239
  }
191
240
 
192
241
  /**
@@ -234,6 +283,29 @@ export interface ViewportState {
234
283
  readonly devicePixelRatio: number;
235
284
  }
236
285
 
286
+ export type PageResidency = "realized" | "cold" | "evicted";
287
+
288
+ export type RehydrationStatus =
289
+ | "available"
290
+ | "requires-rehydration"
291
+ | "unavailable";
292
+
293
+ export type PageResidencySource =
294
+ | "controller"
295
+ | "unavailable";
296
+
297
+ export interface PageResidencySnapshot {
298
+ readonly __mock?: true;
299
+ /** 0-based page index, matching GeometryFacet.getPage(index). */
300
+ readonly pageIndex: number;
301
+ readonly pageId?: string;
302
+ readonly residency: PageResidency;
303
+ readonly status: RehydrationStatus;
304
+ readonly revision: number;
305
+ readonly source: PageResidencySource;
306
+ readonly reason?: string;
307
+ }
308
+
237
309
  export type ScrollTargetBehavior = "auto" | "smooth" | "instant";
238
310
 
239
311
  export type ScrollTarget =
@@ -258,10 +330,14 @@ export type ScrollTarget =
258
330
  * that want to verify their own scroll container landed at the
259
331
  * expected coordinate (visual-fidelity harness: deterministic
260
332
  * per-page capture).
333
+ * - `elementId` is the stable mounted page-card anchor id produced by
334
+ * Layer 11. Mounted consumers can resolve it directly and fall back to
335
+ * `scrollY` in headless / pre-mount paths.
261
336
  */
262
337
  export interface ScrollToPageResult {
263
338
  readonly actualPage: number;
264
339
  readonly scrollY: number;
340
+ readonly elementId: string;
265
341
  }
266
342
 
267
343
  export interface SelectionRangeInput {
@@ -271,71 +347,79 @@ export interface SelectionRangeInput {
271
347
  }
272
348
 
273
349
  /* ================================================================== */
274
- /* OverlaysU4: anchor derivation from geometry */
350
+ /* Object drag mounted object handles */
275
351
  /* ================================================================== */
276
352
 
277
- export type OverlayAnchorQuery =
278
- | { kind: "block"; value: string }
279
- | { kind: "scope"; value: string }
280
- | { kind: "comment"; value: string }
281
- | { kind: "revision"; value: string }
282
- | { kind: "page"; value: number }
283
- | { kind: "selection" };
353
+ export type UiObjectDragHandle =
354
+ | "move"
355
+ | "rotate"
356
+ | "nw"
357
+ | "n"
358
+ | "ne"
359
+ | "w"
360
+ | "e"
361
+ | "sw"
362
+ | "s"
363
+ | "se";
364
+
365
+ export interface UiObjectDragPoint {
366
+ readonly clientX: number;
367
+ readonly clientY: number;
368
+ }
284
369
 
285
- /* ================================================================== */
286
- /* PE2 overlay lanes */
287
- /* ================================================================== */
370
+ export interface UiObjectDragStartInput extends UiObjectDragPoint {
371
+ readonly objectId: string;
372
+ readonly handle: UiObjectDragHandle;
373
+ readonly initialRect: GeometryRect;
374
+ }
288
375
 
289
- export type UiOverlayLaneKind =
290
- | "selection"
291
- | "caret"
292
- | "redlines"
293
- | "field-scopes"
294
- | "broad-scopes"
295
- | "comments"
296
- | "issues"
297
- | "tables"
298
- | "objects"
299
- | "search"
300
- | "presence";
301
-
302
- export type UiOverlayLaneStatus =
303
- | "resolved"
304
- | "requires-rehydration"
305
- | "unavailable";
376
+ export interface UiObjectDragUpdateInput extends Partial<UiObjectDragPoint> {
377
+ readonly deltaX?: number;
378
+ readonly deltaY?: number;
379
+ }
306
380
 
307
- export type UiOverlayLaneSource =
308
- | "geometry"
309
- | "workflow"
310
- | "search"
311
- | "awareness"
312
- | "controller"
313
- | "unavailable";
381
+ export interface UiObjectDragSnapshot {
382
+ readonly objectId: string;
383
+ readonly handle: UiObjectDragHandle;
384
+ readonly status: "active" | "committed" | "cancelled";
385
+ readonly deltaPx: { readonly x: number; readonly y: number };
386
+ readonly previewRect?: GeometryRect;
387
+ }
314
388
 
315
- export interface UiOverlayLaneEntry {
316
- readonly id: string;
317
- readonly status: UiOverlayLaneStatus;
318
- readonly anchor?: OverlayAnchorQuery;
319
- readonly rects?: readonly GeometryRect[];
389
+ export interface UiObjectDragCommitResult extends UiObjectDragSnapshot {
390
+ readonly changed: boolean;
320
391
  readonly reason?: string;
321
- /**
322
- * Lane-specific plain payload. Examples: peer identity for presence,
323
- * issue severity, search rank, table/object classification. Kept plain
324
- * so non-React consumers and debug runners can serialize snapshots.
325
- */
326
- readonly data?: Readonly<Record<string, unknown>>;
327
392
  }
328
393
 
329
- export interface UiOverlayLaneSnapshot {
330
- readonly __mock?: true;
331
- readonly kind: UiOverlayLaneKind;
332
- readonly status: UiOverlayLaneStatus;
333
- readonly entries: readonly UiOverlayLaneEntry[];
334
- readonly revision: number;
335
- readonly source: UiOverlayLaneSource;
336
- readonly reason?: string;
394
+ export interface UiObjectDragSession {
395
+ readonly id: string;
396
+ readonly objectId: string;
397
+ readonly handle: UiObjectDragHandle;
398
+ update(input: UiObjectDragUpdateInput): UiObjectDragSnapshot;
399
+ commit(input?: UiObjectDragUpdateInput): UiObjectDragCommitResult;
400
+ cancel(): UiObjectDragCommitResult;
337
401
  }
338
402
 
403
+ /* Overlays — U4: anchor derivation from geometry */
404
+ /* ================================================================== */
405
+
406
+ export type OverlayAnchorQuery = WorkflowOverlayAnchorQuery;
407
+
408
+ /* ================================================================== */
409
+ /* PE2 overlay lanes */
410
+ /* ================================================================== */
411
+
412
+ /**
413
+ * L10 re-exports the plain PE2 overlay lane contract, but the canonical
414
+ * snapshot shape lives in Layer 6 workflow because durable review/workflow
415
+ * lanes are authored there and consumed by L10/L11.
416
+ */
417
+ export type UiOverlayLaneKind = WorkflowOverlayLaneKind;
418
+ export type UiOverlayLaneStatus = WorkflowOverlayLaneStatus;
419
+ export type UiOverlayLaneSource = WorkflowOverlayLaneSource;
420
+ export type UiOverlayLaneEntry = WorkflowOverlayLaneEntry;
421
+ export type UiOverlayLaneSnapshot = WorkflowOverlayLaneSnapshot;
422
+
339
423
  /* ================================================================== */
340
424
  /* Overlay visibility — U9 (state-classes X3) */
341
425
  /* ================================================================== */
@@ -425,6 +509,48 @@ export interface DebugAttachment {
425
509
  readonly detach: () => void;
426
510
  }
427
511
 
512
+ export const UI_DEBUG_EVIDENCE_LANE_KINDS = [
513
+ "artifact-integrity",
514
+ "pe2-runtime-projection",
515
+ "visual-manifest",
516
+ "cross-oracle",
517
+ "overlay-invalidation",
518
+ "word-field-matrix",
519
+ ] as const;
520
+
521
+ export type UiDebugEvidenceLaneKind =
522
+ typeof UI_DEBUG_EVIDENCE_LANE_KINDS[number];
523
+
524
+ export type UiDebugEvidenceLaneStatus =
525
+ | "available"
526
+ | "requires-rehydration"
527
+ | "unavailable"
528
+ | "infra-blocked";
529
+
530
+ export type UiDebugEvidenceLaneSource =
531
+ | "controller"
532
+ | "unavailable";
533
+
534
+ export interface UiDebugEvidenceLaneEntry {
535
+ readonly id: string;
536
+ readonly status: UiDebugEvidenceLaneStatus;
537
+ readonly label?: string;
538
+ readonly source?: string;
539
+ readonly summary?: string;
540
+ readonly reason?: string;
541
+ readonly payload?: unknown;
542
+ }
543
+
544
+ export interface UiDebugEvidenceLaneSnapshot {
545
+ readonly __mock?: true;
546
+ readonly kind: UiDebugEvidenceLaneKind;
547
+ readonly status: UiDebugEvidenceLaneStatus;
548
+ readonly revision: number;
549
+ readonly source: UiDebugEvidenceLaneSource;
550
+ readonly entries: readonly UiDebugEvidenceLaneEntry[];
551
+ readonly reason?: string;
552
+ }
553
+
428
554
  /* ================================================================== */
429
555
  /* Subscription */
430
556
  /* ================================================================== */
@@ -447,17 +573,33 @@ export interface ApiV3UiSurface {
447
573
  setSelection(range: SelectionRangeInput): void;
448
574
  getViewport(): ViewportState;
449
575
  scrollTo(target: ScrollTarget): Promise<void>;
576
+ beginObjectDrag(input: UiObjectDragStartInput): UiObjectDragSession;
450
577
  }
451
578
 
452
579
  export interface ApiV3UiViewport {
453
580
  get(): ViewportState;
454
581
  subscribe(listener: UiListener<ViewportState>): UiUnsubscribe;
582
+ /**
583
+ * Read L10's page-residency policy for a 0-based page index. When no
584
+ * mounted controller has supplied a residency policy yet, returns an
585
+ * explicit `unavailable` mock snapshot instead of probing geometry or
586
+ * realizing DOM.
587
+ */
588
+ getPageResidency(pageIndex: number): PageResidencySnapshot;
589
+ /**
590
+ * Subscribe to residency changes for a 0-based page index. The listener
591
+ * receives plain snapshots; realization/teardown stays owned by L11.
592
+ */
593
+ subscribePageResidency(
594
+ pageIndex: number,
595
+ listener: UiListener<PageResidencySnapshot>,
596
+ ): UiUnsubscribe;
455
597
 
456
598
  /**
457
599
  * Scroll the mounted surface to a specific 1-based page number.
458
600
  * Resolves via `handle.geometry.getPage`; dispatches through the
459
601
  * bound controller's `dispatchScroll` hook. Returns the settled
460
- * `{ actualPage, scrollY }` or `null` when geometry cannot resolve
602
+ * `{ actualPage, scrollY, elementId }` or `null` when geometry cannot resolve
461
603
  * any page / no controller bound / no dispatchScroll hook.
462
604
  * Clamps pageNumber to the document's valid range; `actualPage`
463
605
  * reflects the clamp. coord-10 §γ first-class replacement for the
@@ -627,6 +769,11 @@ export interface ApiV3UiChrome {
627
769
  export interface ApiV3UiDebug {
628
770
  attach(session: DebugSession): DebugAttachment;
629
771
  detach(): void;
772
+ getEvidenceLane(kind: UiDebugEvidenceLaneKind): UiDebugEvidenceLaneSnapshot;
773
+ subscribeEvidenceLane(
774
+ kind: UiDebugEvidenceLaneKind,
775
+ listener: UiListener<UiDebugEvidenceLaneSnapshot>,
776
+ ): UiUnsubscribe;
630
777
  }
631
778
 
632
779
  export interface UiScopeListFilter {
@@ -127,7 +127,7 @@ export function resolveChromeVisibilityForPreset(input: {
127
127
  pageChrome: true,
128
128
  statusBar: true,
129
129
  reviewRail: false,
130
- shellHeader: true,
130
+ shellHeader: false,
131
131
  },
132
132
  advanced: {
133
133
  toolbar: true,
@@ -138,7 +138,7 @@ export function resolveChromeVisibilityForPreset(input: {
138
138
  pageChrome: true,
139
139
  statusBar: true,
140
140
  reviewRail: true,
141
- shellHeader: true,
141
+ shellHeader: false,
142
142
  },
143
143
  review: {
144
144
  toolbar: true,
@@ -149,7 +149,7 @@ export function resolveChromeVisibilityForPreset(input: {
149
149
  pageChrome: true,
150
150
  statusBar: true,
151
151
  reviewRail: options.showReviewRail,
152
- shellHeader: true,
152
+ shellHeader: false,
153
153
  },
154
154
  workflow: {
155
155
  toolbar: true,
@@ -160,7 +160,7 @@ export function resolveChromeVisibilityForPreset(input: {
160
160
  pageChrome: true,
161
161
  statusBar: true,
162
162
  reviewRail: options.showReviewRail,
163
- shellHeader: true,
163
+ shellHeader: false,
164
164
  },
165
165
  collab: {
166
166
  toolbar: true,
@@ -171,7 +171,7 @@ export function resolveChromeVisibilityForPreset(input: {
171
171
  pageChrome: true,
172
172
  statusBar: true,
173
173
  reviewRail: options.showReviewRail,
174
- shellHeader: true,
174
+ shellHeader: false,
175
175
  },
176
176
  };
177
177
 
@@ -12,7 +12,15 @@
12
12
  */
13
13
 
14
14
  import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
15
- import type { DebugSession, DebugAttachment } from "./_types.ts";
15
+ import { emitUxResponse } from "../_ux-response.ts";
16
+ import type {
17
+ DebugSession,
18
+ DebugAttachment,
19
+ UiDebugEvidenceLaneKind,
20
+ UiDebugEvidenceLaneSnapshot,
21
+ UiListener,
22
+ UiUnsubscribe,
23
+ } from "./_types.ts";
16
24
  import type { UiApiContext } from "./_context.ts";
17
25
 
18
26
  export const attachMetadata: ApiV3FnMetadata = {
@@ -47,10 +55,82 @@ export const detachMetadata: ApiV3FnMetadata = {
47
55
  "§UI API § ui.debug.detach. Production-disabled companion no-op retained for defensive cleanup compatibility.",
48
56
  };
49
57
 
58
+ export const getEvidenceLaneMetadata: ApiV3FnMetadata = {
59
+ name: "ui.debug.getEvidenceLane",
60
+ status: "live-with-adapter",
61
+ sourceLayer: "presentation",
62
+ liveEvidence: {
63
+ runnerTest: "test/api/v3/ui/debug-evidence-lanes.test.ts",
64
+ commit: "refactor-10-ki-010",
65
+ },
66
+ mockShape: {
67
+ deterministic: true,
68
+ seededFrom: "fixed",
69
+ shapeDescription:
70
+ "Unavailable UiDebugEvidenceLaneSnapshot with entries:[] and revision:0 when the mounted controller has not wired the requested debug evidence lane yet.",
71
+ carriesMockFlag: true,
72
+ },
73
+ uxIntent: { uiVisible: false },
74
+ agentMetadata: {
75
+ readOrMutate: "read",
76
+ boundedScope: "session",
77
+ auditCategory: "ui-debug-evidence-read",
78
+ },
79
+ stateClass: "C-local",
80
+ persistsTo: "none",
81
+ rwdReference:
82
+ "§UI API § KI-010 debug inspector evidence lanes. Reads a mounted controller-provided plain evidence lane snapshot for artifact integrity, PE2 runtime projection, visual manifest, cross-oracle, overlay invalidation, or Word-first field matrix evidence. Returns explicit status:'unavailable' when unwired; never dispatches PM transactions or invalidates layout.",
83
+ };
84
+
85
+ export const subscribeEvidenceLaneMetadata: ApiV3FnMetadata = {
86
+ name: "ui.debug.subscribeEvidenceLane",
87
+ status: "live-with-adapter",
88
+ sourceLayer: "presentation",
89
+ liveEvidence: {
90
+ runnerTest: "test/api/v3/ui/debug-evidence-lanes.test.ts",
91
+ commit: "refactor-10-ki-010",
92
+ },
93
+ uxIntent: {
94
+ uiVisible: true,
95
+ expectsUxResponse: "surface-refresh",
96
+ expectedDelta:
97
+ "debug evidence lane subscriber attached; future plain evidence snapshots propagate through the listener without PM document transactions or layout invalidation",
98
+ },
99
+ agentMetadata: {
100
+ readOrMutate: "read",
101
+ boundedScope: "session",
102
+ auditCategory: "ui-debug-evidence-subscribe",
103
+ },
104
+ stateClass: "C-local",
105
+ persistsTo: "none",
106
+ bidirectional: true,
107
+ subscriptionShape: {
108
+ eventType: "ui.debug.evidence_lane_changed",
109
+ payloadType: "UiDebugEvidenceLaneSnapshot",
110
+ coalescing: "raf",
111
+ },
112
+ rwdReference:
113
+ "§UI API § KI-010 debug inspector evidence lanes. Adapter delegates to UiController.subscribeDebugEvidenceLane(kind, listener). Debug infra owns evidence adapters; L10 exposes only plain snapshots and subscription fan-out.",
114
+ };
115
+
50
116
  const DEBUG_ATTACH_DISABLED_MESSAGE =
51
117
  "ui.debug.attach is disabled in production; use the runtime REPL keyboard shortcut instead.";
52
118
 
53
- export function createDebugFamily(_ctx: UiApiContext) {
119
+ function unavailableEvidenceLane(
120
+ kind: UiDebugEvidenceLaneKind,
121
+ ): UiDebugEvidenceLaneSnapshot {
122
+ return {
123
+ __mock: true,
124
+ kind,
125
+ status: "unavailable",
126
+ revision: 0,
127
+ source: "unavailable",
128
+ entries: [],
129
+ reason: "debug evidence lane is unavailable until the mounted controller wires it",
130
+ };
131
+ }
132
+
133
+ export function createDebugFamily(ctx: UiApiContext) {
54
134
  return {
55
135
  attach(_session: DebugSession): DebugAttachment {
56
136
  throw new Error(DEBUG_ATTACH_DISABLED_MESSAGE);
@@ -58,5 +138,38 @@ export function createDebugFamily(_ctx: UiApiContext) {
58
138
  detach(): void {
59
139
  // Idempotent compatibility no-op.
60
140
  },
141
+ getEvidenceLane(kind: UiDebugEvidenceLaneKind): UiDebugEvidenceLaneSnapshot {
142
+ return ctx.binding?.controller.getDebugEvidenceLane?.(kind) ??
143
+ unavailableEvidenceLane(kind);
144
+ },
145
+ subscribeEvidenceLane(
146
+ kind: UiDebugEvidenceLaneKind,
147
+ listener: UiListener<UiDebugEvidenceLaneSnapshot>,
148
+ ): UiUnsubscribe {
149
+ const controller = ctx.binding?.controller;
150
+ if (!controller) {
151
+ throw new Error(
152
+ "ui.debug.subscribeEvidenceLane: no controller bound — call ui.session.bind(controller) first",
153
+ );
154
+ }
155
+ if (!controller.subscribeDebugEvidenceLane) {
156
+ throw new Error(
157
+ `ui.debug.subscribeEvidenceLane: controller of kind "${controller.kind}" did not provide a subscribeDebugEvidenceLane hook`,
158
+ );
159
+ }
160
+ const unsubscribe = controller.subscribeDebugEvidenceLane(kind, listener);
161
+ emitUxResponse(ctx.handle, {
162
+ apiFn: subscribeEvidenceLaneMetadata.name,
163
+ intent: subscribeEvidenceLaneMetadata.uxIntent.expectedDelta ?? "",
164
+ mockOrLive: "live-with-adapter",
165
+ uiVisible: true,
166
+ expectedDelta: subscribeEvidenceLaneMetadata.uxIntent.expectedDelta,
167
+ actualDelta: {
168
+ kind: "surface-refresh",
169
+ payload: { subscribed: "ui.debug.evidenceLane", lane: kind },
170
+ },
171
+ });
172
+ return unsubscribe;
173
+ },
61
174
  };
62
175
  }
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  export { createUiApi } from "./_create.ts";
9
+ export { UI_DEBUG_EVIDENCE_LANE_KINDS } from "./_types.ts";
9
10
  export type {
10
11
  ApiV3Ui,
11
12
  ApiV3UiSession,
@@ -24,10 +25,21 @@ export type {
24
25
  UiScopeListFilter,
25
26
  UiScopeRailOptions,
26
27
  ViewportState,
28
+ PageResidency,
29
+ PageResidencySnapshot,
30
+ PageResidencySource,
31
+ RehydrationStatus,
27
32
  ScrollTarget,
28
33
  ScrollTargetBehavior,
29
34
  ScrollToPageResult,
30
35
  SelectionRangeInput,
36
+ UiObjectDragCommitResult,
37
+ UiObjectDragHandle,
38
+ UiObjectDragPoint,
39
+ UiObjectDragSession,
40
+ UiObjectDragSnapshot,
41
+ UiObjectDragStartInput,
42
+ UiObjectDragUpdateInput,
31
43
  OverlayAnchorQuery,
32
44
  OverlayKind,
33
45
  OverlayVisibility,
@@ -42,6 +54,11 @@ export type {
42
54
  ChromeDebugMode,
43
55
  DebugSession,
44
56
  DebugAttachment,
57
+ UiDebugEvidenceLaneEntry,
58
+ UiDebugEvidenceLaneKind,
59
+ UiDebugEvidenceLaneSnapshot,
60
+ UiDebugEvidenceLaneSource,
61
+ UiDebugEvidenceLaneStatus,
45
62
  GeometryRect,
46
63
  UiOverlayLaneEntry,
47
64
  UiOverlayLaneKind,
@@ -207,13 +207,6 @@ export const getLaneMetadata: ApiV3FnMetadata = {
207
207
  runnerTest: "test/api/v3/ui/overlays-lanes.test.ts",
208
208
  commit: "refactor-10-pe2-overlay-lanes",
209
209
  },
210
- mockShape: {
211
- deterministic: true,
212
- seededFrom: "fixed",
213
- shapeDescription:
214
- "Unavailable UiOverlayLaneSnapshot with entries:[] and revision:0 when the mounted controller has not wired the requested PE2 overlay lane yet.",
215
- carriesMockFlag: true,
216
- },
217
210
  uxIntent: { uiVisible: false },
218
211
  agentMetadata: { readOrMutate: "read", boundedScope: "session", auditCategory: "ui-overlays-lane-read" },
219
212
  stateClass: "C-local",
@@ -412,7 +405,6 @@ export function createOverlaysFamily(ctx: UiApiContext) {
412
405
  reason = "overlay lane is not wired on the active controller",
413
406
  ): UiOverlayLaneSnapshot {
414
407
  return {
415
- __mock: true,
416
408
  kind,
417
409
  status: "unavailable",
418
410
  entries: Object.freeze([]),