@agent-native/core 0.183.0 → 0.184.0-nightly-20260921223836

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 (65) hide show
  1. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +26 -1
  2. package/corpus/templates/content/shared/agent-readable.ts +7 -5
  3. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +45 -17
  4. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +8 -0
  5. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +22 -15
  6. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +69 -30
  7. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +10 -1
  8. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +3 -12
  9. package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +37 -3
  10. package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +5 -2
  11. package/dist/chat-threads/store.d.ts +1 -0
  12. package/dist/chat-threads/store.js +19 -0
  13. package/dist/client/observability/ObservabilityDashboard.js +113 -3
  14. package/dist/client/observability/useObservability.d.ts +9 -0
  15. package/dist/client/observability/useObservability.js +12 -0
  16. package/dist/collab/awareness.d.ts +2 -2
  17. package/dist/file-upload/actions/upload-image.d.ts +3 -3
  18. package/dist/identity/rekey.js +5 -0
  19. package/dist/localization/default-messages.d.ts +24 -0
  20. package/dist/localization/default-messages.js +24 -0
  21. package/dist/notifications/routes.d.ts +3 -3
  22. package/dist/observability/actions/list-observability-reviews.d.ts +5 -0
  23. package/dist/observability/actions/list-observability-reviews.js +23 -0
  24. package/dist/observability/actions/save-observability-instruction-update.d.ts +9 -0
  25. package/dist/observability/actions/save-observability-instruction-update.js +38 -0
  26. package/dist/observability/index.d.ts +2 -2
  27. package/dist/observability/index.js +1 -1
  28. package/dist/observability/reviews.d.ts +6 -0
  29. package/dist/observability/reviews.js +155 -0
  30. package/dist/observability/routes.d.ts +6 -6
  31. package/dist/observability/store.d.ts +8 -1
  32. package/dist/observability/store.js +77 -0
  33. package/dist/observability/types.d.ts +23 -0
  34. package/dist/provider-api/actions/custom-provider-registration.d.ts +17 -17
  35. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  36. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  37. package/dist/secrets/routes.d.ts +6 -6
  38. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  39. package/dist/server/core-routes-plugin.js +4 -3
  40. package/dist/server/realtime-token.d.ts +1 -1
  41. package/dist/templates/default/app/i18n/ar-SA.ts +25 -0
  42. package/dist/templates/default/app/i18n/de-DE.ts +25 -0
  43. package/dist/templates/default/app/i18n/en-US.ts +26 -0
  44. package/dist/templates/default/app/i18n/es-ES.ts +26 -0
  45. package/dist/templates/default/app/i18n/fr-FR.ts +26 -0
  46. package/dist/templates/default/app/i18n/hi-IN.ts +25 -0
  47. package/dist/templates/default/app/i18n/ja-JP.ts +25 -0
  48. package/dist/templates/default/app/i18n/ko-KR.ts +25 -0
  49. package/dist/templates/default/app/i18n/pt-BR.ts +25 -0
  50. package/dist/templates/default/app/i18n/zh-CN.ts +24 -0
  51. package/dist/templates/default/app/i18n/zh-TW.ts +24 -0
  52. package/dist/triggers/actions/manage-automation.d.ts +2 -2
  53. package/dist/vite/action-types-plugin.js +8 -0
  54. package/package.json +5 -3
  55. package/src/templates/default/app/i18n/ar-SA.ts +25 -0
  56. package/src/templates/default/app/i18n/de-DE.ts +25 -0
  57. package/src/templates/default/app/i18n/en-US.ts +26 -0
  58. package/src/templates/default/app/i18n/es-ES.ts +26 -0
  59. package/src/templates/default/app/i18n/fr-FR.ts +26 -0
  60. package/src/templates/default/app/i18n/hi-IN.ts +25 -0
  61. package/src/templates/default/app/i18n/ja-JP.ts +25 -0
  62. package/src/templates/default/app/i18n/ko-KR.ts +25 -0
  63. package/src/templates/default/app/i18n/pt-BR.ts +25 -0
  64. package/src/templates/default/app/i18n/zh-CN.ts +24 -0
  65. package/src/templates/default/app/i18n/zh-TW.ts +24 -0
@@ -52,10 +52,30 @@ import {
52
52
  useState,
53
53
  type Ref,
54
54
  type ReactNode,
55
+ type SVGProps,
55
56
  } from "react";
56
57
  import { useLocation, useNavigate } from "react-router";
57
58
  import { toast } from "sonner";
58
59
 
60
+ function IconSuggestEdits(props: SVGProps<SVGSVGElement>) {
61
+ return (
62
+ <svg
63
+ fill="none"
64
+ stroke="currentColor"
65
+ strokeLinecap="round"
66
+ strokeLinejoin="round"
67
+ strokeWidth="1.5"
68
+ viewBox="0 0 24 24"
69
+ xmlns="http://www.w3.org/2000/svg"
70
+ {...props}
71
+ >
72
+ <path d="M21.9165 10.5001C21.9351 10.6557 21.9495 10.8127 21.9598 10.9708C22.0134 11.801 22.0134 12.6608 21.9598 13.491C21.6856 17.7333 18.3536 21.1126 14.1706 21.3906C12.7435 21.4855 11.2536 21.4853 9.8294 21.3906C9.33896 21.358 8.8044 21.241 8.34401 21.0514C7.83177 20.8404 7.5756 20.7349 7.44544 20.7509C7.31527 20.7669 7.1264 20.9062 6.74868 21.1847C6.08268 21.6758 5.24367 22.0286 3.99943 21.9983C3.37026 21.983 3.05568 21.9753 2.91484 21.7352C2.77401 21.4951 2.94941 21.1627 3.30021 20.4979C3.78674 19.5759 4.09501 18.5204 3.62791 17.6747C2.82343 16.4667 2.1401 15.0361 2.04024 13.491C1.98659 12.6608 1.98659 11.801 2.04024 10.9708C2.31441 6.7285 5.64639 3.34925 9.8294 3.07119C11.0318 2.99126 12.2812 2.97868 13.5 3.0338" />
73
+ <path d="M8.5 15.0001H15.5M8.5 10.0001H11" />
74
+ <path d="M20.8684 2.43946L21.5607 3.13183C22.1465 3.71761 22.1465 4.66736 21.5607 5.25315L17.9333 8.94881C17.648 9.23416 17.283 9.42652 16.8863 9.50061L14.6381 9.98865C14.2832 10.0657 13.9671 9.75054 14.0431 9.39537L14.5217 7.16005C14.5958 6.76336 14.7881 6.39836 15.0735 6.11301L18.747 2.43946C19.3328 1.85368 20.2826 1.85368 20.8684 2.43946Z" />
75
+ </svg>
76
+ );
77
+ }
78
+
59
79
  // The share controller + dialog surface stays out of the editor's first-load
60
80
  // bundle; it loads the first time the Share flow opens.
61
81
  const ShareButton = lazy(() =>
@@ -1185,7 +1205,12 @@ export function DocumentToolbar({
1185
1205
  }, 50);
1186
1206
  }}
1187
1207
  >
1188
- <IconPencil className="me-2 h-4 w-4" />
1208
+ <IconSuggestEdits
1209
+ aria-hidden="true"
1210
+ className="me-2 shrink-0"
1211
+ height={16}
1212
+ width={16}
1213
+ />
1189
1214
  {t(
1190
1215
  suggesting
1191
1216
  ? "editor.toolbar.stopSuggesting"
@@ -151,17 +151,19 @@ export function contentDocumentMcpInstructionText(
151
151
  const summary = contentDocumentAccessSummary(
152
152
  options.accessState ?? "authentication-required",
153
153
  );
154
- const privateAccessFacts =
155
- options.accessState === "authentication-required" || !options.accessState
156
- ? " This response establishes only that anonymous HTTP access is unavailable; the connected account's document permission has not been evaluated. For an MCP-capable agent without a Content connection, the normal access path is for the user to add this instance as a remote MCP server, authenticate, enable the connection or its tools, and retry the original document request. An authenticated get-document not-found response does not distinguish missing permission from a stale, deleted, or invalid document id."
157
- : "";
154
+ if (
155
+ options.accessState === "authentication-required" ||
156
+ !options.accessState
157
+ ) {
158
+ return `Agent-Native Content access record. Resource: private Content document. Anonymous HTTP access: denied. Authenticated Content MCP endpoint: ${mcpUrl}. Connection page: ${mcpConnectUrl}. Official Agent-Native setup documentation: ${CONTENT_MCP_SETUP_DOCUMENTATION_URL}. Content MCP read action: ${CONTENT_DOCUMENT_READ_ACTION}. Document id: ${JSON.stringify(documentId)}. Adding a connection changes the user's agent configuration and is the user's choice. Authentication uses the connected account's existing document permissions and does not grant new document access. The connected account's permission for this document has not been evaluated.`;
159
+ }
158
160
  const mcpPermissionFacts =
159
161
  options.accessState === "public"
160
162
  ? " This public share page does not require an MCP account permission."
161
163
  : options.accessState === "authorized"
162
164
  ? " This page is authorized by its scoped share token. MCP access separately uses the connected account's existing document permissions."
163
165
  : " Document access through MCP uses the connected account's existing permissions.";
164
- return `Content access information: ${summary}${privateAccessFacts}${mcpPermissionFacts} Content MCP server: ${mcpUrl}. Connection setup for this Content instance: ${mcpConnectUrl}. Official Agent-Native setup documentation: ${CONTENT_MCP_SETUP_DOCUMENTATION_URL}. Content MCP read action: ${CONTENT_DOCUMENT_READ_ACTION} with id ${JSON.stringify(documentId)}.`;
166
+ return `Content access information: ${summary}${mcpPermissionFacts} Content MCP server: ${mcpUrl}. Connection setup for this Content instance: ${mcpConnectUrl}. Official Agent-Native setup documentation: ${CONTENT_MCP_SETUP_DOCUMENTATION_URL}. Content MCP read action: ${CONTENT_DOCUMENT_READ_ACTION} with id ${JSON.stringify(documentId)}.`;
165
167
  }
166
168
 
167
169
  export function buildContentPublicDocumentPath(documentId: string): string {
@@ -10880,15 +10880,19 @@ export const editorChromeBridgeScript: string = `"use strict";
10880
10880
  container
10881
10881
  );
10882
10882
  }
10883
- var placementCandidates = children.concat(excluded || []);
10884
- var hasExplicitPlacement = placementCandidates.some(function(child) {
10885
- var childStyles = window.getComputedStyle(child);
10886
- return childStyles.gridColumnStart !== "auto" || childStyles.gridColumnEnd !== "auto" || childStyles.gridRowStart !== "auto" || childStyles.gridRowEnd !== "auto" || childStyles.order !== "0";
10887
- });
10888
10883
  var singleSource = excluded && excluded.length === 1 ? excluded[0] : null;
10889
10884
  var singleSourceStyles = singleSource ? window.getComputedStyle(singleSource) : null;
10890
10885
  var singleSourceColumn = singleSource && trackLayout ? gridItemAxisPlacement(singleSource, trackLayout, "column") : null;
10891
10886
  var singleSourceRow = singleSource && trackLayout ? gridItemAxisPlacement(singleSource, trackLayout, "row") : null;
10887
+ var sourceHasAuthoredPlacement = Boolean(
10888
+ excluded?.some(function(source) {
10889
+ var columnPlacement = trackLayout ? gridItemAxisPlacement(source, trackLayout, "column") : null;
10890
+ var rowPlacement = trackLayout ? gridItemAxisPlacement(source, trackLayout, "row") : null;
10891
+ return Boolean(
10892
+ columnPlacement?.hasAuthoredPlacement || rowPlacement?.hasAuthoredPlacement
10893
+ );
10894
+ })
10895
+ );
10892
10896
  var hasAuthoredSingleCellSourcePlacement = Boolean(
10893
10897
  singleSource && singleSource.parentElement === container && singleSourceStyles && singleSourceStyles.gridColumnStart !== "auto" && singleSourceStyles.gridColumnStart.indexOf("span") !== 0 && singleSourceStyles.gridRowStart !== "auto" && singleSourceStyles.gridRowStart.indexOf("span") !== 0 && (singleSourceStyles.gridColumnEnd === "auto" || singleSourceColumn?.span === 1) && (singleSourceStyles.gridRowEnd === "auto" || singleSourceRow?.span === 1)
10894
10898
  );
@@ -10896,7 +10900,7 @@ export const editorChromeBridgeScript: string = `"use strict";
10896
10900
  while (hit && hit.parentElement && hit.parentElement !== container) {
10897
10901
  hit = hit.parentElement;
10898
10902
  }
10899
- if (trackLayout && hasExplicitPlacement && !hasAuthoredSingleCellSourcePlacement) {
10903
+ if (trackLayout && !hasAuthoredSingleCellSourcePlacement) {
10900
10904
  var column = trackLayout.columnBounds.findIndex(function(bound) {
10901
10905
  return clientX >= bound.start && clientX <= bound.end;
10902
10906
  });
@@ -10949,7 +10953,10 @@ export const editorChromeBridgeScript: string = `"use strict";
10949
10953
  },
10950
10954
  guideMode: displaced ? "grid-line" : "grid-cell",
10951
10955
  guidePlacement: pointer <= midpoint + 0.5 ? "before" : "after",
10952
- gridCell: { column, row },
10956
+ // Column auto-flow derives placement from source order. Persisting
10957
+ // measured coordinates here would freeze responsive auto-flow into
10958
+ // explicit gridColumn/gridRow styles.
10959
+ ...autoFlow[0] === "column" && !sourceHasAuthoredPlacement ? {} : { gridCell: { column, row } },
10953
10960
  gridDisplacement: displaced
10954
10961
  };
10955
10962
  }
@@ -11431,7 +11438,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11431
11438
  );
11432
11439
  if (rootChildSlot) return rootChildSlot;
11433
11440
  }
11434
- if (parent && parent !== document.body && isAutoLayoutElement(parent) && cursor.getAttribute("data-an-primitive") !== "frame" && !isTextBearingLeaf(parent) && !forceNestedAutoLayout && !isTemplateCloneElement(cursor)) {
11441
+ if (parent && parent !== document.body && isAutoLayoutElement(parent) && cursor.getAttribute("data-an-primitive") !== "frame" && (!isContainerDropTarget(cursor) || cursor.tagName.toLowerCase() !== "section" || isTemplateCloneElement(cursor)) && !isTextBearingLeaf(parent) && !forceNestedAutoLayout && !isTemplateCloneElement(cursor)) {
11435
11442
  var directChildSlot = nearestChildInsertionTarget(
11436
11443
  parent,
11437
11444
  clientX,
@@ -11459,7 +11466,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11459
11466
  dropMode: "absolute-container"
11460
11467
  };
11461
11468
  }
11462
- if (cursor !== document.body && isContainerDropTarget(cursor) && !(!forceNestedAutoLayout && parent && parent !== document.body && isAutoLayoutElement(parent) && cursor.getAttribute("data-an-primitive") !== "frame")) {
11469
+ if (cursor !== document.body && isContainerDropTarget(cursor) && !(!forceNestedAutoLayout && parent && parent !== document.body && isAutoLayoutElement(parent) && cursor.getAttribute("data-an-primitive") !== "frame" && (cursor.tagName.toLowerCase() !== "section" || isTemplateCloneElement(cursor)))) {
11463
11470
  if (!isAutoLayoutElement(cursor)) {
11464
11471
  if (cursor === el.parentElement) return null;
11465
11472
  return {
@@ -11829,6 +11836,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11829
11836
  var start = gridLinePosition(startValue, layout, axis);
11830
11837
  var end = gridLinePosition(endValue, layout, axis);
11831
11838
  var authoredSpan = endValue.trim().match(/^span\\s+(\\d+)$/) || startValue.trim().match(/^span\\s+(\\d+)$/);
11839
+ var hasAuthoredPlacement = authoredSpan !== null || startValue.trim() !== "auto" && startValue.trim() !== "" || endValue.trim() !== "auto" && endValue.trim() !== "" || styles.order !== "0";
11832
11840
  var geometricRange = layout ? gridTrackRangeForRect(
11833
11841
  el.getBoundingClientRect(),
11834
11842
  axis === "column" ? layout.columnBounds : layout.rowBounds,
@@ -11839,6 +11847,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11839
11847
  if (start === null && end !== null && authoredSpan) start = end - span;
11840
11848
  return {
11841
11849
  authoredStart: start,
11850
+ hasAuthoredPlacement,
11842
11851
  start: start ?? (geometricRange ? geometricRange.start + 1 : null),
11843
11852
  span
11844
11853
  };
@@ -12091,6 +12100,7 @@ export const editorChromeBridgeScript: string = `"use strict";
12091
12100
  }
12092
12101
  var sourceColumn = gridItemAxisPlacement(el, sourceGridLayout, "column");
12093
12102
  var sourceRow = gridItemAxisPlacement(el, sourceGridLayout, "row");
12103
+ var sourceHasAuthoredPlacement = sourceColumn.hasAuthoredPlacement || sourceRow.hasAuthoredPlacement;
12094
12104
  var columnStart = sourceColumn.start ?? NaN;
12095
12105
  var columnSpan = sourceColumn.span;
12096
12106
  var columnEnd = columnStart + columnSpan;
@@ -12169,6 +12179,18 @@ export const editorChromeBridgeScript: string = `"use strict";
12169
12179
  });
12170
12180
  };
12171
12181
  targetDisplacements.forEach(function(displaced) {
12182
+ var displacedColumnPlacement = gridItemAxisPlacement(
12183
+ displaced,
12184
+ targetGridLayout,
12185
+ "column"
12186
+ );
12187
+ var displacedRowPlacement = gridItemAxisPlacement(
12188
+ displaced,
12189
+ targetGridLayout,
12190
+ "row"
12191
+ );
12192
+ var displacedHasAuthoredPlacement = displacedColumnPlacement.hasAuthoredPlacement || displacedRowPlacement.hasAuthoredPlacement;
12193
+ if (!displacedHasAuthoredPlacement) return;
12172
12194
  var displacedRange = gridTrackRangeForRect(
12173
12195
  displaced.getBoundingClientRect(),
12174
12196
  targetGridLayout.columnBounds,
@@ -12235,14 +12257,16 @@ export const editorChromeBridgeScript: string = `"use strict";
12235
12257
  displaced.style.gridRow = \`\${displacementPlacement.row} / \${displacementPlacement.rowEnd}\`;
12236
12258
  });
12237
12259
  }
12238
- el.style.gridColumn = \`\${target.gridCell.column + 1} / \${target.gridCell.column + 1 + columnSpan}\`;
12239
- el.style.gridRow = \`\${target.gridCell.row + 1} / \${target.gridCell.row + 1 + rowSpan}\`;
12240
- target.gridPlacement = {
12241
- column: target.gridCell.column + 1,
12242
- columnEnd: target.gridCell.column + 1 + columnSpan,
12243
- row: target.gridCell.row + 1,
12244
- rowEnd: target.gridCell.row + 1 + rowSpan
12245
- };
12260
+ if (sourceHasAuthoredPlacement) {
12261
+ el.style.gridColumn = \`\${target.gridCell.column + 1} / \${target.gridCell.column + 1 + columnSpan}\`;
12262
+ el.style.gridRow = \`\${target.gridCell.row + 1} / \${target.gridCell.row + 1 + rowSpan}\`;
12263
+ target.gridPlacement = {
12264
+ column: target.gridCell.column + 1,
12265
+ columnEnd: target.gridCell.column + 1 + columnSpan,
12266
+ row: target.gridCell.row + 1,
12267
+ rowEnd: target.gridCell.row + 1 + rowSpan
12268
+ };
12269
+ }
12246
12270
  }
12247
12271
  rebaseAbsoluteMemberForContainerDrop(el, target);
12248
12272
  var persistenceAnchor = target.persistenceAnchor || target.anchor;
@@ -17058,6 +17082,10 @@ export const editorChromeBridgeScript: string = `"use strict";
17058
17082
  window.addEventListener("message", function(e) {
17059
17083
  if (e.source !== window.parent) return;
17060
17084
  if (!e.data) return;
17085
+ if (e.data.type === "agent-native:editor-chrome-ready-probe") {
17086
+ sendEditorChromeReady();
17087
+ return;
17088
+ }
17061
17089
  if (e.data.type === "resume-text-edit") {
17062
17090
  var resumeScreenId = typeof e.data.screenId === "string" ? e.data.screenId : "";
17063
17091
  var resumeSelector = typeof e.data.selector === "string" ? e.data.selector : "";
@@ -4936,6 +4936,10 @@ export function DesignCanvas({
4936
4936
  const replayIframeEditorState = useCallback(() => {
4937
4937
  const iframe = iframeRef.current;
4938
4938
  if (!iframe) return;
4939
+ iframe.contentWindow?.postMessage(
4940
+ { type: "agent-native:editor-chrome-ready-probe" },
4941
+ "*",
4942
+ );
4939
4943
  iframe.contentWindow?.postMessage(
4940
4944
  {
4941
4945
  type: "embedded-canvas-pan-mode",
@@ -6888,6 +6892,10 @@ export function DesignCanvas({
6888
6892
  onBootReady();
6889
6893
  }
6890
6894
  sendBridgeToContainer();
6895
+ event.currentTarget.contentWindow?.postMessage(
6896
+ { type: "agent-native:editor-chrome-ready-probe" },
6897
+ "*",
6898
+ );
6891
6899
  // The bridge logs into the IFRAME console and cannot read
6892
6900
  // import.meta.env, so dev has to switch it on from out here.
6893
6901
  if (!import.meta.env?.DEV) return;
@@ -3741,15 +3741,19 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
3741
3741
  // become negative or otherwise out of range. The parent window drag
3742
3742
  // listener has the real board point then; stale iframe coordinates
3743
3743
  // must not clear a valid board target.
3744
- if (
3745
- sourceScreenId !== boardFileId &&
3746
- !isPointerInsideSourceIframe({
3747
- iframeX,
3748
- iframeY,
3749
- viewportW,
3750
- viewportH,
3751
- })
3752
- ) {
3744
+ const localPointerInside = isPointerInsideSourceIframe({
3745
+ iframeX,
3746
+ iframeY,
3747
+ viewportW,
3748
+ viewportH,
3749
+ frameWidth:
3750
+ renderedFrameGeometryRef.current[sourceScreenId]?.width ??
3751
+ frameGeometryRef.current[sourceScreenId]?.width,
3752
+ frameHeight:
3753
+ renderedFrameGeometryRef.current[sourceScreenId]?.height ??
3754
+ frameGeometryRef.current[sourceScreenId]?.height,
3755
+ });
3756
+ if (sourceScreenId !== boardFileId && !localPointerInside) {
3753
3757
  const previewPoint =
3754
3758
  boardPointFromParentPointer(
3755
3759
  iframeX,
@@ -3813,12 +3817,8 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
3813
3817
  crossScreenDragMsgRef.current?.styleSnapshotCaptureFailed === true,
3814
3818
  };
3815
3819
 
3816
- const pointerInsideSourceIframe = isPointerInsideSourceIframe({
3817
- iframeX,
3818
- iframeY,
3819
- viewportW,
3820
- viewportH,
3821
- });
3820
+ const pointerInsideSourceIframe =
3821
+ sourceScreenId === boardFileId || localPointerInside;
3822
3822
  const sourceIsBoard = sourceScreenId === boardFileId;
3823
3823
  // Regular screen iframes are finite artboards, so an in-bounds pointer
3824
3824
  // means the source bridge should keep handling the drag. The board
@@ -3911,6 +3911,12 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
3911
3911
  iframeY: msg.iframeY!,
3912
3912
  viewportW: msg.viewportW!,
3913
3913
  viewportH: msg.viewportH!,
3914
+ frameWidth:
3915
+ renderedFrameGeometryRef.current[sourceScreenId]?.width ??
3916
+ frameGeometryRef.current[sourceScreenId]?.width,
3917
+ frameHeight:
3918
+ renderedFrameGeometryRef.current[sourceScreenId]?.height ??
3919
+ frameGeometryRef.current[sourceScreenId]?.height,
3914
3920
  });
3915
3921
  const lastBoardPoint =
3916
3922
  (endPointOutsideSource
@@ -11245,6 +11251,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
11245
11251
  // identical Figma-style indicator between siblings.
11246
11252
  <span
11247
11253
  data-primitive-drop-target
11254
+ data-agent-native-insertion-guide
11248
11255
  data-primitive-drop-placement={primitiveDropTarget.placement}
11249
11256
  className="pointer-events-none absolute z-40 rounded-sm"
11250
11257
  style={getCrossScreenDropGuideStyle({
@@ -9765,7 +9765,7 @@ declare var __INITIAL_SOURCE_HEAD__: string;
9765
9765
  function frameLabelText(frame: Element): string {
9766
9766
  var name =
9767
9767
  layerNameForElement(frame) || frame.getAttribute("aria-label") || "";
9768
- return name.trim() || "Frame" /* i18n-ignore canvas frame label */;
9768
+ return name.trim() || "Frame"; /* i18n-ignore canvas frame label */
9769
9769
  }
9770
9770
 
9771
9771
  function selectFrameFromLabel(frame: Element, e: MouseEvent): void {
@@ -14963,20 +14963,8 @@ declare var __INITIAL_SOURCE_HEAD__: string;
14963
14963
  container,
14964
14964
  );
14965
14965
  }
14966
- var placementCandidates = children.concat(excluded || []);
14967
- var hasExplicitPlacement = placementCandidates.some(function (child) {
14968
- var childStyles = window.getComputedStyle(child);
14969
- return (
14970
- childStyles.gridColumnStart !== "auto" ||
14971
- childStyles.gridColumnEnd !== "auto" ||
14972
- childStyles.gridRowStart !== "auto" ||
14973
- childStyles.gridRowEnd !== "auto" ||
14974
- childStyles.order !== "0"
14975
- );
14976
- });
14977
- // Preserve a single-cell authored slot only for a single source already
14978
- // owned by this grid. Cross-grid and grouped drops must resolve the
14979
- // destination cell normally.
14966
+ // Preserve authored placement for any dragged source. Cross-grid and
14967
+ // grouped drops still need the destination cell for every authored item.
14980
14968
  var singleSource = excluded && excluded.length === 1 ? excluded[0] : null;
14981
14969
  var singleSourceStyles = singleSource
14982
14970
  ? window.getComputedStyle(singleSource)
@@ -14989,6 +14977,20 @@ declare var __INITIAL_SOURCE_HEAD__: string;
14989
14977
  singleSource && trackLayout
14990
14978
  ? gridItemAxisPlacement(singleSource, trackLayout, "row")
14991
14979
  : null;
14980
+ var sourceHasAuthoredPlacement = Boolean(
14981
+ excluded?.some(function (source) {
14982
+ var columnPlacement = trackLayout
14983
+ ? gridItemAxisPlacement(source, trackLayout, "column")
14984
+ : null;
14985
+ var rowPlacement = trackLayout
14986
+ ? gridItemAxisPlacement(source, trackLayout, "row")
14987
+ : null;
14988
+ return Boolean(
14989
+ columnPlacement?.hasAuthoredPlacement ||
14990
+ rowPlacement?.hasAuthoredPlacement,
14991
+ );
14992
+ }),
14993
+ );
14992
14994
  var hasAuthoredSingleCellSourcePlacement = Boolean(
14993
14995
  singleSource &&
14994
14996
  singleSource.parentElement === container &&
@@ -15008,11 +15010,7 @@ declare var __INITIAL_SOURCE_HEAD__: string;
15008
15010
  // Resolve the pointer against rendered tracks and carry the cell through
15009
15011
  // the drop so the source and its persisted markup move together. The
15010
15012
  // occupied cell is also retained as the source-order insertion anchor.
15011
- if (
15012
- trackLayout &&
15013
- hasExplicitPlacement &&
15014
- !hasAuthoredSingleCellSourcePlacement
15015
- ) {
15013
+ if (trackLayout && !hasAuthoredSingleCellSourcePlacement) {
15016
15014
  var column = trackLayout.columnBounds.findIndex(function (bound) {
15017
15015
  return clientX >= bound.start && clientX <= bound.end;
15018
15016
  });
@@ -15088,7 +15086,12 @@ declare var __INITIAL_SOURCE_HEAD__: string;
15088
15086
  },
15089
15087
  guideMode: displaced ? "grid-line" : "grid-cell",
15090
15088
  guidePlacement: pointer <= midpoint + 0.5 ? "before" : "after",
15091
- gridCell: { column, row },
15089
+ // Column auto-flow derives placement from source order. Persisting
15090
+ // measured coordinates here would freeze responsive auto-flow into
15091
+ // explicit gridColumn/gridRow styles.
15092
+ ...(autoFlow[0] === "column" && !sourceHasAuthoredPlacement
15093
+ ? {}
15094
+ : { gridCell: { column, row } }),
15092
15095
  gridDisplacement: displaced,
15093
15096
  };
15094
15097
  }
@@ -15956,6 +15959,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
15956
15959
  parent !== document.body &&
15957
15960
  isAutoLayoutElement(parent) &&
15958
15961
  cursor.getAttribute("data-an-primitive") !== "frame" &&
15962
+ (!isContainerDropTarget(cursor) ||
15963
+ cursor.tagName.toLowerCase() !== "section" ||
15964
+ isTemplateCloneElement(cursor)) &&
15959
15965
  !isTextBearingLeaf(parent) &&
15960
15966
  !forceNestedAutoLayout &&
15961
15967
  !isTemplateCloneElement(cursor)
@@ -16036,7 +16042,9 @@ declare var __INITIAL_SOURCE_HEAD__: string;
16036
16042
  parent &&
16037
16043
  parent !== document.body &&
16038
16044
  isAutoLayoutElement(parent) &&
16039
- cursor.getAttribute("data-an-primitive") !== "frame"
16045
+ cursor.getAttribute("data-an-primitive") !== "frame" &&
16046
+ (cursor.tagName.toLowerCase() !== "section" ||
16047
+ isTemplateCloneElement(cursor))
16040
16048
  )
16041
16049
  ) {
16042
16050
  // Free (absolute) element into a non-auto-layout container stays free:
@@ -16564,6 +16572,11 @@ declare var __INITIAL_SOURCE_HEAD__: string;
16564
16572
  var authoredSpan =
16565
16573
  endValue.trim().match(/^span\s+(\d+)$/) ||
16566
16574
  startValue.trim().match(/^span\s+(\d+)$/);
16575
+ var hasAuthoredPlacement =
16576
+ authoredSpan !== null ||
16577
+ (startValue.trim() !== "auto" && startValue.trim() !== "") ||
16578
+ (endValue.trim() !== "auto" && endValue.trim() !== "") ||
16579
+ styles.order !== "0";
16567
16580
  var geometricRange = layout
16568
16581
  ? gridTrackRangeForRect(
16569
16582
  el.getBoundingClientRect(),
@@ -16582,6 +16595,7 @@ declare var __INITIAL_SOURCE_HEAD__: string;
16582
16595
  if (start === null && end !== null && authoredSpan) start = end - span;
16583
16596
  return {
16584
16597
  authoredStart: start,
16598
+ hasAuthoredPlacement: hasAuthoredPlacement,
16585
16599
  start: start ?? (geometricRange ? geometricRange.start + 1 : null),
16586
16600
  span,
16587
16601
  };
@@ -17042,6 +17056,8 @@ declare var __INITIAL_SOURCE_HEAD__: string;
17042
17056
  }
17043
17057
  var sourceColumn = gridItemAxisPlacement(el, sourceGridLayout, "column");
17044
17058
  var sourceRow = gridItemAxisPlacement(el, sourceGridLayout, "row");
17059
+ var sourceHasAuthoredPlacement =
17060
+ sourceColumn.hasAuthoredPlacement || sourceRow.hasAuthoredPlacement;
17045
17061
  var columnStart = sourceColumn.start ?? NaN;
17046
17062
  var columnSpan = sourceColumn.span;
17047
17063
  var columnEnd = columnStart + columnSpan;
@@ -17178,6 +17194,20 @@ declare var __INITIAL_SOURCE_HEAD__: string;
17178
17194
  });
17179
17195
  };
17180
17196
  targetDisplacements.forEach(function (displaced) {
17197
+ var displacedColumnPlacement = gridItemAxisPlacement(
17198
+ displaced,
17199
+ targetGridLayout,
17200
+ "column",
17201
+ );
17202
+ var displacedRowPlacement = gridItemAxisPlacement(
17203
+ displaced,
17204
+ targetGridLayout,
17205
+ "row",
17206
+ );
17207
+ var displacedHasAuthoredPlacement =
17208
+ displacedColumnPlacement.hasAuthoredPlacement ||
17209
+ displacedRowPlacement.hasAuthoredPlacement;
17210
+ if (!displacedHasAuthoredPlacement) return;
17181
17211
  var displacedRange = gridTrackRangeForRect(
17182
17212
  displaced.getBoundingClientRect(),
17183
17213
  targetGridLayout!.columnBounds,
@@ -17270,14 +17300,16 @@ declare var __INITIAL_SOURCE_HEAD__: string;
17270
17300
  displaced.style.gridRow = `${displacementPlacement.row} / ${displacementPlacement.rowEnd}`;
17271
17301
  });
17272
17302
  }
17273
- el.style.gridColumn = `${target.gridCell.column + 1} / ${target.gridCell.column + 1 + columnSpan}`;
17274
- el.style.gridRow = `${target.gridCell.row + 1} / ${target.gridCell.row + 1 + rowSpan}`;
17275
- target.gridPlacement = {
17276
- column: target.gridCell.column + 1,
17277
- columnEnd: target.gridCell.column + 1 + columnSpan,
17278
- row: target.gridCell.row + 1,
17279
- rowEnd: target.gridCell.row + 1 + rowSpan,
17280
- };
17303
+ if (sourceHasAuthoredPlacement) {
17304
+ el.style.gridColumn = `${target.gridCell.column + 1} / ${target.gridCell.column + 1 + columnSpan}`;
17305
+ el.style.gridRow = `${target.gridCell.row + 1} / ${target.gridCell.row + 1 + rowSpan}`;
17306
+ target.gridPlacement = {
17307
+ column: target.gridCell.column + 1,
17308
+ columnEnd: target.gridCell.column + 1 + columnSpan,
17309
+ row: target.gridCell.row + 1,
17310
+ rowEnd: target.gridCell.row + 1 + rowSpan,
17311
+ };
17312
+ }
17281
17313
  }
17282
17314
  // Must run BEFORE the DOM move below: the delta math reads the member's
17283
17315
  // CURRENT containing block via offsetParent. Called here (the single
@@ -24143,6 +24175,13 @@ declare var __INITIAL_SOURCE_HEAD__: string;
24143
24175
  window.addEventListener("message", function (e) {
24144
24176
  if (e.source !== window.parent) return;
24145
24177
  if (!e.data) return;
24178
+ // The child can finish booting before the parent installs its one-shot
24179
+ // ready listener. Let the parent ask again after the iframe load event;
24180
+ // this is idempotent and also survives a document remount.
24181
+ if (e.data.type === "agent-native:editor-chrome-ready-probe") {
24182
+ sendEditorChromeReady();
24183
+ return;
24184
+ }
24146
24185
  // NOTE: no message type in this handler is sourced from a `payload`
24147
24186
  // sub-object — every host sender (DesignCanvas.tsx) puts its fields
24148
24187
  // directly on the top-level message. A previous blanket
@@ -347,7 +347,16 @@ export function isPrimitiveContainer(args: {
347
347
  display: string;
348
348
  borderRadius: string;
349
349
  }): boolean {
350
- const isDiv = args.tagName.toLowerCase() === "div";
350
+ const isDiv = [
351
+ "div",
352
+ "section",
353
+ "main",
354
+ "header",
355
+ "footer",
356
+ "article",
357
+ "nav",
358
+ "aside",
359
+ ].includes(args.tagName.toLowerCase());
351
360
  const primitiveKind = args.primitiveKind.toLowerCase();
352
361
  const isEllipse =
353
362
  args.borderRadius === "50%" || args.borderRadius === "50% 50% 50% 50%";
@@ -77,6 +77,7 @@ export interface CommitVisualStylesArgs {
77
77
  activeProjectionContent: string;
78
78
  canEditDesign: boolean;
79
79
  canApplyContentEdit: (fileId: string) => boolean;
80
+ onNoRenderedBox?: () => void;
80
81
  applyLinkedComponentEdit?: (
81
82
  fileId: string,
82
83
  nodeId: string,
@@ -199,6 +200,7 @@ export function runCommitVisualStyles(
199
200
  lastLocalContentRef,
200
201
  latestActiveContentRef,
201
202
  liveScreenSnapshotsById,
203
+ onNoRenderedBox,
202
204
  queueFileContentSave,
203
205
  recordContentHistoryEntry,
204
206
  recordLocalContentHistoryChangeFallback,
@@ -302,18 +304,7 @@ export function runCommitVisualStyles(
302
304
  });
303
305
  }
304
306
  }
305
- recordPendingVisualStyleEdit(
306
- activeFile.id,
307
- selector,
308
- styles,
309
- liveTargetInfo,
310
- {
311
- originalStyles: options.originalStyles,
312
- pendingUndoGestureId: options.pendingUndoGestureId,
313
- preserveSelection: options.preserveSelection,
314
- routePath: options.routePath,
315
- },
316
- );
307
+ onNoRenderedBox?.();
317
308
  return;
318
309
  }
319
310
  upsertMotionKeyframesFromStyles(styles, options.elementInfo, selector);
@@ -77,11 +77,42 @@ export interface NudgeSelectionArgs {
77
77
  selectedElement: ElementInfo | null;
78
78
  selectedLayerIdsState: string[];
79
79
  selectedLayerTargetsRef: RefObject<SelectedLayerTarget[]>;
80
+ renderedElementInfoByLayerKeyRef: RefObject<Map<string, ElementInfo>>;
80
81
  setSelectedElement: Dispatch<SetStateAction<ElementInfo | null>>;
81
82
  setSelectedLayerIdsState: Dispatch<SetStateAction<string[]>>;
82
83
  viewModeRef: RefObject<"single" | "overview">;
83
84
  }
84
85
 
86
+ export function resolveNudgeTarget(
87
+ selectedElement: ElementInfo | null,
88
+ selectedLayerTargets: readonly SelectedLayerTarget[],
89
+ renderedElementInfoByLayerKey: ReadonlyMap<string, ElementInfo>,
90
+ ): ElementInfo | null {
91
+ const selectedLayerTarget =
92
+ selectedLayerTargets.find(
93
+ (target) =>
94
+ selectedElement?.sourceLayerIdentity?.screenId === target.fileId &&
95
+ selectedElement.sourceLayerIdentity.nodeId === target.layerId,
96
+ ) ??
97
+ selectedLayerTargets.find(
98
+ (target) =>
99
+ selectedElement?.sourceId === target.layerId ||
100
+ selectedElement?.sourceId === target.node.id,
101
+ ) ??
102
+ selectedLayerTargets[0];
103
+ return (
104
+ (selectedLayerTarget
105
+ ? renderedElementInfoByLayerKey.get(
106
+ `${selectedLayerTarget.fileId}:${selectedLayerTarget.layerId}`,
107
+ )
108
+ : undefined) ??
109
+ (selectedElement?.selector
110
+ ? selectedElement
111
+ : selectedLayerTarget?.elementInfo) ??
112
+ null
113
+ );
114
+ }
115
+
85
116
  export function runNudgeSelection(
86
117
  {
87
118
  applyLinkedComponentEdit,
@@ -104,6 +135,7 @@ export function runNudgeSelection(
104
135
  selectedElement,
105
136
  selectedLayerIdsState,
106
137
  selectedLayerTargetsRef,
138
+ renderedElementInfoByLayerKeyRef,
107
139
  setSelectedElement,
108
140
  setSelectedLayerIdsState,
109
141
  viewModeRef,
@@ -171,9 +203,11 @@ export function runNudgeSelection(
171
203
  // Selecting in the layers tree fills selectedLayerTargets before the
172
204
  // bridge round-trip fills selectedElement, so keying off the latter
173
205
  // alone silently drops the first nudge after every tree selection.
174
- const nudgeTarget = selectedElement?.selector
175
- ? selectedElement
176
- : selectedLayerTargetsRef.current[0]?.elementInfo;
206
+ const nudgeTarget = resolveNudgeTarget(
207
+ selectedElement,
208
+ selectedLayerTargetsRef.current,
209
+ renderedElementInfoByLayerKeyRef.current,
210
+ );
177
211
  if (!nudgeTarget?.selector) return;
178
212
 
179
213
  if (isRunningAppSource && canEditLiveScreen) {
@@ -224,7 +224,7 @@ export interface RedoArgs {
224
224
  pendingVisualStyleUndoStackRef: RefObject<PendingVisualStyleUndoEntry[]>;
225
225
  replayPendingVisualStyleRuntime?: (
226
226
  edits: readonly PendingVisualStyleEdit[],
227
- ) => void;
227
+ ) => number | undefined;
228
228
  setPendingVisualStyleBaselineResetRequest?: Dispatch<
229
229
  SetStateAction<number | null>
230
230
  >;
@@ -781,9 +781,12 @@ export function runRedo({
781
781
  ({ edit }) => Object.keys(edit.styles).length > 0,
782
782
  );
783
783
  if (replayPendingVisualStyleRuntime) {
784
- replayPendingVisualStyleRuntime(
784
+ const requestId = replayPendingVisualStyleRuntime(
785
785
  redoneStyleTargets.map(({ edit }) => edit),
786
786
  );
787
+ if (requestId !== undefined) {
788
+ setPendingVisualStyleBaselineResetRequest?.(requestId);
789
+ }
787
790
  } else if (redoneStyleTargets.length > 0) {
788
791
  const requestId = Date.now() + Math.random();
789
792
  setPendingVisualStyleRevertRequest({
@@ -86,6 +86,7 @@ export declare function createThread(ownerEmail: string, opts?: {
86
86
  export declare function registerChatThreadsShareable(): void;
87
87
  export declare function ensureChatThreadTables(): Promise<void>;
88
88
  export declare function resolveThreadAccess(userEmail: string | null | undefined, threadId: string | null | undefined, minRole?: ShareRole | "owner", ctx?: Omit<AccessContext, "userEmail">): Promise<ChatThread | null>;
89
+ export declare function resolveThreadsAccess(userEmail: string | null | undefined, threadIds: readonly string[], ctx?: Pick<AccessContext, "orgId">): Promise<Map<string, ChatThread>>;
89
90
  export declare function getThread(id: string): Promise<ChatThread | null>;
90
91
  /**
91
92
  * Fill missing provenance on a thread without rewriting an established origin.