@beyondwork/docx-react-component 1.0.128 → 1.0.130

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 (108) hide show
  1. package/dist/api/public-types.cjs +809 -78
  2. package/dist/api/public-types.d.cts +2 -2
  3. package/dist/api/public-types.d.ts +2 -2
  4. package/dist/api/public-types.js +4 -4
  5. package/dist/api/v3.cjs +2059 -402
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +13 -13
  9. package/dist/{canonical-document-CXCFCbAz.d.cts → canonical-document-BMtONpgf.d.cts} +6 -0
  10. package/dist/{canonical-document-CXCFCbAz.d.ts → canonical-document-BMtONpgf.d.ts} +6 -0
  11. package/dist/{chunk-MWSBGJQO.js → chunk-35RHOE6I.js} +105 -4
  12. package/dist/{chunk-2QL5DAKF.js → chunk-3YCQM2RV.js} +6 -6
  13. package/dist/{chunk-ESJ2MES5.js → chunk-4YCWECLZ.js} +1 -1
  14. package/dist/{chunk-4EENH4FG.js → chunk-6TBLDBCL.js} +1 -1
  15. package/dist/{chunk-XRACP43Q.js → chunk-7G5GR3VV.js} +469 -32
  16. package/dist/{chunk-CXSYRB37.js → chunk-A3GSNB4G.js} +183 -55
  17. package/dist/{chunk-5DGKFNQT.js → chunk-A66ZVUAT.js} +150 -1
  18. package/dist/{chunk-YIYM4ZAP.js → chunk-CI2TD3T4.js} +1 -1
  19. package/dist/{chunk-TQDQU2E3.js → chunk-DGA7M77X.js} +2 -2
  20. package/dist/{chunk-EB6M3GE6.js → chunk-FM4K4XFJ.js} +100 -97
  21. package/dist/{chunk-D5HYZQTG.js → chunk-HYHCRMR7.js} +1 -1
  22. package/dist/{chunk-6F5QW44A.js → chunk-KNHMXKC6.js} +2 -2
  23. package/dist/{chunk-4YJVRIUB.js → chunk-M7YRJX6V.js} +61 -29
  24. package/dist/{chunk-KFCQYZXR.js → chunk-OVLZQ6FZ.js} +61 -0
  25. package/dist/{chunk-BYSRJ4FE.js → chunk-PHMWH23E.js} +1 -1
  26. package/dist/{chunk-ZDOAUP3V.js → chunk-Q7Y57KOK.js} +2 -2
  27. package/dist/{chunk-LZVBNDGU.js → chunk-QXKQPUOM.js} +3 -3
  28. package/dist/{chunk-CX42VC67.js → chunk-SYQWQ6FE.js} +1 -1
  29. package/dist/{chunk-KV435YXO.js → chunk-T5YYFDZB.js} +1 -1
  30. package/dist/{chunk-YHZHPXDB.js → chunk-THVM6EP5.js} +419 -24
  31. package/dist/{chunk-V6XVZFFH.js → chunk-VRKK2CSZ.js} +111 -90
  32. package/dist/{chunk-OL2UEHRP.js → chunk-WUDSNHWF.js} +1 -1
  33. package/dist/{chunk-LCYYR57Q.js → chunk-WZDKNF37.js} +666 -107
  34. package/dist/{chunk-6EROGFUF.js → chunk-YLL7MF5C.js} +444 -131
  35. package/dist/{chunk-YD2JE54B.js → chunk-ZVC23LKV.js} +1 -1
  36. package/dist/compare.cjs +100 -97
  37. package/dist/compare.d.cts +1 -1
  38. package/dist/compare.d.ts +1 -1
  39. package/dist/compare.js +3 -3
  40. package/dist/core/commands/formatting-commands.d.cts +2 -2
  41. package/dist/core/commands/formatting-commands.d.ts +2 -2
  42. package/dist/core/commands/image-commands.cjs +182 -54
  43. package/dist/core/commands/image-commands.d.cts +2 -2
  44. package/dist/core/commands/image-commands.d.ts +2 -2
  45. package/dist/core/commands/image-commands.js +5 -5
  46. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  47. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  48. package/dist/core/commands/style-commands.d.cts +2 -2
  49. package/dist/core/commands/style-commands.d.ts +2 -2
  50. package/dist/core/commands/table-structure-commands.cjs +182 -54
  51. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  52. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  53. package/dist/core/commands/table-structure-commands.js +4 -4
  54. package/dist/core/commands/text-commands.cjs +182 -54
  55. package/dist/core/commands/text-commands.d.cts +2 -2
  56. package/dist/core/commands/text-commands.d.ts +2 -2
  57. package/dist/core/commands/text-commands.js +5 -5
  58. package/dist/core/selection/mapping.d.cts +2 -2
  59. package/dist/core/selection/mapping.d.ts +2 -2
  60. package/dist/core/state/editor-state.d.cts +2 -2
  61. package/dist/core/state/editor-state.d.ts +2 -2
  62. package/dist/index.cjs +2765 -557
  63. package/dist/index.d.cts +5 -5
  64. package/dist/index.d.ts +5 -5
  65. package/dist/index.js +52 -28
  66. package/dist/io/docx-session.cjs +267 -211
  67. package/dist/io/docx-session.d.cts +4 -4
  68. package/dist/io/docx-session.d.ts +4 -4
  69. package/dist/io/docx-session.js +6 -6
  70. package/dist/legal.cjs +9 -20
  71. package/dist/legal.d.cts +1 -1
  72. package/dist/legal.d.ts +1 -1
  73. package/dist/legal.js +3 -3
  74. package/dist/{loader-19ct2Be0.d.ts → loader-B-aL5HGD.d.ts} +3 -3
  75. package/dist/{loader-CoXQ2wGd.d.cts → loader-DiY_ZgKl.d.cts} +3 -3
  76. package/dist/{measurement-backend-canvas-Q3MJMEYX.js → measurement-backend-canvas-F7ZYDACK.js} +1 -1
  77. package/dist/{public-types-B-CskQen.d.cts → public-types-DyqnxxO9.d.ts} +252 -2
  78. package/dist/{public-types-7KZsNGE2.d.ts → public-types-gvubspUI.d.cts} +252 -2
  79. package/dist/public-types.cjs +809 -78
  80. package/dist/public-types.d.cts +2 -2
  81. package/dist/public-types.d.ts +2 -2
  82. package/dist/public-types.js +4 -4
  83. package/dist/runtime/collab.d.cts +3 -3
  84. package/dist/runtime/collab.d.ts +3 -3
  85. package/dist/runtime/document-runtime.cjs +1887 -313
  86. package/dist/runtime/document-runtime.d.cts +2 -2
  87. package/dist/runtime/document-runtime.d.ts +2 -2
  88. package/dist/runtime/document-runtime.js +17 -17
  89. package/dist/{session-B5015J4v.d.cts → session-BUN6B-Vj.d.cts} +3 -3
  90. package/dist/{session-C2i8-d6v.d.ts → session-CDB0hohT.d.ts} +3 -3
  91. package/dist/session.cjs +267 -211
  92. package/dist/session.d.cts +5 -5
  93. package/dist/session.d.ts +5 -5
  94. package/dist/session.js +7 -7
  95. package/dist/tailwind.cjs +809 -78
  96. package/dist/tailwind.d.cts +2 -2
  97. package/dist/tailwind.d.ts +2 -2
  98. package/dist/tailwind.js +8 -8
  99. package/dist/{types-DNhN0WeN.d.cts → types-C4bz3kDU.d.cts} +2 -2
  100. package/dist/{types-yvrQuGX9.d.ts → types-VWH6CRvG.d.ts} +2 -2
  101. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  102. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  103. package/dist/ui-tailwind/editor-surface/search-plugin.js +5 -5
  104. package/dist/ui-tailwind.cjs +809 -78
  105. package/dist/ui-tailwind.d.cts +3 -3
  106. package/dist/ui-tailwind.d.ts +3 -3
  107. package/dist/ui-tailwind.js +8 -8
  108. package/package.json +1 -1
@@ -9,6 +9,7 @@ import {
9
9
  enumerateScopes,
10
10
  findParagraphByBlockId,
11
11
  getAIActionPolicy,
12
+ getListKind,
12
13
  parseCanonicalFragmentFromWordML,
13
14
  resolveDirectRunFormattingAtSegment,
14
15
  resolveEditableTableStructureTarget,
@@ -17,7 +18,7 @@ import {
17
18
  resolveScopeRange,
18
19
  scopeSpecificity,
19
20
  searchDocument
20
- } from "./chunk-XRACP43Q.js";
21
+ } from "./chunk-7G5GR3VV.js";
21
22
  import {
22
23
  BROADCAST_COMMAND_TYPES,
23
24
  COMMAND_EVENT_SCHEMA_VERSION,
@@ -28,7 +29,7 @@ import {
28
29
  buildPageAnchorElementId,
29
30
  createUiApi,
30
31
  emitUxResponse
31
- } from "./chunk-YIYM4ZAP.js";
32
+ } from "./chunk-CI2TD3T4.js";
32
33
  import {
33
34
  DEFAULT_PX_PER_TWIP,
34
35
  DEFAULT_REGISTRY_ENTRIES,
@@ -36,23 +37,24 @@ import {
36
37
  LAYCACHE_SCHEMA_VERSION,
37
38
  LAYOUT_ENGINE_VERSION,
38
39
  createScopeTagRegistry
39
- } from "./chunk-YHZHPXDB.js";
40
+ } from "./chunk-THVM6EP5.js";
40
41
  import {
41
42
  chartModelStore,
42
43
  createFormattingContext
43
- } from "./chunk-CXSYRB37.js";
44
+ } from "./chunk-A3GSNB4G.js";
44
45
  import {
46
+ createSelectionSnapshot,
45
47
  deriveDocumentStats
46
48
  } from "./chunk-OYGMRRR7.js";
47
49
  import {
48
50
  DocxSession
49
- } from "./chunk-TQDQU2E3.js";
51
+ } from "./chunk-DGA7M77X.js";
50
52
  import {
51
53
  WORKFLOW_PAYLOAD_PART_PATH,
52
54
  buildEditorStateXml,
53
55
  parseEditorStateXml,
54
56
  parseWorkflowPayloadEnvelopeFromPackage
55
- } from "./chunk-V6XVZFFH.js";
57
+ } from "./chunk-VRKK2CSZ.js";
56
58
  import {
57
59
  EMU_PER_PX,
58
60
  GRADIENT_STOP_UNITS,
@@ -61,10 +63,10 @@ import {
61
63
  createHeaderFooterStoryKey,
62
64
  createNoteStoryKey,
63
65
  validateEditableTargetRef
64
- } from "./chunk-5DGKFNQT.js";
66
+ } from "./chunk-A66ZVUAT.js";
65
67
  import {
66
68
  readOpcPackage
67
- } from "./chunk-OL2UEHRP.js";
69
+ } from "./chunk-WUDSNHWF.js";
68
70
 
69
71
  // src/api/v3/_mocks.ts
70
72
  function mockPayload(reason, shape, body) {
@@ -864,6 +866,10 @@ function extractNLHaystack(entry) {
864
866
  }
865
867
  return out.slice(0, 200).toLowerCase();
866
868
  }
869
+ case "image": {
870
+ const text = entry.image.type === "image" ? entry.image.altText ?? "" : entry.image.anchor.docPr?.descr ?? entry.image.anchor.docPr?.name ?? "";
871
+ return text.slice(0, 200).toLowerCase();
872
+ }
867
873
  case "table":
868
874
  case "table-row":
869
875
  case "table-cell":
@@ -3993,6 +3999,391 @@ function createViewportFamily(runtime) {
3993
3999
  };
3994
4000
  }
3995
4001
 
4002
+ // src/api/v3/runtime/lists.ts
4003
+ var SUPPORTED_COMMANDS = [
4004
+ "toggle-numbered",
4005
+ "toggle-bulleted",
4006
+ "indent",
4007
+ "outdent",
4008
+ "restart-numbering",
4009
+ "continue-numbering"
4010
+ ];
4011
+ var UNSUPPORTED_COMMANDS = [
4012
+ "create",
4013
+ "attach",
4014
+ "detach",
4015
+ "join",
4016
+ "separate",
4017
+ "split",
4018
+ "set-value",
4019
+ "apply-template",
4020
+ "capture-template",
4021
+ "apply-preset",
4022
+ "set-level-numbering",
4023
+ "set-level-bullet",
4024
+ "set-level-picture-bullet",
4025
+ "set-level-alignment",
4026
+ "set-level-indents",
4027
+ "set-level-trailing-character",
4028
+ "set-level-marker-font",
4029
+ "set-level-text",
4030
+ "set-level-start",
4031
+ "set-level-layout",
4032
+ "convert-to-text",
4033
+ "paste-fragment",
4034
+ "drop-fragment"
4035
+ ];
4036
+ var applyCommandMetadata = {
4037
+ name: "runtime.lists.applyCommand",
4038
+ status: "live-with-adapter",
4039
+ sourceLayer: "runtime-core",
4040
+ liveEvidence: {
4041
+ runnerTest: "test/api/v3/runtime/lists.test.ts",
4042
+ commit: "refactor-07-runtime-lists-namespace"
4043
+ },
4044
+ uxIntent: {
4045
+ uiVisible: true,
4046
+ expectsUxResponse: "surface-refresh",
4047
+ expectedDelta: "list structure changes through the L07 list command surface"
4048
+ },
4049
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "scope", auditCategory: "list-command" },
4050
+ stateClass: "A-canonical",
4051
+ persistsTo: "canonical",
4052
+ broadcastsVia: "crdt",
4053
+ rwdReference: "\xA7Runtime API \xA7 runtime.lists.applyCommand. Dispatches only proven L07 list commands through opaque list targets; future commands return owner-routed blockers until command/export/readback support lands."
4054
+ };
4055
+ function createListsFamily(runtime) {
4056
+ return {
4057
+ list(input = {}) {
4058
+ const document = runtime.getCanonicalDocument();
4059
+ const rows = currentListTargets(document).filter((entry) => input.storyKey === void 0 || entry.target.storyKey === input.storyKey).map((entry) => toReadback(document, entry.target, entry.paragraph));
4060
+ return input.limit === void 0 ? rows : rows.slice(0, Math.max(0, input.limit));
4061
+ },
4062
+ get(input) {
4063
+ const resolved = resolveCurrentListTarget(runtime.getCanonicalDocument(), input);
4064
+ return resolved.kind === "resolved" ? toReadback(runtime.getCanonicalDocument(), resolved.target, resolved.paragraph) : null;
4065
+ },
4066
+ previewCommand(input) {
4067
+ return previewListCommand(runtime.getCanonicalDocument(), input);
4068
+ },
4069
+ applyCommand(input) {
4070
+ const preview = previewListCommand(runtime.getCanonicalDocument(), input);
4071
+ if (!preview.supported || !preview.target) {
4072
+ return {
4073
+ applied: false,
4074
+ command: input.command,
4075
+ before: preview.target,
4076
+ blockers: preview.blockers
4077
+ };
4078
+ }
4079
+ const resolved = resolveCurrentListTarget(runtime.getCanonicalDocument(), {
4080
+ addressKey: preview.target.addressKey
4081
+ });
4082
+ if (resolved.kind !== "resolved") {
4083
+ return {
4084
+ applied: false,
4085
+ command: input.command,
4086
+ before: preview.target,
4087
+ blockers: [resolved.blocker]
4088
+ };
4089
+ }
4090
+ const command = editorCommandForListCommand(
4091
+ input.command,
4092
+ resolved.target,
4093
+ runtime.now(),
4094
+ input.startAt
4095
+ );
4096
+ if (!command) {
4097
+ return {
4098
+ applied: false,
4099
+ command: input.command,
4100
+ before: preview.target,
4101
+ blockers: [
4102
+ unsupportedCommandBlocker(input.command, {
4103
+ targetKey: preview.target.targetKey,
4104
+ addressKey: preview.target.addressKey
4105
+ })
4106
+ ]
4107
+ };
4108
+ }
4109
+ const beforeDocument = runtime.getCanonicalDocument();
4110
+ runtime.dispatch(command);
4111
+ const afterDocument = runtime.getCanonicalDocument();
4112
+ const after = resolveCurrentListTarget(afterDocument, { targetKey: preview.target.targetKey });
4113
+ emitUxResponse(runtime, {
4114
+ apiFn: applyCommandMetadata.name,
4115
+ intent: applyCommandMetadata.uxIntent.expectedDelta ?? "",
4116
+ mockOrLive: "live",
4117
+ uiVisible: true,
4118
+ expectedDelta: applyCommandMetadata.uxIntent.expectedDelta
4119
+ });
4120
+ return {
4121
+ applied: beforeDocument !== afterDocument,
4122
+ command: input.command,
4123
+ before: preview.target,
4124
+ ...after.kind === "resolved" ? { after: toReadback(afterDocument, after.target, after.paragraph) } : {},
4125
+ blockers: []
4126
+ };
4127
+ }
4128
+ };
4129
+ }
4130
+ function previewListCommand(document, input) {
4131
+ const resolved = resolveCurrentListTarget(document, input);
4132
+ if (resolved.kind !== "resolved") {
4133
+ return {
4134
+ command: input.command,
4135
+ supported: false,
4136
+ affectedTargets: [],
4137
+ blockers: [resolved.blocker]
4138
+ };
4139
+ }
4140
+ const target = toReadback(document, resolved.target, resolved.paragraph);
4141
+ const targetRef = { targetKey: target.targetKey, addressKey: target.addressKey };
4142
+ if (!SUPPORTED_COMMANDS.includes(input.command)) {
4143
+ return {
4144
+ command: input.command,
4145
+ supported: false,
4146
+ target,
4147
+ affectedTargets: [target],
4148
+ blockers: [unsupportedCommandBlocker(input.command, targetRef)]
4149
+ };
4150
+ }
4151
+ const canContinuePrevious = canContinuePreviousSequence(document, resolved.paragraphIndex);
4152
+ const canJoin = canJoinPreviousSequence(document, resolved.paragraphIndex);
4153
+ const blockers = [];
4154
+ if (input.command === "continue-numbering" && !canContinuePrevious) {
4155
+ blockers.push({
4156
+ code: "list-continue-target-missing",
4157
+ ownerLayer: "L07",
4158
+ message: "No previous compatible list sequence is available for continue-numbering.",
4159
+ ...targetRef
4160
+ });
4161
+ }
4162
+ return {
4163
+ command: input.command,
4164
+ supported: blockers.length === 0,
4165
+ target,
4166
+ affectedTargets: [target],
4167
+ blockers,
4168
+ canJoin,
4169
+ canContinuePrevious
4170
+ };
4171
+ }
4172
+ function editorCommandForListCommand(command, editableTarget, timestamp, startAt) {
4173
+ const origin = { source: "api", timestamp };
4174
+ switch (command) {
4175
+ case "toggle-numbered":
4176
+ return { type: "list.toggle", kind: "numbered", editableTargets: [editableTarget], origin };
4177
+ case "toggle-bulleted":
4178
+ return { type: "list.toggle", kind: "bulleted", editableTargets: [editableTarget], origin };
4179
+ case "indent":
4180
+ return { type: "list.indent", editableTargets: [editableTarget], origin };
4181
+ case "outdent":
4182
+ return { type: "list.outdent", editableTargets: [editableTarget], origin };
4183
+ case "restart-numbering":
4184
+ return {
4185
+ type: "list.restart-numbering",
4186
+ editableTarget,
4187
+ ...startAt !== void 0 ? { startAt } : {},
4188
+ origin
4189
+ };
4190
+ case "continue-numbering":
4191
+ return { type: "list.continue-numbering", editableTarget, origin };
4192
+ default:
4193
+ return void 0;
4194
+ }
4195
+ }
4196
+ function resolveCurrentListTarget(document, input) {
4197
+ if (input.editableTarget) {
4198
+ const shapeIssues = validateEditableTargetRef(input.editableTarget);
4199
+ if (shapeIssues.length > 0) {
4200
+ return {
4201
+ kind: "blocked",
4202
+ blocker: {
4203
+ code: "list-target-malformed",
4204
+ ownerLayer: "L07",
4205
+ message: `List target is malformed: ${shapeIssues[0]?.path ?? "$"}.`,
4206
+ targetKey: input.editableTarget.targetKey,
4207
+ addressKey: input.editableTarget.listAddress?.addressKey
4208
+ }
4209
+ };
4210
+ }
4211
+ }
4212
+ const requestedTargetKey = input.editableTarget?.targetKey ?? input.targetKey;
4213
+ const requestedAddressKey = input.editableTarget?.listAddress?.addressKey ?? input.addressKey;
4214
+ if (!requestedTargetKey && !requestedAddressKey) {
4215
+ return {
4216
+ kind: "blocked",
4217
+ blocker: {
4218
+ code: "list-target-required",
4219
+ ownerLayer: "L07",
4220
+ message: "runtime.lists requires a targetKey, addressKey, or editableTarget."
4221
+ }
4222
+ };
4223
+ }
4224
+ const currentTargets = currentListTargets(document);
4225
+ const resolved = currentTargets.find(
4226
+ ({ target }) => requestedTargetKey !== void 0 && target.targetKey === requestedTargetKey || requestedAddressKey !== void 0 && target.listAddress?.addressKey === requestedAddressKey
4227
+ );
4228
+ if (!resolved) {
4229
+ return {
4230
+ kind: "blocked",
4231
+ blocker: {
4232
+ code: "list-target-not-found",
4233
+ ownerLayer: "L07",
4234
+ message: "List target no longer resolves in the current canonical document.",
4235
+ ...requestedTargetKey !== void 0 ? { targetKey: requestedTargetKey } : {},
4236
+ ...requestedAddressKey !== void 0 ? { addressKey: requestedAddressKey } : {}
4237
+ }
4238
+ };
4239
+ }
4240
+ if (input.editableTarget && !sameTargetStaleHash(input.editableTarget, resolved.target)) {
4241
+ return {
4242
+ kind: "blocked",
4243
+ blocker: {
4244
+ code: "list-target-stale",
4245
+ ownerLayer: "L07",
4246
+ message: "List target resolved by identity but stale discriminators changed.",
4247
+ targetKey: input.editableTarget.targetKey,
4248
+ addressKey: input.editableTarget.listAddress?.addressKey
4249
+ }
4250
+ };
4251
+ }
4252
+ if (resolved.target.editability !== "editable" || resolved.target.posture.blockers.length > 0) {
4253
+ return {
4254
+ kind: "blocked",
4255
+ blocker: {
4256
+ code: "list-target-non-editable",
4257
+ ownerLayer: "L07",
4258
+ message: resolved.target.posture.blockers.length > 0 ? `List target is not editable: ${resolved.target.posture.blockers.join(", ")}.` : "List target is not editable.",
4259
+ targetKey: resolved.target.targetKey,
4260
+ addressKey: resolved.target.listAddress?.addressKey
4261
+ }
4262
+ };
4263
+ }
4264
+ return { kind: "resolved", ...resolved };
4265
+ }
4266
+ function currentListTargets(document) {
4267
+ const paragraphs = collectParagraphEntries(document.content.children, "main");
4268
+ const targets = collectEditableTargetRefs(document).filter(isListTextTarget);
4269
+ const byBlockPath = /* @__PURE__ */ new Map();
4270
+ for (const target of targets) byBlockPath.set(target.blockPath, target);
4271
+ const out = [];
4272
+ for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex += 1) {
4273
+ const entry = paragraphs[paragraphIndex];
4274
+ if (!entry?.paragraph.numbering) continue;
4275
+ const target = byBlockPath.get(entry.blockPath);
4276
+ if (!target) continue;
4277
+ out.push({ target, paragraph: entry.paragraph, paragraphIndex });
4278
+ }
4279
+ return out;
4280
+ }
4281
+ function collectParagraphEntries(blocks, basePath) {
4282
+ const out = [];
4283
+ collectParagraphEntriesInto(blocks, basePath, out);
4284
+ return out;
4285
+ }
4286
+ function collectParagraphEntriesInto(blocks, basePath, out) {
4287
+ for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
4288
+ const block = blocks[blockIndex];
4289
+ if (!block) continue;
4290
+ const blockPath = `${basePath}/block[${blockIndex}]`;
4291
+ switch (block.type) {
4292
+ case "paragraph":
4293
+ out.push({ paragraph: block, blockPath });
4294
+ break;
4295
+ case "table":
4296
+ for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
4297
+ const row = block.rows[rowIndex];
4298
+ if (!row) continue;
4299
+ for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex += 1) {
4300
+ const cell = row.cells[cellIndex];
4301
+ if (!cell) continue;
4302
+ collectParagraphEntriesInto(
4303
+ cell.children,
4304
+ `${blockPath}/row[${rowIndex}]/cell[${cellIndex}]`,
4305
+ out
4306
+ );
4307
+ }
4308
+ }
4309
+ break;
4310
+ case "sdt":
4311
+ collectParagraphEntriesInto(block.children, blockPath, out);
4312
+ break;
4313
+ case "custom_xml":
4314
+ break;
4315
+ default:
4316
+ break;
4317
+ }
4318
+ }
4319
+ }
4320
+ function isListTextTarget(target) {
4321
+ return target.commandFamily === "text-leaf" && target.listAddress?.operationScope === "list-text" && target.listAddress.addressKind === "list-item-text";
4322
+ }
4323
+ function sameTargetStaleHash(left, right) {
4324
+ return left.targetKey === right.targetKey && left.listAddress?.addressKey === right.listAddress?.addressKey && left.listAddress?.resolver?.staleHash === right.listAddress?.resolver?.staleHash && left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength && left.staleCheck.inlineCount === right.staleCheck.inlineCount;
4325
+ }
4326
+ function toReadback(document, target, paragraph) {
4327
+ const numbering = paragraph.numbering;
4328
+ const instance = document.numbering.instances[numbering.numberingInstanceId];
4329
+ const listKind = instance ? getListKind(document.numbering, numbering.numberingInstanceId) : void 0;
4330
+ return {
4331
+ targetKey: target.targetKey,
4332
+ actionHandle: `list-action:${target.listAddress.addressKey}`,
4333
+ kind: target.kind,
4334
+ storyKey: target.storyKey,
4335
+ blockPath: target.blockPath,
4336
+ leafPath: target.leafPath,
4337
+ addressKey: target.listAddress.addressKey,
4338
+ numberingInstanceId: numbering.numberingInstanceId,
4339
+ ...instance?.abstractNumberingId ? { abstractNumberingId: instance.abstractNumberingId } : {},
4340
+ level: numbering.level,
4341
+ ...listKind ? { listKind } : {},
4342
+ editability: target.editability,
4343
+ blockers: target.posture.blockers,
4344
+ supportedCommands: SUPPORTED_COMMANDS,
4345
+ unsupportedCommands: UNSUPPORTED_COMMANDS,
4346
+ staleDiscriminators: {
4347
+ paragraphTextHash: target.staleCheck.paragraphTextHash,
4348
+ paragraphTextLength: target.staleCheck.paragraphTextLength,
4349
+ inlineCount: target.staleCheck.inlineCount,
4350
+ listAddressStaleHash: target.listAddress?.resolver?.staleHash
4351
+ }
4352
+ };
4353
+ }
4354
+ function canContinuePreviousSequence(document, paragraphIndex) {
4355
+ const paragraphs = collectParagraphEntries(document.content.children, "main");
4356
+ const current = paragraphs[paragraphIndex]?.paragraph;
4357
+ if (!current?.numbering) return false;
4358
+ const currentKind = getListKind(document.numbering, current.numbering.numberingInstanceId);
4359
+ if (!currentKind) return false;
4360
+ for (let index = paragraphIndex - 1; index >= 0; index -= 1) {
4361
+ const previous = paragraphs[index]?.paragraph;
4362
+ if (!previous?.numbering) continue;
4363
+ const previousKind = getListKind(document.numbering, previous.numbering.numberingInstanceId);
4364
+ return previousKind === currentKind && previous.numbering.numberingInstanceId !== current.numbering.numberingInstanceId;
4365
+ }
4366
+ return false;
4367
+ }
4368
+ function canJoinPreviousSequence(document, paragraphIndex) {
4369
+ const paragraphs = collectParagraphEntries(document.content.children, "main");
4370
+ const current = paragraphs[paragraphIndex]?.paragraph;
4371
+ const previous = paragraphs[paragraphIndex - 1]?.paragraph;
4372
+ if (!current?.numbering || !previous?.numbering) return false;
4373
+ const currentKind = getListKind(document.numbering, current.numbering.numberingInstanceId);
4374
+ const previousKind = getListKind(document.numbering, previous.numbering.numberingInstanceId);
4375
+ return Boolean(currentKind) && currentKind === previousKind && current.numbering.numberingInstanceId !== previous.numbering.numberingInstanceId;
4376
+ }
4377
+ function unsupportedCommandBlocker(command, target) {
4378
+ return {
4379
+ code: "list-command-unsupported",
4380
+ ownerLayer: "L07",
4381
+ message: `runtime.lists.${command} is reserved but not implemented by the L07 command surface yet.`,
4382
+ ...target.targetKey !== void 0 ? { targetKey: target.targetKey } : {},
4383
+ ...target.addressKey !== void 0 ? { addressKey: target.addressKey } : {}
4384
+ };
4385
+ }
4386
+
3996
4387
  // src/api/v3/ai/_pe2-evidence.ts
3997
4388
  function copyCoverage(coverage) {
3998
4389
  return {
@@ -5720,6 +6111,17 @@ function createTableActionFamily(runtime) {
5720
6111
  operationScope: target.table?.operationScope
5721
6112
  });
5722
6113
  }
6114
+ if (fragmentContent && fragmentContent.blocks.length === 0) {
6115
+ return blockedResult(input, proposalId, {
6116
+ code: `table-action-structured-fragment-empty:${input.operation.kind}`,
6117
+ category: "unsupported-operation",
6118
+ message: "Structured table text actions require a canonical document fragment with at least one block.",
6119
+ nextStep: 'Retry with operation.content.kind="structured" and a CanonicalDocumentFragment whose blocks array contains the paragraph or table content to paste/drop.',
6120
+ actionHandle: input.actionHandle,
6121
+ operation: input.operation.kind,
6122
+ operationScope: target.table?.operationScope
6123
+ });
6124
+ }
5723
6125
  const resolution2 = resolveEditableTextTarget({
5724
6126
  document: runtime.getCanonicalDocument(),
5725
6127
  surface: runtime.getRenderSnapshot().surface?.blocks ?? [],
@@ -5742,6 +6144,7 @@ function createTableActionFamily(runtime) {
5742
6144
  runtime.dispatch({
5743
6145
  type: "fragment.insert",
5744
6146
  fragment: fragmentContent,
6147
+ selection: createSelectionSnapshot(resolution2.range.to, resolution2.range.to),
5745
6148
  editableTarget: target,
5746
6149
  origin: { source: "api", timestamp: nowUtc }
5747
6150
  });
@@ -5754,6 +6157,17 @@ function createTableActionFamily(runtime) {
5754
6157
  });
5755
6158
  }
5756
6159
  const changed2 = runtime.getCanonicalDocument() !== before2;
6160
+ if (!changed2) {
6161
+ return blockedResult(input, proposalId, {
6162
+ code: `table-action-noop:${input.operation.kind}:${input.actionHandle}`,
6163
+ category: "runtime-noop",
6164
+ message: "The runtime accepted the table text target but the operation produced no document change.",
6165
+ nextStep: "Refresh the table action list and verify the target is still editable, the payload is non-empty when required, and structured fragments are dispatched through a command-safe table text action.",
6166
+ actionHandle: input.actionHandle,
6167
+ operation: input.operation.kind,
6168
+ operationScope: target.table?.operationScope
6169
+ });
6170
+ }
5757
6171
  const afterReadback = tableTextReadback(readEditableTargetText(runtime.getCanonicalDocument(), target));
5758
6172
  return {
5759
6173
  proposalId,
@@ -6361,7 +6775,7 @@ var listOperationMetadata = actionMethodMetadata(
6361
6775
  "listOperation",
6362
6776
  "mutate",
6363
6777
  "actions-list-operation",
6364
- "Apply list toggle, indent, outdent, restart, or continue-numbering commands to paragraph-like scope handles.",
6778
+ "Apply list toggle, indent, outdent, restart, or continue-numbering commands through opaque list action handles or command-safe list scope targets.",
6365
6779
  {
6366
6780
  uiVisible: true,
6367
6781
  expectsUxResponse: "inline-change",
@@ -8096,25 +8510,16 @@ function checkPlanStepCapability(runtime, step, before) {
8096
8510
  return null;
8097
8511
  }
8098
8512
  if (step.kind === "listOperation") {
8099
- const resolved = resolveScopeExactTarget(runtime, step.target, step.kind);
8513
+ const resolved = resolveListOperationTarget(runtime, step.target);
8100
8514
  if (!resolved.ok) return resolved.blockerDetails[0] ?? null;
8101
- const scope = resolved.target.scope;
8102
- if (scope.kind !== "list-item" && scope.kind !== "paragraph" && scope.kind !== "heading") {
8103
- return blocker(
8104
- `actions:list-operation:target-kind-unsupported:${scope.kind}`,
8105
- "unsupported",
8106
- "List operations require a paragraph-like scope handle.",
8107
- "Use ai.actions.locateAll or ai.listScopes to select a paragraph, heading, or list-item handle."
8108
- );
8109
- }
8110
- if (paragraphIndexFromHandle(scope.handle) === null) {
8111
- return blockerWithOwner(
8112
- `actions:list-operation:paragraph-index-unresolved:${scope.handle.scopeId}`,
8113
- "blocked",
8114
- "The list operation target did not resolve to a current paragraph index.",
8115
- "Refresh the scope handle and retry; route persistent failures to L08 scope resolution.",
8116
- "L08 semantic scope compiler"
8117
- );
8515
+ const command = runtimeListCommandForOperation(step.operation);
8516
+ const preview = createListsFamily(runtime).previewCommand({
8517
+ ...resolved.input,
8518
+ command,
8519
+ ...step.operation.kind === "restart-numbering" && step.operation.startAt !== void 0 ? { startAt: step.operation.startAt } : {}
8520
+ });
8521
+ if (preview.blockers.length > 0) {
8522
+ return listBlockerDetails("actions:list-operation:preflight", preview.blockers)[0] ?? null;
8118
8523
  }
8119
8524
  return null;
8120
8525
  }
@@ -8271,70 +8676,253 @@ function applyModeledCommand(runtime, targetInput, kind, commandInput, reference
8271
8676
  };
8272
8677
  }
8273
8678
  function applyListOperation(runtime, input) {
8274
- const resolvedScope = resolveScopeExactTarget(runtime, input.target, "listOperation");
8275
- if (!resolvedScope.ok) return blockedApplyFromResolution(resolvedScope);
8679
+ const resolvedTarget = resolveListOperationTarget(runtime, input.target);
8680
+ if (!resolvedTarget.ok) return blockedApplyFromResolution(resolvedTarget);
8681
+ const command = runtimeListCommandForOperation(input.operation);
8682
+ const result = createListsFamily(runtime).applyCommand({
8683
+ ...resolvedTarget.input,
8684
+ command,
8685
+ ...input.operation.kind === "restart-numbering" && input.operation.startAt !== void 0 ? { startAt: input.operation.startAt } : {}
8686
+ });
8687
+ if (!result.applied) {
8688
+ const details = result.blockers.length > 0 ? listBlockerDetails("actions:list-operation", result.blockers) : [
8689
+ blockerWithOwner(
8690
+ `actions:list-operation:runtime-noop:${resolvedTarget.before?.addressKey ?? "unknown"}`,
8691
+ "blocked",
8692
+ "The runtime list command produced no document change for the selected list target.",
8693
+ "Refresh the list action handle and retry; route persistent failures with before/after readback to L07 runtime list commands.",
8694
+ "L07 runtime list commands"
8695
+ )
8696
+ ];
8697
+ return {
8698
+ status: details.some((detail) => detail.category === "unsupported") ? "unsupported" : "blocked",
8699
+ applied: false,
8700
+ changed: false,
8701
+ target: summarizeListTarget(resolvedTarget, result.before ?? resolvedTarget.before),
8702
+ blockers: Object.freeze(details.map((detail) => detail.code)),
8703
+ blockerDetails: Object.freeze(details),
8704
+ listReadback: listOperationReadback(result, resolvedTarget.before)
8705
+ };
8706
+ }
8707
+ const compiledAfter = resolvedTarget.scopeHandle ? createScopeCompilerService(runtime).compileScopeById(resolvedTarget.scopeHandle.scopeId) : null;
8708
+ const target = compiledAfter ? summarizeTarget({ kind: "scope", scope: compiledAfter.scope, handle: compiledAfter.scope.handle }) : summarizeListTarget(resolvedTarget, result.after ?? result.before ?? resolvedTarget.before);
8709
+ return {
8710
+ status: "applied",
8711
+ applied: true,
8712
+ changed: result.applied,
8713
+ target,
8714
+ commandReference: {
8715
+ command: commandReferenceForListCommand(result.command),
8716
+ actorId: input.actorId ?? "v3-ai-api",
8717
+ origin: input.origin ?? "agent",
8718
+ emittedAtUtc: currentAuditTimestamp(runtime)
8719
+ },
8720
+ listReadback: listOperationReadback(result, resolvedTarget.before)
8721
+ };
8722
+ }
8723
+ function resolveListOperationTarget(runtime, targetInput) {
8724
+ const lists = createListsFamily(runtime);
8725
+ if ("actionHandle" in targetInput) {
8726
+ const addressKey = listAddressKeyFromActionHandle(targetInput.actionHandle);
8727
+ if (!addressKey) {
8728
+ const detail = blockerWithOwner(
8729
+ `actions:list-operation:action-handle-malformed:${targetInput.actionHandle}`,
8730
+ "unsupported",
8731
+ "List operations require an opaque list action handle from runtime.lists or list editable-target evidence.",
8732
+ "Call runtime.lists.list or refresh the scope bundle and retry with a list-action:* or scope-command:text-leaf:* list handle.",
8733
+ "L07 runtime list commands and L08 semantic scopes"
8734
+ );
8735
+ return {
8736
+ ok: false,
8737
+ blockers: Object.freeze([detail.code]),
8738
+ blockerDetails: Object.freeze([detail])
8739
+ };
8740
+ }
8741
+ const before2 = lists.get({ addressKey });
8742
+ if (!before2) {
8743
+ const detail = blockerWithOwner(
8744
+ `actions:list-operation:action-handle-not-found:${targetInput.actionHandle}`,
8745
+ "unresolved-target",
8746
+ "No current list target matches the supplied opaque action handle.",
8747
+ "Refresh runtime.lists.list or the scope bundle, then retry with the current list action handle.",
8748
+ "L07 runtime list commands"
8749
+ );
8750
+ return {
8751
+ ok: false,
8752
+ blockers: Object.freeze([detail.code]),
8753
+ blockerDetails: Object.freeze([detail])
8754
+ };
8755
+ }
8756
+ return { ok: true, input: { addressKey }, before: before2 };
8757
+ }
8758
+ const resolvedScope = resolveScopeExactTarget(runtime, targetInput, "listOperation");
8759
+ if (!resolvedScope.ok) return resolvedScope;
8276
8760
  const scope = resolvedScope.target.scope;
8277
8761
  if (scope.kind !== "list-item" && scope.kind !== "paragraph" && scope.kind !== "heading") {
8278
- return blockedApply(
8762
+ const detail = blocker(
8279
8763
  `actions:list-operation:target-kind-unsupported:${scope.kind}`,
8280
8764
  "unsupported",
8281
- "List operations require a paragraph-like scope handle.",
8282
- "Use ai.actions.locateAll or ai.listScopes to select a paragraph, heading, or list-item handle."
8765
+ "List operations require a list item or command-safe paragraph-like scope target.",
8766
+ "Use ai.actions.locateAll, ai.listScopes, or runtime.lists.list to select a current list item target."
8283
8767
  );
8768
+ return {
8769
+ ok: false,
8770
+ blockers: Object.freeze([detail.code]),
8771
+ blockerDetails: Object.freeze([detail])
8772
+ };
8284
8773
  }
8285
- const paragraphIndex = paragraphIndexFromHandle(scope.handle);
8286
- if (paragraphIndex === null) {
8287
- return blockedApply(
8288
- `actions:list-operation:paragraph-index-unresolved:${scope.handle.scopeId}`,
8774
+ const bundle = createScopeCompilerService(runtime).compileBundleById(
8775
+ scope.handle.scopeId,
8776
+ currentAuditTimestamp(runtime)
8777
+ );
8778
+ const entries = bundle?.evidence.editableTargets?.entries ?? [];
8779
+ const listEntry = entries.find(
8780
+ (entry) => entry.commandFamily === "text-leaf" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("list-structure-action") && entry.runtimeCommand.canonicalAddress?.operationScope === "list-text" && entry.runtimeCommand.canonicalAddress.addressKind === "list-item-text"
8781
+ );
8782
+ if (!listEntry) {
8783
+ const detail = blockerWithOwner(
8784
+ `actions:list-operation:list-target-missing:${scope.handle.scopeId}`,
8289
8785
  "blocked",
8290
- "The list operation target did not resolve to a current paragraph index.",
8291
- "Refresh the scope handle and retry; route persistent failures to L08 scope resolution.",
8292
- [
8293
- blockerWithOwner(
8294
- `actions:list-operation:paragraph-index-unresolved:${scope.handle.scopeId}`,
8295
- "blocked",
8296
- "The list operation target did not resolve to a current paragraph index.",
8297
- "Refresh the scope handle and retry; route persistent failures to L08 scope resolution.",
8298
- "L08 semantic scope compiler"
8299
- )
8300
- ]
8786
+ "The selected scope does not expose a command-safe list structure target.",
8787
+ "Refresh the scope bundle and route missing list editable-target evidence to L08/L07; do not derive a paragraph index from the scope handle.",
8788
+ "L08 semantic scopes and L07 runtime list commands"
8301
8789
  );
8790
+ return {
8791
+ ok: false,
8792
+ blockers: Object.freeze([detail.code]),
8793
+ blockerDetails: Object.freeze([detail])
8794
+ };
8302
8795
  }
8303
- const command = listCommandForOperation(input.operation, paragraphIndex, actionOrigin(runtime, input));
8304
- const before = runtime.getCanonicalDocument();
8305
- runtime.dispatch(command);
8306
- const changed = runtime.getCanonicalDocument() !== before;
8307
- if (!changed) {
8308
- return blockedApply(
8309
- `actions:list-operation:runtime-noop:${scope.handle.scopeId}`,
8796
+ const currentTarget = collectEditableTargetRefs(runtime.getCanonicalDocument()).find(
8797
+ (target) => target.targetKey === listEntry.targetKey || target.listAddress?.addressKey === listEntry.runtimeCommand.canonicalAddress?.addressKey
8798
+ );
8799
+ if (!currentTarget) {
8800
+ const detail = blockerWithOwner(
8801
+ `actions:list-operation:list-target-not-current:${scope.handle.scopeId}`,
8802
+ "unresolved-target",
8803
+ "The list editable target evidence is stale in the current document.",
8804
+ "Refresh the scope bundle and retry with the current opaque list target.",
8805
+ "L08 semantic scopes and L07 runtime list commands"
8806
+ );
8807
+ return {
8808
+ ok: false,
8809
+ blockers: Object.freeze([detail.code]),
8810
+ blockerDetails: Object.freeze([detail])
8811
+ };
8812
+ }
8813
+ const before = lists.get({ editableTarget: currentTarget });
8814
+ if (!before) {
8815
+ const detail = blockerWithOwner(
8816
+ `actions:list-operation:list-readback-missing:${scope.handle.scopeId}`,
8310
8817
  "blocked",
8311
- "The list runtime command produced no document change for the selected scope.",
8312
- "Select a list-compatible paragraph and retry, or route to L03/L07 list command support with the scope handle.",
8313
- [
8314
- blockerWithOwner(
8315
- `actions:list-operation:runtime-noop:${scope.handle.scopeId}`,
8316
- "blocked",
8317
- "The list runtime command produced no document change for the selected scope.",
8318
- "Select a list-compatible paragraph and retry, or route to L03/L07 list command support with the scope handle.",
8319
- "L03 numbering/list semantics and L07 runtime list commands"
8320
- )
8321
- ]
8818
+ "The list target was present in scope evidence but runtime.lists could not produce readback.",
8819
+ "Route the target with editable-target evidence to L07 runtime list readback.",
8820
+ "L07 runtime list commands"
8322
8821
  );
8822
+ return {
8823
+ ok: false,
8824
+ blockers: Object.freeze([detail.code]),
8825
+ blockerDetails: Object.freeze([detail])
8826
+ };
8323
8827
  }
8324
- const compiledAfter = createScopeCompilerService(runtime).compileScopeById(scope.handle.scopeId);
8325
8828
  return {
8326
- status: "applied",
8327
- applied: true,
8328
- changed: true,
8329
- target: compiledAfter ? summarizeTarget({ kind: "scope", scope: compiledAfter.scope, handle: compiledAfter.scope.handle }) : summarizeTarget(resolvedScope.target),
8330
- commandReference: {
8331
- command: command.type,
8332
- actorId: input.actorId ?? "v3-ai-api",
8333
- origin: input.origin ?? "agent",
8334
- emittedAtUtc: command.origin?.timestamp ?? currentAuditTimestamp(runtime)
8335
- }
8829
+ ok: true,
8830
+ input: { editableTarget: currentTarget },
8831
+ before,
8832
+ scopeHandle: scope.handle
8336
8833
  };
8337
8834
  }
8835
+ function listAddressKeyFromActionHandle(actionHandle) {
8836
+ const listPrefix = "list-action:";
8837
+ if (actionHandle.startsWith(listPrefix)) return actionHandle.slice(listPrefix.length) || null;
8838
+ const scopeCommandPrefix = "scope-command:text-leaf:";
8839
+ if (actionHandle.startsWith(scopeCommandPrefix)) {
8840
+ return actionHandle.slice(scopeCommandPrefix.length) || null;
8841
+ }
8842
+ return null;
8843
+ }
8844
+ function runtimeListCommandForOperation(operation) {
8845
+ switch (operation.kind) {
8846
+ case "toggle":
8847
+ return operation.listKind === "numbered" ? "toggle-numbered" : "toggle-bulleted";
8848
+ case "indent":
8849
+ return "indent";
8850
+ case "outdent":
8851
+ return "outdent";
8852
+ case "restart-numbering":
8853
+ return "restart-numbering";
8854
+ case "continue-numbering":
8855
+ return "continue-numbering";
8856
+ }
8857
+ }
8858
+ function commandReferenceForListCommand(command) {
8859
+ switch (command) {
8860
+ case "toggle-numbered":
8861
+ case "toggle-bulleted":
8862
+ return "list.toggle";
8863
+ case "indent":
8864
+ return "list.indent";
8865
+ case "outdent":
8866
+ return "list.outdent";
8867
+ case "restart-numbering":
8868
+ return "list.restart-numbering";
8869
+ case "continue-numbering":
8870
+ return "list.continue-numbering";
8871
+ default:
8872
+ return "list.toggle";
8873
+ }
8874
+ }
8875
+ function listOperationReadback(result, fallbackBefore) {
8876
+ const before = sanitizeListReadback(result.before ?? fallbackBefore);
8877
+ const after = sanitizeListReadback(result.after);
8878
+ return {
8879
+ ...before ? { before } : {},
8880
+ ...after ? { after } : {}
8881
+ };
8882
+ }
8883
+ function sanitizeListReadback(readback) {
8884
+ if (!readback) return void 0;
8885
+ return {
8886
+ actionHandle: readback.actionHandle,
8887
+ kind: readback.kind,
8888
+ storyKey: readback.storyKey,
8889
+ addressKey: readback.addressKey,
8890
+ numberingInstanceId: readback.numberingInstanceId,
8891
+ ...readback.abstractNumberingId ? { abstractNumberingId: readback.abstractNumberingId } : {},
8892
+ level: readback.level,
8893
+ ...readback.listKind ? { listKind: readback.listKind } : {},
8894
+ editability: readback.editability,
8895
+ blockers: readback.blockers,
8896
+ supportedCommands: readback.supportedCommands,
8897
+ unsupportedCommands: readback.unsupportedCommands,
8898
+ staleDiscriminators: readback.staleDiscriminators
8899
+ };
8900
+ }
8901
+ function summarizeListTarget(target, readback) {
8902
+ const current = readback ?? target.before;
8903
+ return {
8904
+ kind: "list-item",
8905
+ ...target.scopeHandle ? { handle: target.scopeHandle } : {},
8906
+ ...current?.actionHandle ? { actionHandle: current.actionHandle } : {},
8907
+ canRewriteText: current?.editability === "editable" && (current.blockers.length ?? 0) === 0,
8908
+ canInsertAdjacentText: false,
8909
+ canFlag: Boolean(target.scopeHandle),
8910
+ canMark: Boolean(target.scopeHandle)
8911
+ };
8912
+ }
8913
+ function listBlockerDetails(prefix, blockers) {
8914
+ return Object.freeze(
8915
+ blockers.map(
8916
+ (entry) => blockerWithOwner(
8917
+ `${prefix}:${entry.code}:${entry.addressKey ?? entry.targetKey ?? "unknown"}`,
8918
+ entry.code === "list-command-unsupported" ? "unsupported" : "blocked",
8919
+ entry.message,
8920
+ "Refresh the opaque list target/readback and route persistent blockers to the owning runtime list layer.",
8921
+ entry.ownerLayer === "L07" ? "L07 runtime list commands" : entry.ownerLayer
8922
+ )
8923
+ )
8924
+ );
8925
+ }
8338
8926
  function projectTableApplyResult(result) {
8339
8927
  return {
8340
8928
  status: result.applied ? "applied" : "blocked",
@@ -8462,36 +9050,6 @@ function tableSelectionStepHasDescriptor(operation) {
8462
9050
  operation && "selectionDescriptor" in operation && operation.selectionDescriptor
8463
9051
  );
8464
9052
  }
8465
- function listCommandForOperation(operation, paragraphIndex, origin) {
8466
- switch (operation.kind) {
8467
- case "toggle":
8468
- return {
8469
- type: "list.toggle",
8470
- kind: operation.listKind,
8471
- paragraphIndexes: [paragraphIndex],
8472
- origin
8473
- };
8474
- case "indent":
8475
- return { type: "list.indent", paragraphIndexes: [paragraphIndex], origin };
8476
- case "outdent":
8477
- return { type: "list.outdent", paragraphIndexes: [paragraphIndex], origin };
8478
- case "restart-numbering":
8479
- return {
8480
- type: "list.restart-numbering",
8481
- paragraphIndex,
8482
- ...operation.startAt !== void 0 ? { startAt: operation.startAt } : {},
8483
- origin
8484
- };
8485
- case "continue-numbering":
8486
- return { type: "list.continue-numbering", paragraphIndex, origin };
8487
- }
8488
- }
8489
- function paragraphIndexFromHandle(handle) {
8490
- const raw = handle.semanticPath[handle.semanticPath.length - 1];
8491
- if (raw === void 0) return null;
8492
- const index = Number(raw);
8493
- return Number.isSafeInteger(index) && index >= 0 ? index : null;
8494
- }
8495
9053
  function actionOrigin(runtime, input) {
8496
9054
  return { source: "api", timestamp: currentAuditTimestamp(runtime) };
8497
9055
  }
@@ -8856,7 +9414,8 @@ function createApiV3(handle, opts) {
8856
9414
  chart: createChartFamily(handle),
8857
9415
  search: createSearchFamily(handle),
8858
9416
  table: createTableFamily(handle),
8859
- viewport: createViewportFamily(handle)
9417
+ viewport: createViewportFamily(handle),
9418
+ lists: createListsFamily(handle)
8860
9419
  };
8861
9420
  const ui = opts?.ui ? createUiApi(handle, opts.ui) : void 0;
8862
9421
  const api = ui ? { runtime, ai, ui } : { runtime, ai };