@beyondwork/docx-react-component 1.0.57 → 1.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +2 -1
- package/src/api/awareness-identity-types.ts +4 -2
- package/src/api/comment-negotiation-types.ts +4 -1
- package/src/api/external-custody-types.ts +16 -0
- package/src/api/internal/build-ref-projections.ts +108 -0
- package/src/api/package-version.ts +1 -1
- package/src/api/participants-types.ts +11 -1
- package/src/api/public-types.ts +1149 -8
- package/src/api/scope-metadata-resolver-types.ts +6 -0
- package/src/compare/diff-engine.ts +3 -0
- package/src/core/commands/formatting-commands.ts +1 -0
- package/src/core/commands/index.ts +225 -16
- package/src/core/commands/legacy-form-field-commands.ts +181 -0
- package/src/core/commands/table-structure-commands.ts +149 -31
- package/src/core/selection/mapping.ts +20 -0
- package/src/core/state/editor-state.ts +2 -1
- package/src/index.ts +28 -0
- package/src/io/docx-session.ts +22 -3
- package/src/io/export/export-session.ts +11 -7
- package/src/io/export/ooxml-namespaces.ts +47 -0
- package/src/io/export/reattach-preserved-parts.ts +4 -16
- package/src/io/export/serialize-comments.ts +3 -131
- package/src/io/export/serialize-ffdata.ts +89 -0
- package/src/io/export/serialize-headers-footers.ts +5 -0
- package/src/io/export/serialize-main-document.ts +224 -34
- package/src/io/export/serialize-numbering.ts +22 -2
- package/src/io/export/serialize-revisions.ts +99 -0
- package/src/io/export/serialize-tables.ts +9 -0
- package/src/io/export/split-review-boundaries.ts +1 -0
- package/src/io/export/table-properties-xml.ts +14 -0
- package/src/io/load-scheduler.ts +70 -28
- package/src/io/normalize/normalize-text.ts +13 -0
- package/src/io/ooxml/_mini-xml.ts +198 -0
- package/src/io/ooxml/canonicalize-payload.ts +1 -4
- package/src/io/ooxml/chart/chart-style-table.ts +4 -3
- package/src/io/ooxml/chart/parse-chart-space.ts +2 -4
- package/src/io/ooxml/chart/parse-series.ts +2 -1
- package/src/io/ooxml/chart/resolve-color.ts +2 -2
- package/src/io/ooxml/chart/types.ts +6 -434
- package/src/io/ooxml/comment-presentation-payload.ts +6 -5
- package/src/io/ooxml/highlight-colors.ts +8 -5
- package/src/io/ooxml/parse-anchor.ts +68 -53
- package/src/io/ooxml/parse-comments.ts +14 -142
- package/src/io/ooxml/parse-complex-content.ts +3 -106
- package/src/io/ooxml/parse-drawing.ts +100 -195
- package/src/io/ooxml/parse-ffdata.ts +93 -0
- package/src/io/ooxml/parse-fields.ts +7 -146
- package/src/io/ooxml/parse-fill.ts +88 -8
- package/src/io/ooxml/parse-font-table.ts +5 -105
- package/src/io/ooxml/parse-footnotes.ts +28 -152
- package/src/io/ooxml/parse-headers-footers.ts +106 -212
- package/src/io/ooxml/parse-inline-media.ts +3 -200
- package/src/io/ooxml/parse-main-document.ts +180 -217
- package/src/io/ooxml/parse-numbering.ts +154 -335
- package/src/io/ooxml/parse-object.ts +147 -0
- package/src/io/ooxml/parse-ole-relationship.ts +82 -0
- package/src/io/ooxml/parse-paragraph-formatting.ts +7 -10
- package/src/io/ooxml/parse-picture-sdt.ts +85 -0
- package/src/io/ooxml/parse-picture.ts +120 -39
- package/src/io/ooxml/parse-revisions.ts +285 -51
- package/src/io/ooxml/parse-settings.ts +6 -99
- package/src/io/ooxml/parse-shapes.ts +25 -140
- package/src/io/ooxml/parse-styles.ts +3 -218
- package/src/io/ooxml/parse-tables.ts +76 -256
- package/src/io/ooxml/parse-theme.ts +1 -4
- package/src/io/ooxml/property-grab-bag.ts +5 -47
- package/src/io/ooxml/xml-element-serialize.ts +32 -0
- package/src/io/ooxml/xml-parser.ts +183 -0
- package/src/legal/bookmarks.ts +1 -1
- package/src/legal/cross-references.ts +1 -1
- package/src/legal/defined-terms.ts +1 -1
- package/src/legal/{_document-root.ts → document-root.ts} +8 -0
- package/src/legal/signature-blocks.ts +1 -1
- package/src/model/canonical-document.ts +165 -6
- package/src/model/chart-types.ts +439 -0
- package/src/model/snapshot.ts +3 -1
- package/src/review/store/comment-remapping.ts +24 -11
- package/src/review/store/revision-actions.ts +482 -2
- package/src/review/store/revision-store.ts +15 -0
- package/src/review/store/revision-types.ts +76 -0
- package/src/runtime/collab/remote-cursor-awareness.ts +24 -0
- package/src/runtime/collab/runtime-collab-sync.ts +33 -0
- package/src/runtime/diagnostics/build-diagnostic.ts +151 -0
- package/src/runtime/diagnostics/code-metadata-table.ts +221 -0
- package/src/runtime/document-runtime.ts +544 -35
- package/src/runtime/document-search.ts +176 -0
- package/src/runtime/edit-ops/index.ts +18 -2
- package/src/runtime/footnote-resolver.ts +130 -0
- package/src/runtime/layout/layout-engine-instance.ts +31 -4
- package/src/runtime/layout/layout-engine-version.ts +37 -1
- package/src/runtime/layout/page-graph.ts +14 -1
- package/src/runtime/layout/resolved-formatting-state.ts +21 -0
- package/src/runtime/numbering-prefix.ts +17 -0
- package/src/runtime/query-scopes.ts +183 -0
- package/src/runtime/resolved-numbering-geometry.ts +37 -6
- package/src/runtime/revision-runtime.ts +27 -1
- package/src/runtime/scope-resolver.ts +60 -0
- package/src/runtime/selection/post-edit-validator.ts +60 -6
- package/src/runtime/structure-ops/index.ts +20 -4
- package/src/runtime/surface-projection.ts +293 -18
- package/src/runtime/table-schema.ts +6 -0
- package/src/runtime/theme-color-resolver.ts +2 -2
- package/src/runtime/units.ts +9 -0
- package/src/runtime/workflow-rail-segments.ts +4 -0
- package/src/ui/WordReviewEditor.tsx +258 -44
- package/src/ui/editor-runtime-boundary.ts +13 -0
- package/src/ui/editor-shell-view.tsx +4 -1
- package/src/ui/headless/chrome-registry.ts +53 -0
- package/src/ui/headless/selection-tool-resolver.ts +11 -1
- package/src/ui-tailwind/chrome/chrome-preset-model.ts +13 -0
- package/src/ui-tailwind/chrome/tw-command-palette-mount.tsx +96 -0
- package/src/ui-tailwind/chrome/tw-context-menu.tsx +2 -1
- package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +5 -4
- package/src/ui-tailwind/chrome/tw-mode-dock.tsx +6 -2
- package/src/ui-tailwind/chrome/use-container-breakpoint.ts +111 -0
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +23 -9
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +158 -0
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +6 -7
- package/src/ui-tailwind/editor-surface/pm-schema.ts +105 -17
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +13 -0
- package/src/ui-tailwind/editor-surface/shape-renderer.ts +76 -14
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +18 -1
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +2 -0
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +18 -2
- package/src/ui-tailwind/index.ts +9 -0
- package/src/ui-tailwind/page-chrome-model.ts +77 -5
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +56 -1
- package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +2 -0
- package/src/ui-tailwind/review/tw-comment-sidebar.tsx +116 -113
- package/src/ui-tailwind/review/tw-review-rail-footer.tsx +2 -2
- package/src/ui-tailwind/theme/tokens.ts +14 -0
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +5 -0
- package/src/ui-tailwind/tw-review-workspace.tsx +52 -87
- package/src/validation/diagnostics.ts +1 -0
|
@@ -261,6 +261,22 @@ export interface RuntimeCollabSyncHandle {
|
|
|
261
261
|
* enforces write permissions per §7 of the lane plan.
|
|
262
262
|
*/
|
|
263
263
|
getWorkflowShared(): WorkflowSharedHandle;
|
|
264
|
+
/**
|
|
265
|
+
* R3 — AbortSignal that fires whenever a remote command batch is applied
|
|
266
|
+
* locally. Long-running idle tasks (e.g. Phase 2.5 prerender cache
|
|
267
|
+
* warmups, Phase 2.2 ranged-snapshot prep) should pass this into
|
|
268
|
+
* `loadScheduler.scheduleIdle(task, { signal })` so remote arrivals
|
|
269
|
+
* cancel stale prep before the document moves under it. The signal is
|
|
270
|
+
* recycled after each drain — callers must call this getter on every
|
|
271
|
+
* `scheduleIdle` call rather than caching the result. On `destroy()`
|
|
272
|
+
* the current signal also aborts so consumers detect shutdown.
|
|
273
|
+
*
|
|
274
|
+
* Stability: advanced-supported (v2.0.0). See
|
|
275
|
+
* `docs/reference/public-api.md` §createRuntimeCollabSync for the
|
|
276
|
+
* consumer contract and `docs/wiki/collaboration.md` §"Remote-activity
|
|
277
|
+
* abort signal (R3)" for the end-to-end narrative.
|
|
278
|
+
*/
|
|
279
|
+
getRemoteActivitySignal(): AbortSignal;
|
|
264
280
|
}
|
|
265
281
|
|
|
266
282
|
export function createRuntimeCommandAppliedBridge(): RuntimeCommandAppliedBridge {
|
|
@@ -300,8 +316,19 @@ export function createRuntimeCollabSync(
|
|
|
300
316
|
let rafHandle: number | null = null;
|
|
301
317
|
let timeoutHandle: ReturnType<typeof setTimeout> | null = null;
|
|
302
318
|
|
|
319
|
+
// R3 — remote-activity abort controller. Recycled on every scheduled
|
|
320
|
+
// drain so consumers that registered an idle task with the prior
|
|
321
|
+
// signal get cancelled before the upcoming commit lands. First signal
|
|
322
|
+
// is created eagerly so `getRemoteActivitySignal()` is always safe to
|
|
323
|
+
// call before any remote traffic.
|
|
324
|
+
let remoteActivityController = new AbortController();
|
|
325
|
+
|
|
303
326
|
function scheduleDrain(): void {
|
|
304
327
|
if (rafHandle !== null || timeoutHandle !== null) return;
|
|
328
|
+
// Abort the prior signal BEFORE firing the host hook so any consumer
|
|
329
|
+
// work that branches on the hook sees the fresh signal.
|
|
330
|
+
remoteActivityController.abort();
|
|
331
|
+
remoteActivityController = new AbortController();
|
|
305
332
|
options.onRemoteReplayScheduled?.();
|
|
306
333
|
if (typeof requestAnimationFrame === "function") {
|
|
307
334
|
rafHandle = requestAnimationFrame(() => {
|
|
@@ -572,6 +599,9 @@ export function createRuntimeCollabSync(
|
|
|
572
599
|
workflowShared.destroy();
|
|
573
600
|
runtime.setSharedWorkflowState(null);
|
|
574
601
|
listeners.clear();
|
|
602
|
+
// R3 — abort the current remote-activity signal so any lingering
|
|
603
|
+
// idle consumers detect the shutdown.
|
|
604
|
+
remoteActivityController.abort();
|
|
575
605
|
},
|
|
576
606
|
subscribe(listener) {
|
|
577
607
|
listeners.add(listener);
|
|
@@ -602,6 +632,9 @@ export function createRuntimeCollabSync(
|
|
|
602
632
|
getWorkflowShared() {
|
|
603
633
|
return workflowShared;
|
|
604
634
|
},
|
|
635
|
+
getRemoteActivitySignal() {
|
|
636
|
+
return remoteActivityController.signal;
|
|
637
|
+
},
|
|
605
638
|
};
|
|
606
639
|
|
|
607
640
|
function onYEventsChange(event: Y.YArrayEvent<CommandEvent>): void {
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// v2.0.0 — centralized diagnostic factory. Every error / warning /
|
|
2
|
+
// blocked-command path in the runtime builds its `EditorDiagnostic`
|
|
3
|
+
// through `buildDiagnostic()` so the LLM-metadata defaults from
|
|
4
|
+
// `code-metadata-table.ts` stay consistent.
|
|
5
|
+
//
|
|
6
|
+
// Emitters may override any llmMetadata field on a per-call basis.
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
EditorAnchorProjection,
|
|
10
|
+
EditorDiagnostic,
|
|
11
|
+
EditorDiagnosticCode,
|
|
12
|
+
EditorDiagnosticLlmMetadata,
|
|
13
|
+
EditorDiagnosticTechnical,
|
|
14
|
+
} from "../../api/public-types.ts";
|
|
15
|
+
import { CODE_METADATA_TABLE } from "./code-metadata-table.ts";
|
|
16
|
+
|
|
17
|
+
export interface BuildDiagnosticParams {
|
|
18
|
+
code: EditorDiagnosticCode;
|
|
19
|
+
/** Optional override of the technical payload. `message` + `source` default from the table. */
|
|
20
|
+
technical?: Partial<EditorDiagnosticTechnical> & { message?: string };
|
|
21
|
+
/** Optional override of llmMetadata fields. Spreads over table defaults. */
|
|
22
|
+
llmMetadata?: Partial<EditorDiagnosticLlmMetadata>;
|
|
23
|
+
/** Severity override — defaults to the table's severity for this code. */
|
|
24
|
+
severity?: EditorDiagnostic["severity"];
|
|
25
|
+
/** Convenience: short-hand for technical.affectedAnchor. */
|
|
26
|
+
affectedAnchor?: EditorAnchorProjection;
|
|
27
|
+
/** Convenience: short-hand for technical.cause; accepts a raw Error. */
|
|
28
|
+
cause?: Error | EditorDiagnosticTechnical["cause"];
|
|
29
|
+
/** Convenience: short-hand for technical.details. */
|
|
30
|
+
details?: Record<string, unknown>;
|
|
31
|
+
/** Explicit diagnosticId; auto-generated when omitted. */
|
|
32
|
+
diagnosticId?: string;
|
|
33
|
+
/** Explicit emittedAt ISO string; `new Date().toISOString()` when omitted. */
|
|
34
|
+
emittedAt?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let diagnosticIdCounter = 0;
|
|
38
|
+
|
|
39
|
+
const nextDiagnosticId = (): string => {
|
|
40
|
+
diagnosticIdCounter = (diagnosticIdCounter + 1) | 0;
|
|
41
|
+
return `diag-${Date.now().toString(36)}-${diagnosticIdCounter.toString(36)}`;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const normalizeCause = (
|
|
45
|
+
cause: BuildDiagnosticParams["cause"],
|
|
46
|
+
): EditorDiagnosticTechnical["cause"] | undefined => {
|
|
47
|
+
if (!cause) return undefined;
|
|
48
|
+
if (cause instanceof Error) {
|
|
49
|
+
return {
|
|
50
|
+
message: cause.message,
|
|
51
|
+
name: cause.name,
|
|
52
|
+
stack: cause.stack,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return cause;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export function buildDiagnostic(params: BuildDiagnosticParams): EditorDiagnostic {
|
|
59
|
+
const row = CODE_METADATA_TABLE[params.code];
|
|
60
|
+
if (!row) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`buildDiagnostic: unknown EditorDiagnosticCode "${params.code}" — add a row to code-metadata-table.ts`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const severity = params.severity ?? row.severity;
|
|
67
|
+
const technical: EditorDiagnosticTechnical = {
|
|
68
|
+
message: params.technical?.message ?? row.llmMetadata.userSummary,
|
|
69
|
+
source: params.technical?.source ?? row.source,
|
|
70
|
+
stack: params.technical?.stack,
|
|
71
|
+
cause: normalizeCause(params.cause ?? params.technical?.cause),
|
|
72
|
+
details: params.details ?? params.technical?.details,
|
|
73
|
+
affectedAnchor: params.affectedAnchor ?? params.technical?.affectedAnchor,
|
|
74
|
+
featureEntryId: params.technical?.featureEntryId,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const llmMetadata: EditorDiagnosticLlmMetadata = {
|
|
78
|
+
userSummary: params.llmMetadata?.userSummary ?? row.llmMetadata.userSummary,
|
|
79
|
+
recoveryClass:
|
|
80
|
+
params.llmMetadata?.recoveryClass ?? row.llmMetadata.recoveryClass,
|
|
81
|
+
remediation: params.llmMetadata?.remediation ?? row.llmMetadata.remediation,
|
|
82
|
+
echoedInput: params.llmMetadata?.echoedInput,
|
|
83
|
+
docsUrl: params.llmMetadata?.docsUrl ?? row.llmMetadata.docsUrl,
|
|
84
|
+
tags: params.llmMetadata?.tags ?? row.llmMetadata.tags,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
diagnosticId: params.diagnosticId ?? nextDiagnosticId(),
|
|
89
|
+
severity,
|
|
90
|
+
code: params.code,
|
|
91
|
+
technical,
|
|
92
|
+
llmMetadata,
|
|
93
|
+
emittedAt: params.emittedAt ?? new Date().toISOString(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Convenience: build a diagnostic whose legacy `EditorError.code` is one of
|
|
99
|
+
* the pre-v2.0.0 codes, by mapping to the canonical v2.0.0 code.
|
|
100
|
+
*/
|
|
101
|
+
export function buildDiagnosticFromLegacyErrorCode(
|
|
102
|
+
legacyCode:
|
|
103
|
+
| "import_failed"
|
|
104
|
+
| "export_failed"
|
|
105
|
+
| "package_corrupt"
|
|
106
|
+
| "validation_failed"
|
|
107
|
+
| "datastore_failed"
|
|
108
|
+
| "internal_invariant",
|
|
109
|
+
params: Omit<BuildDiagnosticParams, "code"> = {},
|
|
110
|
+
): EditorDiagnostic {
|
|
111
|
+
const mapping: Record<string, EditorDiagnosticCode> = {
|
|
112
|
+
import_failed: "import.failed",
|
|
113
|
+
export_failed: "export.failed",
|
|
114
|
+
package_corrupt: "import.package_corrupt",
|
|
115
|
+
validation_failed: "validation.failed",
|
|
116
|
+
datastore_failed: "datastore.failed",
|
|
117
|
+
internal_invariant: "runtime.internal_invariant",
|
|
118
|
+
};
|
|
119
|
+
return buildDiagnostic({ ...params, code: mapping[legacyCode] });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Convenience: build a diagnostic whose legacy `EditorWarning.code` is one
|
|
124
|
+
* of the pre-v2.0.0 codes.
|
|
125
|
+
*/
|
|
126
|
+
export function buildDiagnosticFromLegacyWarningCode(
|
|
127
|
+
legacyCode:
|
|
128
|
+
| "unsupported_ooxml_preserved"
|
|
129
|
+
| "unsupported_ooxml_locked"
|
|
130
|
+
| "import_normalized"
|
|
131
|
+
| "export_roundtrip_risk"
|
|
132
|
+
| "comment_anchor_detached"
|
|
133
|
+
| "revision_anchor_detached"
|
|
134
|
+
| "large_document_degraded"
|
|
135
|
+
| "font_substitution"
|
|
136
|
+
| "image_missing",
|
|
137
|
+
params: Omit<BuildDiagnosticParams, "code"> = {},
|
|
138
|
+
): EditorDiagnostic {
|
|
139
|
+
const mapping: Record<string, EditorDiagnosticCode> = {
|
|
140
|
+
unsupported_ooxml_preserved: "import.unsupported_ooxml_preserved",
|
|
141
|
+
unsupported_ooxml_locked: "import.unsupported_ooxml_locked",
|
|
142
|
+
import_normalized: "import.normalized",
|
|
143
|
+
export_roundtrip_risk: "export.roundtrip_risk",
|
|
144
|
+
comment_anchor_detached: "review.comment_anchor_detached",
|
|
145
|
+
revision_anchor_detached: "review.revision_anchor_detached",
|
|
146
|
+
large_document_degraded: "runtime.large_document_degraded",
|
|
147
|
+
font_substitution: "runtime.font_substitution",
|
|
148
|
+
image_missing: "runtime.image_missing",
|
|
149
|
+
};
|
|
150
|
+
return buildDiagnostic({ ...params, code: mapping[legacyCode] });
|
|
151
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// v2.0.0 — canonical LLM-metadata + remediation defaults for every
|
|
2
|
+
// EditorDiagnosticCode. One row per code. The build-diagnostic factory
|
|
3
|
+
// reads this table to populate `EditorDiagnostic.llmMetadata` defaults;
|
|
4
|
+
// emitters may override any field on a per-call basis.
|
|
5
|
+
//
|
|
6
|
+
// Stability: advanced-supported. Changes ship with an updated snapshot
|
|
7
|
+
// in test/api/diagnostic-shape.test.ts.
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
EditorDiagnosticCode,
|
|
11
|
+
EditorDiagnosticLlmMetadata,
|
|
12
|
+
EditorDiagnosticSource,
|
|
13
|
+
} from "../../api/public-types.ts";
|
|
14
|
+
|
|
15
|
+
const DOCS_BASE = "docs/wiki/error-catalog.md";
|
|
16
|
+
|
|
17
|
+
interface CodeMetadataRow {
|
|
18
|
+
readonly source: EditorDiagnosticSource;
|
|
19
|
+
readonly severity: "fatal" | "error" | "warning" | "info";
|
|
20
|
+
readonly llmMetadata: EditorDiagnosticLlmMetadata;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const row = (
|
|
24
|
+
source: EditorDiagnosticSource,
|
|
25
|
+
severity: "fatal" | "error" | "warning" | "info",
|
|
26
|
+
userSummary: string,
|
|
27
|
+
recoveryClass: EditorDiagnosticLlmMetadata["recoveryClass"],
|
|
28
|
+
remediation: EditorDiagnosticLlmMetadata["remediation"],
|
|
29
|
+
tags: string[],
|
|
30
|
+
anchor: string,
|
|
31
|
+
): CodeMetadataRow => ({
|
|
32
|
+
source,
|
|
33
|
+
severity,
|
|
34
|
+
llmMetadata: {
|
|
35
|
+
userSummary,
|
|
36
|
+
recoveryClass,
|
|
37
|
+
remediation,
|
|
38
|
+
tags,
|
|
39
|
+
docsUrl: `${DOCS_BASE}#${anchor}`,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const CODE_METADATA_TABLE: Readonly<
|
|
44
|
+
Record<EditorDiagnosticCode, CodeMetadataRow>
|
|
45
|
+
> = {
|
|
46
|
+
"import.failed": row("import", "error",
|
|
47
|
+
"The document could not be opened — the .docx package appears to be corrupt or incomplete.",
|
|
48
|
+
"requires-input",
|
|
49
|
+
{ kind: "fallback", suggestion: "Ask the user to re-export the document from Word and retry." },
|
|
50
|
+
["import", "package"], "import-failed"),
|
|
51
|
+
"import.package_corrupt": row("import", "error",
|
|
52
|
+
"The .docx package structure is invalid and cannot be loaded.",
|
|
53
|
+
"unrecoverable",
|
|
54
|
+
{ kind: "escalate", to: "author", reason: "Package corruption — source must be regenerated." },
|
|
55
|
+
["import", "package", "corrupt"], "import-package-corrupt"),
|
|
56
|
+
"import.normalized": row("import", "info",
|
|
57
|
+
"The document was loaded successfully with minor automatic repairs.",
|
|
58
|
+
"retry-safe", { kind: "none" }, ["import", "normalized"], "import-normalized"),
|
|
59
|
+
"import.unsupported_ooxml_preserved": row("import", "info",
|
|
60
|
+
"Some advanced content was preserved but cannot be edited — it will round-trip unchanged on export.",
|
|
61
|
+
"retry-safe", { kind: "none" }, ["import", "preserve-only"], "import-unsupported-preserved"),
|
|
62
|
+
"import.unsupported_ooxml_locked": row("import", "warning",
|
|
63
|
+
"Some content is locked for editing because the editor cannot render it.",
|
|
64
|
+
"requires-human",
|
|
65
|
+
{ kind: "escalate", to: "reviewer", reason: "Locked content region requires reviewer acknowledgment." },
|
|
66
|
+
["import", "locked"], "import-unsupported-locked"),
|
|
67
|
+
"export.failed": row("export", "error",
|
|
68
|
+
"The document could not be saved — a serialization step failed.",
|
|
69
|
+
"retry-with-backoff",
|
|
70
|
+
{ kind: "retry", afterMs: 250, maxAttempts: 2 },
|
|
71
|
+
["export"], "export-failed"),
|
|
72
|
+
"export.roundtrip_risk": row("export", "warning",
|
|
73
|
+
"The document was saved, but some content may not open identically in other editors.",
|
|
74
|
+
"requires-human",
|
|
75
|
+
{ kind: "escalate", to: "author", reason: "Roundtrip-risk content flagged; author should verify." },
|
|
76
|
+
["export", "roundtrip"], "export-roundtrip-risk"),
|
|
77
|
+
"review.comment_anchor_detached": row("review", "info",
|
|
78
|
+
"A comment's anchor text was removed; the comment is now detached but still preserved.",
|
|
79
|
+
"retry-safe", { kind: "none" }, ["review", "comment"], "review-comment-anchor-detached"),
|
|
80
|
+
"review.revision_anchor_detached": row("review", "info",
|
|
81
|
+
"A tracked change's anchor was invalidated by a structural edit.",
|
|
82
|
+
"retry-safe", { kind: "none" }, ["review", "tracked-change"], "review-revision-anchor-detached"),
|
|
83
|
+
"runtime.large_document_degraded": row("runtime", "warning",
|
|
84
|
+
"The document is large enough that some rendering optimizations have been relaxed.",
|
|
85
|
+
"retry-safe", { kind: "none" }, ["runtime", "perf"], "runtime-large-document-degraded"),
|
|
86
|
+
"runtime.font_substitution": row("runtime", "info",
|
|
87
|
+
"A requested font was unavailable; a substitute was used.",
|
|
88
|
+
"retry-safe", { kind: "none" }, ["runtime", "font"], "runtime-font-substitution"),
|
|
89
|
+
"runtime.image_missing": row("runtime", "warning",
|
|
90
|
+
"An embedded image could not be loaded — a placeholder is shown.",
|
|
91
|
+
"requires-input",
|
|
92
|
+
{ kind: "fallback", suggestion: "Verify the image media part exists in the package." },
|
|
93
|
+
["runtime", "image"], "runtime-image-missing"),
|
|
94
|
+
"runtime.internal_invariant": row("runtime", "fatal",
|
|
95
|
+
"The editor reached an unexpected state and cannot continue safely.",
|
|
96
|
+
"unrecoverable",
|
|
97
|
+
{ kind: "escalate", to: "admin", reason: "Internal invariant violated — file a bug with the full diagnostic." },
|
|
98
|
+
["runtime", "bug"], "runtime-internal-invariant"),
|
|
99
|
+
"host.adapter_rejected": row("host", "error",
|
|
100
|
+
"A host integration call failed.",
|
|
101
|
+
"retry-with-backoff",
|
|
102
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 3 },
|
|
103
|
+
["host", "adapter"], "host-adapter-rejected"),
|
|
104
|
+
"host.load_rejected": row("host", "error",
|
|
105
|
+
"Loading the document from the host failed.",
|
|
106
|
+
"retry-with-backoff",
|
|
107
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 3 },
|
|
108
|
+
["host", "load"], "host-load-rejected"),
|
|
109
|
+
"host.save_rejected": row("host", "error",
|
|
110
|
+
"Saving the document to the host failed.",
|
|
111
|
+
"retry-with-backoff",
|
|
112
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 3 },
|
|
113
|
+
["host", "save"], "host-save-rejected"),
|
|
114
|
+
"host.chart_preview_rejected": row("host", "warning",
|
|
115
|
+
"A chart preview could not be rendered by the host — a badge is shown instead.",
|
|
116
|
+
"retry-safe", { kind: "none" }, ["host", "chart"], "host-chart-preview-rejected"),
|
|
117
|
+
"datastore.failed": row("datastore", "error",
|
|
118
|
+
"A datastore operation failed.",
|
|
119
|
+
"retry-with-backoff",
|
|
120
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 3 },
|
|
121
|
+
["datastore"], "datastore-failed"),
|
|
122
|
+
"datastore.load_rejected": row("datastore", "error",
|
|
123
|
+
"The datastore could not load the requested snapshot.",
|
|
124
|
+
"retry-with-backoff",
|
|
125
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 3 },
|
|
126
|
+
["datastore", "load"], "datastore-load-rejected"),
|
|
127
|
+
"datastore.save_rejected": row("datastore", "error",
|
|
128
|
+
"The datastore could not save the snapshot.",
|
|
129
|
+
"retry-with-backoff",
|
|
130
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 3 },
|
|
131
|
+
["datastore", "save"], "datastore-save-rejected"),
|
|
132
|
+
"validation.failed": row("validation", "error",
|
|
133
|
+
"A document validation invariant failed.",
|
|
134
|
+
"requires-input",
|
|
135
|
+
{ kind: "fallback", suggestion: "Inspect technical.details.reason for the failing invariant." },
|
|
136
|
+
["validation"], "validation-failed"),
|
|
137
|
+
"validation.invariant_violated": row("validation", "fatal",
|
|
138
|
+
"A critical document invariant was violated.",
|
|
139
|
+
"unrecoverable",
|
|
140
|
+
{ kind: "escalate", to: "admin", reason: "Invariant violated — document state may be corrupt." },
|
|
141
|
+
["validation", "bug"], "validation-invariant-violated"),
|
|
142
|
+
"api.invalid_regex": row("api", "error",
|
|
143
|
+
"The search pattern is not a valid regular expression.",
|
|
144
|
+
"requires-input",
|
|
145
|
+
{ kind: "fallback", suggestion: "Retry with a valid JavaScript regex, or disable the regex flag." },
|
|
146
|
+
["api", "search"], "api-invalid-regex"),
|
|
147
|
+
"api.invalid_anchor": row("api", "error",
|
|
148
|
+
"The provided position is invalid for this document.",
|
|
149
|
+
"requires-input",
|
|
150
|
+
{ kind: "fallback", suggestion: "Resolve a fresh anchor via getCurrentLocation() or findFirstText()." },
|
|
151
|
+
["api", "anchor"], "api-invalid-anchor"),
|
|
152
|
+
"api.invalid_argument": row("api", "error",
|
|
153
|
+
"An argument passed to the editor API is invalid.",
|
|
154
|
+
"requires-input",
|
|
155
|
+
{ kind: "fallback", suggestion: "Check technical.details.argument for the offending field." },
|
|
156
|
+
["api"], "api-invalid-argument"),
|
|
157
|
+
"api.metadata_resolver_missing": row("api", "error",
|
|
158
|
+
"External metadata mode requires a resolver — register one via setScopeMetadataResolver() first.",
|
|
159
|
+
"requires-resolver",
|
|
160
|
+
{ kind: "fallback", suggestion: "Call setScopeMetadataResolver(...) then retry." },
|
|
161
|
+
["api", "metadata", "resolver"], "api-metadata-resolver-missing"),
|
|
162
|
+
"api.metadata_resolver_rejected": row("api", "error",
|
|
163
|
+
"The registered metadata resolver rejected a request.",
|
|
164
|
+
"retry-with-backoff",
|
|
165
|
+
{ kind: "retry", afterMs: 500, maxAttempts: 2 },
|
|
166
|
+
["api", "metadata", "resolver"], "api-metadata-resolver-rejected"),
|
|
167
|
+
"api.scope_not_found": row("api", "error",
|
|
168
|
+
"The requested workflow scope does not exist in the current overlay.",
|
|
169
|
+
"requires-input",
|
|
170
|
+
{ kind: "fallback", suggestion: "Call queryScopes() to enumerate available scopeIds." },
|
|
171
|
+
["api", "scope"], "api-scope-not-found"),
|
|
172
|
+
"api.collab_role_restricted": row("api", "error",
|
|
173
|
+
"The current user's role does not permit this action.",
|
|
174
|
+
"requires-permission",
|
|
175
|
+
{ kind: "escalate", to: "author", reason: "Role-gated action; requires elevated permissions." },
|
|
176
|
+
["api", "collab", "role"], "api-collab-role-restricted"),
|
|
177
|
+
"api.workflow_comment_only": row("api", "warning",
|
|
178
|
+
"This location only allows comments — edits are blocked by the active workflow overlay.",
|
|
179
|
+
"requires-input",
|
|
180
|
+
{ kind: "fallback", suggestion: "Use addComment() instead, or target a scoped location." },
|
|
181
|
+
["api", "workflow"], "api-workflow-comment-only"),
|
|
182
|
+
"api.command_blocked": row("api", "warning",
|
|
183
|
+
"This command is blocked by the current workflow policy.",
|
|
184
|
+
"requires-input",
|
|
185
|
+
{ kind: "fallback", suggestion: "Check technical.details.reasons for the blocking policy." },
|
|
186
|
+
["api", "workflow", "blocked"], "api-command-blocked"),
|
|
187
|
+
// Lane 8 Track H (v2.x) — agent-helper widening.
|
|
188
|
+
"api.projection_unavailable": row("api", "error",
|
|
189
|
+
"A text projection could not be built — the runtime is still loading or the story target is unknown.",
|
|
190
|
+
"retry-with-backoff",
|
|
191
|
+
{ kind: "retry", afterMs: 100, maxAttempts: 3 },
|
|
192
|
+
["api", "agent-helpers", "projection"], "api-projection-unavailable"),
|
|
193
|
+
"api.batch_edit_collision": row("api", "error",
|
|
194
|
+
"A batched-edit operation targeted a range that had already been mutated by an earlier edit in the batch.",
|
|
195
|
+
"requires-input",
|
|
196
|
+
{ kind: "fallback", suggestion: "Rebuild the batch with non-overlapping ranges, or switch to mode: \"atomic\" to abort on conflict." },
|
|
197
|
+
["api", "agent-helpers", "batch"], "api-batch-edit-collision"),
|
|
198
|
+
"api.workflow_patch_invalid": row("api", "error",
|
|
199
|
+
"A workflow-overlay patch referenced an unknown scopeId or candidateId.",
|
|
200
|
+
"requires-input",
|
|
201
|
+
{ kind: "fallback", suggestion: "Call getWorkflowOverlay() to enumerate live ids before patching." },
|
|
202
|
+
["api", "agent-helpers", "workflow"], "api-workflow-patch-invalid"),
|
|
203
|
+
"api.change_id_unknown": row("api", "warning",
|
|
204
|
+
"The provided changeId did not match any comment or tracked-change revision.",
|
|
205
|
+
"requires-input",
|
|
206
|
+
{ kind: "fallback", suggestion: "Call findAllChanges() to enumerate live change ids." },
|
|
207
|
+
["api", "agent-helpers", "change-lookup"], "api-change-id-unknown"),
|
|
208
|
+
"api.ai_explanation_anchor_invalid": row("api", "error",
|
|
209
|
+
"An AI-explanation scope could not be anchored — the referenced change is detached or the overlay refused the range.",
|
|
210
|
+
"requires-input",
|
|
211
|
+
{ kind: "fallback", suggestion: "Filter findAllChanges() by liveOnly: true before attaching explanations." },
|
|
212
|
+
["api", "agent-helpers", "ai-annotation"], "api-ai-explanation-anchor-invalid"),
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Every key in this object is a valid {@link EditorDiagnosticCode}. Exported
|
|
217
|
+
* so test harnesses can assert exhaustiveness without importing the
|
|
218
|
+
* internal row shape.
|
|
219
|
+
*/
|
|
220
|
+
export const KNOWN_DIAGNOSTIC_CODES: ReadonlyArray<EditorDiagnosticCode> =
|
|
221
|
+
Object.freeze(Object.keys(CODE_METADATA_TABLE) as EditorDiagnosticCode[]);
|