@parhelia/core 0.1.12888 → 0.1.12890

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 (342) hide show
  1. package/dist/agents-view/AgentCard.d.ts +2 -1
  2. package/dist/agents-view/AgentCard.js +14 -38
  3. package/dist/agents-view/AgentCard.js.map +1 -1
  4. package/dist/agents-view/AgentGalleryCard.d.ts +12 -0
  5. package/dist/agents-view/AgentGalleryCard.js +12 -0
  6. package/dist/agents-view/AgentGalleryCard.js.map +1 -0
  7. package/dist/agents-view/AgentGalleryView.d.ts +18 -0
  8. package/dist/agents-view/AgentGalleryView.js +88 -0
  9. package/dist/agents-view/AgentGalleryView.js.map +1 -0
  10. package/dist/agents-view/AgentProfileIcon.d.ts +9 -0
  11. package/dist/agents-view/AgentProfileIcon.js +28 -0
  12. package/dist/agents-view/AgentProfileIcon.js.map +1 -0
  13. package/dist/agents-view/AgentsView.d.ts +6 -1
  14. package/dist/agents-view/AgentsView.js +40 -12
  15. package/dist/agents-view/AgentsView.js.map +1 -1
  16. package/dist/agents-view/AgentsWorkspaceView.js +40 -21
  17. package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
  18. package/dist/agents-view/DateAgentsGroup.d.ts +2 -1
  19. package/dist/agents-view/DateAgentsGroup.js +2 -2
  20. package/dist/agents-view/DateAgentsGroup.js.map +1 -1
  21. package/dist/agents-view/ProfileAgentsGroup.d.ts +2 -1
  22. package/dist/agents-view/ProfileAgentsGroup.js +5 -8
  23. package/dist/agents-view/ProfileAgentsGroup.js.map +1 -1
  24. package/dist/agents-view/RenameAgentDialog.d.ts +12 -0
  25. package/dist/agents-view/RenameAgentDialog.js +40 -0
  26. package/dist/agents-view/RenameAgentDialog.js.map +1 -0
  27. package/dist/components/FilterInput.d.ts +2 -0
  28. package/dist/components/FilterInput.js +4 -2
  29. package/dist/components/FilterInput.js.map +1 -1
  30. package/dist/components/ui/alert-dialog.d.ts +1 -1
  31. package/dist/components/ui/alert-dialog.js +5 -5
  32. package/dist/components/ui/alert-dialog.js.map +1 -1
  33. package/dist/components/ui/alert.d.ts +3 -2
  34. package/dist/components/ui/alert.js +9 -4
  35. package/dist/components/ui/alert.js.map +1 -1
  36. package/dist/components/ui/badge.d.ts +1 -1
  37. package/dist/components/ui/button.d.ts +9 -4
  38. package/dist/components/ui/button.js +16 -9
  39. package/dist/components/ui/button.js.map +1 -1
  40. package/dist/components/ui/dialog.d.ts +1 -1
  41. package/dist/components/ui/dialog.js +4 -3
  42. package/dist/components/ui/dialog.js.map +1 -1
  43. package/dist/components/ui/styled-dialog-title.js +1 -1
  44. package/dist/components/ui/styled-dialog-title.js.map +1 -1
  45. package/dist/config/config.js +4 -3
  46. package/dist/config/config.js.map +1 -1
  47. package/dist/editor/FieldListField.js +6 -2
  48. package/dist/editor/FieldListField.js.map +1 -1
  49. package/dist/editor/GlobalMenuBar.js +3 -1
  50. package/dist/editor/GlobalMenuBar.js.map +1 -1
  51. package/dist/editor/LinkEditorDialog.js +3 -3
  52. package/dist/editor/LinkEditorDialog.js.map +1 -1
  53. package/dist/editor/MainLayout.js +11 -9
  54. package/dist/editor/MainLayout.js.map +1 -1
  55. package/dist/editor/WorkspaceTitleSwitcher.d.ts +5 -0
  56. package/dist/editor/WorkspaceTitleSwitcher.js +86 -0
  57. package/dist/editor/WorkspaceTitleSwitcher.js.map +1 -0
  58. package/dist/editor/ai/AgentInlineDialogContent.js +1 -1
  59. package/dist/editor/ai/AgentInlineDialogContent.js.map +1 -1
  60. package/dist/editor/ai/Agents.js +155 -43
  61. package/dist/editor/ai/Agents.js.map +1 -1
  62. package/dist/editor/ai/InlineAiDialog.js +1 -1
  63. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  64. package/dist/editor/ai/dialogs/QuestionnaireInline.js +52 -82
  65. package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
  66. package/dist/editor/ai/terminal/agentQuestionnaireRecap.d.ts +82 -0
  67. package/dist/editor/ai/terminal/agentQuestionnaireRecap.js +277 -0
  68. package/dist/editor/ai/terminal/agentQuestionnaireRecap.js.map +1 -0
  69. package/dist/editor/ai/terminal/agentQuestionnaireTranscriptRecovery.d.ts +3 -0
  70. package/dist/editor/ai/terminal/agentQuestionnaireTranscriptRecovery.js +3 -3
  71. package/dist/editor/ai/terminal/agentQuestionnaireTranscriptRecovery.js.map +1 -1
  72. package/dist/editor/ai/terminal/agentSessionLiveTotals.d.ts +5 -0
  73. package/dist/editor/ai/terminal/agentSessionLiveTotals.js +14 -0
  74. package/dist/editor/ai/terminal/agentSessionLiveTotals.js.map +1 -1
  75. package/dist/editor/ai/terminal/agentSessionSnapshot.js +2 -0
  76. package/dist/editor/ai/terminal/agentSessionSnapshot.js.map +1 -1
  77. package/dist/editor/ai/terminal/components/AgentFullPromptControls.js +1 -1
  78. package/dist/editor/ai/terminal/components/AgentFullPromptControls.js.map +1 -1
  79. package/dist/editor/ai/terminal/components/AgentGreeting.js +5 -2
  80. package/dist/editor/ai/terminal/components/AgentGreeting.js.map +1 -1
  81. package/dist/editor/ai/terminal/components/AgentProjectProgress.d.ts +12 -0
  82. package/dist/editor/ai/terminal/components/AgentProjectProgress.js +207 -0
  83. package/dist/editor/ai/terminal/components/AgentProjectProgress.js.map +1 -0
  84. package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js +3 -3
  85. package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js.map +1 -1
  86. package/dist/editor/ai/terminal/components/AgentPromptComposer.d.ts +2 -1
  87. package/dist/editor/ai/terminal/components/AgentPromptComposer.js +5 -2
  88. package/dist/editor/ai/terminal/components/AgentPromptComposer.js.map +1 -1
  89. package/dist/editor/ai/terminal/components/AgentPromptInputArea.d.ts +2 -1
  90. package/dist/editor/ai/terminal/components/AgentPromptInputArea.js +5 -3
  91. package/dist/editor/ai/terminal/components/AgentPromptInputArea.js.map +1 -1
  92. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.d.ts +4 -3
  93. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js +6 -19
  94. package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js.map +1 -1
  95. package/dist/editor/ai/terminal/components/AgentTerminalFullUpperContent.d.ts +5 -1
  96. package/dist/editor/ai/terminal/components/AgentTerminalFullUpperContent.js +33 -2
  97. package/dist/editor/ai/terminal/components/AgentTerminalFullUpperContent.js.map +1 -1
  98. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.d.ts +2 -0
  99. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js +20 -1
  100. package/dist/editor/ai/terminal/components/AgentTerminalStatusBar.js.map +1 -1
  101. package/dist/editor/ai/terminal/components/AgentTerminalSummaryLayout.js +2 -1
  102. package/dist/editor/ai/terminal/components/AgentTerminalSummaryLayout.js.map +1 -1
  103. package/dist/editor/ai/terminal/components/AgentTerminalView.d.ts +3 -2
  104. package/dist/editor/ai/terminal/components/AgentTerminalView.js +11 -2
  105. package/dist/editor/ai/terminal/components/AgentTerminalView.js.map +1 -1
  106. package/dist/editor/ai/terminal/components/AiResponseMessage.js +59 -7
  107. package/dist/editor/ai/terminal/components/AiResponseMessage.js.map +1 -1
  108. package/dist/editor/ai/terminal/components/QuestionnaireRecap.d.ts +9 -0
  109. package/dist/editor/ai/terminal/components/QuestionnaireRecap.js +56 -0
  110. package/dist/editor/ai/terminal/components/QuestionnaireRecap.js.map +1 -0
  111. package/dist/editor/ai/terminal/contextBreakdown.d.ts +17 -0
  112. package/dist/editor/ai/terminal/contextBreakdown.js +58 -0
  113. package/dist/editor/ai/terminal/contextBreakdown.js.map +1 -0
  114. package/dist/editor/ai/terminal/types.d.ts +2 -0
  115. package/dist/editor/ai/terminal/useAgentAutoStartOnCreate.d.ts +29 -0
  116. package/dist/editor/ai/terminal/useAgentAutoStartOnCreate.js +68 -0
  117. package/dist/editor/ai/terminal/useAgentAutoStartOnCreate.js.map +1 -0
  118. package/dist/editor/ai/terminal/useAgentInlineDialogEvents.js +8 -3
  119. package/dist/editor/ai/terminal/useAgentInlineDialogEvents.js.map +1 -1
  120. package/dist/editor/ai/terminal/useAgentInlineDialogState.d.ts +10 -3
  121. package/dist/editor/ai/terminal/useAgentInlineDialogState.js +33 -4
  122. package/dist/editor/ai/terminal/useAgentInlineDialogState.js.map +1 -1
  123. package/dist/editor/ai/terminal/useAgentRunResyncSocketHandler.js +16 -2
  124. package/dist/editor/ai/terminal/useAgentRunResyncSocketHandler.js.map +1 -1
  125. package/dist/editor/ai/terminal/useAgentRunStatusSocketHandler.js +3 -1
  126. package/dist/editor/ai/terminal/useAgentRunStatusSocketHandler.js.map +1 -1
  127. package/dist/editor/ai/terminal/useAgentSession.js +12 -1
  128. package/dist/editor/ai/terminal/useAgentSession.js.map +1 -1
  129. package/dist/editor/ai/terminal/useAgentSubmitLifecycle.d.ts +3 -0
  130. package/dist/editor/ai/terminal/useAgentSubmitLifecycle.js +6 -1
  131. package/dist/editor/ai/terminal/useAgentSubmitLifecycle.js.map +1 -1
  132. package/dist/editor/ai/terminal/useAgentTerminalController.js +48 -4
  133. package/dist/editor/ai/terminal/useAgentTerminalController.js.map +1 -1
  134. package/dist/editor/ai/terminal/useAgentTerminalViewProps.d.ts +1 -0
  135. package/dist/editor/ai/terminal/useAgentTerminalViewProps.js +2 -1
  136. package/dist/editor/ai/terminal/useAgentTerminalViewProps.js.map +1 -1
  137. package/dist/editor/ai/terminal/useAgentToolCallHandler.js +13 -1
  138. package/dist/editor/ai/terminal/useAgentToolCallHandler.js.map +1 -1
  139. package/dist/editor/ai/terminal/useAgentToolResultHandler.js +31 -7
  140. package/dist/editor/ai/terminal/useAgentToolResultHandler.js.map +1 -1
  141. package/dist/editor/bridge/BridgeClient.d.ts +1 -8
  142. package/dist/editor/bridge/BridgeClient.js +2 -4
  143. package/dist/editor/bridge/BridgeClient.js.map +1 -1
  144. package/dist/editor/bridge/protocol.d.ts +512 -0
  145. package/dist/editor/bridge/protocol.js +188 -0
  146. package/dist/editor/bridge/protocol.js.map +1 -0
  147. package/dist/editor/client/AboutDialog.js +15 -4
  148. package/dist/editor/client/AboutDialog.js.map +1 -1
  149. package/dist/editor/client/EditorShell.js +50 -13
  150. package/dist/editor/client/EditorShell.js.map +1 -1
  151. package/dist/editor/client/editContext.d.ts +6 -0
  152. package/dist/editor/client/editContext.js.map +1 -1
  153. package/dist/editor/client/hooks/useSocketMessageHandler.d.ts +3 -0
  154. package/dist/editor/client/hooks/useSocketMessageHandler.js +57 -25
  155. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  156. package/dist/editor/client/hooks/useWorkbox.d.ts +1 -0
  157. package/dist/editor/client/hooks/useWorkbox.js +14 -1
  158. package/dist/editor/client/hooks/useWorkbox.js.map +1 -1
  159. package/dist/editor/client/operationToasts.d.ts +2 -0
  160. package/dist/editor/client/operationToasts.js +35 -0
  161. package/dist/editor/client/operationToasts.js.map +1 -0
  162. package/dist/editor/client/operations.d.ts +4 -0
  163. package/dist/editor/client/operations.js +134 -74
  164. package/dist/editor/client/operations.js.map +1 -1
  165. package/dist/editor/client/pageModelBuilder.d.ts +1 -0
  166. package/dist/editor/client/pageModelBuilder.js +22 -13
  167. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  168. package/dist/editor/client/waitForEditOperationTerminal.d.ts +1 -0
  169. package/dist/editor/client/waitForEditOperationTerminal.js +1 -1
  170. package/dist/editor/client/waitForEditOperationTerminal.js.map +1 -1
  171. package/dist/editor/commands/itemCommands.js +5 -16
  172. package/dist/editor/commands/itemCommands.js.map +1 -1
  173. package/dist/editor/content-tree/IndicatorSettings.js +3 -2
  174. package/dist/editor/content-tree/IndicatorSettings.js.map +1 -1
  175. package/dist/editor/field-types/CheckboxEditor.js +3 -1
  176. package/dist/editor/field-types/CheckboxEditor.js.map +1 -1
  177. package/dist/editor/field-types/MultiLineText.js +24 -7
  178. package/dist/editor/field-types/MultiLineText.js.map +1 -1
  179. package/dist/editor/field-types/SingleLineText.js +19 -2
  180. package/dist/editor/field-types/SingleLineText.js.map +1 -1
  181. package/dist/editor/field-types/useTextCompletion.d.ts +20 -0
  182. package/dist/editor/field-types/useTextCompletion.js +166 -0
  183. package/dist/editor/field-types/useTextCompletion.js.map +1 -0
  184. package/dist/editor/menubar/ItemLanguageVersion.js +3 -14
  185. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
  186. package/dist/editor/menubar/OperationsIndicator.d.ts +7 -0
  187. package/dist/editor/menubar/OperationsIndicator.js +87 -0
  188. package/dist/editor/menubar/OperationsIndicator.js.map +1 -0
  189. package/dist/editor/menubar/ToolbarFactory.js +4 -1
  190. package/dist/editor/menubar/ToolbarFactory.js.map +1 -1
  191. package/dist/editor/menubar/VersionSelector.d.ts +3 -2
  192. package/dist/editor/menubar/VersionSelector.js +28 -12
  193. package/dist/editor/menubar/VersionSelector.js.map +1 -1
  194. package/dist/editor/menubar/WorkflowButton.js +7 -4
  195. package/dist/editor/menubar/WorkflowButton.js.map +1 -1
  196. package/dist/editor/menubar/toolbar-sections/EditControls.js +7 -3
  197. package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
  198. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +4 -1
  199. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
  200. package/dist/editor/notifications/NotificationCenter.js +28 -27
  201. package/dist/editor/notifications/NotificationCenter.js.map +1 -1
  202. package/dist/editor/notifications/NotificationItem.js +100 -15
  203. package/dist/editor/notifications/NotificationItem.js.map +1 -1
  204. package/dist/editor/notifications/watchEventOptions.js +3 -2
  205. package/dist/editor/notifications/watchEventOptions.js.map +1 -1
  206. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.d.ts +1 -1
  207. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +8 -2
  208. package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -1
  209. package/dist/editor/page-editor-chrome/PageEditorChrome.d.ts +1 -1
  210. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +7 -1
  211. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  212. package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js +3 -10
  213. package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js.map +1 -1
  214. package/dist/editor/page-editor-chrome/overlay/geometry.d.ts +2 -2
  215. package/dist/editor/page-editor-chrome/useBridgeInlineEditing.d.ts +1 -1
  216. package/dist/editor/page-viewer/MiniMap.d.ts +21 -0
  217. package/dist/editor/page-viewer/MiniMap.js +113 -11
  218. package/dist/editor/page-viewer/MiniMap.js.map +1 -1
  219. package/dist/editor/page-viewer/PageViewerFrame.js +155 -22
  220. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  221. package/dist/editor/page-viewer/bridgeFieldPatch.d.ts +1 -2
  222. package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -1
  223. package/dist/editor/page-viewer/pageViewContext.d.ts +1 -1
  224. package/dist/editor/reviews/DecisionsMatrix.js +5 -1
  225. package/dist/editor/reviews/DecisionsMatrix.js.map +1 -1
  226. package/dist/editor/reviews/SuggestedEdit.js +12 -2
  227. package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
  228. package/dist/editor/reviews/latestFeedbackData.js +7 -1
  229. package/dist/editor/reviews/latestFeedbackData.js.map +1 -1
  230. package/dist/editor/reviews/suggestedEditState.d.ts +2 -0
  231. package/dist/editor/reviews/suggestedEditState.js +20 -0
  232. package/dist/editor/reviews/suggestedEditState.js.map +1 -1
  233. package/dist/editor/reviews/suggestionContentChange.d.ts +1 -1
  234. package/dist/editor/reviews/suggestionContentChange.js +23 -3
  235. package/dist/editor/reviews/suggestionContentChange.js.map +1 -1
  236. package/dist/editor/services/agentService.d.ts +6 -0
  237. package/dist/editor/services/agentService.js +14 -0
  238. package/dist/editor/services/agentService.js.map +1 -1
  239. package/dist/editor/services/aiService.d.ts +5 -0
  240. package/dist/editor/services/aiService.js.map +1 -1
  241. package/dist/editor/settings/About.js +1 -1
  242. package/dist/editor/settings/About.js.map +1 -1
  243. package/dist/editor/settings/panels/AgentProfileConfigPanel.js +4 -2
  244. package/dist/editor/settings/panels/AgentProfileConfigPanel.js.map +1 -1
  245. package/dist/editor/settings/panels/AgentToolsPanel.js +61 -33
  246. package/dist/editor/settings/panels/AgentToolsPanel.js.map +1 -1
  247. package/dist/editor/settings/panels/ClusterInstancesPanel.js +2 -1
  248. package/dist/editor/settings/panels/ClusterInstancesPanel.js.map +1 -1
  249. package/dist/editor/settings/panels/JavaScriptToolAgentPanel.js +3 -2
  250. package/dist/editor/settings/panels/JavaScriptToolAgentPanel.js.map +1 -1
  251. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js +3 -2
  252. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js.map +1 -1
  253. package/dist/editor/settings/panels/StatusPanel.js +10 -7
  254. package/dist/editor/settings/panels/StatusPanel.js.map +1 -1
  255. package/dist/editor/sidebar/Completions.js +1 -1
  256. package/dist/editor/sidebar/Completions.js.map +1 -1
  257. package/dist/editor/sidebar/ComponentTree.js +1 -1
  258. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  259. package/dist/editor/sidebar/OperationItem.js +1 -1
  260. package/dist/editor/sidebar/OperationItem.js.map +1 -1
  261. package/dist/editor/sidebar/Workbox.js +18 -4
  262. package/dist/editor/sidebar/Workbox.js.map +1 -1
  263. package/dist/editor/template-wizard/TemplateStructureInlineEditor.js +3 -2
  264. package/dist/editor/template-wizard/TemplateStructureInlineEditor.js.map +1 -1
  265. package/dist/editor/tree-indicators/GutterColumns.js +3 -2
  266. package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
  267. package/dist/editor/ui/DialogButtons.d.ts +3 -1
  268. package/dist/editor/ui/DialogButtons.js +3 -2
  269. package/dist/editor/ui/DialogButtons.js.map +1 -1
  270. package/dist/editor/ui/Icons.js +1 -1
  271. package/dist/editor/ui/Icons.js.map +1 -1
  272. package/dist/editor/ui/ItemCollectionEditor.js +2 -2
  273. package/dist/editor/ui/ItemCollectionEditor.js.map +1 -1
  274. package/dist/editor/ui/PublishItemDialog.js +4 -6
  275. package/dist/editor/ui/PublishItemDialog.js.map +1 -1
  276. package/dist/editor/ui/SimpleTabs.d.ts +2 -1
  277. package/dist/editor/ui/SimpleTabs.js +23 -5
  278. package/dist/editor/ui/SimpleTabs.js.map +1 -1
  279. package/dist/editor/ui/Splitter.js +120 -3
  280. package/dist/editor/ui/Splitter.js.map +1 -1
  281. package/dist/editor/ui/splitterResizeEvent.d.ts +7 -0
  282. package/dist/editor/ui/splitterResizeEvent.js +6 -0
  283. package/dist/editor/ui/splitterResizeEvent.js.map +1 -1
  284. package/dist/editor/version-diff/versionDiffTargets.d.ts +1 -1
  285. package/dist/editor/workflowFields.d.ts +1 -0
  286. package/dist/editor/workflowFields.js +16 -0
  287. package/dist/editor/workflowFields.js.map +1 -0
  288. package/dist/index.d.ts +4 -2
  289. package/dist/index.js +3 -2
  290. package/dist/index.js.map +1 -1
  291. package/dist/revision.d.ts +2 -2
  292. package/dist/revision.js +2 -2
  293. package/dist/splash-screen/ModernSplashScreen.js +20 -11
  294. package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
  295. package/dist/splash-screen/NewPage.js +26 -7
  296. package/dist/splash-screen/NewPage.js.map +1 -1
  297. package/dist/task-board/TaskBoardWorkspace.js +154 -121
  298. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  299. package/dist/task-board/components/CreateTaskDialog.js +1 -1
  300. package/dist/task-board/components/CreateTaskDialog.js.map +1 -1
  301. package/dist/task-board/components/ProjectDashboard.d.ts +12 -22
  302. package/dist/task-board/components/ProjectDashboard.js +120 -108
  303. package/dist/task-board/components/ProjectDashboard.js.map +1 -1
  304. package/dist/task-board/components/ProjectOverviewContent.js +3 -0
  305. package/dist/task-board/components/ProjectOverviewContent.js.map +1 -1
  306. package/dist/task-board/components/ProjectPropertiesPanel.d.ts +2 -0
  307. package/dist/task-board/components/ProjectPropertiesPanel.js +7 -4
  308. package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
  309. package/dist/task-board/components/ProjectSettingsDialog.d.ts +16 -0
  310. package/dist/task-board/components/ProjectSettingsDialog.js +55 -47
  311. package/dist/task-board/components/ProjectSettingsDialog.js.map +1 -1
  312. package/dist/task-board/components/TaskAgentPanel.js +6 -5
  313. package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
  314. package/dist/task-board/components/TaskAssigneePicker.js +3 -2
  315. package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
  316. package/dist/task-board/components/TaskAttachmentsSection.js +1 -1
  317. package/dist/task-board/components/TaskAttachmentsSection.js.map +1 -1
  318. package/dist/task-board/components/TaskBoardHomeView.d.ts +7 -0
  319. package/dist/task-board/components/TaskBoardHomeView.js +21 -0
  320. package/dist/task-board/components/TaskBoardHomeView.js.map +1 -0
  321. package/dist/task-board/components/TaskBoardProjectListSidebar.js +74 -12
  322. package/dist/task-board/components/TaskBoardProjectListSidebar.js.map +1 -1
  323. package/dist/task-board/components/TaskBoardTitlebar.js +9 -52
  324. package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
  325. package/dist/task-board/components/TaskCard.js +5 -13
  326. package/dist/task-board/components/TaskCard.js.map +1 -1
  327. package/dist/task-board/components/TaskRow.js +3 -2
  328. package/dist/task-board/components/TaskRow.js.map +1 -1
  329. package/dist/task-board/taskBoardNavStore.d.ts +0 -2
  330. package/dist/task-board/taskBoardNavStore.js +0 -2
  331. package/dist/task-board/taskBoardNavStore.js.map +1 -1
  332. package/dist/task-board/views/DependencyGraphView.js +3 -2
  333. package/dist/task-board/views/DependencyGraphView.js.map +1 -1
  334. package/dist/task-board/views/KanbanView.js +161 -38
  335. package/dist/task-board/views/KanbanView.js.map +1 -1
  336. package/dist/task-board/views/ListView.js +1 -2
  337. package/dist/task-board/views/ListView.js.map +1 -1
  338. package/dist/task-board/views/WizardView.d.ts +2 -0
  339. package/dist/task-board/views/WizardView.js +7 -4
  340. package/dist/task-board/views/WizardView.js.map +1 -1
  341. package/package.json +1 -2
  342. package/styles.css +4 -3
@@ -9,24 +9,21 @@ import { createOrUpdateSuggestedEdit, deleteSuggestedEdit, } from "../services/s
9
9
  import { hasSuggestionContentChange, shouldRemoveNoOpSuggestion, } from "../reviews/suggestionContentChange";
10
10
  import { GUID_REGEX_EXACT, getItemDescriptor } from "../utils";
11
11
  import { cleanId } from "../utils/id-helper";
12
- import { copyItemsNeedsTerminalCompletion, waitForEditOperationTerminal, } from "./waitForEditOperationTerminal";
12
+ import { copyItemsNeedsTerminalCompletion, normalizeOpId, waitForEditOperationTerminal, } from "./waitForEditOperationTerminal";
13
+ import { isWorkflowMetadataField } from "../workflowFields";
13
14
  import { ExternalChangesWarningContent, TreeOperationConfirmContent, UndoDifferentItemContent, } from "./OperationDialogContent";
14
- import { upsertSuggestedEdit } from "../reviews/suggestedEditState";
15
+ import { isSuggestedEditRemoved, markSuggestedEditRemoved, upsertSuggestedEdit, } from "../reviews/suggestedEditState";
15
16
  /** When true, the delete dialog shows "permanently delete (bypass recycle bin)". */
16
17
  const ENABLE_HARD_DELETE_IN_DELETE_DIALOG = false;
17
18
  // Track pending suggested edit save requests to prevent race conditions
18
19
  const pendingSuggestedEditSaves = new Map();
19
20
  // Track pending suggested edits to prevent creating duplicates before server response
20
21
  const pendingSuggestedEdits = new Map();
21
- // Suggestions that were reverted to a no-op while a debounced save was still in
22
- // flight. A pending save must not (re-)create or re-add them on the server or in
23
- // local state. Ids are uuids and never reused, so retaining them is safe.
24
- const removedSuggestedEditIds = new Set();
25
22
  const SUGGESTED_EDIT_SAVE_DEBOUNCE_MS = 500;
26
23
  function createDelayedSuggestedEditSave(suggestedEdit) {
27
24
  return new Promise((resolve, reject) => {
28
25
  globalThis.setTimeout(() => {
29
- if (removedSuggestedEditIds.has(suggestedEdit.id)) {
26
+ if (isSuggestedEditRemoved(suggestedEdit.id)) {
30
27
  // The suggestion was reverted to a no-op while this save was pending.
31
28
  // It never reached the server, so there is nothing to persist or delete.
32
29
  resolve({ type: "ignored" });
@@ -124,6 +121,12 @@ export function getOperationsContext(state, ui) {
124
121
  if (returnedOp.executionStatus !== "executing") {
125
122
  setExecutingEditOperations((ops) => ops ? ops.filter((x) => x.id !== op.id) : []);
126
123
  }
124
+ else {
125
+ // Swap in the server's "executing" version so consumers (e.g. the
126
+ // operations indicator) can tell long-running ops apart from ops that
127
+ // are merely awaiting their HTTP response
128
+ setExecutingEditOperations((ops) => (ops ?? []).map((x) => (x.id === op.id ? returnedOp : x)));
129
+ }
127
130
  return returnedOp;
128
131
  }, []);
129
132
  const duplicateComponents = useCallback(({ componentIds }) => {
@@ -288,6 +291,9 @@ export function getOperationsContext(state, ui) {
288
291
  else
289
292
  stateRef.current.requestRefresh("immediate");
290
293
  }, []);
294
+ const refreshWorkboxAfterWorkflowChange = useDebouncedCallback(() => {
295
+ stateRef.current.refreshWorkbox?.();
296
+ }, 300, { trailing: true });
291
297
  const executeWorkflowCommandAndRefresh = useCallback(async (item, commandId) => {
292
298
  const result = await executeWorkflowCommand(item, commandId, "");
293
299
  if (result.type === "success") {
@@ -298,9 +304,12 @@ export function getOperationsContext(state, ui) {
298
304
  };
299
305
  ui.showErrorToast(errorMessage);
300
306
  }
307
+ if (result.data.succeeded) {
308
+ refreshWorkboxAfterWorkflowChange();
309
+ }
301
310
  stateRef.current.requestRefresh("immediate");
302
311
  }
303
- }, [ui]);
312
+ }, [refreshWorkboxAfterWorkflowChange, ui]);
304
313
  const renameItem = useCallback(async (item, newName) => {
305
314
  await executeOp({
306
315
  type: "rename-item",
@@ -382,6 +391,7 @@ export function getOperationsContext(state, ui) {
382
391
  user: stateRef.current.user,
383
392
  itemsRepository: itemsRepository,
384
393
  comments: stateRef.current.comments,
394
+ commentsLoaded: stateRef.current.commentsLoaded,
385
395
  suggestedEdits: stateRef.current.suggestedEdits,
386
396
  setSuggestedEdits: stateRef.current.setSuggestedEdits,
387
397
  });
@@ -412,10 +422,14 @@ export function getOperationsContext(state, ui) {
412
422
  // Update the suggested edits state with the result from the server
413
423
  if (result.type === "success" && result.data) {
414
424
  const updatedEdit = result.data;
415
- if (removedSuggestedEditIds.has(updatedEdit.id)) {
425
+ if (isSuggestedEditRemoved(updatedEdit.id)) {
416
426
  // Reverted to a no-op while this save was in flight; make sure
417
427
  // it stays gone on the server and do not re-add it locally.
418
- void deleteSuggestedEdit(updatedEdit).catch(() => undefined);
428
+ void deleteSuggestedEdit(updatedEdit).then((deleteResult) => {
429
+ if (deleteResult.type !== "success") {
430
+ console.warn("Failed to delete reverted suggestion after save:", deleteResult.summary, deleteResult.details);
431
+ }
432
+ }, () => undefined);
419
433
  return result;
420
434
  }
421
435
  stateRef.current.setSuggestedEdits((current) => upsertSuggestedEdit(current, updatedEdit, {
@@ -425,11 +439,15 @@ export function getOperationsContext(state, ui) {
425
439
  }
426
440
  else if (result.type === "error" ||
427
441
  result.type === "unauthorized") {
428
- // Show error toast for failed suggested edit save
429
- ui.showErrorToast({
430
- summary: result.summary || "Failed to save suggestion",
431
- details: result.details,
432
- });
442
+ // Show error toast for failed suggested edit save — unless the
443
+ // suggestion was reverted while the request was in flight, in
444
+ // which case there is nothing for the user to see or retry.
445
+ if (!isSuggestedEditRemoved(saveSnapshot.id)) {
446
+ ui.showErrorToast({
447
+ summary: result.summary || "Failed to save suggestion",
448
+ details: result.details,
449
+ });
450
+ }
433
451
  }
434
452
  return result;
435
453
  })
@@ -515,6 +533,10 @@ export function getOperationsContext(state, ui) {
515
533
  // Don't refresh here - the websocket handler will trigger a refresh when
516
534
  // it receives the item-changed notification from the server. This avoids
517
535
  // duplicate refresh calls for the same edit.
536
+ if (result.executionStatus !== "failed" &&
537
+ isWorkflowMetadataField(op.fieldId, op.fieldName)) {
538
+ refreshWorkboxAfterWorkflowChange();
539
+ }
518
540
  itemsRepository.onFieldSaved(field, val, saveSequence || 0, fieldModificationStore);
519
541
  }
520
542
  catch (error) {
@@ -523,7 +545,7 @@ export function getOperationsContext(state, ui) {
523
545
  console.error("[editFieldImmediate] Error saving field:", error);
524
546
  itemsRepository.clearDirtyState(field, fieldModificationStore);
525
547
  }
526
- }, [itemsRepository, executeOp]);
548
+ }, [itemsRepository, executeOp, refreshWorkboxAfterWorkflowChange]);
527
549
  const executeEditFieldDebounced = useDebouncedCallback(async ({ field, value, rawValue, refresh, saveSequence, fieldModificationStore, }) => {
528
550
  // Fix: Use the saveSequence passed from editField instead of calling
529
551
  // updateFieldValue again. This prevents the race condition where the
@@ -1367,19 +1389,14 @@ export function getOperationsContext(state, ui) {
1367
1389
  const terminal = await waitForEditOperationTerminal(cloneResult.id, 120_000);
1368
1390
  cloneResult = { ...cloneResult, ...terminal };
1369
1391
  }
1370
- catch (e) {
1371
- ui.showErrorToast({
1372
- summary: "Clone failed",
1373
- details: e?.message || "Operation timed out",
1374
- });
1392
+ catch {
1393
+ // No terminal message within the timeout; the central lifecycle
1394
+ // toast keeps tracking the operation
1375
1395
  return [];
1376
1396
  }
1377
1397
  }
1378
1398
  if (cloneResult?.errorMessage) {
1379
- ui.showErrorToast({
1380
- summary: "Clone failed",
1381
- details: cloneResult.errorMessage,
1382
- });
1399
+ // operation:failed already produced the central error toast
1383
1400
  return [];
1384
1401
  }
1385
1402
  if (cloneResult?.createdItemIds) {
@@ -1390,7 +1407,7 @@ export function getOperationsContext(state, ui) {
1390
1407
  }));
1391
1408
  }
1392
1409
  return [];
1393
- }, [executeOp, ui]);
1410
+ }, [executeOp]);
1394
1411
  const duplicateItem = useCallback(async (item, target, name) => {
1395
1412
  // Use generic edit endpoint for long-running operation support
1396
1413
  // Duplicate is a copy to the same parent, positioned after the original
@@ -1411,19 +1428,14 @@ export function getOperationsContext(state, ui) {
1411
1428
  const terminal = await waitForEditOperationTerminal(copyResult.id, 120_000);
1412
1429
  copyResult = { ...copyResult, ...terminal };
1413
1430
  }
1414
- catch (e) {
1415
- ui.showErrorToast({
1416
- summary: "Duplicate failed",
1417
- details: e?.message || "Operation timed out",
1418
- });
1431
+ catch {
1432
+ // No terminal message within the timeout; the central lifecycle
1433
+ // toast keeps tracking the operation
1419
1434
  return;
1420
1435
  }
1421
1436
  }
1422
1437
  if (copyResult.errorMessage) {
1423
- ui.showErrorToast({
1424
- summary: "Duplicate failed",
1425
- details: copyResult.errorMessage,
1426
- });
1438
+ // operation:failed already produced the central error toast
1427
1439
  return;
1428
1440
  }
1429
1441
  itemsRepository.refreshItems([target]);
@@ -1436,7 +1448,7 @@ export function getOperationsContext(state, ui) {
1436
1448
  };
1437
1449
  }
1438
1450
  return undefined;
1439
- }, [executeOp, itemsRepository, ui]);
1451
+ }, [executeOp, itemsRepository]);
1440
1452
  const publishItem = useCallback(async (operation) => {
1441
1453
  const result = (await executeOp(operation, {
1442
1454
  refresh: "immediate",
@@ -1509,11 +1521,32 @@ export function getOperationsContext(state, ui) {
1509
1521
  // This prevents fields from getting stuck in "saving" state when navigating away
1510
1522
  const cleanup = useCallback(() => {
1511
1523
  executeEditFieldDebounced.flush();
1512
- }, []);
1524
+ refreshWorkboxAfterWorkflowChange.cancel();
1525
+ }, [executeEditFieldDebounced, refreshWorkboxAfterWorkflowChange]);
1513
1526
  // Function to mark an operation as no longer executing
1514
1527
  // Called when WebSocket receives operation:completed or operation:failed
1515
1528
  const markOperationComplete = useCallback((operationId) => {
1516
- setExecutingEditOperations((ops) => ops ? ops.filter((x) => x.id !== operationId) : []);
1529
+ const key = normalizeOpId(operationId);
1530
+ setExecutingEditOperations((ops) => ops ? ops.filter((x) => normalizeOpId(x.id) !== key) : []);
1531
+ }, []);
1532
+ // Upsert a long-running operation reported by the WebSocket. Covers ops
1533
+ // started in another tab of the same user, which never pass through
1534
+ // executeOp in this tab.
1535
+ const addExecutingOperation = useCallback((operation) => {
1536
+ const key = normalizeOpId(operation.id);
1537
+ setExecutingEditOperations((ops) => {
1538
+ const list = ops ?? [];
1539
+ const existing = list.find((x) => normalizeOpId(x.id) === key);
1540
+ if (existing) {
1541
+ return list.map((x) => normalizeOpId(x.id) === key ? { ...x, ...operation } : x);
1542
+ }
1543
+ return [...list, operation];
1544
+ });
1545
+ }, []);
1546
+ // Live progress for an executing operation (from operation:progress messages)
1547
+ const updateExecutingOperationProgress = useCallback((operationId, progress, statusMessage) => {
1548
+ const key = normalizeOpId(operationId);
1549
+ setExecutingEditOperations((ops) => (ops ?? []).map((x) => normalizeOpId(x.id) === key ? { ...x, progress, statusMessage } : x));
1517
1550
  }, []);
1518
1551
  return useMemo(() => ({
1519
1552
  ops,
@@ -1521,40 +1554,46 @@ export function getOperationsContext(state, ui) {
1521
1554
  editOperationExecuted,
1522
1555
  executingEditOperations,
1523
1556
  markOperationComplete,
1557
+ addExecutingOperation,
1558
+ updateExecutingOperationProgress,
1524
1559
  },
1525
1560
  cleanup,
1526
1561
  }), [
1527
1562
  executingEditOperations,
1528
1563
  editOperationExecuted,
1529
1564
  markOperationComplete,
1565
+ addExecutingOperation,
1566
+ updateExecutingOperationProgress,
1530
1567
  ops,
1531
1568
  cleanup,
1532
1569
  ]);
1533
1570
  }
1534
- function removeSuggestedEditFromState(edit, state, pendingFieldKey) {
1535
- // Mark as removed first so any in-flight debounced save neither re-creates the
1571
+ function removeSuggestedEditFromState(edit, state, keys) {
1572
+ // Tombstone first so any in-flight debounced save neither re-creates the
1536
1573
  // suggestion on the server nor re-adds it to local state via its save-ack.
1537
- removedSuggestedEditIds.add(edit.id);
1538
- const saveKey = `${edit.itemId}:${edit.mainItemLanguage}:${edit.mainItemVersion}:${edit.fieldId}`;
1539
- const pendingSave = pendingSuggestedEditSaves.get(saveKey);
1540
- pendingSuggestedEdits.delete(pendingFieldKey);
1574
+ // The tombstone is permanent for the session: a save scheduled while this
1575
+ // removal is settling (e.g. an edit queued behind the in-flight save) would
1576
+ // otherwise fire after an early release and resurrect the suggestion.
1577
+ markSuggestedEditRemoved(edit.id);
1578
+ // The saves map is keyed by the field's own item descriptor (which can have
1579
+ // a different version/language than the page the suggestion is stored
1580
+ // under), so the caller passes the exact keys it used.
1581
+ const pendingSave = pendingSuggestedEditSaves.get(keys.saveKey);
1582
+ pendingSuggestedEdits.delete(keys.pendingFieldKey);
1541
1583
  cleanupPendingSuggestedEditOperations(edit, state.user);
1542
- const nextSuggestedEdits = state.suggestedEdits.filter((candidate) => candidate.id !== edit.id);
1543
- state.suggestedEdits = nextSuggestedEdits;
1544
- state.setSuggestedEdits(nextSuggestedEdits);
1584
+ state.setSuggestedEdits((current) => current.filter((candidate) => candidate.id !== edit.id));
1545
1585
  // Delete on the server only after any in-flight save settles, otherwise the
1546
1586
  // delete can race ahead of a pending create and the suggestion comes back.
1547
- // Once that latest save has resolved, all earlier debounced timers for this
1548
- // field have already fired and checked the removed set, so the id can be
1549
- // dropped to keep the set from growing unbounded over a long session.
1550
1587
  void Promise.resolve(pendingSave)
1551
1588
  .catch(() => undefined)
1552
1589
  .then(() => deleteSuggestedEdit(edit))
1590
+ .then((result) => {
1591
+ if (result.type !== "success") {
1592
+ console.warn("Failed to delete no-op suggestion:", result.summary, result.details);
1593
+ }
1594
+ })
1553
1595
  .catch((error) => {
1554
1596
  console.warn("Failed to delete no-op suggestion:", error);
1555
- })
1556
- .finally(() => {
1557
- removedSuggestedEditIds.delete(edit.id);
1558
1597
  });
1559
1598
  }
1560
1599
  function getSuggestionCommentCount(edit, state) {
@@ -1578,14 +1617,37 @@ async function getOrMergeSuggestedEditOp(field, rawValue, value, state) {
1578
1617
  if (!pageDescriptor) {
1579
1618
  return;
1580
1619
  }
1581
- // Create a unique key for this field to check for pending edits
1582
- const fieldKey = `${field.item.id}:${field.item.language}:${field.item.version}:${field.fieldId}:${state.user?.name || "unknown"}`;
1583
- // First check if there's a pending suggested edit for this field
1584
- const pendingEdit = pendingSuggestedEdits.get(fieldKey);
1620
+ // Keys for the per-field bookkeeping maps. The saves map must use the same
1621
+ // key format as editField (the field's own item descriptor — NOT the
1622
+ // suggestion's mainItem fields, which hold the page's language/version and
1623
+ // diverge for datasource items).
1624
+ const saveKey = `${field.item.id}:${field.item.language}:${field.item.version}:${field.fieldId}`;
1625
+ const fieldKey = `${saveKey}:${state.user?.name || "unknown"}`;
1626
+ const shouldRemoveAsNoOp = (edit, nextValue) =>
1627
+ // Comments load asynchronously; deleting on the strength of a not-yet-
1628
+ // loaded comments array would destroy another reviewer's thread (the
1629
+ // server cascade-deletes a suggestion's comments along with it).
1630
+ state.commentsLoaded === true &&
1631
+ shouldRemoveNoOpSuggestion(edit.oldValue, nextValue, () => getSuggestionCommentCount(edit, state)) &&
1632
+ // Only auto-remove when the typed value is also a no-op against the
1633
+ // field's live value: if the field changed underneath the suggestion, the
1634
+ // typed content still differs from the page and must stay recorded.
1635
+ !hasSuggestionContentChange(fieldItem.rawValue, nextValue);
1636
+ // First check if there's a pending suggested edit for this field. A draft
1637
+ // whose suggestion was already reverted must not be revived — a new edit
1638
+ // mints a fresh suggestion instead.
1639
+ let pendingEdit = pendingSuggestedEdits.get(fieldKey);
1640
+ if (pendingEdit && isSuggestedEditRemoved(pendingEdit.id)) {
1641
+ pendingSuggestedEdits.delete(fieldKey);
1642
+ pendingEdit = undefined;
1643
+ }
1585
1644
  if (pendingEdit) {
1586
1645
  const nextValue = newVal || "";
1587
- if (shouldRemoveNoOpSuggestion(pendingEdit.oldValue, nextValue, getSuggestionCommentCount(pendingEdit, state))) {
1588
- removeSuggestedEditFromState(pendingEdit, state, fieldKey);
1646
+ if (shouldRemoveAsNoOp(pendingEdit, nextValue)) {
1647
+ removeSuggestedEditFromState(pendingEdit, state, {
1648
+ pendingFieldKey: fieldKey,
1649
+ saveKey,
1650
+ });
1589
1651
  return;
1590
1652
  }
1591
1653
  // Update the pending edit instead of creating a new one.
@@ -1596,9 +1658,7 @@ async function getOrMergeSuggestedEditOp(field, rawValue, value, state) {
1596
1658
  updatedBy: state.user?.name || "unknown",
1597
1659
  };
1598
1660
  pendingSuggestedEdits.set(fieldKey, updatedEdit);
1599
- const nextSuggestedEdits = upsertSuggestedEdit(state.suggestedEdits, updatedEdit, { source: "local" });
1600
- state.suggestedEdits = nextSuggestedEdits;
1601
- state.setSuggestedEdits(nextSuggestedEdits);
1661
+ state.setSuggestedEdits((current) => upsertSuggestedEdit(current, updatedEdit, { source: "local" }));
1602
1662
  return updatedEdit;
1603
1663
  }
1604
1664
  const matchingSuggestions = state.suggestedEdits.filter((edit) => edit.mainItemId === pageDescriptor.id &&
@@ -1606,17 +1666,24 @@ async function getOrMergeSuggestedEditOp(field, rawValue, value, state) {
1606
1666
  edit.itemId === item.id &&
1607
1667
  edit.fieldId === field.fieldId);
1608
1668
  // Attempt to find an existing suggested edit by the same user for this field.
1669
+ // Tombstoned ids are skipped: the state snapshot can still contain a
1670
+ // suggestion that was just reverted, and reusing its id would tie the new
1671
+ // edit to a save pipeline that permanently ignores it.
1609
1672
  const existing = matchingSuggestions.find((edit) => edit.mainItemId === pageDescriptor.id &&
1610
1673
  edit.mainItemLanguage === pageDescriptor.language &&
1611
1674
  edit.mainItemVersion === pageDescriptor.version &&
1612
1675
  edit.itemId === item.id &&
1613
1676
  edit.fieldId === field.fieldId &&
1614
1677
  edit.author === (state.user?.name || "unknown") &&
1615
- edit.status === "pending");
1678
+ edit.status === "pending" && // or any status that indicates it's open for further editing.
1679
+ !isSuggestedEditRemoved(edit.id));
1616
1680
  if (existing) {
1617
1681
  const nextValue = newVal || "";
1618
- if (shouldRemoveNoOpSuggestion(existing.oldValue, nextValue, getSuggestionCommentCount(existing, state))) {
1619
- removeSuggestedEditFromState(existing, state, fieldKey);
1682
+ if (shouldRemoveAsNoOp(existing, nextValue)) {
1683
+ removeSuggestedEditFromState(existing, state, {
1684
+ pendingFieldKey: fieldKey,
1685
+ saveKey,
1686
+ });
1620
1687
  return;
1621
1688
  }
1622
1689
  // Update the existing suggestion.
@@ -1626,10 +1693,7 @@ async function getOrMergeSuggestedEditOp(field, rawValue, value, state) {
1626
1693
  updated: new Date().toISOString(),
1627
1694
  updatedBy: state.user?.name || "unknown",
1628
1695
  };
1629
- const nextSuggestedEdits = upsertSuggestedEdit(state.suggestedEdits, updatedEdit, { source: "local" });
1630
- state.suggestedEdits = nextSuggestedEdits;
1631
- // Optionally, you might update the comments or other fields.
1632
- state.setSuggestedEdits(nextSuggestedEdits);
1696
+ state.setSuggestedEdits((current) => upsertSuggestedEdit(current, updatedEdit, { source: "local" }));
1633
1697
  return updatedEdit;
1634
1698
  }
1635
1699
  else {
@@ -1657,11 +1721,7 @@ async function getOrMergeSuggestedEditOp(field, rawValue, value, state) {
1657
1721
  };
1658
1722
  // Add to pending edits to prevent race conditions
1659
1723
  pendingSuggestedEdits.set(fieldKey, newEdit);
1660
- const nextSuggestedEdits = upsertSuggestedEdit(state.suggestedEdits, newEdit, {
1661
- source: "local",
1662
- });
1663
- state.suggestedEdits = nextSuggestedEdits;
1664
- state.setSuggestedEdits(nextSuggestedEdits);
1724
+ state.setSuggestedEdits((current) => upsertSuggestedEdit(current, newEdit, { source: "local" }));
1665
1725
  return newEdit;
1666
1726
  }
1667
1727
  }