@beyondwork/docx-react-component 1.0.31 → 1.0.33

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 CHANGED
@@ -126,6 +126,7 @@ For the normative API and host contract, use:
126
126
  - [`docs/reference/consumer-matrix.md`](docs/reference/consumer-matrix.md)
127
127
  - [`docs/reference/public-api.md`](docs/reference/public-api.md)
128
128
  - [`docs/reference/integration-guide.md`](docs/reference/integration-guide.md)
129
+ - [`docs/reference/glossary.md`](docs/reference/glossary.md)
129
130
 
130
131
  ### Wrapper And Agent Path
131
132
 
@@ -137,7 +138,9 @@ For the normative API and host contract, use:
137
138
  - [`docs/reference/agent-read-models-and-snapshots.md`](docs/reference/agent-read-models-and-snapshots.md)
138
139
  - [`docs/reference/agent-workflow-and-suggestions.md`](docs/reference/agent-workflow-and-suggestions.md)
139
140
  - [`docs/reference/scope-aware-selection-tooling.md`](docs/reference/scope-aware-selection-tooling.md)
141
+ - [`docs/reference/glossary.md`](docs/reference/glossary.md)
140
142
  - [`docs/reference/editor-integration-style.md`](docs/reference/editor-integration-style.md)
143
+ - [`docs/reference/ui-theming-and-styling.md`](docs/reference/ui-theming-and-styling.md)
141
144
  - [`docs/reference/beyondwork-runtime-environment.md`](docs/reference/beyondwork-runtime-environment.md)
142
145
 
143
146
  Wrapper and agent docs stay on `main`, but they are downstream integration guidance rather than the canonical package contract.
@@ -151,6 +154,9 @@ Current integration honesty:
151
154
  ### Maintainer Path
152
155
 
153
156
  - [`docs/maintainers/README.md`](docs/maintainers/README.md)
157
+ - [`docs/ccep-contract-templates/README.md`](docs/ccep-contract-templates/README.md)
158
+
159
+ The CCEP corpus is kept on `main` as a maintainer-safe smoke-doc source set for agreement-heavy validation and wrapper or agent benchmarking.
154
160
 
155
161
  Maintainer prompts, operator runbooks, and proof/closure material remain important, but they are not the first reading path for package consumers.
156
162
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@beyondwork/docx-react-component",
3
3
  "publisher": "beyondwork",
4
- "version": "1.0.31",
4
+ "version": "1.0.33",
5
5
  "description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
6
6
  "type": "module",
7
7
  "sideEffects": [
@@ -680,7 +680,8 @@ export type SurfaceInlineSegment =
680
680
  detail: string;
681
681
  featureKey?: string;
682
682
  blockedReasonCode?: "workflow_preserve_only" | "workflow_blocked_import";
683
- presentation?: "inline-chip" | "quiet-marker";
683
+ presentation?: "inline-chip" | "quiet-marker" | "text-box" | "checkbox";
684
+ displayText?: string;
684
685
  state: "locked-preserve-only";
685
686
  }
686
687
  | {
@@ -1092,6 +1093,7 @@ export interface EditorSessionState {
1092
1093
  warningLog: EditorWarning[];
1093
1094
  protectionSnapshot?: ProtectionSnapshot;
1094
1095
  sourcePackage?: RuntimePersistedEditorSnapshot["sourcePackage"];
1096
+ workflowOverlay?: WorkflowOverlay;
1095
1097
  workflowMetadata?: WorkflowMetadataSnapshot;
1096
1098
  }
1097
1099
 
@@ -1109,6 +1111,7 @@ export interface PersistedEditorSnapshot {
1109
1111
  warningLog: EditorWarning[];
1110
1112
  protectionSnapshot?: ProtectionSnapshot;
1111
1113
  sourcePackage?: RuntimePersistedEditorSnapshot["sourcePackage"];
1114
+ workflowOverlay?: WorkflowOverlay;
1112
1115
  workflowMetadata?: WorkflowMetadataSnapshot;
1113
1116
  }
1114
1117
 
@@ -1218,10 +1221,22 @@ export interface WorkflowBlockedCommandReason {
1218
1221
  message: string;
1219
1222
  scopeId?: string;
1220
1223
  workItemId?: string;
1224
+ fragmentId?: string;
1225
+ label?: string;
1226
+ detail?: string;
1221
1227
  anchor?: EditorAnchorProjection;
1222
1228
  storyTarget?: EditorStoryTarget;
1223
1229
  }
1224
1230
 
1231
+ export interface WorkflowLockedZone {
1232
+ fragmentId: string;
1233
+ code: "workflow_preserve_only" | "workflow_blocked_import";
1234
+ label: string;
1235
+ detail: string;
1236
+ anchor: EditorAnchorProjection;
1237
+ storyTarget?: EditorStoryTarget;
1238
+ }
1239
+
1225
1240
  export interface WorkflowScopeSnapshot {
1226
1241
  overlayPresent: boolean;
1227
1242
  activeWorkItemId?: string | null;
@@ -33,6 +33,7 @@ export function editorSessionStateFromPersistedSnapshot(
33
33
  warningLog: snapshot.warningLog,
34
34
  protectionSnapshot: snapshot.protectionSnapshot,
35
35
  sourcePackage: snapshot.sourcePackage,
36
+ workflowOverlay: snapshot.workflowOverlay,
36
37
  workflowMetadata: snapshot.workflowMetadata,
37
38
  });
38
39
  }
@@ -57,6 +58,7 @@ export function persistedSnapshotFromEditorSessionState(
57
58
  warningLog: sessionState.warningLog,
58
59
  protectionSnapshot: sessionState.protectionSnapshot,
59
60
  sourcePackage: sessionState.sourcePackage,
61
+ workflowOverlay: sessionState.workflowOverlay,
60
62
  workflowMetadata: sessionState.workflowMetadata,
61
63
  });
62
64
  }
@@ -46,7 +46,8 @@ import {
46
46
  import {
47
47
  buildWorkflowPayloadParts,
48
48
  getDocumentBackedWorkflowMetadata,
49
- parseWorkflowPayloadFromPackage,
49
+ parseWorkflowPayloadEnvelopeFromPackage,
50
+ resolvePayloadPartPath,
50
51
  WORKFLOW_PAYLOAD_CONTENT_TYPE,
51
52
  WORKFLOW_PAYLOAD_CUSTOM_PROPS_CONTENT_TYPE,
52
53
  WORKFLOW_PAYLOAD_CUSTOM_PROPS_PART_PATH,
@@ -54,6 +55,7 @@ import {
54
55
  WORKFLOW_PAYLOAD_ITEM_PROPS_CONTENT_TYPE,
55
56
  WORKFLOW_PAYLOAD_ITEM_PROPS_PART_PATH,
56
57
  WORKFLOW_PAYLOAD_PART_PATH,
58
+ WORKFLOW_PAYLOAD_RELATIONSHIP_TYPE,
57
59
  } from "./ooxml/workflow-payload.ts";
58
60
  import {
59
61
  classifyCorruptPackageError,
@@ -289,7 +291,9 @@ export function loadDocxEditorSession(
289
291
  }),
290
292
  );
291
293
  }
292
- const embeddedWorkflowMetadata = parseWorkflowPayloadFromPackage(sourcePackage);
294
+ const embeddedWorkflowPayload = parseWorkflowPayloadEnvelopeFromPackage(sourcePackage);
295
+ const embeddedWorkflowMetadata = embeddedWorkflowPayload?.workflowMetadata;
296
+ const embeddedWorkflowOverlay = embeddedWorkflowPayload?.workflowOverlay;
293
297
 
294
298
  const mainDocumentPath = resolveMainDocumentPartPath(sourcePackage);
295
299
  const brokenRelationshipIssues = collectBrokenInternalRelationshipIssues(
@@ -718,6 +722,7 @@ export function loadDocxEditorSession(
718
722
  compatibility: toPublicCompatibilityReport(compatibility),
719
723
  protectionSnapshot: importedProtectionSnapshot,
720
724
  sourcePackage: createPersistedSourcePackage(sourceBytes, options.sourceLabel),
725
+ workflowOverlay: embeddedWorkflowOverlay,
721
726
  workflowMetadata: embeddedWorkflowMetadata,
722
727
  });
723
728
  const snapshotIssues = validatePersistedEditorSnapshot(snapshot);
@@ -828,6 +833,8 @@ function exportDocxEditorSession(
828
833
  state.initialCanonicalSignature;
829
834
  const canReuse = canReuseSourceBytesForCurrentDocument(state, currentDocument);
830
835
  const durableWorkflowMetadata = getDocumentBackedWorkflowMetadata(sessionState.workflowMetadata);
836
+ const hasWorkflowOverlay = Boolean(sessionState.workflowOverlay);
837
+ const sourceHasWorkflowPayload = resolvePayloadPartPath(state.sourcePackage) !== null;
831
838
  const commentCount = Object.keys(currentDocument.review?.comments ?? {}).length;
832
839
  const currentRevisions = toReviewRevisionRecords(currentDocument.review.revisions);
833
840
  const hasActiveImportedPreserveOnlyRevisions = currentRevisions.some(
@@ -842,7 +849,9 @@ function exportDocxEditorSession(
842
849
  signatureMatch &&
843
850
  canReuse &&
844
851
  durableWorkflowMetadata.definitions.length === 0 &&
845
- durableWorkflowMetadata.entries.length === 0
852
+ durableWorkflowMetadata.entries.length === 0 &&
853
+ !hasWorkflowOverlay &&
854
+ !sourceHasWorkflowPayload
846
855
  ) {
847
856
  return {
848
857
  bytes: new Uint8Array(state.sourceBytes),
@@ -1048,6 +1057,7 @@ function exportDocxEditorSession(
1048
1057
  signatureMatch &&
1049
1058
  durableWorkflowMetadata.definitions.length === 0 &&
1050
1059
  durableWorkflowMetadata.entries.length === 0 &&
1060
+ !hasWorkflowOverlay &&
1051
1061
  commentCount === 0 &&
1052
1062
  hasActiveImportedPreserveOnlyRevisions
1053
1063
  ? state.sourceDocumentXml
@@ -1644,6 +1654,7 @@ function createImportedSnapshot(input: {
1644
1654
  compatibility: PersistedEditorSnapshot["compatibility"];
1645
1655
  protectionSnapshot: ProtectionSnapshot;
1646
1656
  sourcePackage?: PersistedEditorSnapshot["sourcePackage"];
1657
+ workflowOverlay?: PersistedEditorSnapshot["workflowOverlay"];
1647
1658
  workflowMetadata?: PersistedEditorSnapshot["workflowMetadata"];
1648
1659
  }): PersistedEditorSnapshot {
1649
1660
  return {
@@ -1660,6 +1671,7 @@ function createImportedSnapshot(input: {
1660
1671
  warningLog: input.compatibility.warnings,
1661
1672
  protectionSnapshot: input.protectionSnapshot,
1662
1673
  sourcePackage: input.sourcePackage,
1674
+ workflowOverlay: input.workflowOverlay,
1663
1675
  workflowMetadata: input.workflowMetadata,
1664
1676
  };
1665
1677
  }
@@ -2724,6 +2736,7 @@ function ensureWorkflowPayloadParts(
2724
2736
  const payloadParts = buildWorkflowPayloadParts({
2725
2737
  sourcePackage,
2726
2738
  workflowMetadata: sessionState.workflowMetadata,
2739
+ workflowOverlay: sessionState.workflowOverlay,
2727
2740
  documentId: sessionState.documentId,
2728
2741
  createdAt: document.createdAt,
2729
2742
  updatedAt: document.updatedAt,
@@ -11,6 +11,7 @@ import type {
11
11
  TableRowNode,
12
12
  TextMark,
13
13
  } from "../../model/canonical-document.ts";
14
+ import { classifyFieldInstruction } from "./parse-fields.ts";
14
15
  import {
15
16
  readCellBorders,
16
17
  readCellShading,
@@ -220,12 +221,7 @@ function parseParagraphElement(pElement: XmlElementNode): ParagraphNode {
220
221
  activeComplexField = appendRunNodes(child, children, activeComplexField);
221
222
  } else if (name === "hyperlink") {
222
223
  if (activeComplexField && activeComplexField.instruction.trim().length > 0) {
223
- children.push({
224
- type: "field",
225
- fieldType: "complex",
226
- instruction: activeComplexField.instruction,
227
- children: activeComplexField.children,
228
- });
224
+ children.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
229
225
  activeComplexField = null;
230
226
  }
231
227
  children.push(parseHyperlinkElement(child));
@@ -235,24 +231,14 @@ function parseParagraphElement(pElement: XmlElementNode): ParagraphNode {
235
231
  activeComplexField.children.push(bookmarkNode);
236
232
  } else {
237
233
  if (activeComplexField && activeComplexField.instruction.trim().length > 0) {
238
- children.push({
239
- type: "field",
240
- fieldType: "complex",
241
- instruction: activeComplexField.instruction,
242
- children: activeComplexField.children,
243
- });
234
+ children.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
244
235
  activeComplexField = null;
245
236
  }
246
237
  children.push(bookmarkNode);
247
238
  }
248
239
  } else if (name === "fldSimple") {
249
240
  if (activeComplexField && activeComplexField.instruction.trim().length > 0) {
250
- children.push({
251
- type: "field",
252
- fieldType: "complex",
253
- instruction: activeComplexField.instruction,
254
- children: activeComplexField.children,
255
- });
241
+ children.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
256
242
  activeComplexField = null;
257
243
  }
258
244
  pushFieldNode(children, child, "simple");
@@ -260,12 +246,7 @@ function parseParagraphElement(pElement: XmlElementNode): ParagraphNode {
260
246
  }
261
247
 
262
248
  if (activeComplexField && activeComplexField.instruction.trim().length > 0) {
263
- children.push({
264
- type: "field",
265
- fieldType: "complex",
266
- instruction: activeComplexField.instruction,
267
- children: activeComplexField.children,
268
- });
249
+ children.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
269
250
  }
270
251
 
271
252
  return {
@@ -307,12 +288,7 @@ function appendRunNodes(
307
288
  activeComplexField.mode = "result";
308
289
  } else if (fldType === "end" && activeComplexField) {
309
290
  if (activeComplexField.instruction.trim().length > 0) {
310
- nodes.push({
311
- type: "field",
312
- fieldType: "complex",
313
- instruction: activeComplexField.instruction,
314
- children: activeComplexField.children,
315
- });
291
+ nodes.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
316
292
  }
317
293
  activeComplexField = null;
318
294
  }
@@ -489,12 +465,26 @@ function pushFieldNode(
489
465
  return;
490
466
  }
491
467
 
492
- nodes.push({
468
+ const classification = classifyFieldInstruction(instruction);
469
+
470
+ nodes.push(createFieldNode(instruction, fieldType));
471
+ }
472
+
473
+ function createFieldNode(
474
+ instruction: string,
475
+ fieldType: "simple" | "complex",
476
+ children: InlineNode[] = [],
477
+ ): Extract<InlineNode, { type: "field" }> {
478
+ const classification = classifyFieldInstruction(instruction);
479
+ return {
493
480
  type: "field",
494
481
  fieldType,
495
482
  instruction,
496
- children: [],
497
- });
483
+ children,
484
+ fieldFamily: classification.family,
485
+ ...(classification.target ? { fieldTarget: classification.target } : {}),
486
+ refreshStatus: classification.supported ? "stale" : "preserve-only",
487
+ };
498
488
  }
499
489
 
500
490
  function readFieldInstruction(element: XmlElementNode): string | undefined {
@@ -274,12 +274,7 @@ function parseParagraphElement(pElement: XmlElementNode): ParagraphNode {
274
274
  children.push(parseBookmarkElement(child));
275
275
  } else if (name === "fldSimple") {
276
276
  if (activeComplexField && activeComplexField.instruction.trim().length > 0) {
277
- children.push({
278
- type: "field",
279
- fieldType: "complex",
280
- instruction: activeComplexField.instruction,
281
- children: activeComplexField.children,
282
- });
277
+ children.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
283
278
  activeComplexField = null;
284
279
  }
285
280
  pushFieldNode(children, child, "simple");
@@ -287,12 +282,7 @@ function parseParagraphElement(pElement: XmlElementNode): ParagraphNode {
287
282
  }
288
283
 
289
284
  if (activeComplexField && activeComplexField.instruction.trim().length > 0) {
290
- children.push({
291
- type: "field",
292
- fieldType: "complex",
293
- instruction: activeComplexField.instruction,
294
- children: activeComplexField.children,
295
- });
285
+ children.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
296
286
  }
297
287
 
298
288
  return {
@@ -335,12 +325,7 @@ function appendRunNodes(
335
325
  activeComplexField.mode = "result";
336
326
  } else if (fldType === "end" && activeComplexField) {
337
327
  if (activeComplexField.instruction.trim().length > 0) {
338
- nodes.push({
339
- type: "field",
340
- fieldType: "complex",
341
- instruction: activeComplexField.instruction,
342
- children: activeComplexField.children,
343
- });
328
+ nodes.push(createFieldNode(activeComplexField.instruction, "complex", activeComplexField.children));
344
329
  }
345
330
  activeComplexField = null;
346
331
  }
@@ -609,12 +594,26 @@ function pushFieldNode(
609
594
  return;
610
595
  }
611
596
 
612
- nodes.push({
597
+ const classification = classifyFieldInstruction(instruction);
598
+
599
+ nodes.push(createFieldNode(instruction, fieldType));
600
+ }
601
+
602
+ function createFieldNode(
603
+ instruction: string,
604
+ fieldType: "simple" | "complex",
605
+ children: InlineNode[] = [],
606
+ ): Extract<InlineNode, { type: "field" }> {
607
+ const classification = classifyFieldInstruction(instruction);
608
+ return {
613
609
  type: "field",
614
610
  fieldType,
615
611
  instruction,
616
- children: [],
617
- });
612
+ children,
613
+ fieldFamily: classification.family,
614
+ ...(classification.target ? { fieldTarget: classification.target } : {}),
615
+ refreshStatus: classification.supported ? "stale" : "preserve-only",
616
+ };
618
617
  }
619
618
 
620
619
  function readFieldInstruction(element: XmlElementNode): string | undefined {