@beyondwork/docx-react-component 1.0.133 → 1.0.134

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 (70) hide show
  1. package/dist/api/public-types.cjs +3 -1
  2. package/dist/api/public-types.d.cts +1 -1
  3. package/dist/api/public-types.d.ts +1 -1
  4. package/dist/api/public-types.js +1 -1
  5. package/dist/api/v3.cjs +688 -45
  6. package/dist/api/v3.d.cts +2 -2
  7. package/dist/api/v3.d.ts +2 -2
  8. package/dist/api/v3.js +3 -3
  9. package/dist/{chunk-S3PEKX6H.js → chunk-3YR47WTD.js} +53 -547
  10. package/dist/{chunk-57HTKX3P.js → chunk-74R5B2EZ.js} +1 -1
  11. package/dist/{chunk-KL4TZSZV.js → chunk-7Y6JCIK3.js} +1 -1
  12. package/dist/{chunk-3JEE5RJU.js → chunk-EBSI6VQX.js} +457 -16
  13. package/dist/{chunk-OTRVGNZQ.js → chunk-ESEEWELA.js} +547 -2
  14. package/dist/{chunk-224TSMEB.js → chunk-IJD6D7HU.js} +137 -41
  15. package/dist/{chunk-CVSD3UNK.js → chunk-O4EDZR44.js} +3 -1
  16. package/dist/{chunk-ZFCZ7XXH.js → chunk-VA24T4EB.js} +1 -1
  17. package/dist/core/commands/formatting-commands.d.cts +1 -1
  18. package/dist/core/commands/formatting-commands.d.ts +1 -1
  19. package/dist/core/commands/image-commands.d.cts +1 -1
  20. package/dist/core/commands/image-commands.d.ts +1 -1
  21. package/dist/core/commands/section-layout-commands.d.cts +1 -1
  22. package/dist/core/commands/section-layout-commands.d.ts +1 -1
  23. package/dist/core/commands/style-commands.d.cts +1 -1
  24. package/dist/core/commands/style-commands.d.ts +1 -1
  25. package/dist/core/commands/table-structure-commands.d.cts +1 -1
  26. package/dist/core/commands/table-structure-commands.d.ts +1 -1
  27. package/dist/core/commands/text-commands.d.cts +1 -1
  28. package/dist/core/commands/text-commands.d.ts +1 -1
  29. package/dist/core/selection/mapping.d.cts +1 -1
  30. package/dist/core/selection/mapping.d.ts +1 -1
  31. package/dist/core/state/editor-state.d.cts +1 -1
  32. package/dist/core/state/editor-state.d.ts +1 -1
  33. package/dist/index.cjs +1289 -615
  34. package/dist/index.d.cts +4 -4
  35. package/dist/index.d.ts +4 -4
  36. package/dist/index.js +105 -19
  37. package/dist/io/docx-session.d.cts +3 -3
  38. package/dist/io/docx-session.d.ts +3 -3
  39. package/dist/{loader-B2H99237.d.cts → loader-CK3lZy4h.d.cts} +2 -2
  40. package/dist/{loader-DfTjqVwn.d.ts → loader-CQXplstv.d.ts} +2 -2
  41. package/dist/{public-types-S8gTYwKo.d.cts → public-types-BR1SYK2F.d.cts} +140 -3
  42. package/dist/{public-types-B5lOUIrP.d.ts → public-types-DXNZVKrS.d.ts} +140 -3
  43. package/dist/public-types.cjs +3 -1
  44. package/dist/public-types.d.cts +1 -1
  45. package/dist/public-types.d.ts +1 -1
  46. package/dist/public-types.js +1 -1
  47. package/dist/runtime/collab.d.cts +2 -2
  48. package/dist/runtime/collab.d.ts +2 -2
  49. package/dist/runtime/document-runtime.cjs +591 -54
  50. package/dist/runtime/document-runtime.d.cts +1 -1
  51. package/dist/runtime/document-runtime.d.ts +1 -1
  52. package/dist/runtime/document-runtime.js +4 -4
  53. package/dist/{session-CBDIOYXA.d.ts → session-C9UjrhJF.d.ts} +2 -2
  54. package/dist/{session-CR2A1hGZ.d.cts → session-CSbwkgII.d.cts} +2 -2
  55. package/dist/session.d.cts +4 -4
  56. package/dist/session.d.ts +4 -4
  57. package/dist/tailwind.cjs +54 -546
  58. package/dist/tailwind.d.cts +1 -1
  59. package/dist/tailwind.d.ts +1 -1
  60. package/dist/tailwind.js +4 -4
  61. package/dist/{types-yty2K-hk.d.cts → types-CZtAueri.d.cts} +1 -1
  62. package/dist/{types-B-90ywjU.d.ts → types-RzkCXDNV.d.ts} +1 -1
  63. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +2 -2
  64. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +2 -2
  65. package/dist/ui-tailwind/editor-surface/search-plugin.js +2 -2
  66. package/dist/ui-tailwind.cjs +54 -546
  67. package/dist/ui-tailwind.d.cts +2 -2
  68. package/dist/ui-tailwind.d.ts +2 -2
  69. package/dist/ui-tailwind.js +4 -4
  70. package/package.json +1 -1
@@ -18,7 +18,7 @@ import {
18
18
  resolveScopeRange,
19
19
  scopeSpecificity,
20
20
  searchDocument
21
- } from "./chunk-224TSMEB.js";
21
+ } from "./chunk-IJD6D7HU.js";
22
22
  import {
23
23
  BROADCAST_COMMAND_TYPES,
24
24
  COMMAND_EVENT_SCHEMA_VERSION,
@@ -37,7 +37,7 @@ import {
37
37
  LAYCACHE_SCHEMA_VERSION,
38
38
  LAYOUT_ENGINE_VERSION,
39
39
  createScopeTagRegistry
40
- } from "./chunk-CVSD3UNK.js";
40
+ } from "./chunk-O4EDZR44.js";
41
41
  import {
42
42
  chartModelStore,
43
43
  createEditorSurfaceSnapshot,
@@ -7224,6 +7224,216 @@ function createOutlineFamily(runtime) {
7224
7224
  };
7225
7225
  }
7226
7226
 
7227
+ // src/api/v3/ai/object.ts
7228
+ var applyObjectActionMetadata = {
7229
+ name: "ai.applyObjectAction",
7230
+ status: "live-with-adapter",
7231
+ sourceLayer: "runtime-core",
7232
+ liveEvidence: {
7233
+ runnerTest: "test/api/v3/ai/ai-object-actions.test.ts",
7234
+ commit: "refactor-09-object-actions"
7235
+ },
7236
+ uxIntent: {
7237
+ uiVisible: true,
7238
+ expectsUxResponse: "inline-change",
7239
+ expectedDelta: "image object layout changes"
7240
+ },
7241
+ agentMetadata: {
7242
+ readOrMutate: "mutate",
7243
+ boundedScope: "scope",
7244
+ auditCategory: "object-action-apply",
7245
+ contextPromptShape: "Apply an image object layout operation to an opaque actionHandle from ai.listObjectActions; preserve-only objects return typed blockers."
7246
+ },
7247
+ stateClass: "A-canonical",
7248
+ persistsTo: "canonical",
7249
+ broadcastsVia: "crdt",
7250
+ rwdReference: "\xA7AI API \xA7 ai.applyObjectAction"
7251
+ };
7252
+ function createObjectActionFamily(runtime) {
7253
+ const compiler = createScopeCompilerService(runtime);
7254
+ return {
7255
+ listObjectActions(input) {
7256
+ const bundle = compiler.compileBundleById(input.handle.scopeId, input.nowUtc);
7257
+ if (!bundle) {
7258
+ return {
7259
+ scopeId: input.handle.scopeId,
7260
+ actions: [],
7261
+ blockers: [`scope-not-resolvable:${input.handle.scopeId}`]
7262
+ };
7263
+ }
7264
+ const seed = documentSeed2(runtime);
7265
+ return {
7266
+ scopeId: input.handle.scopeId,
7267
+ actions: bundle.evidence.editableTargets?.entries.filter(isSupportedImageObjectEvidence).map((entry) => projectObjectDescriptor(runtime, seed, entry)) ?? []
7268
+ };
7269
+ },
7270
+ applyObjectAction(input) {
7271
+ emitUxResponse(runtime, {
7272
+ apiFn: applyObjectActionMetadata.name,
7273
+ intent: "object-action-apply",
7274
+ mockOrLive: applyObjectActionMetadata.status,
7275
+ uiVisible: true,
7276
+ expectedDelta: applyObjectActionMetadata.uxIntent.expectedDelta
7277
+ });
7278
+ const nowUtc = currentAuditTimestamp(runtime);
7279
+ const proposalId = input.proposalId ?? mockId(documentSeed2(runtime), `object-action-${input.actionHandle || "missing-handle"}-${input.operation.kind}`);
7280
+ if (!input.actionHandle) {
7281
+ return blockedResult2(input, proposalId, {
7282
+ code: "object-action-handle-required",
7283
+ category: "unresolved-target",
7284
+ message: "Object actions require an actionHandle from ai.listObjectActions.",
7285
+ nextStep: "Call ai.listObjectActions for the owning scope and retry with one returned actionHandle.",
7286
+ operation: input.operation.kind
7287
+ });
7288
+ }
7289
+ const target = resolveObjectActionHandle(runtime, documentSeed2(runtime), input.actionHandle);
7290
+ if (!target) {
7291
+ return blockedResult2(input, proposalId, {
7292
+ code: `object-action-handle-not-found:${input.actionHandle}`,
7293
+ category: "unresolved-target",
7294
+ message: "No current object action matches the supplied opaque action handle.",
7295
+ nextStep: "Refresh the scope bundle or call ai.listObjectActions before retrying.",
7296
+ actionHandle: input.actionHandle,
7297
+ operation: input.operation.kind
7298
+ });
7299
+ }
7300
+ if (!isSupportedImageTarget(target)) {
7301
+ return blockedResult2(input, proposalId, {
7302
+ code: "object-action-image-target-required",
7303
+ category: "blocked-target",
7304
+ message: "The supplied object action handle no longer identifies a mutable image target.",
7305
+ nextStep: "Refresh object actions; chart, OLE, custom XML, opaque, and stale object targets remain refused.",
7306
+ actionHandle: input.actionHandle,
7307
+ operation: input.operation.kind
7308
+ });
7309
+ }
7310
+ const mediaId = target.object?.mediaId;
7311
+ if (!mediaId) {
7312
+ return blockedResult2(input, proposalId, {
7313
+ code: "object-action-media-id-required",
7314
+ category: "blocked-target",
7315
+ message: "Image object layout mutation requires a mediaId-backed target.",
7316
+ nextStep: "Retry only with an image action handle whose readback includes mediaId.",
7317
+ actionHandle: input.actionHandle,
7318
+ operation: input.operation.kind
7319
+ });
7320
+ }
7321
+ const before = runtime.getCanonicalDocument();
7322
+ runtime.dispatch({
7323
+ type: "image.set-layout",
7324
+ mediaId,
7325
+ dimensions: {
7326
+ widthEmu: input.operation.dimensions.widthEmu,
7327
+ heightEmu: input.operation.dimensions.heightEmu
7328
+ },
7329
+ origin: { source: "api", timestamp: nowUtc }
7330
+ });
7331
+ const changed = runtime.getCanonicalDocument() !== before;
7332
+ if (!changed) {
7333
+ return blockedResult2(input, proposalId, {
7334
+ code: `object-action-noop:${input.operation.kind}:${input.actionHandle}`,
7335
+ category: "runtime-noop",
7336
+ message: "The runtime accepted the image target but the object operation produced no document change.",
7337
+ nextStep: "Refresh object actions and verify the image media item still exists before retrying.",
7338
+ actionHandle: input.actionHandle,
7339
+ operation: input.operation.kind
7340
+ });
7341
+ }
7342
+ return {
7343
+ proposalId,
7344
+ applied: true,
7345
+ changed: true,
7346
+ actionHandle: input.actionHandle,
7347
+ operation: input.operation.kind,
7348
+ commandReference: {
7349
+ command: "image.set-layout",
7350
+ actorId: input.actorId ?? "v3-ai-api",
7351
+ origin: input.origin ?? "agent",
7352
+ emittedAtUtc: nowUtc
7353
+ },
7354
+ readback: objectReadback(runtime, target),
7355
+ posture: "supported",
7356
+ support: objectActionSupport()
7357
+ };
7358
+ }
7359
+ };
7360
+ }
7361
+ function isSupportedImageObjectEvidence(entry) {
7362
+ return entry.kind === "object-anchor" && entry.commandFamily === "object" && entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.includes("image-layout") && isImageKind(entry.object?.objectKind) && typeof entry.object?.mediaId === "string";
7363
+ }
7364
+ function projectObjectDescriptor(runtime, seed, entry) {
7365
+ return {
7366
+ actionHandle: objectActionHandle(seed, entry.targetKey),
7367
+ objectKind: entry.object?.objectKind ?? "unknown",
7368
+ targetKind: entry.kind,
7369
+ relation: entry.relation,
7370
+ callableOperations: ["set-image-layout"],
7371
+ supportedOperations: ["set-image-layout"],
7372
+ readback: objectReadback(runtime, entry),
7373
+ reason: entry.runtimeCommand.reason
7374
+ };
7375
+ }
7376
+ function resolveObjectActionHandle(runtime, seed, actionHandle) {
7377
+ return collectEditableTargetRefs(runtime.getCanonicalDocument()).find(
7378
+ (target) => objectActionHandle(seed, target.targetKey) === actionHandle && isSupportedImageTarget(target)
7379
+ ) ?? null;
7380
+ }
7381
+ function isSupportedImageTarget(target) {
7382
+ return target.kind === "object-anchor" && target.commandFamily === "object" && isImageKind(target.object?.objectKind) && typeof target.object?.mediaId === "string" && target.object.mediaId.length > 0 && onlyObjectActionBlockers(target.posture.blockers, ["unmodeled-target"]);
7383
+ }
7384
+ function isImageKind(kind) {
7385
+ return kind === "legacy-image" || kind === "picture";
7386
+ }
7387
+ function onlyObjectActionBlockers(blockers, allowed) {
7388
+ const allowedSet = new Set(allowed);
7389
+ return blockers.every((blocker2) => allowedSet.has(blocker2));
7390
+ }
7391
+ function objectReadback(runtime, target) {
7392
+ const mediaId = target.object?.mediaId;
7393
+ if (!mediaId) return {};
7394
+ const media = runtime.getCanonicalDocument().media.items[mediaId];
7395
+ return {
7396
+ mediaId,
7397
+ ...media?.widthEmu !== void 0 ? { widthEmu: media.widthEmu } : {},
7398
+ ...media?.heightEmu !== void 0 ? { heightEmu: media.heightEmu } : {}
7399
+ };
7400
+ }
7401
+ function blockedResult2(input, proposalId, detail) {
7402
+ return {
7403
+ proposalId,
7404
+ applied: false,
7405
+ changed: false,
7406
+ actionHandle: input.actionHandle,
7407
+ operation: input.operation.kind,
7408
+ reason: detail.code,
7409
+ blockers: [detail.code],
7410
+ blockerDetails: [detail]
7411
+ };
7412
+ }
7413
+ function objectActionSupport() {
7414
+ return {
7415
+ undo: "supported",
7416
+ replay: "supported",
7417
+ exportReopen: "supported",
7418
+ audit: "command-reference"
7419
+ };
7420
+ }
7421
+ function objectActionHandle(seed, targetKey) {
7422
+ return `object-action:${hashOpaque2(`${seed}::${targetKey}`)}`;
7423
+ }
7424
+ function documentSeed2(runtime) {
7425
+ const state = runtime.getSessionState();
7426
+ return state.documentId ?? "document";
7427
+ }
7428
+ function hashOpaque2(input) {
7429
+ let h = 2166136261;
7430
+ for (let i = 0; i < input.length; i += 1) {
7431
+ h ^= input.charCodeAt(i);
7432
+ h = Math.imul(h, 16777619);
7433
+ }
7434
+ return (h >>> 0).toString(36).padStart(7, "0");
7435
+ }
7436
+
7227
7437
  // src/api/v3/ai/actions.ts
7228
7438
  function actionMethodMetadata(method, readOrMutate, auditCategory, contextPromptShape, uxIntent) {
7229
7439
  return {
@@ -7268,6 +7478,17 @@ var locateAllMetadata = actionMethodMetadata(
7268
7478
  "Find scope/table-text targets by query; table text matches include readback {text,isEmpty}.",
7269
7479
  { uiVisible: false, expectsUxResponse: "none" }
7270
7480
  );
7481
+ var createPlaceholderScopesMetadata = actionMethodMetadata(
7482
+ "createPlaceholderScopes",
7483
+ "mutate",
7484
+ "actions-placeholder-scopes",
7485
+ "Create marker-backed workflow scopes for bracketed placeholder matches in paragraphs, tables, and lists using one bounded regex search.",
7486
+ {
7487
+ uiVisible: true,
7488
+ expectsUxResponse: "scope-created",
7489
+ expectedDelta: "placeholder text ranges become workflow scopes"
7490
+ }
7491
+ );
7271
7492
  var rewriteMetadata = actionMethodMetadata(
7272
7493
  "rewrite",
7273
7494
  "mutate",
@@ -7480,6 +7701,7 @@ var ACTION_METHODS = Object.freeze([
7480
7701
  "discover",
7481
7702
  "locate",
7482
7703
  "locateAll",
7704
+ "createPlaceholderScopes",
7483
7705
  "rewrite",
7484
7706
  "rewriteAll",
7485
7707
  "insertText",
@@ -7505,6 +7727,8 @@ var DEFAULT_LOCATE_LIMIT = 20;
7505
7727
  var DEFAULT_REWRITE_ALL_LIMIT = 10;
7506
7728
  var DEFAULT_TABLE_TEXT_SCOPE_LIMIT = 3;
7507
7729
  var DEFAULT_PLAN_STEP_LIMIT = 20;
7730
+ var DEFAULT_PLACEHOLDER_QUERY = "\\[[^\\[\\]]{1,200}\\]";
7731
+ var DEFAULT_PLACEHOLDER_LIMIT = 200;
7508
7732
  function createActionsFamily(runtime) {
7509
7733
  const category = {
7510
7734
  discover(input) {
@@ -7559,6 +7783,9 @@ function createActionsFamily(runtime) {
7559
7783
  locateAll(input) {
7560
7784
  return locateAll(runtime, input);
7561
7785
  },
7786
+ createPlaceholderScopes(input) {
7787
+ return createPlaceholderScopes(runtime, input ?? {});
7788
+ },
7562
7789
  rewrite(input) {
7563
7790
  if (input.text === void 0) {
7564
7791
  return blockedApply(
@@ -8327,6 +8554,169 @@ function locateAll(runtime, input) {
8327
8554
  ...matches.length === 0 ? { blockers: Object.freeze([`actions:locate:not-found:${input.query}`]) } : {}
8328
8555
  };
8329
8556
  }
8557
+ function createPlaceholderScopes(runtime, input) {
8558
+ const query = input.query ?? DEFAULT_PLACEHOLDER_QUERY;
8559
+ if (!query) {
8560
+ const detail = blocker(
8561
+ "actions:placeholder-scopes:query-required",
8562
+ "input",
8563
+ "Placeholder scope creation requires a non-empty query.",
8564
+ "Retry with a non-empty query string or omit query to use the bracketed-placeholder default."
8565
+ );
8566
+ return {
8567
+ status: "blocked",
8568
+ totalHits: 0,
8569
+ created: 0,
8570
+ blocked: 0,
8571
+ scopes: Object.freeze([]),
8572
+ blockers: Object.freeze([detail.code]),
8573
+ blockerDetails: Object.freeze([detail])
8574
+ };
8575
+ }
8576
+ const limit = Math.max(0, input.limit ?? DEFAULT_PLACEHOLDER_LIMIT);
8577
+ let hits;
8578
+ try {
8579
+ hits = runtime.findAllText(query, {
8580
+ regex: input.regex ?? true,
8581
+ matchCase: input.matchCase ?? true,
8582
+ limit
8583
+ });
8584
+ } catch {
8585
+ const detail = blocker(
8586
+ "actions:placeholder-scopes:invalid-query",
8587
+ "input",
8588
+ "The placeholder query could not be compiled or searched.",
8589
+ "Retry with a valid literal query or JavaScript regex pattern."
8590
+ );
8591
+ return {
8592
+ status: "blocked",
8593
+ totalHits: 0,
8594
+ created: 0,
8595
+ blocked: 0,
8596
+ scopes: Object.freeze([]),
8597
+ blockers: Object.freeze([detail.code]),
8598
+ blockerDetails: Object.freeze([detail])
8599
+ };
8600
+ }
8601
+ if (hits.length === 0) {
8602
+ return {
8603
+ status: "not-found",
8604
+ totalHits: 0,
8605
+ created: 0,
8606
+ blocked: 0,
8607
+ scopes: Object.freeze([]),
8608
+ blockers: Object.freeze([`actions:placeholder-scopes:not-found:${query}`])
8609
+ };
8610
+ }
8611
+ const surface = runtime.getRenderSnapshot().surface;
8612
+ const orderedHits = hits.filter((hit) => hit.kind === "range").map((hit, originalIndex) => ({
8613
+ hit,
8614
+ originalIndex,
8615
+ text: surface ? textForSurfaceRange(surface.blocks, hit.from, hit.to) : ""
8616
+ })).sort((a, b) => b.hit.from - a.hit.from || b.originalIndex - a.originalIndex);
8617
+ if (orderedHits.length === 0) {
8618
+ const detail = blocker(
8619
+ "actions:placeholder-scopes:no-range-hits",
8620
+ "unsupported",
8621
+ "The placeholder query matched only projections that cannot be converted into workflow ranges.",
8622
+ "Retry with a text query that resolves to concrete document text ranges."
8623
+ );
8624
+ return {
8625
+ status: "blocked",
8626
+ totalHits: hits.length,
8627
+ created: 0,
8628
+ blocked: hits.length,
8629
+ scopes: Object.freeze([]),
8630
+ blockers: Object.freeze([detail.code]),
8631
+ blockerDetails: Object.freeze([detail])
8632
+ };
8633
+ }
8634
+ const compiler = createScopeCompilerService(runtime);
8635
+ const byOriginalIndex = /* @__PURE__ */ new Map();
8636
+ for (const item of orderedHits) {
8637
+ const text = item.text || query;
8638
+ const label = input.labelPrefix === void 0 ? text : `${input.labelPrefix} ${item.originalIndex + 1}`;
8639
+ const result = createScopeFromAnchor(runtime, {
8640
+ anchor: { from: item.hit.from, to: item.hit.to },
8641
+ mode: input.mode ?? "edit",
8642
+ label,
8643
+ ...input.visibility ? { visibility: input.visibility } : {},
8644
+ ...input.guardPolicy ? { guardPolicy: input.guardPolicy } : {},
8645
+ ...input.assoc ? { assoc: input.assoc } : {},
8646
+ ...input.stableRefHint ? { stableRefHint: input.stableRefHint } : {}
8647
+ });
8648
+ if (result.status === "created") {
8649
+ const compiled = compiler.compileScopeById(result.scopeId)?.scope;
8650
+ byOriginalIndex.set(item.originalIndex, {
8651
+ status: "created",
8652
+ text,
8653
+ excerpt: excerpt(text),
8654
+ scopeId: result.scopeId,
8655
+ ...compiled?.handle ? { handle: compiled.handle } : {}
8656
+ });
8657
+ continue;
8658
+ }
8659
+ const detail = blockerWithOwner(
8660
+ `actions:placeholder-scopes:create-refused:${result.reason}`,
8661
+ "blocked",
8662
+ "The placeholder match could not be converted into a workflow scope.",
8663
+ "Refresh the document and retry; if it still refuses, route the target to the workflow/scope writer owner.",
8664
+ "L06"
8665
+ );
8666
+ byOriginalIndex.set(item.originalIndex, {
8667
+ status: "blocked",
8668
+ text,
8669
+ excerpt: excerpt(text),
8670
+ blockers: Object.freeze([detail.code]),
8671
+ blockerDetails: Object.freeze([detail])
8672
+ });
8673
+ }
8674
+ const scopes = orderedHits.map((item) => byOriginalIndex.get(item.originalIndex)).filter((value) => value !== void 0);
8675
+ const created = scopes.filter((scope) => scope.status === "created").length;
8676
+ const blocked = scopes.length - created;
8677
+ const blockerDetails = scopes.flatMap((scope) => scope.blockerDetails ?? []);
8678
+ return {
8679
+ status: created === scopes.length ? "created" : created > 0 ? "partial" : "blocked",
8680
+ totalHits: hits.length,
8681
+ created,
8682
+ blocked,
8683
+ scopes: Object.freeze(scopes),
8684
+ ...blockerDetails.length > 0 ? {
8685
+ blockers: Object.freeze(blockerDetails.map((detail) => detail.code)),
8686
+ blockerDetails: Object.freeze(blockerDetails)
8687
+ } : {}
8688
+ };
8689
+ }
8690
+ function textForSurfaceRange(blocks, from, to) {
8691
+ let acc = "";
8692
+ const visit = (items) => {
8693
+ for (const block of items) {
8694
+ if (block.kind === "paragraph") {
8695
+ for (const segment of block.segments) {
8696
+ if (segment.kind !== "text") continue;
8697
+ if (segment.from >= to) return;
8698
+ if (segment.to <= from) continue;
8699
+ acc += segment.text.slice(
8700
+ Math.max(0, from - segment.from),
8701
+ Math.min(segment.text.length, to - segment.from)
8702
+ );
8703
+ }
8704
+ continue;
8705
+ }
8706
+ if (block.kind === "table") {
8707
+ for (const row of block.rows) {
8708
+ for (const cell of row.cells) visit(cell.content);
8709
+ }
8710
+ continue;
8711
+ }
8712
+ if (block.kind === "sdt_block") {
8713
+ visit(block.children);
8714
+ }
8715
+ }
8716
+ };
8717
+ visit(blocks);
8718
+ return acc;
8719
+ }
8330
8720
  function validateTemplateTargets(runtime, input) {
8331
8721
  if (!Array.isArray(input.targets) || input.targets.length === 0) {
8332
8722
  const detail = blocker(
@@ -8747,6 +9137,15 @@ function applyRewrite(runtime, target, input) {
8747
9137
  if (!listTextTarget.ok) return blockedApplyFromResolution(listTextTarget);
8748
9138
  return applyEditableTextRewrite(runtime, listTextTarget.target, input);
8749
9139
  }
9140
+ const tableTextTarget = uniqueTableTextActionForScope(runtime, target.handle);
9141
+ if (tableTextTarget.ok && tableTextTarget.action.readback?.text === target.scope.content.text) {
9142
+ return applyTableScopedMarkerRewrite(
9143
+ runtime,
9144
+ target,
9145
+ tableTextTarget.action,
9146
+ input
9147
+ );
9148
+ }
8750
9149
  const rewriteBlocker = scopeRewriteCapabilityBlocker(target.scope);
8751
9150
  if (rewriteBlocker) {
8752
9151
  return blockedApply(
@@ -8879,6 +9278,106 @@ function applyEditableTextRewrite(runtime, target, input) {
8879
9278
  afterReadback
8880
9279
  };
8881
9280
  }
9281
+ function applyTableScopedMarkerRewrite(runtime, target, action, input) {
9282
+ const workflowScope = runtime.getScope(target.handle.scopeId);
9283
+ const editableTarget = tableEditableTargetForActionHandle(
9284
+ runtime,
9285
+ action.actionHandle
9286
+ );
9287
+ if (!workflowScope || workflowScope.anchor.kind !== "range" || !editableTarget) {
9288
+ return blockedApply(
9289
+ `actions:rewrite:table-marker-target-unresolved:${target.handle.scopeId}`,
9290
+ "unresolved-target",
9291
+ "The table-contained marker scope could not be joined to a current table text target.",
9292
+ "Refresh placeholder scopes and retry; route persistent failures to L08 table scope target mapping."
9293
+ );
9294
+ }
9295
+ const before = runtime.getCanonicalDocument();
9296
+ try {
9297
+ runtime.dispatch({
9298
+ type: "selection.set",
9299
+ selection: {
9300
+ anchor: workflowScope.anchor.from,
9301
+ head: workflowScope.anchor.to,
9302
+ isCollapsed: workflowScope.anchor.from === workflowScope.anchor.to,
9303
+ activeRange: {
9304
+ kind: "range",
9305
+ from: workflowScope.anchor.from,
9306
+ to: workflowScope.anchor.to,
9307
+ assoc: workflowScope.anchor.assoc ?? { start: -1, end: 1 }
9308
+ }
9309
+ },
9310
+ origin: actionOrigin(runtime, input)
9311
+ });
9312
+ runtime.applyActiveStoryTextCommand({
9313
+ type: "text.insert",
9314
+ text: input.text,
9315
+ editableTarget,
9316
+ origin: actionOrigin(runtime, input)
9317
+ });
9318
+ } catch {
9319
+ return blockedApply(
9320
+ `actions:rewrite:table-marker-command-refused:${target.handle.scopeId}`,
9321
+ "blocked",
9322
+ "The table-contained marker scope could not be rewritten by the runtime text command.",
9323
+ "Retry with an exact table text actionHandle; route repeated failures to L07 table text command support.",
9324
+ [
9325
+ blockerWithOwner(
9326
+ `actions:rewrite:table-marker-command-refused:${target.handle.scopeId}`,
9327
+ "blocked",
9328
+ "The table-contained marker scope could not be rewritten by the runtime text command.",
9329
+ "Retry with an exact table text actionHandle; route repeated failures to L07 table text command support.",
9330
+ "L07 runtime text command support"
9331
+ )
9332
+ ]
9333
+ );
9334
+ }
9335
+ const changed = runtime.getCanonicalDocument() !== before;
9336
+ const paragraph = resolveParagraphTextTarget2(
9337
+ runtime.getCanonicalDocument(),
9338
+ editableTarget
9339
+ );
9340
+ const afterText = paragraph ? collectInlineText3(paragraph.children) : void 0;
9341
+ const afterReadback = afterText === void 0 ? void 0 : { text: afterText, isEmpty: afterText.length === 0 };
9342
+ if (!changed || afterReadback?.text !== input.text) {
9343
+ return {
9344
+ status: "blocked",
9345
+ applied: false,
9346
+ changed,
9347
+ target: summarizeTarget({ kind: "table-text", action }),
9348
+ posture: "suspect-readback",
9349
+ blockers: Object.freeze([
9350
+ `actions:rewrite:table-marker-readback-mismatch:${target.handle.scopeId}`
9351
+ ]),
9352
+ blockerDetails: Object.freeze([
9353
+ blocker(
9354
+ `actions:rewrite:table-marker-readback-mismatch:${target.handle.scopeId}`,
9355
+ "blocked",
9356
+ "The table-contained marker rewrite did not produce the requested exact table-cell readback.",
9357
+ "Treat the mutation as suspect. Re-read the target and export before claiming success."
9358
+ )
9359
+ ]),
9360
+ ...afterReadback ? { afterReadback } : {}
9361
+ };
9362
+ }
9363
+ return {
9364
+ status: "applied",
9365
+ applied: true,
9366
+ changed: true,
9367
+ target: summarizeTarget({
9368
+ kind: "table-text",
9369
+ action: { ...action, readback: afterReadback }
9370
+ }),
9371
+ commandReference: {
9372
+ command: "text.insert",
9373
+ actorId: input.actorId ?? "v3-ai-api",
9374
+ origin: input.origin ?? "agent",
9375
+ emittedAtUtc: currentAuditTimestamp(runtime)
9376
+ },
9377
+ ...action.readback ? { beforeReadback: action.readback } : {},
9378
+ afterReadback
9379
+ };
9380
+ }
8882
9381
  function projectRewriteScopeResult(runtime, result, target, beforeText, proposedText, documentMutated) {
8883
9382
  if (!result.applied) return projectApplyResult(result, target);
8884
9383
  const compiledAfter = createScopeCompilerService(runtime).compileScopeById(
@@ -8995,6 +9494,51 @@ function tableTextActionsForScope(runtime, handle) {
8995
9494
  });
8996
9495
  return result.actions.filter((action) => action.family === "table-text");
8997
9496
  }
9497
+ function uniqueTableTextActionForScope(runtime, handle) {
9498
+ const actions = tableTextActionsForScope(runtime, handle).filter(
9499
+ (action) => action.readback !== void 0
9500
+ );
9501
+ if (actions.length === 1 && actions[0]) {
9502
+ return { ok: true, action: actions[0] };
9503
+ }
9504
+ if (actions.length === 0) {
9505
+ return {
9506
+ ok: false,
9507
+ blockers: Object.freeze(["actions:rewrite:table-text-target-missing"]),
9508
+ blockerDetails: Object.freeze([
9509
+ blocker(
9510
+ "actions:rewrite:table-text-target-missing",
9511
+ "unsupported",
9512
+ "The scope does not expose a unique command-safe table text target.",
9513
+ "Use a paragraph/list scope, or retry with an exact table text actionHandle returned by ai.actions.locateAll."
9514
+ )
9515
+ ])
9516
+ };
9517
+ }
9518
+ return {
9519
+ ok: false,
9520
+ blockers: Object.freeze(["actions:rewrite:table-text-target-ambiguous"]),
9521
+ blockerDetails: Object.freeze([
9522
+ blocker(
9523
+ "actions:rewrite:table-text-target-ambiguous",
9524
+ "ambiguous-target",
9525
+ "The scope exposes multiple table text targets, so broad rewrite would be ambiguous.",
9526
+ "Retry with the exact table text actionHandle returned by ai.actions.locateAll or ai.listTableActions."
9527
+ )
9528
+ ])
9529
+ };
9530
+ }
9531
+ function tableEditableTargetForActionHandle(runtime, actionHandle) {
9532
+ for (const target of collectEditableTargetRefs(runtime.getCanonicalDocument())) {
9533
+ if (target.commandFamily !== "text-leaf" || target.table?.operationScope !== "text") {
9534
+ continue;
9535
+ }
9536
+ if (deriveTableActionHandleForTarget(runtime, target.targetKey) === actionHandle) {
9537
+ return target;
9538
+ }
9539
+ }
9540
+ return null;
9541
+ }
8998
9542
  function editableTextActionsForScope(runtime, handle) {
8999
9543
  const bundle = createScopeCompilerService(runtime).compileBundleById(
9000
9544
  handle.scopeId,
@@ -10518,6 +11062,7 @@ function createApiV3(handle, opts) {
10518
11062
  ...createStatsFamily(handle),
10519
11063
  ...createOutlineFamily(handle),
10520
11064
  ...createTableActionFamily(handle),
11065
+ ...createObjectActionFamily(handle),
10521
11066
  ...createActionsFamily(handle)
10522
11067
  };
10523
11068
  const runtime = {