@alpaca-editor/core 1.0.4170 → 1.0.4173

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 (213) hide show
  1. package/dist/agents-view/AgentsView.d.ts +5 -0
  2. package/dist/agents-view/AgentsView.js +213 -0
  3. package/dist/agents-view/AgentsView.js.map +1 -0
  4. package/dist/components/ui/context-menu.js +51 -7
  5. package/dist/components/ui/context-menu.js.map +1 -1
  6. package/dist/config/config.d.ts +1 -2
  7. package/dist/config/config.js +103 -8
  8. package/dist/config/config.js.map +1 -1
  9. package/dist/config/types.d.ts +1 -1
  10. package/dist/editor/ConfirmationDialog.js +2 -1
  11. package/dist/editor/ConfirmationDialog.js.map +1 -1
  12. package/dist/editor/ContentTree.d.ts +2 -1
  13. package/dist/editor/ContentTree.js +18 -3
  14. package/dist/editor/ContentTree.js.map +1 -1
  15. package/dist/editor/ContextMenu.js +1 -1
  16. package/dist/editor/ContextMenu.js.map +1 -1
  17. package/dist/editor/FieldList.js +7 -3
  18. package/dist/editor/FieldList.js.map +1 -1
  19. package/dist/editor/FieldListField.d.ts +3 -2
  20. package/dist/editor/FieldListField.js +4 -4
  21. package/dist/editor/FieldListField.js.map +1 -1
  22. package/dist/editor/FieldListFieldWithFallbacks.d.ts +2 -1
  23. package/dist/editor/FieldListFieldWithFallbacks.js +5 -2
  24. package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
  25. package/dist/editor/ItemInfo.js +8 -2
  26. package/dist/editor/ItemInfo.js.map +1 -1
  27. package/dist/editor/MainLayout.js +1 -1
  28. package/dist/editor/PictureEditor.js +2 -4
  29. package/dist/editor/PictureEditor.js.map +1 -1
  30. package/dist/editor/QuickItemSwitcher.d.ts +9 -0
  31. package/dist/editor/QuickItemSwitcher.js +56 -0
  32. package/dist/editor/QuickItemSwitcher.js.map +1 -0
  33. package/dist/editor/ai/AgentCostDisplay.js +4 -4
  34. package/dist/editor/ai/AgentCostDisplay.js.map +1 -1
  35. package/dist/editor/ai/AgentProfilesOverview.d.ts +9 -0
  36. package/dist/editor/ai/AgentProfilesOverview.js +16 -0
  37. package/dist/editor/ai/AgentProfilesOverview.js.map +1 -0
  38. package/dist/editor/ai/AgentTerminal.d.ts +2 -1
  39. package/dist/editor/ai/AgentTerminal.js +1051 -557
  40. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  41. package/dist/editor/ai/Agents.js +108 -31
  42. package/dist/editor/ai/Agents.js.map +1 -1
  43. package/dist/editor/ai/AiResponseMessage.d.ts +2 -1
  44. package/dist/editor/ai/AiResponseMessage.js +4 -2
  45. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  46. package/dist/editor/ai/ContextInfoBar.js +17 -17
  47. package/dist/editor/ai/ToolCallDisplay.js +4 -2
  48. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  49. package/dist/editor/ai/useAgentStatus.js +21 -9
  50. package/dist/editor/ai/useAgentStatus.js.map +1 -1
  51. package/dist/editor/client/EditorShell.js +172 -21
  52. package/dist/editor/client/EditorShell.js.map +1 -1
  53. package/dist/editor/client/hooks/useSocketMessageHandler.js +12 -0
  54. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  55. package/dist/editor/client/ui/EditorChrome.js +1 -1
  56. package/dist/editor/client/ui/EditorChrome.js.map +1 -1
  57. package/dist/editor/commands/itemCommands.d.ts +1 -0
  58. package/dist/editor/commands/itemCommands.js +53 -1
  59. package/dist/editor/commands/itemCommands.js.map +1 -1
  60. package/dist/editor/control-center/WebSocketMessages.js +4 -1
  61. package/dist/editor/control-center/WebSocketMessages.js.map +1 -1
  62. package/dist/editor/control-center/parhelia-setup/Overview.d.ts +1 -0
  63. package/dist/editor/control-center/parhelia-setup/Overview.js +91 -0
  64. package/dist/editor/control-center/parhelia-setup/Overview.js.map +1 -0
  65. package/dist/editor/control-center/setup-steps/AiSetupStep/tools/GenerateToolsSection.js +4 -0
  66. package/dist/editor/control-center/setup-steps/AiSetupStep/tools/GenerateToolsSection.js.map +1 -1
  67. package/dist/editor/field-types/AttachmentEditor.d.ts +7 -2
  68. package/dist/editor/field-types/AttachmentEditor.js +71 -3
  69. package/dist/editor/field-types/AttachmentEditor.js.map +1 -1
  70. package/dist/editor/field-types/DropLinkEditor.js +2 -2
  71. package/dist/editor/field-types/DropLinkEditor.js.map +1 -1
  72. package/dist/editor/field-types/DropListEditor.js +2 -1
  73. package/dist/editor/field-types/DropListEditor.js.map +1 -1
  74. package/dist/editor/field-types/InternalLinkFieldEditor.js +3 -3
  75. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
  76. package/dist/editor/field-types/MultiLineText.d.ts +2 -1
  77. package/dist/editor/field-types/MultiLineText.js +2 -2
  78. package/dist/editor/field-types/MultiLineText.js.map +1 -1
  79. package/dist/editor/field-types/RawEditor.d.ts +2 -1
  80. package/dist/editor/field-types/RawEditor.js +2 -2
  81. package/dist/editor/field-types/RawEditor.js.map +1 -1
  82. package/dist/editor/field-types/SingleLineText.d.ts +2 -1
  83. package/dist/editor/field-types/SingleLineText.js +2 -2
  84. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  85. package/dist/editor/field-types/TreeListEditor.js +9 -7
  86. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  87. package/dist/editor/fieldTypes.d.ts +4 -0
  88. package/dist/editor/media-selector/MediaFolderBrowser.js +68 -7
  89. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
  90. package/dist/editor/media-selector/TreeSelector.js +1 -1
  91. package/dist/editor/media-selector/TreeSelector.js.map +1 -1
  92. package/dist/editor/menubar/ActiveUsers.js +2 -2
  93. package/dist/editor/menubar/FavoritesControls.js +2 -2
  94. package/dist/editor/menubar/FavoritesControls.js.map +1 -1
  95. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +1 -1
  96. package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
  97. package/dist/editor/page-editor-chrome/FrameMenu.js +10 -1
  98. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  99. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +14 -4
  100. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  101. package/dist/editor/page-viewer/PageViewerFrame.js +17 -7
  102. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  103. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +14 -0
  104. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +1 -1
  105. package/dist/editor/services/agentService.d.ts +6 -2
  106. package/dist/editor/services/agentService.js +13 -2
  107. package/dist/editor/services/agentService.js.map +1 -1
  108. package/dist/editor/services/aiService.d.ts +5 -1
  109. package/dist/editor/services/aiService.js +1 -1
  110. package/dist/editor/services/aiService.js.map +1 -1
  111. package/dist/editor/services/contentService.d.ts +1 -1
  112. package/dist/editor/services/contentService.js +4 -2
  113. package/dist/editor/services/contentService.js.map +1 -1
  114. package/dist/editor/services/editService.d.ts +6 -1
  115. package/dist/editor/services/editService.js +7 -1
  116. package/dist/editor/services/editService.js.map +1 -1
  117. package/dist/editor/services/setupService.d.ts +21 -0
  118. package/dist/editor/services/setupService.js +10 -0
  119. package/dist/editor/services/setupService.js.map +1 -0
  120. package/dist/editor/sidebar/ComponentTree.js +15 -1
  121. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  122. package/dist/editor/sidebar/SidebarView.js +1 -1
  123. package/dist/editor/sidebar/SidebarView.js.map +1 -1
  124. package/dist/editor/ui/ItemSearch.d.ts +1 -0
  125. package/dist/editor/ui/ItemSearch.js +2 -2
  126. package/dist/editor/ui/ItemSearch.js.map +1 -1
  127. package/dist/editor/ui/PerfectTree.d.ts +5 -1
  128. package/dist/editor/ui/PerfectTree.js +308 -29
  129. package/dist/editor/ui/PerfectTree.js.map +1 -1
  130. package/dist/editor/ui/SimpleIconButton.js +1 -1
  131. package/dist/editor/ui/SimpleIconButton.js.map +1 -1
  132. package/dist/editor/ui/TemplateSelectorDialog.d.ts +8 -0
  133. package/dist/editor/ui/TemplateSelectorDialog.js +61 -0
  134. package/dist/editor/ui/TemplateSelectorDialog.js.map +1 -0
  135. package/dist/editor/utils/keyboardNavigation.d.ts +2 -0
  136. package/dist/editor/utils/keyboardNavigation.js +80 -2
  137. package/dist/editor/utils/keyboardNavigation.js.map +1 -1
  138. package/dist/editor/views/SingleEditView.js +6 -4
  139. package/dist/editor/views/SingleEditView.js.map +1 -1
  140. package/dist/index.d.ts +2 -2
  141. package/dist/index.js +2 -2
  142. package/dist/index.js.map +1 -1
  143. package/dist/revision.d.ts +2 -2
  144. package/dist/revision.js +2 -2
  145. package/dist/splash-screen/SplashScreen.js +78 -4
  146. package/dist/splash-screen/SplashScreen.js.map +1 -1
  147. package/dist/styles.css +164 -20
  148. package/dist/types.d.ts +7 -1
  149. package/package.json +1 -1
  150. package/src/agents-view/AgentsView.tsx +431 -0
  151. package/src/components/ui/context-menu.tsx +62 -7
  152. package/src/config/config.tsx +112 -7
  153. package/src/config/types.ts +8 -2
  154. package/src/editor/ConfirmationDialog.tsx +42 -10
  155. package/src/editor/ContentTree.tsx +20 -1
  156. package/src/editor/ContextMenu.tsx +4 -1
  157. package/src/editor/FieldList.tsx +10 -4
  158. package/src/editor/FieldListField.tsx +7 -0
  159. package/src/editor/FieldListFieldWithFallbacks.tsx +10 -0
  160. package/src/editor/ItemInfo.tsx +15 -1
  161. package/src/editor/MainLayout.tsx +1 -1
  162. package/src/editor/PictureEditor.tsx +21 -23
  163. package/src/editor/QuickItemSwitcher.tsx +190 -0
  164. package/src/editor/ai/AgentCostDisplay.tsx +28 -6
  165. package/src/editor/ai/AgentProfilesOverview.tsx +81 -0
  166. package/src/editor/ai/AgentTerminal.tsx +734 -187
  167. package/src/editor/ai/Agents.tsx +167 -67
  168. package/src/editor/ai/AiResponseMessage.tsx +12 -1
  169. package/src/editor/ai/ContextInfoBar.tsx +17 -17
  170. package/src/editor/ai/ToolCallDisplay.tsx +2 -5
  171. package/src/editor/ai/useAgentStatus.ts +24 -9
  172. package/src/editor/client/EditorShell.tsx +231 -31
  173. package/src/editor/client/hooks/useSocketMessageHandler.ts +28 -13
  174. package/src/editor/client/ui/EditorChrome.tsx +1 -1
  175. package/src/editor/commands/itemCommands.tsx +77 -0
  176. package/src/editor/control-center/WebSocketMessages.tsx +4 -1
  177. package/src/editor/control-center/parhelia-setup/Overview.tsx +184 -0
  178. package/src/editor/control-center/setup-steps/AiSetupStep/tools/GenerateToolsSection.tsx +5 -0
  179. package/src/editor/field-types/AttachmentEditor.tsx +111 -3
  180. package/src/editor/field-types/DropLinkEditor.tsx +2 -2
  181. package/src/editor/field-types/DropListEditor.tsx +2 -1
  182. package/src/editor/field-types/InternalLinkFieldEditor.tsx +3 -3
  183. package/src/editor/field-types/MultiLineText.tsx +3 -0
  184. package/src/editor/field-types/RawEditor.tsx +3 -0
  185. package/src/editor/field-types/SingleLineText.tsx +3 -0
  186. package/src/editor/field-types/TreeListEditor.tsx +32 -24
  187. package/src/editor/fieldTypes.ts +4 -0
  188. package/src/editor/media-selector/MediaFolderBrowser.tsx +93 -9
  189. package/src/editor/media-selector/TreeSelector.tsx +1 -0
  190. package/src/editor/menubar/ActiveUsers.tsx +2 -2
  191. package/src/editor/menubar/FavoritesControls.tsx +5 -5
  192. package/src/editor/menubar/toolbar-sections/UtilityControls.tsx +1 -1
  193. package/src/editor/page-editor-chrome/FrameMenu.tsx +10 -1
  194. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +12 -4
  195. package/src/editor/page-viewer/PageViewerFrame.tsx +15 -6
  196. package/src/editor/page-viewer/pageModelSkeletonBuilder.ts +17 -0
  197. package/src/editor/services/agentService.ts +18 -2
  198. package/src/editor/services/aiService.ts +6 -2
  199. package/src/editor/services/contentService.ts +4 -1
  200. package/src/editor/services/editService.ts +23 -3
  201. package/src/editor/services/setupService.ts +35 -0
  202. package/src/editor/sidebar/ComponentTree.tsx +16 -1
  203. package/src/editor/sidebar/SidebarView.tsx +1 -1
  204. package/src/editor/ui/ItemSearch.tsx +3 -1
  205. package/src/editor/ui/PerfectTree.tsx +393 -42
  206. package/src/editor/ui/SimpleIconButton.tsx +1 -0
  207. package/src/editor/ui/TemplateSelectorDialog.tsx +129 -0
  208. package/src/editor/utils/keyboardNavigation.ts +97 -1
  209. package/src/editor/views/SingleEditView.tsx +27 -13
  210. package/src/index.ts +3 -3
  211. package/src/revision.ts +2 -2
  212. package/src/splash-screen/SplashScreen.tsx +134 -2
  213. package/src/types.ts +9 -1
@@ -120,6 +120,7 @@ import { Toaster } from "../../components/ui/sonner";
120
120
 
121
121
  import { Tour } from "../../tour/Tour";
122
122
  import { usePageViewContext } from "../page-viewer/pageViewContext";
123
+ import { QuickItemSwitcher } from "../QuickItemSwitcher";
123
124
 
124
125
  import {
125
126
  getComments,
@@ -388,7 +389,7 @@ export function EditorShell({
388
389
 
389
390
  const [enableCompletions, setEnableCompletions] = useState(false);
390
391
  const [showComponentNavigator, setShowComponentNavigator] = useState(
391
- userPreferences.showComponentNavigator ?? true,
392
+ userPreferences.showComponentNavigator ?? false,
392
393
  );
393
394
  const [showAgentsPanel, setShowAgentsPanel] = useState(
394
395
  userPreferences.showAgentsPanel ?? false,
@@ -409,6 +410,11 @@ export function EditorShell({
409
410
 
410
411
  const [favorites, setFavorites] = useState<any[]>([]);
411
412
 
413
+ // Quick item switcher state
414
+ const [quickSwitcherVisible, setQuickSwitcherVisible] = useState(false);
415
+ const [quickSwitcherSelectedIndex, setQuickSwitcherSelectedIndex] =
416
+ useState(0);
417
+
412
418
  // Track initial load to know when to sync state from URL vs URL from state
413
419
  const [isInitialLoad, setIsInitialLoad] = useState(true);
414
420
 
@@ -1511,6 +1517,109 @@ export function EditorShell({
1511
1517
  [operations, ignoreBlur, sessionId],
1512
1518
  );
1513
1519
 
1520
+ // Quick switcher handlers
1521
+ const showQuickSwitcher = useCallback(
1522
+ (show: boolean) => {
1523
+ console.log(
1524
+ `[QuickSwitcher] showQuickSwitcher called: show=${show}, historyLength=${browseHistory.length}`,
1525
+ );
1526
+ if (show && browseHistory.length > 1) {
1527
+ setQuickSwitcherVisible(true);
1528
+ // Start with index 1 (second item - previous item) for quick switching
1529
+ setQuickSwitcherSelectedIndex(1);
1530
+ console.log("[QuickSwitcher] Switcher opened, selected index: 1");
1531
+ console.log(
1532
+ "[QuickSwitcher] Browse history:",
1533
+ browseHistory.map((h, i) => `[${i}] ${h.name}`),
1534
+ );
1535
+ } else {
1536
+ setQuickSwitcherVisible(false);
1537
+ console.log("[QuickSwitcher] Switcher closed");
1538
+ }
1539
+ },
1540
+ [browseHistory],
1541
+ );
1542
+
1543
+ const cycleQuickSwitcher = useCallback(
1544
+ (direction: "next" | "prev" | "up" | "down") => {
1545
+ console.log(
1546
+ `[QuickSwitcher] cycleQuickSwitcher: direction=${direction}, visible=${quickSwitcherVisible}`,
1547
+ );
1548
+ if (!quickSwitcherVisible) return;
1549
+ const maxItems = Math.min(5, browseHistory.length);
1550
+
1551
+ setQuickSwitcherSelectedIndex((current) => {
1552
+ let newIndex = current;
1553
+
1554
+ // Determine grid layout (responsive columns)
1555
+ // Matches the grid in QuickItemSwitcher: 2/3/4/5 columns
1556
+ const getColumnsForWidth = () => {
1557
+ const width = window.innerWidth;
1558
+ if (width >= 1280) return 5; // xl
1559
+ if (width >= 1024) return 4; // lg
1560
+ if (width >= 768) return 3; // md
1561
+ return 2; // default
1562
+ };
1563
+
1564
+ const columns = getColumnsForWidth();
1565
+
1566
+ switch (direction) {
1567
+ case "next":
1568
+ newIndex = (current + 1) % maxItems;
1569
+ break;
1570
+ case "prev":
1571
+ newIndex = (current - 1 + maxItems) % maxItems;
1572
+ break;
1573
+ case "down":
1574
+ newIndex = current + columns;
1575
+ if (newIndex >= maxItems) {
1576
+ // Wrap to first row
1577
+ newIndex = current % columns;
1578
+ }
1579
+ break;
1580
+ case "up":
1581
+ newIndex = current - columns;
1582
+ if (newIndex < 0) {
1583
+ // Wrap to last row
1584
+ const currentCol = current % columns;
1585
+ const rows = Math.ceil(maxItems / columns);
1586
+ newIndex = (rows - 1) * columns + currentCol;
1587
+ if (newIndex >= maxItems) {
1588
+ newIndex = maxItems - columns + currentCol;
1589
+ }
1590
+ }
1591
+ break;
1592
+ }
1593
+
1594
+ console.log(
1595
+ `[QuickSwitcher] Cycling from index ${current} to ${newIndex} (${columns} columns)`,
1596
+ );
1597
+ return newIndex;
1598
+ });
1599
+ },
1600
+ [quickSwitcherVisible, browseHistory],
1601
+ );
1602
+
1603
+ const handleQuickSwitcherSelect = useCallback(
1604
+ (index: number) => {
1605
+ console.log(`[QuickSwitcher] Selecting item at index ${index}`);
1606
+ const selectedItem = browseHistory[index];
1607
+ if (selectedItem) {
1608
+ console.log(`[QuickSwitcher] Loading item:`, selectedItem);
1609
+ loadItem(
1610
+ {
1611
+ id: selectedItem.id,
1612
+ language: selectedItem.language,
1613
+ version: selectedItem.version || 0,
1614
+ },
1615
+ { addToBrowseHistory: false },
1616
+ );
1617
+ }
1618
+ setQuickSwitcherVisible(false);
1619
+ },
1620
+ [browseHistory, loadItem],
1621
+ );
1622
+
1514
1623
  const { handleKeyDown } = useKeyboardNavigation({
1515
1624
  editContextRef,
1516
1625
  operations,
@@ -1522,10 +1631,57 @@ export function EditorShell({
1522
1631
  showInfoToast,
1523
1632
  showErrorToast,
1524
1633
  executeCommand,
1634
+ showQuickSwitcher,
1635
+ cycleQuickSwitcher,
1525
1636
  });
1526
1637
 
1527
1638
  useGlobalEditorKeyDown(handleKeyDown);
1528
1639
 
1640
+ // Global keydown/keyup handler to manage quick switcher
1641
+ useEffect(() => {
1642
+ const handleKeyDown = (event: KeyboardEvent) => {
1643
+ if (!quickSwitcherVisible) return;
1644
+
1645
+ // Enter to select and close
1646
+ if (event.key === "Enter") {
1647
+ event.preventDefault();
1648
+ handleQuickSwitcherSelect(quickSwitcherSelectedIndex);
1649
+ }
1650
+ };
1651
+
1652
+ const handleKeyUp = (event: KeyboardEvent) => {
1653
+ // Close on Escape without selecting
1654
+ if (event.key === "Escape" && quickSwitcherVisible) {
1655
+ setQuickSwitcherVisible(false);
1656
+ }
1657
+ // Close and select when releasing Ctrl, Alt, or Meta (Win key)
1658
+ if (
1659
+ (event.key === "Control" ||
1660
+ event.key === "Alt" ||
1661
+ event.key === "Meta") &&
1662
+ quickSwitcherVisible
1663
+ ) {
1664
+ // Small delay to ensure the key release is not part of the initial trigger
1665
+ setTimeout(() => {
1666
+ handleQuickSwitcherSelect(quickSwitcherSelectedIndex);
1667
+ }, 50);
1668
+ }
1669
+ };
1670
+
1671
+ if (typeof window !== "undefined") {
1672
+ window.addEventListener("keydown", handleKeyDown);
1673
+ window.addEventListener("keyup", handleKeyUp);
1674
+ return () => {
1675
+ window.removeEventListener("keydown", handleKeyDown);
1676
+ window.removeEventListener("keyup", handleKeyUp);
1677
+ };
1678
+ }
1679
+ }, [
1680
+ quickSwitcherVisible,
1681
+ quickSwitcherSelectedIndex,
1682
+ handleQuickSwitcherSelect,
1683
+ ]);
1684
+
1529
1685
  // Global ctrl+click handler for GUID detection and navigation
1530
1686
  useEffect(() => {
1531
1687
  const isGuid = (text: string): boolean => {
@@ -1998,34 +2154,72 @@ export function EditorShell({
1998
2154
 
1999
2155
  console.log("Field action after setActiveFieldActions");
2000
2156
 
2001
- await executeFieldServerAction(
2002
- fieldDescriptor.item,
2003
- fieldDescriptor.fieldId,
2004
- contentEditorItem!.descriptor,
2005
- actionButton.action,
2006
- editContext!.sessionId,
2007
- selectedRange?.text || "",
2008
- parameters || {},
2009
- (data: any) => {
2010
- console.log("Field action progress", data);
2011
- // Update progress message if available
2012
- if (data?.responseText) {
2013
- op.message = data.responseText;
2014
- setActiveFieldActions((prevFieldActions) => [
2015
- ...prevFieldActions,
2016
- ]);
2017
- }
2018
- },
2019
- );
2020
-
2021
- console.log("Field action completed", op);
2157
+ try {
2158
+ await executeFieldServerAction(
2159
+ fieldDescriptor.item,
2160
+ fieldDescriptor.fieldId,
2161
+ contentEditorItem!.descriptor,
2162
+ actionButton.action,
2163
+ editContext!.sessionId,
2164
+ selectedRange?.text || "",
2165
+ parameters || {},
2166
+ (data: any) => {
2167
+ console.log("Field action progress", data);
2168
+ // Update progress message if available
2169
+ if (data?.responseText) {
2170
+ op.message = data.responseText;
2171
+ setActiveFieldActions((prevFieldActions) => [
2172
+ ...prevFieldActions,
2173
+ ]);
2174
+ }
2175
+ },
2176
+ );
2022
2177
 
2023
- itemsRepository.refreshItems([fieldDescriptor.item]);
2178
+ console.log("Field action completed", op);
2179
+
2180
+ itemsRepository.refreshItems([fieldDescriptor.item]);
2181
+
2182
+ // Only mark as success if no websocket error has been reported
2183
+ if (op.state === "running") {
2184
+ op.state = "success";
2185
+ // Auto-dismiss successful actions after a brief delay
2186
+ setTimeout(() => {
2187
+ setActiveFieldActions((prevFieldActions) =>
2188
+ prevFieldActions.filter(
2189
+ (x) =>
2190
+ !(
2191
+ x.field.fieldId === fieldDescriptor.fieldId &&
2192
+ x.field.item.id === fieldDescriptor.item.id &&
2193
+ x.field.item.language ===
2194
+ fieldDescriptor.item.language &&
2195
+ x.field.item.version === fieldDescriptor.item.version &&
2196
+ x.state === "success"
2197
+ ),
2198
+ ),
2199
+ );
2200
+ }, 500);
2201
+ }
2202
+ requestRefresh("immediate");
2203
+ } catch (error) {
2204
+ console.error("Field action failed", error);
2205
+
2206
+ // Mark as failed and show error message
2207
+ op.state = "error";
2208
+ op.message =
2209
+ error instanceof Error ? error.message : "Field action failed";
2210
+
2211
+ // Update the field action state to show error
2212
+ setActiveFieldActions((prevFieldActions) => {
2213
+ const isSameField = (x: FieldAction) =>
2214
+ x.field.fieldId == fieldDescriptor.fieldId &&
2215
+ x.field.item.id == fieldItem.id &&
2216
+ x.field.item.language == fieldItem.language &&
2217
+ x.field.item.version == fieldItem.version;
2218
+
2219
+ return [...prevFieldActions.filter((x) => !isSameField(x)), op];
2220
+ });
2024
2221
 
2025
- // Only mark as success if no websocket error has been reported
2026
- if (op.state === "running") {
2027
- op.state = "success";
2028
- // Auto-dismiss successful actions after a brief delay
2222
+ // Auto-dismiss error after a longer delay
2029
2223
  setTimeout(() => {
2030
2224
  setActiveFieldActions((prevFieldActions) =>
2031
2225
  prevFieldActions.filter(
@@ -2034,14 +2228,12 @@ export function EditorShell({
2034
2228
  x.field.fieldId === fieldDescriptor.fieldId &&
2035
2229
  x.field.item.id === fieldDescriptor.item.id &&
2036
2230
  x.field.item.language === fieldDescriptor.item.language &&
2037
- x.field.item.version === fieldDescriptor.item.version &&
2038
- x.state === "success"
2231
+ x.field.item.version === fieldDescriptor.item.version
2039
2232
  ),
2040
2233
  ),
2041
2234
  );
2042
- }, 500);
2235
+ }, 3000);
2043
2236
  }
2044
- requestRefresh("immediate");
2045
2237
  }
2046
2238
  },
2047
2239
  dismissFieldAction: (fieldDescriptor: FieldDescriptor) => {
@@ -2251,6 +2443,7 @@ export function EditorShell({
2251
2443
  setCurrentWizardId,
2252
2444
  favorites,
2253
2445
  loadFavorites,
2446
+ isQuickSwitcherVisible: quickSwitcherVisible,
2254
2447
  // Context factory registry methods
2255
2448
  registerContextFactory: (
2256
2449
  name: string,
@@ -2700,6 +2893,13 @@ export function EditorShell({
2700
2893
  {dialog}
2701
2894
  <Toaster position="top-center" />{" "}
2702
2895
  <ConfirmationDialog ref={confirmationDialogRef} />
2896
+ <QuickItemSwitcher
2897
+ visible={quickSwitcherVisible}
2898
+ items={browseHistory.slice(0, 5)}
2899
+ selectedIndex={quickSwitcherSelectedIndex}
2900
+ onSelect={handleQuickSwitcherSelect}
2901
+ onClose={() => setQuickSwitcherVisible(false)}
2902
+ />
2703
2903
  <EditContextMenu ref={contextMenuRef} />
2704
2904
  {media.mediaSelectorVisible && (
2705
2905
  <MediaSelector
@@ -133,21 +133,21 @@ export function useSocketMessageHandler(deps: {
133
133
  version: 0,
134
134
  });
135
135
  }
136
- } else {
137
- await itemsRepository.refreshItems(
138
- [message.payload.item],
139
- message.payload.changes,
140
- );
141
- const changes = message?.payload?.changes;
142
- const isVersionChange = changes?.versions === true;
143
- if (
144
- isVersionChange &&
145
- message.payload.item.id === currentItemDescriptor?.id
146
- ) {
147
- await loadItemVersions();
136
+ } else {
137
+ await itemsRepository.refreshItems(
138
+ [message.payload.item],
139
+ message.payload.changes,
140
+ );
141
+ const changes = message?.payload?.changes;
142
+ const isVersionChange = changes?.versions === true;
143
+ if (
144
+ isVersionChange &&
145
+ message.payload.item.id === currentItemDescriptor?.id
146
+ ) {
147
+ await loadItemVersions();
148
+ }
148
149
  }
149
150
  }
150
- }
151
151
 
152
152
  if (message.type === "item-version-added") {
153
153
  if (currentItemRef.current) {
@@ -334,6 +334,21 @@ export function useSocketMessageHandler(deps: {
334
334
  }
335
335
  }
336
336
 
337
+ // Agent WebSocket messages - forward to agent terminal via listeners
338
+ if (
339
+ message.type === "agent:name:updated" ||
340
+ message.type === "agent:status:changed" ||
341
+ message.type === "agent:run:start" ||
342
+ message.type === "agent:user:message" ||
343
+ message.type === "agent:run:delta" ||
344
+ message.type === "agent:run:status" ||
345
+ message.type === "agent:run:complete" ||
346
+ message.type === "agent:run:error"
347
+ ) {
348
+ // These messages are handled by AgentTerminal via socketMessageListeners
349
+ // Just pass through to listeners
350
+ }
351
+
337
352
  socketMessageListeners.current.forEach((listener) => listener(message));
338
353
  },
339
354
  [currentItemDescriptor, sessionId],
@@ -65,7 +65,7 @@ export function EditorChrome(props: {
65
65
  title: "Agents",
66
66
  content: <Agents />,
67
67
  initialSize: 70,
68
- noOverflow: true,
68
+ noOverflow: false,
69
69
  },
70
70
  ],
71
71
  }}
@@ -14,6 +14,10 @@ import {
14
14
  CopyMoveTargetSelectorDialog,
15
15
  CopyMoveTargetSelectorDialogProps,
16
16
  } from "../ui/CopyMoveTargetSelectorDialog";
17
+ import {
18
+ TemplateSelectorDialog,
19
+ TemplateSelectorDialogProps,
20
+ } from "../ui/TemplateSelectorDialog";
17
21
  import { defaultTranslateAll } from "./localizeItem/LocalizeItemUtils";
18
22
  import { TranslationStatus } from "../../config/types";
19
23
  import {
@@ -28,7 +32,9 @@ import {
28
32
  Upload,
29
33
  Globe,
30
34
  CopyPlus,
35
+ RefreshCw,
31
36
  } from "lucide-react";
37
+ import { executeChangeTemplate } from "../services/editService";
32
38
 
33
39
  export type ItemCommandData = CommandData & {
34
40
  items: FullItem[];
@@ -42,6 +48,7 @@ export const deleteItemCommand: ItemCommand = {
42
48
  id: "deleteItem",
43
49
  label: "Delete",
44
50
  icon: <Trash2 strokeWidth={1} />,
51
+ keyBinding: "Delete",
45
52
  disabled: (context: ItemCommandContext) =>
46
53
  !context.data?.items || !context.data?.items[0]?.canDelete || false,
47
54
  execute: async (context: ItemCommandContext) => {
@@ -358,6 +365,76 @@ export const localizeItemCommand: LocalizeItemCommand = {
358
365
  },
359
366
  };
360
367
 
368
+ export const changeTemplateCommand: ItemCommand = {
369
+ id: "changeTemplate",
370
+ label: "Change Template",
371
+ icon: <RefreshCw strokeWidth={1} />,
372
+ disabled: (context: ItemCommandContext) =>
373
+ !context.data?.items ||
374
+ context.data.items.length !== 1 ||
375
+ !context.data.items[0]?.canWriteItem ||
376
+ false,
377
+ execute: async (context: ItemCommandContext) => {
378
+ const item = context.data?.items[0];
379
+ if (!item) return;
380
+
381
+ // Open template selector dialog
382
+ const selectedTemplate = await context.openDialog<
383
+ ItemDescriptor,
384
+ TemplateSelectorDialogProps
385
+ >(TemplateSelectorDialog, {
386
+ currentItem: item,
387
+ editContext: context.editContext,
388
+ });
389
+
390
+ if (!selectedTemplate) return;
391
+
392
+ // Show confirmation dialog with warning
393
+ const confirmed = await new Promise<boolean>((resolve) => {
394
+ context.editContext.confirm({
395
+ message: (
396
+ <div>
397
+ Are you sure you want to change the template of <em>{item.name}</em>
398
+ ?
399
+ <div className="mt-4 text-sm">
400
+ <strong>Warning:</strong> Changing the template may result in data
401
+ loss for fields that are not present in the new template.
402
+ </div>
403
+ </div>
404
+ ),
405
+ header: "Change Template",
406
+ icon: <TriangleAlert strokeWidth={1} />,
407
+ accept: () => resolve(true),
408
+ reject: () => resolve(false),
409
+ showCancel: true,
410
+ });
411
+ });
412
+
413
+ if (!confirmed) return;
414
+
415
+ try {
416
+ // Execute the change template operation
417
+ const result = await executeChangeTemplate(
418
+ item.descriptor,
419
+ selectedTemplate.id,
420
+ context.editContext.sessionId,
421
+ );
422
+
423
+ if (result.type === "success") {
424
+ toast.success("Template changed successfully");
425
+ // Refresh the item to show updated template
426
+ context.editContext.loadItem(item.descriptor);
427
+ } else {
428
+ toast.error(result.details || "Failed to change template");
429
+ }
430
+ } catch (error) {
431
+ toast.error(
432
+ error instanceof Error ? error.message : "Failed to change template",
433
+ );
434
+ }
435
+ },
436
+ };
437
+
361
438
  export const publishItemCommand: ItemCommand = {
362
439
  id: "publishItem",
363
440
  label: "Publish",
@@ -54,7 +54,10 @@ export function WebSocketMessages() {
54
54
  "suggested-edit-updated": "bg-indigo-100 text-indigo-800",
55
55
  "suggested-edit-deleted": "bg-red-100 text-red-800",
56
56
  "update-quota": "bg-gray-100 text-gray-800",
57
- "agent-status-changed": "bg-violet-100 text-violet-800",
57
+ "agent:status:changed": "bg-violet-100 text-violet-800",
58
+ "agent:run:closed": "bg-red-100 text-red-800",
59
+ "agent:run:start": "bg-green-100 text-green-800",
60
+ "agent:name:updated": "bg-blue-100 text-blue-800",
58
61
  };
59
62
  return colors[type] || "bg-gray-100 text-gray-800";
60
63
  };