@agent-native/core 0.81.0 → 0.81.2

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 (47) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/client/AgentPanel.tsx +33 -1
  5. package/corpus/core/src/server/core-routes-plugin.ts +4 -5
  6. package/corpus/core/src/server/create-server.ts +3 -5
  7. package/corpus/core/src/server/google-oauth.ts +4 -0
  8. package/corpus/templates/calendar/actions/create-event.ts +9 -2
  9. package/corpus/templates/calendar/actions/event-action-helpers.ts +8 -2
  10. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +11 -0
  11. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +17 -0
  12. package/corpus/templates/calendar/app/hooks/use-google-auth.ts +70 -39
  13. package/corpus/templates/calendar/changelog/2026-06-30-google-calendar-connection-errors-now-stay-in-the-app-instea.md +6 -0
  14. package/corpus/templates/calendar/server/handlers/google-auth.ts +77 -21
  15. package/corpus/templates/calendar/server/lib/google-calendar.ts +19 -8
  16. package/corpus/templates/design/actions/apply-design-token-edit.ts +13 -6
  17. package/corpus/templates/design/actions/import-design-tokens.ts +17 -13
  18. package/corpus/templates/design/actions/preview-design-token-edit.ts +20 -3
  19. package/corpus/templates/design/actions/run-design-audit.ts +9 -2
  20. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +35 -14
  21. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +20 -3
  22. package/corpus/templates/design/app/pages/DesignEditor.tsx +237 -51
  23. package/corpus/templates/design/app/pages/VisualEdit.tsx +1 -1
  24. package/corpus/templates/design/changelog/2026-06-30-design-editor-undo-drag-drop-style-editing-and-visual-edit-s.md +6 -0
  25. package/corpus/templates/design/shared/resolve-tweaks.ts +29 -6
  26. package/dist/client/AgentPanel.d.ts +1 -1
  27. package/dist/client/AgentPanel.d.ts.map +1 -1
  28. package/dist/client/AgentPanel.js +18 -3
  29. package/dist/client/AgentPanel.js.map +1 -1
  30. package/dist/collab/awareness.d.ts +2 -2
  31. package/dist/collab/awareness.d.ts.map +1 -1
  32. package/dist/collab/routes.d.ts +2 -2
  33. package/dist/notifications/routes.d.ts +3 -3
  34. package/dist/progress/routes.d.ts +1 -1
  35. package/dist/resources/handlers.d.ts +3 -3
  36. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  37. package/dist/server/core-routes-plugin.js +1 -2
  38. package/dist/server/core-routes-plugin.js.map +1 -1
  39. package/dist/server/create-server.d.ts.map +1 -1
  40. package/dist/server/create-server.js +1 -2
  41. package/dist/server/create-server.js.map +1 -1
  42. package/dist/server/google-oauth.d.ts +2 -0
  43. package/dist/server/google-oauth.d.ts.map +1 -1
  44. package/dist/server/google-oauth.js +3 -0
  45. package/dist/server/google-oauth.js.map +1 -1
  46. package/dist/server/transcribe-voice.d.ts +1 -1
  47. package/package.json +1 -1
@@ -870,12 +870,35 @@ interface GeometryHistoryEntry {
870
870
  after: CanvasFrameGeometryById;
871
871
  }
872
872
 
873
- interface ContentHistoryEntry {
873
+ export interface ContentHistoryChange {
874
874
  fileId: string;
875
875
  before: string;
876
876
  after: string;
877
877
  }
878
878
 
879
+ export interface ContentHistoryGroup {
880
+ changes: ContentHistoryChange[];
881
+ }
882
+
883
+ export type ContentHistoryEntry = ContentHistoryChange | ContentHistoryGroup;
884
+
885
+ export function getContentHistoryChanges(
886
+ entry: ContentHistoryEntry,
887
+ ): ContentHistoryChange[] {
888
+ return "changes" in entry ? entry.changes : [entry];
889
+ }
890
+
891
+ export function getAvailableContentHistoryChanges(
892
+ entry: ContentHistoryEntry,
893
+ availableFileIds: Iterable<string>,
894
+ activeFileId?: string | null,
895
+ ): ContentHistoryChange[] {
896
+ const fileIds = new Set(availableFileIds);
897
+ return getContentHistoryChanges(entry).filter(
898
+ (change) => change.fileId === activeFileId || fileIds.has(change.fileId),
899
+ );
900
+ }
901
+
879
902
  type PatchProofStatus =
880
903
  | "runtime"
881
904
  | "queued"
@@ -3533,6 +3556,7 @@ export default function DesignEditor() {
3533
3556
  useState<{ screenId: string; layerId: string } | null>(null);
3534
3557
  const pendingOverviewScreenSelectionRef = useRef<string | null>(null);
3535
3558
  const pendingOverviewLayerSelectionRef = useRef<string | null>(null);
3559
+ const lastOverviewSelectedScreenIdsRef = useRef<string[]>([]);
3536
3560
  // Tracks the nodeId of the most recently created TEXT primitive across one
3537
3561
  // handleCreatePrimitive → handlePrimitiveCreated round-trip. Cleared after
3538
3562
  // use. Lets handlePrimitiveCreated trigger begin-text-edit without needing
@@ -3850,10 +3874,13 @@ export default function DesignEditor() {
3850
3874
  }, []);
3851
3875
  const recordContentHistoryEntry = useCallback(
3852
3876
  (entry: ContentHistoryEntry) => {
3853
- if (entry.before === entry.after) return;
3877
+ const changes = getContentHistoryChanges(entry).filter(
3878
+ (change) => change.before !== change.after,
3879
+ );
3880
+ if (changes.length === 0) return;
3854
3881
  contentUndoStackRef.current = [
3855
3882
  ...contentUndoStackRef.current.slice(-(MAX_DESIGN_UNDO_STACK - 1)),
3856
- entry,
3883
+ changes.length === 1 ? changes[0] : { changes },
3857
3884
  ];
3858
3885
  contentRedoStackRef.current = [];
3859
3886
  historyOrderRef.current = [
@@ -3910,6 +3937,13 @@ export default function DesignEditor() {
3910
3937
  useEffect(() => {
3911
3938
  viewModeRef.current = viewMode;
3912
3939
  }, [viewMode]);
3940
+
3941
+ useEffect(() => {
3942
+ if (viewMode !== "overview" || overviewSelectedScreenIds.length === 0) {
3943
+ return;
3944
+ }
3945
+ lastOverviewSelectedScreenIdsRef.current = [...overviewSelectedScreenIds];
3946
+ }, [overviewSelectedScreenIds, viewMode]);
3913
3947
  const [hasPendingGeneration, setHasPendingGeneration] = useState(() =>
3914
3948
  hasFreshPendingGeneration(id),
3915
3949
  );
@@ -6733,20 +6767,24 @@ export default function DesignEditor() {
6733
6767
  skipPreview?: boolean;
6734
6768
  immediateSave?: boolean;
6735
6769
  persist?: boolean;
6770
+ recordHistory?: boolean;
6736
6771
  updatedAt?: string;
6737
6772
  } = {},
6738
6773
  ) => {
6739
6774
  if (!activeFile || !canEditDesignRef.current) return;
6775
+ const shouldRecordHistory =
6776
+ options.recordHistory !== false && !options.updatedAt;
6740
6777
  const previousContent =
6741
6778
  collabContentFileIdRef.current === activeFile.id &&
6742
6779
  typeof collabContentRef.current === "string"
6743
6780
  ? collabContentRef.current
6744
6781
  : (activeFile.content ?? "");
6745
6782
  const yjsHistoryAvailable = Boolean(
6746
- ydoc && isSynced && undoManagerRef.current,
6783
+ shouldRecordHistory && ydoc && isSynced && undoManagerRef.current,
6747
6784
  );
6748
6785
  if (
6749
6786
  !suppressContentHistoryRef.current &&
6787
+ shouldRecordHistory &&
6750
6788
  !yjsHistoryAvailable &&
6751
6789
  previousContent !== nextContent
6752
6790
  ) {
@@ -6810,10 +6848,13 @@ export default function DesignEditor() {
6810
6848
  if (ydoc && isSynced) {
6811
6849
  const ytext = ydoc.getText("content");
6812
6850
  if (ytext.toString() !== nextContent) {
6813
- ydoc.transact(() => {
6814
- ytext.delete(0, ytext.length);
6815
- ytext.insert(0, nextContent);
6816
- }, LOCAL_EDIT_ORIGIN);
6851
+ ydoc.transact(
6852
+ () => {
6853
+ ytext.delete(0, ytext.length);
6854
+ ytext.insert(0, nextContent);
6855
+ },
6856
+ shouldRecordHistory ? LOCAL_EDIT_ORIGIN : TAB_ID,
6857
+ );
6817
6858
  }
6818
6859
  }
6819
6860
  if (options.persist === false) {
@@ -6849,6 +6890,7 @@ export default function DesignEditor() {
6849
6890
  refreshPreview?: boolean;
6850
6891
  skipPreview?: boolean;
6851
6892
  persist?: boolean;
6893
+ recordHistory?: boolean;
6852
6894
  updatedAt?: string;
6853
6895
  } = {},
6854
6896
  ) => {
@@ -6858,6 +6900,21 @@ export default function DesignEditor() {
6858
6900
  return;
6859
6901
  }
6860
6902
  const previousFile = files.find((file) => file.id === fileId);
6903
+ const previousContent =
6904
+ getScreenContent(fileId) ?? previousFile?.content ?? "";
6905
+ const shouldRecordHistory =
6906
+ options.recordHistory !== false && !options.updatedAt;
6907
+ if (
6908
+ !suppressContentHistoryRef.current &&
6909
+ shouldRecordHistory &&
6910
+ previousContent !== nextContent
6911
+ ) {
6912
+ recordContentHistoryEntry({
6913
+ fileId,
6914
+ before: previousContent,
6915
+ after: nextContent,
6916
+ });
6917
+ }
6861
6918
  if (options.updatedAt) {
6862
6919
  clearPendingLocalFileContent(fileId);
6863
6920
  } else {
@@ -6902,9 +6959,11 @@ export default function DesignEditor() {
6902
6959
  cancelQueuedFileContentSave,
6903
6960
  clearPendingLocalFileContent,
6904
6961
  files,
6962
+ getScreenContent,
6905
6963
  id,
6906
6964
  markPendingLocalFileContent,
6907
6965
  queryClient,
6966
+ recordContentHistoryEntry,
6908
6967
  saveFileContent,
6909
6968
  ],
6910
6969
  );
@@ -9461,10 +9520,27 @@ export default function DesignEditor() {
9461
9520
  destNodeAttrId,
9462
9521
  );
9463
9522
 
9523
+ recordContentHistoryEntry({
9524
+ changes: [
9525
+ {
9526
+ fileId: sourceScreenId,
9527
+ before: sourceContent,
9528
+ after: result.sourceHtml,
9529
+ },
9530
+ {
9531
+ fileId: targetScreenId,
9532
+ before: destContent,
9533
+ after: strippedDest,
9534
+ },
9535
+ ],
9536
+ });
9537
+
9464
9538
  applyFileContentUpdate(sourceScreenId, result.sourceHtml, {
9539
+ recordHistory: false,
9465
9540
  refreshPreview: true,
9466
9541
  });
9467
9542
  applyFileContentUpdate(targetScreenId, strippedDest, {
9543
+ recordHistory: false,
9468
9544
  refreshPreview: true,
9469
9545
  });
9470
9546
 
@@ -9478,7 +9554,13 @@ export default function DesignEditor() {
9478
9554
  setSelectedElement(elementInfoFromCodeLayerNode(movedNodeFinal));
9479
9555
  }
9480
9556
  },
9481
- [applyFileContentUpdate, canEditDesign, getScreenContent, t],
9557
+ [
9558
+ applyFileContentUpdate,
9559
+ canEditDesign,
9560
+ getScreenContent,
9561
+ recordContentHistoryEntry,
9562
+ t,
9563
+ ],
9482
9564
  );
9483
9565
 
9484
9566
  /**
@@ -9573,10 +9655,27 @@ export default function DesignEditor() {
9573
9655
  destNodeAttrId,
9574
9656
  );
9575
9657
 
9658
+ recordContentHistoryEntry({
9659
+ changes: [
9660
+ {
9661
+ fileId: sourceScreenId,
9662
+ before: sourceContent,
9663
+ after: result.sourceHtml,
9664
+ },
9665
+ {
9666
+ fileId: targetScreenId,
9667
+ before: destContent,
9668
+ after: strippedDest,
9669
+ },
9670
+ ],
9671
+ });
9672
+
9576
9673
  applyFileContentUpdate(sourceScreenId, result.sourceHtml, {
9674
+ recordHistory: false,
9577
9675
  refreshPreview: true,
9578
9676
  });
9579
9677
  applyFileContentUpdate(targetScreenId, strippedDest, {
9678
+ recordHistory: false,
9580
9679
  refreshPreview: true,
9581
9680
  });
9582
9681
 
@@ -9592,7 +9691,13 @@ export default function DesignEditor() {
9592
9691
  setSelectedElement(elementInfoFromCodeLayerNode(movedNodeFinal));
9593
9692
  }
9594
9693
  },
9595
- [applyFileContentUpdate, canEditDesign, getScreenContent, t],
9694
+ [
9695
+ applyFileContentUpdate,
9696
+ canEditDesign,
9697
+ getScreenContent,
9698
+ recordContentHistoryEntry,
9699
+ t,
9700
+ ],
9596
9701
  );
9597
9702
 
9598
9703
  const handleCutSelection = useCallback(async () => {
@@ -9800,12 +9905,12 @@ export default function DesignEditor() {
9800
9905
  const entry =
9801
9906
  contentUndoStackRef.current[contentUndoStackRef.current.length - 1];
9802
9907
  if (!entry) return false;
9803
- if (
9804
- entry.fileId !== activeFile?.id &&
9805
- !files.some((file) => file.id === entry.fileId)
9806
- ) {
9807
- return false;
9808
- }
9908
+ const changes = getAvailableContentHistoryChanges(
9909
+ entry,
9910
+ files.map((file) => file.id),
9911
+ activeFile?.id,
9912
+ );
9913
+ if (changes.length === 0) return false;
9809
9914
  contentUndoStackRef.current.pop();
9810
9915
  contentRedoStackRef.current = [
9811
9916
  ...contentRedoStackRef.current.slice(-(MAX_DESIGN_UNDO_STACK - 1)),
@@ -9817,27 +9922,34 @@ export default function DesignEditor() {
9817
9922
  ];
9818
9923
  suppressContentHistoryRef.current = true;
9819
9924
  try {
9820
- if (entry.fileId === activeFile?.id) {
9821
- applyLocalContentUpdate(entry.before, {
9822
- refreshPreview: false,
9823
- immediateSave: true,
9824
- });
9825
- } else {
9826
- applyFileContentUpdate(entry.fileId, entry.before, {
9827
- refreshPreview: false,
9828
- });
9925
+ for (const change of changes) {
9926
+ if (change.fileId === activeFile?.id) {
9927
+ applyLocalContentUpdate(change.before, {
9928
+ refreshPreview: false,
9929
+ immediateSave: true,
9930
+ recordHistory: false,
9931
+ });
9932
+ } else {
9933
+ applyFileContentUpdate(change.fileId, change.before, {
9934
+ recordHistory: false,
9935
+ refreshPreview: false,
9936
+ });
9937
+ }
9829
9938
  }
9830
9939
  } finally {
9831
9940
  suppressContentHistoryRef.current = false;
9832
9941
  }
9833
- if (entry.fileId === activeFile?.id) {
9942
+ const activeChange = changes.find(
9943
+ (change) => change.fileId === activeFile?.id,
9944
+ );
9945
+ if (activeChange) {
9834
9946
  setSelectedElement((prev) => {
9835
9947
  if (!prev) return prev;
9836
- return refreshElementInfoFromContent(entry.before, prev);
9948
+ return refreshElementInfoFromContent(activeChange.before, prev);
9837
9949
  });
9838
9950
  setHoveredElement((prev) => {
9839
9951
  if (!prev) return prev;
9840
- return refreshElementInfoFromContent(entry.before, prev);
9952
+ return refreshElementInfoFromContent(activeChange.before, prev);
9841
9953
  });
9842
9954
  }
9843
9955
  return true;
@@ -9927,12 +10039,12 @@ export default function DesignEditor() {
9927
10039
  const entry =
9928
10040
  contentRedoStackRef.current[contentRedoStackRef.current.length - 1];
9929
10041
  if (!entry) return false;
9930
- if (
9931
- entry.fileId !== activeFile?.id &&
9932
- !files.some((file) => file.id === entry.fileId)
9933
- ) {
9934
- return false;
9935
- }
10042
+ const changes = getAvailableContentHistoryChanges(
10043
+ entry,
10044
+ files.map((file) => file.id),
10045
+ activeFile?.id,
10046
+ );
10047
+ if (changes.length === 0) return false;
9936
10048
  contentRedoStackRef.current.pop();
9937
10049
  contentUndoStackRef.current = [
9938
10050
  ...contentUndoStackRef.current.slice(-(MAX_DESIGN_UNDO_STACK - 1)),
@@ -9944,27 +10056,34 @@ export default function DesignEditor() {
9944
10056
  ];
9945
10057
  suppressContentHistoryRef.current = true;
9946
10058
  try {
9947
- if (entry.fileId === activeFile?.id) {
9948
- applyLocalContentUpdate(entry.after, {
9949
- refreshPreview: false,
9950
- immediateSave: true,
9951
- });
9952
- } else {
9953
- applyFileContentUpdate(entry.fileId, entry.after, {
9954
- refreshPreview: false,
9955
- });
10059
+ for (const change of changes) {
10060
+ if (change.fileId === activeFile?.id) {
10061
+ applyLocalContentUpdate(change.after, {
10062
+ refreshPreview: false,
10063
+ immediateSave: true,
10064
+ recordHistory: false,
10065
+ });
10066
+ } else {
10067
+ applyFileContentUpdate(change.fileId, change.after, {
10068
+ recordHistory: false,
10069
+ refreshPreview: false,
10070
+ });
10071
+ }
9956
10072
  }
9957
10073
  } finally {
9958
10074
  suppressContentHistoryRef.current = false;
9959
10075
  }
9960
- if (entry.fileId === activeFile?.id) {
10076
+ const activeChange = changes.find(
10077
+ (change) => change.fileId === activeFile?.id,
10078
+ );
10079
+ if (activeChange) {
9961
10080
  setSelectedElement((prev) => {
9962
10081
  if (!prev) return prev;
9963
- return refreshElementInfoFromContent(entry.after, prev);
10082
+ return refreshElementInfoFromContent(activeChange.after, prev);
9964
10083
  });
9965
10084
  setHoveredElement((prev) => {
9966
10085
  if (!prev) return prev;
9967
- return refreshElementInfoFromContent(entry.after, prev);
10086
+ return refreshElementInfoFromContent(activeChange.after, prev);
9968
10087
  });
9969
10088
  }
9970
10089
  return true;
@@ -10077,6 +10196,15 @@ export default function DesignEditor() {
10077
10196
  transition?.updateCallbackDone?.catch(() => {});
10078
10197
  }, []);
10079
10198
 
10199
+ const getRestoredOverviewSelection = useCallback(() => {
10200
+ const fileIds = new Set(files.map((file) => file.id));
10201
+ const restored = lastOverviewSelectedScreenIdsRef.current.filter((id) =>
10202
+ fileIds.has(id),
10203
+ );
10204
+ if (restored.length > 0) return restored;
10205
+ return activeFileId && fileIds.has(activeFileId) ? [activeFileId] : [];
10206
+ }, [activeFileId, files]);
10207
+
10080
10208
  const enterOverviewFromZoom = useCallback(() => {
10081
10209
  if (viewModeRef.current === "overview") return;
10082
10210
  viewModeRef.current = "overview";
@@ -10084,6 +10212,7 @@ export default function DesignEditor() {
10084
10212
  pendingOverviewLayerSelectionRef.current = null;
10085
10213
  clearPendingOverviewLayerSelectionTimer();
10086
10214
  setCreatedOverviewLayerSelection(null);
10215
+ const restoredOverviewSelection = getRestoredOverviewSelection();
10087
10216
  runEditorViewTransition(() => {
10088
10217
  setDrawMode(false);
10089
10218
  setPinMode(false);
@@ -10091,9 +10220,15 @@ export default function DesignEditor() {
10091
10220
  setSelectedElement(null);
10092
10221
  setHoveredElement(null);
10093
10222
  setActiveTool("move");
10223
+ setOverviewSelectedScreenIds(restoredOverviewSelection);
10224
+ setSelectedLayerIdsState(restoredOverviewSelection);
10094
10225
  setViewMode("overview");
10095
10226
  });
10096
- }, [clearPendingOverviewLayerSelectionTimer, runEditorViewTransition]);
10227
+ }, [
10228
+ clearPendingOverviewLayerSelectionTimer,
10229
+ getRestoredOverviewSelection,
10230
+ runEditorViewTransition,
10231
+ ]);
10097
10232
 
10098
10233
  const enterSingleScreen = useCallback(
10099
10234
  (fileId?: string | null) => {
@@ -10198,6 +10333,14 @@ export default function DesignEditor() {
10198
10333
 
10199
10334
  const handleSidebarScreenSelect = useCallback(
10200
10335
  (screenId: string) => {
10336
+ if (
10337
+ viewModeRef.current === "overview" &&
10338
+ overviewSelectedScreenIds.length > 0
10339
+ ) {
10340
+ lastOverviewSelectedScreenIdsRef.current = [
10341
+ ...overviewSelectedScreenIds,
10342
+ ];
10343
+ }
10201
10344
  pendingOverviewScreenSelectionRef.current = null;
10202
10345
  pendingOverviewLayerSelectionRef.current = null;
10203
10346
  clearPendingOverviewLayerSelectionTimer();
@@ -10206,16 +10349,21 @@ export default function DesignEditor() {
10206
10349
  setSelectedLayerIdsState([]);
10207
10350
  enterSingleScreen(screenId);
10208
10351
  },
10209
- [clearPendingOverviewLayerSelectionTimer, enterSingleScreen],
10352
+ [
10353
+ clearPendingOverviewLayerSelectionTimer,
10354
+ enterSingleScreen,
10355
+ overviewSelectedScreenIds,
10356
+ ],
10210
10357
  );
10211
10358
 
10212
10359
  const handleSidebarScreenOverview = useCallback(() => {
10360
+ const restoredOverviewSelection = getRestoredOverviewSelection();
10213
10361
  pendingOverviewScreenSelectionRef.current = null;
10214
10362
  pendingOverviewLayerSelectionRef.current = null;
10215
10363
  clearPendingOverviewLayerSelectionTimer();
10216
10364
  setCreatedOverviewLayerSelection(null);
10217
- setOverviewSelectedScreenIds([]);
10218
- setSelectedLayerIdsState([]);
10365
+ setOverviewSelectedScreenIds(restoredOverviewSelection);
10366
+ setSelectedLayerIdsState(restoredOverviewSelection);
10219
10367
  if (viewModeRef.current === "overview") {
10220
10368
  setDrawMode(false);
10221
10369
  setPinMode(false);
@@ -10226,7 +10374,11 @@ export default function DesignEditor() {
10226
10374
  return;
10227
10375
  }
10228
10376
  enterOverviewFromZoom();
10229
- }, [clearPendingOverviewLayerSelectionTimer, enterOverviewFromZoom]);
10377
+ }, [
10378
+ clearPendingOverviewLayerSelectionTimer,
10379
+ enterOverviewFromZoom,
10380
+ getRestoredOverviewSelection,
10381
+ ]);
10230
10382
 
10231
10383
  const handlePinToolToggle = useCallback(() => {
10232
10384
  if (!activeFile || !canEditDesign) return;
@@ -12183,6 +12335,7 @@ ${serializedHtml}
12183
12335
  // Group by source file so multiple nodes from the same source are
12184
12336
  // applied sequentially against the running source content.
12185
12337
  const sourceContentMap = new Map<string, string>();
12338
+ const sourceOriginalContentMap = new Map<string, string>();
12186
12339
  const movedNodeIdByDraggedId = new Map<string, string>();
12187
12340
  for (const { draggedId, sourceFileId } of getLayerMoveIterationOrder(
12188
12341
  crossFileDrags,
@@ -12197,6 +12350,9 @@ ${serializedHtml}
12197
12350
  sourceFileContent: srcFile.content,
12198
12351
  sourceContentMap,
12199
12352
  });
12353
+ if (!sourceOriginalContentMap.has(sourceFileId)) {
12354
+ sourceOriginalContentMap.set(sourceFileId, currentSourceContent);
12355
+ }
12200
12356
 
12201
12357
  // The dragged node's data-agent-native-node-id is the node id tracked
12202
12358
  // by code-layer. Look up the actual attribute value from the owner.
@@ -12274,9 +12430,37 @@ ${serializedHtml}
12274
12430
  });
12275
12431
  }
12276
12432
 
12433
+ const hasCrossFileMoves = sourceContentMap.size > 0;
12434
+ if (hasCrossFileMoves) {
12435
+ recordContentHistoryEntry({
12436
+ changes: [
12437
+ ...Array.from(sourceContentMap.entries()).map(
12438
+ ([sourceFileId, newSourceContent]) => ({
12439
+ fileId: sourceFileId,
12440
+ before:
12441
+ sourceOriginalContentMap.get(sourceFileId) ??
12442
+ files.find((file) => file.id === sourceFileId)?.content ??
12443
+ "",
12444
+ after: newSourceContent,
12445
+ }),
12446
+ ),
12447
+ ...(nextDestContent !== destContent
12448
+ ? [
12449
+ {
12450
+ fileId: targetOwner.fileId,
12451
+ before: destContent,
12452
+ after: nextDestContent,
12453
+ },
12454
+ ]
12455
+ : []),
12456
+ ],
12457
+ });
12458
+ }
12459
+
12277
12460
  // Persist source files that changed.
12278
12461
  for (const [sourceFileId, newSourceContent] of sourceContentMap) {
12279
12462
  applyFileContentUpdate(sourceFileId, newSourceContent, {
12463
+ recordHistory: !hasCrossFileMoves,
12280
12464
  refreshPreview: false,
12281
12465
  });
12282
12466
  }
@@ -12284,6 +12468,7 @@ ${serializedHtml}
12284
12468
  // Persist dest file (which may also be the active file).
12285
12469
  if (nextDestContent !== destContent) {
12286
12470
  applyFileContentUpdate(targetOwner.fileId, nextDestContent, {
12471
+ recordHistory: !hasCrossFileMoves,
12287
12472
  refreshPreview: false,
12288
12473
  });
12289
12474
  }
@@ -12297,6 +12482,7 @@ ${serializedHtml}
12297
12482
  effectiveCodeLayerState,
12298
12483
  files,
12299
12484
  getFreshActiveContent,
12485
+ recordContentHistoryEntry,
12300
12486
  t,
12301
12487
  ],
12302
12488
  );
@@ -11,7 +11,7 @@ import { Link } from "react-router";
11
11
  import { Button } from "@/components/ui/button";
12
12
 
13
13
  function buildSignInHref(): string {
14
- const ret = "/?intent=save";
14
+ const ret = "/visual-edit?intent=save";
15
15
  return `${agentNativePath("/_agent-native/sign-in")}?return=${encodeURIComponent(ret)}`;
16
16
  }
17
17
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-30
4
+ ---
5
+
6
+ Design editor undo, drag/drop, style editing, and visual-edit save flows are more reliable.
@@ -36,27 +36,47 @@ export type TweakSelections = Record<string, string | number | boolean>;
36
36
  */
37
37
  const CSS_CUSTOM_PROPERTY_NAME = /^--[-_a-zA-Z0-9]+$/;
38
38
 
39
+ export function isSafeCssVarName(value: string): boolean {
40
+ return CSS_CUSTOM_PROPERTY_NAME.test(value);
41
+ }
42
+
43
+ export function isSafeCssTokenValue(value: string): boolean {
44
+ return (
45
+ value.length > 0 &&
46
+ value.length <= 300 &&
47
+ !/[;{}<>]/.test(value) &&
48
+ !/\/\*/.test(value) &&
49
+ !/[\u0000-\u001f\u007f]/.test(value)
50
+ );
51
+ }
52
+
39
53
  export function resolveTweaksToCssVars(
40
54
  tweaks: TweakDefinition[],
41
55
  selections: TweakSelections,
42
56
  ): Record<string, string> {
43
57
  const out: Record<string, string> = {};
44
58
  for (const t of tweaks) {
45
- if (!t.cssVar) continue;
59
+ if (!t.cssVar || !isSafeCssVarName(t.cssVar)) continue;
46
60
  const v = selections[t.id] ?? t.defaultValue;
47
- out[t.cssVar] = stringifyCssVarValue(t.cssVar, v, t.unit);
61
+ const resolved = stringifyCssVarValue(t.cssVar, v, t.unit);
62
+ if (isSafeCssTokenValue(resolved)) {
63
+ out[t.cssVar] = resolved;
64
+ }
48
65
  }
49
66
 
50
67
  for (const [key, value] of Object.entries(selections)) {
51
68
  if (!isDirectCssVarSelectionKey(key)) continue;
52
- out[key] = stringifyCssVarValue(key, value);
69
+ const resolved = stringifyCssVarValue(key, value);
70
+ if (isSafeCssTokenValue(resolved)) {
71
+ out[key] = resolved;
72
+ }
53
73
  }
54
74
 
55
75
  return out;
56
76
  }
57
77
 
58
78
  export function isDirectCssVarSelectionKey(key: string): boolean {
59
- return CSS_CUSTOM_PROPERTY_NAME.test(key);
79
+ return isSafeCssVarName(key);
60
80
  }
61
81
 
62
82
  function stringifyCssVarValue(
@@ -84,8 +104,11 @@ export function renderResolvedRootBlock(
84
104
  resolvedCssVars: Record<string, string>,
85
105
  ): string {
86
106
  const entries = Object.entries(resolvedCssVars);
87
- if (entries.length === 0) return "";
88
- const decls = entries
107
+ const safeEntries = entries.filter(
108
+ ([name, value]) => isSafeCssVarName(name) && isSafeCssTokenValue(value),
109
+ );
110
+ if (safeEntries.length === 0) return "";
111
+ const decls = safeEntries
89
112
  .map(([name, value]) => ` ${name}: ${value};`)
90
113
  .join("\n");
91
114
  return `:root {\n${decls}\n}`;
@@ -188,6 +188,6 @@ export declare function focusAgentChat(): void;
188
188
  */
189
189
  export declare function AgentToggleButton({ className }: {
190
190
  className?: string;
191
- }): React.JSX.Element;
191
+ }): React.JSX.Element | null;
192
192
  export {};
193
193
  //# sourceMappingURL=AgentPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentPanel.d.ts","sourceRoot":"","sources":["../../src/client/AgentPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AgentPanel.d.ts","sourceRoot":"","sources":["../../src/client/AgentPanel.tsx"],"names":[],"mappings":"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"}