@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.
- package/package.json +19 -5
- package/src/api/geometry-overlay-rects.ts +5 -0
- package/src/api/package-version.ts +1 -1
- package/src/api/page-anchor-id.ts +5 -0
- package/src/api/public-types.ts +16 -9
- package/src/api/table-node-specs.ts +6 -0
- package/src/api/v3/_create.ts +2 -1
- package/src/api/v3/_page-anchor-id.ts +52 -0
- package/src/api/v3/_runtime-handle.ts +92 -1
- package/src/api/v3/ai/_audit-time.ts +5 -0
- package/src/api/v3/ai/_pe2-evidence.ts +38 -0
- package/src/api/v3/ai/attach.ts +7 -2
- package/src/api/v3/ai/replacement.ts +101 -18
- package/src/api/v3/ai/resolve.ts +2 -2
- package/src/api/v3/ai/review.ts +177 -3
- package/src/api/v3/index.ts +1 -0
- package/src/api/v3/runtime/collab.ts +462 -0
- package/src/api/v3/runtime/document.ts +503 -20
- package/src/api/v3/runtime/geometry.ts +97 -0
- package/src/api/v3/runtime/layout.ts +744 -0
- package/src/api/v3/runtime/perf-probe.ts +14 -0
- package/src/api/v3/runtime/viewport.ts +9 -8
- package/src/api/v3/ui/_types.ts +149 -55
- package/src/api/v3/ui/chrome-preset-model.ts +5 -5
- package/src/api/v3/ui/debug.ts +115 -2
- package/src/api/v3/ui/index.ts +13 -0
- package/src/api/v3/ui/overlays.ts +0 -8
- package/src/api/v3/ui/surface.ts +56 -0
- package/src/api/v3/ui/viewport.ts +22 -9
- package/src/core/commands/image-commands.ts +1 -0
- package/src/core/commands/index.ts +6 -0
- package/src/core/schema/text-schema.ts +43 -5
- package/src/core/selection/mapping.ts +8 -1
- package/src/core/selection/review-anchors.ts +5 -1
- package/src/core/state/text-transaction.ts +8 -2
- package/src/io/export/serialize-revisions.ts +149 -1
- package/src/io/normalize/normalize-text.ts +6 -0
- package/src/io/ooxml/parse-bookmark-references.ts +55 -0
- package/src/io/ooxml/parse-fields.ts +24 -2
- package/src/io/ooxml/parse-headers-footers.ts +38 -5
- package/src/io/ooxml/parse-main-document.ts +153 -9
- package/src/io/ooxml/parse-numbering.ts +20 -0
- package/src/io/ooxml/parse-revisions.ts +19 -8
- package/src/io/opc/package-reader.ts +98 -8
- package/src/model/anchor.ts +4 -3
- package/src/model/canonical-document.ts +220 -2
- package/src/model/canonical-hash.ts +221 -0
- package/src/model/canonical-layout-inputs.ts +245 -6
- package/src/model/layout/index.ts +1 -0
- package/src/model/layout/page-graph-types.ts +118 -1
- package/src/model/review/revision-types.ts +14 -3
- package/src/preservation/store.ts +20 -4
- package/src/review/README.md +1 -1
- package/src/review/store/revision-actions.ts +14 -2
- package/src/runtime/collab/event-types.ts +67 -1
- package/src/runtime/collab/runtime-collab-sync.ts +177 -5
- package/src/runtime/diagnostics/layout-guard-warning.ts +18 -0
- package/src/runtime/document-heading-outline.ts +147 -0
- package/src/runtime/document-navigation.ts +8 -243
- package/src/runtime/document-runtime.ts +240 -97
- package/src/runtime/edit-dispatch/dispatch-text-command.ts +11 -0
- package/src/runtime/formatting/layout-inputs.ts +38 -5
- package/src/runtime/formatting/numbering/geometry.ts +28 -2
- package/src/runtime/geometry/adjacent-geometry-intake.ts +835 -0
- package/src/runtime/geometry/caret-geometry.ts +5 -6
- package/src/runtime/geometry/geometry-facet.ts +60 -10
- package/src/runtime/geometry/geometry-index.ts +591 -20
- package/src/runtime/geometry/geometry-types.ts +59 -0
- package/src/runtime/geometry/hit-test.ts +11 -1
- package/src/runtime/geometry/overlay-rects.ts +5 -3
- package/src/runtime/geometry/project-anchors.ts +1 -1
- package/src/runtime/geometry/word-layout-v2-line-intake.ts +323 -0
- package/src/runtime/layout/index.ts +6 -0
- package/src/runtime/layout/layout-engine-instance.ts +6 -1
- package/src/runtime/layout/layout-engine-version.ts +181 -16
- package/src/runtime/layout/layout-facet-types.ts +6 -0
- package/src/runtime/layout/page-graph.ts +21 -4
- package/src/runtime/layout/paginated-layout-engine.ts +139 -15
- package/src/runtime/layout/project-block-fragments.ts +265 -7
- package/src/runtime/layout/public-facet.ts +78 -24
- package/src/runtime/layout/table-row-continuation-contract.ts +107 -0
- package/src/runtime/layout/table-row-split.ts +92 -35
- package/src/runtime/prerender/cache-envelope.ts +2 -2
- package/src/runtime/prerender/cache-key.ts +5 -4
- package/src/runtime/prerender/customxml-cache.ts +0 -1
- package/src/runtime/render/render-kernel.ts +1 -1
- package/src/runtime/revision-runtime.ts +112 -10
- package/src/runtime/scopes/_scope-dependencies.ts +1 -0
- package/src/runtime/scopes/action-validation.ts +22 -2
- package/src/runtime/scopes/capabilities.ts +316 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +14 -0
- package/src/runtime/scopes/compiler-service.ts +108 -4
- package/src/runtime/scopes/content-control-evidence.ts +79 -0
- package/src/runtime/scopes/create-issue.ts +5 -5
- package/src/runtime/scopes/evidence.ts +91 -0
- package/src/runtime/scopes/formatting/apply.ts +2 -0
- package/src/runtime/scopes/geometry-evidence.ts +130 -0
- package/src/runtime/scopes/index.ts +54 -0
- package/src/runtime/scopes/issue-lifecycle.ts +224 -0
- package/src/runtime/scopes/layout-evidence.ts +374 -0
- package/src/runtime/scopes/multi-paragraph-refusal.ts +37 -0
- package/src/runtime/scopes/preservation-boundary.ts +7 -1
- package/src/runtime/scopes/replacement/apply.ts +97 -34
- package/src/runtime/scopes/scope-kinds/paragraph.ts +108 -12
- package/src/runtime/scopes/semantic-scope-types.ts +242 -3
- package/src/runtime/scopes/visualization.ts +28 -0
- package/src/runtime/surface-projection.ts +44 -5
- package/src/runtime/telemetry/perf-probe.ts +216 -0
- package/src/runtime/virtualized-rendering.ts +36 -1
- package/src/runtime/workflow/ai-issue-lifecycle.ts +253 -0
- package/src/runtime/workflow/coordinator.ts +39 -11
- package/src/runtime/workflow/derived-scope-resolver.ts +63 -9
- package/src/runtime/workflow/index.ts +3 -0
- package/src/runtime/workflow/overlay-lane-types.ts +58 -0
- package/src/runtime/workflow/overlay-lanes.ts +168 -10
- package/src/runtime/workflow/overlay-store.ts +2 -2
- package/src/runtime/workflow/redline-posture-calibration.ts +257 -0
- package/src/runtime/workflow/word-field-matrix-calibration.ts +231 -0
- package/src/session/_sync-legacy.ts +17 -27
- package/src/session/import/loader.ts +6 -4
- package/src/session/import/source-package-evidence.ts +186 -2
- package/src/session/index.ts +5 -6
- package/src/session/session.ts +30 -56
- package/src/session/types.ts +8 -13
- package/src/shell/session-bootstrap.ts +155 -81
- package/src/ui/WordReviewEditor.tsx +520 -12
- package/src/ui/editor-shell-view.tsx +14 -4
- package/src/ui/editor-surface-controller.tsx +5 -3
- package/src/ui/headless/selection-tool-resolver.ts +1 -2
- package/src/ui/presence-overlay-lane.ts +0 -1
- package/src/ui/ui-controller-factory.ts +7 -0
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +5 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +105 -5
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +7 -0
- package/src/ui-tailwind/chrome/layer-debug-contracts.ts +208 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +13 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +11 -3
- package/src/ui-tailwind/chrome/tw-command-palette.tsx +36 -6
- package/src/ui-tailwind/chrome/tw-context-menu.tsx +6 -1
- package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +42 -109
- package/src/ui-tailwind/chrome/tw-inline-find-bar.tsx +26 -6
- package/src/ui-tailwind/chrome/tw-navigation-command-bar.tsx +328 -0
- package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +8 -4
- package/src/ui-tailwind/chrome/tw-runtime-repl-dialog.tsx +129 -1
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +19 -5
- package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +5 -1
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +28 -12
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +30 -3
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +116 -10
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +223 -94
- package/src/ui-tailwind/chrome-overlay/tw-presence-overlay-lane.tsx +157 -0
- package/src/ui-tailwind/chrome-overlay/tw-review-overlay-lane-markers.tsx +259 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +5 -2
- package/src/ui-tailwind/chrome-overlay/tw-substrate-overlay-lanes.tsx +314 -0
- package/src/ui-tailwind/debug/README.md +4 -1
- package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +272 -0
- package/src/ui-tailwind/debug/layer11-word-field-matrix-evidence.ts +160 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +14 -215
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +42 -0
- package/src/ui-tailwind/editor-surface/pm-position-map.ts +38 -2
- package/src/ui-tailwind/editor-surface/pm-schema.ts +14 -4
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +34 -5
- package/src/ui-tailwind/editor-surface/runtime-decoration-plugin.ts +9 -19
- package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -2
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +145 -0
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +16 -11
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +8 -10
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +3 -0
- package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +4 -2
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +60 -20
- package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +16 -11
- package/src/ui-tailwind/review/tw-health-panel.tsx +36 -17
- package/src/ui-tailwind/review/tw-review-rail.tsx +7 -4
- package/src/ui-tailwind/review-workspace/diagnostics-visibility.ts +44 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +11 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +16 -1
- package/src/ui-tailwind/review-workspace/types.ts +26 -12
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +40 -11
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +15 -26
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +35 -18
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +41 -32
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +2 -1
- package/src/ui-tailwind/status/tw-status-bar.tsx +6 -5
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +52 -80
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +12 -48
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +9 -4
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +328 -361
- package/src/ui-tailwind/tw-review-workspace.tsx +152 -286
|
@@ -24,10 +24,21 @@ import type {
|
|
|
24
24
|
} from "./_scope-dependencies.ts";
|
|
25
25
|
|
|
26
26
|
import { AI_EXPLANATION_METADATA_ID } from "./attach-explanation.ts";
|
|
27
|
+
import { deriveScopeCapabilities } from "./capabilities.ts";
|
|
28
|
+
import { deriveScopeContentControlEvidence } from "./content-control-evidence.ts";
|
|
27
29
|
import { AI_ISSUE_METADATA_ID } from "./create-issue.ts";
|
|
28
30
|
import type { EnumeratedScope } from "./enumerate-scopes.ts";
|
|
31
|
+
import {
|
|
32
|
+
deriveScopeGeometryEvidence,
|
|
33
|
+
type ScopeGeometryEvidenceProvider,
|
|
34
|
+
} from "./geometry-evidence.ts";
|
|
35
|
+
import {
|
|
36
|
+
deriveScopeLayoutEvidence,
|
|
37
|
+
type ScopeLayoutEvidenceProvider,
|
|
38
|
+
} from "./layout-evidence.ts";
|
|
29
39
|
import { buildScopePositionMap, type ScopePositionRange } from "./position-map.ts";
|
|
30
40
|
import { rangesOverlap, resolveScopeRange } from "./scope-range.ts";
|
|
41
|
+
import { deriveScopeVisualization } from "./visualization.ts";
|
|
31
42
|
import type {
|
|
32
43
|
AIExplanationSummary,
|
|
33
44
|
AIIssueSummary,
|
|
@@ -86,6 +97,16 @@ export interface EvidenceInputs {
|
|
|
86
97
|
* `runtime.getWorkflowMetadataSnapshot().entries` through here.
|
|
87
98
|
*/
|
|
88
99
|
readonly workflowMetadataEntries?: readonly WorkflowMetadataEntry[];
|
|
100
|
+
/**
|
|
101
|
+
* Layer-05 geometry facet subset. When present, evidence includes the
|
|
102
|
+
* current replacement envelope or an explicit requires-rehydration status.
|
|
103
|
+
*/
|
|
104
|
+
readonly geometry?: ScopeGeometryEvidenceProvider;
|
|
105
|
+
/**
|
|
106
|
+
* Optional lower-layer layout evidence seam. Missing provider or missing
|
|
107
|
+
* rows are surfaced explicitly in `ScopeBundleEvidence.layout`.
|
|
108
|
+
*/
|
|
109
|
+
readonly layout?: ScopeLayoutEvidenceProvider;
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
function normalizeSeverity(raw: unknown): AIIssueSummary["severity"] {
|
|
@@ -98,6 +119,38 @@ function normalizeStatus(raw: unknown): AIIssueSummary["status"] {
|
|
|
98
119
|
return "open";
|
|
99
120
|
}
|
|
100
121
|
|
|
122
|
+
function projectIssueTransition(raw: unknown): AIIssueSummary["lastTransition"] | undefined {
|
|
123
|
+
const value = raw as
|
|
124
|
+
| {
|
|
125
|
+
action?: unknown;
|
|
126
|
+
actorId?: unknown;
|
|
127
|
+
at?: unknown;
|
|
128
|
+
origin?: unknown;
|
|
129
|
+
fromStatus?: unknown;
|
|
130
|
+
toStatus?: unknown;
|
|
131
|
+
}
|
|
132
|
+
| undefined;
|
|
133
|
+
if (!value || typeof value !== "object") return undefined;
|
|
134
|
+
if (value.action !== "resolve" && value.action !== "reopen") return undefined;
|
|
135
|
+
if (typeof value.actorId !== "string") return undefined;
|
|
136
|
+
if (typeof value.at !== "string") return undefined;
|
|
137
|
+
if (typeof value.origin !== "string") return undefined;
|
|
138
|
+
if (value.fromStatus !== "open" && value.fromStatus !== "resolved") {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
if (value.toStatus !== "open" && value.toStatus !== "resolved") {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
action: value.action,
|
|
146
|
+
actorId: value.actorId,
|
|
147
|
+
at: value.at,
|
|
148
|
+
origin: value.origin,
|
|
149
|
+
fromStatus: value.fromStatus,
|
|
150
|
+
toStatus: value.toStatus,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
101
154
|
function projectAIExplanation(
|
|
102
155
|
entry: WorkflowMetadataEntry,
|
|
103
156
|
): AIExplanationSummary | null {
|
|
@@ -127,9 +180,18 @@ function projectAIIssue(
|
|
|
127
180
|
severity?: unknown;
|
|
128
181
|
status?: unknown;
|
|
129
182
|
createdAtUtc?: string;
|
|
183
|
+
statusUpdatedAtUtc?: string;
|
|
184
|
+
resolvedAtUtc?: string;
|
|
185
|
+
resolvedBy?: string;
|
|
186
|
+
reopenedAtUtc?: string;
|
|
187
|
+
reopenedBy?: string;
|
|
188
|
+
lifecycle?: unknown[];
|
|
130
189
|
}
|
|
131
190
|
| undefined;
|
|
132
191
|
if (!value || typeof value.summary !== "string") return null;
|
|
192
|
+
const lastTransition = Array.isArray(value.lifecycle)
|
|
193
|
+
? projectIssueTransition(value.lifecycle[value.lifecycle.length - 1])
|
|
194
|
+
: undefined;
|
|
133
195
|
return {
|
|
134
196
|
issueId:
|
|
135
197
|
typeof value.issueId === "string" && value.issueId.length > 0
|
|
@@ -141,6 +203,22 @@ function projectAIIssue(
|
|
|
141
203
|
...(typeof value.createdAtUtc === "string"
|
|
142
204
|
? { createdAtUtc: value.createdAtUtc }
|
|
143
205
|
: {}),
|
|
206
|
+
...(typeof value.statusUpdatedAtUtc === "string"
|
|
207
|
+
? { statusUpdatedAtUtc: value.statusUpdatedAtUtc }
|
|
208
|
+
: {}),
|
|
209
|
+
...(typeof value.resolvedAtUtc === "string"
|
|
210
|
+
? { resolvedAtUtc: value.resolvedAtUtc }
|
|
211
|
+
: {}),
|
|
212
|
+
...(typeof value.resolvedBy === "string"
|
|
213
|
+
? { resolvedBy: value.resolvedBy }
|
|
214
|
+
: {}),
|
|
215
|
+
...(typeof value.reopenedAtUtc === "string"
|
|
216
|
+
? { reopenedAtUtc: value.reopenedAtUtc }
|
|
217
|
+
: {}),
|
|
218
|
+
...(typeof value.reopenedBy === "string"
|
|
219
|
+
? { reopenedBy: value.reopenedBy }
|
|
220
|
+
: {}),
|
|
221
|
+
...(lastTransition ? { lastTransition } : {}),
|
|
144
222
|
};
|
|
145
223
|
}
|
|
146
224
|
|
|
@@ -221,11 +299,24 @@ export function composeEvidence(inputs: EvidenceInputs): ScopeBundleEvidence {
|
|
|
221
299
|
aiExplanations.sort((a, b) => a.explanationId.localeCompare(b.explanationId));
|
|
222
300
|
aiIssues.sort((a, b) => a.issueId.localeCompare(b.issueId));
|
|
223
301
|
|
|
302
|
+
const layout = deriveScopeLayoutEvidence(scope.handle.scopeId, inputs.layout);
|
|
303
|
+
const geometry = deriveScopeGeometryEvidence(scope.handle.scopeId, inputs.geometry);
|
|
304
|
+
const contentControls = deriveScopeContentControlEvidence(document, selfRange);
|
|
305
|
+
|
|
224
306
|
return {
|
|
225
307
|
formattingSummary: formattingSummaryOf(scope),
|
|
226
308
|
reviewItemIds,
|
|
227
309
|
overlappingWorkflowScopeIds,
|
|
228
310
|
compatibilityFlags,
|
|
311
|
+
layout,
|
|
312
|
+
geometry,
|
|
313
|
+
visualization: deriveScopeVisualization(scope),
|
|
314
|
+
contentControls,
|
|
315
|
+
capabilities: deriveScopeCapabilities(scope, {
|
|
316
|
+
layout,
|
|
317
|
+
geometry,
|
|
318
|
+
contentControls,
|
|
319
|
+
}),
|
|
229
320
|
...(inputs.workflowMetadataEntries
|
|
230
321
|
? { aiExplanations, aiIssues }
|
|
231
322
|
: {}),
|
|
@@ -156,6 +156,7 @@ export function applyScopeFormatting(
|
|
|
156
156
|
if (!resolvedScope || !resolvedEnumerated) {
|
|
157
157
|
const validation: ValidationResult = {
|
|
158
158
|
safe: false,
|
|
159
|
+
posture: "hard-refusal",
|
|
159
160
|
blockedReasons: Object.freeze([
|
|
160
161
|
`scope-not-resolvable:${proposed.targetHandle.scopeId}`,
|
|
161
162
|
]),
|
|
@@ -211,6 +212,7 @@ export function applyScopeFormatting(
|
|
|
211
212
|
: `compile-refused:${resolvedScope.kind}:formatting-not-implemented`;
|
|
212
213
|
const refused: ValidationResult = {
|
|
213
214
|
safe: false,
|
|
215
|
+
posture: "hard-refusal",
|
|
214
216
|
blockedReasons: Object.freeze([blocker]),
|
|
215
217
|
warnings: verdict.warnings,
|
|
216
218
|
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope geometry evidence projection.
|
|
3
|
+
*
|
|
4
|
+
* Layer 08 consumes the Layer 05 replacement-envelope seam when it is wired,
|
|
5
|
+
* but it does not compute geometry itself. Cold or missing geometry remains
|
|
6
|
+
* explicit evidence, not a synthesized rectangle.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
ScopeGeometryEvidence,
|
|
11
|
+
ScopeGeometryEvidencePrecision,
|
|
12
|
+
ScopeGeometryEvidenceRect,
|
|
13
|
+
ScopeLayoutContinuationEvidence,
|
|
14
|
+
} from "./semantic-scope-types.ts";
|
|
15
|
+
|
|
16
|
+
type GeometrySpace = ScopeGeometryEvidenceRect["space"];
|
|
17
|
+
|
|
18
|
+
interface EnvelopeRectLike {
|
|
19
|
+
readonly leftPx: number;
|
|
20
|
+
readonly topPx: number;
|
|
21
|
+
readonly widthPx: number;
|
|
22
|
+
readonly heightPx: number;
|
|
23
|
+
readonly space: GeometrySpace;
|
|
24
|
+
readonly precision?: ScopeGeometryEvidencePrecision;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface EnvelopeLike {
|
|
28
|
+
readonly scopeRects: readonly EnvelopeRectLike[];
|
|
29
|
+
readonly pageIds?: readonly string[];
|
|
30
|
+
readonly continuation?: ScopeLayoutContinuationEvidence;
|
|
31
|
+
readonly attachPoint: {
|
|
32
|
+
readonly xPx: number;
|
|
33
|
+
readonly yPx: number;
|
|
34
|
+
readonly space: GeometrySpace;
|
|
35
|
+
};
|
|
36
|
+
readonly confidence: "exact" | "medium" | "detached";
|
|
37
|
+
readonly linesCrossed: number;
|
|
38
|
+
readonly rehydrationStatus?: "realized" | "requires-rehydration" | "unavailable";
|
|
39
|
+
readonly precision?: ScopeGeometryEvidencePrecision;
|
|
40
|
+
readonly sourceIdentity?: {
|
|
41
|
+
readonly storyKey?: string;
|
|
42
|
+
readonly blockPath?: string;
|
|
43
|
+
readonly tableKey?: string;
|
|
44
|
+
readonly rowKey?: string;
|
|
45
|
+
readonly cellKey?: string;
|
|
46
|
+
readonly scopeKey?: string;
|
|
47
|
+
readonly scopeId?: string;
|
|
48
|
+
readonly objectKey?: string;
|
|
49
|
+
readonly inlinePath?: string;
|
|
50
|
+
readonly objectKind?: string;
|
|
51
|
+
readonly editPosture?: string;
|
|
52
|
+
readonly joinKind?: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ScopeGeometryEvidenceProvider {
|
|
57
|
+
getReplacementEnvelope(scopeId: string): EnvelopeLike | null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function mapRect(rect: EnvelopeRectLike): ScopeGeometryEvidenceRect {
|
|
61
|
+
return {
|
|
62
|
+
x: rect.leftPx,
|
|
63
|
+
y: rect.topPx,
|
|
64
|
+
width: rect.widthPx,
|
|
65
|
+
height: rect.heightPx,
|
|
66
|
+
space: rect.space,
|
|
67
|
+
...(rect.precision ? { precision: rect.precision } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function deriveScopeGeometryEvidence(
|
|
72
|
+
scopeId: string,
|
|
73
|
+
provider?: ScopeGeometryEvidenceProvider,
|
|
74
|
+
): ScopeGeometryEvidence {
|
|
75
|
+
if (!provider) {
|
|
76
|
+
return {
|
|
77
|
+
status: "unavailable",
|
|
78
|
+
requiresRehydration: false,
|
|
79
|
+
reason: "geometry-facet-unavailable",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const envelope = provider.getReplacementEnvelope(scopeId);
|
|
84
|
+
if (!envelope) {
|
|
85
|
+
return {
|
|
86
|
+
status: "requires-rehydration",
|
|
87
|
+
requiresRehydration: true,
|
|
88
|
+
reason: "replacement-envelope-unavailable",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (envelope.rehydrationStatus === "unavailable") {
|
|
93
|
+
return {
|
|
94
|
+
status: "unavailable",
|
|
95
|
+
requiresRehydration: false,
|
|
96
|
+
reason: "replacement-envelope-unavailable",
|
|
97
|
+
...(envelope.pageIds ? { pageIds: Object.freeze([...envelope.pageIds]) } : {}),
|
|
98
|
+
...(envelope.continuation
|
|
99
|
+
? { continuationState: { ...envelope.continuation } }
|
|
100
|
+
: {}),
|
|
101
|
+
...(envelope.sourceIdentity
|
|
102
|
+
? { sourceIdentity: { ...envelope.sourceIdentity } }
|
|
103
|
+
: {}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const requiresRehydration =
|
|
108
|
+
envelope.rehydrationStatus === "requires-rehydration";
|
|
109
|
+
return {
|
|
110
|
+
status: requiresRehydration ? "requires-rehydration" : "available",
|
|
111
|
+
requiresRehydration,
|
|
112
|
+
...(requiresRehydration ? { reason: "replacement-envelope-requires-rehydration" } : {}),
|
|
113
|
+
...(envelope.pageIds ? { pageIds: Object.freeze([...envelope.pageIds]) } : {}),
|
|
114
|
+
confidence: envelope.confidence,
|
|
115
|
+
...(envelope.precision ? { precision: envelope.precision } : {}),
|
|
116
|
+
rects: Object.freeze(envelope.scopeRects.map(mapRect)),
|
|
117
|
+
attachPoint: {
|
|
118
|
+
x: envelope.attachPoint.xPx,
|
|
119
|
+
y: envelope.attachPoint.yPx,
|
|
120
|
+
space: envelope.attachPoint.space,
|
|
121
|
+
},
|
|
122
|
+
linesCrossed: envelope.linesCrossed,
|
|
123
|
+
...(envelope.continuation
|
|
124
|
+
? { continuationState: { ...envelope.continuation } }
|
|
125
|
+
: {}),
|
|
126
|
+
...(envelope.sourceIdentity
|
|
127
|
+
? { sourceIdentity: { ...envelope.sourceIdentity } }
|
|
128
|
+
: {}),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -26,8 +26,24 @@ export type {
|
|
|
26
26
|
ReplacementOperationKind,
|
|
27
27
|
ReplacementPreservePolicy,
|
|
28
28
|
ReplacementScope,
|
|
29
|
+
ScopeReplacementOperationKind,
|
|
29
30
|
ScopeActionOperationKind,
|
|
30
31
|
ScopeActionProposal,
|
|
32
|
+
ScopeCapabilities,
|
|
33
|
+
ScopeCapabilityStatus,
|
|
34
|
+
ScopeCapabilityVerdict,
|
|
35
|
+
ScopeContentControlEvidence,
|
|
36
|
+
ScopeContentControlEvidenceEntry,
|
|
37
|
+
ScopeContentControlEvidenceStatus,
|
|
38
|
+
ScopeEvidenceAvailability,
|
|
39
|
+
ScopeGeometryEvidence,
|
|
40
|
+
ScopeGeometryEvidencePrecision,
|
|
41
|
+
ScopeGeometryEvidenceRect,
|
|
42
|
+
ScopeGeometryEvidenceStatus,
|
|
43
|
+
ScopeLayoutContinuationEvidence,
|
|
44
|
+
ScopeLayoutEvidence,
|
|
45
|
+
ScopeVisualizationClass,
|
|
46
|
+
ScopeVisualizationHint,
|
|
31
47
|
RuntimeOperationPlan,
|
|
32
48
|
RuntimeOperationStep,
|
|
33
49
|
RuntimeOperationStepKind,
|
|
@@ -35,6 +51,7 @@ export type {
|
|
|
35
51
|
ScopeFormattingAction,
|
|
36
52
|
ScopeFormattingClearTarget,
|
|
37
53
|
ScopeFormattingScope,
|
|
54
|
+
ScopeActionPosture,
|
|
38
55
|
ScopeBundle,
|
|
39
56
|
ScopeBundleEvidence,
|
|
40
57
|
ScopeBundleNeighborhood,
|
|
@@ -56,6 +73,33 @@ export type {
|
|
|
56
73
|
ValidationIssue,
|
|
57
74
|
ValidationResult,
|
|
58
75
|
} from "./semantic-scope-types.ts";
|
|
76
|
+
export { deriveScopeCapabilities } from "./capabilities.ts";
|
|
77
|
+
export type { ScopeCapabilityContext } from "./capabilities.ts";
|
|
78
|
+
export {
|
|
79
|
+
deriveScopeContentControlEvidence,
|
|
80
|
+
findContentControlsIntersectingRange,
|
|
81
|
+
} from "./content-control-evidence.ts";
|
|
82
|
+
export {
|
|
83
|
+
deriveScopeGeometryEvidence,
|
|
84
|
+
type ScopeGeometryEvidenceProvider,
|
|
85
|
+
} from "./geometry-evidence.ts";
|
|
86
|
+
export {
|
|
87
|
+
deriveScopeLayoutEvidence,
|
|
88
|
+
collectTopLevelTableBlockIdsFromRenderSnapshot,
|
|
89
|
+
createRuntimeTableFrameLayoutEvidenceProvider,
|
|
90
|
+
type RuntimeTableFrameLayoutEvidenceOptions,
|
|
91
|
+
type ScopeLayoutEvidenceEntry,
|
|
92
|
+
type ScopeLayoutEvidenceProvider,
|
|
93
|
+
type ScopeRuntimeLayoutEvidenceSource,
|
|
94
|
+
type ScopeRuntimeLayoutFragment,
|
|
95
|
+
type ScopeRuntimeRenderSnapshotLike,
|
|
96
|
+
} from "./layout-evidence.ts";
|
|
97
|
+
export {
|
|
98
|
+
MULTI_PARAGRAPH_REPLACEMENT_REFUSAL,
|
|
99
|
+
multiParagraphReplacementBlockers,
|
|
100
|
+
} from "./multi-paragraph-refusal.ts";
|
|
101
|
+
export type { MultiParagraphReplacementShape } from "./multi-paragraph-refusal.ts";
|
|
102
|
+
export { deriveScopeVisualization } from "./visualization.ts";
|
|
59
103
|
|
|
60
104
|
export {
|
|
61
105
|
buildParagraphIndexMap,
|
|
@@ -153,6 +197,15 @@ export {
|
|
|
153
197
|
type IssueSeverity,
|
|
154
198
|
type IssueStatus,
|
|
155
199
|
} from "./create-issue.ts";
|
|
200
|
+
export {
|
|
201
|
+
resolveIssueLifecycleTarget,
|
|
202
|
+
transitionScopeIssueLifecycle,
|
|
203
|
+
type IssueLifecycleAction,
|
|
204
|
+
type IssueLifecycleRuntime,
|
|
205
|
+
type IssueLifecycleTarget,
|
|
206
|
+
type TransitionScopeIssueLifecycleInputs,
|
|
207
|
+
type TransitionScopeIssueLifecycleResult,
|
|
208
|
+
} from "./issue-lifecycle.ts";
|
|
156
209
|
export {
|
|
157
210
|
createScopeCompilerService,
|
|
158
211
|
type ApplyFormattingRequest,
|
|
@@ -161,5 +214,6 @@ export {
|
|
|
161
214
|
type CompileScopeByIdResult,
|
|
162
215
|
type CompilerServiceRuntime,
|
|
163
216
|
type CreateIssueRequest,
|
|
217
|
+
type TransitionIssueLifecycleRequest,
|
|
164
218
|
type ScopeCompilerService,
|
|
165
219
|
} from "./compiler-service.ts";
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 08 issue lifecycle binding.
|
|
3
|
+
*
|
|
4
|
+
* Layer 06 owns durable `ai.issue` metadata status transitions. This module
|
|
5
|
+
* adds the scope-compiler binding that future L09 `resolveIssue` /
|
|
6
|
+
* `reopenIssue` APIs need: find the issue's scope, require that scope to still
|
|
7
|
+
* compile, preserve the existing metadata entry id, and emit scope-shaped audit
|
|
8
|
+
* evidence for the lifecycle transition.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { TelemetryBus } from "../debug/telemetry-bus.ts";
|
|
12
|
+
import {
|
|
13
|
+
projectAIIssueLifecycleReadback,
|
|
14
|
+
transitionAIIssueLifecycle,
|
|
15
|
+
type AIIssueLifecycleAction,
|
|
16
|
+
type AIIssueLifecycleAuditEntry,
|
|
17
|
+
type AIIssueStatus,
|
|
18
|
+
} from "../workflow/ai-issue-lifecycle.ts";
|
|
19
|
+
import type {
|
|
20
|
+
WorkflowEventOrigin,
|
|
21
|
+
WorkflowMetadataEntry,
|
|
22
|
+
WorkflowMetadataSnapshot,
|
|
23
|
+
} from "./_scope-dependencies.ts";
|
|
24
|
+
import type { CanonicalDocumentEnvelope } from "../../core/state/editor-state.ts";
|
|
25
|
+
import type {
|
|
26
|
+
ReplacementScope,
|
|
27
|
+
ScopeActionAudit,
|
|
28
|
+
SemanticScope,
|
|
29
|
+
ValidationResult,
|
|
30
|
+
} from "./semantic-scope-types.ts";
|
|
31
|
+
|
|
32
|
+
export type IssueLifecycleAction = AIIssueLifecycleAction;
|
|
33
|
+
|
|
34
|
+
export interface IssueLifecycleRuntime {
|
|
35
|
+
getCanonicalDocument(): CanonicalDocumentEnvelope;
|
|
36
|
+
getWorkflowMetadataSnapshot(): WorkflowMetadataSnapshot;
|
|
37
|
+
setWorkflowMetadataEntries(
|
|
38
|
+
entries: readonly WorkflowMetadataEntry[],
|
|
39
|
+
origin?: WorkflowEventOrigin,
|
|
40
|
+
): void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface IssueLifecycleTarget {
|
|
44
|
+
readonly issueId: string;
|
|
45
|
+
readonly entryId: string;
|
|
46
|
+
readonly scopeId: string;
|
|
47
|
+
readonly status: AIIssueStatus;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface TransitionScopeIssueLifecycleInputs {
|
|
51
|
+
readonly runtime: IssueLifecycleRuntime;
|
|
52
|
+
readonly documentBefore: CanonicalDocumentEnvelope;
|
|
53
|
+
readonly targetScopeSnapshot: SemanticScope;
|
|
54
|
+
readonly issueId: string;
|
|
55
|
+
readonly action: IssueLifecycleAction;
|
|
56
|
+
readonly actorId: string;
|
|
57
|
+
readonly origin: "ui" | "agent" | "host";
|
|
58
|
+
readonly emittedAtUtc: string;
|
|
59
|
+
readonly bus?: TelemetryBus;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type TransitionScopeIssueLifecycleResult =
|
|
63
|
+
| {
|
|
64
|
+
readonly transitioned: true;
|
|
65
|
+
readonly issueId: string;
|
|
66
|
+
readonly entryId: string;
|
|
67
|
+
readonly scopeId: string;
|
|
68
|
+
readonly fromStatus: AIIssueStatus;
|
|
69
|
+
readonly toStatus: AIIssueStatus;
|
|
70
|
+
readonly lifecycleAudit: AIIssueLifecycleAuditEntry;
|
|
71
|
+
readonly targetScopeSnapshot: SemanticScope;
|
|
72
|
+
readonly audit: ScopeActionAudit;
|
|
73
|
+
}
|
|
74
|
+
| {
|
|
75
|
+
readonly transitioned: false;
|
|
76
|
+
readonly issueId: string;
|
|
77
|
+
readonly reason: string;
|
|
78
|
+
readonly blockers: readonly string[];
|
|
79
|
+
readonly scopeId?: string;
|
|
80
|
+
readonly targetScopeSnapshot?: SemanticScope;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
function documentHash(doc: CanonicalDocumentEnvelope): string {
|
|
84
|
+
let textLength = 0;
|
|
85
|
+
for (const block of doc.content.children) {
|
|
86
|
+
if (block.type !== "paragraph") continue;
|
|
87
|
+
for (const child of block.children) {
|
|
88
|
+
if (child.type === "text") textLength += child.text.length;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return `blocks:${doc.content.children.length}|text:${textLength}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function freezeBlocker(reason: string): readonly string[] {
|
|
95
|
+
return Object.freeze([reason]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function resolveIssueLifecycleTarget(
|
|
99
|
+
snapshot: WorkflowMetadataSnapshot,
|
|
100
|
+
issueIdOrEntryId: string,
|
|
101
|
+
): IssueLifecycleTarget | null {
|
|
102
|
+
const readback = projectAIIssueLifecycleReadback(snapshot.entries).find(
|
|
103
|
+
(issue) =>
|
|
104
|
+
issue.issueId === issueIdOrEntryId || issue.entryId === issueIdOrEntryId,
|
|
105
|
+
);
|
|
106
|
+
if (!readback || !readback.scopeId) return null;
|
|
107
|
+
return {
|
|
108
|
+
issueId: readback.issueId,
|
|
109
|
+
entryId: readback.entryId,
|
|
110
|
+
scopeId: readback.scopeId,
|
|
111
|
+
status: readback.status,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function buildLifecycleAudit(
|
|
116
|
+
inputs: TransitionScopeIssueLifecycleInputs,
|
|
117
|
+
transition: {
|
|
118
|
+
readonly issueId: string;
|
|
119
|
+
readonly entryId: string;
|
|
120
|
+
readonly fromStatus: AIIssueStatus;
|
|
121
|
+
readonly toStatus: AIIssueStatus;
|
|
122
|
+
readonly audit: AIIssueLifecycleAuditEntry;
|
|
123
|
+
},
|
|
124
|
+
): ScopeActionAudit {
|
|
125
|
+
const snapshot = inputs.targetScopeSnapshot;
|
|
126
|
+
const proposed: ReplacementScope = {
|
|
127
|
+
targetHandle: snapshot.handle,
|
|
128
|
+
operation: "annotate",
|
|
129
|
+
proposedContent: {
|
|
130
|
+
kind: "structured",
|
|
131
|
+
structured: {
|
|
132
|
+
metadataKind: "issue-lifecycle",
|
|
133
|
+
issueId: transition.issueId,
|
|
134
|
+
entryId: transition.entryId,
|
|
135
|
+
action: inputs.action,
|
|
136
|
+
fromStatus: transition.fromStatus,
|
|
137
|
+
toStatus: transition.toStatus,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
proposedAtUtc: inputs.emittedAtUtc,
|
|
141
|
+
};
|
|
142
|
+
const validation: ValidationResult = {
|
|
143
|
+
safe: true,
|
|
144
|
+
posture: "supported",
|
|
145
|
+
blockedReasons: Object.freeze([]),
|
|
146
|
+
warnings: Object.freeze([]),
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
actionId:
|
|
150
|
+
inputs.action === "resolve" ? "ai.resolveIssue" : "ai.reopenIssue",
|
|
151
|
+
actorId: inputs.actorId,
|
|
152
|
+
origin: inputs.origin,
|
|
153
|
+
documentHashBefore: documentHash(inputs.documentBefore),
|
|
154
|
+
documentHashAfter: documentHash(inputs.runtime.getCanonicalDocument()),
|
|
155
|
+
targetScopeSnapshot: snapshot,
|
|
156
|
+
proposed,
|
|
157
|
+
compiledOperations: Object.freeze([
|
|
158
|
+
{
|
|
159
|
+
kind:
|
|
160
|
+
inputs.action === "resolve"
|
|
161
|
+
? "metadata-issue-resolve"
|
|
162
|
+
: "metadata-issue-reopen",
|
|
163
|
+
summary: `${inputs.action} issue ${transition.issueId} on scope ${snapshot.handle.scopeId}`,
|
|
164
|
+
},
|
|
165
|
+
]),
|
|
166
|
+
validation,
|
|
167
|
+
emittedAtUtc: inputs.emittedAtUtc,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function transitionScopeIssueLifecycle(
|
|
172
|
+
inputs: TransitionScopeIssueLifecycleInputs,
|
|
173
|
+
): TransitionScopeIssueLifecycleResult {
|
|
174
|
+
const target = resolveIssueLifecycleTarget(
|
|
175
|
+
inputs.runtime.getWorkflowMetadataSnapshot(),
|
|
176
|
+
inputs.issueId,
|
|
177
|
+
);
|
|
178
|
+
if (!target) {
|
|
179
|
+
const reason = `issue-not-found:${inputs.issueId}`;
|
|
180
|
+
return {
|
|
181
|
+
transitioned: false,
|
|
182
|
+
issueId: inputs.issueId,
|
|
183
|
+
reason,
|
|
184
|
+
blockers: freezeBlocker(reason),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const transition = transitionAIIssueLifecycle(inputs.runtime, {
|
|
189
|
+
issueId: target.issueId,
|
|
190
|
+
action: inputs.action,
|
|
191
|
+
actorId: inputs.actorId,
|
|
192
|
+
at: inputs.emittedAtUtc,
|
|
193
|
+
origin: { source: inputs.origin, at: inputs.emittedAtUtc },
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
if (!transition.transitioned) {
|
|
197
|
+
const reason = `${transition.reason}:${transition.issueId}`;
|
|
198
|
+
return {
|
|
199
|
+
transitioned: false,
|
|
200
|
+
issueId: transition.issueId,
|
|
201
|
+
reason,
|
|
202
|
+
blockers: freezeBlocker(reason),
|
|
203
|
+
scopeId: target.scopeId,
|
|
204
|
+
targetScopeSnapshot: inputs.targetScopeSnapshot,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const audit = buildLifecycleAudit(inputs, transition);
|
|
209
|
+
inputs.bus?.emitLazy("scope", () => ({
|
|
210
|
+
type: "scope.action_audit",
|
|
211
|
+
payload: audit,
|
|
212
|
+
}));
|
|
213
|
+
return {
|
|
214
|
+
transitioned: true,
|
|
215
|
+
issueId: transition.issueId,
|
|
216
|
+
entryId: transition.entryId,
|
|
217
|
+
scopeId: target.scopeId,
|
|
218
|
+
fromStatus: transition.fromStatus,
|
|
219
|
+
toStatus: transition.toStatus,
|
|
220
|
+
lifecycleAudit: transition.audit,
|
|
221
|
+
targetScopeSnapshot: inputs.targetScopeSnapshot,
|
|
222
|
+
audit,
|
|
223
|
+
};
|
|
224
|
+
}
|