@parhelia/core 0.1.12565 → 0.1.12570

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 (575) hide show
  1. package/dist/agents-view/AgentCard.d.ts +4 -6
  2. package/dist/agents-view/AgentCard.js +24 -143
  3. package/dist/agents-view/AgentCard.js.map +1 -1
  4. package/dist/agents-view/AgentsInbox.d.ts +1 -1
  5. package/dist/agents-view/AgentsInbox.js +92 -7
  6. package/dist/agents-view/AgentsInbox.js.map +1 -1
  7. package/dist/agents-view/AgentsTitlebar.js +2 -3
  8. package/dist/agents-view/AgentsTitlebar.js.map +1 -1
  9. package/dist/agents-view/AgentsView.d.ts +7 -6
  10. package/dist/agents-view/AgentsView.js +99 -191
  11. package/dist/agents-view/AgentsView.js.map +1 -1
  12. package/dist/agents-view/AgentsWorkspaceView.d.ts +6 -2
  13. package/dist/agents-view/AgentsWorkspaceView.js +113 -266
  14. package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
  15. package/dist/agents-view/ProfileAgentsGroup.d.ts +1 -2
  16. package/dist/agents-view/ProfileAgentsGroup.js +3 -4
  17. package/dist/agents-view/ProfileAgentsGroup.js.map +1 -1
  18. package/dist/components/ActionButton.d.ts +1 -1
  19. package/dist/components/ActionButton.js.map +1 -1
  20. package/dist/components/FilterInput.d.ts +1 -1
  21. package/dist/components/FilterInput.js +1 -1
  22. package/dist/components/FilterInput.js.map +1 -1
  23. package/dist/components/ui/LanguageSelector.js +4 -2
  24. package/dist/components/ui/LanguageSelector.js.map +1 -1
  25. package/dist/components/ui/PlaceholderInput.js +3 -3
  26. package/dist/components/ui/PlaceholderInput.js.map +1 -1
  27. package/dist/components/ui/PlaceholderInputTypes.js +1 -1
  28. package/dist/components/ui/PlaceholderInputTypes.js.map +1 -1
  29. package/dist/components/ui/alert-dialog.d.ts +1 -1
  30. package/dist/components/ui/alert-dialog.js +10 -6
  31. package/dist/components/ui/alert-dialog.js.map +1 -1
  32. package/dist/components/ui/button.d.ts +4 -4
  33. package/dist/components/ui/button.js +1 -4
  34. package/dist/components/ui/button.js.map +1 -1
  35. package/dist/components/ui/context-menu.d.ts +1 -1
  36. package/dist/components/ui/context-menu.js +4 -12
  37. package/dist/components/ui/context-menu.js.map +1 -1
  38. package/dist/components/ui/copy-button.d.ts +1 -2
  39. package/dist/components/ui/copy-button.js +2 -2
  40. package/dist/components/ui/copy-button.js.map +1 -1
  41. package/dist/components/ui/dialog.d.ts +1 -1
  42. package/dist/components/ui/dialog.js +126 -21
  43. package/dist/components/ui/dialog.js.map +1 -1
  44. package/dist/components/ui/input.d.ts +1 -1
  45. package/dist/components/ui/input.js +3 -5
  46. package/dist/components/ui/input.js.map +1 -1
  47. package/dist/components/ui/paste-button.d.ts +1 -2
  48. package/dist/components/ui/paste-button.js +2 -2
  49. package/dist/components/ui/paste-button.js.map +1 -1
  50. package/dist/components/ui/popover.js +9 -1
  51. package/dist/components/ui/popover.js.map +1 -1
  52. package/dist/components/ui/select.js +1 -1
  53. package/dist/components/ui/select.js.map +1 -1
  54. package/dist/components/ui/styled-dialog-title.js +1 -1
  55. package/dist/components/ui/styled-dialog-title.js.map +1 -1
  56. package/dist/components/ui/tabs.d.ts +1 -1
  57. package/dist/components/ui/tabs.js +11 -4
  58. package/dist/components/ui/tabs.js.map +1 -1
  59. package/dist/config/config.d.ts +2 -4
  60. package/dist/config/config.js +70 -250
  61. package/dist/config/config.js.map +1 -1
  62. package/dist/config/types/workspace.d.ts +0 -6
  63. package/dist/config/types.d.ts +12 -63
  64. package/dist/config/types.js.map +1 -1
  65. package/dist/editor/ComponentInfo.d.ts +4 -0
  66. package/dist/editor/ComponentInfo.js +41 -0
  67. package/dist/editor/ComponentInfo.js.map +1 -0
  68. package/dist/editor/ConfirmationDialog.js +4 -20
  69. package/dist/editor/ConfirmationDialog.js.map +1 -1
  70. package/dist/editor/ContentTree.d.ts +1 -2
  71. package/dist/editor/ContentTree.js +32 -93
  72. package/dist/editor/ContentTree.js.map +1 -1
  73. package/dist/editor/Editor.js +22 -87
  74. package/dist/editor/Editor.js.map +1 -1
  75. package/dist/editor/FieldHistory.js +36 -84
  76. package/dist/editor/FieldHistory.js.map +1 -1
  77. package/dist/editor/FieldListField.js +9 -21
  78. package/dist/editor/FieldListField.js.map +1 -1
  79. package/dist/editor/FieldListFieldWithFallbacks.js +2 -23
  80. package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
  81. package/dist/editor/GlobalMenuBar.js +2 -29
  82. package/dist/editor/GlobalMenuBar.js.map +1 -1
  83. package/dist/editor/ImageEditor.js +2 -5
  84. package/dist/editor/ImageEditor.js.map +1 -1
  85. package/dist/editor/ItemInfo.js +1 -36
  86. package/dist/editor/ItemInfo.js.map +1 -1
  87. package/dist/editor/LinkEditorDialog.js +0 -3
  88. package/dist/editor/LinkEditorDialog.js.map +1 -1
  89. package/dist/editor/MainLayout.d.ts +2 -0
  90. package/dist/editor/MainLayout.js +8 -65
  91. package/dist/editor/MainLayout.js.map +1 -1
  92. package/dist/editor/MigrationsView.js +5 -29
  93. package/dist/editor/MigrationsView.js.map +1 -1
  94. package/dist/editor/MobileLayout.js +12 -37
  95. package/dist/editor/MobileLayout.js.map +1 -1
  96. package/dist/editor/PictureCropper.js +45 -54
  97. package/dist/editor/PictureCropper.js.map +1 -1
  98. package/dist/editor/PictureEditor.js +15 -17
  99. package/dist/editor/PictureEditor.js.map +1 -1
  100. package/dist/editor/QuickItemSwitcher.js +21 -21
  101. package/dist/editor/QuickItemSwitcher.js.map +1 -1
  102. package/dist/editor/SetupWizard.js +12 -52
  103. package/dist/editor/SetupWizard.js.map +1 -1
  104. package/dist/editor/Titlebar.js +2 -7
  105. package/dist/editor/Titlebar.js.map +1 -1
  106. package/dist/editor/ai/AgentCostDisplay.d.ts +0 -1
  107. package/dist/editor/ai/AgentCostDisplay.js +1 -1
  108. package/dist/editor/ai/AgentCostDisplay.js.map +1 -1
  109. package/dist/editor/ai/AgentDocumentList.js +14 -32
  110. package/dist/editor/ai/AgentDocumentList.js.map +1 -1
  111. package/dist/editor/ai/AgentGreeting.js +2 -3
  112. package/dist/editor/ai/AgentGreeting.js.map +1 -1
  113. package/dist/editor/ai/AgentProfileSelector.js +1 -2
  114. package/dist/editor/ai/AgentProfileSelector.js.map +1 -1
  115. package/dist/editor/ai/AgentStatusBadge.d.ts +5 -0
  116. package/dist/editor/ai/AgentStatusBadge.js +65 -67
  117. package/dist/editor/ai/AgentStatusBadge.js.map +1 -1
  118. package/dist/editor/ai/AgentTerminal.d.ts +2 -14
  119. package/dist/editor/ai/AgentTerminal.js +496 -2406
  120. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  121. package/dist/editor/ai/AgentTerminalStatusBar.d.ts +3 -8
  122. package/dist/editor/ai/AgentTerminalStatusBar.js +56 -481
  123. package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
  124. package/dist/editor/ai/Agents.js +113 -161
  125. package/dist/editor/ai/Agents.js.map +1 -1
  126. package/dist/editor/ai/AiResponseMessage.d.ts +1 -10
  127. package/dist/editor/ai/AiResponseMessage.js +26 -267
  128. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  129. package/dist/editor/ai/ContextInfoBar.d.ts +3 -2
  130. package/dist/editor/ai/ContextInfoBar.js +7 -64
  131. package/dist/editor/ai/ContextInfoBar.js.map +1 -1
  132. package/dist/editor/ai/GuidanceOverlay.js +11 -17
  133. package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
  134. package/dist/editor/ai/HelpTerminal.d.ts +5 -0
  135. package/dist/editor/ai/HelpTerminal.js +166 -0
  136. package/dist/editor/ai/HelpTerminal.js.map +1 -0
  137. package/dist/editor/ai/InlineAiDialog.d.ts +1 -1
  138. package/dist/editor/ai/InlineAiDialog.js +192 -514
  139. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  140. package/dist/editor/ai/InlineAiTrigger.js +12 -115
  141. package/dist/editor/ai/InlineAiTrigger.js.map +1 -1
  142. package/dist/editor/ai/MediaImage.js +8 -40
  143. package/dist/editor/ai/MediaImage.js.map +1 -1
  144. package/dist/editor/ai/SpawnedAgentsPanel.js +12 -10
  145. package/dist/editor/ai/SpawnedAgentsPanel.js.map +1 -1
  146. package/dist/editor/ai/ToolCallDisplay.d.ts +2 -22
  147. package/dist/editor/ai/ToolCallDisplay.js +150 -542
  148. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  149. package/dist/editor/ai/dialogs/AgentDialogHandler.d.ts +8 -1
  150. package/dist/editor/ai/dialogs/AgentDialogHandler.js +42 -379
  151. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  152. package/dist/editor/ai/dialogs/QuestionnaireInline.d.ts +1 -5
  153. package/dist/editor/ai/dialogs/QuestionnaireInline.js +60 -628
  154. package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
  155. package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +0 -115
  156. package/dist/editor/ai/dialogs/agentDialogTypes.js +0 -2
  157. package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
  158. package/dist/editor/ai/types.d.ts +1 -3
  159. package/dist/editor/ai/useAgentStatus.d.ts +1 -2
  160. package/dist/editor/ai/useAgentStatus.js +100 -90
  161. package/dist/editor/ai/useAgentStatus.js.map +1 -1
  162. package/dist/editor/ai/useInlineAiPosition.js +5 -45
  163. package/dist/editor/ai/useInlineAiPosition.js.map +1 -1
  164. package/dist/editor/client/AboutDialog.js +2 -4
  165. package/dist/editor/client/AboutDialog.js.map +1 -1
  166. package/dist/editor/client/EditorShell.d.ts +1 -4
  167. package/dist/editor/client/EditorShell.js +237 -770
  168. package/dist/editor/client/EditorShell.js.map +1 -1
  169. package/dist/editor/client/editContext.d.ts +19 -33
  170. package/dist/editor/client/editContext.js.map +1 -1
  171. package/dist/editor/client/helpers.js +0 -6
  172. package/dist/editor/client/helpers.js.map +1 -1
  173. package/dist/editor/client/hooks/useEditorUrlSync.js +2 -1
  174. package/dist/editor/client/hooks/useEditorUrlSync.js.map +1 -1
  175. package/dist/editor/client/hooks/useEditorWebSocket.d.ts +0 -10
  176. package/dist/editor/client/hooks/useEditorWebSocket.js +14 -209
  177. package/dist/editor/client/hooks/useEditorWebSocket.js.map +1 -1
  178. package/dist/editor/client/hooks/useQuota.d.ts +0 -8
  179. package/dist/editor/client/hooks/useQuota.js.map +1 -1
  180. package/dist/editor/client/hooks/useSocketMessageHandler.js +15 -73
  181. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  182. package/dist/editor/client/itemsRepository.js +6 -10
  183. package/dist/editor/client/itemsRepository.js.map +1 -1
  184. package/dist/editor/client/operations.d.ts +3 -6
  185. package/dist/editor/client/operations.js +30 -208
  186. package/dist/editor/client/operations.js.map +1 -1
  187. package/dist/editor/client/pageModelBuilder.js +31 -4
  188. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  189. package/dist/editor/client/ui/DevModeIndicator.js +2 -2
  190. package/dist/editor/client/ui/DevModeIndicator.js.map +1 -1
  191. package/dist/editor/client/ui/EditorChrome.d.ts +6 -0
  192. package/dist/editor/client/ui/EditorChrome.js +72 -55
  193. package/dist/editor/client/ui/EditorChrome.js.map +1 -1
  194. package/dist/editor/client/ui/FullscreenControls.js +3 -5
  195. package/dist/editor/client/ui/FullscreenControls.js.map +1 -1
  196. package/dist/editor/commands/commands.d.ts +1 -11
  197. package/dist/editor/commands/commands.js +1 -12
  198. package/dist/editor/commands/commands.js.map +1 -1
  199. package/dist/editor/commands/componentCommands.js +55 -109
  200. package/dist/editor/commands/componentCommands.js.map +1 -1
  201. package/dist/editor/commands/customCommandConverter.d.ts +1 -8
  202. package/dist/editor/commands/customCommandConverter.js +5 -35
  203. package/dist/editor/commands/customCommandConverter.js.map +1 -1
  204. package/dist/editor/commands/handlers/agentHandler.js +1 -2
  205. package/dist/editor/commands/handlers/agentHandler.js.map +1 -1
  206. package/dist/editor/commands/itemCommands.d.ts +0 -3
  207. package/dist/editor/commands/itemCommands.js +10 -93
  208. package/dist/editor/commands/itemCommands.js.map +1 -1
  209. package/dist/editor/commands/undo.d.ts +15 -9
  210. package/dist/editor/commands/undo.js +0 -24
  211. package/dist/editor/commands/undo.js.map +1 -1
  212. package/dist/editor/context-menu/InsertMenu.js +39 -83
  213. package/dist/editor/context-menu/InsertMenu.js.map +1 -1
  214. package/dist/editor/field-types/MultiLineText.js +1 -1
  215. package/dist/editor/field-types/MultiLineText.js.map +1 -1
  216. package/dist/editor/field-types/RawEditor.js +1 -1
  217. package/dist/editor/field-types/ReactQuill.d.ts +125 -0
  218. package/dist/editor/field-types/ReactQuill.js +385 -0
  219. package/dist/editor/field-types/ReactQuill.js.map +1 -0
  220. package/dist/editor/field-types/RichTextEditor.js +5 -13
  221. package/dist/editor/field-types/RichTextEditor.js.map +1 -1
  222. package/dist/editor/field-types/RichTextEditorComponent.js +3 -37
  223. package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
  224. package/dist/editor/field-types/SingleLineText.js +1 -1
  225. package/dist/editor/field-types/TreeListEditor.js +2 -3
  226. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  227. package/dist/editor/field-types/richtext/components/ReactSlate.css +5 -23
  228. package/dist/editor/field-types/richtext/components/ReactSlate.d.ts +0 -2
  229. package/dist/editor/field-types/richtext/components/ReactSlate.js +4 -28
  230. package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
  231. package/dist/editor/field-types/richtext/components/ToolbarButton.js +2 -4
  232. package/dist/editor/field-types/richtext/components/ToolbarButton.js.map +1 -1
  233. package/dist/editor/field-types/richtext/contextMenuFactory.d.ts +0 -13
  234. package/dist/editor/field-types/richtext/contextMenuFactory.js +24 -181
  235. package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -1
  236. package/dist/editor/field-types/richtext/types.d.ts +0 -2
  237. package/dist/editor/field-types/richtext/types.js.map +1 -1
  238. package/dist/editor/field-types/richtext/utils/plugins.js +0 -4
  239. package/dist/editor/field-types/richtext/utils/plugins.js.map +1 -1
  240. package/dist/editor/field-types/textContextMenuFactory.js +2 -3
  241. package/dist/editor/field-types/textContextMenuFactory.js.map +1 -1
  242. package/dist/editor/media-selector/AiImageSearchPrompt.js +2 -4
  243. package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -1
  244. package/dist/editor/media-selector/MediaFolderBrowser.js +1 -1
  245. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
  246. package/dist/editor/media-selector/MediaSelector.js +1 -7
  247. package/dist/editor/media-selector/MediaSelector.js.map +1 -1
  248. package/dist/editor/media-selector/TreeSelector.js +35 -40
  249. package/dist/editor/media-selector/TreeSelector.js.map +1 -1
  250. package/dist/editor/menubar/ActiveUsers.js +1 -1
  251. package/dist/editor/menubar/ActiveUsers.js.map +1 -1
  252. package/dist/editor/menubar/GenericToolbar.js +2 -4
  253. package/dist/editor/menubar/GenericToolbar.js.map +1 -1
  254. package/dist/editor/menubar/ItemLanguageVersion.js +2 -2
  255. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
  256. package/dist/editor/menubar/PageSelector.js +147 -26
  257. package/dist/editor/menubar/PageSelector.js.map +1 -1
  258. package/dist/editor/menubar/Separator.js +1 -1
  259. package/dist/editor/menubar/VersionSelector.js +4 -2
  260. package/dist/editor/menubar/VersionSelector.js.map +1 -1
  261. package/dist/editor/menubar/WorkflowButton.js +12 -39
  262. package/dist/editor/menubar/WorkflowButton.js.map +1 -1
  263. package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js +38 -16
  264. package/dist/editor/menubar/toolbar-sections/CustomCommandsToolbar.js.map +1 -1
  265. package/dist/editor/menubar/toolbar-sections/EditControls.js +3 -3
  266. package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
  267. package/dist/editor/menubar/toolbar-sections/HelpButton.js +0 -1
  268. package/dist/editor/menubar/toolbar-sections/HelpButton.js.map +1 -1
  269. package/dist/editor/menubar/toolbar-sections/ManualBrowser.d.ts +10 -6
  270. package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +220 -597
  271. package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
  272. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +2 -13
  273. package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
  274. package/dist/editor/page-editor-chrome/CommentHighlighting.js +1 -42
  275. package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
  276. package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
  277. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  278. package/dist/editor/page-editor-chrome/InlineEditor.js +48 -97
  279. package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
  280. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +17 -38
  281. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  282. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +11 -17
  283. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  284. package/dist/editor/page-editor-chrome/useInlineAICompletion.js +301 -301
  285. package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
  286. package/dist/editor/page-viewer/DeviceToolbar.js +1 -1
  287. package/dist/editor/page-viewer/DeviceToolbar.js.map +1 -1
  288. package/dist/editor/page-viewer/EditorForm.js +11 -69
  289. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  290. package/dist/editor/page-viewer/MiniMap.d.ts +4 -2
  291. package/dist/editor/page-viewer/MiniMap.js +28 -91
  292. package/dist/editor/page-viewer/MiniMap.js.map +1 -1
  293. package/dist/editor/page-viewer/PageViewer.d.ts +1 -3
  294. package/dist/editor/page-viewer/PageViewer.js +19 -92
  295. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  296. package/dist/editor/page-viewer/PageViewerFrame.d.ts +1 -2
  297. package/dist/editor/page-viewer/PageViewerFrame.js +115 -348
  298. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  299. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +49 -114
  300. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +1 -1
  301. package/dist/editor/page-viewer/pageViewContext.d.ts +0 -1
  302. package/dist/editor/page-viewer/pageViewContext.js +14 -51
  303. package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
  304. package/dist/editor/pageModel.d.ts +1 -14
  305. package/dist/editor/reviews/Comment.js +12 -26
  306. package/dist/editor/reviews/Comment.js.map +1 -1
  307. package/dist/editor/reviews/CommentDisplayPopover.js +5 -7
  308. package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
  309. package/dist/editor/reviews/CommentView.js +4 -19
  310. package/dist/editor/reviews/CommentView.js.map +1 -1
  311. package/dist/editor/reviews/Comments.js +72 -89
  312. package/dist/editor/reviews/Comments.js.map +1 -1
  313. package/dist/editor/reviews/CreateReviewDialog.js +177 -281
  314. package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
  315. package/dist/editor/reviews/DecisionsMatrix.js +25 -96
  316. package/dist/editor/reviews/DecisionsMatrix.js.map +1 -1
  317. package/dist/editor/reviews/DiffView.js +14 -7
  318. package/dist/editor/reviews/DiffView.js.map +1 -1
  319. package/dist/editor/reviews/EditReviewSettingsDialog.js +4 -6
  320. package/dist/editor/reviews/EditReviewSettingsDialog.js.map +1 -1
  321. package/dist/editor/reviews/MultiReviewManager.js +3 -25
  322. package/dist/editor/reviews/MultiReviewManager.js.map +1 -1
  323. package/dist/editor/reviews/PagesPanel.js +15 -31
  324. package/dist/editor/reviews/PagesPanel.js.map +1 -1
  325. package/dist/editor/reviews/PreviewInfo.js +4 -1
  326. package/dist/editor/reviews/PreviewInfo.js.map +1 -1
  327. package/dist/editor/reviews/ReviewCard.js +7 -13
  328. package/dist/editor/reviews/ReviewCard.js.map +1 -1
  329. package/dist/editor/reviews/ReviewDetail.js +2 -3
  330. package/dist/editor/reviews/ReviewDetail.js.map +1 -1
  331. package/dist/editor/reviews/ReviewsList.js +3 -7
  332. package/dist/editor/reviews/ReviewsList.js.map +1 -1
  333. package/dist/editor/reviews/SuggestedEdit.js +3 -34
  334. package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
  335. package/dist/editor/reviews/SuggestionDisplayPopover.js +5 -31
  336. package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
  337. package/dist/editor/reviews/commentAi.js +6 -25
  338. package/dist/editor/reviews/commentAi.js.map +1 -1
  339. package/dist/editor/reviews/reviewCommands.js +1 -4
  340. package/dist/editor/reviews/reviewCommands.js.map +1 -1
  341. package/dist/editor/reviews/useMultiReview.js +2 -2
  342. package/dist/editor/reviews/useMultiReview.js.map +1 -1
  343. package/dist/editor/reviews/useReviews.d.ts +2 -2
  344. package/dist/editor/reviews/useReviews.js +30 -12
  345. package/dist/editor/reviews/useReviews.js.map +1 -1
  346. package/dist/editor/services/agentService.d.ts +5 -229
  347. package/dist/editor/services/agentService.js +39 -292
  348. package/dist/editor/services/agentService.js.map +1 -1
  349. package/dist/editor/services/aiService.d.ts +1 -57
  350. package/dist/editor/services/aiService.js +6 -79
  351. package/dist/editor/services/aiService.js.map +1 -1
  352. package/dist/editor/services/contentService.d.ts +3 -6
  353. package/dist/editor/services/contentService.js +12 -13
  354. package/dist/editor/services/contentService.js.map +1 -1
  355. package/dist/editor/services/editService.d.ts +1 -52
  356. package/dist/editor/services/editService.js +2 -94
  357. package/dist/editor/services/editService.js.map +1 -1
  358. package/dist/editor/services/indexService.js +1 -1
  359. package/dist/editor/services/indexService.js.map +1 -1
  360. package/dist/editor/services/reviewsService.d.ts +6 -3
  361. package/dist/editor/services/reviewsService.js +11 -2
  362. package/dist/editor/services/reviewsService.js.map +1 -1
  363. package/dist/editor/services/serviceHelper.d.ts +1 -2
  364. package/dist/editor/services/serviceHelper.js +20 -112
  365. package/dist/editor/services/serviceHelper.js.map +1 -1
  366. package/dist/editor/services/systemService.d.ts +1 -2
  367. package/dist/editor/services/systemService.js +0 -3
  368. package/dist/editor/services/systemService.js.map +1 -1
  369. package/dist/editor/services-server/api.d.ts +2 -1
  370. package/dist/editor/services-server/api.js +6 -11
  371. package/dist/editor/services-server/api.js.map +1 -1
  372. package/dist/editor/services-server/graphQL.d.ts +29 -0
  373. package/dist/editor/services-server/graphQL.js +53 -0
  374. package/dist/editor/services-server/graphQL.js.map +1 -0
  375. package/dist/editor/settings/About.js +3 -317
  376. package/dist/editor/settings/About.js.map +1 -1
  377. package/dist/editor/settings/AllAgentsPanel.d.ts +5 -0
  378. package/dist/editor/settings/AllAgentsPanel.js +139 -0
  379. package/dist/editor/settings/AllAgentsPanel.js.map +1 -0
  380. package/dist/editor/settings/LatestFeedback.d.ts +1 -0
  381. package/dist/editor/settings/LatestFeedback.js +136 -0
  382. package/dist/editor/settings/LatestFeedback.js.map +1 -0
  383. package/dist/editor/settings/QuotaInfo.js +4 -210
  384. package/dist/editor/settings/QuotaInfo.js.map +1 -1
  385. package/dist/editor/settings/SettingsView.js +23 -25
  386. package/dist/editor/settings/SettingsView.js.map +1 -1
  387. package/dist/editor/settings/Setup.d.ts +1 -0
  388. package/dist/editor/settings/Setup.js +211 -0
  389. package/dist/editor/settings/Setup.js.map +1 -0
  390. package/dist/editor/settings/Status.js +6 -7
  391. package/dist/editor/settings/Status.js.map +1 -1
  392. package/dist/editor/settings/index/useIndexStatus.js +22 -20
  393. package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
  394. package/dist/editor/settings/panels/AgentsPanel.d.ts +4 -0
  395. package/dist/editor/settings/panels/AgentsPanel.js +121 -95
  396. package/dist/editor/settings/panels/AgentsPanel.js.map +1 -1
  397. package/dist/editor/settings/panels/DatabasePanel.d.ts +6 -0
  398. package/dist/editor/settings/panels/DatabasePanel.js +50 -0
  399. package/dist/editor/settings/panels/DatabasePanel.js.map +1 -0
  400. package/dist/editor/settings/panels/ModelsPanel.js +108 -329
  401. package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
  402. package/dist/editor/settings/panels/ProvidersPanel.d.ts +1 -1
  403. package/dist/editor/settings/panels/ProvidersPanel.js +59 -86
  404. package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
  405. package/dist/editor/settings/panels/SearchConfigPanel.js +4 -4
  406. package/dist/editor/settings/panels/SearchConfigPanel.js.map +1 -1
  407. package/dist/editor/settings/panels/index.d.ts +2 -3
  408. package/dist/editor/settings/panels/index.js +2 -3
  409. package/dist/editor/settings/panels/index.js.map +1 -1
  410. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.d.ts +2 -0
  411. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js +195 -0
  412. package/dist/editor/settings/setup-steps/AiSetupStep/EmbeddingsModelSection.js.map +1 -0
  413. package/dist/editor/settings/setup-steps/AiSetupStep/index.d.ts +2 -0
  414. package/dist/editor/settings/setup-steps/AiSetupStep/index.js +21 -0
  415. package/dist/editor/settings/setup-steps/AiSetupStep/index.js.map +1 -0
  416. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.d.ts +1 -0
  417. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js +233 -0
  418. package/dist/editor/settings/setup-steps/AiSetupStep/provider/ProviderSection.js.map +1 -0
  419. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.d.ts +15 -0
  420. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js +14 -0
  421. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js.map +1 -0
  422. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.d.ts +1 -0
  423. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js +94 -0
  424. package/dist/editor/settings/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js.map +1 -0
  425. package/dist/editor/settings/setup-steps/AiSetupStep/types.d.ts +1 -0
  426. package/dist/editor/settings/setup-steps/AiSetupStep/types.js +2 -0
  427. package/dist/editor/settings/setup-steps/AiSetupStep/types.js.map +1 -0
  428. package/dist/editor/settings/setup-steps/AiSetupStep/utils.d.ts +5 -0
  429. package/dist/editor/settings/setup-steps/AiSetupStep/utils.js +44 -0
  430. package/dist/editor/settings/setup-steps/AiSetupStep/utils.js.map +1 -0
  431. package/dist/editor/settings/setup-steps/IndexSetupStep.d.ts +2 -0
  432. package/dist/editor/settings/setup-steps/IndexSetupStep.js +36 -0
  433. package/dist/editor/settings/setup-steps/IndexSetupStep.js.map +1 -0
  434. package/dist/editor/settings/setup-steps/SettingsSetupStep.d.ts +2 -0
  435. package/dist/editor/settings/setup-steps/SettingsSetupStep.js +111 -0
  436. package/dist/editor/settings/setup-steps/SettingsSetupStep.js.map +1 -0
  437. package/dist/editor/settings/setup-steps/SetupOverview.d.ts +14 -0
  438. package/dist/editor/settings/setup-steps/SetupOverview.js +38 -0
  439. package/dist/editor/settings/setup-steps/SetupOverview.js.map +1 -0
  440. package/dist/editor/settings/status/coreStatusChecks.js +19 -124
  441. package/dist/editor/settings/status/coreStatusChecks.js.map +1 -1
  442. package/dist/editor/settings/status/useStartupChecks.d.ts +1 -3
  443. package/dist/editor/settings/status/useStartupChecks.js +5 -9
  444. package/dist/editor/settings/status/useStartupChecks.js.map +1 -1
  445. package/dist/editor/setup-wizard/steps/CompleteStep.d.ts +1 -2
  446. package/dist/editor/setup-wizard/steps/CompleteStep.js +1 -2
  447. package/dist/editor/setup-wizard/steps/CompleteStep.js.map +1 -1
  448. package/dist/editor/sidebar/ComponentPalette.js +1 -2
  449. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  450. package/dist/editor/sidebar/ComponentTree.d.ts +1 -8
  451. package/dist/editor/sidebar/ComponentTree.js +69 -216
  452. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  453. package/dist/editor/sidebar/Debug.d.ts +1 -0
  454. package/dist/editor/sidebar/Debug.js +70 -0
  455. package/dist/editor/sidebar/Debug.js.map +1 -0
  456. package/dist/editor/sidebar/EditHistory.js +46 -22
  457. package/dist/editor/sidebar/EditHistory.js.map +1 -1
  458. package/dist/editor/sidebar/Favorites.js +8 -4
  459. package/dist/editor/sidebar/Favorites.js.map +1 -1
  460. package/dist/editor/sidebar/GraphQL.d.ts +2 -0
  461. package/dist/editor/sidebar/GraphQL.js +234 -0
  462. package/dist/editor/sidebar/GraphQL.js.map +1 -0
  463. package/dist/editor/sidebar/LeftToolbar.d.ts +1 -0
  464. package/dist/editor/sidebar/LeftToolbar.js +12 -0
  465. package/dist/editor/sidebar/LeftToolbar.js.map +1 -0
  466. package/dist/editor/sidebar/MainContentTree.js +3 -4
  467. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  468. package/dist/editor/sidebar/NavigationSidebar.d.ts +4 -0
  469. package/dist/editor/sidebar/NavigationSidebar.js +254 -0
  470. package/dist/editor/sidebar/NavigationSidebar.js.map +1 -0
  471. package/dist/editor/sidebar/OperationItem.js +7 -21
  472. package/dist/editor/sidebar/OperationItem.js.map +1 -1
  473. package/dist/editor/sidebar/SidebarPanel.d.ts +1 -3
  474. package/dist/editor/sidebar/SidebarPanel.js +12 -44
  475. package/dist/editor/sidebar/SidebarPanel.js.map +1 -1
  476. package/dist/editor/sidebar/SidebarStack.d.ts +1 -2
  477. package/dist/editor/sidebar/SidebarStack.js +3 -4
  478. package/dist/editor/sidebar/SidebarStack.js.map +1 -1
  479. package/dist/editor/sidebar/Validation.js +12 -24
  480. package/dist/editor/sidebar/Validation.js.map +1 -1
  481. package/dist/editor/sidebar/Workbox.js +3 -53
  482. package/dist/editor/sidebar/Workbox.js.map +1 -1
  483. package/dist/editor/sidebar/WorkspaceRail.d.ts +1 -0
  484. package/dist/editor/sidebar/WorkspaceRail.js +167 -56
  485. package/dist/editor/sidebar/WorkspaceRail.js.map +1 -1
  486. package/dist/editor/tree-indicators/GutterColumns.d.ts +1 -3
  487. package/dist/editor/tree-indicators/GutterColumns.js +5 -26
  488. package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
  489. package/dist/editor/tree-indicators/GutterContext.d.ts +0 -4
  490. package/dist/editor/tree-indicators/GutterContext.js +0 -23
  491. package/dist/editor/tree-indicators/GutterContext.js.map +1 -1
  492. package/dist/editor/tree-indicators/GutterSelector.d.ts +5 -0
  493. package/dist/editor/tree-indicators/GutterSelector.js +91 -0
  494. package/dist/editor/tree-indicators/GutterSelector.js.map +1 -0
  495. package/dist/editor/tree-indicators/index.d.ts +1 -0
  496. package/dist/editor/tree-indicators/index.js +1 -0
  497. package/dist/editor/tree-indicators/index.js.map +1 -1
  498. package/dist/editor/tree-indicators/types.d.ts +1 -12
  499. package/dist/editor/ui/CopyMoveTargetSelectorDialog.js +1 -1
  500. package/dist/editor/ui/CopyMoveTargetSelectorDialog.js.map +1 -1
  501. package/dist/editor/ui/Icons.js +1 -1
  502. package/dist/editor/ui/Icons.js.map +1 -1
  503. package/dist/editor/ui/ItemNameDialogNew.d.ts +0 -2
  504. package/dist/editor/ui/ItemNameDialogNew.js +17 -33
  505. package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
  506. package/dist/editor/ui/ItemSearch.js +11 -7
  507. package/dist/editor/ui/ItemSearch.js.map +1 -1
  508. package/dist/editor/ui/SimpleIconButton.js +1 -1
  509. package/dist/editor/ui/SimpleIconButton.js.map +1 -1
  510. package/dist/editor/ui/SimpleTabs.d.ts +0 -1
  511. package/dist/editor/ui/SimpleTabs.js +25 -45
  512. package/dist/editor/ui/SimpleTabs.js.map +1 -1
  513. package/dist/editor/ui/Splitter.d.ts +0 -1
  514. package/dist/editor/ui/Splitter.js +86 -102
  515. package/dist/editor/ui/Splitter.js.map +1 -1
  516. package/dist/editor/ui/TemplateSelectorDialog.js +4 -4
  517. package/dist/editor/ui/TemplateSelectorDialog.js.map +1 -1
  518. package/dist/editor/ui/TreeListSelector.d.ts +1 -6
  519. package/dist/editor/ui/TreeListSelector.js +2 -2
  520. package/dist/editor/ui/TreeListSelector.js.map +1 -1
  521. package/dist/editor/utils/keyboardNavigation.d.ts +20 -6
  522. package/dist/editor/utils/keyboardNavigation.js +140 -48
  523. package/dist/editor/utils/keyboardNavigation.js.map +1 -1
  524. package/dist/editor/utils.js +9 -19
  525. package/dist/editor/utils.js.map +1 -1
  526. package/dist/editor/views/CompareView.d.ts +1 -3
  527. package/dist/editor/views/CompareView.js +5 -7
  528. package/dist/editor/views/CompareView.js.map +1 -1
  529. package/dist/editor/views/EditView.js +1 -1
  530. package/dist/editor/views/EditView.js.map +1 -1
  531. package/dist/editor/views/EditorSlot.js +34 -27
  532. package/dist/editor/views/EditorSlot.js.map +1 -1
  533. package/dist/editor/views/ItemEditor.js +3 -7
  534. package/dist/editor/views/ItemEditor.js.map +1 -1
  535. package/dist/editor/views/MediaFolderEditView.js +1 -1
  536. package/dist/editor/views/MediaFolderEditView.js.map +1 -1
  537. package/dist/editor/views/ParheliaView.js +6 -5
  538. package/dist/editor/views/ParheliaView.js.map +1 -1
  539. package/dist/editor/views/SingleEditView.d.ts +1 -2
  540. package/dist/editor/views/SingleEditView.js +8 -10
  541. package/dist/editor/views/SingleEditView.js.map +1 -1
  542. package/dist/editor/views/editorSlotContext.js +6 -35
  543. package/dist/editor/views/editorSlotContext.js.map +1 -1
  544. package/dist/index.d.ts +2 -16
  545. package/dist/index.js +0 -11
  546. package/dist/index.js.map +1 -1
  547. package/dist/revision.d.ts +2 -2
  548. package/dist/revision.js +2 -2
  549. package/dist/setup/services/setupWizardService.d.ts +13 -40
  550. package/dist/setup/services/setupWizardService.js +17 -32
  551. package/dist/setup/services/setupWizardService.js.map +1 -1
  552. package/dist/setup/wizard/steps/AddModelDialog.js +3 -12
  553. package/dist/setup/wizard/steps/AddModelDialog.js.map +1 -1
  554. package/dist/setup/wizard/steps/ImportModelDialog.js +22 -39
  555. package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
  556. package/dist/splash-screen/ModernSplashScreen.js +32 -112
  557. package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
  558. package/dist/splash-screen/NewPage.js +50 -33
  559. package/dist/splash-screen/NewPage.js.map +1 -1
  560. package/dist/splash-screen/OpenPage.js +6 -2
  561. package/dist/splash-screen/OpenPage.js.map +1 -1
  562. package/dist/splash-screen/ParheliaAssistantChat.js +29 -12
  563. package/dist/splash-screen/ParheliaAssistantChat.js.map +1 -1
  564. package/dist/splash-screen/ParheliaLogo.js +37 -87
  565. package/dist/splash-screen/ParheliaLogo.js.map +1 -1
  566. package/dist/splash-screen/RecentPages.js +3 -3
  567. package/dist/splash-screen/RecentPages.js.map +1 -1
  568. package/dist/tour/Tour.d.ts +1 -2
  569. package/dist/tour/Tour.js +75 -256
  570. package/dist/tour/Tour.js.map +1 -1
  571. package/dist/tour/default-tour.js +96 -222
  572. package/dist/tour/default-tour.js.map +1 -1
  573. package/dist/types.d.ts +29 -63
  574. package/package.json +15 -19
  575. package/styles.css +10 -39
@@ -1,17 +1,15 @@
1
1
  "use client";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import React, { useState, useEffect, useRef, useCallback, useSyncExternalStore, useMemo, startTransition, } from "react";
4
4
  import { toast } from "sonner";
5
- import { EditContextProvider, FieldsEditContextProvider, OperationsContextProvider, useEditContext, } from "./editContext";
5
+ import { EditContextProvider, FieldsEditContextProvider, OperationsContextProvider, } from "./editContext";
6
6
  import { fieldModificationStore } from "./fieldModificationStore";
7
- import { useRouter, useSearchParams, usePathname } from "./navigation";
7
+ import { useRouter, useSearchParams, usePathname } from "next/navigation";
8
8
  import { findComponent, getComponentById } from "../componentTreeHelper";
9
9
  import { getOperationsContext } from "./operations";
10
10
  import { handleErrorResult } from "./helpers";
11
- import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, getRunningOperations, reconnectSession, releaseFieldLocks, validateItems, } from "../services/editService";
11
+ import { executeFieldAction as executeFieldServerAction, connectSocket, getEditHistory, getRunningOperations, releaseFieldLocks, validateItems, } from "../services/editService";
12
12
  import { useEditorWebSocket } from "./hooks/useEditorWebSocket";
13
- import { createEditorSocketDiagnostics, } from "./socketDiagnostics";
14
- import { localStorageService } from "../services/localStorageService";
15
13
  import { useSocketMessageHandler } from "./hooks/useSocketMessageHandler";
16
14
  import "react-json-view-lite/dist/index.css";
17
15
  import { MediaSelector, } from "../media-selector/MediaSelector";
@@ -22,7 +20,6 @@ import { getItemDescriptor } from "../utils";
22
20
  import { EditContextMenu } from "../ContextMenu";
23
21
  import { InlineAiTrigger } from "../ai/InlineAiTrigger";
24
22
  import { FieldEditorPopup } from "../FieldEditorPopup";
25
- import { ConcurrentUserLimitDialog } from "../ConcurrentUserLimitDialog";
26
23
  import { post } from "../services/serviceHelper";
27
24
  import { PageViewerFrame } from "../page-viewer/PageViewerFrame";
28
25
  import { useItemsRepository } from "./itemsRepository";
@@ -36,7 +33,6 @@ import { GuidanceOverlay } from "../ai/GuidanceOverlay";
36
33
  import { AgentDialogHandler } from "../ai/dialogs";
37
34
  import { usePageViewContext, } from "../page-viewer/pageViewContext";
38
35
  import { QuickItemSwitcher } from "../QuickItemSwitcher";
39
- import { useEditorSlotContext, } from "../views/editorSlotContext";
40
36
  import { getComments, getAvailableCommentTags, } from "../services/reviewsService";
41
37
  import { useReviews } from "../reviews/useReviews";
42
38
  import uuid from "react-uuid";
@@ -53,33 +49,7 @@ import { useWorkbox } from "./hooks/useWorkbox";
53
49
  import { useMediaSelector } from "./hooks/useMediaSelector";
54
50
  import { useGlobalEditorKeyDown } from "./hooks/useGlobalEditorKeyDown";
55
51
  import { useStartupChecks } from "../settings/status/index";
56
- import { FeatureGate, LicenseFeatures, LicenseProvider, LicenseOverlay, } from "../../licensing";
57
- function AgentsSlotContextBridge({ slot }) {
58
- const editContext = useEditContext();
59
- const slotContext = useEditorSlotContext({
60
- slotId: slot.slotId,
61
- itemDescriptor: slot.itemDescriptor,
62
- refreshToken: slot.refreshToken,
63
- });
64
- if (!editContext || !slotContext)
65
- return null;
66
- useEffect(() => {
67
- editContext.registerSlotContext(slot.slotId, slotContext);
68
- return () => {
69
- editContext.unregisterSlotContext(slot.slotId);
70
- };
71
- }, [
72
- slot.slotId,
73
- slotContext,
74
- editContext.registerSlotContext,
75
- editContext.unregisterSlotContext,
76
- ]);
77
- return null;
78
- }
79
- function AgentsSlotContextBridgeHost({ slots }) {
80
- return (_jsx(_Fragment, { children: slots.map((slot) => (_jsx(AgentsSlotContextBridge, { slot: slot }, `agents-slot-bridge-${slot.slotId}`))) }));
81
- }
82
- export function EditorShell({ configuration, className, item: loadItemDescriptor, sessionId, userInfo, userPreferences, initialLicenseStatus, initialLicenseStatusLoaded, parheliaSettings, setUserPreferences, children, }) {
52
+ export function EditorShell({ configuration, className, item: loadItemDescriptor, sessionId, userInfo, userPreferences, parheliaSettings, setUserPreferences, children, }) {
83
53
  const router = useRouter();
84
54
  const pathname = usePathname();
85
55
  const searchParams = useSearchParams();
@@ -127,7 +97,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
127
97
  const [historyMode, setHistoryMode] = useState("global");
128
98
  const [showOnlyMyChanges, setShowOnlyMyChanges] = useState(true);
129
99
  const [filterByCurrentLanguage, setFilterByCurrentLanguage] = useState(true);
130
- const [historySearchQuery, setHistorySearchQuery] = useState("");
131
100
  const [recentEdits, setRecentEdits] = useState([]);
132
101
  const addRecentEdit = useCallback((edit) => {
133
102
  setRecentEdits((prevEditedFields) => {
@@ -155,14 +124,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
155
124
  if (typeof window !== "undefined")
156
125
  sessionStorage?.setItem("sessionId", sessionId);
157
126
  // Workspace state
158
- // Note: "reviews" is a sidebar, not a workspace. If workspace=reviews, we should
127
+ // Note: "reviews" is a sidebar, not a workspace. If view/workspace=reviews, we should
159
128
  // set workspace to "editor" and open the reviews sidebar instead.
160
129
  // Memoize searchParams reads to avoid triggering Router state updates during render
161
130
  // (Next.js App Router uses startTransition internally for URL changes)
162
- const rawWorkspace = useMemo(() => searchParams.get("workspace"), [searchParams]);
131
+ const rawWorkspace = useMemo(() => searchParams.get("workspace") ?? searchParams.get("view"), [searchParams]);
163
132
  const isReviewsSidebarRequest = rawWorkspace === "reviews";
164
133
  const [workspaceId, setWorkspaceId] = useState(
165
- // If workspace=reviews, use "editor" workspace (reviews is a sidebar, not a workspace)
134
+ // If view=reviews, use "editor" workspace (reviews is a sidebar, not a workspace)
166
135
  isReviewsSidebarRequest
167
136
  ? "editor"
168
137
  : (rawWorkspace ??
@@ -184,7 +153,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
184
153
  else {
185
154
  sidebars = [...(configuration.editor.defaultOpenSidebars ?? [])];
186
155
  }
187
- // If workspace=reviews was requested, ensure reviews sidebar is open
156
+ // If view/workspace=reviews was requested, ensure reviews sidebar is open
188
157
  if (isReviewsSidebarRequest && !sidebars.includes("reviews")) {
189
158
  sidebars.push("reviews");
190
159
  }
@@ -192,11 +161,17 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
192
161
  });
193
162
  // Toolbar pinned sidebars - icons always visible in toolbar (defined early so callbacks can access)
194
163
  const [pinnedSidebars, setPinnedSidebars] = useState(userInfo.preferences?.pinnedSidebars || []);
195
- const pinnedSidebarsRef = useRef(pinnedSidebars);
196
164
  // Locked sidebars - open panels that stay visible when selecting another sidebar
197
165
  const [lockedSidebars, setLockedSidebars] = useState(() => {
166
+ if (typeof window === "undefined") {
167
+ return [];
168
+ }
198
169
  try {
199
- const parsed = localStorageService.getOrSetItem("editor.lockedSidebars", []);
170
+ const stored = window.localStorage.getItem("editor.lockedSidebars");
171
+ if (!stored) {
172
+ return [];
173
+ }
174
+ const parsed = JSON.parse(stored);
200
175
  if (!Array.isArray(parsed) ||
201
176
  !parsed.every((id) => typeof id === "string")) {
202
177
  return [];
@@ -212,9 +187,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
212
187
  useEffect(() => {
213
188
  lockedSidebarsRef.current = lockedSidebars;
214
189
  }, [lockedSidebars]);
215
- useEffect(() => {
216
- pinnedSidebarsRef.current = pinnedSidebars;
217
- }, [pinnedSidebars]);
218
190
  // Filter locked sidebars to only include currently open sidebars
219
191
  useEffect(() => {
220
192
  const openSet = new Set(openSidebars);
@@ -276,11 +248,15 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
276
248
  // Group open sidebars into vertical stacks (each stack shares one left column).
277
249
  const [sidebarStacks, setSidebarStacks] = useState(() => {
278
250
  const defaultStacks = openSidebars.map((id) => [id]);
251
+ if (typeof window === "undefined") {
252
+ return normalizeSidebarStacks(openSidebars, defaultStacks);
253
+ }
279
254
  try {
280
- const parsed = localStorageService.getItem("editor.sidebarStacks");
281
- if (!parsed) {
255
+ const stored = window.localStorage.getItem("editor.sidebarStacks");
256
+ if (!stored) {
282
257
  return normalizeSidebarStacks(openSidebars, defaultStacks);
283
258
  }
259
+ const parsed = JSON.parse(stored);
284
260
  if (!Array.isArray(parsed) ||
285
261
  !parsed.every((x) => Array.isArray(x) && x.every((id) => typeof id === "string"))) {
286
262
  return normalizeSidebarStacks(openSidebars, defaultStacks);
@@ -302,19 +278,28 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
302
278
  }, [openSidebars, normalizeSidebarStacks]);
303
279
  // Persist stacks independently of the URL (user layout preference).
304
280
  useEffect(() => {
281
+ if (typeof window === "undefined")
282
+ return;
305
283
  try {
306
- localStorageService.setItem("editor.sidebarStacks", sidebarStacks);
284
+ window.localStorage.setItem("editor.sidebarStacks", JSON.stringify(sidebarStacks));
307
285
  }
308
286
  catch { }
309
287
  }, [sidebarStacks]);
310
288
  // Persist locked sidebars to localStorage.
311
289
  useEffect(() => {
290
+ if (typeof window === "undefined")
291
+ return;
312
292
  try {
313
- localStorageService.setItem("editor.lockedSidebars", lockedSidebars);
293
+ window.localStorage.setItem("editor.lockedSidebars", JSON.stringify(lockedSidebars));
314
294
  }
315
295
  catch { }
316
296
  }, [lockedSidebars]);
297
+ // Legacy aliases for backwards compatibility
317
298
  const viewName = workspaceId;
299
+ const setViewName = setWorkspaceId;
300
+ const viewNameRef = workspaceIdRef;
301
+ const previousViewName = previousWorkspaceId;
302
+ const setPreviousViewName = setPreviousWorkspaceId;
318
303
  const [compareMode, setCompareModeState] = useState(false);
319
304
  const [componentDesignerComponent, setComponentDesignerComponent] = useState();
320
305
  const [componentDesignerRendering, setComponentDesignerRendering] = useState();
@@ -322,7 +307,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
322
307
  const [ignoreBlur, setIgnoreBlur] = useState(false);
323
308
  const [currentItemDescriptor, setCurrentItemDescriptor] = useState();
324
309
  const currentItemDescriptorRef = useRef(undefined);
325
- const latestGlobalLoadKeyRef = useRef(null);
326
310
  const [editorSlots, setEditorSlots] = useState(() => {
327
311
  // Always start with empty slots - don't persist the number of slots
328
312
  return [];
@@ -342,29 +326,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
342
326
  activeSlotIdRef.current = activeSlotId;
343
327
  }, [activeSlotId]);
344
328
  const [slotContexts, setSlotContexts] = useState(() => new Map());
345
- const promptSessionReconnect = useCallback((reason) => {
346
- const description = reason && reason !== "session-revoked"
347
- ? `${reason}. Click reconnect to continue in this browser.`
348
- : "You were disconnected because this account is active in another browser.";
349
- toast.error("Session disconnected", {
350
- id: "session-revoked",
351
- description,
352
- action: {
353
- label: "Reconnect",
354
- onClick: async () => {
355
- const result = await reconnectSession(sessionId);
356
- if (result.type === "success") {
357
- window.location.reload();
358
- return;
359
- }
360
- toast.error("Reconnect failed", {
361
- description: "Could not claim this browser session. Try again.",
362
- });
363
- },
364
- },
365
- duration: Infinity,
366
- });
367
- }, [sessionId]);
368
329
  // Track previous item ID to detect actual navigation between pages
369
330
  const previousItemIdRef = useRef(undefined);
370
331
  useEffect(() => {
@@ -393,9 +354,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
393
354
  // Ref to track when we're handling a popstate event (browser back/forward)
394
355
  // This prevents the URL sync effect from pushing new history entries during back navigation
395
356
  const isHandlingPopStateRef = useRef(false);
396
- // When switchWorkspace already pushed a URL entry, the follow-up URL sync
397
- // effect should only *replace* that entry (not push a second one).
398
- const switchWorkspacePushedRef = useRef(false);
399
357
  // Ref to track the last known URL for the popstate handler
400
358
  // This is updated both when the popstate handler runs AND when the URL sync effect pushes a new URL
401
359
  // Without this, the popstate handler would have a stale lastUrl value after pushState calls
@@ -412,16 +370,26 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
412
370
  const [showSuggestedEditsDiff, setShowSuggestedEditsDiff] = useState(false);
413
371
  const [availableCommentTags, setAvailableCommentTags] = useState([]);
414
372
  const [showComments, setShowComments] = useState(() => {
415
- return localStorageService.getOrSetItem("editor.showComments", true);
373
+ const savedShowComments = typeof window !== "undefined"
374
+ ? localStorage.getItem("editor.showComments")
375
+ : null;
376
+ return savedShowComments ? JSON.parse(savedShowComments) : true;
416
377
  });
417
378
  useEffect(() => {
418
- localStorageService.setItem("editor.showComments", showComments);
379
+ if (typeof window !== "undefined") {
380
+ localStorage.setItem("editor.showComments", JSON.stringify(showComments));
381
+ }
419
382
  }, [showComments]);
420
383
  const [showResolvedComments, setShowResolvedComments] = useState(() => {
421
- return localStorageService.getOrSetItem("editor.showResolvedComments", false);
384
+ const saved = typeof window !== "undefined"
385
+ ? localStorage.getItem("editor.showResolvedComments")
386
+ : null;
387
+ return saved ? JSON.parse(saved) : false;
422
388
  });
423
389
  useEffect(() => {
424
- localStorageService.setItem("editor.showResolvedComments", showResolvedComments);
390
+ if (typeof window !== "undefined") {
391
+ localStorage.setItem("editor.showResolvedComments", JSON.stringify(showResolvedComments));
392
+ }
425
393
  }, [showResolvedComments]);
426
394
  const [selectedComment, setSelectedComment] = useState();
427
395
  const [browseHistory, setBrowseHistory] = useState(() => {
@@ -440,12 +408,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
440
408
  visitedAt: entry.visitedAt,
441
409
  }));
442
410
  });
443
- // Navigation history for browser history (workspace + item combinations)
411
+ // Navigation history for browser history (view + item combinations)
444
412
  const [navigationHistory, setNavigationHistory] = useState(() => {
445
- // Initialize from browse history with the current workspace
413
+ // Initialize from browse history with current view
446
414
  if (!userInfo.browseHistory)
447
415
  return [];
448
416
  const defaultWorkspaceId = searchParams.get("workspace") ??
417
+ searchParams.get("view") ??
449
418
  configuration.editor.defaultWorkspace ??
450
419
  configuration.editor.workspaces?.[0]?.id ??
451
420
  "editor";
@@ -477,43 +446,20 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
477
446
  const [statusMessage, setStatusMessage] = useState("");
478
447
  const [focusFieldComponentId, setFocusFieldComponentId] = useState();
479
448
  const [enableCompletions, setEnableCompletions] = useState(false);
480
- const [showComponentNavigatorDefault, setShowComponentNavigatorDefault] = useState(userPreferences.showComponentNavigator ?? false);
481
- const [slotComponentNavigatorVisibility, setSlotComponentNavigatorVisibility] = useState({});
482
- useEffect(() => {
483
- setSlotComponentNavigatorVisibility((prev) => {
484
- const next = {};
485
- let changed = false;
486
- for (const slot of editorSlots) {
487
- if (Object.prototype.hasOwnProperty.call(prev, slot.slotId)) {
488
- next[slot.slotId] = prev[slot.slotId];
489
- }
490
- else {
491
- next[slot.slotId] = showComponentNavigatorDefault;
492
- changed = true;
493
- }
494
- }
495
- if (Object.keys(prev).length !== editorSlots.length) {
496
- changed = true;
497
- }
498
- return changed ? next : prev;
499
- });
500
- }, [editorSlots, showComponentNavigatorDefault]);
449
+ const [showComponentNavigator, setShowComponentNavigator] = useState(userPreferences.showComponentNavigator ?? false);
501
450
  const [showAgentsPanel, setShowAgentsPanel] = useState(userPreferences.showAgentsPanel ?? false);
502
451
  const [showMinimap, setShowMinimap] = useState(userPreferences.showMinimap ?? true);
503
452
  const [showHelpTerminal, setShowHelpTerminal] = useState(false);
504
453
  const [helpTerminalInitialPrompt, setHelpTerminalInitialPrompt] = useState(undefined);
505
454
  const [helpTerminalProfileName, setHelpTerminalProfileName] = useState(undefined);
506
455
  const [helpTerminalActiveTab, setHelpTerminalActiveTab] = useState(undefined);
507
- const [selectedHelpSectionId, setSelectedHelpSectionId] = useState(null);
508
- const [showAgentsWorkspaceEditor, setShowAgentsWorkspaceEditor] = useState(false);
509
- const [selectedAgentsWorkspaceAgentId, setSelectedAgentsWorkspaceAgentId] = useState(null);
456
+ const [showAgentsWorkspaceEditor, setShowAgentsWorkspaceEditor] = useState(true);
510
457
  const [activeEditorTab, setActiveEditorTab] = useState(null);
511
458
  const [showLayoutComponents, setShowLayoutComponents] = useState(userPreferences.showLayoutComponents ?? false);
512
459
  const { quotaInfo, setQuotaInfo, isQuotaExceeded, getQuotaWarningMessage } = useQuota({
513
460
  showError: ({ summary, details }) => showErrorToast({ summary, details }),
514
461
  });
515
462
  const [webSocketMessages, setWebSocketMessages] = useState([]);
516
- const [socketDiagnostics, setSocketDiagnostics] = useState(() => createEditorSocketDiagnostics(sessionId));
517
463
  const [favorites, setFavorites] = useState([]);
518
464
  // Quick item switcher state
519
465
  const [quickSwitcherVisible, setQuickSwitcherVisible] = useState(false);
@@ -531,12 +477,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
531
477
  if (!startupChecks.hasBlockingIssues)
532
478
  return;
533
479
  // Don't redirect if already in settings workspace - let user navigate freely within settings
534
- const currentWorkspace = searchParams.get("workspace");
480
+ const currentWorkspace = searchParams.get("workspace") ?? searchParams.get("view");
535
481
  if (currentWorkspace === "settings")
536
482
  return;
537
483
  // Redirect to the status panel (where user can see all issues and navigate to fixes)
538
484
  const url = new URL(window.location.href);
539
485
  url.searchParams.set("workspace", "settings");
486
+ url.searchParams.delete("view"); // Remove legacy param
540
487
  url.searchParams.set("ccpanel", "status");
541
488
  router.push(url.toString(), { scroll: false });
542
489
  }, [
@@ -554,16 +501,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
554
501
  setMode(queryMode);
555
502
  }
556
503
  }, [searchParams, isInitialLoad]);
557
- useEffect(() => {
558
- if (!isInitialLoad)
559
- return;
560
- const helpParam = searchParams.get("help");
561
- if (helpParam) {
562
- setHelpTerminalActiveTab("manual");
563
- setShowHelpTerminal(true);
564
- setSelectedHelpSectionId(helpParam === "contents" || helpParam === "true" ? null : helpParam);
565
- }
566
- }, [searchParams, isInitialLoad]);
567
504
  useEffect(() => {
568
505
  if (mode === "suggestions") {
569
506
  // Ensure we're in the editor workspace and open the feedback sidebar
@@ -610,19 +547,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
610
547
  setSlotContexts((prev) => {
611
548
  if (!prev.has(slotId))
612
549
  return prev;
613
- if (slotId === activeSlotIdRef.current) {
614
- const activeCtx = prev.get(slotId);
615
- if (activeCtx) {
616
- lastActiveSlotContextRef.current = activeCtx;
617
- }
618
- }
619
550
  const next = new Map(prev);
620
551
  next.delete(slotId);
621
552
  return next;
622
553
  });
623
554
  }, []);
624
555
  const slotContextsRef = useRef(slotContexts);
625
- const lastActiveSlotContextRef = useRef(null);
626
556
  useEffect(() => {
627
557
  slotContextsRef.current = slotContexts;
628
558
  }, [slotContexts]);
@@ -648,12 +578,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
648
578
  const activeSlotContext = activeSlotId
649
579
  ? slotContexts.get(activeSlotId)
650
580
  : undefined;
651
- const isComponentNavigatorOpenForSlot = useCallback((slotId) => {
652
- if (!slotId)
653
- return showComponentNavigatorDefault;
654
- return (slotComponentNavigatorVisibility[slotId] ?? showComponentNavigatorDefault);
655
- }, [slotComponentNavigatorVisibility, showComponentNavigatorDefault]);
656
- const showComponentNavigator = isComponentNavigatorOpenForSlot(activeSlotId);
657
581
  // Sync global compareMode from the active slot's compareMode for URL syncing
658
582
  useEffect(() => {
659
583
  if (activeSlotContext && activeSlotContext.compareMode !== compareMode) {
@@ -701,9 +625,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
701
625
  const isItemUsedInCurrentPage = useCallback((item) => pageItemsSetRef.current.has(makeItemKey(item)), [makeItemKey]);
702
626
  const socketMessageListeners = useRef(new Set());
703
627
  const [socketConnectionVersion, setSocketConnectionVersion] = useState(0);
704
- useEffect(() => {
705
- setSocketDiagnostics(createEditorSocketDiagnostics(sessionId));
706
- }, [sessionId]);
707
628
  const addSocketMessageListener = useCallback((callback) => {
708
629
  socketMessageListeners.current.add(callback);
709
630
  return () => socketMessageListeners.current.delete(callback);
@@ -788,13 +709,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
788
709
  console.error(`No workspace found for id: ${workspaceId}`);
789
710
  return null;
790
711
  }
791
- const activeKeyboardCommands = useMemo(() => {
792
- const activeCommandIds = new Set(currentWorkspace.keyboardCommandIds ?? []);
793
- return (configuration.commands.keyboardCommands ?? []).filter((command) => activeCommandIds.has(command.id));
794
- }, [
795
- currentWorkspace.keyboardCommandIds,
796
- configuration.commands.keyboardCommands,
797
- ]);
712
+ // Legacy alias for backwards compatibility
713
+ const currentView = currentWorkspace;
798
714
  useEffect(() => {
799
715
  if (currentWorkspace?.component) {
800
716
  setCenterPanelView(currentWorkspace.component);
@@ -822,12 +738,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
822
738
  const sendClientInfo = useCallback(() => {
823
739
  debouncedSendClientInfo();
824
740
  }, [debouncedSendClientInfo]);
825
- const getCurrentHistoryState = useCallback(() => {
826
- if (typeof window === "undefined") {
827
- return null;
828
- }
829
- return window.history.state;
830
- }, []);
831
741
  const startTour = useCallback(() => {
832
742
  setIsTourActive(true);
833
743
  // Persist tour state to URL so it survives navigation/remounts
@@ -835,61 +745,32 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
835
745
  const params = new URLSearchParams(window.location.search);
836
746
  params.set("tour", "active");
837
747
  const newUrl = `${window.location.pathname}?${params.toString()}`;
838
- window.history.replaceState(getCurrentHistoryState(), "", newUrl);
748
+ window.history.replaceState(null, "", newUrl);
839
749
  }, [setIsTourActive]);
840
- const isMobile = useMediaQuery("(max-width: 767px)");
841
- // On mobile, clear all locked sidebars and keep only the last-opened panel.
842
- // Handles viewport resize: desktop -> mobile unlocks everything and trims to one panel.
843
- useEffect(() => {
844
- if (isMobile) {
845
- setLockedSidebars([]);
846
- const current = openSidebarsRef.current;
847
- const lastSidebar = current[current.length - 1];
848
- if (current.length > 1 && lastSidebar) {
849
- const trimmed = [lastSidebar];
850
- openSidebarsRef.current = trimmed;
851
- setOpenSidebars(trimmed);
852
- }
853
- }
854
- }, [isMobile]);
855
- const setComponentNavigatorOpenForSlot = useCallback((slotId, value) => {
856
- const previousValue = isComponentNavigatorOpenForSlot(slotId);
857
- const newValue = typeof value === "function" ? value(previousValue) : value;
858
- if (slotId) {
859
- setSlotComponentNavigatorVisibility((prev) => {
860
- const currentValue = prev[slotId] ?? showComponentNavigatorDefault;
861
- if (currentValue === newValue && prev[slotId] !== undefined) {
862
- return prev;
863
- }
864
- return {
865
- ...prev,
866
- [slotId]: newValue,
867
- };
868
- });
869
- }
870
- setShowComponentNavigatorDefault(newValue);
750
+ const isMobile = useMediaQuery("(max-width: 768px)");
751
+ const handleSetShowComponentNavigator = useCallback((value) => {
752
+ const newValue = typeof value === "function" ? value(showComponentNavigator) : value;
753
+ setShowComponentNavigator(newValue);
871
754
  setUserPreferences({ showComponentNavigator: newValue });
755
+ // On mobile, close Agents Panel when opening Component Navigator
872
756
  if (isMobile && newValue) {
873
757
  setShowAgentsPanel(false);
874
758
  setUserPreferences({ showAgentsPanel: false });
875
759
  }
876
760
  }, [
877
- isComponentNavigatorOpenForSlot,
878
- showComponentNavigatorDefault,
761
+ showComponentNavigator,
762
+ setShowComponentNavigator,
879
763
  setUserPreferences,
880
764
  isMobile,
881
765
  setShowAgentsPanel,
882
766
  ]);
883
- const handleSetShowComponentNavigator = useCallback((value) => {
884
- setComponentNavigatorOpenForSlot(activeSlotIdRef.current, value);
885
- }, [setComponentNavigatorOpenForSlot]);
886
767
  const handleSetShowAgentsPanel = useCallback((value) => {
887
768
  const newValue = typeof value === "function" ? value(showAgentsPanel) : value;
888
769
  setShowAgentsPanel(newValue);
889
770
  setUserPreferences({ showAgentsPanel: newValue });
890
771
  // On mobile, close Component Navigator when opening Agents Panel
891
772
  if (isMobile && newValue) {
892
- setComponentNavigatorOpenForSlot(activeSlotIdRef.current, false);
773
+ setShowComponentNavigator(false);
893
774
  setUserPreferences({ showComponentNavigator: false });
894
775
  }
895
776
  }, [
@@ -897,40 +778,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
897
778
  setShowAgentsPanel,
898
779
  setUserPreferences,
899
780
  isMobile,
900
- setComponentNavigatorOpenForSlot,
781
+ setShowComponentNavigator,
901
782
  ]);
902
- // Mobile editor panel state (EditorForm shown in bottom panel on mobile)
903
- const [mobileEditorPanelOpen, setMobileEditorPanelOpenRaw] = useState(false);
904
- const [dismissedMobilePanelToken, setDismissedMobilePanelToken] = useState(null);
905
- const previousActiveSlotIdRef = useRef(null);
906
- const mobilePanelDismissToken = useMemo(() => {
907
- const selectionKey = selection.join(",");
908
- return [
909
- activeSlotId || "no-slot",
910
- selectionKey,
911
- insertMode ? "insert" : "browse",
912
- ].join("|");
913
- }, [activeSlotId, insertMode, selection]);
914
- useEffect(() => {
915
- const previousActiveSlotId = previousActiveSlotIdRef.current;
916
- if (previousActiveSlotId !== activeSlotId) {
917
- setDismissedMobilePanelToken(null);
918
- }
919
- previousActiveSlotIdRef.current = activeSlotId;
920
- }, [activeSlotId]);
921
- const handleSetMobileEditorPanelOpen = useCallback((open) => {
922
- setMobileEditorPanelOpenRaw(open);
923
- if (!open) {
924
- setDismissedMobilePanelToken(mobilePanelDismissToken);
925
- return;
926
- }
927
- setDismissedMobilePanelToken(null);
928
- if (open && isMobile) {
929
- // Close all sidebars when opening the editor panel on mobile
930
- openSidebarsRef.current = [];
931
- setOpenSidebars([]);
932
- }
933
- }, [isMobile, mobilePanelDismissToken]);
934
783
  const handleSetShowMinimap = useCallback((value) => {
935
784
  const newValue = typeof value === "function" ? value(showMinimap) : value;
936
785
  setShowMinimap(newValue);
@@ -944,7 +793,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
944
793
  setHelpTerminalInitialPrompt(undefined);
945
794
  setHelpTerminalProfileName(undefined);
946
795
  setHelpTerminalActiveTab(undefined);
947
- setSelectedHelpSectionId(null);
948
796
  }
949
797
  }, [showHelpTerminal]);
950
798
  const toggleHelpTerminal = useCallback((options) => {
@@ -987,27 +835,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
987
835
  setOpenSidebars(newOrder);
988
836
  setSidebarStacks((prev) => normalizeSidebarStacks(newOrder, prev));
989
837
  }, []);
990
- const ensureSidebarPinned = useCallback((sidebarId) => {
991
- const currentPinnedSidebars = pinnedSidebarsRef.current;
992
- if (currentPinnedSidebars.includes(sidebarId)) {
993
- return;
994
- }
995
- const newPinnedSidebars = [...currentPinnedSidebars, sidebarId];
996
- pinnedSidebarsRef.current = newPinnedSidebars;
997
- setPinnedSidebars(newPinnedSidebars);
998
- setUserPreferences({ pinnedSidebars: newPinnedSidebars });
999
- }, [setUserPreferences]);
1000
838
  // messageHandler is defined after loadItem/loadHistory declarations to avoid temporal dead zones
1001
839
  const user = activeSessions.find((x) => x.sessionId === sessionId)?.user ||
1002
840
  userInfo.user;
1003
- // Self-heal if our session disappears (e.g., after HMR). Skip when concurrent user limit
1004
- // is showing so we don't spam recovery attempts when the connection was rejected.
841
+ // Self-heal if our session disappears (e.g., after HMR)
1005
842
  const missingSessionRecoveryTimerRef = useRef(null);
1006
843
  const missingSessionRecoveryAttemptsRef = useRef(0);
1007
- const concurrentUserLimitErrorRef = useRef(null);
1008
844
  useEffect(() => {
1009
- if (concurrentUserLimitErrorRef.current !== null)
1010
- return;
1011
845
  const hasMySession = activeSessions.some((s) => s.sessionId === sessionId);
1012
846
  if (hasMySession) {
1013
847
  // Reset recovery state when we see ourselves again
@@ -1023,6 +857,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1023
857
  return;
1024
858
  const attempt = missingSessionRecoveryAttemptsRef.current + 1;
1025
859
  const delay = Math.min(250 * Math.pow(2, attempt - 1), 2000);
860
+ console.warn(`⚠️ Current session not present in active sessions. Recovery attempt ${attempt} in ${delay}ms...`);
1026
861
  missingSessionRecoveryTimerRef.current = setTimeout(() => {
1027
862
  missingSessionRecoveryTimerRef.current = null;
1028
863
  missingSessionRecoveryAttemptsRef.current = attempt;
@@ -1031,7 +866,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1031
866
  }
1032
867
  else {
1033
868
  // Force a reconnect to refresh presence after several failed nudges
1034
- console.warn("Session presence did not recover after retries. Forcing reconnect.");
1035
869
  try {
1036
870
  globalThis.editorSocket?.close(4000, "recover-presence");
1037
871
  }
@@ -1051,15 +885,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1051
885
  // Initialize lastUrlRef to current URL on mount
1052
886
  lastUrlRef.current = window.location.href;
1053
887
  const keepAliveUrl = "/parhelia/keepalive";
1054
- const runSessionCheck = () => {
888
+ const interval = setInterval(() => {
1055
889
  fetch(keepAliveUrl + "?ts=" + Date.now())
1056
890
  .then((response) => {
1057
- if (response.headers.get("X-Parhelia-Session-Revoked") === "true") {
1058
- window.dispatchEvent(new CustomEvent("parhelia:session-revoked", {
1059
- detail: { reason: "session-revoked" },
1060
- }));
1061
- return;
1062
- }
1063
891
  if (response.status === 401 || response.status === 403) {
1064
892
  toast.error("Your session has expired", {
1065
893
  description: "Please login again to continue editing.",
@@ -1072,24 +900,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1072
900
  }
1073
901
  })
1074
902
  .catch((error) => console.error("Keep Alive error:", error));
1075
- };
1076
- const keepaliveIntervalMs = (() => {
1077
- const param = new URLSearchParams(window.location.search).get("keepaliveIntervalMs");
1078
- if (!param)
1079
- return 5 * 60 * 1000;
1080
- const ms = parseInt(param, 10);
1081
- return Number.isFinite(ms) && ms >= 2000 && ms <= 60000
1082
- ? ms
1083
- : 5 * 60 * 1000;
1084
- })();
1085
- const interval = setInterval(() => {
1086
- runSessionCheck();
1087
- }, keepaliveIntervalMs);
1088
- const handleVisibilityChange = () => {
1089
- if (document.visibilityState === "visible") {
1090
- runSessionCheck();
1091
- }
1092
- };
903
+ }, 5 * 60 * 1000);
1093
904
  const handleMessage = (event) => {
1094
905
  if (event.data.type === "componentsSelected") {
1095
906
  setSelection(event.data.componentIds);
@@ -1104,8 +915,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1104
915
  isHandlingPopStateRef.current = true;
1105
916
  // Sync URL parameters back to component state for browser navigation
1106
917
  const urlParams = new URLSearchParams(window.location.search);
1107
- const urlWorkspace = urlParams.get("workspace");
1108
- if (urlWorkspace && urlWorkspace !== workspaceIdRef.current) {
918
+ // Handle workspace changes (with legacy view fallback)
919
+ const urlWorkspace = urlParams.get("workspace") ?? urlParams.get("view");
920
+ if (urlWorkspace && urlWorkspace !== viewNameRef.current) {
1109
921
  setWorkspaceId(urlWorkspace);
1110
922
  }
1111
923
  // Handle sidebar changes
@@ -1122,18 +934,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1122
934
  if (compareValue !== compareMode) {
1123
935
  setCompareMode(compareValue);
1124
936
  }
1125
- // Handle help panel changes
1126
- const helpParam = urlParams.get("help");
1127
- if (helpParam) {
1128
- setHelpTerminalActiveTab("manual");
1129
- setShowHelpTerminal(true);
1130
- setSelectedHelpSectionId(helpParam === "contents" || helpParam === "true"
1131
- ? null
1132
- : helpParam);
1133
- }
1134
- else {
1135
- handleSetShowHelpTerminal(false);
1136
- }
1137
937
  // Handle mode changes
1138
938
  const urlMode = urlParams.get("mode");
1139
939
  if (urlMode && urlMode !== mode) {
@@ -1189,11 +989,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1189
989
  };
1190
990
  window.addEventListener("message", handleMessage);
1191
991
  window.addEventListener("popstate", handlePopState);
1192
- window.addEventListener("visibilitychange", handleVisibilityChange);
1193
992
  return () => {
1194
993
  window.removeEventListener("message", handleMessage);
1195
994
  window.removeEventListener("popstate", handlePopState);
1196
- window.removeEventListener("visibilitychange", handleVisibilityChange);
1197
995
  clearInterval(interval);
1198
996
  };
1199
997
  }, []);
@@ -1203,34 +1001,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1203
1001
  if (searchParams.get("noTour") !== null) {
1204
1002
  return;
1205
1003
  }
1206
- // Don't start tour when there are setup errors (user is or will be on system status page)
1207
- if (startupChecks.state === "complete" && startupChecks.hasBlockingIssues) {
1208
- return;
1209
- }
1210
- // Don't start tour when already on settings system status page
1211
- if (viewName === "settings" && searchParams.get("ccpanel") === "status") {
1212
- return;
1213
- }
1214
- // Wait for startup checks so we know whether we'll redirect to status
1215
- if (startupChecks.state !== "complete") {
1216
- return;
1217
- }
1218
1004
  const tour = configuration.activeTour;
1219
1005
  const key = tour === "default" ? "editor.tourShown" : "editor.tourShown." + tour;
1220
- const tourShown = localStorageService.getString(key);
1006
+ const tourShown = localStorage.getItem(key);
1221
1007
  if (!tourShown) {
1222
1008
  startTour();
1223
- localStorageService.setString(key, "true");
1009
+ localStorage.setItem(key, "true");
1224
1010
  }
1225
- }, [
1226
- user,
1227
- startupChecks.state,
1228
- startupChecks.hasBlockingIssues,
1229
- viewName,
1230
- searchParams,
1231
- configuration.activeTour,
1232
- startTour,
1233
- ]);
1011
+ }, [user]);
1234
1012
  // WebSocket initialization is performed after messageHandler is defined
1235
1013
  // Defer URL sync until loadItem is defined below
1236
1014
  // Mark end of initial load phase
@@ -1362,8 +1140,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1362
1140
  const loadComments = useCallback(async () => {
1363
1141
  if (!currentItemDescriptor)
1364
1142
  return;
1365
- const reviewId = searchParams.get("reviewId");
1366
- const result = await getComments(currentItemDescriptor.id, currentItemDescriptor.language, currentItemDescriptor.version, reviewId ?? undefined);
1143
+ const result = await getComments(currentItemDescriptor.id, currentItemDescriptor.language, currentItemDescriptor.version);
1367
1144
  if (handleErrorResult(result, ui, state))
1368
1145
  return;
1369
1146
  setComments((x) => {
@@ -1376,7 +1153,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1376
1153
  allComments.sort((a, b) => a.position - b.position);
1377
1154
  return allComments;
1378
1155
  });
1379
- }, [currentItemDescriptor, searchParams]);
1156
+ }, [currentItemDescriptor]);
1380
1157
  // Assuming currentItemDescriptor, ui, state, handleErrorResult, and setSuggestedEdits
1381
1158
  // are available in your component context.
1382
1159
  const loadSuggestedEdits = useCallback(async () => {
@@ -1385,8 +1162,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1385
1162
  const result = await getSuggestedEdits(item.descriptor.id, item.descriptor.language, item.descriptor.version);
1386
1163
  if (handleErrorResult(result, ui, state))
1387
1164
  return;
1388
- const edits = result.data || [];
1389
- setSuggestedEdits(edits);
1165
+ setSuggestedEdits(result.data || []);
1390
1166
  }, [item]);
1391
1167
  const loadFavorites = useCallback(async () => {
1392
1168
  try {
@@ -1460,25 +1236,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1460
1236
  return idB.localeCompare(idA);
1461
1237
  });
1462
1238
  }, []);
1463
- const normalizeEditHistoryPayload = useCallback((value) => {
1464
- if (Array.isArray(value)) {
1465
- return value;
1466
- }
1467
- if (value && typeof value === "object") {
1468
- const payload = value;
1469
- const candidates = [
1470
- payload.operations,
1471
- payload.history,
1472
- payload.items,
1473
- payload.data,
1474
- ];
1475
- const firstArray = candidates.find((candidate) => Array.isArray(candidate));
1476
- if (Array.isArray(firstArray)) {
1477
- return firstArray;
1478
- }
1479
- }
1480
- return [];
1481
- }, []);
1482
1239
  useEffect(() => {
1483
1240
  // Read fresh page from the mutable slot context ref chain.
1484
1241
  // The slot context uses a stable ref that is mutated in-place (see editorSlotContext.ts),
@@ -1501,7 +1258,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1501
1258
  if (handleErrorResult(result, ui, state))
1502
1259
  return;
1503
1260
  setEditHistory((prev) => {
1504
- const next = normalizeEditHistoryPayload(result.data);
1261
+ const next = result.data || [];
1505
1262
  if (!prev.length)
1506
1263
  return sortEditHistoryByDateDesc(next);
1507
1264
  if (!next.length)
@@ -1560,8 +1317,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1560
1317
  const shouldFilterByLanguage = filterByLanguage !== undefined
1561
1318
  ? filterByLanguage
1562
1319
  : filterByCurrentLanguage;
1563
- const trimmedHistoryQuery = historySearchQuery.trim();
1564
- const historyQuery = trimmedHistoryQuery.length > 0 ? trimmedHistoryQuery : undefined;
1565
1320
  if (currentMode === "global") {
1566
1321
  // Global mode: optionally filter by session and/or language
1567
1322
  const currentLanguage = item?.descriptor?.language || currentItemDescriptor?.language;
@@ -1571,14 +1326,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1571
1326
  language: shouldFilterByLanguage && currentLanguage
1572
1327
  ? currentLanguage
1573
1328
  : undefined,
1574
- query: historyQuery,
1575
1329
  });
1576
1330
  if (handleErrorResult(result, ui, state)) {
1577
1331
  console.error("[EditorShell] Failed to load history:", result);
1578
1332
  return;
1579
1333
  }
1580
1334
  setEditHistory((prev) => {
1581
- const next = normalizeEditHistoryPayload(result.data);
1335
+ const next = result.data || [];
1582
1336
  const scope = {
1583
1337
  mode: currentMode,
1584
1338
  filterBySession: shouldFilterBySession,
@@ -1589,12 +1343,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1589
1343
  };
1590
1344
  if (!prev.length)
1591
1345
  return sortEditHistoryByDateDesc(next.filter((op) => matchesHistoryScope(op, scope)));
1592
- if (!next.length) {
1593
- // When searching, respect the empty result — don't fall back to previous items
1594
- if (historyQuery)
1595
- return [];
1346
+ if (!next.length)
1596
1347
  return sortEditHistoryByDateDesc(prev.filter((op) => matchesHistoryScope(op, scope)));
1597
- }
1598
1348
  const prevById = new Map(prev.map((x) => [x.id, x]));
1599
1349
  const nextById = new Set(next.map((x) => x.id));
1600
1350
  const merged = next
@@ -1630,12 +1380,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1630
1380
  return mergedOp;
1631
1381
  });
1632
1382
  // Preserve operations that arrived via WebSocket during the fetch window
1633
- // but not when filtering by search query — search results are authoritative
1634
- if (!historyQuery) {
1635
- for (const [id, priorOp] of prevById) {
1636
- if (!nextById.has(id) && matchesHistoryScope(priorOp, scope)) {
1637
- merged.push(priorOp);
1638
- }
1383
+ for (const [id, priorOp] of prevById) {
1384
+ if (!nextById.has(id) && matchesHistoryScope(priorOp, scope)) {
1385
+ merged.push(priorOp);
1639
1386
  }
1640
1387
  }
1641
1388
  return sortEditHistoryByDateDesc(merged);
@@ -1658,13 +1405,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1658
1405
  const result = await getEditHistory({
1659
1406
  item: itemFilter,
1660
1407
  sessionId: shouldFilterBySession ? sessionId : undefined,
1661
- query: historyQuery,
1662
1408
  });
1663
1409
  if (handleErrorResult(result, ui, state)) {
1664
1410
  console.error("[EditorShell] Failed to load item history:", result);
1665
1411
  return;
1666
1412
  }
1667
- let operations = normalizeEditHistoryPayload(result.data);
1413
+ let operations = result.data || [];
1668
1414
  // Client-side version filtering for current-version mode
1669
1415
  if (currentMode === "current-version") {
1670
1416
  // Defensive filter: only include operations for the current version
@@ -1687,11 +1433,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1687
1433
  };
1688
1434
  if (!prev.length)
1689
1435
  return sortEditHistoryByDateDesc(operations.filter((op) => matchesHistoryScope(op, scope)));
1690
- if (!operations.length) {
1691
- if (historyQuery)
1692
- return [];
1436
+ if (!operations.length)
1693
1437
  return sortEditHistoryByDateDesc(prev.filter((op) => matchesHistoryScope(op, scope)));
1694
- }
1695
1438
  const prevById = new Map(prev.map((x) => [x.id, x]));
1696
1439
  const nextById = new Set(operations.map((x) => x.id));
1697
1440
  const merged = operations
@@ -1727,12 +1470,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1727
1470
  return mergedOp;
1728
1471
  });
1729
1472
  // Preserve operations that arrived via WebSocket during the fetch window
1730
- // but not when filtering by search query — search results are authoritative
1731
- if (!historyQuery) {
1732
- for (const [id, priorOp] of prevById) {
1733
- if (!nextById.has(id) && matchesHistoryScope(priorOp, scope)) {
1734
- merged.push(priorOp);
1735
- }
1473
+ for (const [id, priorOp] of prevById) {
1474
+ if (!nextById.has(id) && matchesHistoryScope(priorOp, scope)) {
1475
+ merged.push(priorOp);
1736
1476
  }
1737
1477
  }
1738
1478
  return sortEditHistoryByDateDesc(merged);
@@ -1743,11 +1483,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1743
1483
  historyMode,
1744
1484
  showOnlyMyChanges,
1745
1485
  filterByCurrentLanguage,
1746
- historySearchQuery,
1747
1486
  item,
1748
1487
  currentItemDescriptor,
1749
1488
  matchesHistoryScope,
1750
- normalizeEditHistoryPayload,
1751
1489
  sortEditHistoryByDateDesc,
1752
1490
  ]);
1753
1491
  // Debounced history refresh to avoid hammering `/parhelia/editHistory` on rapid UI changes.
@@ -1813,14 +1551,13 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1813
1551
  }
1814
1552
  }
1815
1553
  else if (historyMode !== "global" && currentItemDescriptor) {
1816
- // Always load immediately for page-centric/current-version/timeline so we don't show
1817
- // an empty history list for the debounce window (e.g. 600ms). The effect only runs on
1818
- // mode or item id/lang/version change, not on every keystroke, so this avoids flaky
1819
- // undo/redo tests and improves UX when switching to page-centric.
1820
1554
  if (!historyInitialLoadDoneRef.current) {
1821
1555
  historyInitialLoadDoneRef.current = true;
1556
+ refreshHistoryRef.current(historyMode);
1557
+ }
1558
+ else {
1559
+ debouncedRefreshHistoryRef.current(historyMode);
1822
1560
  }
1823
- refreshHistoryRef.current(historyMode);
1824
1561
  }
1825
1562
  else if (historyMode !== "global" && !currentItemDescriptor) {
1826
1563
  // Clear history if no item loaded in page-centric modes
@@ -1833,7 +1570,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1833
1570
  historyMode,
1834
1571
  showOnlyMyChanges,
1835
1572
  filterByCurrentLanguage,
1836
- historySearchQuery,
1837
1573
  currentItemDescriptor?.id,
1838
1574
  currentItemDescriptor?.language,
1839
1575
  currentItemDescriptor?.version,
@@ -1898,9 +1634,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1898
1634
  if (isInitialLoad)
1899
1635
  return;
1900
1636
  const current = new URLSearchParams(window.location.search);
1901
- const urlWorkspace = current.get("workspace");
1902
- const urlView = current.get("view");
1903
- const isWorkspaceTransitioning = !!urlWorkspace && urlWorkspace !== viewName;
1904
1637
  // Sync item-related parameters only when an item is selected
1905
1638
  if (currentItemDescriptor) {
1906
1639
  if (current.get("itemid") !== currentItemDescriptor.id) {
@@ -1931,9 +1664,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1931
1664
  // If reviewId or urlItemId exists, preserve itemid/lang/version from URL
1932
1665
  }
1933
1666
  // Always sync workspace-related parameters regardless of item selection
1934
- if (!isWorkspaceTransitioning && current.get("workspace") !== viewName) {
1667
+ if (current.get("workspace") !== viewName) {
1935
1668
  current.set("workspace", viewName);
1936
1669
  }
1670
+ current.delete("view"); // Remove legacy view param
1937
1671
  // Sync sidebar state
1938
1672
  const currentSidebars = current.get("sidebar") ?? "";
1939
1673
  const newSidebars = openSidebars.join(",");
@@ -1945,12 +1679,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1945
1679
  current.delete("sidebar");
1946
1680
  }
1947
1681
  }
1948
- if (showHelpTerminal) {
1949
- current.set("help", selectedHelpSectionId ?? "contents");
1950
- }
1951
- else {
1952
- current.delete("help");
1953
- }
1954
1682
  if (!compareMode) {
1955
1683
  current.delete("compare");
1956
1684
  current.delete("compareLanguage");
@@ -1975,15 +1703,15 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1975
1703
  else {
1976
1704
  current.delete("wizardid");
1977
1705
  }
1978
- // Preserve settings-specific parameters while transitioning into Settings too.
1979
- // Some callers update the URL first and switch the workspace state a moment later.
1980
- const isSettingsNavigation = viewName === "settings" ||
1981
- urlWorkspace === "settings" ||
1982
- urlView === "settings";
1983
- if (!isSettingsNavigation) {
1706
+ // Only preserve ccpanel parameter when on settings view, remove it otherwise
1707
+ if (viewName === "settings") {
1708
+ const ccpanel = current.get("ccpanel");
1709
+ if (ccpanel) {
1710
+ current.set("ccpanel", ccpanel);
1711
+ }
1712
+ }
1713
+ else {
1984
1714
  current.delete("ccpanel");
1985
- current.delete("providerId");
1986
- current.delete("modelId");
1987
1715
  }
1988
1716
  // Preserve reviewId parameter if it exists (for review links)
1989
1717
  // This ensures review links don't lose the reviewId when URL is synced
@@ -1996,28 +1724,17 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
1996
1724
  const browserPathname = typeof window !== "undefined" ? window.location.pathname : pathname;
1997
1725
  const newUrl = `${browserPathname}?${current.toString()}`;
1998
1726
  const oldUrl = `${browserPathname}${window.location.search}`;
1999
- const isRestoringLastSyncedUrl = newUrl === lastUrlRef.current;
2000
1727
  // Skip pushing to history if we're handling a popstate event (browser back/forward)
2001
1728
  // This prevents the URL sync from overwriting the history during back navigation
2002
1729
  if (isHandlingPopStateRef.current) {
2003
1730
  return;
2004
1731
  }
2005
1732
  if (newUrl !== oldUrl) {
2006
- if (switchWorkspacePushedRef.current || isRestoringLastSyncedUrl) {
2007
- window.history.replaceState(getCurrentHistoryState(), "", newUrl);
2008
- switchWorkspacePushedRef.current = false;
2009
- }
2010
- else {
2011
- window.history.pushState(getCurrentHistoryState(), "", newUrl);
2012
- }
1733
+ window.history.pushState(null, "", newUrl);
1734
+ // Update lastUrlRef so the popstate handler knows the current URL
1735
+ // This fixes the issue where goBack() wouldn't work because lastUrl was stale
2013
1736
  lastUrlRef.current = newUrl;
2014
1737
  }
2015
- else if (switchWorkspacePushedRef.current) {
2016
- // A workspace change may already have pushed the exact target URL. If we leave
2017
- // this flag set, the next unrelated item navigation will incorrectly replace
2018
- // history instead of pushing a new entry, which breaks browser back/forward.
2019
- switchWorkspacePushedRef.current = false;
2020
- }
2021
1738
  }, [
2022
1739
  currentItemDescriptor,
2023
1740
  viewName,
@@ -2029,8 +1746,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2029
1746
  fullscreen,
2030
1747
  currentWizardId,
2031
1748
  openSidebars,
2032
- showHelpTerminal,
2033
- selectedHelpSectionId,
2034
1749
  ]);
2035
1750
  useEffect(() => {
2036
1751
  async function load() {
@@ -2127,9 +1842,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2127
1842
  "en",
2128
1843
  version: 0,
2129
1844
  };
1845
+ const loadedItem = await itemsRepository.getItem(itemToLoad);
1846
+ if (!loadedItem) {
1847
+ return undefined;
1848
+ }
2130
1849
  // ensure this is object has no additional properties
2131
1850
  itemToLoad = getItemDescriptor(itemToLoad);
2132
- const requestedItemKey = makeItemKey(itemToLoad);
2133
1851
  // Check if item is already open in any slot - if so, reuse that slot instead of creating a new one
2134
1852
  const existingSlotForItem = editorSlots.find((s) => s.itemDescriptor.id === itemToLoad.id &&
2135
1853
  s.itemDescriptor.language === itemToLoad.language &&
@@ -2140,17 +1858,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2140
1858
  !options?.openInNewSlot &&
2141
1859
  !options?.targetSlotId) {
2142
1860
  const isExistingSlotActive = existingSlotForItem.slotId === activeSlotIdRef.current;
2143
- if (isExistingSlotActive) {
2144
- latestGlobalLoadKeyRef.current = requestedItemKey;
2145
- }
2146
- const loadedItem = await itemsRepository.getItem(itemToLoad);
2147
- if (!loadedItem) {
2148
- return undefined;
2149
- }
2150
- if (isExistingSlotActive &&
2151
- latestGlobalLoadKeyRef.current !== requestedItemKey) {
2152
- return loadedItem;
2153
- }
2154
1861
  // If forceRefresh is true, update the slot with a new refreshToken to trigger a reload
2155
1862
  if (options?.forceRefresh) {
2156
1863
  setEditorSlots((prev) => {
@@ -2225,17 +1932,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2225
1932
  // - If the slot is active (or is becoming active as the first slot), do update.
2226
1933
  const isFirstSlot = editorSlots.length === 0;
2227
1934
  const shouldUpdateGlobalCurrentItem = isFirstSlot || targetSlotId === activeSlotIdRef.current;
2228
- if (shouldUpdateGlobalCurrentItem) {
2229
- latestGlobalLoadKeyRef.current = requestedItemKey;
2230
- }
2231
- const loadedItem = await itemsRepository.getItem(itemToLoad);
2232
- if (!loadedItem) {
2233
- return undefined;
2234
- }
2235
- if (shouldUpdateGlobalCurrentItem &&
2236
- latestGlobalLoadKeyRef.current !== requestedItemKey) {
2237
- return loadedItem;
2238
- }
2239
1935
  // Active slot is controlled ONLY by mouse hover - only activate the first slot on initial load
2240
1936
  if (isFirstSlot) {
2241
1937
  activeSlotIdRef.current = targetSlotId;
@@ -2343,10 +2039,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2343
2039
  useEffect(() => {
2344
2040
  if (fullscreen &&
2345
2041
  !searchParams.get("fullscreen") &&
2346
- !configuration.forceFullscreen &&
2347
- !isMobile)
2042
+ !configuration.forceFullscreen)
2348
2043
  setShowFullscreenHint(true);
2349
- }, [fullscreen, configuration.forceFullscreen, searchParams, isMobile]);
2044
+ }, [fullscreen, configuration.forceFullscreen, searchParams]);
2350
2045
  const state = {
2351
2046
  page,
2352
2047
  configuration,
@@ -2445,35 +2140,20 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2445
2140
  ? existingOp.progress
2446
2141
  : op.progress;
2447
2142
  // IMPORTANT: Once canUndo becomes true, never downgrade it to false,
2448
- // UNLESS this update indicates the operation was undone.
2449
- // Runtime logs show long-running undo completion can arrive as:
2450
- // - existing: canUndo=true, executionStatus=executing
2451
- // - incoming: canUndo=false, executionStatus=completed
2452
- // without explicit undone/canRedo flags yet.
2453
- const isExplicitUndoUpdate = op.undone === true || op.canRedo === true;
2454
- const isInferredUndoCompletion = existingOp.executionStatus === "executing" &&
2455
- op.executionStatus === "completed" &&
2456
- existingOp.canUndo === true &&
2457
- op.canUndo === false;
2458
- const isUndoUpdate = isExplicitUndoUpdate || isInferredUndoCompletion;
2143
+ // UNLESS this update indicates the operation was undone. When an undo
2144
+ // completes, the server sends canUndo: false and canRedo: true (or undone: true).
2145
+ // We must respect that transition so the UI reflects the undo.
2146
+ const isUndoUpdate = op.undone === true || op.canRedo === true;
2459
2147
  const mergedCanUndo = isUndoUpdate
2460
2148
  ? false
2461
2149
  : existingOp.canUndo === true
2462
2150
  ? true
2463
2151
  : op.canUndo;
2464
- const mergedCanRedo = isUndoUpdate
2465
- ? true
2466
- : op.canRedo ?? existingOp.canRedo;
2467
- const mergedUndone = isUndoUpdate
2468
- ? true
2469
- : op.undone ?? existingOp.undone;
2470
2152
  const mergedOp = {
2471
2153
  ...existingOp,
2472
2154
  ...op,
2473
2155
  progress: mergedProgress,
2474
2156
  canUndo: mergedCanUndo,
2475
- canRedo: mergedCanRedo,
2476
- undone: mergedUndone,
2477
2157
  };
2478
2158
  // Ensure undone operations always have canRedo: true.
2479
2159
  if (mergedOp.undone && !mergedOp.canRedo) {
@@ -2527,6 +2207,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2527
2207
  });
2528
2208
  // Ref for markOperationComplete callback (needed because operationsContext is created later)
2529
2209
  const markOperationCompleteRef = useRef(null);
2210
+ // When the websocket is reconnecting, we can briefly lose the ability to send messages.
2211
+ // Agent dialog responses (e.g. questionnaire cancel/submit) must not be dropped, otherwise
2212
+ // the backend tool call can remain pending and tests/users will hang.
2213
+ const pendingAgentDialogResponsesRef = useRef([]);
2530
2214
  // WebSocket message handler and connection
2531
2215
  const messageHandler = useSocketMessageHandler({
2532
2216
  sessionId,
@@ -2552,31 +2236,28 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2552
2236
  markOperationCompleteRef.current?.(operationId);
2553
2237
  },
2554
2238
  });
2555
- // Concurrent user limit error state
2556
- const [concurrentUserLimitError, setConcurrentUserLimitError] = useState(null);
2557
- concurrentUserLimitErrorRef.current = concurrentUserLimitError;
2558
- const handleRetryConnection = useCallback(() => {
2559
- setConcurrentUserLimitError(null);
2560
- // Force reconnection by triggering a new connection attempt
2561
- // The useEditorWebSocket hook will check availability again
2562
- const socket = globalThis.editorSocket;
2563
- if (socket) {
2564
- socket.close();
2565
- delete globalThis.editorSocket;
2566
- }
2567
- // The hook will automatically attempt to reconnect
2568
- }, []);
2569
2239
  const { socketRef: socketInstanceRef } = useEditorWebSocket({
2570
2240
  sessionId,
2571
2241
  onMessage: messageHandler,
2572
2242
  onOpen: async () => {
2573
- // Clear concurrent user limit error on successful connection
2574
- setConcurrentUserLimitError(null);
2575
- // Startup WebSocket probe may have failed with a blocking error while seats were full;
2576
- // re-run status checks quietly so "1 error" does not stick after a successful connect.
2577
- void startupChecks.recheckQuiet();
2578
2243
  // Increment socket connection version to trigger re-subscriptions
2579
2244
  setSocketConnectionVersion((v) => v + 1);
2245
+ // Flush any queued agent dialog responses now that the socket is open.
2246
+ // Keep this early so pending tool calls unblock ASAP.
2247
+ try {
2248
+ if (socketInstanceRef.current &&
2249
+ socketInstanceRef.current.readyState === WebSocket.OPEN &&
2250
+ pendingAgentDialogResponsesRef.current.length > 0) {
2251
+ // FIFO flush
2252
+ while (pendingAgentDialogResponsesRef.current.length > 0) {
2253
+ const queued = pendingAgentDialogResponsesRef.current.shift();
2254
+ socketInstanceRef.current.send(JSON.stringify(queued));
2255
+ }
2256
+ }
2257
+ }
2258
+ catch (e) {
2259
+ console.error("Failed to flush queued agent dialog responses:", e);
2260
+ }
2580
2261
  // Fetch any running operations on (re)connect for auto-resume
2581
2262
  // This ensures the UI shows operations that are still executing
2582
2263
  try {
@@ -2592,37 +2273,24 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2592
2273
  }
2593
2274
  },
2594
2275
  onError: (error) => console.error("WebSocket error:", error),
2595
- onConcurrentUserLimit: (error) => {
2596
- setConcurrentUserLimitError(error);
2597
- },
2598
- onSessionRevoked: () => promptSessionReconnect("session-revoked"),
2599
2276
  connectSocket,
2600
2277
  requestQuota,
2601
2278
  sendClientInfo,
2602
- setSocketDiagnostics,
2603
2279
  });
2604
- useEffect(() => {
2605
- const hasMySession = activeSessions.some((s) => s.sessionId === sessionId);
2606
- if (hasMySession &&
2607
- socketInstanceRef.current?.readyState === WebSocket.OPEN) {
2608
- toast.dismiss("session-revoked");
2609
- }
2610
- }, [activeSessions, sessionId, socketConnectionVersion, socketInstanceRef]);
2611
- useEffect(() => {
2612
- const handleRevoked = (event) => {
2613
- const customEvent = event;
2614
- promptSessionReconnect(customEvent?.detail?.reason);
2615
- };
2616
- window.addEventListener("parhelia:session-revoked", handleRevoked);
2617
- return () => {
2618
- window.removeEventListener("parhelia:session-revoked", handleRevoked);
2619
- };
2620
- }, [promptSessionReconnect]);
2621
2280
  const sendSocketMessage = useCallback((message) => {
2622
2281
  if (socketInstanceRef.current &&
2623
2282
  socketInstanceRef.current.readyState === WebSocket.OPEN) {
2624
2283
  socketInstanceRef.current.send(JSON.stringify(message));
2625
2284
  }
2285
+ else if (message.type === "agent-dialog-response") {
2286
+ // Queue dialog responses to avoid losing them during reconnects.
2287
+ pendingAgentDialogResponsesRef.current.push(message);
2288
+ // Prevent unbounded growth in pathological scenarios.
2289
+ if (pendingAgentDialogResponsesRef.current.length > 50) {
2290
+ pendingAgentDialogResponsesRef.current =
2291
+ pendingAgentDialogResponsesRef.current.slice(-50);
2292
+ }
2293
+ }
2626
2294
  }, [socketInstanceRef]);
2627
2295
  // URL update helper - defined early so it can be used by workspace/sidebar functions
2628
2296
  const updateUrl = useCallback((params) => {
@@ -2641,7 +2309,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2641
2309
  ? `${browserPathname}?${queryString}`
2642
2310
  : browserPathname;
2643
2311
  if (typeof window !== "undefined") {
2644
- window.history.pushState(getCurrentHistoryState(), "", newUrl);
2312
+ window.history.pushState(null, "", newUrl);
2645
2313
  }
2646
2314
  else {
2647
2315
  router.push(newUrl, { scroll: false });
@@ -2666,13 +2334,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2666
2334
  if (!options?.skipNavigationHistory) {
2667
2335
  addNavigationEntry(targetWorkspaceId, item);
2668
2336
  }
2669
- // Mark that we're pushing from switchWorkspace so the URL sync effect
2670
- // will replaceState instead of pushing a second history entry.
2671
- switchWorkspacePushedRef.current = true;
2672
- updateUrl({
2673
- workspace: targetWorkspaceId,
2674
- ...options?.urlParams,
2675
- });
2337
+ // Update URL
2338
+ updateUrl({ workspace: targetWorkspaceId });
2676
2339
  if (typeof document.startViewTransition === "function") {
2677
2340
  document.startViewTransition(() => {
2678
2341
  flushSync(() => {
@@ -2692,6 +2355,14 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2692
2355
  updateUrl,
2693
2356
  handleSetShowAgentsPanel,
2694
2357
  ]);
2358
+ // Legacy alias for backwards compatibility
2359
+ const switchView = useCallback((viewName, options) => {
2360
+ // Handle ccpanel for settings workspace
2361
+ if (options?.ccpanel) {
2362
+ updateUrl({ ccpanel: options.ccpanel, workspace: viewName });
2363
+ }
2364
+ switchWorkspace(viewName, options);
2365
+ }, [switchWorkspace, updateUrl]);
2695
2366
  // Helper: get all sidebar IDs that should be preserved (locked sidebars + their stack mates)
2696
2367
  const getPreservedSidebarIds = useCallback(() => {
2697
2368
  const lockedSet = new Set(lockedSidebarsRef.current);
@@ -2729,9 +2400,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2729
2400
  setOpenSidebars(newSidebars);
2730
2401
  setLockedSidebars((locked) => locked.filter((id) => id !== sidebarId));
2731
2402
  setSidebarStacks((prevStacks) => normalizeSidebarStacks(newSidebars, prevStacks));
2732
- if (sidebarId === "agents-panel") {
2733
- setUserPreferences({ showAgentsPanel: false });
2734
- }
2735
2403
  startTransition(() => {
2736
2404
  updateUrl({ sidebar: newSidebars.join(",") || undefined });
2737
2405
  });
@@ -2746,69 +2414,34 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2746
2414
  ];
2747
2415
  openSidebarsRef.current = newSidebars;
2748
2416
  setOpenSidebars(newSidebars);
2749
- ensureSidebarPinned(sidebarId);
2750
2417
  setSidebarStacks((prevStacks) => normalizeSidebarStacks(newSidebars, prevStacks));
2751
- if (sidebarId === "agents-panel") {
2752
- setUserPreferences({ showAgentsPanel: true });
2753
- }
2754
- // On mobile, close the editor form panel when opening a sidebar
2755
- if (isMobile) {
2756
- setMobileEditorPanelOpenRaw(false);
2757
- }
2758
2418
  startTransition(() => {
2759
2419
  updateUrl({ sidebar: newSidebars.join(",") || undefined });
2760
2420
  });
2761
- }, [
2762
- updateUrl,
2763
- getPreservedSidebarIds,
2764
- normalizeSidebarStacks,
2765
- ensureSidebarPinned,
2766
- setUserPreferences,
2767
- isMobile,
2768
- ]);
2421
+ }, [updateUrl, getPreservedSidebarIds, normalizeSidebarStacks]);
2769
2422
  // Ensure a sidebar is open (without toggling it closed if already open)
2770
- const openSidebar = useCallback((sidebarId, options) => {
2423
+ const openSidebar = useCallback((sidebarId) => {
2771
2424
  const currentOpenSidebars = openSidebarsRef.current;
2772
2425
  if (currentOpenSidebars.includes(sidebarId)) {
2773
2426
  // Already open, nothing to do
2774
2427
  return;
2775
2428
  }
2776
- const preservedSet = options?.preserveOpenSidebars
2777
- ? undefined
2778
- : getPreservedSidebarIds();
2779
- const newSidebars = options?.preserveOpenSidebars
2780
- ? [...currentOpenSidebars, sidebarId]
2781
- : [
2782
- ...currentOpenSidebars.filter((id) => preservedSet?.has(id)),
2783
- sidebarId,
2784
- ];
2429
+ // Keep sidebars that are locked OR in a stack with a locked sidebar
2430
+ const preservedSet = getPreservedSidebarIds();
2431
+ const newSidebars = [
2432
+ ...currentOpenSidebars.filter((id) => preservedSet.has(id)), // Keep locked stacks
2433
+ sidebarId, // Add the new one
2434
+ ];
2785
2435
  openSidebarsRef.current = newSidebars;
2786
2436
  setOpenSidebars(newSidebars);
2787
- ensureSidebarPinned(sidebarId);
2788
2437
  setSidebarStacks((prevStacks) => normalizeSidebarStacks(newSidebars, prevStacks));
2789
- if (sidebarId === "agents-panel") {
2790
- setUserPreferences({ showAgentsPanel: true });
2791
- }
2792
- // On mobile, close the editor form panel when opening a sidebar
2793
- if (isMobile) {
2794
- setMobileEditorPanelOpenRaw(false);
2795
- }
2796
2438
  startTransition(() => {
2797
2439
  updateUrl({ sidebar: newSidebars.join(",") || undefined });
2798
2440
  });
2799
- }, [
2800
- updateUrl,
2801
- getPreservedSidebarIds,
2802
- normalizeSidebarStacks,
2803
- ensureSidebarPinned,
2804
- setUserPreferences,
2805
- isMobile,
2806
- ]);
2441
+ }, [updateUrl, getPreservedSidebarIds, normalizeSidebarStacks]);
2807
2442
  // Toggle lock state for a sidebar stack (keeps it visible when selecting another)
2808
2443
  // When toggling any sidebar, we toggle the entire stack it belongs to
2809
2444
  const toggleSidebarLock = useCallback((sidebarId) => {
2810
- if (isMobile)
2811
- return;
2812
2445
  const currentStacks = sidebarStacksRef.current;
2813
2446
  const stackContainingSidebar = currentStacks.find((stack) => stack.includes(sidebarId));
2814
2447
  const sidebarIdsToToggle = stackContainingSidebar || [sidebarId];
@@ -2826,7 +2459,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2826
2459
  ];
2827
2460
  }
2828
2461
  });
2829
- }, [isMobile]);
2462
+ }, []);
2830
2463
  const stackSidebar = useCallback((sidebarId, targetSidebarId, position = "after") => {
2831
2464
  if (!sidebarId || !targetSidebarId || sidebarId === targetSidebarId)
2832
2465
  return;
@@ -2858,38 +2491,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2858
2491
  return normalizeSidebarStacks(openIds, next);
2859
2492
  });
2860
2493
  }, [normalizeSidebarStacks]);
2861
- const moveSidebarToColumn = useCallback((sidebarId, targetSidebarId, position = "after") => {
2862
- if (!sidebarId || !targetSidebarId || sidebarId === targetSidebarId) {
2863
- return;
2864
- }
2865
- const currentOpen = openSidebarsRef.current;
2866
- const baseOpen = currentOpen.filter((id) => id !== sidebarId);
2867
- const targetIndex = baseOpen.indexOf(targetSidebarId);
2868
- if (targetIndex === -1) {
2869
- return;
2870
- }
2871
- const insertIndex = position === "before" ? targetIndex : targetIndex + 1;
2872
- const nextOpen = [...baseOpen];
2873
- nextOpen.splice(insertIndex, 0, sidebarId);
2874
- openSidebarsRef.current = nextOpen;
2875
- setOpenSidebars(nextOpen);
2876
- startTransition(() => {
2877
- updateUrl({ sidebar: nextOpen.join(",") || undefined });
2878
- });
2879
- setSidebarStacks((prev) => {
2880
- const normalized = normalizeSidebarStacks(nextOpen, prev);
2881
- const next = normalized
2882
- .map((stack) => stack.filter((id) => id !== sidebarId))
2883
- .filter((stack) => stack.length > 0);
2884
- const targetStackIndex = next.findIndex((stack) => stack.includes(targetSidebarId));
2885
- if (targetStackIndex === -1) {
2886
- next.push([sidebarId]);
2887
- return normalizeSidebarStacks(nextOpen, next);
2888
- }
2889
- next.splice(position === "before" ? targetStackIndex : targetStackIndex + 1, 0, [sidebarId]);
2890
- return normalizeSidebarStacks(nextOpen, next);
2891
- });
2892
- }, [normalizeSidebarStacks, updateUrl]);
2893
2494
  const unstackSidebar = useCallback((sidebarId) => {
2894
2495
  setSidebarStacks((prev) => {
2895
2496
  const openIds = openSidebarsRef.current;
@@ -2935,34 +2536,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2935
2536
  // Get resolved sidebar (with panels materialized)
2936
2537
  // Note: This is defined as a function that will be called later when editContext is available
2937
2538
  const sidebars = configuration.editor.sidebars ?? [];
2938
- const taskboardSidebarIds = new Set([
2939
- "taskboard-project-list",
2940
- "taskboard-my-tasks",
2941
- ]);
2942
- const getSidebarsForWorkspace = useCallback((targetWorkspaceId) => {
2943
- const isTaskboardWorkspace = targetWorkspaceId === "taskboard";
2944
- const workspaceAllowedSidebarIds = userInfo.workspaces?.find((w) => w.id === targetWorkspaceId)
2945
- ?.sidebars ?? [];
2946
- return sidebars.filter((s) => {
2947
- const isTaskboardSidebar = taskboardSidebarIds.has(s.id);
2948
- if (isTaskboardWorkspace && !isTaskboardSidebar)
2949
- return false;
2950
- if (!isTaskboardWorkspace && isTaskboardSidebar)
2951
- return false;
2952
- // Always show agents-panel regardless of workspace settings.
2953
- if (s.id === "agents-panel") {
2954
- return true;
2955
- }
2956
- // If no workspace settings or no sidebars defined for current workspace, show all.
2957
- if (workspaceAllowedSidebarIds.length === 0) {
2958
- return true;
2959
- }
2960
- // Only show sidebars that are in the allowed list for the current workspace.
2961
- return workspaceAllowedSidebarIds.includes(s.id);
2962
- });
2963
- }, [sidebars, userInfo.workspaces]);
2964
2539
  const getResolvedSidebar = useCallback((sidebarId) => {
2965
- const sidebar = getSidebarsForWorkspace(workspaceId).find((s) => s.id === sidebarId);
2540
+ const sidebar = sidebars.find((s) => s.id === sidebarId);
2966
2541
  if (!sidebar)
2967
2542
  return undefined;
2968
2543
  // Resolve panel factories using editContextRef to avoid circular dependency
@@ -2976,35 +2551,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
2976
2551
  ...sidebar,
2977
2552
  panels: resolvedPanels,
2978
2553
  };
2979
- }, [getSidebarsForWorkspace, workspaceId]);
2980
- useEffect(() => {
2981
- if (!currentWorkspace.supportsSidebars) {
2982
- return;
2983
- }
2984
- const allowedIds = new Set(getSidebarsForWorkspace(workspaceId).map((sidebar) => sidebar.id));
2985
- const currentOpen = openSidebarsRef.current;
2986
- let nextOpen = currentOpen.filter((id) => allowedIds.has(id));
2987
- if (nextOpen.length === 0 && currentWorkspace.defaultSidebars?.length) {
2988
- nextOpen = currentWorkspace.defaultSidebars.filter((id) => allowedIds.has(id));
2989
- }
2990
- const unchanged = nextOpen.length === currentOpen.length &&
2991
- nextOpen.every((id, index) => id === currentOpen[index]);
2992
- if (unchanged) {
2993
- return;
2994
- }
2995
- openSidebarsRef.current = nextOpen;
2996
- setOpenSidebars(nextOpen);
2997
- setSidebarStacks((prev) => normalizeSidebarStacks(nextOpen, prev));
2998
- startTransition(() => {
2999
- updateUrl({ sidebar: nextOpen.join(",") || undefined });
3000
- });
3001
- }, [
3002
- currentWorkspace,
3003
- getSidebarsForWorkspace,
3004
- normalizeSidebarStacks,
3005
- updateUrl,
3006
- workspaceId,
3007
- ]);
2554
+ }, [sidebars]);
3008
2555
  // Listen for switch-workspace and open-sidebar commands from agents via websocket
3009
2556
  useEffect(() => {
3010
2557
  const handleAgentMessage = (message) => {
@@ -3218,45 +2765,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3218
2765
  }
3219
2766
  return true;
3220
2767
  }, [operations, ignoreBlur, sessionId]);
3221
- const quickSwitcherEntries = useMemo(() => {
3222
- const entries = [];
3223
- const seen = new Set();
3224
- const pushEntry = (entry) => {
3225
- const key = entry.item
3226
- ? `${entry.workspaceId}:${entry.item.id}:${entry.item.language}:${entry.item.version}`
3227
- : `${entry.workspaceId}:no-item`;
3228
- if (seen.has(key))
3229
- return;
3230
- seen.add(key);
3231
- entries.push(entry);
3232
- };
3233
- for (const entry of navigationHistory) {
3234
- pushEntry(entry);
3235
- }
3236
- for (const entry of browseHistory) {
3237
- if (!entry.id || !entry.language)
3238
- continue;
3239
- pushEntry({
3240
- workspaceId,
3241
- item: {
3242
- id: entry.id,
3243
- language: entry.language,
3244
- version: entry.version ?? 0,
3245
- },
3246
- timestamp: entry.visitedAt
3247
- ? new Date(entry.visitedAt).getTime()
3248
- : Date.now(),
3249
- displayName: entry.name || workspaceId,
3250
- itemName: entry.name,
3251
- itemPath: entry.path,
3252
- itemIcon: entry.icon,
3253
- });
3254
- }
3255
- return entries.slice(0, 25);
3256
- }, [navigationHistory, browseHistory, workspaceId]);
3257
2768
  // Quick switcher handlers
3258
2769
  const showQuickSwitcher = useCallback((show) => {
3259
- if (show && quickSwitcherEntries.length > 1) {
2770
+ if (show && navigationHistory.length > 1) {
3260
2771
  setQuickSwitcherVisible(true);
3261
2772
  // Start with index 1 (second entry - previous entry) for quick switching
3262
2773
  setQuickSwitcherSelectedIndex(1);
@@ -3264,11 +2775,11 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3264
2775
  else {
3265
2776
  setQuickSwitcherVisible(false);
3266
2777
  }
3267
- }, [quickSwitcherEntries]);
2778
+ }, [navigationHistory]);
3268
2779
  const cycleQuickSwitcher = useCallback((direction) => {
3269
2780
  if (!quickSwitcherVisible)
3270
2781
  return;
3271
- const maxItems = Math.min(5, quickSwitcherEntries.length);
2782
+ const maxItems = Math.min(5, navigationHistory.length);
3272
2783
  setQuickSwitcherSelectedIndex((current) => {
3273
2784
  let newIndex = current;
3274
2785
  // Determine grid layout (responsive columns)
@@ -3313,9 +2824,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3313
2824
  }
3314
2825
  return newIndex;
3315
2826
  });
3316
- }, [quickSwitcherVisible, quickSwitcherEntries]);
2827
+ }, [quickSwitcherVisible, navigationHistory]);
3317
2828
  const handleQuickSwitcherSelect = useCallback((index) => {
3318
- const selectedEntry = quickSwitcherEntries[index];
2829
+ const selectedEntry = navigationHistory[index];
3319
2830
  if (selectedEntry) {
3320
2831
  // Determine target workspace: entries with items should go to "editor" workspace
3321
2832
  // (fixes issue where browse history entries initialized with wrong workspaceId)
@@ -3367,46 +2878,23 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3367
2878
  }
3368
2879
  setQuickSwitcherVisible(false);
3369
2880
  }, [
3370
- quickSwitcherEntries,
2881
+ navigationHistory,
3371
2882
  loadItem,
3372
2883
  switchWorkspace,
3373
2884
  workspaceId,
3374
2885
  item,
3375
2886
  setNavigationHistory,
3376
2887
  ]);
3377
- useEffect(() => {
3378
- if (typeof window === "undefined" ||
3379
- process.env.PARHELIA_DEV_MODE !== "true") {
3380
- return;
3381
- }
3382
- window.__parheliaQuickSwitcherTestApi = {
3383
- open: () => showQuickSwitcher(true),
3384
- cycle: (direction = "next") => cycleQuickSwitcher(direction),
3385
- closeWithoutSelection: () => setQuickSwitcherVisible(false),
3386
- selectCurrent: () => handleQuickSwitcherSelect(quickSwitcherSelectedIndex),
3387
- getState: () => ({
3388
- visible: quickSwitcherVisible,
3389
- selectedIndex: quickSwitcherSelectedIndex,
3390
- entryCount: quickSwitcherEntries.length,
3391
- entries: quickSwitcherEntries.map((entry) => ({
3392
- workspaceId: entry.workspaceId,
3393
- itemId: entry.item?.id,
3394
- displayName: entry.displayName,
3395
- })),
3396
- }),
3397
- };
3398
- return () => {
3399
- delete window.__parheliaQuickSwitcherTestApi;
3400
- };
3401
- }, [
3402
- showQuickSwitcher,
3403
- cycleQuickSwitcher,
3404
- handleQuickSwitcherSelect,
3405
- quickSwitcherSelectedIndex,
3406
- ]);
3407
2888
  const { handleKeyDown } = useKeyboardNavigation({
3408
2889
  editContextRef,
3409
- keyboardCommands: activeKeyboardCommands,
2890
+ operations,
2891
+ pageViewContext: activePageViewContext,
2892
+ configuration,
2893
+ item,
2894
+ browseHistory,
2895
+ loadItem,
2896
+ showInfoToast,
2897
+ showErrorToast,
3410
2898
  executeCommand,
3411
2899
  showQuickSwitcher,
3412
2900
  cycleQuickSwitcher,
@@ -3526,19 +3014,10 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3526
3014
  }
3527
3015
  return null;
3528
3016
  };
3529
- let modifierWasPressedOnMouseDown = false;
3530
- const handleMouseDown = (event) => {
3531
- modifierWasPressedOnMouseDown = event.ctrlKey || event.metaKey;
3532
- };
3533
3017
  const handleCtrlClick = async (event) => {
3534
- // Only proceed if Ctrl/Cmd was already pressed when the mouse interaction started.
3535
- // This avoids accidental navigation when users press Ctrl after selecting text to copy.
3536
- if (!modifierWasPressedOnMouseDown)
3537
- return;
3538
- // Also require the modifier to still be held for the final click event.
3018
+ // Only proceed if Ctrl (or Cmd on Mac) is pressed
3539
3019
  if (!event.ctrlKey && !event.metaKey)
3540
3020
  return;
3541
- modifierWasPressedOnMouseDown = false;
3542
3021
  const target = event.target;
3543
3022
  const text = getTextFromElement(target);
3544
3023
  if (text && isGuid(text)) {
@@ -3553,7 +3032,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3553
3032
  skipViewChange: true,
3554
3033
  });
3555
3034
  if (item) {
3556
- switchWorkspace("editor", {
3035
+ // Switch to the editor view
3036
+ switchView("editor", {
3557
3037
  skipNavigationHistory: true,
3558
3038
  });
3559
3039
  showInfoToast({
@@ -3579,14 +3059,12 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3579
3059
  }
3580
3060
  };
3581
3061
  if (typeof document !== "undefined") {
3582
- document.addEventListener("mousedown", handleMouseDown, true);
3583
3062
  document.addEventListener("click", handleCtrlClick, true);
3584
3063
  return () => {
3585
- document.removeEventListener("mousedown", handleMouseDown, true);
3586
3064
  document.removeEventListener("click", handleCtrlClick, true);
3587
3065
  };
3588
3066
  }
3589
- }, [loadItem, switchWorkspace, showInfoToast, showErrorToast]);
3067
+ }, [loadItem, switchView, showInfoToast, showErrorToast]);
3590
3068
  useEffect(() => {
3591
3069
  const handleGlobalBlur = () => {
3592
3070
  operations.onFieldBlur?.();
@@ -3624,6 +3102,21 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3624
3102
  // Otherwise, only show workspaces that are in the settings
3625
3103
  return workspaceIdsFromSettings.includes(w.id) && !w.visible;
3626
3104
  });
3105
+ // Get sidebars allowed for the current workspace from settings
3106
+ const currentWorkspaceSettings = userInfo.workspaces?.find((w) => w.id === workspaceId);
3107
+ const allowedSidebarIds = currentWorkspaceSettings?.sidebars ?? [];
3108
+ // Legacy: Calculate visible views for backwards compatibility
3109
+ const allViews = (configuration.editor.views ?? [])
3110
+ .filter((x) => {
3111
+ return !x.visible && !x.hidden;
3112
+ })
3113
+ .filter((x) => !userInfo.views ||
3114
+ userInfo.views.map((view) => view.name).includes(x.name));
3115
+ const pinnedViews = userInfo.preferences?.pinnedViews ||
3116
+ configuration.editor.defaultPinnedViews ||
3117
+ [];
3118
+ // Legacy visibleViews for backwards compatibility
3119
+ const visibleViews = allViews.filter((view) => view.name === viewName || pinnedViews.includes(view.name));
3627
3120
  // Handle initial mode setup from URL (only on initial load)
3628
3121
  useEffect(() => {
3629
3122
  if (!isInitialLoad)
@@ -3668,7 +3161,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3668
3161
  // This is especially important when called from the tour, where the current workspace
3669
3162
  // might be the editor and URL-only navigation would get "corrected" back.
3670
3163
  try {
3671
- switchWorkspace("home", {
3164
+ switchView("home", {
3672
3165
  skipConfirmation: true,
3673
3166
  skipNavigationHistory: true,
3674
3167
  });
@@ -3715,6 +3208,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3715
3208
  const current = new URLSearchParams(searchParams.toString());
3716
3209
  current.delete("version");
3717
3210
  current.delete("itemid");
3211
+ current.delete("view"); // Remove legacy param
3718
3212
  current.delete("workspace"); // Clear workspace
3719
3213
  current.set("create", "1");
3720
3214
  const newUrl = `${pathname}?${current.toString()}`;
@@ -3994,8 +3488,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
3994
3488
  setShowOnlyMyChanges,
3995
3489
  filterByCurrentLanguage,
3996
3490
  setFilterByCurrentLanguage,
3997
- historySearchQuery,
3998
- setHistorySearchQuery,
3999
3491
  refreshHistory,
4000
3492
  isRefreshing,
4001
3493
  activeSessions,
@@ -4033,8 +3525,19 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4033
3525
  workspaceId,
4034
3526
  previousWorkspaceId,
4035
3527
  switchWorkspace,
4036
- // Sidebar state
4037
- availableSidebars: getSidebarsForWorkspace(workspaceId),
3528
+ // Sidebar state - filter by workspace settings if available
3529
+ availableSidebars: (configuration.editor.sidebars ?? []).filter((s) => {
3530
+ // Always show agents-panel regardless of workspace settings
3531
+ if (s.id === "agents-panel") {
3532
+ return true;
3533
+ }
3534
+ // If no workspace settings or no sidebars defined for current workspace, show all
3535
+ if (!allowedSidebarIds || allowedSidebarIds.length === 0) {
3536
+ return true;
3537
+ }
3538
+ // Only show sidebars that are in the allowed list for the current workspace
3539
+ return allowedSidebarIds.includes(s.id);
3540
+ }),
4038
3541
  openSidebars,
4039
3542
  pinnedSidebars,
4040
3543
  lockedSidebars,
@@ -4044,12 +3547,17 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4044
3547
  toggleSidebarPin,
4045
3548
  toggleSidebarLock,
4046
3549
  stackSidebar,
4047
- moveSidebarToColumn,
4048
3550
  unstackSidebar,
4049
3551
  reorderSidebarInStack,
4050
3552
  reorderPinnedSidebars,
4051
3553
  reorderOpenSidebars,
4052
3554
  getResolvedSidebar,
3555
+ // Legacy compatibility (deprecated)
3556
+ viewName,
3557
+ previousViewName,
3558
+ switchView,
3559
+ view: currentView,
3560
+ visibleViews,
4053
3561
  compareMode,
4054
3562
  setCompareMode,
4055
3563
  fullscreen,
@@ -4089,7 +3597,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4089
3597
  addSocketMessageListener,
4090
3598
  sendSocketMessage,
4091
3599
  socketConnectionVersion,
4092
- socketDiagnostics,
4093
3600
  currentItemDescriptor,
4094
3601
  editorSlots,
4095
3602
  activeSlotId,
@@ -4102,7 +3609,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4102
3609
  setActiveSlot,
4103
3610
  revision,
4104
3611
  notifyPageModelReady,
4105
- pageModelReadyToken,
4106
3612
  selectedComment,
4107
3613
  setSelectedComment,
4108
3614
  comments,
@@ -4181,8 +3687,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4181
3687
  setEnableCompletions,
4182
3688
  showComponentNavigator,
4183
3689
  setShowComponentNavigator: handleSetShowComponentNavigator,
4184
- isComponentNavigatorOpenForSlot,
4185
- setComponentNavigatorOpenForSlot,
4186
3690
  showAgentsPanel,
4187
3691
  setShowAgentsPanel: handleSetShowAgentsPanel,
4188
3692
  showMinimap,
@@ -4194,12 +3698,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4194
3698
  helpTerminalProfileName,
4195
3699
  helpTerminalActiveTab,
4196
3700
  setHelpTerminalActiveTab,
4197
- selectedHelpSectionId,
4198
- setSelectedHelpSectionId,
4199
3701
  showAgentsWorkspaceEditor,
4200
3702
  setShowAgentsWorkspaceEditor: handleSetShowAgentsWorkspaceEditor,
4201
- selectedAgentsWorkspaceAgentId,
4202
- setSelectedAgentsWorkspaceAgentId,
4203
3703
  activeEditorTab,
4204
3704
  setActiveEditorTab,
4205
3705
  showLayoutComponents,
@@ -4208,8 +3708,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4208
3708
  isQuotaExceeded: isQuotaExceeded(),
4209
3709
  getQuotaWarningMessage,
4210
3710
  isMobile,
4211
- mobileEditorPanelOpen,
4212
- setMobileEditorPanelOpen: handleSetMobileEditorPanelOpen,
4213
3711
  openDialog,
4214
3712
  webSocketMessages,
4215
3713
  clearWebSocketMessages: () => setWebSocketMessages([]),
@@ -4248,6 +3746,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4248
3746
  configuration,
4249
3747
  updateUrl,
4250
3748
  workspaceId,
3749
+ switchView,
4251
3750
  pathname,
4252
3751
  router,
4253
3752
  item,
@@ -4277,6 +3776,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4277
3776
  currentWorkspace,
4278
3777
  previousWorkspaceId,
4279
3778
  switchWorkspace,
3779
+ allowedSidebarIds,
4280
3780
  openSidebars,
4281
3781
  pinnedSidebars,
4282
3782
  lockedSidebars,
@@ -4288,6 +3788,9 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4288
3788
  reorderOpenSidebars,
4289
3789
  getResolvedSidebar,
4290
3790
  viewName,
3791
+ previousViewName,
3792
+ currentView,
3793
+ visibleViews,
4291
3794
  compareMode,
4292
3795
  // Important: in multi-slot mode the active PageViewContext can change
4293
3796
  // without the base `pageViewContext` identity changing (e.g. switching slots).
@@ -4312,7 +3815,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4312
3815
  currentItemDescriptor,
4313
3816
  revision,
4314
3817
  notifyPageModelReady,
4315
- pageModelReadyToken,
4316
3818
  selectedComment,
4317
3819
  comments,
4318
3820
  availableCommentTags,
@@ -4331,7 +3833,6 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4331
3833
  quickSwitcherSelectedIndex,
4332
3834
  handleQuickSwitcherSelect,
4333
3835
  webSocketMessages,
4334
- socketDiagnostics,
4335
3836
  factoriesRef,
4336
3837
  user,
4337
3838
  statusMessage,
@@ -4340,11 +3841,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4340
3841
  isQuotaExceeded,
4341
3842
  getQuotaWarningMessage,
4342
3843
  isMobile,
4343
- mobileEditorPanelOpen,
4344
- handleSetMobileEditorPanelOpen,
4345
3844
  showComponentNavigator,
4346
- isComponentNavigatorOpenForSlot,
4347
- setComponentNavigatorOpenForSlot,
4348
3845
  handleSetShowComponentNavigator,
4349
3846
  showAgentsPanel,
4350
3847
  handleSetShowAgentsPanel,
@@ -4356,9 +3853,7 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4356
3853
  helpTerminalProfileName,
4357
3854
  helpTerminalActiveTab,
4358
3855
  setHelpTerminalActiveTab,
4359
- selectedHelpSectionId,
4360
3856
  showAgentsWorkspaceEditor,
4361
- selectedAgentsWorkspaceAgentId,
4362
3857
  activeEditorTab,
4363
3858
  showLayoutComponents,
4364
3859
  openDialog,
@@ -4603,40 +4098,18 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4603
4098
  // prevDependencies.current = currentDependencies;
4604
4099
  // editContextRef.current = editContext;
4605
4100
  // }, [editContext]);
4606
- // Auto-open the mobile editor panel for new selection/intent changes, but
4607
- // keep a manual close sticky for the exact same context.
4608
- useEffect(() => {
4609
- if (!isMobile || workspaceId !== "editor")
4610
- return;
4611
- if (activeEditorTab) {
4612
- handleSetMobileEditorPanelOpen(true);
4613
- return;
4614
- }
4615
- if (!(selection.length > 0 || insertMode))
4616
- return;
4617
- if (dismissedMobilePanelToken === mobilePanelDismissToken)
4618
- return;
4619
- handleSetMobileEditorPanelOpen(true);
4620
- }, [
4621
- activeEditorTab,
4622
- dismissedMobilePanelToken,
4623
- handleSetMobileEditorPanelOpen,
4624
- insertMode,
4625
- isMobile,
4626
- mobilePanelDismissToken,
4627
- selection,
4628
- workspaceId,
4629
- ]);
4630
4101
  useEffect(() => {
4631
4102
  fieldsEditContext.clearModifiedFields();
4632
4103
  }, [currentItemDescriptor]);
4633
- if (!currentWorkspace)
4104
+ if (!currentView)
4634
4105
  return null;
4635
- const editorUi = fullscreen ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "fixed inset-0 flex", children: [_jsx(PageViewerFrame, { compareView: compareMode, pageViewContext: activePageViewContext }), _jsx(FullscreenControls, { device: activePageViewContext.device, setDevice: (d) => activePageViewContext.setDevice(d), canExit: !configuration.forceFullscreen, onExit: () => setFullscreen(false), firstMobileDeviceName: configuration.devices[0]?.name })] }), showFullscreenHint && !configuration.forceFullscreen && !isMobile && (_jsx("div", { className: "fixed inset-0 z-10000", onMouseMoveCapture: () => {
4106
+ const editorUi = fullscreen ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "fixed inset-0 flex", children: [_jsx(PageViewerFrame, { compareView: compareMode, pageViewContext: activePageViewContext }), _jsx(FullscreenControls, { device: activePageViewContext.device, setDevice: (d) => activePageViewContext.setDevice(d), canExit: !configuration.forceFullscreen, onExit: () => setFullscreen(false), firstMobileDeviceName: configuration.devices[0]?.name })] }), showFullscreenHint && !configuration.forceFullscreen && (_jsx("div", { className: "fixed inset-0", onMouseMoveCapture: () => {
4636
4107
  setTimeout(() => {
4637
4108
  setShowFullscreenHint(false);
4638
4109
  }, 600);
4639
- }, "data-testid": "fullscreen-hint-overlay", children: _jsxs("div", { className: "fixed top-6 left-1/2 -translate-x-1/2 transform rounded-full bg-black/60 px-6 py-2.5 text-sm font-medium text-white shadow-2xl backdrop-blur-md transition-all duration-500", children: ["Press", " ", _jsx("kbd", { className: "mx-1 rounded bg-white/20 px-1.5 py-0.5 text-xs font-semibold", children: "Ctrl + F11" }), " ", "to exit fullscreen"] }) }))] })) : (_jsxs(_Fragment, { children: [_jsx(EditorChrome, { className: className, currentWorkspace: currentWorkspace, centerPanelView: centerPanelView, editContext: editContext, showAgentsPanel: showAgentsPanel, handleSetShowAgentsPanel: handleSetShowAgentsPanel, workspaceId: workspaceId }), isTourActive && (_jsx(Tour, { tourStopCallback: () => {
4110
+ }, "data-testid": "fullscreen-hint-overlay", children: _jsxs("div", { className: "fixed top-6 left-1/2 -translate-x-1/2 transform rounded-full bg-black/60 px-6 py-2.5 text-sm font-medium text-white shadow-2xl backdrop-blur-md transition-all duration-500", children: ["Press", " ", _jsx("kbd", { className: "mx-1 rounded bg-white/20 px-1.5 py-0.5 text-xs font-semibold", children: "Ctrl + F11" }), " ", "to exit fullscreen"] }) }))] })) : (_jsxs(_Fragment, { children: [_jsx(EditorChrome, { className: className, currentWorkspace: currentWorkspace, centerPanelView: centerPanelView, editContext: editContext, showComponentNavigator: showComponentNavigator, handleSetShowComponentNavigator: handleSetShowComponentNavigator, showAgentsPanel: showAgentsPanel, handleSetShowAgentsPanel: handleSetShowAgentsPanel, workspaceId: workspaceId,
4111
+ // Legacy props for backwards compatibility
4112
+ currentView: currentView, viewName: viewName }), isTourActive && (_jsx(Tour, { tourStopCallback: () => {
4640
4113
  setIsTourActive(false);
4641
4114
  // Remove tour state from URL
4642
4115
  // Use history.replaceState instead of router.replace to avoid triggering React navigation
@@ -4646,14 +4119,8 @@ export function EditorShell({ configuration, className, item: loadItemDescriptor
4646
4119
  const newUrl = queryString
4647
4120
  ? `${window.location.pathname}?${queryString}`
4648
4121
  : window.location.pathname;
4649
- window.history.replaceState(getCurrentHistoryState(), "", newUrl);
4650
- }, configuration: configuration, restoredFromUrl: tourRestoredRef.current })), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(GuidanceOverlay, {}) }), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(AgentDialogHandler, {}) })] }));
4651
- return (_jsx(LicenseProvider, { initialLicenseStatus: initialLicenseStatus, initialStatusLoaded: initialLicenseStatusLoaded, children: _jsx("div", { className: `editor h-full w-full`, children: _jsx(OperationsContextProvider, { value: operationsContext.context, children: _jsx(FieldsEditContextProvider, { value: fieldsEditContext, children: _jsxs(EditContextProvider, { value: editContext, children: [_jsx(DevModeIndicator, {}), startupChecks.state === "loading" && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-white/70 backdrop-blur-[1px]", children: _jsx("div", { className: "flex items-center gap-3 rounded-md border border-gray-200 bg-white px-4 py-3 text-gray-700 shadow-sm", children: _jsx(Spinner, { size: "xl" }) }) })), editContext.isRefreshing && (_jsx("div", { className: "pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center text-gray-600 opacity-50 select-none", children: _jsx(Spinner, {}) })), (currentWorkspace.id === "agents" ||
4652
- currentWorkspace.id === "taskboard") &&
4653
- showAgentsWorkspaceEditor && (_jsx(AgentsSlotContextBridgeHost, { slots: editorSlots })), startupChecks.state !== "loading" && (children || editorUi), startupChecks.state !== "loading" && dialog, _jsx(Toaster, { position: "top-center" }), " ", _jsx(ConfirmationDialog, { ref: confirmationDialogRef }), _jsx(ConcurrentUserLimitDialog, { open: concurrentUserLimitError !== null, onOpenChange: (open) => {
4654
- if (!open) {
4655
- setConcurrentUserLimitError(null);
4656
- }
4657
- }, sessionId: sessionId, currentUsers: concurrentUserLimitError?.currentUsers ?? 0, maxUsers: concurrentUserLimitError?.maxUsers ?? 0, message: concurrentUserLimitError?.message ?? "", onRetry: handleRetryConnection, isAdministrator: userInfo.user.isAdministrator === true }), _jsx(QuickItemSwitcher, { visible: quickSwitcherVisible, entries: quickSwitcherEntries.slice(0, 5), selectedIndex: quickSwitcherSelectedIndex, onSelect: handleQuickSwitcherSelect, onClose: () => setQuickSwitcherVisible(false) }), _jsx(EditContextMenu, { ref: contextMenuRef }), _jsx(FeatureGate, { feature: LicenseFeatures.AI, children: _jsx(InlineAiTrigger, {}) }), media.mediaSelectorVisible && (_jsx(MediaSelector, { language: editContext.currentItemDescriptor.language, visible: media.mediaSelectorVisible, onHide: media.handleHide, onMediaSelected: media.onMediaSelect, selectedIdPath: media.selectedMediaIdPath, mode: media.mediaSelectorMode, initialSearchTerm: media.initialSearchTerm })), _jsx(FieldEditorPopup, { ref: fieldEditorPopupRef }), _jsx(LicenseOverlay, {})] }) }) }) }) }));
4122
+ window.history.replaceState(null, "", newUrl);
4123
+ }, configuration: configuration, restoredFromUrl: tourRestoredRef.current })), _jsx(GuidanceOverlay, {}), _jsx(AgentDialogHandler, { sendWebSocketMessage: (type, payload) => sendSocketMessage({ type, payload }) })] }));
4124
+ return (_jsx("div", { className: `editor h-full w-full`, children: _jsx(OperationsContextProvider, { value: operationsContext.context, children: _jsx(FieldsEditContextProvider, { value: fieldsEditContext, children: _jsxs(EditContextProvider, { value: editContext, children: [_jsx(DevModeIndicator, {}), startupChecks.state === "loading" && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-white/70 backdrop-blur-[1px]", children: _jsx("div", { className: "flex items-center gap-3 rounded-md border border-gray-200 bg-white px-4 py-3 text-gray-700 shadow-sm", children: _jsx(Spinner, { size: "xl" }) }) })), editContext.isRefreshing && (_jsx("div", { className: "pointer-events-none fixed right-0 bottom-0 flex h-24 w-24 items-center justify-center text-gray-600 opacity-50 select-none", children: _jsx(Spinner, {}) })), children || editorUi, dialog, _jsx(Toaster, { position: "top-center" }), " ", _jsx(ConfirmationDialog, { ref: confirmationDialogRef }), _jsx(QuickItemSwitcher, { visible: quickSwitcherVisible, entries: navigationHistory.slice(0, 5), selectedIndex: quickSwitcherSelectedIndex, onSelect: handleQuickSwitcherSelect, onClose: () => setQuickSwitcherVisible(false) }), _jsx(EditContextMenu, { ref: contextMenuRef }), _jsx(InlineAiTrigger, {}), media.mediaSelectorVisible && (_jsx(MediaSelector, { language: editContext.currentItemDescriptor.language, visible: media.mediaSelectorVisible, onHide: media.handleHide, onMediaSelected: media.onMediaSelect, selectedIdPath: media.selectedMediaIdPath, mode: media.mediaSelectorMode, initialSearchTerm: media.initialSearchTerm })), _jsx(FieldEditorPopup, { ref: fieldEditorPopupRef })] }) }) }) }));
4658
4125
  }
4659
4126
  //# sourceMappingURL=EditorShell.js.map