@taskforcehq/taskforce 0.3.326 → 0.3.328

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 (1382) hide show
  1. package/LICENSE.md +68 -0
  2. package/README.md +19 -0
  3. package/dist/Taskforce.module.css +2168 -585
  4. package/dist/TaskforceCore.d.ts +1 -0
  5. package/dist/TaskforceCore.js +65 -22
  6. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.d.ts +1 -0
  7. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +3 -2
  8. package/dist/annotatedAttachments/commandService.d.ts +68 -0
  9. package/dist/annotatedAttachments/commandService.js +348 -0
  10. package/dist/annotatedAttachments/service.d.ts +2 -0
  11. package/dist/annotatedAttachments/service.js +13 -12
  12. package/dist/cli.js +158 -9
  13. package/dist/cliOpenPort.d.ts +1 -0
  14. package/dist/cliOpenPort.js +4 -0
  15. package/dist/compat/taskforceAgentDefinitionCompat.d.ts +12 -0
  16. package/dist/compat/taskforceAgentDefinitionCompat.js +25 -0
  17. package/dist/compat/workspaceSyncCompat.js +6 -2
  18. package/dist/compat/workspaceSyncV3CombinedCoverageCompat.d.ts +6 -0
  19. package/dist/compat/workspaceSyncV3CombinedCoverageCompat.js +22 -0
  20. package/dist/compat/workspaceSyncV3OperationCompat.d.ts +7 -0
  21. package/dist/compat/workspaceSyncV3OperationCompat.js +30 -0
  22. package/dist/components/activity/EntityActivityTimeline.d.ts +10 -2
  23. package/dist/components/activity/EntityActivityTimeline.js +83 -35
  24. package/dist/components/context/AttachmentPreviewHost.d.ts +6 -0
  25. package/dist/components/context/AttachmentPreviewHost.js +222 -0
  26. package/dist/components/context/ContextAttachmentManager.d.ts +7 -0
  27. package/dist/components/context/ContextAttachmentManager.js +514 -208
  28. package/dist/components/features/AiProfilesModule.d.ts +24 -0
  29. package/dist/components/features/AiProfilesModule.js +744 -0
  30. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +4 -1
  31. package/dist/components/features/AnnotatedAttachmentWorkspace.js +351 -79
  32. package/dist/components/features/DocumentGenerateModal.js +23 -5
  33. package/dist/components/features/DocumentIndex.d.ts +19 -1
  34. package/dist/components/features/DocumentIndex.js +104 -15
  35. package/dist/components/features/DocumentViewer.d.ts +9 -1
  36. package/dist/components/features/DocumentViewer.js +721 -100
  37. package/dist/components/features/DocumentWorkspace.d.ts +37 -2
  38. package/dist/components/features/DocumentWorkspace.js +21 -6
  39. package/dist/components/features/TaskSettings.d.ts +6 -27
  40. package/dist/components/features/TaskSettings.js +232 -143
  41. package/dist/components/features/TaskforceAgentsModule.d.ts +36 -0
  42. package/dist/components/features/TaskforceAgentsModule.js +1782 -0
  43. package/dist/components/features/agentBehavior/AgentBehaviorManagerShared.d.ts +94 -0
  44. package/dist/components/features/agentBehavior/AgentBehaviorManagerShared.js +70 -0
  45. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +65 -0
  46. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +115 -0
  47. package/dist/components/features/agentRoles/RoleManagerPanel.d.ts +4 -0
  48. package/dist/components/features/agentRoles/RoleManagerPanel.js +382 -0
  49. package/dist/components/features/agentSkills/SkillManagerPanel.d.ts +5 -0
  50. package/dist/components/features/agentSkills/SkillManagerPanel.js +355 -0
  51. package/dist/components/features/documentWorkspaceModel.d.ts +16 -4
  52. package/dist/components/features/documentWorkspaceModel.js +30 -5
  53. package/dist/components/features/planning/PlanningArchiveConfirmation.d.ts +9 -0
  54. package/dist/components/features/planning/PlanningArchiveConfirmation.js +19 -0
  55. package/dist/components/features/planning/PlanningCardIdentity.d.ts +12 -0
  56. package/dist/components/features/planning/PlanningCardIdentity.js +44 -0
  57. package/dist/components/features/planning/PlanningEntityDetails.d.ts +36 -0
  58. package/dist/components/features/planning/PlanningEntityDetails.js +131 -0
  59. package/dist/components/features/planning/PlanningEntitySummary.d.ts +46 -0
  60. package/dist/components/features/planning/PlanningEntitySummary.js +98 -0
  61. package/dist/components/features/planning/PlanningLinkPicker.d.ts +11 -0
  62. package/dist/components/features/planning/PlanningLinkPicker.js +28 -0
  63. package/dist/components/features/planning/PlanningModule.d.ts +6 -0
  64. package/dist/components/features/planning/PlanningModule.js +588 -0
  65. package/dist/components/features/planning/PlanningOwnerDropdown.d.ts +27 -0
  66. package/dist/components/features/planning/PlanningOwnerDropdown.js +80 -0
  67. package/dist/components/features/planning/PlanningTaskArrangeControl.d.ts +5 -0
  68. package/dist/components/features/planning/PlanningTaskArrangeControl.js +11 -0
  69. package/dist/components/features/planning/PlanningTaskCard.d.ts +20 -0
  70. package/dist/components/features/planning/PlanningTaskCard.js +26 -0
  71. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +10 -0
  72. package/dist/components/features/planning/PlanningTaskOrderList.js +52 -0
  73. package/dist/components/features/planning/PlanningUnlinkConfirmation.d.ts +15 -0
  74. package/dist/components/features/planning/PlanningUnlinkConfirmation.js +7 -0
  75. package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
  76. package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
  77. package/dist/components/features/planning/planningCreateIntent.d.ts +10 -0
  78. package/dist/components/features/planning/planningCreateIntent.js +16 -0
  79. package/dist/components/features/planning/planningNavigator.d.ts +33 -0
  80. package/dist/components/features/planning/planningNavigator.js +96 -0
  81. package/dist/components/features/planning/planningTaskArrangement.d.ts +18 -0
  82. package/dist/components/features/planning/planningTaskArrangement.js +106 -0
  83. package/dist/components/features/planning/planningWorkspaceModel.d.ts +132 -0
  84. package/dist/components/features/planning/planningWorkspaceModel.js +5 -0
  85. package/dist/components/features/settings/CategoryManager.js +2 -2
  86. package/dist/components/features/settings/TaxonomyEditor.js +1 -1
  87. package/dist/components/features/settings/TaxonomyManager.js +1 -1
  88. package/dist/components/features/settings/TypeManager.js +1 -1
  89. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.d.ts +10 -0
  90. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +175 -0
  91. package/dist/components/features/taskforceAgentAssignments/agentBehaviorCatalogApi.d.ts +27 -0
  92. package/dist/components/features/taskforceAgentAssignments/agentBehaviorCatalogApi.js +24 -0
  93. package/dist/components/features/taskforceAgentEditorModel.d.ts +109 -0
  94. package/dist/components/features/taskforceAgentEditorModel.js +145 -0
  95. package/dist/components/features/useDocumentWorkspaceController.d.ts +20 -1
  96. package/dist/components/features/useDocumentWorkspaceController.js +106 -21
  97. package/dist/components/features/workflowManager/WorkflowManagerModule.d.ts +11 -0
  98. package/dist/components/features/workflowManager/WorkflowManagerModule.js +313 -0
  99. package/dist/components/features/workflowManager/WorkflowPublishDialog.d.ts +11 -0
  100. package/dist/components/features/workflowManager/WorkflowPublishDialog.js +8 -0
  101. package/dist/components/features/workflowManager/types.d.ts +74 -0
  102. package/dist/components/features/workflowManager/types.js +1 -0
  103. package/dist/components/features/workflowManager/useWorkflowManager.d.ts +30 -0
  104. package/dist/components/features/workflowManager/useWorkflowManager.js +213 -0
  105. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +52 -0
  106. package/dist/components/features/workflowManager/workflowManagerApi.js +142 -0
  107. package/dist/components/task/TaskActionHeader.d.ts +7 -3
  108. package/dist/components/task/TaskActionHeader.js +46 -53
  109. package/dist/components/task/TaskCard.d.ts +10 -2
  110. package/dist/components/task/TaskCard.js +138 -56
  111. package/dist/components/task/TaskContextUpload.d.ts +4 -0
  112. package/dist/components/task/TaskContextUpload.js +3 -2
  113. package/dist/components/task/TaskForm.d.ts +16 -17
  114. package/dist/components/task/TaskForm.js +569 -199
  115. package/dist/components/task/TaskImageReviews.d.ts +8 -0
  116. package/dist/components/task/TaskImageReviews.js +47 -0
  117. package/dist/components/task/TaskKanban.d.ts +9 -10
  118. package/dist/components/task/TaskKanban.js +70 -18
  119. package/dist/components/task/TaskList.d.ts +9 -8
  120. package/dist/components/task/TaskList.js +46 -32
  121. package/dist/components/task/TaskReferenceBadge.d.ts +2 -1
  122. package/dist/components/task/TaskReferenceBadge.js +3 -2
  123. package/dist/components/task/TaskStatusActions.d.ts +3 -1
  124. package/dist/components/task/TaskStatusActions.js +27 -7
  125. package/dist/components/task/TaskWorkflowAssignmentField.d.ts +18 -0
  126. package/dist/components/task/TaskWorkflowAssignmentField.js +362 -0
  127. package/dist/components/task/TaskWorkstreamPicker.d.ts +8 -0
  128. package/dist/components/task/TaskWorkstreamPicker.js +25 -0
  129. package/dist/components/task/TrashRestoreControls.d.ts +18 -0
  130. package/dist/components/task/TrashRestoreControls.js +71 -0
  131. package/dist/components/ui/AiIdentityRosterCard.d.ts +20 -0
  132. package/dist/components/ui/AiIdentityRosterCard.js +5 -0
  133. package/dist/components/ui/AssetTraySortControl.d.ts +10 -0
  134. package/dist/components/ui/AssetTraySortControl.js +38 -0
  135. package/dist/components/ui/AssigneeIdentity.d.ts +12 -0
  136. package/dist/components/ui/AssigneeIdentity.js +41 -0
  137. package/dist/components/ui/DiscardChangesDialog.d.ts +10 -0
  138. package/dist/components/ui/DiscardChangesDialog.js +7 -0
  139. package/dist/components/ui/DisclosureSectionHeader.d.ts +4 -1
  140. package/dist/components/ui/DisclosureSectionHeader.js +2 -2
  141. package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
  142. package/dist/components/ui/DocumentTypeIcon.js +8 -0
  143. package/dist/components/ui/EditableAvatarButton.d.ts +6 -1
  144. package/dist/components/ui/EditableAvatarButton.js +6 -5
  145. package/dist/components/ui/HierarchyActionBadge.d.ts +2 -1
  146. package/dist/components/ui/HierarchyActionBadge.js +2 -2
  147. package/dist/components/ui/Markdown.d.ts +13 -3
  148. package/dist/components/ui/Markdown.fixture.d.ts +1 -0
  149. package/dist/components/ui/Markdown.fixture.js +23 -0
  150. package/dist/components/ui/Markdown.js +158 -68
  151. package/dist/components/ui/Modal.d.ts +3 -1
  152. package/dist/components/ui/Modal.js +85 -19
  153. package/dist/components/ui/MultiSelectFilter.d.ts +9 -2
  154. package/dist/components/ui/MultiSelectFilter.js +26 -5
  155. package/dist/components/ui/ReferenceBadgeButton.js +2 -3
  156. package/dist/components/ui/TaxonomyDropdown.d.ts +18 -1
  157. package/dist/components/ui/TaxonomyDropdown.js +177 -59
  158. package/dist/components/ui/TopNoticeLayer.d.ts +2 -1
  159. package/dist/components/ui/TopNoticeLayer.js +5 -2
  160. package/dist/components/ui/useFallbackImageUrl.d.ts +4 -0
  161. package/dist/components/ui/useFallbackImageUrl.js +20 -0
  162. package/dist/components/views/AppShellHeader.js +2 -2
  163. package/dist/components/views/StandaloneLayout.d.ts +1 -0
  164. package/dist/components/views/StandaloneLayout.js +1717 -600
  165. package/dist/components/views/WidgetView.d.ts +1 -0
  166. package/dist/components/views/WidgetView.js +99 -31
  167. package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +4 -2
  168. package/dist/components/views/chrome/WorkspaceChromeSections.js +3 -6
  169. package/dist/components/views/chrome/workspaceChrome.d.ts +5 -8
  170. package/dist/components/views/chrome/workspaceChrome.js +62 -27
  171. package/dist/components/views/panels/FilterToolbar.d.ts +4 -3
  172. package/dist/components/views/panels/FilterToolbar.js +8 -5
  173. package/dist/components/views/panels/FilterToolbarControls.d.ts +11 -2
  174. package/dist/components/views/panels/FilterToolbarControls.js +35 -20
  175. package/dist/components/views/panels/PlanningDrawer.d.ts +66 -49
  176. package/dist/components/views/panels/PlanningDrawer.js +983 -314
  177. package/dist/components/views/planningScope.js +7 -1
  178. package/dist/components/views/standalone/modals/AccountSettingsModal.d.ts +62 -0
  179. package/dist/components/views/standalone/modals/AccountSettingsModal.js +197 -0
  180. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +7 -2
  181. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +56 -9
  182. package/dist/components/views/standalone/modals/HelpModal.d.ts +1 -2
  183. package/dist/components/views/standalone/modals/HelpModal.js +3 -4
  184. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +8 -9
  185. package/dist/components/views/standalone/modals/SyncStatusModal.js +85 -25
  186. package/dist/components/views/standalone/modals/TeamManagementModal.js +1 -1
  187. package/dist/config/applicationBaseUrl.d.ts +2 -0
  188. package/dist/config/applicationBaseUrl.js +23 -0
  189. package/dist/config/envSchema.d.ts +1 -1
  190. package/dist/config/envSchema.js +167 -5
  191. package/dist/config/localServiceCloudTarget.d.ts +10 -0
  192. package/dist/config/localServiceCloudTarget.js +76 -0
  193. package/dist/core/AdminAuditRetentionService.d.ts +43 -0
  194. package/dist/core/AdminAuditRetentionService.js +126 -0
  195. package/dist/core/AiProfileService.d.ts +35 -0
  196. package/dist/core/AiProfileService.js +511 -251
  197. package/dist/core/AttachmentLinkService.d.ts +10 -2
  198. package/dist/core/AttachmentLinkService.js +50 -15
  199. package/dist/core/AuthIdentityService.d.ts +6 -0
  200. package/dist/core/AuthIdentityService.js +38 -0
  201. package/dist/core/AuthTokenService.d.ts +1 -0
  202. package/dist/core/AuthTokenService.js +13 -0
  203. package/dist/core/DeletedTaskLifecycleService.d.ts +8 -2
  204. package/dist/core/DeletedTaskLifecycleService.js +145 -38
  205. package/dist/core/GlobalSettingsService.d.ts +3 -1
  206. package/dist/core/GlobalSettingsService.js +30 -4
  207. package/dist/core/InitiativeDurableMutationService.d.ts +89 -0
  208. package/dist/core/InitiativeDurableMutationService.js +187 -0
  209. package/dist/core/McpTokenService.d.ts +5 -0
  210. package/dist/core/McpTokenService.js +91 -13
  211. package/dist/core/PlanningCommandPreparationService.d.ts +60 -0
  212. package/dist/core/PlanningCommandPreparationService.js +149 -0
  213. package/dist/core/ScheduleCommandService.d.ts +76 -0
  214. package/dist/core/ScheduleCommandService.js +165 -0
  215. package/dist/core/SyncReconciliationService.d.ts +29 -6
  216. package/dist/core/SyncReconciliationService.js +256 -84
  217. package/dist/core/TaskActivityService.d.ts +22 -2
  218. package/dist/core/TaskActivityService.js +177 -29
  219. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +36 -0
  220. package/dist/core/TaskAttachmentLinksDurableMutationService.js +240 -0
  221. package/dist/core/TaskChecklistCommandService.d.ts +50 -0
  222. package/dist/core/TaskChecklistCommandService.js +111 -0
  223. package/dist/core/TaskDurableCreateMutationService.d.ts +38 -0
  224. package/dist/core/TaskDurableCreateMutationService.js +85 -0
  225. package/dist/core/TaskDurableDeleteMutationService.d.ts +47 -0
  226. package/dist/core/TaskDurableDeleteMutationService.js +54 -0
  227. package/dist/core/TaskDurableLifecycleMutationService.d.ts +38 -0
  228. package/dist/core/TaskDurableLifecycleMutationService.js +42 -0
  229. package/dist/core/TaskDurableRelationshipMutationService.d.ts +58 -0
  230. package/dist/core/TaskDurableRelationshipMutationService.js +66 -0
  231. package/dist/core/TaskDurableRestoreMutationService.d.ts +31 -0
  232. package/dist/core/TaskDurableRestoreMutationService.js +33 -0
  233. package/dist/core/TaskDurableStatusMutationService.d.ts +74 -0
  234. package/dist/core/TaskDurableStatusMutationService.js +247 -0
  235. package/dist/core/TaskDurableSyncMutationService.d.ts +34 -0
  236. package/dist/core/TaskDurableSyncMutationService.js +70 -0
  237. package/dist/core/TaskDurableWorkflowMutationService.d.ts +48 -0
  238. package/dist/core/TaskDurableWorkflowMutationService.js +59 -0
  239. package/dist/core/TaskLifecycleCommandService.d.ts +101 -0
  240. package/dist/core/TaskLifecycleCommandService.js +161 -0
  241. package/dist/core/TaskRootCommandPreparationService.d.ts +35 -0
  242. package/dist/core/TaskRootCommandPreparationService.js +103 -0
  243. package/dist/core/Taskforce.d.ts +542 -60
  244. package/dist/core/Taskforce.js +4220 -905
  245. package/dist/core/WorkflowAssignmentService.d.ts +40 -0
  246. package/dist/core/WorkflowAssignmentService.js +158 -0
  247. package/dist/core/WorkflowExecutionService.d.ts +69 -0
  248. package/dist/core/WorkflowExecutionService.js +342 -0
  249. package/dist/core/WorkflowTaskActivationService.d.ts +32 -0
  250. package/dist/core/WorkflowTaskActivationService.js +63 -0
  251. package/dist/core/WorkflowTemplateService.d.ts +64 -0
  252. package/dist/core/WorkflowTemplateService.js +223 -0
  253. package/dist/core/WorkspaceLifecycleService.d.ts +1 -0
  254. package/dist/core/WorkspaceLifecycleService.js +18 -0
  255. package/dist/core/WorkstreamDurableMutationService.d.ts +90 -0
  256. package/dist/core/WorkstreamDurableMutationService.js +184 -0
  257. package/dist/core/planningReferencePolicy.d.ts +14 -0
  258. package/dist/core/planningReferencePolicy.js +53 -0
  259. package/dist/core/taskReferencePolicy.js +24 -3
  260. package/dist/core/types.d.ts +12 -11
  261. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +33 -2
  262. package/dist/documentReviews/DocumentReviewCommentStore.js +125 -8
  263. package/dist/documentReviews/commandService.d.ts +51 -0
  264. package/dist/documentReviews/commandService.js +63 -0
  265. package/dist/documentReviews/service.d.ts +24 -1
  266. package/dist/documentReviews/service.js +354 -49
  267. package/dist/documentReviews/types.d.ts +18 -1
  268. package/dist/hooks/sync/bootstrap.d.ts +3 -7
  269. package/dist/hooks/sync/bootstrap.js +6 -14
  270. package/dist/hooks/sync/browserSyncAuthority.d.ts +21 -0
  271. package/dist/hooks/sync/browserSyncAuthority.js +70 -0
  272. package/dist/hooks/sync/browserSyncRemoteServices.d.ts +29 -0
  273. package/dist/hooks/sync/browserSyncRemoteServices.js +58 -0
  274. package/dist/hooks/sync/controlPlane.d.ts +1 -37
  275. package/dist/hooks/sync/controlPlane.js +1 -78
  276. package/dist/hooks/sync/lifecyclePolicy.d.ts +1 -45
  277. package/dist/hooks/sync/lifecyclePolicy.js +1 -93
  278. package/dist/hooks/sync/orchestratorShared.d.ts +9 -3
  279. package/dist/hooks/sync/orchestratorShared.js +70 -96
  280. package/dist/hooks/sync/pullLifecycle.d.ts +1 -31
  281. package/dist/hooks/sync/pullLifecycle.js +1 -24
  282. package/dist/hooks/sync/realtime.d.ts +4 -1
  283. package/dist/hooks/sync/realtime.js +103 -3
  284. package/dist/hooks/sync/recovery.d.ts +1 -84
  285. package/dist/hooks/sync/recovery.js +1 -245
  286. package/dist/hooks/sync/transfers.d.ts +8 -129
  287. package/dist/hooks/sync/transfers.js +19 -581
  288. package/dist/hooks/sync/useDataVersionRefresh.d.ts +6 -1
  289. package/dist/hooks/sync/useDataVersionRefresh.js +127 -12
  290. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +14 -0
  291. package/dist/hooks/sync/useDurableLocalOutboxDrain.js +208 -0
  292. package/dist/hooks/sync/useDurableTaskCreateMutation.d.ts +15 -0
  293. package/dist/hooks/sync/useDurableTaskCreateMutation.js +152 -0
  294. package/dist/hooks/sync/useDurableTaskDeleteMutation.d.ts +11 -0
  295. package/dist/hooks/sync/useDurableTaskDeleteMutation.js +21 -0
  296. package/dist/hooks/sync/useDurableTaskLifecycleMutation.d.ts +12 -0
  297. package/dist/hooks/sync/useDurableTaskLifecycleMutation.js +22 -0
  298. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +14 -0
  299. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +24 -0
  300. package/dist/hooks/sync/useDurableTaskRestoreMutation.d.ts +12 -0
  301. package/dist/hooks/sync/useDurableTaskRestoreMutation.js +24 -0
  302. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +18 -0
  303. package/dist/hooks/sync/useDurableTaskStatusMutation.js +23 -0
  304. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +23 -0
  305. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +414 -0
  306. package/dist/hooks/sync/useSyncStatusActions.d.ts +2 -1
  307. package/dist/hooks/sync/useSyncStatusActions.js +8 -3
  308. package/dist/hooks/tasks/taskHttpMutation.d.ts +25 -0
  309. package/dist/hooks/tasks/taskHttpMutation.js +134 -0
  310. package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +6 -1
  311. package/dist/hooks/tasks/useCurrentTaskRelations.js +32 -6
  312. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +4 -3
  313. package/dist/hooks/tasks/useTaskEditorNavigation.js +9 -13
  314. package/dist/hooks/tasks/useTaskFormActions.d.ts +20 -2
  315. package/dist/hooks/tasks/useTaskFormActions.js +339 -59
  316. package/dist/hooks/tasks/useTaskReferenceContract.d.ts +5 -0
  317. package/dist/hooks/tasks/useTaskReferenceContract.js +17 -0
  318. package/dist/hooks/tasks/useTaskRelationships.d.ts +1 -3
  319. package/dist/hooks/tasks/useTaskRelationships.js +5 -25
  320. package/dist/hooks/tasks/useTrashSelection.d.ts +12 -0
  321. package/dist/hooks/tasks/useTrashSelection.js +49 -0
  322. package/dist/hooks/ui/useInitiativeTemplates.d.ts +24 -0
  323. package/dist/hooks/ui/useInitiativeTemplates.js +22 -0
  324. package/dist/hooks/ui/useSettingsModel.d.ts +5 -29
  325. package/dist/hooks/ui/useSettingsModel.js +31 -15
  326. package/dist/hooks/ui/useSettingsPersistence.d.ts +0 -1
  327. package/dist/hooks/ui/useSettingsPersistence.js +4 -8
  328. package/dist/hooks/ui/useSettingsTaxonomyManagement.js +31 -0
  329. package/dist/hooks/useFilterSort.d.ts +2 -2
  330. package/dist/hooks/useFilterSort.js +19 -15
  331. package/dist/hooks/useRealtimeSync.d.ts +10 -0
  332. package/dist/hooks/useRealtimeSync.js +57 -4
  333. package/dist/hooks/useSyncOrchestrator.d.ts +32 -1
  334. package/dist/hooks/useSyncOrchestrator.js +963 -287
  335. package/dist/hooks/useTaskData.d.ts +11 -2
  336. package/dist/hooks/useTaskData.js +59 -26
  337. package/dist/hooks/useTaskMutations.d.ts +42 -5
  338. package/dist/hooks/useTaskMutations.js +750 -125
  339. package/dist/hooks/useTaskforce.d.ts +79 -74
  340. package/dist/hooks/useTaskforce.js +1205 -450
  341. package/dist/hooks/useUiNotice.d.ts +5 -1
  342. package/dist/hooks/useUiNotice.js +13 -2
  343. package/dist/hooks/useWorkspaceSyncController.d.ts +9 -0
  344. package/dist/hooks/useWorkspaceSyncController.js +159 -17
  345. package/dist/hooks/workspace/usePersistedAppUiState.d.ts +74 -0
  346. package/dist/hooks/workspace/usePersistedAppUiState.js +325 -0
  347. package/dist/hooks/workspace/usePersistedLayoutUiState.d.ts +76 -0
  348. package/dist/hooks/workspace/usePersistedLayoutUiState.js +479 -0
  349. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +2 -7
  350. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +42 -31
  351. package/dist/hooks/workspace/workspaceLocalState.d.ts +17 -6
  352. package/dist/hooks/workspace/workspaceLocalState.js +175 -5
  353. package/dist/hooks/workstreams/workstreamHttpMutation.d.ts +23 -0
  354. package/dist/hooks/workstreams/workstreamHttpMutation.js +134 -0
  355. package/dist/localization/locales/en-US.d.ts +3 -3
  356. package/dist/localization/locales/en-US.js +3 -3
  357. package/dist/localization/locales/es-419.js +3 -3
  358. package/dist/localization/locales/pt-BR.js +3 -3
  359. package/dist/mcp/adminWorkspaceRegistrar.js +2 -30
  360. package/dist/mcp/aiProfileBootstrap.d.ts +3 -0
  361. package/dist/mcp/aiProfileBootstrap.js +4 -0
  362. package/dist/mcp/canonicalAssetHelpers.d.ts +29 -4
  363. package/dist/mcp/canonicalAssetHelpers.js +138 -35
  364. package/dist/mcp/clientIntegrations.d.ts +4 -2
  365. package/dist/mcp/clientIntegrations.js +58 -57
  366. package/dist/mcp/clientRegistry.d.ts +30 -0
  367. package/dist/mcp/clientRegistry.js +134 -0
  368. package/dist/mcp/collaborationRegistrar.js +31 -15
  369. package/dist/mcp/documentAssetRegistrar.js +231 -56
  370. package/dist/mcp/documentContentCommand.d.ts +94 -0
  371. package/dist/mcp/documentContentCommand.js +226 -0
  372. package/dist/mcp/documentHelpers.d.ts +13 -65
  373. package/dist/mcp/documentHelpers.js +49 -62
  374. package/dist/mcp/durableTaskMutationRouter.d.ts +65 -0
  375. package/dist/mcp/durableTaskMutationRouter.js +217 -0
  376. package/dist/mcp/durableTaskRelationshipMutationRouter.d.ts +38 -0
  377. package/dist/mcp/durableTaskRelationshipMutationRouter.js +168 -0
  378. package/dist/mcp/durableTaskRootMutationRouter.d.ts +64 -0
  379. package/dist/mcp/durableTaskRootMutationRouter.js +226 -0
  380. package/dist/mcp/gitWorktreeRoots.d.ts +2 -0
  381. package/dist/mcp/gitWorktreeRoots.js +19 -0
  382. package/dist/mcp/legacyServer.d.ts +1 -0
  383. package/dist/mcp/legacyServer.js +42 -0
  384. package/dist/mcp/localCliHealth.d.ts +56 -0
  385. package/dist/mcp/localCliHealth.js +170 -0
  386. package/dist/mcp/localServiceProxy.d.ts +23 -0
  387. package/dist/mcp/localServiceProxy.js +258 -0
  388. package/dist/mcp/mcpInputValidator.d.ts +17 -0
  389. package/dist/mcp/mcpInputValidator.js +58 -0
  390. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +127 -0
  391. package/dist/mcp/planningAttachmentCommandAdapter.js +188 -0
  392. package/dist/mcp/programScaffoldCommandAdapter.d.ts +6 -0
  393. package/dist/mcp/programScaffoldCommandAdapter.js +39 -0
  394. package/dist/mcp/proxyServer.d.ts +1 -0
  395. package/dist/mcp/proxyServer.js +2 -0
  396. package/dist/mcp/runtime.d.ts +98 -1
  397. package/dist/mcp/runtime.js +4682 -1927
  398. package/dist/mcp/server.js +29 -2
  399. package/dist/mcp/sharedLocalServiceGateD.d.ts +115 -0
  400. package/dist/mcp/sharedLocalServiceGateD.js +344 -0
  401. package/dist/mcp/stdioLifecycle.d.ts +22 -0
  402. package/dist/mcp/stdioLifecycle.js +54 -0
  403. package/dist/mcp/taskAttachmentCommandAdapter.d.ts +192 -0
  404. package/dist/mcp/taskAttachmentCommandAdapter.js +470 -0
  405. package/dist/mcp/taskAttachmentHelpers.d.ts +8 -6
  406. package/dist/mcp/taskAttachmentHelpers.js +74 -2
  407. package/dist/mcp/taskAttachmentTypes.d.ts +26 -5
  408. package/dist/mcp/taskPlanCommand.d.ts +64 -0
  409. package/dist/mcp/taskPlanCommand.js +98 -0
  410. package/dist/mcp/taskPlanningRegistrar.js +240 -44
  411. package/dist/mcp/toolCallCompatibility.d.ts +6 -0
  412. package/dist/mcp/toolCallCompatibility.js +16 -0
  413. package/dist/mcp/toolCatalog.d.ts +3 -1
  414. package/dist/mcp/toolProfiles.d.ts +12 -1
  415. package/dist/mcp/toolProfiles.js +43 -0
  416. package/dist/mcp/toolRegistry.d.ts +17 -2
  417. package/dist/mcp/toolRegistry.js +26 -11
  418. package/dist/mcp/workflowExecutionRegistrar.d.ts +2 -0
  419. package/dist/mcp/workflowExecutionRegistrar.js +51 -0
  420. package/dist/migrations/taskSchemaMigrations.d.ts +35 -0
  421. package/dist/migrations/taskSchemaMigrations.js +1892 -64
  422. package/dist/migrations/taskUpdatedAtSyncDriftMigration.d.ts +20 -0
  423. package/dist/migrations/taskUpdatedAtSyncDriftMigration.js +153 -0
  424. package/dist/migrations/taskforceAgentDefinitionMigration.d.ts +26 -0
  425. package/dist/migrations/taskforceAgentDefinitionMigration.js +116 -0
  426. package/dist/plugins/vite.js +48 -17
  427. package/dist/public/Taskforce_Van.webp +0 -0
  428. package/dist/runtime/appGateDefinitions.d.ts +16 -10
  429. package/dist/runtime/appGateDefinitions.js +16 -10
  430. package/dist/runtime/appGates.d.ts +5 -4
  431. package/dist/runtime/appGates.js +4 -3
  432. package/dist/server/aiProfileAvatarAssets.d.ts +11 -8
  433. package/dist/server/aiProfileAvatarAssets.js +159 -70
  434. package/dist/server/appAccess.d.ts +12 -0
  435. package/dist/server/appAccess.js +21 -0
  436. package/dist/server/auth.js +15 -1
  437. package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
  438. package/dist/server/authorizedWorkspaceAccess.js +40 -0
  439. package/dist/server/cloudCollectionRead.d.ts +25 -0
  440. package/dist/server/cloudCollectionRead.js +120 -0
  441. package/dist/server/cloudCollectionReadPool.d.ts +52 -0
  442. package/dist/server/cloudCollectionReadPool.js +140 -0
  443. package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
  444. package/dist/server/cloudCollectionReadWorker.js +36 -0
  445. package/dist/server/cors.d.ts +2 -1
  446. package/dist/server/cors.js +45 -8
  447. package/dist/server/email.d.ts +3 -1
  448. package/dist/server/email.js +46 -8
  449. package/dist/server/index.d.ts +27 -12
  450. package/dist/server/index.js +395 -86
  451. package/dist/server/localDataOwnerPermit.d.ts +18 -0
  452. package/dist/server/localDataOwnerPermit.js +58 -0
  453. package/dist/server/localDatabaseIdentity.d.ts +14 -0
  454. package/dist/server/localDatabaseIdentity.js +69 -0
  455. package/dist/server/localRealtimeFileInvalidation.d.ts +1 -0
  456. package/dist/server/localRealtimeFileInvalidation.js +7 -0
  457. package/dist/server/localServiceLease.d.ts +65 -0
  458. package/dist/server/localServiceLease.js +485 -0
  459. package/dist/server/localServiceOwnershipBootstrap.d.ts +19 -0
  460. package/dist/server/localServiceOwnershipBootstrap.js +84 -0
  461. package/dist/server/localServiceSessions.d.ts +87 -0
  462. package/dist/server/localServiceSessions.js +309 -0
  463. package/dist/server/localServiceWindowsAcl.d.ts +8 -0
  464. package/dist/server/localServiceWindowsAcl.js +60 -0
  465. package/dist/server/localSyncProcessLockBootstrap.d.ts +3 -0
  466. package/dist/server/localSyncProcessLockBootstrap.js +16 -0
  467. package/dist/server/localWorkspaceSyncServerComposition.d.ts +59 -0
  468. package/dist/server/localWorkspaceSyncServerComposition.js +91 -0
  469. package/dist/server/localWorkspaceSyncServerRuntime.d.ts +119 -0
  470. package/dist/server/localWorkspaceSyncServerRuntime.js +1163 -0
  471. package/dist/server/rateLimit.d.ts +1 -0
  472. package/dist/server/rateLimit.js +16 -0
  473. package/dist/server/routes/admin.d.ts +2 -4
  474. package/dist/server/routes/admin.js +199 -337
  475. package/dist/server/routes/agentRoles.d.ts +13 -0
  476. package/dist/server/routes/agentRoles.js +273 -0
  477. package/dist/server/routes/agentSkills.d.ts +16 -0
  478. package/dist/server/routes/agentSkills.js +291 -0
  479. package/dist/server/routes/agents.d.ts +49 -0
  480. package/dist/server/routes/agents.js +1455 -0
  481. package/dist/server/routes/annotatedAttachments.js +46 -9
  482. package/dist/server/routes/assetAccess.d.ts +36 -0
  483. package/dist/server/routes/assetAccess.js +93 -0
  484. package/dist/server/routes/auth.d.ts +4 -3
  485. package/dist/server/routes/auth.js +236 -21
  486. package/dist/server/routes/authSupport.d.ts +3 -1
  487. package/dist/server/routes/authSupport.js +22 -8
  488. package/dist/server/routes/documentReviews.d.ts +2 -0
  489. package/dist/server/routes/documentReviews.js +155 -15
  490. package/dist/server/routes/documents.d.ts +6 -2
  491. package/dist/server/routes/documents.js +492 -151
  492. package/dist/server/routes/durableTaskHttpRouters.d.ts +167 -0
  493. package/dist/server/routes/durableTaskHttpRouters.js +89 -0
  494. package/dist/server/routes/localMcpHealth.d.ts +11 -0
  495. package/dist/server/routes/localMcpHealth.js +29 -0
  496. package/dist/server/routes/localService.d.ts +13 -0
  497. package/dist/server/routes/localService.js +446 -0
  498. package/dist/server/routes/localUpdate.d.ts +11 -0
  499. package/dist/server/routes/localUpdate.js +154 -0
  500. package/dist/server/routes/primitives.d.ts +29 -0
  501. package/dist/server/routes/primitives.js +18 -0
  502. package/dist/server/routes/resources.d.ts +1 -10
  503. package/dist/server/routes/resources.js +1 -153
  504. package/dist/server/routes/shared.d.ts +55 -2
  505. package/dist/server/routes/shared.js +506 -16
  506. package/dist/server/routes/sync.d.ts +2 -0
  507. package/dist/server/routes/sync.js +206 -272
  508. package/dist/server/routes/syncAuxRoutes.d.ts +3 -1
  509. package/dist/server/routes/syncAuxRoutes.js +9 -4
  510. package/dist/server/routes/syncCoordinatorLocalRoutes.d.ts +6 -0
  511. package/dist/server/routes/syncCoordinatorLocalRoutes.js +867 -0
  512. package/dist/server/routes/syncPullApplyRoutes.d.ts +29 -1
  513. package/dist/server/routes/syncPullApplyRoutes.js +520 -17
  514. package/dist/server/routes/syncPushRoutes.d.ts +33 -4
  515. package/dist/server/routes/syncPushRoutes.js +251 -62
  516. package/dist/server/routes/syncRouteTypes.d.ts +1 -1
  517. package/dist/server/routes/syncSnapshotRoutes.d.ts +15 -7
  518. package/dist/server/routes/syncSnapshotRoutes.js +95 -17
  519. package/dist/server/routes/syncV3DiagnosticsRoutes.d.ts +14 -0
  520. package/dist/server/routes/syncV3DiagnosticsRoutes.js +72 -0
  521. package/dist/server/routes/syncV3FeedRoutes.d.ts +20 -0
  522. package/dist/server/routes/syncV3FeedRoutes.js +464 -0
  523. package/dist/server/routes/syncV3LocalCaptureRoutes.d.ts +37 -0
  524. package/dist/server/routes/syncV3LocalCaptureRoutes.js +915 -0
  525. package/dist/server/routes/syncV3LocalDispatchRoutes.d.ts +17 -0
  526. package/dist/server/routes/syncV3LocalDispatchRoutes.js +280 -0
  527. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +17 -0
  528. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +493 -0
  529. package/dist/server/routes/syncV3LocalOwnershipRoutes.d.ts +10 -0
  530. package/dist/server/routes/syncV3LocalOwnershipRoutes.js +51 -0
  531. package/dist/server/routes/syncV3LocalRecoveryRoutes.d.ts +12 -0
  532. package/dist/server/routes/syncV3LocalRecoveryRoutes.js +78 -0
  533. package/dist/server/routes/syncV3OperationRoutes.d.ts +35 -0
  534. package/dist/server/routes/syncV3OperationRoutes.js +1151 -0
  535. package/dist/server/routes/tasks.d.ts +0 -2
  536. package/dist/server/routes/tasks.js +1083 -236
  537. package/dist/server/routes/workflows.d.ts +26 -0
  538. package/dist/server/routes/workflows.js +500 -0
  539. package/dist/server/routes.d.ts +1 -6
  540. package/dist/server/routes.js +179 -342
  541. package/dist/server/smtpTransport.d.ts +11 -3
  542. package/dist/server/smtpTransport.js +9 -2
  543. package/dist/server/start.js +42 -10
  544. package/dist/service/localServiceCli.d.ts +33 -0
  545. package/dist/service/localServiceCli.js +376 -0
  546. package/dist/service/localServiceClientLifecycle.d.ts +25 -0
  547. package/dist/service/localServiceClientLifecycle.js +189 -0
  548. package/dist/service/localServiceOpen.d.ts +17 -0
  549. package/dist/service/localServiceOpen.js +27 -0
  550. package/dist/services/agentRoleResolver.d.ts +4 -0
  551. package/dist/services/agentRoleResolver.js +7 -0
  552. package/dist/services/aiProfileAvatarGenerationService.d.ts +41 -0
  553. package/dist/services/aiProfileAvatarGenerationService.js +158 -0
  554. package/dist/services/avatarImageProvider.d.ts +33 -0
  555. package/dist/services/avatarImageProvider.js +140 -0
  556. package/dist/services/bedrockAnthropicMessagesModelGateway.d.ts +24 -0
  557. package/dist/services/bedrockAnthropicMessagesModelGateway.js +95 -0
  558. package/dist/services/bedrockMantleModelGateway.d.ts +43 -0
  559. package/dist/services/bedrockMantleModelGateway.js +81 -0
  560. package/dist/services/bedrockModelGateway.d.ts +26 -0
  561. package/dist/services/bedrockModelGateway.js +94 -0
  562. package/dist/services/modelGateway.d.ts +82 -0
  563. package/dist/services/modelGateway.js +61 -0
  564. package/dist/services/taskforceAgentAvatarImageProvider.d.ts +8 -0
  565. package/dist/services/taskforceAgentAvatarImageProvider.js +24 -0
  566. package/dist/services/taskforceAgentMcpBridge.d.ts +77 -0
  567. package/dist/services/taskforceAgentMcpBridge.js +527 -0
  568. package/dist/shared/agentRoleDefinition.d.ts +34 -0
  569. package/dist/shared/agentRoleDefinition.js +207 -0
  570. package/dist/shared/aiProfileAvatarEligibility.d.ts +10 -0
  571. package/dist/shared/aiProfileAvatarEligibility.js +27 -0
  572. package/dist/shared/aiProfileColors.d.ts +7 -0
  573. package/dist/shared/aiProfileColors.js +33 -0
  574. package/dist/shared/colorPalette.d.ts +3 -0
  575. package/dist/shared/colorPalette.js +20 -0
  576. package/dist/shared/commentProvenance.d.ts +4 -0
  577. package/dist/shared/commentProvenance.js +6 -0
  578. package/dist/shared/deletedTaskRetention.d.ts +2 -0
  579. package/dist/shared/deletedTaskRetention.js +7 -0
  580. package/dist/shared/passwordPolicy.d.ts +2 -1
  581. package/dist/shared/passwordPolicy.js +9 -0
  582. package/dist/shared/planningIdentity.d.ts +20 -0
  583. package/dist/shared/planningIdentity.js +79 -0
  584. package/dist/shared/taskDeepLinks.d.ts +28 -0
  585. package/dist/shared/taskDeepLinks.js +48 -0
  586. package/dist/shared/taskRestoreDestination.d.ts +2 -0
  587. package/dist/shared/taskRestoreDestination.js +5 -0
  588. package/dist/shared/taskforceAgentDefinition.d.ts +88 -0
  589. package/dist/shared/taskforceAgentDefinition.js +434 -0
  590. package/dist/shared/taskforceAgentExecutionSnapshot.d.ts +50 -0
  591. package/dist/shared/taskforceAgentExecutionSnapshot.js +68 -0
  592. package/dist/shared/taskforceAgentModels.d.ts +56 -0
  593. package/dist/shared/taskforceAgentModels.js +314 -0
  594. package/dist/shared/taskforceAgentRunContext.d.ts +23 -0
  595. package/dist/shared/taskforceAgentRunContext.js +21 -0
  596. package/dist/shared/taskforceAgentRuntimeResolution.d.ts +31 -0
  597. package/dist/shared/taskforceAgentRuntimeResolution.js +72 -0
  598. package/dist/shared/taskforceAgentSkill.d.ts +33 -0
  599. package/dist/shared/taskforceAgentSkill.js +149 -0
  600. package/dist/storage/agentRoleStore.d.ts +91 -0
  601. package/dist/storage/agentRoleStore.js +385 -0
  602. package/dist/storage/databaseAdapter.d.ts +1 -0
  603. package/dist/storage/databaseAdapter.js +7 -1
  604. package/dist/storage/documentIntegrity.d.ts +12 -3
  605. package/dist/storage/documentIntegrity.js +105 -27
  606. package/dist/storage/objectStorageClient.d.ts +10 -4
  607. package/dist/storage/objectStorageClient.js +73 -43
  608. package/dist/storage/postgresAdapter.d.ts +2 -1
  609. package/dist/storage/postgresAdapter.js +42 -6
  610. package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
  611. package/dist/storage/postgresRequestDiagnostics.js +24 -0
  612. package/dist/storage/postgresWorker.js +65 -1
  613. package/dist/storage/sqliteAdapter.d.ts +1 -1
  614. package/dist/storage/sqliteAdapter.js +7 -1
  615. package/dist/storage/sqliteWalHealth.d.ts +71 -0
  616. package/dist/storage/sqliteWalHealth.js +176 -0
  617. package/dist/storage/taskDataPath.d.ts +1 -0
  618. package/dist/storage/taskDataPath.js +20 -0
  619. package/dist/storage/taskforceAgentConversationStore.d.ts +66 -0
  620. package/dist/storage/taskforceAgentConversationStore.js +264 -0
  621. package/dist/storage/taskforceAgentSkillStore.d.ts +93 -0
  622. package/dist/storage/taskforceAgentSkillStore.js +355 -0
  623. package/dist/storage/taskforceAgentStore.d.ts +105 -0
  624. package/dist/storage/taskforceAgentStore.js +549 -0
  625. package/dist/storage/workflowStore.d.ts +223 -0
  626. package/dist/storage/workflowStore.js +1032 -0
  627. package/dist/storage/workspaceAssetStore.d.ts +102 -0
  628. package/dist/storage/workspaceAssetStore.js +488 -25
  629. package/dist/sync/aiProfileAvatarSyncPaths.d.ts +14 -0
  630. package/dist/sync/aiProfileAvatarSyncPaths.js +56 -0
  631. package/dist/sync/cloudSyncApi.d.ts +329 -0
  632. package/dist/sync/cloudSyncApi.js +574 -1
  633. package/dist/sync/collaborationSyncPayload.d.ts +5 -1
  634. package/dist/sync/collaborationSyncPayload.js +213 -1
  635. package/dist/sync/collaborationSyncState.d.ts +23 -3
  636. package/dist/sync/collaborationSyncState.js +92 -3
  637. package/dist/sync/contentSyncPayload.d.ts +9 -0
  638. package/dist/sync/contentSyncPayload.js +29 -0
  639. package/dist/sync/contentSyncState.d.ts +79 -4
  640. package/dist/sync/contentSyncState.js +1113 -313
  641. package/dist/sync/coordinator/localSyncBrowserApplyPermitContext.d.ts +39 -0
  642. package/dist/sync/coordinator/localSyncBrowserApplyPermitContext.js +234 -0
  643. package/dist/sync/coordinator/localSyncBrowserAuthorityCapability.d.ts +7 -0
  644. package/dist/sync/coordinator/localSyncBrowserAuthorityCapability.js +10 -0
  645. package/dist/sync/coordinator/localSyncCommittedApplyPolicy.d.ts +7 -0
  646. package/dist/sync/coordinator/localSyncCommittedApplyPolicy.js +41 -0
  647. package/dist/sync/coordinator/localSyncCoordinatorBrowserClient.d.ts +178 -0
  648. package/dist/sync/coordinator/localSyncCoordinatorBrowserClient.js +131 -0
  649. package/dist/sync/coordinator/localSyncCoordinatorCommandLifecycle.d.ts +25 -0
  650. package/dist/sync/coordinator/localSyncCoordinatorCommandLifecycle.js +200 -0
  651. package/dist/sync/coordinator/localSyncCoordinatorHost.d.ts +84 -0
  652. package/dist/sync/coordinator/localSyncCoordinatorHost.js +435 -0
  653. package/dist/sync/coordinator/localSyncCoordinatorRouteServices.d.ts +33 -0
  654. package/dist/sync/coordinator/localSyncCoordinatorRouteServices.js +1 -0
  655. package/dist/sync/coordinator/localSyncCoordinatorStore.d.ts +122 -0
  656. package/dist/sync/coordinator/localSyncCoordinatorStore.js +1039 -0
  657. package/dist/sync/coordinator/localSyncCoordinatorTypes.d.ts +82 -0
  658. package/dist/sync/coordinator/localSyncCoordinatorTypes.js +9 -0
  659. package/dist/sync/coordinator/localSyncDispatchTracker.d.ts +15 -0
  660. package/dist/sync/coordinator/localSyncDispatchTracker.js +68 -0
  661. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +216 -0
  662. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +1436 -0
  663. package/dist/sync/coordinator/localSyncExecutionPermitTypes.d.ts +52 -0
  664. package/dist/sync/coordinator/localSyncExecutionPermitTypes.js +8 -0
  665. package/dist/sync/coordinator/localSyncOwnershipDrainBarrier.d.ts +33 -0
  666. package/dist/sync/coordinator/localSyncOwnershipDrainBarrier.js +83 -0
  667. package/dist/sync/coordinator/localSyncPermitTransactionHooks.d.ts +9 -0
  668. package/dist/sync/coordinator/localSyncPermitTransactionHooks.js +27 -0
  669. package/dist/sync/coordinator/localSyncProcessLock.d.ts +12 -0
  670. package/dist/sync/coordinator/localSyncProcessLock.js +212 -0
  671. package/dist/sync/coordinator/localSyncV3DispatchRecoveryReconciler.d.ts +17 -0
  672. package/dist/sync/coordinator/localSyncV3DispatchRecoveryReconciler.js +82 -0
  673. package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +134 -0
  674. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +981 -0
  675. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +189 -0
  676. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +961 -0
  677. package/dist/sync/coordinator/workspaceSyncCloudCredentialValidator.d.ts +19 -0
  678. package/dist/sync/coordinator/workspaceSyncCloudCredentialValidator.js +83 -0
  679. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +117 -0
  680. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +323 -0
  681. package/dist/sync/coordinator/workspaceSyncLocalAccessBootstrap.d.ts +11 -0
  682. package/dist/sync/coordinator/workspaceSyncLocalAccessBootstrap.js +51 -0
  683. package/dist/sync/coordinator/workspaceSyncTransportGateway.d.ts +139 -0
  684. package/dist/sync/coordinator/workspaceSyncTransportGateway.js +740 -0
  685. package/dist/sync/engine/localWorkspaceContentManifestService.d.ts +21 -0
  686. package/dist/sync/engine/localWorkspaceContentManifestService.js +44 -0
  687. package/dist/sync/engine/workspaceSyncAtomicLocalPublisher.d.ts +36 -0
  688. package/dist/sync/engine/workspaceSyncAtomicLocalPublisher.js +203 -0
  689. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +21 -0
  690. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.js +13 -0
  691. package/dist/sync/engine/workspaceSyncContentPullObligationStore.d.ts +65 -0
  692. package/dist/sync/engine/workspaceSyncContentPullObligationStore.js +160 -0
  693. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +216 -0
  694. package/dist/sync/engine/workspaceSyncContentVersionStore.js +1068 -0
  695. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.d.ts +28 -0
  696. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +543 -0
  697. package/dist/sync/engine/workspaceSyncEngineContracts.d.ts +78 -0
  698. package/dist/sync/engine/workspaceSyncEngineContracts.js +1 -0
  699. package/dist/sync/engine/workspaceSyncEngineControlPlane.d.ts +37 -0
  700. package/dist/sync/engine/workspaceSyncEngineControlPlane.js +79 -0
  701. package/dist/sync/engine/workspaceSyncEngineIdentity.d.ts +1 -0
  702. package/dist/sync/engine/workspaceSyncEngineIdentity.js +4 -0
  703. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.d.ts +68 -0
  704. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +180 -0
  705. package/dist/sync/engine/workspaceSyncEngineLocalApply.d.ts +72 -0
  706. package/dist/sync/engine/workspaceSyncEngineLocalApply.js +132 -0
  707. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +70 -0
  708. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +25 -0
  709. package/dist/sync/engine/workspaceSyncEngineParity.d.ts +8 -0
  710. package/dist/sync/engine/workspaceSyncEngineParity.js +7 -0
  711. package/dist/sync/engine/workspaceSyncEnginePullPolicy.d.ts +32 -0
  712. package/dist/sync/engine/workspaceSyncEnginePullPolicy.js +27 -0
  713. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +20 -0
  714. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +87 -0
  715. package/dist/sync/engine/workspaceSyncEngineRecovery.d.ts +56 -0
  716. package/dist/sync/engine/workspaceSyncEngineRecovery.js +288 -0
  717. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +109 -0
  718. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +21 -0
  719. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +61 -0
  720. package/dist/sync/engine/workspaceSyncEngineRuntime.js +59 -0
  721. package/dist/sync/engine/workspaceSyncEngineServerApplyBoundary.d.ts +28 -0
  722. package/dist/sync/engine/workspaceSyncEngineServerApplyBoundary.js +86 -0
  723. package/dist/sync/engine/workspaceSyncEngineServerLocalServices.d.ts +73 -0
  724. package/dist/sync/engine/workspaceSyncEngineServerLocalServices.js +452 -0
  725. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +23 -0
  726. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +466 -0
  727. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +125 -0
  728. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +1147 -0
  729. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.d.ts +63 -0
  730. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +276 -0
  731. package/dist/sync/engine/workspaceSyncEngineTransferCompletion.d.ts +20 -0
  732. package/dist/sync/engine/workspaceSyncEngineTransferCompletion.js +37 -0
  733. package/dist/sync/engine/workspaceSyncEngineTransferTypes.d.ts +7 -0
  734. package/dist/sync/engine/workspaceSyncEngineTransferTypes.js +1 -0
  735. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +240 -0
  736. package/dist/sync/engine/workspaceSyncEngineTransfers.js +1184 -0
  737. package/dist/sync/engine/workspaceSyncEngineV3LocalFeedApply.d.ts +39 -0
  738. package/dist/sync/engine/workspaceSyncEngineV3LocalFeedApply.js +39 -0
  739. package/dist/sync/engine/workspaceSyncImmutableContentGcRunner.d.ts +25 -0
  740. package/dist/sync/engine/workspaceSyncImmutableContentGcRunner.js +83 -0
  741. package/dist/sync/engine/workspaceSyncImmutableContentProvider.d.ts +71 -0
  742. package/dist/sync/engine/workspaceSyncImmutableContentProvider.js +209 -0
  743. package/dist/sync/engine/workspaceSyncImmutableContentStager.d.ts +32 -0
  744. package/dist/sync/engine/workspaceSyncImmutableContentStager.js +202 -0
  745. package/dist/sync/engine/workspaceSyncPublishedContentResolver.d.ts +43 -0
  746. package/dist/sync/engine/workspaceSyncPublishedContentResolver.js +142 -0
  747. package/dist/sync/engine/workspaceSyncServerContentRuntime.d.ts +26 -0
  748. package/dist/sync/engine/workspaceSyncServerContentRuntime.js +41 -0
  749. package/dist/sync/engine/workspaceSyncServerDataServices.d.ts +44 -0
  750. package/dist/sync/engine/workspaceSyncServerDataServices.js +143 -0
  751. package/dist/sync/engine/workspaceSyncTransferEvidence.d.ts +39 -0
  752. package/dist/sync/engine/workspaceSyncTransferEvidence.js +45 -0
  753. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +44 -0
  754. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +992 -0
  755. package/dist/sync/engine/workspaceSyncV2PreparedContent.d.ts +82 -0
  756. package/dist/sync/engine/workspaceSyncV2PreparedContent.js +219 -0
  757. package/dist/sync/planningCanonicalFields.d.ts +41 -0
  758. package/dist/sync/planningCanonicalFields.js +211 -0
  759. package/dist/sync/planningSyncPayload.d.ts +5 -1
  760. package/dist/sync/planningSyncPayload.js +88 -4
  761. package/dist/sync/syncApplyHandlers.d.ts +100 -8
  762. package/dist/sync/syncApplyHandlers.js +845 -78
  763. package/dist/sync/syncResourceAdapters.d.ts +10 -0
  764. package/dist/sync/syncResourceAdapters.js +21 -1
  765. package/dist/sync/syncService.d.ts +57 -1
  766. package/dist/sync/syncService.js +1094 -138
  767. package/dist/sync/taskNestedContent.d.ts +2 -0
  768. package/dist/sync/taskNestedContent.js +8 -0
  769. package/dist/sync/taskSyncChangeKey.js +0 -1
  770. package/dist/sync/taskSyncPayload.d.ts +1 -1
  771. package/dist/sync/taskSyncPayload.js +20 -3
  772. package/dist/sync/v3/canonicalWorkspaceSyncJson.d.ts +2 -0
  773. package/dist/sync/v3/canonicalWorkspaceSyncJson.js +26 -0
  774. package/dist/sync/v3/combinedFeedCapability.d.ts +21 -0
  775. package/dist/sync/v3/combinedFeedCapability.js +80 -0
  776. package/dist/sync/v3/combinedFeedPrerequisites.d.ts +18 -0
  777. package/dist/sync/v3/combinedFeedPrerequisites.js +184 -0
  778. package/dist/sync/v3/durableInitiativeMutationRouter.d.ts +61 -0
  779. package/dist/sync/v3/durableInitiativeMutationRouter.js +287 -0
  780. package/dist/sync/v3/durableOperationReplay.d.ts +36 -0
  781. package/dist/sync/v3/durableOperationReplay.js +103 -0
  782. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +50 -0
  783. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +216 -0
  784. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +47 -0
  785. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +182 -0
  786. package/dist/sync/v3/durableTaskCommentMutationRouter.d.ts +47 -0
  787. package/dist/sync/v3/durableTaskCommentMutationRouter.js +191 -0
  788. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +60 -0
  789. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +333 -0
  790. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +40 -0
  791. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +518 -0
  792. package/dist/sync/v3/durableTaxonomyMutationRouter.d.ts +63 -0
  793. package/dist/sync/v3/durableTaxonomyMutationRouter.js +289 -0
  794. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +77 -0
  795. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +361 -0
  796. package/dist/sync/v3/durableWorkstreamMutationRouter.d.ts +61 -0
  797. package/dist/sync/v3/durableWorkstreamMutationRouter.js +287 -0
  798. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.d.ts +42 -0
  799. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +122 -0
  800. package/dist/sync/v3/entityEventLegacyAdoptionContract.d.ts +6 -0
  801. package/dist/sync/v3/entityEventLegacyAdoptionContract.js +6 -0
  802. package/dist/sync/v3/entityEventLegacyAdoptionService.d.ts +62 -0
  803. package/dist/sync/v3/entityEventLegacyAdoptionService.js +180 -0
  804. package/dist/sync/v3/initiativeActivityAuthoritativeRevision.d.ts +11 -0
  805. package/dist/sync/v3/initiativeActivityAuthoritativeRevision.js +23 -0
  806. package/dist/sync/v3/initiativeActivityIdentity.d.ts +8 -0
  807. package/dist/sync/v3/initiativeActivityIdentity.js +14 -0
  808. package/dist/sync/v3/initiativeCoexistence.d.ts +26 -0
  809. package/dist/sync/v3/initiativeCoexistence.js +148 -0
  810. package/dist/sync/v3/initiativeFeedActivationCapability.d.ts +6 -0
  811. package/dist/sync/v3/initiativeFeedActivationCapability.js +16 -0
  812. package/dist/sync/v3/initiativeMutationPayload.d.ts +26 -0
  813. package/dist/sync/v3/initiativeMutationPayload.js +144 -0
  814. package/dist/sync/v3/initiativeMutationService.d.ts +62 -0
  815. package/dist/sync/v3/initiativeMutationService.js +206 -0
  816. package/dist/sync/v3/localEntityEventLegacyAdoption.d.ts +31 -0
  817. package/dist/sync/v3/localEntityEventLegacyAdoption.js +607 -0
  818. package/dist/sync/v3/localInitiativeOutboxHandler.d.ts +8 -0
  819. package/dist/sync/v3/localInitiativeOutboxHandler.js +88 -0
  820. package/dist/sync/v3/localInitiativeOutboxService.d.ts +50 -0
  821. package/dist/sync/v3/localInitiativeOutboxService.js +497 -0
  822. package/dist/sync/v3/localOperationIdentityStore.d.ts +81 -0
  823. package/dist/sync/v3/localOperationIdentityStore.js +388 -0
  824. package/dist/sync/v3/localOutboxDispatchCapability.d.ts +7 -0
  825. package/dist/sync/v3/localOutboxDispatchCapability.js +13 -0
  826. package/dist/sync/v3/localOutboxDispatchRuntime.d.ts +16 -0
  827. package/dist/sync/v3/localOutboxDispatchRuntime.js +269 -0
  828. package/dist/sync/v3/localOutboxDispatcher.d.ts +53 -0
  829. package/dist/sync/v3/localOutboxDispatcher.js +366 -0
  830. package/dist/sync/v3/localOutboxDrainClient.d.ts +50 -0
  831. package/dist/sync/v3/localOutboxDrainClient.js +250 -0
  832. package/dist/sync/v3/localOutboxOperationHandler.d.ts +31 -0
  833. package/dist/sync/v3/localOutboxOperationHandler.js +10 -0
  834. package/dist/sync/v3/localOutboxRecoveryClient.d.ts +14 -0
  835. package/dist/sync/v3/localOutboxRecoveryClient.js +45 -0
  836. package/dist/sync/v3/localOutboxRecoveryPreparationService.d.ts +12 -0
  837. package/dist/sync/v3/localOutboxRecoveryPreparationService.js +151 -0
  838. package/dist/sync/v3/localSyncIdentityStore.d.ts +9 -0
  839. package/dist/sync/v3/localSyncIdentityStore.js +43 -0
  840. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.d.ts +10 -0
  841. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +80 -0
  842. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +46 -0
  843. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +303 -0
  844. package/dist/sync/v3/localTaskChecklistOutboxHandler.d.ts +10 -0
  845. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +54 -0
  846. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +47 -0
  847. package/dist/sync/v3/localTaskChecklistOutboxService.js +221 -0
  848. package/dist/sync/v3/localTaskCommentOutboxHandler.d.ts +10 -0
  849. package/dist/sync/v3/localTaskCommentOutboxHandler.js +94 -0
  850. package/dist/sync/v3/localTaskCommentOutboxService.d.ts +75 -0
  851. package/dist/sync/v3/localTaskCommentOutboxService.js +391 -0
  852. package/dist/sync/v3/localTaskCreateClient.d.ts +27 -0
  853. package/dist/sync/v3/localTaskCreateClient.js +209 -0
  854. package/dist/sync/v3/localTaskCreateOutboxHandler.d.ts +8 -0
  855. package/dist/sync/v3/localTaskCreateOutboxHandler.js +147 -0
  856. package/dist/sync/v3/localTaskCreateOutboxService.d.ts +77 -0
  857. package/dist/sync/v3/localTaskCreateOutboxService.js +397 -0
  858. package/dist/sync/v3/localTaskDeleteClient.d.ts +10 -0
  859. package/dist/sync/v3/localTaskDeleteClient.js +23 -0
  860. package/dist/sync/v3/localTaskDeleteOutboxHandler.d.ts +8 -0
  861. package/dist/sync/v3/localTaskDeleteOutboxHandler.js +54 -0
  862. package/dist/sync/v3/localTaskDeleteOutboxService.d.ts +38 -0
  863. package/dist/sync/v3/localTaskDeleteOutboxService.js +235 -0
  864. package/dist/sync/v3/localTaskLegacyRootAdoption.d.ts +28 -0
  865. package/dist/sync/v3/localTaskLegacyRootAdoption.js +219 -0
  866. package/dist/sync/v3/localTaskLifecycleClient.d.ts +49 -0
  867. package/dist/sync/v3/localTaskLifecycleClient.js +57 -0
  868. package/dist/sync/v3/localTaskLifecycleOutboxHandler.d.ts +8 -0
  869. package/dist/sync/v3/localTaskLifecycleOutboxHandler.js +94 -0
  870. package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +60 -0
  871. package/dist/sync/v3/localTaskLifecycleOutboxService.js +304 -0
  872. package/dist/sync/v3/localTaskMetadataClient.d.ts +13 -0
  873. package/dist/sync/v3/localTaskMetadataClient.js +30 -0
  874. package/dist/sync/v3/localTaskMetadataOutboxHandler.d.ts +8 -0
  875. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +70 -0
  876. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +48 -0
  877. package/dist/sync/v3/localTaskMetadataOutboxService.js +229 -0
  878. package/dist/sync/v3/localTaskOperationClient.d.ts +72 -0
  879. package/dist/sync/v3/localTaskOperationClient.js +195 -0
  880. package/dist/sync/v3/localTaskRelationshipOutboxHandler.d.ts +8 -0
  881. package/dist/sync/v3/localTaskRelationshipOutboxHandler.js +114 -0
  882. package/dist/sync/v3/localTaskRelationshipOutboxService.d.ts +45 -0
  883. package/dist/sync/v3/localTaskRelationshipOutboxService.js +192 -0
  884. package/dist/sync/v3/localTaskRestoreClient.d.ts +13 -0
  885. package/dist/sync/v3/localTaskRestoreClient.js +32 -0
  886. package/dist/sync/v3/localTaskRestoreOutboxHandler.d.ts +8 -0
  887. package/dist/sync/v3/localTaskRestoreOutboxHandler.js +41 -0
  888. package/dist/sync/v3/localTaskRestoreOutboxService.d.ts +56 -0
  889. package/dist/sync/v3/localTaskRestoreOutboxService.js +323 -0
  890. package/dist/sync/v3/localTaskStatusClient.d.ts +17 -0
  891. package/dist/sync/v3/localTaskStatusClient.js +35 -0
  892. package/dist/sync/v3/localTaskStatusOutboxHandler.d.ts +8 -0
  893. package/dist/sync/v3/localTaskStatusOutboxHandler.js +75 -0
  894. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +53 -0
  895. package/dist/sync/v3/localTaskStatusOutboxService.js +422 -0
  896. package/dist/sync/v3/localTaxonomyCompositeOutboxService.d.ts +34 -0
  897. package/dist/sync/v3/localTaxonomyCompositeOutboxService.js +290 -0
  898. package/dist/sync/v3/localTaxonomyOutboxHandler.d.ts +9 -0
  899. package/dist/sync/v3/localTaxonomyOutboxHandler.js +106 -0
  900. package/dist/sync/v3/localTaxonomyOutboxService.d.ts +30 -0
  901. package/dist/sync/v3/localTaxonomyOutboxService.js +181 -0
  902. package/dist/sync/v3/localWorkflowRuntimeOutboxHandler.d.ts +8 -0
  903. package/dist/sync/v3/localWorkflowRuntimeOutboxHandler.js +113 -0
  904. package/dist/sync/v3/localWorkflowRuntimeOutboxService.d.ts +37 -0
  905. package/dist/sync/v3/localWorkflowRuntimeOutboxService.js +330 -0
  906. package/dist/sync/v3/localWorkspaceSyncServerOutboxDispatcher.d.ts +63 -0
  907. package/dist/sync/v3/localWorkspaceSyncServerOutboxDispatcher.js +264 -0
  908. package/dist/sync/v3/localWorkstreamOutboxHandler.d.ts +8 -0
  909. package/dist/sync/v3/localWorkstreamOutboxHandler.js +102 -0
  910. package/dist/sync/v3/localWorkstreamOutboxService.d.ts +52 -0
  911. package/dist/sync/v3/localWorkstreamOutboxService.js +581 -0
  912. package/dist/sync/v3/localWorkstreamTaskOrderOutboxHandler.d.ts +10 -0
  913. package/dist/sync/v3/localWorkstreamTaskOrderOutboxHandler.js +57 -0
  914. package/dist/sync/v3/localWorkstreamTaskOrderOutboxService.d.ts +30 -0
  915. package/dist/sync/v3/localWorkstreamTaskOrderOutboxService.js +128 -0
  916. package/dist/sync/v3/planningActivation.d.ts +13 -0
  917. package/dist/sync/v3/planningActivation.js +33 -0
  918. package/dist/sync/v3/planningAttachmentActivityValidation.d.ts +9 -0
  919. package/dist/sync/v3/planningAttachmentActivityValidation.js +87 -0
  920. package/dist/sync/v3/programScaffoldService.d.ts +143 -0
  921. package/dist/sync/v3/programScaffoldService.js +478 -0
  922. package/dist/sync/v3/syncDurabilityStore.d.ts +781 -0
  923. package/dist/sync/v3/syncDurabilityStore.js +4773 -0
  924. package/dist/sync/v3/taskActivityAuthoritativeRevision.d.ts +16 -0
  925. package/dist/sync/v3/taskActivityAuthoritativeRevision.js +67 -0
  926. package/dist/sync/v3/taskActivityJournal.d.ts +20 -0
  927. package/dist/sync/v3/taskActivityJournal.js +195 -0
  928. package/dist/sync/v3/taskAttachmentLinksActivityIdentity.d.ts +6 -0
  929. package/dist/sync/v3/taskAttachmentLinksActivityIdentity.js +14 -0
  930. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +112 -0
  931. package/dist/sync/v3/taskAttachmentLinksMutationService.js +218 -0
  932. package/dist/sync/v3/taskChecklistActivityIdentity.d.ts +6 -0
  933. package/dist/sync/v3/taskChecklistActivityIdentity.js +14 -0
  934. package/dist/sync/v3/taskChecklistMutationService.d.ts +92 -0
  935. package/dist/sync/v3/taskChecklistMutationService.js +156 -0
  936. package/dist/sync/v3/taskCommentActivityIdentity.d.ts +7 -0
  937. package/dist/sync/v3/taskCommentActivityIdentity.js +15 -0
  938. package/dist/sync/v3/taskCommentMutationService.d.ts +150 -0
  939. package/dist/sync/v3/taskCommentMutationService.js +392 -0
  940. package/dist/sync/v3/taskCommentReconcileProvenance.d.ts +58 -0
  941. package/dist/sync/v3/taskCommentReconcileProvenance.js +170 -0
  942. package/dist/sync/v3/taskCreateActivation.d.ts +19 -0
  943. package/dist/sync/v3/taskCreateActivation.js +84 -0
  944. package/dist/sync/v3/taskCreateActivityIdentity.d.ts +7 -0
  945. package/dist/sync/v3/taskCreateActivityIdentity.js +18 -0
  946. package/dist/sync/v3/taskCreateMutationService.d.ts +103 -0
  947. package/dist/sync/v3/taskCreateMutationService.js +283 -0
  948. package/dist/sync/v3/taskDeleteActivation.d.ts +7 -0
  949. package/dist/sync/v3/taskDeleteActivation.js +14 -0
  950. package/dist/sync/v3/taskDeleteMutationService.d.ts +35 -0
  951. package/dist/sync/v3/taskDeleteMutationService.js +133 -0
  952. package/dist/sync/v3/taskLegacyRootAdoptionService.d.ts +78 -0
  953. package/dist/sync/v3/taskLegacyRootAdoptionService.js +175 -0
  954. package/dist/sync/v3/taskLifecycleActivityIdentity.d.ts +9 -0
  955. package/dist/sync/v3/taskLifecycleActivityIdentity.js +18 -0
  956. package/dist/sync/v3/taskLifecycleMutationPayload.d.ts +5 -0
  957. package/dist/sync/v3/taskLifecycleMutationPayload.js +28 -0
  958. package/dist/sync/v3/taskLifecycleMutationService.d.ts +66 -0
  959. package/dist/sync/v3/taskLifecycleMutationService.js +92 -0
  960. package/dist/sync/v3/taskMetadataActivation.d.ts +12 -0
  961. package/dist/sync/v3/taskMetadataActivation.js +38 -0
  962. package/dist/sync/v3/taskMetadataActivityIdentity.d.ts +7 -0
  963. package/dist/sync/v3/taskMetadataActivityIdentity.js +18 -0
  964. package/dist/sync/v3/taskMetadataCoexistence.d.ts +37 -0
  965. package/dist/sync/v3/taskMetadataCoexistence.js +138 -0
  966. package/dist/sync/v3/taskMetadataMutationService.d.ts +71 -0
  967. package/dist/sync/v3/taskMetadataMutationService.js +199 -0
  968. package/dist/sync/v3/taskRelationshipLegacyAdoptionService.d.ts +48 -0
  969. package/dist/sync/v3/taskRelationshipLegacyAdoptionService.js +164 -0
  970. package/dist/sync/v3/taskRelationshipMutationService.d.ts +50 -0
  971. package/dist/sync/v3/taskRelationshipMutationService.js +148 -0
  972. package/dist/sync/v3/taskRestoreMutationService.d.ts +90 -0
  973. package/dist/sync/v3/taskRestoreMutationService.js +179 -0
  974. package/dist/sync/v3/taskStatusActivation.d.ts +7 -0
  975. package/dist/sync/v3/taskStatusActivation.js +15 -0
  976. package/dist/sync/v3/taskStatusMutationService.d.ts +76 -0
  977. package/dist/sync/v3/taskStatusMutationService.js +308 -0
  978. package/dist/sync/v3/taskWorkflowMutationPayload.d.ts +4 -0
  979. package/dist/sync/v3/taskWorkflowMutationPayload.js +22 -0
  980. package/dist/sync/v3/taskWorkflowMutationService.d.ts +64 -0
  981. package/dist/sync/v3/taskWorkflowMutationService.js +102 -0
  982. package/dist/sync/v3/taxonomyCoexistence.d.ts +10 -0
  983. package/dist/sync/v3/taxonomyCoexistence.js +19 -0
  984. package/dist/sync/v3/taxonomyCompositeMutationService.d.ts +110 -0
  985. package/dist/sync/v3/taxonomyCompositeMutationService.js +304 -0
  986. package/dist/sync/v3/taxonomyMutationService.d.ts +57 -0
  987. package/dist/sync/v3/taxonomyMutationService.js +106 -0
  988. package/dist/sync/v3/taxonomyStateMutation.d.ts +22 -0
  989. package/dist/sync/v3/taxonomyStateMutation.js +49 -0
  990. package/dist/sync/v3/taxonomySyncPayload.d.ts +9 -0
  991. package/dist/sync/v3/taxonomySyncPayload.js +199 -0
  992. package/dist/sync/v3/workflowAssignmentSync.d.ts +22 -0
  993. package/dist/sync/v3/workflowAssignmentSync.js +213 -0
  994. package/dist/sync/v3/workflowRuntimeMutationService.d.ts +89 -0
  995. package/dist/sync/v3/workflowRuntimeMutationService.js +359 -0
  996. package/dist/sync/v3/workflowRuntimeOperationIdentity.d.ts +13 -0
  997. package/dist/sync/v3/workflowRuntimeOperationIdentity.js +35 -0
  998. package/dist/sync/v3/workflowRuntimeSync.d.ts +141 -0
  999. package/dist/sync/v3/workflowRuntimeSync.js +485 -0
  1000. package/dist/sync/v3/workspaceSyncJournalReader.d.ts +43 -0
  1001. package/dist/sync/v3/workspaceSyncJournalReader.js +45 -0
  1002. package/dist/sync/v3/workspaceSyncLocalOwnershipSnapshot.d.ts +28 -0
  1003. package/dist/sync/v3/workspaceSyncLocalOwnershipSnapshot.js +81 -0
  1004. package/dist/sync/v3/workspaceSyncPayloadFingerprint.d.ts +1 -0
  1005. package/dist/sync/v3/workspaceSyncPayloadFingerprint.js +5 -0
  1006. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +16 -0
  1007. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +153 -0
  1008. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +83 -0
  1009. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +161 -0
  1010. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +16 -0
  1011. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +90 -0
  1012. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +65 -0
  1013. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +357 -0
  1014. package/dist/sync/v3/workspaceSyncV3CombinedCoverage.d.ts +51 -0
  1015. package/dist/sync/v3/workspaceSyncV3CombinedCoverage.js +171 -0
  1016. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.d.ts +43 -0
  1017. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +541 -0
  1018. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.d.ts +50 -0
  1019. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +1161 -0
  1020. package/dist/sync/v3/workspaceSyncV3CombinedProjectionState.d.ts +96 -0
  1021. package/dist/sync/v3/workspaceSyncV3CombinedProjectionState.js +672 -0
  1022. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +46 -0
  1023. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +621 -0
  1024. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +66 -0
  1025. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +527 -0
  1026. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +78 -0
  1027. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +566 -0
  1028. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +45 -0
  1029. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +125 -0
  1030. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.d.ts +13 -0
  1031. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +34 -0
  1032. package/dist/sync/v3/workspaceSyncV3CursorEncoding.d.ts +1 -0
  1033. package/dist/sync/v3/workspaceSyncV3CursorEncoding.js +6 -0
  1034. package/dist/sync/v3/workspaceSyncV3DomainAdmission.d.ts +43 -0
  1035. package/dist/sync/v3/workspaceSyncV3DomainAdmission.js +118 -0
  1036. package/dist/sync/v3/workspaceSyncV3Feed.d.ts +95 -0
  1037. package/dist/sync/v3/workspaceSyncV3Feed.js +243 -0
  1038. package/dist/sync/v3/workspaceSyncV3FeedApply.d.ts +13 -0
  1039. package/dist/sync/v3/workspaceSyncV3FeedApply.js +67 -0
  1040. package/dist/sync/v3/workspaceSyncV3FeedClientContract.d.ts +3 -0
  1041. package/dist/sync/v3/workspaceSyncV3FeedClientContract.js +46 -0
  1042. package/dist/sync/v3/workspaceSyncV3FeedCursorKeys.d.ts +10 -0
  1043. package/dist/sync/v3/workspaceSyncV3FeedCursorKeys.js +58 -0
  1044. package/dist/sync/v3/workspaceSyncV3FeedOrchestrator.d.ts +31 -0
  1045. package/dist/sync/v3/workspaceSyncV3FeedOrchestrator.js +228 -0
  1046. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +32 -0
  1047. package/dist/sync/v3/workspaceSyncV3FeedProfile.js +21 -0
  1048. package/dist/sync/v3/workspaceSyncV3InitiativeLocalApply.d.ts +36 -0
  1049. package/dist/sync/v3/workspaceSyncV3InitiativeLocalApply.js +163 -0
  1050. package/dist/sync/v3/workspaceSyncV3InitiativeRepair.d.ts +33 -0
  1051. package/dist/sync/v3/workspaceSyncV3InitiativeRepair.js +118 -0
  1052. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +10 -0
  1053. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +45 -0
  1054. package/dist/sync/v3/workspaceSyncV3LocalOutboxStatus.d.ts +27 -0
  1055. package/dist/sync/v3/workspaceSyncV3LocalOutboxStatus.js +83 -0
  1056. package/dist/sync/v3/workspaceSyncV3NestedCoverage.d.ts +10 -0
  1057. package/dist/sync/v3/workspaceSyncV3NestedCoverage.js +40 -0
  1058. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +83 -0
  1059. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +325 -0
  1060. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +59 -0
  1061. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +302 -0
  1062. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +47 -0
  1063. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +329 -0
  1064. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +19 -0
  1065. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +41 -0
  1066. package/dist/sync/v3/workspaceSyncV3NestedWireContract.d.ts +6 -0
  1067. package/dist/sync/v3/workspaceSyncV3NestedWireContract.js +16 -0
  1068. package/dist/sync/v3/workspaceSyncV3OperationProjection.d.ts +8 -0
  1069. package/dist/sync/v3/workspaceSyncV3OperationProjection.js +52 -0
  1070. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +230 -0
  1071. package/dist/sync/v3/workspaceSyncV3OperationProtocol.js +1 -0
  1072. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +165 -0
  1073. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +414 -0
  1074. package/dist/sync/v3/workspaceSyncV3OriginActor.d.ts +36 -0
  1075. package/dist/sync/v3/workspaceSyncV3OriginActor.js +61 -0
  1076. package/dist/sync/v3/workspaceSyncV3OriginAssertion.d.ts +46 -0
  1077. package/dist/sync/v3/workspaceSyncV3OriginAssertion.js +121 -0
  1078. package/dist/sync/v3/workspaceSyncV3OriginAssertionHeader.d.ts +1 -0
  1079. package/dist/sync/v3/workspaceSyncV3OriginAssertionHeader.js +1 -0
  1080. package/dist/sync/v3/workspaceSyncV3PlanningOrderCoverage.d.ts +10 -0
  1081. package/dist/sync/v3/workspaceSyncV3PlanningOrderCoverage.js +34 -0
  1082. package/dist/sync/v3/workspaceSyncV3PlanningOrderWireContract.d.ts +6 -0
  1083. package/dist/sync/v3/workspaceSyncV3PlanningOrderWireContract.js +10 -0
  1084. package/dist/sync/v3/workspaceSyncV3ProjectionState.d.ts +105 -0
  1085. package/dist/sync/v3/workspaceSyncV3ProjectionState.js +467 -0
  1086. package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
  1087. package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
  1088. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.d.ts +56 -0
  1089. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +250 -0
  1090. package/dist/sync/v3/workspaceSyncV3TaskRelationshipProjection.d.ts +30 -0
  1091. package/dist/sync/v3/workspaceSyncV3TaskRelationshipProjection.js +142 -0
  1092. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +40 -0
  1093. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +246 -0
  1094. package/dist/sync/v3/workspaceSyncV3TaxonomyFeedProjection.d.ts +39 -0
  1095. package/dist/sync/v3/workspaceSyncV3TaxonomyFeedProjection.js +185 -0
  1096. package/dist/sync/v3/workspaceSyncV3WorkflowCoverage.d.ts +10 -0
  1097. package/dist/sync/v3/workspaceSyncV3WorkflowCoverage.js +36 -0
  1098. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +17 -0
  1099. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +143 -0
  1100. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeProjection.d.ts +9 -0
  1101. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeProjection.js +195 -0
  1102. package/dist/sync/v3/workspaceSyncV3WorkflowWireContract.d.ts +11 -0
  1103. package/dist/sync/v3/workspaceSyncV3WorkflowWireContract.js +12 -0
  1104. package/dist/sync/v3/workspaceSyncV3WorkstreamProjection.d.ts +4 -0
  1105. package/dist/sync/v3/workspaceSyncV3WorkstreamProjection.js +98 -0
  1106. package/dist/sync/v3/workspaceSyncV3WorkstreamTaskOrderProjection.d.ts +9 -0
  1107. package/dist/sync/v3/workspaceSyncV3WorkstreamTaskOrderProjection.js +72 -0
  1108. package/dist/sync/v3/workstreamActivityAuthoritativeRevision.d.ts +11 -0
  1109. package/dist/sync/v3/workstreamActivityAuthoritativeRevision.js +23 -0
  1110. package/dist/sync/v3/workstreamActivityIdentity.d.ts +8 -0
  1111. package/dist/sync/v3/workstreamActivityIdentity.js +14 -0
  1112. package/dist/sync/v3/workstreamCoexistence.d.ts +19 -0
  1113. package/dist/sync/v3/workstreamCoexistence.js +64 -0
  1114. package/dist/sync/v3/workstreamMutationPayload.d.ts +27 -0
  1115. package/dist/sync/v3/workstreamMutationPayload.js +147 -0
  1116. package/dist/sync/v3/workstreamMutationService.d.ts +72 -0
  1117. package/dist/sync/v3/workstreamMutationService.js +256 -0
  1118. package/dist/sync/v3/workstreamTaskOrderMutationService.d.ts +55 -0
  1119. package/dist/sync/v3/workstreamTaskOrderMutationService.js +110 -0
  1120. package/dist/sync/v3/workstreamTaskOrderSync.d.ts +14 -0
  1121. package/dist/sync/v3/workstreamTaskOrderSync.js +25 -0
  1122. package/dist/sync/workspaceContentManifest.d.ts +86 -0
  1123. package/dist/sync/workspaceContentManifest.js +123 -0
  1124. package/dist/sync/workspacePullFeed.d.ts +191 -2
  1125. package/dist/sync/workspacePullFeed.js +523 -135
  1126. package/dist/sync/workspacePushPreparedPlan.d.ts +21 -0
  1127. package/dist/sync/workspacePushPreparedPlan.js +1 -0
  1128. package/dist/sync/workspaceRepair.d.ts +17 -25
  1129. package/dist/sync/workspaceRepair.js +348 -25
  1130. package/dist/sync/workspaceSyncContentDecryption.d.ts +6 -0
  1131. package/dist/sync/workspaceSyncContentDecryption.js +11 -0
  1132. package/dist/sync/workspaceSyncModel.d.ts +227 -5
  1133. package/dist/sync/workspaceSyncModel.js +398 -37
  1134. package/dist/sync/workspaceSyncSnapshotProjection.d.ts +11 -0
  1135. package/dist/sync/workspaceSyncSnapshotProjection.js +101 -0
  1136. package/dist/sync/workspaceSyncState.d.ts +13 -0
  1137. package/dist/sync/workspaceSyncState.js +36 -0
  1138. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +106 -0
  1139. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +193 -0
  1140. package/dist/types.d.ts +31 -15
  1141. package/dist/types.js +1 -3
  1142. package/dist/ui/ai-profile-clients/amazon-nova.svg +1 -0
  1143. package/dist/ui/ai-profile-clients/antigravity.png +0 -0
  1144. package/dist/ui/ai-profile-clients/chatgpt.svg +10 -0
  1145. package/dist/ui/ai-profile-clients/claude-chat.svg +1 -0
  1146. package/dist/ui/ai-profile-clients/claude-code.svg +15 -0
  1147. package/dist/ui/ai-profile-clients/cline-app-icon-light.png +0 -0
  1148. package/dist/ui/ai-profile-clients/cline.svg +16 -0
  1149. package/dist/ui/ai-profile-clients/codex.svg +1 -0
  1150. package/dist/ui/ai-profile-clients/copilot.png +0 -0
  1151. package/dist/ui/ai-profile-clients/cursor.svg +1 -0
  1152. package/dist/ui/ai-profile-clients/deepseek.svg +1 -0
  1153. package/dist/ui/ai-profile-clients/gemini-cli-icon.png +0 -0
  1154. package/dist/ui/ai-profile-clients/gemini.svg +10 -0
  1155. package/dist/ui/ai-profile-clients/grok.svg +31 -0
  1156. package/dist/ui/ai-profile-clients/kiro.svg +11 -0
  1157. package/dist/ui/ai-profile-clients/llama.svg +1 -0
  1158. package/dist/ui/ai-profile-clients/mistral.svg +1 -0
  1159. package/dist/ui/ai-profile-clients/ms_copilot.jpeg +0 -0
  1160. package/dist/ui/ai-profile-clients/openclaw.png +0 -0
  1161. package/dist/ui/ai-profile-clients/perplexity.svg +1 -0
  1162. package/dist/ui/ai-profile-clients/vscode.svg +41 -0
  1163. package/dist/ui/ai-profile-clients/windsurf.svg +11 -0
  1164. package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +1 -0
  1165. package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +1 -0
  1166. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +1 -0
  1167. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +3 -0
  1168. package/dist/ui/assets/AssetTraySortControl-B9k5caQW.css +1 -0
  1169. package/dist/ui/assets/AssetTraySortControl-Kf1pelSy.js +1 -0
  1170. package/dist/ui/assets/ContextAttachmentManager-B8boOs6Q.js +3 -0
  1171. package/dist/ui/assets/DocumentWorkspace-BIBGBfd7.css +1 -0
  1172. package/dist/ui/assets/DocumentWorkspace-DXH4XUsB.js +261 -0
  1173. package/dist/ui/assets/EntityActivityTimeline-BfJbZRdl.css +1 -0
  1174. package/dist/ui/assets/EntityActivityTimeline-BtSTq0ON.js +1 -0
  1175. package/dist/ui/assets/PlanningModule-BPVyEa-f.js +1 -0
  1176. package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
  1177. package/dist/ui/assets/PlansPage-C2nkK2Bp.css +1 -0
  1178. package/dist/ui/assets/PlansPage-ChqgxALc.js +1 -0
  1179. package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +1 -0
  1180. package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
  1181. package/dist/ui/assets/TaskSettings-g4ECKNOz.js +12 -0
  1182. package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +21 -0
  1183. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +1 -0
  1184. package/dist/ui/assets/WorkflowManagerModule-DF10XENz.css +1 -0
  1185. package/dist/ui/assets/WorkflowManagerModule-DWFspC-o.js +1 -0
  1186. package/dist/ui/assets/antigravity-DRKQga2U.png +0 -0
  1187. package/dist/ui/assets/cursor-BM_3k4Y4.svg +1 -0
  1188. package/dist/ui/assets/gemini-cli-icon-dBAVjCcn.png +0 -0
  1189. package/dist/ui/assets/grok-BuodbWaG.svg +31 -0
  1190. package/dist/ui/assets/index-BUplSsv_.js +7 -0
  1191. package/dist/ui/assets/index-gz2EXuoK.css +1 -0
  1192. package/dist/ui/assets/{vendor-dnd-DRzYolkg.js → vendor-dnd-CJ-AjP-Y.js} +1 -1
  1193. package/dist/ui/assets/{vendor-icons-CLnehDTw.js → vendor-icons-BkFLXavV.js} +1 -1
  1194. package/dist/ui/assets/{vendor-markdown-BUxTU7dS.js → vendor-markdown-_lhNCyq-.js} +9 -9
  1195. package/dist/ui/assets/vendor-router-AqJMU8Lz.js +3 -0
  1196. package/dist/ui/assets/vscode-C_7wk1WI.svg +41 -0
  1197. package/dist/ui/branding/logos/logo_dark_bg.png +0 -0
  1198. package/dist/ui/branding/logos/logo_favicon_dark.png +0 -0
  1199. package/dist/ui/branding/logos/logo_favicon_dark.svg +56 -0
  1200. package/dist/ui/branding/logos/logo_favicon_light.png +0 -0
  1201. package/dist/ui/branding/logos/logo_light_bg.png +0 -0
  1202. package/dist/ui/images/Taskforce_Van.webp +0 -0
  1203. package/dist/ui/index.html +6 -6
  1204. package/dist/update/uiUpdateService.d.ts +43 -0
  1205. package/dist/update/uiUpdateService.js +149 -0
  1206. package/dist/update/updateCli.d.ts +15 -0
  1207. package/dist/update/updateCli.js +76 -0
  1208. package/dist/update/updateExecutor.d.ts +40 -0
  1209. package/dist/update/updateExecutor.js +474 -0
  1210. package/dist/update/updateStatus.d.ts +83 -0
  1211. package/dist/update/updateStatus.js +703 -0
  1212. package/dist/utils/aiProfileAvatarPaths.d.ts +14 -0
  1213. package/dist/utils/aiProfileAvatarPaths.js +52 -0
  1214. package/dist/utils/aiProfileDefaultLogo.d.ts +7 -0
  1215. package/dist/utils/aiProfileDefaultLogo.js +84 -0
  1216. package/dist/utils/aiProfileEvents.d.ts +9 -1
  1217. package/dist/utils/annotatedAttachments.d.ts +8 -0
  1218. package/dist/utils/annotatedAttachments.js +17 -1
  1219. package/dist/utils/assetTraySorting.d.ts +25 -0
  1220. package/dist/utils/assetTraySorting.js +83 -0
  1221. package/dist/utils/assignees.d.ts +5 -0
  1222. package/dist/utils/assignees.js +14 -9
  1223. package/dist/utils/authLogin.d.ts +10 -0
  1224. package/dist/utils/authLogin.js +8 -0
  1225. package/dist/utils/authSessionEvents.d.ts +2 -0
  1226. package/dist/utils/authSessionEvents.js +6 -0
  1227. package/dist/utils/avatarUpload.js +5 -5
  1228. package/dist/utils/canonicalReferenceAttachments.d.ts +12 -0
  1229. package/dist/utils/canonicalReferenceAttachments.js +42 -0
  1230. package/dist/utils/cloudAssetDisplay.d.ts +2 -0
  1231. package/dist/utils/cloudAssetDisplay.js +8 -0
  1232. package/dist/utils/constants.d.ts +4 -11
  1233. package/dist/utils/constants.js +6 -65
  1234. package/dist/utils/contextAttachmentPreview.d.ts +11 -0
  1235. package/dist/utils/contextAttachmentPreview.js +8 -0
  1236. package/dist/utils/contextAttachmentUpload.d.ts +10 -0
  1237. package/dist/utils/contextAttachmentUpload.js +151 -0
  1238. package/dist/utils/contextFiles.d.ts +1 -1
  1239. package/dist/utils/contextFiles.js +4 -4
  1240. package/dist/utils/documentNames.js +6 -4
  1241. package/dist/utils/entityReferences.d.ts +14 -0
  1242. package/dist/utils/entityReferences.js +21 -0
  1243. package/dist/utils/httpSetCookie.d.ts +3 -0
  1244. package/dist/utils/httpSetCookie.js +22 -0
  1245. package/dist/utils/imageNoteStoragePaths.d.ts +3 -0
  1246. package/dist/utils/imageNoteStoragePaths.js +19 -0
  1247. package/dist/utils/imageReferences.d.ts +6 -0
  1248. package/dist/utils/imageReferences.js +1 -0
  1249. package/dist/utils/planningArchiveOrchestrator.d.ts +23 -0
  1250. package/dist/utils/planningArchiveOrchestrator.js +37 -0
  1251. package/dist/utils/planningArchivePresentation.d.ts +20 -0
  1252. package/dist/utils/planningArchivePresentation.js +23 -0
  1253. package/dist/utils/planningArchiveReadiness.d.ts +26 -0
  1254. package/dist/utils/planningArchiveReadiness.js +30 -0
  1255. package/dist/utils/planningFavorites.d.ts +7 -0
  1256. package/dist/utils/planningFavorites.js +34 -0
  1257. package/dist/utils/syncEventPresentation.js +53 -0
  1258. package/dist/utils/syncStatusPresentation.d.ts +25 -0
  1259. package/dist/utils/syncStatusPresentation.js +86 -5
  1260. package/dist/utils/taskActivity.d.ts +9 -2
  1261. package/dist/utils/taskActivity.js +61 -0
  1262. package/dist/utils/taskDraftDefaults.d.ts +0 -8
  1263. package/dist/utils/taskDraftDefaults.js +0 -4
  1264. package/dist/utils/taskEvents.d.ts +11 -0
  1265. package/dist/utils/taskEvents.js +6 -0
  1266. package/dist/utils/taskHeaderQuickFilter.d.ts +14 -0
  1267. package/dist/utils/taskHeaderQuickFilter.js +32 -0
  1268. package/dist/utils/taskInvalidation.d.ts +23 -0
  1269. package/dist/utils/taskInvalidation.js +67 -0
  1270. package/dist/utils/taskNormalization.d.ts +2 -1
  1271. package/dist/utils/taskNormalization.js +44 -18
  1272. package/dist/utils/taskReferences.d.ts +16 -0
  1273. package/dist/utils/taskReferences.js +63 -0
  1274. package/dist/utils/taskforceAgentEvents.d.ts +8 -0
  1275. package/dist/utils/taskforceAgentEvents.js +6 -0
  1276. package/dist/utils/taskforceAgentSkillEvents.d.ts +7 -0
  1277. package/dist/utils/taskforceAgentSkillEvents.js +8 -0
  1278. package/dist/utils/uiNotice.d.ts +3 -0
  1279. package/dist/utils/uiNotice.js +1 -1
  1280. package/dist/utils/workspaceResourceEvents.d.ts +7 -0
  1281. package/dist/utils/workspaceResourceEvents.js +6 -0
  1282. package/dist/utils/workspaceSyncPresentation.d.ts +24 -0
  1283. package/dist/utils/workspaceSyncPresentation.js +243 -6
  1284. package/package.json +74 -21
  1285. package/dist/components/features/AgentsModule.d.ts +0 -18
  1286. package/dist/components/features/AgentsModule.js +0 -479
  1287. package/dist/components/features/InitiativesModule.d.ts +0 -22
  1288. package/dist/components/features/InitiativesModule.js +0 -33
  1289. package/dist/components/features/WorkflowsModule.d.ts +0 -27
  1290. package/dist/components/features/WorkflowsModule.js +0 -21
  1291. package/dist/components/features/settings/WorkflowEditor.d.ts +0 -15
  1292. package/dist/components/features/settings/WorkflowEditor.js +0 -245
  1293. package/dist/components/views/panels/DocumentFilterToolbar.d.ts +0 -10
  1294. package/dist/components/views/panels/DocumentFilterToolbar.js +0 -7
  1295. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +0 -61
  1296. package/dist/components/views/standalone/modals/AccountHubModal.js +0 -108
  1297. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +0 -19
  1298. package/dist/components/views/standalone/modals/EditProfileModal.js +0 -11
  1299. package/dist/hooks/ui/useResourceExport.d.ts +0 -21
  1300. package/dist/hooks/ui/useResourceExport.js +0 -87
  1301. package/dist/hooks/ui/useWorkflowTemplates.d.ts +0 -37
  1302. package/dist/hooks/ui/useWorkflowTemplates.js +0 -116
  1303. package/dist/mcp/clientProfileDefaults.d.ts +0 -12
  1304. package/dist/mcp/clientProfileDefaults.js +0 -41
  1305. package/dist/resources/templates/WORKFLOW_V2_POLICY.md +0 -55
  1306. package/dist/resources/templates/environments/aider.yaml +0 -14
  1307. package/dist/resources/templates/environments/antigravity.yaml +0 -10
  1308. package/dist/resources/templates/environments/claude.yaml +0 -10
  1309. package/dist/resources/templates/environments/cline.yaml +0 -10
  1310. package/dist/resources/templates/environments/codex.yaml +0 -13
  1311. package/dist/resources/templates/environments/copilot.yaml +0 -10
  1312. package/dist/resources/templates/environments/cursor.yaml +0 -9
  1313. package/dist/resources/templates/environments/gemini.yaml +0 -9
  1314. package/dist/resources/templates/environments/windsurf.yaml +0 -10
  1315. package/dist/resources/templates/workflow-sources/README.md +0 -9
  1316. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +0 -530
  1317. package/dist/resources/templates/workflow-sources/workflowEditorOverrides.json +0 -1
  1318. package/dist/resources/templates/workflows/collaborate.yaml +0 -109
  1319. package/dist/resources/templates/workflows/do.yaml +0 -87
  1320. package/dist/resources/templates/workflows/evaluate.yaml +0 -116
  1321. package/dist/resources/templates/workflows/execute.yaml +0 -156
  1322. package/dist/resources/templates/workflows/plan.yaml +0 -118
  1323. package/dist/resources/templates/workflows/review.yaml +0 -114
  1324. package/dist/services/formatTransformers.d.ts +0 -29
  1325. package/dist/services/formatTransformers.js +0 -56
  1326. package/dist/services/templateEngine.d.ts +0 -46
  1327. package/dist/services/templateEngine.js +0 -148
  1328. package/dist/shared/workflowDefaults.d.ts +0 -9
  1329. package/dist/shared/workflowDefaults.js +0 -11
  1330. package/dist/ui/agent-logos/Gemini CLI.jpeg +0 -0
  1331. package/dist/ui/agent-logos/antigravity.jpeg +0 -0
  1332. package/dist/ui/agent-logos/chatgpt.png +0 -0
  1333. package/dist/ui/agent-logos/claude-code.jpeg +0 -0
  1334. package/dist/ui/agent-logos/codex.jpeg +0 -0
  1335. package/dist/ui/agent-logos/cursor.png +0 -0
  1336. package/dist/ui/agent-logos/openclaw.jpeg +0 -0
  1337. package/dist/ui/agent-logos/windsurf.png +0 -0
  1338. package/dist/ui/assets/AgentsModule-C4LcqhcZ.js +0 -1
  1339. package/dist/ui/assets/AnnotatedAttachmentWorkspace-B-Dq22d2.js +0 -3
  1340. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +0 -1
  1341. package/dist/ui/assets/ContextAttachmentManager-DsXPTvi-.js +0 -3
  1342. package/dist/ui/assets/DocumentWorkspace-CxA1wO3U.js +0 -252
  1343. package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +0 -1
  1344. package/dist/ui/assets/EntityActivityTimeline-B8nSe8l3.js +0 -1
  1345. package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +0 -1
  1346. package/dist/ui/assets/InitiativesModule-VY95v38E.js +0 -1
  1347. package/dist/ui/assets/PlansPage-CQbKDv1a.js +0 -1
  1348. package/dist/ui/assets/PlansPage-DeAzWYTb.css +0 -1
  1349. package/dist/ui/assets/TaskContextUpload-DvDlNpHC.js +0 -1
  1350. package/dist/ui/assets/TaskSettings-CUWbYYtP.js +0 -12
  1351. package/dist/ui/assets/WorkflowsModule-CgM3Jako.js +0 -5
  1352. package/dist/ui/assets/documentReferences-Do9YjrS3.js +0 -1
  1353. package/dist/ui/assets/index--mh3pktj.js +0 -5
  1354. package/dist/ui/assets/index-BawaaEXS.css +0 -1
  1355. package/dist/ui/assets/vendor-router-BbWMxlnO.js +0 -3
  1356. package/dist/ui/branding/logos/logo_black_01.png +0 -0
  1357. package/dist/ui/branding/logos/logo_black_02.png +0 -0
  1358. package/dist/ui/branding/logos/logo_white_01.png +0 -0
  1359. package/dist/ui/branding/logos/logo_white_02.png +0 -0
  1360. package/scripts/generate-workflow-templates.mjs +0 -134
  1361. package/src/resources/templates/WORKFLOW_V2_POLICY.md +0 -55
  1362. package/src/resources/templates/environments/aider.yaml +0 -14
  1363. package/src/resources/templates/environments/antigravity.yaml +0 -10
  1364. package/src/resources/templates/environments/claude.yaml +0 -10
  1365. package/src/resources/templates/environments/cline.yaml +0 -10
  1366. package/src/resources/templates/environments/codex.yaml +0 -13
  1367. package/src/resources/templates/environments/copilot.yaml +0 -10
  1368. package/src/resources/templates/environments/cursor.yaml +0 -9
  1369. package/src/resources/templates/environments/gemini.yaml +0 -9
  1370. package/src/resources/templates/environments/windsurf.yaml +0 -10
  1371. package/src/resources/templates/workflow-sources/README.md +0 -9
  1372. package/src/resources/templates/workflow-sources/workflowDocs.mjs +0 -530
  1373. package/src/resources/templates/workflow-sources/workflowEditorOverrides.json +0 -1
  1374. package/src/resources/templates/workflows/collaborate.yaml +0 -109
  1375. package/src/resources/templates/workflows/do.yaml +0 -87
  1376. package/src/resources/templates/workflows/evaluate.yaml +0 -116
  1377. package/src/resources/templates/workflows/execute.yaml +0 -156
  1378. package/src/resources/templates/workflows/plan.yaml +0 -118
  1379. package/src/resources/templates/workflows/review.yaml +0 -114
  1380. /package/dist/ui/branding/logos/{logo_dark.svg → logo_dark_no_bg.svg} +0 -0
  1381. /package/dist/ui/branding/logos/{logo_favicon.svg → logo_favicon_light.svg} +0 -0
  1382. /package/dist/ui/branding/logos/{logo_light.svg → logo_light_no_bg.svg} +0 -0
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useMemo, useCallback, useState, useEffect, useRef, Suspense } from 'react';
2
+ import React, { useMemo, useCallback, useState, useEffect, useRef, useLayoutEffect, Suspense } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { useLocation, useNavigate } from 'react-router-dom';
5
- import { Settings, Plus, Filter, Layers, User, Maximize2, Minimize2, Check, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, AlertTriangle, Save, Loader2, Folder, FileText, LogOut, NotebookTabs, ClipboardCheck, Cloud, CloudOff, Users, ClockAlert, Mail, ChevronsUp, ChevronsDown, EyeOff, Zap, HelpCircle, Bot, Image, Workflow, Plug } from 'lucide-react';
5
+ import { Settings, Plus, Filter, Layers, User, Maximize2, Minimize2, Check, X, ChevronLeft, ChevronRight, ArrowUp, ArrowDown, ArrowUpDown, AlertTriangle, Save, Loader2, Folder, FileText, LogOut, NotebookTabs, ClipboardCheck, Cloud, CloudOff, Users, ClockAlert, ChevronsUp, ChevronsDown, EyeOff, Zap, HelpCircle, Bot, Image, Plug, Workflow } from 'lucide-react';
6
6
  import { STATUS_OPTIONS, getStatusDefinition } from '../../utils/constants';
7
7
  import styles from '../../Taskforce.module.css';
8
8
  import shellStyles from './WorkspaceShell.module.css';
@@ -11,45 +11,62 @@ import authStyles from './AuthShell.module.css';
11
11
  import folderBrowserStyles from './FolderBrowser.module.css';
12
12
  import modalStyles from '../ui/Modal.module.css';
13
13
  import { CreateWorkspaceConfirmModal } from './standalone/modals/CreateWorkspaceConfirmModal';
14
- import { AccountHubModal } from './standalone/modals/AccountHubModal';
14
+ import { AccountSettingsModal } from './standalone/modals/AccountSettingsModal';
15
15
  import { AvatarImageManagerModal } from './standalone/modals/AvatarImageManagerModal';
16
- import { EditProfileModal } from './standalone/modals/EditProfileModal';
17
16
  import { HelpModal } from './standalone/modals/HelpModal';
18
17
  import { ScheduleWarningModal } from './standalone/modals/ScheduleWarningModal';
19
18
  import { SyncEnableWarningModal } from './standalone/modals/SyncEnableWarningModal';
20
19
  import { SyncStatusModal } from './standalone/modals/SyncStatusModal';
21
20
  import { TeamManagementModal } from './standalone/modals/TeamManagementModal';
21
+ import { getDeletedTaskExpiresAt } from '../../shared/deletedTaskRetention';
22
22
  import { Modal } from '../ui/Modal';
23
+ import { DiscardChangesDialog } from '../ui/DiscardChangesDialog';
23
24
  import { TaskForm } from '../task/TaskForm';
25
+ import { AttachmentPreviewHost } from '../context/AttachmentPreviewHost';
24
26
  import { TaskKanban } from '../task/TaskKanban';
25
27
  import { TaskActionHeader } from '../task/TaskActionHeader';
28
+ import { TrashRestoreControls } from '../task/TrashRestoreControls';
26
29
  import { TopNoticeLayer } from '../ui/TopNoticeLayer';
27
30
  import { TypeMeta } from '../../utils/constants';
28
31
  import { resolveDraftDefaultsForGrouping } from '../../utils/taskDraftDefaults';
29
32
  import { formatDate } from '../../utils/formatting';
30
- import { resolveHeaderWorkspaceSyncPresentation } from '../../utils/workspaceSyncPresentation';
33
+ import { resolveCoordinatorWorkspaceSyncPresentation, resolveHeaderWorkspaceSyncPresentation, } from '../../utils/workspaceSyncPresentation';
31
34
  import { getTaskReferenceLabel, parseTaskReference } from '../../utils/taskReferences';
35
+ import { useTaskReferenceContract } from '../../hooks/tasks/useTaskReferenceContract';
36
+ import { useTrashSelection } from '../../hooks/tasks/useTrashSelection';
32
37
  import { normalizeTaskSearchQuery, taskMatchesSearch } from '../../utils/taskSearch';
38
+ import { matchesTaskHeaderQuickFilter, useTaskHeaderQuickFilter } from '../../utils/taskHeaderQuickFilter';
33
39
  import { formatInitiativeReference, formatWorkstreamReference, parseWorkstreamReference, resolveInitiativeReference } from '../../utils/planningReferences';
34
40
  import { DEFAULT_TYPE_VALUE } from '../../shared/taxonomyDefaults.js';
35
41
  import { getImageReferenceLabel } from '../../utils/imageReferences';
42
+ import { TASK_DEEP_LINK_QUERY_KEYS } from '../../shared/taskDeepLinks';
36
43
  import { isPlanningEntityVisibleForScope, scopePlanningSummaries, scopeTasksToPlanningSelection } from './planningScope';
37
- import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, } from '../../utils/syncStatusPresentation';
44
+ import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, resolveHeaderSyncStatusMeta, } from '../../utils/syncStatusPresentation';
38
45
  import { buildCustomTaxonomySortOptions } from '../../utils/taxonomySorting.js';
39
46
  import { getLocale, t } from '../../localization';
40
- import { resolveAnnotatedAttachmentDetail } from '../../utils/annotatedAttachments';
47
+ import { getAnnotatedAttachmentContextIdentity, resolveAnnotatedAttachmentDetail, shouldApplyPersistedAnnotatedAttachmentContext, } from '../../utils/annotatedAttachments';
48
+ import { dispatchPreviewContextAttachment } from '../../utils/contextAttachmentPreview';
49
+ import { parseCanonicalEntityReference, } from '../../utils/entityReferences';
50
+ import { resolveCanonicalAttachmentReference } from '../../utils/canonicalReferenceAttachments';
41
51
  import { ACCOUNT_PROFILE_SUMMARY_PATH, invalidateAccountProfileSummaryCache, loadAccountProfileSummaryCached } from '../../utils/accountProfileSummaryCache';
42
52
  import { prepareAvatarUploadFile } from '../../utils/avatarUpload';
43
53
  import { resolveCommercialLifecyclePresentation } from '../../utils/commercialLifecyclePresentation';
44
54
  import { buildSupportMailtoHref } from '../../utils/supportContact';
55
+ import { mergePlanningLifetimeTasks, resolveInitiativeArchiveReadiness, resolveWorkstreamArchiveReadiness, } from '../../utils/planningArchiveReadiness';
56
+ import { archiveResolvedInitiativeHierarchy, archiveResolvedWorkstreamHierarchy, } from '../../utils/planningArchiveOrchestrator';
57
+ import { resolvePlanningArchiveDetailState } from '../../utils/planningArchivePresentation';
45
58
  import { AppShellHeader } from './AppShellHeader';
46
59
  import { getTaskforceCloudEnvironmentConfig, parseTaskforceCloudEnvironment, resolveTaskforceCloudEnvironmentFromBaseUrl } from '../../config/cloudEnvironment';
47
- import { logBootstrapDebug, persistRemoteUiState } from '../../hooks/workspace/workspaceLocalState';
60
+ import { logBootstrapDebug } from '../../hooks/workspace/workspaceLocalState';
61
+ import { buildLayoutUiStateLoadKey, usePersistedLayoutUiState, } from '../../hooks/workspace/usePersistedLayoutUiState';
62
+ import { togglePlanningFavorite } from '../../utils/planningFavorites';
48
63
  import { FilterToolbar } from './panels/FilterToolbar';
49
- import { DocumentFilterToolbar } from './panels/DocumentFilterToolbar';
50
64
  import { PlanningDrawer, getPlanningDrawerWidthPx, } from './panels/PlanningDrawer';
65
+ import { normalizePlanningTaskArrangeMode, } from '../features/planning/planningTaskArrangement';
66
+ import { resolveWorkstreamCreateInitiativeId } from '../features/planning/planningCreateIntent';
67
+ import { shouldUsePlanningBootstrapTaskSummaries } from '../features/planning/planningWorkspaceModel';
51
68
  import { getWorkspaceChromeDefinition, getWorkspaceModuleDefinitions, resolveWorkspaceModule, } from './chrome/workspaceChrome';
52
- import { EmptyWorkspaceFilterBar, WorkspaceHeaderActions, WorkspaceHeaderDivider, WorkspaceHeaderSearch, WorkspaceHeaderSelect, WorkspacePrimaryAction, } from './chrome/WorkspaceChromeSections';
69
+ import { WorkspaceHeaderActions, WorkspaceHeaderDivider, WorkspaceHeaderSearch, WorkspaceHeaderSelect, WorkspacePrimaryAction, } from './chrome/WorkspaceChromeSections';
53
70
  import { ScheduleSidebar, SCHEDULE_SIDEBAR_WIDTH_PX } from './panels/ScheduleSidebar';
54
71
  import { DOCUMENT_ATTACHMENT_FILTER_OPTIONS, DOCUMENT_TYPE_FILTER_OPTIONS, } from '../features/documentWorkspaceFilters';
55
72
  import { canManageTeamWorkspace as computeCanManageTeamWorkspace, canOpenTeamManagement as computeCanOpenTeamManagement } from './teamManagementAccess';
@@ -57,17 +74,29 @@ import { useRecentSyncEvents } from '../../hooks/sync/useRecentSyncEvents';
57
74
  import { useSyncStatusActions } from '../../hooks/sync/useSyncStatusActions';
58
75
  import { useSyncStatusControls } from '../../hooks/sync/useSyncStatusControls';
59
76
  import { toDateOnlyLocal, parseDateOnlyLocal, startOfWeek, getDayOffsetFromWeekStart, addDays, dateOnlyToIsoWeekKey, SCHEDULE_DAY_KEYS, SCHEDULE_DAY_LABELS, } from './panels/scheduleUtils';
60
- import { AGENTS_WORKSPACE_FEATURE_KEY, ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY, DOCUMENT_WORKSPACE_FEATURE_KEY, INITIATIVES_WORKSPACE_FEATURE_KEY, WORKFLOWS_WORKSPACE_FEATURE_KEY, resolveFeatureAccess, } from '../../runtime/appGates';
77
+ import { AI_PROFILES_WORKSPACE_FEATURE_KEY, ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY, DOCUMENT_WORKSPACE_FEATURE_KEY, PLANNING_WORKSPACE_FEATURE_KEY, TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY, WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY, resolveFeatureAccess, } from '../../runtime/appGates';
61
78
  // Heavy feature modules — lazy-loaded to reduce the initial app chunk size.
62
79
  const TaskSettings = React.lazy(() => import('../features/TaskSettings').then(m => ({ default: m.TaskSettings })));
63
80
  const AnnotatedAttachmentWorkspaceShell = React.lazy(() => import('../features/AnnotatedAttachmentWorkspace').then(m => ({ default: m.AnnotatedAttachmentWorkspaceShell })));
64
81
  const DocumentWorkspaceShell = React.lazy(() => import('../features/DocumentWorkspace').then(m => ({ default: m.DocumentWorkspaceShell })));
65
- const WorkflowsModule = React.lazy(() => import('../features/WorkflowsModule').then(m => ({ default: m.WorkflowsModule })));
66
- const AgentsModule = React.lazy(() => import('../features/AgentsModule').then(m => ({ default: m.AgentsModule })));
67
- const InitiativesModule = React.lazy(() => import('../features/InitiativesModule').then(m => ({ default: m.InitiativesModule })));
82
+ const TaskforceAgentsModule = React.lazy(() => import('../features/TaskforceAgentsModule').then(m => ({ default: m.TaskforceAgentsModule })));
83
+ const WorkflowManagerModule = React.lazy(() => import('../features/workflowManager/WorkflowManagerModule').then(m => ({ default: m.WorkflowManagerModule })));
84
+ const AiProfilesModule = React.lazy(() => import('../features/AiProfilesModule').then(m => ({ default: m.AiProfilesModule })));
85
+ const PlanningModule = React.lazy(() => import('../features/planning/PlanningModule').then(m => ({ default: m.PlanningModule })));
68
86
  const PlansPage = React.lazy(() => import('./PlansPage').then(m => ({ default: m.PlansPage })));
87
+ const MAX_REMEMBERED_LAYOUT_ITEMS = 50;
88
+ function withBoundedRecordEntry(current, key, value) {
89
+ const normalizedKey = key.trim();
90
+ if (!normalizedKey)
91
+ return current;
92
+ const next = { ...current };
93
+ delete next[normalizedKey];
94
+ next[normalizedKey] = value;
95
+ return Object.fromEntries(Object.entries(next).slice(-MAX_REMEMBERED_LAYOUT_ITEMS));
96
+ }
69
97
  const PROFILE_AVATAR_ACCEPT = 'image/png,image/jpeg,image/webp,image/gif';
70
98
  const PROFILE_AVATAR_MAX_BYTES = 5 * 1024 * 1024;
99
+ const TASKFORCE_AGENT_DRAWER_FALLBACK_TOP = 56;
71
100
  const resolveSameOriginTaskforcePath = (path) => path;
72
101
  function resolveConnectedEnvironmentLabel(explicitEnvironment, candidates) {
73
102
  const parsedExplicitEnvironment = parseTaskforceCloudEnvironment(explicitEnvironment);
@@ -140,13 +169,13 @@ export function StandaloneLayout(props) {
140
169
  // State
141
170
  activeTab, setActiveTab, activeCategories, groupBy, setGroupBy, activeWorkspaceModule, setActiveWorkspaceModule, emptyColumnMode, setEmptyColumnMode, zenMode, setZenMode, filterStatus, setFilterStatus,
142
171
  // Data & Actions
143
- tasks, handleEdit, handleSubmit, resetForm, handleUpdateTask,
172
+ tasks, handleEdit, handleSubmit, resetForm, discardDescriptionImageDraft, handleUpdateTask, handleSetStatus: handleSetStatusDurably,
144
173
  // Form State (destructure all needed for TaskForm)
145
- editingTaskId, loading, error, title, setTitle, description, setDescription, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, setStatus, approach, setApproach, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, setAttachmentsDirty, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp, showChecklist, setShowChecklist, showComments, setShowComments,
174
+ editingTaskId, loading, error, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, attachmentsDirty, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
146
175
  // Form Actions
147
176
  handleAddComment, handleSetWorkstreamForCurrentTask, handleOpenTaskById,
148
177
  // Other Props for Form
149
- taxonomies, activeTypes, priorities, taxonomyDisplayLabels, approaches, copiedId, handleCopyId, handleToggleInProgress, handleToggleComplete, handleToggleReview, handleToggleCancel, handleArchiveTask, handleDelete, handleUnarchive, handleRestoreDeletedTask, handlePermanentlyDeleteDeletedTask, handleEmptyDeletedTasks, fetchTasks, searchQuery, setSearchQuery, filterCategories, setFilterCategories, filterTypes, setFilterTypes, filterPriorities, setFilterPriorities, filterAssignees, setFilterAssignees, hasInitedFilters, assigneeOptions, taskScope, setTaskScope,
178
+ taxonomies, activeTypes, priorities, taxonomyDisplayLabels, copiedId, handleCopyId, handleToggleInProgress, handleToggleComplete, handleToggleReview, handleToggleCancel, handleArchiveTask, handleDelete, handleUnarchive, handleRestoreDeletedTask, handleRestoreSelectedDeletedTasks, handlePermanentlyDeleteDeletedTask, handleEmptyDeletedTasks, fetchTasks, searchQuery, setSearchQuery, filterCategories, setFilterCategories, filterTypes, setFilterTypes, filterPriorities, setFilterPriorities, filterAssignees, setFilterAssignees, hasInitedFilters, assigneeOptions, taskScope, setTaskScope, compressedCards, setCompressedCards,
150
179
  // filterStatus, setFilterStatus, // This was duplicated, removed one instance
151
180
  sortBy, setSortBy, clearFilters, // setSearchQuery, // This was duplicated, removed one instance
152
181
  // filterCategories, setFilterCategories, // This was duplicated, removed one instance
@@ -157,19 +186,18 @@ export function StandaloneLayout(props) {
157
186
  // clearFilters, // This was duplicated, removed one instance
158
187
  // activeTypes, // This was duplicated, removed one instance
159
188
  // Settings State & Props
160
- settingsModel, configLoaded, currentTheme, setCurrentTheme, pathSaved, saveSettings, keyShortcut, setKeyShortcut, globalWeekStartsOn, locale, jsonBackupEnabled, setJsonBackupEnabled, mcpHostRoot, setMcpHostRoot, settingsSection, setSettingsSection, runtimeMode, workspaceSwitchingEnabled, cloudAuthConfigured, authRequiredForApi, authBlocked, isAuthenticated, authUserId, authWorkspaceId, authUserEmail, authUserDisplayName, authUserAvatarUrl, authSessionResolved, realtimeSyncEnabled, realtimeSyncFlagSource, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceSyncStatus, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncBusy, workspaceSyncPendingChanges, saveWorkspaceCloudSyncSettings, pushNotice, userGlobalSyncStatus, workspaceLastSuccessfulSyncAt, workspaceLastPullAt, workspaceLastPushAt, workspaceLastErrorAt, userGlobalSyncError, workspaceLastErrorMessage, retryWorkspaceCloudSync, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics, currentWorkspaceId, currentWorkspaceRole, availableWorkspaces, switchWorkspace, updateCurrentUserProfile, resolveCloudAuthUrl = resolveSameOriginTaskforcePath, logout, fetchLoginMethods, unlinkLoginMethod, addPasswordToAccount, beginOAuthLogin, beginOAuthLink, availableAuthProviders, projectRoot, projectName, mcpScriptPath, serverHostRoot,
189
+ settingsModel, configLoaded, currentTheme, setCurrentTheme, pathSaved, saveSettings, keyShortcut, setKeyShortcut, globalWeekStartsOn, locale, jsonBackupEnabled, setJsonBackupEnabled, mcpHostRoot, setMcpHostRoot, settingsSection, setSettingsSection, runtimeMode, workspaceSwitchingEnabled, cloudAuthConfigured, authRequiredForApi, authBlocked, isAuthenticated, authUserId, authWorkspaceId, authUserEmail, authUserDisplayName, authUserAvatarUrl, authSessionResolved, realtimeSyncEnabled, realtimeSyncFlagSource, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceSyncStatus, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncBusy, workspaceSyncPendingChanges, localCoordinatorStatus, transferLocalCoordinatorOwnership, saveWorkspaceCloudSyncSettings, pushNotice, userGlobalSyncStatus, workspaceLastSuccessfulSyncAt, workspaceLastPullAt, workspaceLastPushAt, workspaceLastErrorAt, userGlobalSyncError, workspaceLastErrorMessage, retryWorkspaceCloudSync, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics, currentWorkspaceId, currentWorkspaceRole, availableWorkspaces, switchWorkspace, updateCurrentUserProfile, resolveCloudAuthUrl = resolveSameOriginTaskforcePath, logout, fetchLoginMethods, unlinkLoginMethod, addPasswordToAccount, changePassword, beginOAuthLogin, beginOAuthLink, availableAuthProviders, projectRoot, projectName, mcpScriptPath, serverHostRoot,
161
190
  // Browser Props
162
191
  showFolderBrowser, setShowFolderBrowser, folders, files, currentBrowsePath, fetchFolders, browserTarget, setBrowserTarget, handleSelectPath, handleAddPath, handleRemovePath,
163
192
  // Settings Managers
164
- handleUpdateCategory, handleRemoveCategory, handleSaveCategory, handleUpdateCategoryIcon, handleUpdateCategoryColor, handleSaveType, handleRemoveType, handleUpdateTaxonomies, handleUpdatePriorities, pathValidation,
165
- // Exports
166
- exportEnvironment, setExportEnvironment, exportWorkflowsPath, setExportWorkflowsPath, exportResult, exportingResource, availableWorkflows, onExportWorkflows, fetchWorkflows, availableEnvironments, initiativeTemplates, fetchInitiativeTemplates, createInitiativeFromTemplate,
193
+ handleUpdateCategory, handleRemoveCategory, handleSaveCategory, handleUpdateCategoryIcon, handleUpdateCategoryColor, handleSaveType, handleRemoveType, handleUpdateTaxonomies, handleUpdatePriorities, pathValidation, taskforceAgentId, setTaskforceAgentId, taskforceAgentConversationId, setTaskforceAgentConversationId, taskforceAgentConversationByAgentId, setTaskforceAgentConversationByAgentId, uiStateReady, initiativeTemplates, fetchInitiativeTemplates, createInitiativeFromTemplate,
167
194
  // Misc
168
- uiNotice, clearNotice, taskReturnTrail, clearReturnToParentTask, returnToPreviousTask, tasksScrollRef, setTasksScrollPos,
195
+ uiNotice, clearNotice, clearTaskError, taskReturnTrail, clearReturnToParentTask, returnToPreviousTask, tasksScrollRef, setTasksScrollPos,
169
196
  // Refs
170
197
  commentsEndRef,
171
198
  // Modals - Unsaved Changes
172
199
  autoSaveState, unsavedModalOpen, setUnsavedModalOpen, pendingNavigation, handleNavigation, currentTask, currentTaskWorkstream, currentTaskInitiative, scheduleWarningPrompt, confirmScheduleWarning, cancelScheduleWarning } = props;
200
+ const taskReferences = useTaskReferenceContract(tasks, handleOpenTaskById);
173
201
  const resolvedLocale = locale || getLocale();
174
202
  useEffect(() => {
175
203
  const normalizedProject = String(projectName || '').trim();
@@ -178,6 +206,9 @@ export function StandaloneLayout(props) {
178
206
  // Handlers
179
207
  const handleDiscard = () => {
180
208
  setUnsavedModalOpen(false);
209
+ if (activeTab === 'add' && !editingTaskId) {
210
+ void discardDescriptionImageDraft();
211
+ }
181
212
  if (pendingNavigation) {
182
213
  if (activeTab === 'add')
183
214
  resetForm();
@@ -198,8 +229,6 @@ export function StandaloneLayout(props) {
198
229
  pendingNavigation();
199
230
  }
200
231
  };
201
- // State for Card Compression
202
- const [compressedCards, setCompressedCards] = useState(false);
203
232
  const [scheduleShowWeekends, setScheduleShowWeekends] = useState(false);
204
233
  const [scheduleShowBacklog, setScheduleShowBacklog] = useState(true);
205
234
  const [scheduleOnlyExpired, setScheduleOnlyExpired] = useState(false);
@@ -213,43 +242,75 @@ export function StandaloneLayout(props) {
213
242
  const [showFilters, setShowFilters] = useState(false);
214
243
  const [taskModalFullscreen, setTaskModalFullscreen] = useState(false);
215
244
  const [planningDrawerOpen, setPlanningDrawerOpen] = useState(false);
245
+ const planningDrawerLauncherRef = useRef(null);
216
246
  const [documentTrayOpen, setDocumentTrayOpen] = useState(true);
217
247
  const [imageTrayOpen, setImageTrayOpen] = useState(true);
218
248
  const [agentTrayOpen, setAgentTrayOpen] = useState(true);
249
+ const [taskforceAgentRosterTrayOpen, setTaskforceAgentRosterTrayOpen] = useState(true);
250
+ const [workflowLibraryTrayOpen, setWorkflowLibraryTrayOpen] = useState(true);
251
+ const [workflowManagerHasUnsavedChanges, setWorkflowManagerHasUnsavedChanges] = useState(false);
252
+ const [pendingWorkflowDiscardAction, setPendingWorkflowDiscardAction] = useState(null);
253
+ const workflowDiscardBypassRef = useRef(false);
254
+ const appShellHeaderRef = useRef(null);
255
+ const [taskforceAgentDrawerTop, setTaskforceAgentDrawerTop] = useState(TASKFORCE_AGENT_DRAWER_FALLBACK_TOP);
219
256
  const [planningTreeCollapsed, setPlanningTreeCollapsed] = useState(false);
220
257
  const [planningPrimaryCollapsed, setPlanningPrimaryCollapsed] = useState(false);
221
258
  const [planningSecondaryCollapsed, setPlanningSecondaryCollapsed] = useState(false);
259
+ const [planningFavoritesSectionCollapsed, setPlanningFavoritesSectionCollapsed] = useState(false);
260
+ const [planningInitiativesSectionCollapsed, setPlanningInitiativesSectionCollapsed] = useState(false);
261
+ const [planningWorkstreamsSectionCollapsed, setPlanningWorkstreamsSectionCollapsed] = useState(false);
262
+ const [planningNavigatorSort, setPlanningNavigatorSort] = useState('default');
263
+ const [planningTaskArrangeMode, setPlanningTaskArrangeMode] = useState('execution');
264
+ const [planningFavorites, setPlanningFavorites] = useState([]);
222
265
  const [selectedPlanningInitiativeId, setSelectedPlanningInitiativeId] = useState('');
223
266
  const [selectedPlanningWorkstreamId, setSelectedPlanningWorkstreamId] = useState('');
224
267
  const [expandedPlanningInitiativeIds, setExpandedPlanningInitiativeIds] = useState(new Set());
225
268
  const [planningDrawerDetail, setPlanningDrawerDetail] = useState(null);
226
269
  const [planningNestedWorkstreamDetailId, setPlanningNestedWorkstreamDetailId] = useState(null);
270
+ const [planningHydrationStateByEntity, setPlanningHydrationStateByEntity] = useState({});
227
271
  const [planningEditor, setPlanningEditor] = useState(null);
228
272
  const [planningSecondaryEditor, setPlanningSecondaryEditor] = useState(null);
229
273
  const [planningDraftTitle, setPlanningDraftTitle] = useState('');
230
274
  const [planningDraftDescription, setPlanningDraftDescription] = useState('');
231
275
  const [planningDraftOwner, setPlanningDraftOwner] = useState('');
232
276
  const [planningDraftInitiativeId, setPlanningDraftInitiativeId] = useState('');
277
+ const [planningDraftIcon, setPlanningDraftIcon] = useState(null);
278
+ const [planningDraftColor, setPlanningDraftColor] = useState(null);
233
279
  const [isSubmittingPlanningEditor, setIsSubmittingPlanningEditor] = useState(false);
234
280
  const taskContextAttachmentDraftRef = useRef({
235
281
  taskId: null,
236
282
  attachments: [],
237
283
  });
284
+ const todayDateOnly = useMemo(() => toDateOnlyLocal(new Date()), []);
285
+ const normalizedAuthUserId = String(authUserId || '').trim();
286
+ const { taskHeaderQuickFilter, toggleTaskHeaderQuickFilter, clearTaskHeaderQuickFilter, } = useTaskHeaderQuickFilter({
287
+ authUserId: normalizedAuthUserId,
288
+ workspaceId: currentWorkspaceId,
289
+ taskScope,
290
+ });
238
291
  const planningContextAttachmentDraftsRef = useRef(new Map());
239
292
  const planningContextAttachmentUpdateQueueRef = useRef(new Map());
240
293
  const [documentTypeFilters, setDocumentTypeFilters] = useState(() => DOCUMENT_TYPE_FILTER_OPTIONS.map((option) => option.value));
241
294
  const [documentAttachmentFilters, setDocumentAttachmentFilters] = useState(() => DOCUMENT_ATTACHMENT_FILTER_OPTIONS.map((option) => option.value));
295
+ const [documentSortField, setDocumentSortField] = useState('updated');
296
+ const [documentSortOrder, setDocumentSortOrder] = useState('desc');
297
+ const [documentPinnedDocIds, setDocumentPinnedDocIds] = useState([]);
298
+ const [documentSearchQuery, setDocumentSearchQuery] = useState('');
299
+ const [documentSelectedDocId, setDocumentSelectedDocId] = useState(null);
300
+ const [documentScrollByDocId, setDocumentScrollByDocId] = useState({});
301
+ const [documentListScrollTop, setDocumentListScrollTop] = useState(0);
242
302
  const [requestedDocPath, setRequestedDocPath] = useState(null);
243
303
  const [requestedDocAssetId, setRequestedDocAssetId] = useState(null);
244
304
  const [requestedAnnotatedTarget, setRequestedAnnotatedTarget] = useState(null);
245
305
  const [requestedAnnotatedSessionId, setRequestedAnnotatedSessionId] = useState(null);
306
+ const [annotatedViewportByContextKey, setAnnotatedViewportByContextKey] = useState({});
246
307
  const [requestedAnnotatedOpenVersion, setRequestedAnnotatedOpenVersion] = useState(0);
308
+ const handledEntityDeepLinkRef = useRef(null);
247
309
  const [canonicalAnnotatedImageReferenceLabels, setCanonicalAnnotatedImageReferenceLabels] = useState({});
248
- const [layoutStateReady, setLayoutStateReady] = useState(false);
249
310
  const planningEditorSubmitInFlightRef = useRef(false);
250
- const loadedLayoutStateWorkspaceRef = useRef('');
251
311
  const requestedAnnotatedTargetRef = useRef(null);
252
312
  const requestedAnnotatedSessionIdRef = useRef(null);
313
+ const lastHydratedAnnotatedContextIdentityRef = useRef(null);
253
314
  const annotatedImageReferenceFetchesRef = useRef(new Set());
254
315
  useEffect(() => {
255
316
  taskContextAttachmentDraftRef.current = {
@@ -269,7 +330,15 @@ export function StandaloneLayout(props) {
269
330
  setAttachments(nextAttachments);
270
331
  setAttachmentsDirty(true);
271
332
  if (taskId) {
272
- void handleUpdateTask(taskId, { attachments: nextAttachments });
333
+ void handleUpdateTask(taskId, { attachments: nextAttachments }).then((saved) => {
334
+ const latestDraft = taskContextAttachmentDraftRef.current;
335
+ if (saved !== false && latestDraft.taskId === taskId
336
+ && latestDraft.attachments === nextAttachments) {
337
+ setAttachmentsDirty(false);
338
+ }
339
+ }).catch(() => {
340
+ // Keep the attachment draft dirty so the editor can retry it.
341
+ });
273
342
  }
274
343
  }, [attachments, editingTaskId, handleUpdateTask, setAttachments, setAttachmentsDirty]);
275
344
  const workspaceUiStateHeaders = useMemo(() => {
@@ -280,8 +349,15 @@ export function StandaloneLayout(props) {
280
349
  }
281
350
  return headers;
282
351
  }, [runtimeMode, currentWorkspaceId]);
283
- const layoutStateWorkspaceKey = useMemo(() => `${runtimeMode}:${String(currentWorkspaceId || 'default').trim() || 'default'}`, [runtimeMode, currentWorkspaceId]);
284
- const annotatedLayoutCacheKey = useMemo(() => `taskforce:annotate-layout:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
352
+ const layoutStateWorkspaceKey = useMemo(() => buildLayoutUiStateLoadKey({
353
+ runtimeMode,
354
+ workspaceId: currentWorkspaceId,
355
+ userId: normalizedAuthUserId,
356
+ }), [currentWorkspaceId, normalizedAuthUserId, runtimeMode]);
357
+ const annotatedContextScopeRef = useRef(layoutStateWorkspaceKey);
358
+ const annotatedContextMatchesLayoutScope = annotatedContextScopeRef.current === layoutStateWorkspaceKey;
359
+ const scopedRequestedAnnotatedTarget = annotatedContextMatchesLayoutScope ? requestedAnnotatedTarget : null;
360
+ const scopedRequestedAnnotatedSessionId = annotatedContextMatchesLayoutScope ? requestedAnnotatedSessionId : null;
285
361
  const taskOriginWorkspaceModuleKey = useMemo(() => `taskforce:task-origin-workspace-module:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
286
362
  const annotatedWorkspaceReady = useMemo(() => (runtimeMode === 'cloud' ? authSessionResolved : configLoaded), [authSessionResolved, configLoaded, runtimeMode]);
287
363
  const openedTaskOriginWorkspaceModuleRef = useRef(false);
@@ -315,6 +391,16 @@ export function StandaloneLayout(props) {
315
391
  useEffect(() => {
316
392
  requestedAnnotatedSessionIdRef.current = requestedAnnotatedSessionId;
317
393
  }, [requestedAnnotatedSessionId]);
394
+ useEffect(() => {
395
+ if (annotatedContextScopeRef.current === layoutStateWorkspaceKey)
396
+ return;
397
+ annotatedContextScopeRef.current = layoutStateWorkspaceKey;
398
+ requestedAnnotatedTargetRef.current = null;
399
+ requestedAnnotatedSessionIdRef.current = null;
400
+ lastHydratedAnnotatedContextIdentityRef.current = null;
401
+ setRequestedAnnotatedTarget(null);
402
+ setRequestedAnnotatedSessionId(null);
403
+ }, [layoutStateWorkspaceKey]);
318
404
  const workspaceFeatureAccess = useMemo(() => ({
319
405
  [DOCUMENT_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
320
406
  featureKey: DOCUMENT_WORKSPACE_FEATURE_KEY,
@@ -324,25 +410,75 @@ export function StandaloneLayout(props) {
324
410
  featureKey: ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY,
325
411
  runtimeMode,
326
412
  }),
327
- [WORKFLOWS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
328
- featureKey: WORKFLOWS_WORKSPACE_FEATURE_KEY,
413
+ [WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
414
+ featureKey: WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY,
329
415
  runtimeMode,
330
416
  }),
331
- [AGENTS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
332
- featureKey: AGENTS_WORKSPACE_FEATURE_KEY,
417
+ [TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
418
+ featureKey: TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY,
333
419
  runtimeMode,
334
420
  }),
335
- [INITIATIVES_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
336
- featureKey: INITIATIVES_WORKSPACE_FEATURE_KEY,
421
+ [AI_PROFILES_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
422
+ featureKey: AI_PROFILES_WORKSPACE_FEATURE_KEY,
423
+ runtimeMode,
424
+ }),
425
+ [PLANNING_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
426
+ featureKey: PLANNING_WORKSPACE_FEATURE_KEY,
337
427
  runtimeMode,
338
428
  }),
339
429
  }), [runtimeMode]);
340
430
  const workspaceModules = useMemo(() => getWorkspaceModuleDefinitions({ featureAccess: workspaceFeatureAccess }), [workspaceFeatureAccess]);
341
431
  const resolvedWorkspaceModule = useMemo(() => resolveWorkspaceModule(activeWorkspaceModule, workspaceModules), [activeWorkspaceModule, workspaceModules]);
432
+ const planningSurfaceVisible = planningDrawerOpen || resolvedWorkspaceModule === 'planning';
433
+ useEffect(() => {
434
+ if (!planningSurfaceVisible)
435
+ return;
436
+ void props.ensureArchiveHydrated(true);
437
+ }, [planningSurfaceVisible, props.ensureArchiveHydrated, currentWorkspaceId]);
438
+ const [taskforceAgentDrawerOpen, setTaskforceAgentDrawerOpen] = useState(false);
439
+ const [taskforceAgentPanelCollapsed, setTaskforceAgentPanelCollapsed] = useState(false);
440
+ const [taskforceAgentsLaunchContext, setTaskforceAgentsLaunchContext] = useState(null);
441
+ const [taskforceAgentDrawerHeaderContent, setTaskforceAgentDrawerHeaderContent] = useState(null);
442
+ const handleRenderTaskforceAgentDrawerHeader = useCallback((content) => {
443
+ setTaskforceAgentDrawerHeaderContent(content);
444
+ }, []);
445
+ const handleRememberTaskforceAgentSelection = useCallback((selection) => {
446
+ const nextAgentId = String(selection.agentId || '').trim();
447
+ const nextConversationId = String(selection.conversationId || '').trim();
448
+ setTaskforceAgentId(nextAgentId);
449
+ setTaskforceAgentConversationId(nextConversationId);
450
+ if (!nextAgentId)
451
+ return;
452
+ setTaskforceAgentConversationByAgentId((current) => {
453
+ if (nextConversationId) {
454
+ if (current[nextAgentId] === nextConversationId)
455
+ return current;
456
+ return { ...current, [nextAgentId]: nextConversationId };
457
+ }
458
+ if (!current[nextAgentId])
459
+ return current;
460
+ const next = { ...current };
461
+ delete next[nextAgentId];
462
+ return next;
463
+ });
464
+ }, [setTaskforceAgentConversationByAgentId, setTaskforceAgentConversationId, setTaskforceAgentId]);
342
465
  const documentsWorkspaceEnabled = workspaceFeatureAccess[DOCUMENT_WORKSPACE_FEATURE_KEY]?.allowed ?? false;
343
466
  const annotatedAttachmentsWorkspaceEnabled = workspaceFeatureAccess[ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY]?.allowed ?? false;
467
+ const taskforceAgentsWorkspaceEnabled = workspaceFeatureAccess[TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]?.allowed ?? false;
344
468
  const documentsWorkspaceUnavailableMessage = 'Documents is not available in this build yet.';
345
469
  const annotatedAttachmentsWorkspaceUnavailableMessage = 'Annotate is not available in this build yet.';
470
+ const handoffTaskModalToWorkspace = useCallback((action) => {
471
+ if (activeTab !== 'add') {
472
+ action();
473
+ return;
474
+ }
475
+ void handleNavigation(() => {
476
+ setTaskModalFullscreen(false);
477
+ resetForm();
478
+ setActiveTab('tasks');
479
+ action();
480
+ });
481
+ }, [activeTab, handleNavigation, resetForm, setActiveTab]);
346
482
  useEffect(() => {
347
483
  const handleOpenMarkdownDocument = (event) => {
348
484
  const customEvent = event;
@@ -355,16 +491,18 @@ export function StandaloneLayout(props) {
355
491
  pushNotice(documentsWorkspaceUnavailableMessage, 'error');
356
492
  return;
357
493
  }
358
- rememberTaskOriginWorkspaceModule(customEvent.detail?.taskId);
359
- setRequestedDocPath(fsPath || null);
360
- setRequestedDocAssetId(assetId);
361
- setActiveWorkspaceModule('docs');
494
+ handoffTaskModalToWorkspace(() => {
495
+ rememberTaskOriginWorkspaceModule(customEvent.detail?.taskId);
496
+ setRequestedDocPath(fsPath || null);
497
+ setRequestedDocAssetId(assetId);
498
+ setActiveWorkspaceModule('docs');
499
+ });
362
500
  };
363
501
  window.addEventListener('taskforce:open-markdown-document', handleOpenMarkdownDocument);
364
502
  return () => {
365
503
  window.removeEventListener('taskforce:open-markdown-document', handleOpenMarkdownDocument);
366
504
  };
367
- }, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, pushNotice, rememberTaskOriginWorkspaceModule, setActiveWorkspaceModule]);
505
+ }, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, handoffTaskModalToWorkspace, pushNotice, rememberTaskOriginWorkspaceModule, setActiveWorkspaceModule]);
368
506
  useEffect(() => {
369
507
  if (resolvedWorkspaceModule !== activeWorkspaceModule) {
370
508
  setActiveWorkspaceModule(resolvedWorkspaceModule);
@@ -376,25 +514,6 @@ export function StandaloneLayout(props) {
376
514
  setRequestedDocPath(null);
377
515
  setRequestedDocAssetId(null);
378
516
  }, [documentsWorkspaceEnabled, resolvedWorkspaceModule]);
379
- useEffect(() => {
380
- if (typeof window === 'undefined')
381
- return;
382
- try {
383
- const cachedRaw = window.sessionStorage.getItem(annotatedLayoutCacheKey);
384
- if (!cachedRaw)
385
- return;
386
- const cached = JSON.parse(cachedRaw);
387
- if (cached?.annotatedTarget && typeof cached.annotatedTarget === 'object') {
388
- setRequestedAnnotatedTarget(cached.annotatedTarget);
389
- }
390
- if (typeof cached?.annotatedSessionId === 'string') {
391
- setRequestedAnnotatedSessionId(cached.annotatedSessionId.trim() || null);
392
- }
393
- }
394
- catch {
395
- // ignore cache read failure
396
- }
397
- }, [annotatedLayoutCacheKey]);
398
517
  useEffect(() => {
399
518
  if (taskOriginWorkspaceModuleRestoreHandledRef.current)
400
519
  return;
@@ -418,161 +537,126 @@ export function StandaloneLayout(props) {
418
537
  taskOriginWorkspaceModuleRestoreHandledRef.current = false;
419
538
  openedTaskOriginWorkspaceModuleRef.current = false;
420
539
  }, [taskOriginWorkspaceModuleKey]);
421
- useEffect(() => {
422
- if (loadedLayoutStateWorkspaceRef.current === layoutStateWorkspaceKey)
423
- return;
424
- loadedLayoutStateWorkspaceRef.current = layoutStateWorkspaceKey;
425
- setLayoutStateReady(false);
426
- let cancelled = false;
427
- const loadLayoutUiState = async () => {
428
- try {
429
- const res = await fetch('/api/taskforce/ui-state?key=layout', {
430
- method: 'GET',
431
- credentials: 'include',
432
- headers: workspaceUiStateHeaders
433
- });
434
- if (!res.ok)
435
- return;
436
- const data = await res.json().catch(() => ({}));
437
- const state = (data?.state && typeof data.state === 'object')
438
- ? data.state
439
- : null;
440
- if (!state || cancelled)
441
- return;
442
- if (typeof state.scheduleShowWeekends === 'boolean')
443
- setScheduleShowWeekends(state.scheduleShowWeekends);
444
- if (typeof state.scheduleShowBacklog === 'boolean')
445
- setScheduleShowBacklog(state.scheduleShowBacklog);
446
- if (typeof state.scheduleOnlyExpired === 'boolean')
447
- setScheduleOnlyExpired(state.scheduleOnlyExpired);
448
- if (typeof state.scheduleSidebarOpen === 'boolean')
449
- setScheduleSidebarOpen(state.scheduleSidebarOpen);
450
- if (typeof state.scheduleSelectedDate === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(state.scheduleSelectedDate)) {
451
- setScheduleSelectedDate(state.scheduleSelectedDate);
452
- }
453
- if (typeof state.scheduleCalendarMonth === 'string' && /^\d{4}-\d{2}$/.test(state.scheduleCalendarMonth)) {
454
- setScheduleCalendarMonth(state.scheduleCalendarMonth);
455
- }
456
- if (typeof state.scheduleScrollLeft === 'number' && Number.isFinite(state.scheduleScrollLeft) && state.scheduleScrollLeft >= 0) {
457
- setScheduleScrollLeft(state.scheduleScrollLeft);
458
- }
459
- if (typeof state.showFilters === 'boolean')
460
- setShowFilters(state.showFilters);
461
- if (Array.isArray(state.documentTypeFilters)) {
462
- setDocumentTypeFilters(state.documentTypeFilters);
463
- }
464
- if (Array.isArray(state.documentAttachmentFilters)) {
465
- setDocumentAttachmentFilters(state.documentAttachmentFilters);
466
- }
467
- if (typeof state.planningDrawerOpen === 'boolean') {
468
- setPlanningDrawerOpen(state.planningDrawerOpen);
469
- }
470
- if (typeof state.documentTrayOpen === 'boolean') {
471
- setDocumentTrayOpen(state.documentTrayOpen);
472
- }
473
- if (typeof state.imageTrayOpen === 'boolean') {
474
- setImageTrayOpen(state.imageTrayOpen);
475
- }
476
- if (typeof state.agentTrayOpen === 'boolean') {
477
- setAgentTrayOpen(state.agentTrayOpen);
478
- }
479
- if (typeof state.planningTreeCollapsed === 'boolean') {
480
- setPlanningTreeCollapsed(state.planningTreeCollapsed);
481
- }
482
- if (typeof state.planningPrimaryCollapsed === 'boolean') {
483
- setPlanningPrimaryCollapsed(state.planningPrimaryCollapsed);
484
- }
485
- if (typeof state.planningSecondaryCollapsed === 'boolean') {
486
- setPlanningSecondaryCollapsed(state.planningSecondaryCollapsed);
487
- }
488
- if (Array.isArray(state.planningExpandedInitiativeIds)) {
489
- setExpandedPlanningInitiativeIds(new Set(state.planningExpandedInitiativeIds
490
- .map((value) => String(value || '').trim())
491
- .filter(Boolean)));
492
- }
493
- if (state.planningDrawerDetail
494
- && typeof state.planningDrawerDetail === 'object'
495
- && (state.planningDrawerDetail.type === 'initiative' || state.planningDrawerDetail.type === 'workstream')
496
- && typeof state.planningDrawerDetail.id === 'string') {
497
- const detailId = state.planningDrawerDetail.id.trim();
498
- setPlanningDrawerDetail(detailId ? { type: state.planningDrawerDetail.type, id: detailId } : null);
499
- }
500
- else if (state.planningDrawerDetail === null) {
501
- setPlanningDrawerDetail(null);
502
- }
503
- if (typeof state.planningNestedWorkstreamDetailId === 'string') {
504
- setPlanningNestedWorkstreamDetailId(state.planningNestedWorkstreamDetailId.trim() || null);
505
- }
506
- else if (state.planningNestedWorkstreamDetailId === null) {
507
- setPlanningNestedWorkstreamDetailId(null);
508
- }
509
- const annotatedTarget = state.annotatedTarget;
510
- if (annotatedTarget && typeof annotatedTarget === 'object') {
511
- if (!requestedAnnotatedTargetRef.current) {
512
- setRequestedAnnotatedTarget(annotatedTarget);
513
- }
514
- }
515
- if (typeof state.annotatedSessionId === 'string') {
516
- if (!requestedAnnotatedSessionIdRef.current) {
517
- setRequestedAnnotatedSessionId(state.annotatedSessionId.trim() || null);
518
- }
519
- }
520
- }
521
- catch {
522
- // ignore read failure
523
- }
524
- finally {
525
- if (!cancelled)
526
- setLayoutStateReady(true);
527
- }
528
- };
529
- loadLayoutUiState();
530
- return () => {
531
- cancelled = true;
532
- };
533
- }, [layoutStateWorkspaceKey, workspaceUiStateHeaders]);
534
- useEffect(() => {
535
- if (!layoutStateReady)
536
- return;
537
- const timeoutId = window.setTimeout(async () => {
538
- try {
539
- await persistRemoteUiState({
540
- stateKey: 'layout',
541
- workspaceId: currentWorkspaceId,
542
- headers: workspaceUiStateHeaders,
543
- patch: {
544
- scheduleShowWeekends,
545
- scheduleShowBacklog,
546
- scheduleOnlyExpired,
547
- scheduleSidebarOpen,
548
- scheduleSelectedDate,
549
- scheduleCalendarMonth,
550
- scheduleScrollLeft,
551
- showFilters,
552
- documentTypeFilters,
553
- documentAttachmentFilters,
554
- documentTrayOpen,
555
- imageTrayOpen,
556
- agentTrayOpen,
557
- planningDrawerOpen,
558
- planningTreeCollapsed,
559
- planningPrimaryCollapsed,
560
- planningSecondaryCollapsed,
561
- planningExpandedInitiativeIds: Array.from(expandedPlanningInitiativeIds),
562
- planningDrawerDetail,
563
- planningNestedWorkstreamDetailId,
564
- annotatedTarget: requestedAnnotatedTarget,
565
- annotatedSessionId: requestedAnnotatedSessionId
566
- }
567
- });
568
- }
569
- catch {
570
- // ignore write failure
571
- }
572
- }, 250);
573
- return () => window.clearTimeout(timeoutId);
574
- }, [
575
- layoutStateReady,
540
+ const applyPersistedLayoutState = useCallback((state) => {
541
+ if (typeof state.scheduleShowWeekends === 'boolean')
542
+ setScheduleShowWeekends(state.scheduleShowWeekends);
543
+ if (typeof state.scheduleShowBacklog === 'boolean')
544
+ setScheduleShowBacklog(state.scheduleShowBacklog);
545
+ if (typeof state.scheduleOnlyExpired === 'boolean')
546
+ setScheduleOnlyExpired(state.scheduleOnlyExpired);
547
+ if (typeof state.scheduleSidebarOpen === 'boolean')
548
+ setScheduleSidebarOpen(state.scheduleSidebarOpen);
549
+ if (typeof state.scheduleSelectedDate === 'string')
550
+ setScheduleSelectedDate(state.scheduleSelectedDate);
551
+ if (typeof state.scheduleCalendarMonth === 'string')
552
+ setScheduleCalendarMonth(state.scheduleCalendarMonth);
553
+ if (typeof state.scheduleScrollLeft === 'number')
554
+ setScheduleScrollLeft(state.scheduleScrollLeft);
555
+ if (typeof state.showFilters === 'boolean')
556
+ setShowFilters(state.showFilters);
557
+ if (Array.isArray(state.documentTypeFilters)) {
558
+ setDocumentTypeFilters(state.documentTypeFilters);
559
+ }
560
+ if (Array.isArray(state.documentAttachmentFilters)) {
561
+ setDocumentAttachmentFilters(state.documentAttachmentFilters);
562
+ }
563
+ if (state.documentSortField === 'updated'
564
+ || state.documentSortField === 'reference'
565
+ || state.documentSortField === 'name'
566
+ || state.documentSortField === 'size'
567
+ || state.documentSortField === 'created') {
568
+ setDocumentSortField(state.documentSortField);
569
+ }
570
+ if (state.documentSortOrder === 'asc' || state.documentSortOrder === 'desc') {
571
+ setDocumentSortOrder(state.documentSortOrder);
572
+ }
573
+ if (Array.isArray(state.documentPinnedDocIds)) {
574
+ setDocumentPinnedDocIds(state.documentPinnedDocIds);
575
+ }
576
+ if (typeof state.documentSearchQuery === 'string') {
577
+ setDocumentSearchQuery(state.documentSearchQuery);
578
+ }
579
+ if (typeof state.documentSelectedDocId === 'string' || state.documentSelectedDocId === null) {
580
+ setDocumentSelectedDocId(state.documentSelectedDocId);
581
+ }
582
+ setDocumentScrollByDocId(state.documentScrollByDocId && typeof state.documentScrollByDocId === 'object'
583
+ ? state.documentScrollByDocId
584
+ : {});
585
+ if (typeof state.documentListScrollTop === 'number') {
586
+ setDocumentListScrollTop(state.documentListScrollTop);
587
+ }
588
+ if (typeof state.planningDrawerOpen === 'boolean') {
589
+ setPlanningDrawerOpen(state.planningDrawerOpen);
590
+ }
591
+ if (typeof state.documentTrayOpen === 'boolean') {
592
+ setDocumentTrayOpen(state.documentTrayOpen);
593
+ }
594
+ if (typeof state.imageTrayOpen === 'boolean') {
595
+ setImageTrayOpen(state.imageTrayOpen);
596
+ }
597
+ if (typeof state.agentTrayOpen === 'boolean') {
598
+ setAgentTrayOpen(state.agentTrayOpen);
599
+ }
600
+ if (typeof state.taskforceAgentRosterTrayOpen === 'boolean') {
601
+ setTaskforceAgentRosterTrayOpen(state.taskforceAgentRosterTrayOpen);
602
+ }
603
+ if (typeof state.taskforceAgentDrawerOpen === 'boolean') {
604
+ setTaskforceAgentDrawerOpen(state.taskforceAgentDrawerOpen);
605
+ }
606
+ if (typeof state.taskforceAgentPanelCollapsed === 'boolean') {
607
+ setTaskforceAgentPanelCollapsed(state.taskforceAgentPanelCollapsed);
608
+ }
609
+ if (typeof state.planningTreeCollapsed === 'boolean') {
610
+ setPlanningTreeCollapsed(state.planningTreeCollapsed);
611
+ }
612
+ if (typeof state.planningPrimaryCollapsed === 'boolean') {
613
+ setPlanningPrimaryCollapsed(state.planningPrimaryCollapsed);
614
+ }
615
+ if (typeof state.planningSecondaryCollapsed === 'boolean') {
616
+ setPlanningSecondaryCollapsed(state.planningSecondaryCollapsed);
617
+ }
618
+ setPlanningFavoritesSectionCollapsed(Boolean(state.planningFavoritesSectionCollapsed));
619
+ setPlanningInitiativesSectionCollapsed(Boolean(state.planningInitiativesSectionCollapsed));
620
+ setPlanningWorkstreamsSectionCollapsed(Boolean(state.planningWorkstreamsSectionCollapsed));
621
+ if (state.planningNavigatorSort === 'default'
622
+ || state.planningNavigatorSort === 'title'
623
+ || state.planningNavigatorSort === 'owner'
624
+ || state.planningNavigatorSort === 'progress') {
625
+ setPlanningNavigatorSort(state.planningNavigatorSort);
626
+ }
627
+ setPlanningTaskArrangeMode(normalizePlanningTaskArrangeMode(state.planningTaskArrangeMode));
628
+ setPlanningFavorites(Array.isArray(state.planningFavorites) ? state.planningFavorites : []);
629
+ if (Array.isArray(state.planningExpandedInitiativeIds)) {
630
+ setExpandedPlanningInitiativeIds(new Set(state.planningExpandedInitiativeIds));
631
+ }
632
+ if (state.planningDrawerDetail !== undefined) {
633
+ setPlanningDrawerDetail(state.planningDrawerDetail);
634
+ }
635
+ if (typeof state.planningNestedWorkstreamDetailId === 'string' || state.planningNestedWorkstreamDetailId === null) {
636
+ setPlanningNestedWorkstreamDetailId(state.planningNestedWorkstreamDetailId);
637
+ }
638
+ const annotatedTarget = state.annotatedTarget && typeof state.annotatedTarget === 'object'
639
+ ? state.annotatedTarget
640
+ : null;
641
+ const annotatedSessionId = annotatedTarget && typeof state.annotatedSessionId === 'string'
642
+ ? state.annotatedSessionId
643
+ : null;
644
+ if (shouldApplyPersistedAnnotatedAttachmentContext({
645
+ currentTarget: requestedAnnotatedTargetRef.current,
646
+ currentSessionId: requestedAnnotatedSessionIdRef.current,
647
+ lastHydratedIdentity: lastHydratedAnnotatedContextIdentityRef.current,
648
+ })) {
649
+ requestedAnnotatedTargetRef.current = annotatedTarget;
650
+ requestedAnnotatedSessionIdRef.current = annotatedSessionId;
651
+ lastHydratedAnnotatedContextIdentityRef.current = getAnnotatedAttachmentContextIdentity(annotatedTarget, annotatedSessionId);
652
+ setRequestedAnnotatedTarget(annotatedTarget);
653
+ setRequestedAnnotatedSessionId(annotatedSessionId);
654
+ }
655
+ setAnnotatedViewportByContextKey(state.annotatedViewportByContextKey && typeof state.annotatedViewportByContextKey === 'object'
656
+ ? state.annotatedViewportByContextKey
657
+ : {});
658
+ }, []);
659
+ const layoutUiStateSnapshot = useMemo(() => ({
576
660
  scheduleShowWeekends,
577
661
  scheduleShowBacklog,
578
662
  scheduleOnlyExpired,
@@ -583,33 +667,92 @@ export function StandaloneLayout(props) {
583
667
  showFilters,
584
668
  documentTypeFilters,
585
669
  documentAttachmentFilters,
670
+ documentSortField,
671
+ documentSortOrder,
672
+ documentPinnedDocIds,
673
+ documentSearchQuery,
674
+ documentSelectedDocId,
675
+ documentScrollByDocId,
676
+ documentListScrollTop,
586
677
  documentTrayOpen,
587
678
  imageTrayOpen,
588
679
  agentTrayOpen,
680
+ taskforceAgentRosterTrayOpen,
681
+ taskforceAgentDrawerOpen,
682
+ taskforceAgentPanelCollapsed,
589
683
  planningDrawerOpen,
590
684
  planningTreeCollapsed,
591
685
  planningPrimaryCollapsed,
592
686
  planningSecondaryCollapsed,
687
+ planningFavoritesSectionCollapsed,
688
+ planningInitiativesSectionCollapsed,
689
+ planningWorkstreamsSectionCollapsed,
690
+ planningNavigatorSort,
691
+ planningTaskArrangeMode,
692
+ planningFavorites,
693
+ planningExpandedInitiativeIds: Array.from(expandedPlanningInitiativeIds),
694
+ planningDrawerDetail,
695
+ planningNestedWorkstreamDetailId,
696
+ annotatedTarget: scopedRequestedAnnotatedTarget,
697
+ annotatedSessionId: scopedRequestedAnnotatedSessionId,
698
+ annotatedViewportByContextKey,
699
+ }), [
700
+ scheduleShowWeekends,
701
+ scheduleShowBacklog,
702
+ scheduleOnlyExpired,
703
+ scheduleSidebarOpen,
704
+ scheduleSelectedDate,
705
+ scheduleCalendarMonth,
706
+ scheduleScrollLeft,
707
+ showFilters,
708
+ documentTypeFilters,
709
+ documentAttachmentFilters,
710
+ documentSortField,
711
+ documentSortOrder,
712
+ documentPinnedDocIds,
713
+ documentSearchQuery,
714
+ documentSelectedDocId,
715
+ documentScrollByDocId,
716
+ documentListScrollTop,
717
+ documentTrayOpen,
718
+ imageTrayOpen,
719
+ agentTrayOpen,
720
+ taskforceAgentRosterTrayOpen,
721
+ taskforceAgentDrawerOpen,
722
+ taskforceAgentPanelCollapsed,
723
+ planningDrawerOpen,
724
+ planningTreeCollapsed,
725
+ planningPrimaryCollapsed,
726
+ planningSecondaryCollapsed,
727
+ planningFavoritesSectionCollapsed,
728
+ planningInitiativesSectionCollapsed,
729
+ planningWorkstreamsSectionCollapsed,
730
+ planningNavigatorSort,
731
+ planningTaskArrangeMode,
732
+ planningFavorites,
593
733
  expandedPlanningInitiativeIds,
594
734
  planningDrawerDetail,
595
735
  planningNestedWorkstreamDetailId,
596
- requestedAnnotatedTarget,
597
- requestedAnnotatedSessionId,
598
- workspaceUiStateHeaders
736
+ scopedRequestedAnnotatedTarget,
737
+ scopedRequestedAnnotatedSessionId,
738
+ annotatedViewportByContextKey,
599
739
  ]);
600
740
  useEffect(() => {
601
- if (typeof window === 'undefined')
602
- return;
603
- try {
604
- window.sessionStorage.setItem(annotatedLayoutCacheKey, JSON.stringify({
605
- annotatedTarget: requestedAnnotatedTarget,
606
- annotatedSessionId: requestedAnnotatedSessionId,
607
- }));
608
- }
609
- catch {
610
- // ignore cache write failure
611
- }
612
- }, [annotatedLayoutCacheKey, requestedAnnotatedSessionId, requestedAnnotatedTarget]);
741
+ setPlanningFavorites([]);
742
+ }, [layoutStateWorkspaceKey]);
743
+ const { ready: layoutUiStateReady } = usePersistedLayoutUiState({
744
+ currentWorkspaceId,
745
+ loadKey: layoutStateWorkspaceKey,
746
+ enabled: runtimeMode !== 'cloud' || authSessionResolved,
747
+ headers: workspaceUiStateHeaders,
748
+ remotePlanningFavoritesAuthoritative: Boolean(normalizedAuthUserId)
749
+ && normalizedAuthUserId !== 'anonymous',
750
+ useCloudProxy: runtimeMode === 'local'
751
+ && Boolean(normalizedAuthUserId)
752
+ && normalizedAuthUserId !== 'anonymous',
753
+ snapshot: layoutUiStateSnapshot,
754
+ onApplyState: applyPersistedLayoutState,
755
+ });
613
756
  useEffect(() => {
614
757
  if (groupBy === 'schedule') {
615
758
  setScheduleSidebarOpen(true);
@@ -660,11 +803,16 @@ export function StandaloneLayout(props) {
660
803
  pushNotice(annotatedAttachmentsWorkspaceUnavailableMessage, 'error');
661
804
  return;
662
805
  }
663
- setRequestedAnnotatedTarget(detail);
664
- setRequestedAnnotatedSessionId(null);
665
- setRequestedAnnotatedOpenVersion((current) => current + 1);
666
- rememberTaskOriginWorkspaceModule(detail.taskId);
667
- setActiveWorkspaceModule('annotate');
806
+ handoffTaskModalToWorkspace(() => {
807
+ requestedAnnotatedTargetRef.current = detail;
808
+ const sessionId = String(detail.sessionId || '').trim() || null;
809
+ requestedAnnotatedSessionIdRef.current = sessionId;
810
+ setRequestedAnnotatedTarget(detail);
811
+ setRequestedAnnotatedSessionId(sessionId);
812
+ setRequestedAnnotatedOpenVersion((current) => current + 1);
813
+ rememberTaskOriginWorkspaceModule(detail.taskId);
814
+ setActiveWorkspaceModule('annotate');
815
+ });
668
816
  };
669
817
  window.addEventListener('taskforce:open-annotated-attachment', handleOpenAnnotatedAttachment);
670
818
  return () => {
@@ -674,21 +822,22 @@ export function StandaloneLayout(props) {
674
822
  annotatedAttachmentTasks,
675
823
  annotatedAttachmentsWorkspaceEnabled,
676
824
  annotatedAttachmentsWorkspaceUnavailableMessage,
825
+ handoffTaskModalToWorkspace,
677
826
  pushNotice,
678
827
  rememberTaskOriginWorkspaceModule,
679
828
  setActiveWorkspaceModule
680
829
  ]);
681
830
  useEffect(() => {
682
- if (!requestedAnnotatedTarget)
831
+ if (!scopedRequestedAnnotatedTarget)
683
832
  return;
684
- const resolvedTarget = resolveAnnotatedAttachmentDetail(requestedAnnotatedTarget, annotatedAttachmentTasks);
833
+ const resolvedTarget = resolveAnnotatedAttachmentDetail(scopedRequestedAnnotatedTarget, annotatedAttachmentTasks);
685
834
  if (!resolvedTarget)
686
835
  return;
687
- if (resolvedTarget.taskReferenceLabel === requestedAnnotatedTarget.taskReferenceLabel
688
- && resolvedTarget.imageReferenceLabel === requestedAnnotatedTarget.imageReferenceLabel)
836
+ if (resolvedTarget.taskReferenceLabel === scopedRequestedAnnotatedTarget.taskReferenceLabel
837
+ && resolvedTarget.imageReferenceLabel === scopedRequestedAnnotatedTarget.imageReferenceLabel)
689
838
  return;
690
839
  setRequestedAnnotatedTarget(resolvedTarget);
691
- }, [annotatedAttachmentTasks, requestedAnnotatedTarget]);
840
+ }, [annotatedAttachmentTasks, scopedRequestedAnnotatedTarget]);
692
841
  useEffect(() => {
693
842
  const activeTarget = requestedAnnotatedTargetRef.current;
694
843
  const normalizedAssetId = String(activeTarget?.assetId || '').trim();
@@ -707,11 +856,11 @@ export function StandaloneLayout(props) {
707
856
  imageReferenceLabel: canonicalReferenceLabel,
708
857
  };
709
858
  });
710
- }, [canonicalAnnotatedImageReferenceLabels, requestedAnnotatedTarget]);
859
+ }, [canonicalAnnotatedImageReferenceLabels, scopedRequestedAnnotatedTarget]);
711
860
  useEffect(() => {
712
861
  if (!annotatedWorkspaceReady)
713
862
  return;
714
- const activeTarget = requestedAnnotatedTarget;
863
+ const activeTarget = scopedRequestedAnnotatedTarget;
715
864
  const normalizedAssetId = String(activeTarget?.assetId || '').trim();
716
865
  if (!normalizedAssetId)
717
866
  return;
@@ -756,11 +905,13 @@ export function StandaloneLayout(props) {
756
905
  return () => {
757
906
  cancelled = true;
758
907
  };
759
- }, [annotatedWorkspaceReady, canonicalAnnotatedImageReferenceLabels, currentWorkspaceId, requestedAnnotatedTarget, workspaceUiStateHeaders]);
908
+ }, [annotatedWorkspaceReady, canonicalAnnotatedImageReferenceLabels, currentWorkspaceId, scopedRequestedAnnotatedTarget, workspaceUiStateHeaders]);
760
909
  const deletedScopeAllTasks = useMemo(() => props.deletedTasks.map((entry) => ({
761
910
  ...entry.taskSnapshot,
762
911
  isDeleted: true,
763
- deletedRecordId: entry.id
912
+ deletedRecordId: entry.id,
913
+ deletedAt: entry.deletedAt,
914
+ deletedExpiresAt: getDeletedTaskExpiresAt(entry.deletedAt),
764
915
  })), [props.deletedTasks]);
765
916
  const deletedTaskRecordByTaskId = useMemo(() => {
766
917
  const map = new Map();
@@ -825,18 +976,26 @@ export function StandaloneLayout(props) {
825
976
  .map((type) => ({ value: type.value, label: `${type.label} (Retired)` }));
826
977
  return [...activeTypeOptions, ...retiredTypesInUse];
827
978
  }, [activeTypes, taskFilterRecords]);
979
+ const applyTaskHeaderQuickFilter = useCallback((candidateTasks) => {
980
+ if (!taskHeaderQuickFilter)
981
+ return candidateTasks;
982
+ return candidateTasks.filter((task) => matchesTaskHeaderQuickFilter(task, taskHeaderQuickFilter, normalizedAuthUserId, todayDateOnly));
983
+ }, [normalizedAuthUserId, taskHeaderQuickFilter, todayDateOnly]);
984
+ const quickFilteredOpenTasks = useMemo(() => applyTaskHeaderQuickFilter(props.filteredTasks), [applyTaskHeaderQuickFilter, props.filteredTasks]);
828
985
  const kanbanTasks = useMemo(() => {
829
986
  if (taskScope === 'archived')
830
987
  return archivedScopeTasks;
831
988
  if (taskScope === 'deleted')
832
989
  return filteredDeletedTasks;
833
990
  if (!showArchive)
834
- return props.filteredTasks;
835
- return [...props.filteredTasks, ...archivedScopeTasks];
836
- }, [archivedScopeTasks, filteredDeletedTasks, props.filteredTasks, showArchive, taskScope]);
991
+ return quickFilteredOpenTasks;
992
+ return [...quickFilteredOpenTasks, ...archivedScopeTasks];
993
+ }, [archivedScopeTasks, filteredDeletedTasks, quickFilteredOpenTasks, showArchive, taskScope]);
837
994
  const scheduleBaseTasks = useMemo(() => taskScope === 'open'
838
- ? props.tasks.filter(task => !task.isArchived)
839
- : kanbanTasks, [kanbanTasks, props.tasks, taskScope]);
995
+ ? (taskHeaderQuickFilter
996
+ ? quickFilteredOpenTasks
997
+ : props.tasks.filter(task => !task.isArchived))
998
+ : kanbanTasks, [kanbanTasks, props.tasks, quickFilteredOpenTasks, taskHeaderQuickFilter, taskScope]);
840
999
  const scheduleFilteredTaskIds = useMemo(() => new Set(kanbanTasks.map(task => task.id)), [kanbanTasks]);
841
1000
  const kanbanAllTasks = useMemo(() => {
842
1001
  if (taskScope === 'archived')
@@ -875,16 +1034,34 @@ export function StandaloneLayout(props) {
875
1034
  return map;
876
1035
  }, [assigneeOptions, authUserDisplayName, authUserEmail, authUserId]);
877
1036
  const planningStructure = useMemo(() => {
878
- const planningScopedTasks = taskScope === 'archived'
879
- ? archivedScopeAllTasks
880
- : taskScope === 'deleted'
881
- ? deletedScopeAllTasks
882
- : props.tasks.filter((task) => !task.isArchived);
883
- const planningPreviewTasks = taskScope === 'deleted'
884
- ? deletedScopeAllTasks
885
- : Array.from([...props.tasks, ...archivedScopeAllTasks]
886
- .reduce((map, task) => map.set(task.id, task), new Map())
887
- .values());
1037
+ const prerequisiteTaskIdsByTaskId = new Map();
1038
+ props.workspaceTaskRelationships.forEach((relationship) => {
1039
+ if (relationship.deletedAt || relationship.kind !== 'dependency')
1040
+ return;
1041
+ const current = prerequisiteTaskIdsByTaskId.get(relationship.sourceTaskId) || [];
1042
+ current.push(relationship.targetTaskId);
1043
+ prerequisiteTaskIdsByTaskId.set(relationship.sourceTaskId, current);
1044
+ });
1045
+ const planningLifetimeTasks = mergePlanningLifetimeTasks(props.tasks, archivedScopeAllTasks);
1046
+ const planningLifetimeTaskById = new Map(planningLifetimeTasks.map((task) => [task.id, task]));
1047
+ const getDependencyState = (taskId) => {
1048
+ const prerequisiteIds = prerequisiteTaskIdsByTaskId.get(taskId) || [];
1049
+ if (prerequisiteIds.length === 0)
1050
+ return 'ready';
1051
+ let invalid = false;
1052
+ for (const prerequisiteId of prerequisiteIds) {
1053
+ const prerequisite = planningLifetimeTaskById.get(prerequisiteId);
1054
+ if (!prerequisite || getStatusDefinition(prerequisite.status).value === 'cancelled') {
1055
+ invalid = true;
1056
+ continue;
1057
+ }
1058
+ if (getStatusDefinition(prerequisite.status).value !== 'done')
1059
+ return 'blocked';
1060
+ }
1061
+ return invalid ? 'invalid' : 'ready';
1062
+ };
1063
+ const planningProgressTasks = planningLifetimeTasks;
1064
+ const planningPreviewTasks = planningLifetimeTasks;
888
1065
  const summarizeTaskCounts = (taskCount, completedTaskCount) => {
889
1066
  return {
890
1067
  progressPercent: taskCount > 0 ? Math.round((completedTaskCount / taskCount) * 100) : 0,
@@ -892,19 +1069,53 @@ export function StandaloneLayout(props) {
892
1069
  completedTaskCount,
893
1070
  };
894
1071
  };
895
- const useBootstrapTaskSummaries = taskScope === 'open'
896
- && props.planningBootstrapTaskSummaries.length > 0
897
- && (props.loadingTasks || props.tasks.length === 0);
1072
+ const summarizeTaskStatuses = (tasks) => {
1073
+ const counts = {
1074
+ task: 0,
1075
+ 'on-hold': 0,
1076
+ 'in-progress': 0,
1077
+ review: 0,
1078
+ done: 0,
1079
+ cancelled: 0,
1080
+ };
1081
+ tasks.forEach((task) => {
1082
+ counts[getStatusDefinition(task.status).value] += 1;
1083
+ });
1084
+ return counts;
1085
+ };
1086
+ const combineTaskStatuses = (workstreams) => {
1087
+ const counts = summarizeTaskStatuses([]);
1088
+ workstreams.forEach((workstream) => {
1089
+ Object.entries(workstream.statusCounts || {}).forEach(([status, count]) => {
1090
+ counts[status] += Number(count) || 0;
1091
+ });
1092
+ });
1093
+ return counts;
1094
+ };
1095
+ const useBootstrapTaskSummaries = shouldUsePlanningBootstrapTaskSummaries({
1096
+ taskScope,
1097
+ summaryCount: props.planningBootstrapTaskSummaries.length,
1098
+ loadingTasks: props.loadingTasks,
1099
+ activeTaskCount: props.tasks.length,
1100
+ archiveHydrated: props.archiveHydratedWorkspaceId === currentWorkspaceId,
1101
+ });
898
1102
  const workstreamTaskSummaryById = new Map();
899
1103
  const workstreamTaskPreviewsById = new Map();
1104
+ const workstreamStatusCountsById = new Map();
900
1105
  if (useBootstrapTaskSummaries) {
901
1106
  props.planningBootstrapTaskSummaries.forEach((summary) => {
902
- workstreamTaskSummaryById.set(summary.workstreamId, summary);
903
- workstreamTaskPreviewsById.set(summary.workstreamId, summary.tasks || []);
1107
+ const tasks = (summary.tasks || []).map((task) => ({
1108
+ ...task,
1109
+ prerequisiteTaskIds: prerequisiteTaskIdsByTaskId.get(task.id) || [],
1110
+ dependencyState: getDependencyState(task.id),
1111
+ }));
1112
+ workstreamTaskSummaryById.set(summary.workstreamId, { ...summary, tasks });
1113
+ workstreamTaskPreviewsById.set(summary.workstreamId, tasks);
1114
+ workstreamStatusCountsById.set(summary.workstreamId, summarizeTaskStatuses(tasks));
904
1115
  });
905
1116
  }
906
1117
  else {
907
- planningScopedTasks.forEach((task) => {
1118
+ planningProgressTasks.forEach((task) => {
908
1119
  const workstreamId = String(task.workstreamId || '').trim();
909
1120
  if (!workstreamId)
910
1121
  return;
@@ -915,9 +1126,12 @@ export function StandaloneLayout(props) {
915
1126
  tasks: [],
916
1127
  };
917
1128
  current.taskCount += 1;
918
- if (task.isArchived || task.status === 'done' || task.status === 'cancelled') {
1129
+ if (task.status === 'done' || task.status === 'cancelled') {
919
1130
  current.completedTaskCount += 1;
920
1131
  }
1132
+ const statusCounts = workstreamStatusCountsById.get(workstreamId) || summarizeTaskStatuses([]);
1133
+ statusCounts[getStatusDefinition(task.status).value] += 1;
1134
+ workstreamStatusCountsById.set(workstreamId, statusCounts);
921
1135
  workstreamTaskSummaryById.set(workstreamId, current);
922
1136
  });
923
1137
  planningPreviewTasks.forEach((task) => {
@@ -928,8 +1142,17 @@ export function StandaloneLayout(props) {
928
1142
  current.push({
929
1143
  id: task.id,
930
1144
  referenceNumber: task.referenceNumber ?? null,
1145
+ localReferenceNumber: task.localReferenceNumber ?? null,
1146
+ referenceLabel: task.referenceLabel,
931
1147
  title: task.title,
1148
+ createdAt: task.createdAt,
932
1149
  status: task.status || null,
1150
+ priority: Number(task.priority) || 0,
1151
+ workstreamOrder: task.workstreamOrder ?? null,
1152
+ prerequisiteTaskIds: prerequisiteTaskIdsByTaskId.get(task.id) || [],
1153
+ dependencyState: getDependencyState(task.id),
1154
+ assignee: task.assignee || null,
1155
+ attachmentCount: Array.isArray(task.attachments) ? task.attachments.length : 0,
933
1156
  isArchived: Boolean(task.isArchived),
934
1157
  });
935
1158
  workstreamTaskPreviewsById.set(workstreamId, current);
@@ -942,6 +1165,12 @@ export function StandaloneLayout(props) {
942
1165
  const buildWorkstreamSummary = (workstream) => {
943
1166
  const taskSummary = workstreamTaskSummaryById.get(workstream.id);
944
1167
  const taskPreviews = workstreamTaskPreviewsById.get(workstream.id) || taskSummary?.tasks || [];
1168
+ const taskCounts = summarizeTaskCounts(taskSummary?.taskCount || 0, taskSummary?.completedTaskCount || 0);
1169
+ const archiveReadiness = resolveWorkstreamArchiveReadiness({
1170
+ isArchived: Boolean(workstream.isArchived),
1171
+ tasks: taskPreviews,
1172
+ dataReady: !useBootstrapTaskSummaries,
1173
+ });
945
1174
  const summary = {
946
1175
  id: workstream.id,
947
1176
  referenceNumber: workstream.referenceNumber ?? null,
@@ -949,12 +1178,20 @@ export function StandaloneLayout(props) {
949
1178
  description: String(workstream.description || '').trim() || undefined,
950
1179
  ownerId: workstream.ownerId ? String(workstream.ownerId) : null,
951
1180
  ownerLabel: workstream.ownerId ? assigneeLabelByValue.get(String(workstream.ownerId)) || String(workstream.ownerId) : null,
952
- ...summarizeTaskCounts(taskSummary?.taskCount || 0, taskSummary?.completedTaskCount || 0),
1181
+ icon: workstream.icon ?? null,
1182
+ color: workstream.color ?? null,
1183
+ ...taskCounts,
1184
+ statusCounts: workstreamStatusCountsById.get(workstream.id) || summarizeTaskStatuses([]),
953
1185
  initiativeId: workstream.initiativeId || null,
954
1186
  commentCount: Array.isArray(workstream.comments) ? workstream.comments.length : 0,
1187
+ comments: Array.isArray(workstream.comments) ? workstream.comments : [],
1188
+ activity: Array.isArray(workstream.activity) ? workstream.activity : [],
1189
+ entityEvents: Array.isArray(workstream.entityEvents) ? workstream.entityEvents : [],
955
1190
  attachmentCount: Array.isArray(workstream.attachments) ? workstream.attachments.length : 0,
956
1191
  attachments: Array.isArray(workstream.attachments) ? workstream.attachments : [],
957
1192
  isArchived: Boolean(workstream.isArchived),
1193
+ archiveReady: archiveReadiness.archiveReady,
1194
+ archiveActiveTaskCount: archiveReadiness.activeTaskCount,
958
1195
  tasks: taskPreviews,
959
1196
  };
960
1197
  workstreamTaskIds.set(workstream.id, taskPreviews.map((task) => task.id));
@@ -972,8 +1209,14 @@ export function StandaloneLayout(props) {
972
1209
  const allWorkstreamsForInitiative = workstreamsByInitiativeId.get(initiative.id) || [];
973
1210
  const workstreams = allWorkstreamsForInitiative
974
1211
  .filter((workstream) => isPlanningEntityVisibleForScope(taskScope, Boolean(workstream.isArchived)));
975
- const taskCount = workstreams.reduce((sum, workstream) => sum + workstream.taskCount, 0);
976
- const completedTaskCount = workstreams.reduce((sum, workstream) => sum + workstream.completedTaskCount, 0);
1212
+ const taskCount = allWorkstreamsForInitiative.reduce((sum, workstream) => sum + workstream.taskCount, 0);
1213
+ const completedTaskCount = allWorkstreamsForInitiative.reduce((sum, workstream) => sum + workstream.completedTaskCount, 0);
1214
+ const initiativeTaskCounts = summarizeTaskCounts(taskCount, completedTaskCount);
1215
+ const archiveReadiness = resolveInitiativeArchiveReadiness({
1216
+ isArchived: Boolean(initiative.isArchived),
1217
+ workstreams: allWorkstreamsForInitiative,
1218
+ dataReady: !useBootstrapTaskSummaries,
1219
+ });
977
1220
  const initiativeSummary = {
978
1221
  id: initiative.id,
979
1222
  referenceNumber: initiative.referenceNumber ?? null,
@@ -981,14 +1224,23 @@ export function StandaloneLayout(props) {
981
1224
  description: String(initiative.description || '').trim() || undefined,
982
1225
  ownerId: initiative.ownerId ? String(initiative.ownerId) : null,
983
1226
  ownerLabel: initiative.ownerId ? assigneeLabelByValue.get(String(initiative.ownerId)) || String(initiative.ownerId) : null,
984
- ...summarizeTaskCounts(taskCount, completedTaskCount),
1227
+ icon: initiative.icon ?? null,
1228
+ color: initiative.color ?? null,
1229
+ ...initiativeTaskCounts,
1230
+ statusCounts: combineTaskStatuses(allWorkstreamsForInitiative),
985
1231
  workstreamCount: workstreams.length,
986
1232
  workstreams,
987
1233
  allWorkstreams: allWorkstreamsForInitiative,
988
1234
  commentCount: Array.isArray(initiative.comments) ? initiative.comments.length : 0,
1235
+ comments: Array.isArray(initiative.comments) ? initiative.comments : [],
1236
+ activity: Array.isArray(initiative.activity) ? initiative.activity : [],
1237
+ entityEvents: Array.isArray(initiative.entityEvents) ? initiative.entityEvents : [],
989
1238
  attachmentCount: Array.isArray(initiative.attachments) ? initiative.attachments.length : 0,
990
1239
  attachments: Array.isArray(initiative.attachments) ? initiative.attachments : [],
991
1240
  isArchived: Boolean(initiative.isArchived),
1241
+ archiveReady: archiveReadiness.archiveReady,
1242
+ archiveActiveTaskCount: archiveReadiness.activeTaskCount,
1243
+ archiveActiveWorkstreamCount: archiveReadiness.activeWorkstreamCount,
992
1244
  };
993
1245
  return initiativeSummary;
994
1246
  });
@@ -1000,7 +1252,10 @@ export function StandaloneLayout(props) {
1000
1252
  return {
1001
1253
  initiatives,
1002
1254
  standaloneWorkstreams,
1255
+ allInitiatives,
1003
1256
  allStandaloneWorkstreams,
1257
+ allInitiativeById: new Map(allInitiatives.map((initiative) => [initiative.id, initiative])),
1258
+ allWorkstreamById: new Map(allWorkstreamSummaries.map((workstream) => [workstream.id, workstream])),
1004
1259
  workstreamTaskIds,
1005
1260
  workstreamInitiativeIds,
1006
1261
  initiativeTaskIds,
@@ -1009,11 +1264,13 @@ export function StandaloneLayout(props) {
1009
1264
  };
1010
1265
  }, [
1011
1266
  archivedScopeAllTasks,
1267
+ currentWorkspaceId,
1268
+ props.archiveHydratedWorkspaceId,
1012
1269
  assigneeLabelByValue,
1013
- deletedScopeAllTasks,
1014
1270
  props.initiatives,
1015
1271
  props.loadingTasks,
1016
1272
  props.planningBootstrapTaskSummaries,
1273
+ props.workspaceTaskRelationships,
1017
1274
  props.tasks,
1018
1275
  props.workstreams,
1019
1276
  taskScope,
@@ -1025,6 +1282,45 @@ export function StandaloneLayout(props) {
1025
1282
  label: referenceLabel || initiative.title,
1026
1283
  };
1027
1284
  }), [planningStructure.initiatives]);
1285
+ const planningLinkOptions = useMemo(() => {
1286
+ const sortByTitle = (left, right) => (left.title.localeCompare(right.title, undefined, { sensitivity: 'base' }));
1287
+ const initiatives = Array.from(planningStructure.allInitiativeById.values())
1288
+ .filter((initiative) => !initiative.isArchived)
1289
+ .map((initiative) => ({
1290
+ id: initiative.id,
1291
+ referenceLabel: formatInitiativeReference(initiative) || initiative.id,
1292
+ title: initiative.title,
1293
+ icon: initiative.icon,
1294
+ color: initiative.color,
1295
+ meta: `${initiative.workstreamCount || 0} workstream${initiative.workstreamCount === 1 ? '' : 's'}`,
1296
+ }))
1297
+ .sort(sortByTitle);
1298
+ const workstreams = Array.from(planningStructure.allWorkstreamById.values())
1299
+ .filter((workstream) => !workstream.isArchived)
1300
+ .map((workstream) => ({
1301
+ id: workstream.id,
1302
+ referenceLabel: formatWorkstreamReference(workstream) || workstream.id,
1303
+ title: workstream.title,
1304
+ icon: workstream.icon,
1305
+ color: workstream.color,
1306
+ meta: workstream.initiativeId
1307
+ ? `In ${planningStructure.allInitiativeById.get(workstream.initiativeId)?.title || 'another initiative'}`
1308
+ : 'Standalone workstream',
1309
+ }))
1310
+ .sort(sortByTitle);
1311
+ const tasks = hierarchyTasks
1312
+ .filter((task) => !task.isArchived && !task.isDeleted)
1313
+ .map((task) => ({
1314
+ id: task.id,
1315
+ referenceLabel: getTaskReferenceLabel(task) || task.id,
1316
+ title: task.title,
1317
+ meta: task.workstreamId
1318
+ ? `In ${planningStructure.allWorkstreamById.get(task.workstreamId)?.title || 'another workstream'}`
1319
+ : 'Unassigned to a workstream',
1320
+ }))
1321
+ .sort(sortByTitle);
1322
+ return { initiatives, workstreams, tasks };
1323
+ }, [hierarchyTasks, planningStructure.allInitiativeById, planningStructure.allWorkstreamById]);
1028
1324
  const workstreamFilterOptions = useMemo(() => {
1029
1325
  const visibleInitiativeWorkstreams = selectedPlanningInitiativeId
1030
1326
  ? (planningStructure.initiativeById.get(selectedPlanningInitiativeId)?.workstreams || [])
@@ -1065,22 +1361,20 @@ export function StandaloneLayout(props) {
1065
1361
  if (!planningDrawerDetail)
1066
1362
  return null;
1067
1363
  if (planningDrawerDetail.type === 'initiative') {
1068
- const item = planningStructure.initiativeById.get(planningDrawerDetail.id);
1364
+ const item = planningStructure.allInitiativeById.get(planningDrawerDetail.id);
1069
1365
  return item ? { type: 'initiative', item } : null;
1070
1366
  }
1071
- const item = planningStructure.workstreamById.get(planningDrawerDetail.id)
1072
- || planningStructure.standaloneWorkstreams.find((workstream) => workstream.id === planningDrawerDetail.id);
1367
+ const item = planningStructure.allWorkstreamById.get(planningDrawerDetail.id);
1073
1368
  return item ? { type: 'workstream', item } : null;
1074
- }, [planningDrawerDetail, planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
1369
+ }, [planningDrawerDetail, planningStructure.allInitiativeById, planningStructure.allWorkstreamById]);
1075
1370
  const planningNestedWorkstreamItem = useMemo(() => {
1076
1371
  if (!planningNestedWorkstreamDetailId)
1077
1372
  return null;
1078
- const item = planningStructure.workstreamById.get(planningNestedWorkstreamDetailId)
1079
- || planningStructure.standaloneWorkstreams.find((workstream) => workstream.id === planningNestedWorkstreamDetailId);
1373
+ const item = planningStructure.allWorkstreamById.get(planningNestedWorkstreamDetailId);
1080
1374
  return item ? { type: 'workstream', item } : null;
1081
- }, [planningNestedWorkstreamDetailId, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
1375
+ }, [planningNestedWorkstreamDetailId, planningStructure.allWorkstreamById]);
1082
1376
  const planningSecondaryPane = useMemo(() => {
1083
- if (planningSecondaryEditor) {
1377
+ if (planningSecondaryEditor?.mode === 'create') {
1084
1378
  return { kind: 'editor', editor: planningSecondaryEditor };
1085
1379
  }
1086
1380
  if (planningNestedWorkstreamItem) {
@@ -1088,15 +1382,22 @@ export function StandaloneLayout(props) {
1088
1382
  }
1089
1383
  return null;
1090
1384
  }, [planningNestedWorkstreamItem, planningSecondaryEditor]);
1091
- const planningDrawerWidthPx = getPlanningDrawerWidthPx(planningTreeCollapsed, Boolean(planningDrawerItem || planningEditor), planningPrimaryCollapsed, Boolean(planningSecondaryPane), planningSecondaryCollapsed);
1385
+ const primaryPlanningHydrationState = planningDrawerDetail
1386
+ ? planningHydrationStateByEntity[`${planningDrawerDetail.type}:${planningDrawerDetail.id}`]
1387
+ : undefined;
1388
+ const secondaryPlanningHydrationState = planningNestedWorkstreamDetailId
1389
+ ? planningHydrationStateByEntity[`workstream:${planningNestedWorkstreamDetailId}`]
1390
+ : undefined;
1391
+ const planningDrawerEstimatedWidthPx = getPlanningDrawerWidthPx(planningTreeCollapsed, Boolean(planningDrawerItem || planningEditor), planningPrimaryCollapsed, Boolean(planningSecondaryPane), planningSecondaryCollapsed);
1392
+ const [planningDrawerWidthPx, setPlanningDrawerWidthPx] = useState(planningDrawerEstimatedWidthPx);
1092
1393
  const planningDraftInitiativeSummary = useMemo(() => {
1093
1394
  if (!planningDraftInitiativeId.trim())
1094
1395
  return null;
1095
- const exactInitiative = planningStructure.initiativeById.get(planningDraftInitiativeId);
1396
+ const exactInitiative = planningStructure.allInitiativeById.get(planningDraftInitiativeId);
1096
1397
  if (exactInitiative)
1097
1398
  return exactInitiative;
1098
- return resolveInitiativeReference(planningStructure.initiatives, planningDraftInitiativeId);
1099
- }, [planningDraftInitiativeId, planningStructure.initiativeById, planningStructure.initiatives]);
1399
+ return resolveInitiativeReference(planningStructure.allInitiatives, planningDraftInitiativeId);
1400
+ }, [planningDraftInitiativeId, planningStructure.allInitiativeById, planningStructure.allInitiatives]);
1100
1401
  useEffect(() => {
1101
1402
  if (selectedPlanningInitiativeId && !planningStructure.initiativeById.has(selectedPlanningInitiativeId)) {
1102
1403
  setSelectedPlanningInitiativeId('');
@@ -1115,13 +1416,6 @@ export function StandaloneLayout(props) {
1115
1416
  return scheduleBaseTasks;
1116
1417
  return kanbanTasks;
1117
1418
  }, [groupBy, kanbanTasks, scheduleBaseTasks]);
1118
- const todayDateOnly = useMemo(() => {
1119
- const now = new Date();
1120
- const y = now.getFullYear();
1121
- const m = String(now.getMonth() + 1).padStart(2, '0');
1122
- const d = String(now.getDate()).padStart(2, '0');
1123
- return `${y}-${m}-${d}`;
1124
- }, []);
1125
1419
  const boardVisibleTasks = useMemo(() => {
1126
1420
  if (groupBy !== 'schedule' || !scheduleOnlyExpired)
1127
1421
  return hierarchyVisibleTasks;
@@ -1137,9 +1431,46 @@ export function StandaloneLayout(props) {
1137
1431
  const scopedBoardVisibleTasks = useMemo(() => {
1138
1432
  return scopeTasksToPlanningSelection(boardVisibleTasks, selectedPlanningTaskIds);
1139
1433
  }, [boardVisibleTasks, selectedPlanningTaskIds]);
1434
+ const trashSelection = useTrashSelection(props.deletedTasks, scopedBoardVisibleTasks.map((task) => task.id), taskScope === 'deleted');
1140
1435
  const scopedKanbanAllTasks = useMemo(() => {
1141
1436
  return scopeTasksToPlanningSelection(kanbanAllTasks, selectedPlanningTaskIds);
1142
1437
  }, [kanbanAllTasks, selectedPlanningTaskIds]);
1438
+ const scheduleFilteredTaskIdList = useMemo(() => Array.from(scheduleFilteredTaskIds), [scheduleFilteredTaskIds]);
1439
+ const handleBoardScheduleDaySelected = useCallback((dateOnly) => {
1440
+ setScheduleSelectedDate(dateOnly);
1441
+ const parsed = parseDateOnlyLocal(dateOnly);
1442
+ if (parsed) {
1443
+ setScheduleCalendarMonth(`${parsed.getFullYear()}-${String(parsed.getMonth() + 1).padStart(2, '0')}`);
1444
+ }
1445
+ }, []);
1446
+ const handleBoardScrollLeftChange = useCallback((scrollLeft) => {
1447
+ if (groupBy !== 'schedule')
1448
+ return;
1449
+ setScheduleScrollLeft(scrollLeft);
1450
+ }, [groupBy]);
1451
+ const handleBoardUnarchive = useCallback((taskId) => {
1452
+ if (taskScope === 'deleted') {
1453
+ const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
1454
+ if (!deletedRecord)
1455
+ return;
1456
+ void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
1457
+ return;
1458
+ }
1459
+ void handleUnarchive(taskId);
1460
+ }, [deletedTaskRecordByTaskId, handleRestoreDeletedTask, handleUnarchive, taskScope]);
1461
+ const handleBoardDelete = useCallback((taskId) => {
1462
+ if (taskScope === 'deleted') {
1463
+ const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
1464
+ if (!deletedRecord)
1465
+ return;
1466
+ const confirmed = window.confirm('Permanently delete this task? This cannot be undone.');
1467
+ if (!confirmed)
1468
+ return;
1469
+ void handlePermanentlyDeleteDeletedTask(deletedRecord.id);
1470
+ return;
1471
+ }
1472
+ void handleDelete(taskId);
1473
+ }, [deletedTaskRecordByTaskId, handleDelete, handlePermanentlyDeleteDeletedTask, taskScope]);
1143
1474
  const expiredRecoveryCandidates = useMemo(() => {
1144
1475
  if (groupBy !== 'schedule')
1145
1476
  return [];
@@ -1172,7 +1503,6 @@ export function StandaloneLayout(props) {
1172
1503
  return !!task.dueDate && task.dueDate < todayDateOnly;
1173
1504
  }).length;
1174
1505
  }, [groupBy, hierarchyVisibleTasks, todayDateOnly]);
1175
- const normalizedAuthUserId = String(authUserId || '').trim();
1176
1506
  const assignedTaskCount = useMemo(() => {
1177
1507
  if (!normalizedAuthUserId || normalizedAuthUserId === 'anonymous')
1178
1508
  return 0;
@@ -1225,35 +1555,179 @@ export function StandaloneLayout(props) {
1225
1555
  setTaskModalFullscreen(false);
1226
1556
  }
1227
1557
  }, [activeTab]);
1228
- const handleSetStatus = useCallback((task, status) => {
1229
- if (task.status === status)
1558
+ const handleSetStatus = useCallback(async (task, status, options) => {
1559
+ if (task.status === status && !options?.allowSameStatus)
1230
1560
  return;
1231
- if (status === 'in-progress') {
1232
- void handleToggleInProgress(task);
1561
+ await handleSetStatusDurably(task, status);
1562
+ }, [handleSetStatusDurably]);
1563
+ const handleSetPlanningTaskStatus = useCallback(async (taskId, status) => {
1564
+ const task = hierarchyTaskById.get(taskId);
1565
+ if (!task) {
1566
+ pushNotice('Task details are still loading.', 'info');
1233
1567
  return;
1234
1568
  }
1235
- if (status === 'review') {
1236
- void handleToggleReview(task);
1237
- return;
1569
+ await handleSetStatus(task, status);
1570
+ await props.fetchPlanningEntities();
1571
+ }, [handleSetStatus, hierarchyTaskById, props.fetchPlanningEntities, pushNotice]);
1572
+ const handleChangePlanningTaskAssignee = useCallback(async (taskId, assignee) => {
1573
+ const saved = await handleUpdateTask(taskId, { assignee });
1574
+ if (saved !== false)
1575
+ await props.fetchPlanningEntities();
1576
+ }, [handleUpdateTask, props.fetchPlanningEntities]);
1577
+ const archivePlanningTaskById = useCallback(async (taskId) => {
1578
+ const task = hierarchyTaskById.get(taskId);
1579
+ if (!task) {
1580
+ pushNotice('Task details are still loading.', 'info');
1581
+ return false;
1238
1582
  }
1239
- if (status === 'done') {
1240
- void handleToggleComplete(task);
1241
- return;
1583
+ if (task.isArchived)
1584
+ return true;
1585
+ if (task.status !== 'done' && task.status !== 'cancelled') {
1586
+ pushNotice('Only completed or cancelled tasks can be archived from Planning.', 'error');
1587
+ return false;
1242
1588
  }
1243
- if (status === 'cancelled') {
1244
- void handleToggleCancel(task);
1245
- return;
1589
+ return handleArchiveTask(task);
1590
+ }, [handleArchiveTask, hierarchyTaskById, pushNotice]);
1591
+ const handleArchivePlanningTask = useCallback(async (taskId) => {
1592
+ const archived = await archivePlanningTaskById(taskId);
1593
+ if (archived) {
1594
+ await props.fetchPlanningEntities();
1595
+ pushNotice('Task archived', 'success');
1596
+ }
1597
+ return archived;
1598
+ }, [archivePlanningTaskById, props.fetchPlanningEntities, pushNotice]);
1599
+ const handleArchiveResolvedWorkstream = useCallback(async (workstreamId) => {
1600
+ const workstream = planningStructure.allWorkstreamById.get(workstreamId);
1601
+ if (!workstream?.archiveReady) {
1602
+ pushNotice('This workstream is no longer ready to archive.', 'error');
1603
+ return false;
1604
+ }
1605
+ try {
1606
+ const archived = await archiveResolvedWorkstreamHierarchy({
1607
+ workstream,
1608
+ archiveTask: archivePlanningTaskById,
1609
+ archiveWorkstream: props.archiveWorkstream,
1610
+ });
1611
+ if (!archived) {
1612
+ pushNotice('Workstream archive stopped safely. Resolve any remaining tasks and retry.', 'error');
1613
+ return false;
1614
+ }
1615
+ pushNotice('Completed tasks and workstream archived', 'success');
1616
+ return true;
1617
+ }
1618
+ catch (error) {
1619
+ pushNotice(error instanceof Error
1620
+ ? `Workstream archive stopped safely: ${error.message}`
1621
+ : 'Workstream archive stopped safely. Retry to archive the remaining items.', 'error');
1622
+ return false;
1623
+ }
1624
+ }, [archivePlanningTaskById, planningStructure.allWorkstreamById, props.archiveWorkstream, pushNotice]);
1625
+ const handleArchiveResolvedInitiative = useCallback(async (initiativeId) => {
1626
+ const initiative = planningStructure.allInitiativeById.get(initiativeId);
1627
+ if (!initiative?.archiveReady) {
1628
+ pushNotice('This initiative is no longer ready to archive.', 'error');
1629
+ return false;
1630
+ }
1631
+ try {
1632
+ const archived = await archiveResolvedInitiativeHierarchy({
1633
+ initiativeId: initiative.id,
1634
+ workstreams: initiative.allWorkstreams || initiative.workstreams,
1635
+ archiveTask: archivePlanningTaskById,
1636
+ archiveWorkstream: props.archiveWorkstream,
1637
+ archiveInitiative: props.archiveInitiative,
1638
+ });
1639
+ if (!archived) {
1640
+ pushNotice('Initiative archive stopped safely. Resolve any remaining tasks and retry.', 'error');
1641
+ return false;
1642
+ }
1643
+ pushNotice('Completed tasks, workstreams, and initiative archived', 'success');
1644
+ return true;
1645
+ }
1646
+ catch (error) {
1647
+ pushNotice(error instanceof Error
1648
+ ? `Initiative archive stopped safely: ${error.message}`
1649
+ : 'Initiative archive stopped safely. Retry to archive the remaining items.', 'error');
1650
+ return false;
1246
1651
  }
1247
- void handleUpdateTask(task.id, {
1248
- status,
1249
- completedAt: null
1652
+ }, [
1653
+ archivePlanningTaskById,
1654
+ planningStructure.allInitiativeById,
1655
+ props.archiveInitiative,
1656
+ props.archiveWorkstream,
1657
+ pushNotice,
1658
+ ]);
1659
+ const handleArchivePlanningEntity = useCallback(async (entityType, entityId) => {
1660
+ const item = entityType === 'initiative'
1661
+ ? planningStructure.allInitiativeById.get(entityId)
1662
+ : planningStructure.allWorkstreamById.get(entityId);
1663
+ if (!item) {
1664
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} not found.`, 'error');
1665
+ return false;
1666
+ }
1667
+ const archiveState = resolvePlanningArchiveDetailState({
1668
+ entityType,
1669
+ isArchived: item.isArchived,
1670
+ taskCount: item.taskCount,
1671
+ completedTaskCount: item.completedTaskCount,
1672
+ archiveReady: item.archiveReady,
1673
+ activeWorkstreamCount: item.archiveActiveWorkstreamCount,
1250
1674
  });
1251
- }, [handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleUpdateTask]);
1675
+ if (archiveState.mode === 'archived')
1676
+ return true;
1677
+ if (archiveState.mode === 'ready') {
1678
+ return entityType === 'initiative'
1679
+ ? handleArchiveResolvedInitiative(entityId)
1680
+ : handleArchiveResolvedWorkstream(entityId);
1681
+ }
1682
+ if (archiveState.mode !== 'empty') {
1683
+ pushNotice(archiveState.mode === 'blocked'
1684
+ ? `Archive unavailable while active ${archiveState.remainingKind === 'task' ? 'tasks' : 'workstreams'} remain.`
1685
+ : 'Archive availability is still loading.', 'error');
1686
+ return false;
1687
+ }
1688
+ try {
1689
+ if (entityType === 'initiative') {
1690
+ await props.archiveInitiative(entityId);
1691
+ }
1692
+ else {
1693
+ await props.archiveWorkstream(entityId);
1694
+ }
1695
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} archived`, 'success');
1696
+ return true;
1697
+ }
1698
+ catch (error) {
1699
+ pushNotice(error instanceof Error ? error.message : `Failed to archive ${entityType}.`, 'error');
1700
+ return false;
1701
+ }
1702
+ }, [
1703
+ handleArchiveResolvedInitiative,
1704
+ handleArchiveResolvedWorkstream,
1705
+ planningStructure.allInitiativeById,
1706
+ planningStructure.allWorkstreamById,
1707
+ props.archiveInitiative,
1708
+ props.archiveWorkstream,
1709
+ pushNotice,
1710
+ ]);
1711
+ const handleUnarchivePlanningEntity = useCallback(async (entityType, entityId) => {
1712
+ try {
1713
+ if (entityType === 'initiative') {
1714
+ await props.unarchiveInitiative(entityId);
1715
+ }
1716
+ else {
1717
+ await props.unarchiveWorkstream(entityId);
1718
+ }
1719
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} unarchived`, 'success');
1720
+ return true;
1721
+ }
1722
+ catch (error) {
1723
+ pushNotice(error instanceof Error ? error.message : `Failed to unarchive ${entityType}.`, 'error');
1724
+ return false;
1725
+ }
1726
+ }, [props.unarchiveInitiative, props.unarchiveWorkstream, pushNotice]);
1252
1727
  const handleAddTaskToColumn = useCallback((groupField, value) => {
1253
1728
  resetForm();
1254
1729
  const defaults = resolveDraftDefaultsForGrouping(groupField, value, {
1255
- categories: activeCategories,
1256
- approaches
1730
+ categories: activeCategories
1257
1731
  });
1258
1732
  if (defaults.category)
1259
1733
  setCategory(defaults.category);
@@ -1263,12 +1737,6 @@ export function StandaloneLayout(props) {
1263
1737
  setPriority(defaults.priority);
1264
1738
  if (typeof defaults.complexity === 'number')
1265
1739
  setComplexity(defaults.complexity);
1266
- if (defaults.approach)
1267
- setApproach(defaults.approach);
1268
- const taxonomyApproach = defaults.taxonomyApproach;
1269
- if (typeof taxonomyApproach === 'string' && taxonomyApproach.length > 0) {
1270
- setFormTaxonomies(prev => ({ ...prev, approach: taxonomyApproach }));
1271
- }
1272
1740
  if (defaults.assignee)
1273
1741
  setAssignee(defaults.assignee);
1274
1742
  if (defaults.status)
@@ -1276,7 +1744,7 @@ export function StandaloneLayout(props) {
1276
1744
  if (defaults.scheduledDate)
1277
1745
  setScheduledDate(defaults.scheduledDate);
1278
1746
  setActiveTab('add');
1279
- }, [resetForm, activeCategories, approaches, setCategory, setType, setPriority, setComplexity, setStatus, setApproach, setAssignee, setScheduledDate, setFormTaxonomies, setActiveTab]);
1747
+ }, [resetForm, activeCategories, setCategory, setType, setPriority, setComplexity, setStatus, setAssignee, setScheduledDate, setActiveTab]);
1280
1748
  // Ensure 'done' status is shown by default as requested
1281
1749
  React.useEffect(() => {
1282
1750
  if (filterStatus && !filterStatus.includes('done')) {
@@ -1286,8 +1754,8 @@ export function StandaloneLayout(props) {
1286
1754
  // Local state for filter toolbar
1287
1755
  const [showHelpModal, setShowHelpModal] = useState(false);
1288
1756
  const [showAccountMenu, setShowAccountMenu] = useState(false);
1289
- const [showAccountHub, setShowAccountHub] = useState(false);
1290
- const [showEditProfileModal, setShowEditProfileModal] = useState(false);
1757
+ const [showAccountSettings, setShowAccountSettings] = useState(false);
1758
+ const accountSettingsWasOpenRef = useRef(false);
1291
1759
  const [showAvatarPhotoManager, setShowAvatarPhotoManager] = useState(false);
1292
1760
  const [workspaceActionBusy, setWorkspaceActionBusy] = useState(false);
1293
1761
  const [workspaceActionError, setWorkspaceActionError] = useState('');
@@ -1353,9 +1821,17 @@ export function StandaloneLayout(props) {
1353
1821
  const canManageCloudWorkspaces = runtimeMode === 'cloud' && workspaceSwitchingEnabled && isAuthenticated;
1354
1822
  const canAccessCloudTeamManagement = isAuthenticated && (runtimeMode === 'cloud' || cloudAuthConfigured);
1355
1823
  const canManageWorkspaceSync = runtimeMode === 'local' && isAuthenticated;
1824
+ const serverCoordinatorSyncEnabled = (localCoordinatorStatus?.phase === 'ready'
1825
+ && localCoordinatorStatus.snapshot?.state.ownershipMode === 'server')
1826
+ ? localCoordinatorStatus.snapshot.workspace?.runner?.checkpoint
1827
+ ?.checkpoint.syncEnabled
1828
+ : null;
1829
+ const effectiveWorkspaceCloudSyncEnabled = typeof serverCoordinatorSyncEnabled === 'boolean'
1830
+ ? serverCoordinatorSyncEnabled
1831
+ : workspaceCloudSyncEnabled;
1356
1832
  const { showSyncStatusModal, showSyncEnableWarning, workspaceSyncError, syncControlBusy, openSyncStatusModal, closeSyncStatusModal, handleWorkspaceSyncToggle, cancelSyncEnableWarning, confirmSyncEnableWarning, } = useSyncStatusControls({
1357
1833
  canManageWorkspaceSync,
1358
- workspaceCloudSyncEnabled,
1834
+ workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled,
1359
1835
  saveWorkspaceCloudSyncSettings,
1360
1836
  });
1361
1837
  const currentWorkspaceLabel = useMemo(() => {
@@ -1410,14 +1886,15 @@ export function StandaloneLayout(props) {
1410
1886
  ]);
1411
1887
  const isAuthBootstrapPending = cloudAuthConfigured && !authSessionResolved;
1412
1888
  useEffect(() => {
1413
- if (!showEditProfileModal)
1414
- return;
1415
- setProfileDisplayNameDraft(authDisplayName);
1416
- setProfileAvatarPreviewUrl(authAvatarUrl);
1417
- setProfileAvatarDraftId(null);
1418
- setProfileSaveError(null);
1419
- setProfileSaveNotice(null);
1420
- }, [authAvatarUrl, authDisplayName, showEditProfileModal]);
1889
+ if (showAccountSettings && !accountSettingsWasOpenRef.current) {
1890
+ setProfileDisplayNameDraft(authDisplayName);
1891
+ setProfileAvatarPreviewUrl(authAvatarUrl);
1892
+ setProfileAvatarDraftId(null);
1893
+ setProfileSaveError(null);
1894
+ setProfileSaveNotice(null);
1895
+ }
1896
+ accountSettingsWasOpenRef.current = showAccountSettings;
1897
+ }, [authAvatarUrl, authDisplayName, showAccountSettings]);
1421
1898
  const discardProfileAvatarDraft = useCallback(async (draftId) => {
1422
1899
  const normalizedDraftId = String(draftId || '').trim();
1423
1900
  if (!normalizedDraftId || !cloudAuthConfigured)
@@ -1434,9 +1911,9 @@ export function StandaloneLayout(props) {
1434
1911
  // Best-effort cleanup only.
1435
1912
  }
1436
1913
  }, [cloudAuthConfigured, resolveCloudAuthUrl]);
1437
- const closeEditProfileModal = useCallback(() => {
1914
+ const closeAccountSettingsModal = useCallback(() => {
1438
1915
  const pendingDraftId = profileAvatarDraftId;
1439
- setShowEditProfileModal(false);
1916
+ setShowAccountSettings(false);
1440
1917
  setShowAvatarPhotoManager(false);
1441
1918
  setProfileSaveError(null);
1442
1919
  setProfileSaveNotice(null);
@@ -1574,7 +2051,6 @@ export function StandaloneLayout(props) {
1574
2051
  setProfileAvatarPreviewUrl('');
1575
2052
  setProfileSaveBusy(false);
1576
2053
  setShowAvatarPhotoManager(false);
1577
- setShowEditProfileModal(false);
1578
2054
  }, [authAvatarUrl, profileAvatarDraftId, profileAvatarPreviewUrl, profileDisplayNameDraft, updateCurrentUserProfile]);
1579
2055
  const teamAdminHeaders = useCallback(() => {
1580
2056
  const headers = {};
@@ -1592,7 +2068,7 @@ export function StandaloneLayout(props) {
1592
2068
  }, [currentWorkspaceRole, teamManagementWorkspaceId, teamWorkspaceRole]);
1593
2069
  const startAccountSurfaceTiming = useCallback((surface) => {
1594
2070
  const expectsBilling = isAuthenticated;
1595
- const expectsTeamManagement = canAccessCloudTeamManagement;
2071
+ const expectsTeamManagement = surface === 'account_menu' && canAccessCloudTeamManagement;
1596
2072
  accountSurfaceOpenStartedAtRef.current = getTimingNow();
1597
2073
  accountSurfacePendingRef.current = {
1598
2074
  billing: expectsBilling,
@@ -1622,13 +2098,13 @@ export function StandaloneLayout(props) {
1622
2098
  if (startedAt === null)
1623
2099
  return;
1624
2100
  logBootstrapDebug('account_surface_ready', {
1625
- surface: showAccountHub ? 'account_hub' : (showAccountMenu ? 'account_menu' : 'closed'),
2101
+ surface: showAccountSettings ? 'account_settings' : (showAccountMenu ? 'account_menu' : 'closed'),
1626
2102
  durationMs: Math.round(getTimingNow() - startedAt),
1627
2103
  teamManagementVisible: canOpenTeamManagement,
1628
2104
  billingPlanId: String(accountProfileSummary?.planId || '').trim() || null
1629
2105
  });
1630
2106
  accountSurfaceOpenStartedAtRef.current = null;
1631
- }, [accountProfileSummary?.planId, canOpenTeamManagement, showAccountHub, showAccountMenu]);
2107
+ }, [accountProfileSummary?.planId, canOpenTeamManagement, showAccountMenu, showAccountSettings]);
1632
2108
  const loadAccountProfileSummary = useCallback(async (options) => {
1633
2109
  const accountProfileSummaryUrl = resolveCloudAuthUrl(ACCOUNT_PROFILE_SUMMARY_PATH);
1634
2110
  if (!isAuthenticated) {
@@ -1798,10 +2274,10 @@ export function StandaloneLayout(props) {
1798
2274
  void loadAccountProfileSummary();
1799
2275
  }, [authSessionResolved, isAuthenticated, loadAccountProfileSummary]);
1800
2276
  useEffect(() => {
1801
- if (!showAccountHub && !showAccountMenu)
2277
+ if (!showAccountSettings && !showAccountMenu)
1802
2278
  return;
1803
2279
  void loadAccountProfileSummary();
1804
- }, [loadAccountProfileSummary, showAccountHub, showAccountMenu]);
2280
+ }, [loadAccountProfileSummary, showAccountMenu, showAccountSettings]);
1805
2281
  const loadTeamUsers = useCallback(async () => {
1806
2282
  if (!canManageTeamWorkspace)
1807
2283
  return;
@@ -1891,7 +2367,7 @@ export function StandaloneLayout(props) {
1891
2367
  const targetRaw = `${location.pathname}${location.search}${location.hash}`;
1892
2368
  const target = (!targetRaw || targetRaw === '/login' || !targetRaw.startsWith('/')) ? '/' : targetRaw;
1893
2369
  setShowAccountMenu(false);
1894
- setShowAccountHub(false);
2370
+ setShowAccountSettings(false);
1895
2371
  closeSyncStatusModal();
1896
2372
  navigate(`/login?mode=${mode}&next=${encodeURIComponent(target)}`);
1897
2373
  }, [closeSyncStatusModal, location.hash, location.pathname, location.search, navigate]);
@@ -1984,9 +2460,28 @@ export function StandaloneLayout(props) {
1984
2460
  setActiveTab,
1985
2461
  setActiveWorkspaceModule,
1986
2462
  ]);
2463
+ const handleTaskHeaderQuickFilter = useCallback((filter) => {
2464
+ toggleTaskHeaderQuickFilter(filter);
2465
+ setTaskScope('open');
2466
+ setShowArchive(false);
2467
+ setActiveWorkspaceModule('tasks');
2468
+ if (isPlansScreen)
2469
+ closePlansScreen();
2470
+ }, [
2471
+ closePlansScreen,
2472
+ isPlansScreen,
2473
+ setActiveWorkspaceModule,
2474
+ setShowArchive,
2475
+ setTaskScope,
2476
+ toggleTaskHeaderQuickFilter,
2477
+ ]);
1987
2478
  const handleSwitchWorkspace = useCallback(async (workspaceId) => {
1988
2479
  if (!workspaceId || workspaceActionBusy)
1989
2480
  return;
2481
+ if (workflowManagerHasUnsavedChanges && !workflowDiscardBypassRef.current) {
2482
+ setPendingWorkflowDiscardAction(() => () => { void handleSwitchWorkspace(workspaceId); });
2483
+ return;
2484
+ }
1990
2485
  setWorkspaceActionError('');
1991
2486
  setWorkspaceActionBusy(true);
1992
2487
  try {
@@ -2005,7 +2500,7 @@ export function StandaloneLayout(props) {
2005
2500
  finally {
2006
2501
  setWorkspaceActionBusy(false);
2007
2502
  }
2008
- }, [switchWorkspace, workspaceActionBusy, fetchTasks, openWorkspaceSetup]);
2503
+ }, [switchWorkspace, workspaceActionBusy, fetchTasks, openWorkspaceSetup, workflowManagerHasUnsavedChanges]);
2009
2504
  const openTeamManagementModal = useCallback(async () => {
2010
2505
  setShowAccountMenu(false);
2011
2506
  setShowTeamManagementModal(true);
@@ -2094,6 +2589,7 @@ export function StandaloneLayout(props) {
2094
2589
  const hasPriorityFilter = filterPriorities.length !== priorities.length;
2095
2590
  const hasStatusFilter = filterStatus.length !== STATUS_OPTIONS.length;
2096
2591
  const hasAssigneeFilter = filterAssignees.length !== assigneeOptions.length;
2592
+ const hasHeaderQuickFilter = taskHeaderQuickFilter !== null;
2097
2593
  const hasInitiativeScopeFilter = selectedPlanningInitiativeId.length > 0;
2098
2594
  const hasWorkstreamScopeFilter = selectedPlanningWorkstreamId.length > 0;
2099
2595
  return hasCategoryFilter
@@ -2101,6 +2597,7 @@ export function StandaloneLayout(props) {
2101
2597
  || hasPriorityFilter
2102
2598
  || hasStatusFilter
2103
2599
  || hasAssigneeFilter
2600
+ || hasHeaderQuickFilter
2104
2601
  || hasInitiativeScopeFilter
2105
2602
  || hasWorkstreamScopeFilter;
2106
2603
  }, [
@@ -2115,25 +2612,41 @@ export function StandaloneLayout(props) {
2115
2612
  priorities.length,
2116
2613
  selectedPlanningInitiativeId,
2117
2614
  selectedPlanningWorkstreamId,
2615
+ taskHeaderQuickFilter,
2118
2616
  ]);
2119
- const hasDocumentDropdownFilters = useMemo(() => (documentTypeFilters.length !== DOCUMENT_TYPE_FILTER_OPTIONS.length
2120
- || documentAttachmentFilters.length !== DOCUMENT_ATTACHMENT_FILTER_OPTIONS.length), [documentAttachmentFilters.length, documentTypeFilters.length]);
2121
2617
  const workspaceChromeMode = resolvedWorkspaceModule;
2122
2618
  const workspaceChromeDefinition = useMemo(() => getWorkspaceChromeDefinition(workspaceChromeMode), [workspaceChromeMode]);
2123
- const hasActiveWorkspaceFilterControls = useMemo(() => {
2124
- switch (workspaceChromeDefinition.filterBar.kind) {
2125
- case 'task-filters':
2126
- return hasDropdownFilters;
2127
- case 'document-filters':
2128
- return hasDocumentDropdownFilters;
2129
- default:
2130
- return false;
2619
+ useLayoutEffect(() => {
2620
+ if (!taskforceAgentDrawerOpen && activeTab !== 'add')
2621
+ return;
2622
+ const updateDrawerTop = () => {
2623
+ const appHeader = appShellHeaderRef.current;
2624
+ const headerBottom = appHeader
2625
+ ? Math.ceil(appHeader.getBoundingClientRect().bottom)
2626
+ : TASKFORCE_AGENT_DRAWER_FALLBACK_TOP;
2627
+ setTaskforceAgentDrawerTop(Math.max(TASKFORCE_AGENT_DRAWER_FALLBACK_TOP, headerBottom));
2628
+ };
2629
+ updateDrawerTop();
2630
+ window.addEventListener('resize', updateDrawerTop);
2631
+ const appHeader = appShellHeaderRef.current;
2632
+ const resizeObserver = typeof ResizeObserver !== 'undefined'
2633
+ ? new ResizeObserver(updateDrawerTop)
2634
+ : null;
2635
+ if (resizeObserver) {
2636
+ if (appHeader)
2637
+ resizeObserver.observe(appHeader);
2131
2638
  }
2132
- }, [
2133
- hasDocumentDropdownFilters,
2134
- hasDropdownFilters,
2135
- workspaceChromeDefinition.filterBar.kind,
2136
- ]);
2639
+ return () => {
2640
+ window.removeEventListener('resize', updateDrawerTop);
2641
+ resizeObserver?.disconnect();
2642
+ };
2643
+ }, [activeTab, taskforceAgentDrawerOpen]);
2644
+ useEffect(() => {
2645
+ if (!taskforceAgentsWorkspaceEnabled) {
2646
+ setTaskforceAgentDrawerOpen(false);
2647
+ }
2648
+ }, [taskforceAgentsWorkspaceEnabled]);
2649
+ const hasActiveWorkspaceFilterControls = workspaceChromeDefinition.moduleId === 'tasks' && hasDropdownFilters;
2137
2650
  // Check if any filters are set (search + dropdown filters)
2138
2651
  const isFiltered = hasSearchFilter || hasDropdownFilters;
2139
2652
  const totalActiveCount = taskScope === 'archived'
@@ -2145,11 +2658,13 @@ export function StandaloneLayout(props) {
2145
2658
  ? archivedScopeTasks.length
2146
2659
  : taskScope === 'deleted'
2147
2660
  ? filteredDeletedTasks.length
2148
- : props.filteredTasks.length;
2661
+ : quickFilteredOpenTasks.length;
2149
2662
  const activeCountLabel = isFiltered ? `${visibleActiveCount}/${totalActiveCount}` : `${totalActiveCount}`;
2150
2663
  const activeCountTitle = isFiltered
2151
2664
  ? `${taskScope.charAt(0).toUpperCase() + taskScope.slice(1)} tasks matching current filters`
2152
- : `${taskScope.charAt(0).toUpperCase() + taskScope.slice(1)} tasks`;
2665
+ : taskScope === 'deleted'
2666
+ ? 'Trash tasks — automatically deleted after 90 days'
2667
+ : `${taskScope.charAt(0).toUpperCase() + taskScope.slice(1)} tasks`;
2153
2668
  const shouldShowSyncStatus = runtimeMode === 'local' && isAuthenticated;
2154
2669
  const formatSyncTimestamp = useCallback((value) => {
2155
2670
  if (!value)
@@ -2164,7 +2679,9 @@ export function StandaloneLayout(props) {
2164
2679
  const formattedLastPushTime = useMemo(() => formatSyncTimestamp(workspaceLastPushAt), [formatSyncTimestamp, workspaceLastPushAt]);
2165
2680
  const rawSyncLastError = workspaceSyncError || workspaceLastErrorMessage || userGlobalSyncError || 'None';
2166
2681
  const workspaceSyncDiagnostics = getWorkspaceSyncDiagnostics();
2167
- const headerSyncPresentation = useMemo(() => resolveHeaderWorkspaceSyncPresentation({
2682
+ const coordinatorRecoveryObligations = localCoordinatorStatus?.snapshot
2683
+ ?.permits.recoveryObligations || 0;
2684
+ const browserHeaderSyncPresentation = useMemo(() => resolveHeaderWorkspaceSyncPresentation({
2168
2685
  runtimeMode,
2169
2686
  isAuthenticated,
2170
2687
  workspaceSyncStatus,
@@ -2172,6 +2689,7 @@ export function StandaloneLayout(props) {
2172
2689
  workspaceSyncSummary,
2173
2690
  workspaceSyncRecommendedAction,
2174
2691
  workspaceSyncError: rawSyncLastError,
2692
+ coordinatorRecoveryObligations,
2175
2693
  pushBlockedReason: workspaceSyncDiagnostics.pushBlockedReason || null,
2176
2694
  pullBlockedReason: workspaceSyncDiagnostics.pullBlockedReason || null,
2177
2695
  retryBlockedReason: workspaceSyncDiagnostics.retryBlockedReason || null
@@ -2183,13 +2701,73 @@ export function StandaloneLayout(props) {
2183
2701
  workspaceSyncSummary,
2184
2702
  workspaceSyncRecommendedAction,
2185
2703
  rawSyncLastError,
2704
+ coordinatorRecoveryObligations,
2186
2705
  workspaceSyncDiagnostics.pushBlockedReason,
2187
2706
  workspaceSyncDiagnostics.pullBlockedReason,
2188
2707
  workspaceSyncDiagnostics.retryBlockedReason
2189
2708
  ]);
2709
+ const coordinatorSyncPresentation = useMemo(() => resolveCoordinatorWorkspaceSyncPresentation(localCoordinatorStatus), [localCoordinatorStatus]);
2710
+ const headerSyncPresentation = coordinatorSyncPresentation?.header
2711
+ || browserHeaderSyncPresentation;
2712
+ const effectivePendingLocalChanges = coordinatorSyncPresentation
2713
+ ? coordinatorSyncPresentation.pendingLocalChanges
2714
+ : workspaceSyncPendingChanges;
2715
+ const effectiveLastPullAt = coordinatorSyncPresentation
2716
+ ? coordinatorSyncPresentation.lastPullAt
2717
+ : workspaceLastPullAt;
2718
+ const effectiveLastPushAt = coordinatorSyncPresentation
2719
+ ? coordinatorSyncPresentation.lastPushAt
2720
+ : workspaceLastPushAt;
2721
+ const effectiveLastSyncedAt = coordinatorSyncPresentation
2722
+ ? coordinatorSyncPresentation.lastSyncedAt
2723
+ : workspaceLastSuccessfulSyncAt;
2724
+ const effectiveFormattedLastPullTime = formatSyncTimestamp(effectiveLastPullAt);
2725
+ const effectiveFormattedLastPushTime = formatSyncTimestamp(effectiveLastPushAt);
2726
+ const effectiveFormattedLastSyncTime = formatSyncTimestamp(effectiveLastSyncedAt);
2727
+ const effectiveWorkspaceSyncBusy = coordinatorSyncPresentation
2728
+ ? coordinatorSyncPresentation.busy
2729
+ : workspaceSyncBusy;
2730
+ const coordinatorOwnershipState = localCoordinatorStatus?.snapshot
2731
+ ?.state.ownershipMode || null;
2732
+ const coordinatorOwnershipMode = (coordinatorOwnershipState === 'server'
2733
+ || coordinatorOwnershipState === 'browser-gateway') ? coordinatorOwnershipState : null;
2734
+ const [coordinatorOwnershipTransferBusy, setCoordinatorOwnershipTransferBusy] = useState(false);
2735
+ const coordinatorOwnershipTransferDisabled = (localCoordinatorStatus?.phase !== 'ready'
2736
+ || !localCoordinatorStatus.snapshot
2737
+ || localCoordinatorStatus.snapshot.state.transitionState !== 'idle'
2738
+ || localCoordinatorStatus.snapshot.permits.active > 0
2739
+ || coordinatorRecoveryObligations > 0);
2740
+ const handleCoordinatorOwnershipTransfer = useCallback(async () => {
2741
+ if (!coordinatorOwnershipMode || coordinatorOwnershipTransferBusy)
2742
+ return;
2743
+ setCoordinatorOwnershipTransferBusy(true);
2744
+ try {
2745
+ const targetMode = coordinatorOwnershipMode === 'server'
2746
+ ? 'browser-gateway'
2747
+ : 'server';
2748
+ await transferLocalCoordinatorOwnership(targetMode);
2749
+ pushNotice(targetMode === 'server'
2750
+ ? 'The local Taskforce server now owns background synchronization.'
2751
+ : 'This browser now owns background synchronization.', 'success');
2752
+ }
2753
+ catch (error) {
2754
+ pushNotice(error instanceof Error && error.message.trim()
2755
+ ? error.message
2756
+ : 'Sync ownership could not be transferred.', 'error');
2757
+ }
2758
+ finally {
2759
+ setCoordinatorOwnershipTransferBusy(false);
2760
+ }
2761
+ }, [
2762
+ coordinatorOwnershipMode,
2763
+ coordinatorOwnershipTransferBusy,
2764
+ pushNotice,
2765
+ transferLocalCoordinatorOwnership,
2766
+ ]);
2190
2767
  const syncLastError = headerSyncPresentation.lastError;
2191
2768
  const [headerSyncStatus, setHeaderSyncStatus] = useState(headerSyncPresentation.status);
2192
- const syncDiagnosticsSummary = useMemo(() => buildSyncDiagnosticsSummary(workspaceSyncDiagnostics), [workspaceSyncDiagnostics]);
2769
+ const syncDiagnosticsSummary = useMemo(() => coordinatorSyncPresentation?.diagnostics
2770
+ || buildSyncDiagnosticsSummary({ ...workspaceSyncDiagnostics, coordinatorRecoveryObligations }), [coordinatorSyncPresentation, workspaceSyncDiagnostics, coordinatorRecoveryObligations]);
2193
2771
  const { syncRecentEvents, syncRecentEventsLoading, syncRecentEventsError, syncEventsListRef, loadRecentSyncEvents, } = useRecentSyncEvents({
2194
2772
  isOpen: showSyncStatusModal,
2195
2773
  workspaceId: currentWorkspaceId,
@@ -2203,7 +2781,7 @@ export function StandaloneLayout(props) {
2203
2781
  const shouldDelayHeaderSyncing = headerSyncPresentation.actionable
2204
2782
  && workspaceSyncStatus === 'syncing'
2205
2783
  && workspaceSyncPhase === 'active'
2206
- && workspaceSyncPendingChanges === 0;
2784
+ && effectivePendingLocalChanges === 0;
2207
2785
  useEffect(() => {
2208
2786
  if (!shouldDelayHeaderSyncing) {
2209
2787
  setHeaderSyncStatus(headerSyncPresentation.status);
@@ -2222,16 +2800,17 @@ export function StandaloneLayout(props) {
2222
2800
  const referenceMismatchCount = useMemo(() => getActiveReferenceMismatchCount(syncRecentEvents), [syncRecentEvents]);
2223
2801
  const activeReferenceMismatchSummaries = useMemo(() => buildReferenceMismatchSummaries(syncRecentEvents), [syncRecentEvents]);
2224
2802
  const syncStatusMeta = useMemo(() => resolveSyncStatusMeta(headerSyncStatus), [headerSyncStatus]);
2803
+ const headerSyncStatusMeta = useMemo(() => resolveHeaderSyncStatusMeta(headerSyncStatus, effectiveWorkspaceCloudSyncEnabled), [effectiveWorkspaceCloudSyncEnabled, headerSyncStatus]);
2225
2804
  const { workspaceSyncRepairBusy, workspaceSyncRepairQueued, workspaceSyncCopied, handleCopySyncDetails, handleQueueOrRunRepairSync, } = useSyncStatusActions({
2226
2805
  currentWorkspaceId,
2227
2806
  syncStatusLabel: syncStatusMeta.label,
2228
2807
  workspaceSyncSummary: headerSyncPresentation.summary,
2229
2808
  workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction,
2230
- formattedLastSyncTime,
2231
- formattedLastPullTime,
2232
- formattedLastPushTime,
2809
+ formattedLastSyncTime: effectiveFormattedLastSyncTime,
2810
+ formattedLastPullTime: effectiveFormattedLastPullTime,
2811
+ formattedLastPushTime: effectiveFormattedLastPushTime,
2233
2812
  workspaceSyncDiagnostics,
2234
- workspaceSyncPendingChanges,
2813
+ workspaceSyncPendingChanges: effectivePendingLocalChanges,
2235
2814
  syncLastError,
2236
2815
  workspaceSyncPhase,
2237
2816
  referenceMismatchCount,
@@ -2239,9 +2818,14 @@ export function StandaloneLayout(props) {
2239
2818
  loadRecentSyncEvents,
2240
2819
  pushNotice,
2241
2820
  resetWorkspaceSyncCursorAndPull,
2242
- workspaceSyncBusy,
2821
+ workspaceSyncBusy: effectiveWorkspaceSyncBusy,
2822
+ durableRepairQueueAvailable: coordinatorOwnershipMode === 'server',
2243
2823
  });
2244
- const syncStageLabel = useMemo(() => resolveSyncStageLabel(workspaceSyncPhase, workspaceSyncRepairBusy, workspaceSyncBusy), [workspaceSyncBusy, workspaceSyncPhase, workspaceSyncRepairBusy]);
2824
+ const effectiveWorkspaceSyncRepairBusy = coordinatorSyncPresentation
2825
+ ? coordinatorSyncPresentation.repairBusy
2826
+ : workspaceSyncRepairBusy;
2827
+ const syncStageLabel = useMemo(() => coordinatorSyncPresentation?.stage
2828
+ || resolveSyncStageLabel(workspaceSyncPhase, workspaceSyncRepairBusy, workspaceSyncBusy), [coordinatorSyncPresentation, workspaceSyncBusy, workspaceSyncPhase, workspaceSyncRepairBusy]);
2245
2829
  const selectedDateObj = useMemo(() => parseDateOnlyLocal(scheduleSelectedDate) || new Date(), [scheduleSelectedDate]);
2246
2830
  const scheduleWeekStart = useMemo(() => startOfWeek(selectedDateObj, globalWeekStartsOn), [selectedDateObj, globalWeekStartsOn]);
2247
2831
  const scheduleDates = useMemo(() => {
@@ -2363,8 +2947,6 @@ export function StandaloneLayout(props) {
2363
2947
  { value: 4, label: 'High', icon: 'Gauge', color: '#8b5cf6' },
2364
2948
  { value: 5, label: 'Epic', icon: 'Gauge', color: '#d946ef' }
2365
2949
  ];
2366
- case 'approach':
2367
- return approaches;
2368
2950
  case 'assignee':
2369
2951
  return assigneeOptions.map((option) => ({
2370
2952
  value: option.value,
@@ -2387,7 +2969,7 @@ export function StandaloneLayout(props) {
2387
2969
  default:
2388
2970
  return activeCategories;
2389
2971
  }
2390
- }, [groupBy, activeCategories, activeTypes, priorities, approaches, assigneeOptions, scheduleColumns]);
2972
+ }, [groupBy, activeCategories, activeTypes, priorities, assigneeOptions, scheduleColumns]);
2391
2973
  // === SECTION: AccountMenuControl ===
2392
2974
  // Not extracted: ~25 distinct props from local state would be needed.
2393
2975
  // References: isAuthenticated, authIdentityLabel, accountProfileSummary, runtimeLabel,
@@ -2420,21 +3002,12 @@ export function StandaloneLayout(props) {
2420
3002
  setShowAccountMenu(false);
2421
3003
  }, role: "menuitem", disabled: workspaceActionBusy, children: [_jsx(Plus, { size: 15 }), "Create Workspace"] }), workspaceActionError && (_jsx("div", { className: accountStyles.accountMenuError, children: workspaceActionError }))] })), teamManagementAccessLoading ? (_jsx("div", { className: accountStyles.accountMenuHint, children: "Resolving team management access..." })) : canOpenTeamManagement ? (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => { void openTeamManagementModal(); }, role: "menuitem", children: [_jsx(Users, { size: 15 }), "Team Management"] })) : teamManagementAccessError ? (_jsx("div", { className: accountStyles.accountMenuHint, children: "Team Management unavailable right now." })) : null, isAuthenticated && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2422
3004
  setShowAccountMenu(false);
2423
- setShowEditProfileModal(true);
2424
- }, role: "menuitem", children: [_jsx(User, { size: 15 }), "Edit Profile"] })), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2425
- setShowAccountMenu(false);
2426
- openPlansScreen();
2427
- }, role: "menuitem", children: [_jsx(Layers, { size: 15 }), "Plans"] }), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2428
- setShowAccountMenu(false);
2429
- startAccountSurfaceTiming('account_hub');
2430
- setShowAccountHub(true);
2431
- }, role: "menuitem", children: [_jsx(User, { size: 15 }), "Account Hub"] }), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2432
- setShowAccountMenu(false);
2433
- setShowHelpModal(true);
2434
- }, role: "menuitem", children: [_jsx(HelpCircle, { size: 15 }), "Help & Support"] }), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
3005
+ startAccountSurfaceTiming('account_settings');
3006
+ setShowAccountSettings(true);
3007
+ }, role: "menuitem", children: [_jsx(Settings, { size: 15 }), "Account Settings"] })), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2435
3008
  setShowAccountMenu(false);
2436
3009
  setShowHelpModal(true);
2437
- }, role: "menuitem", children: [_jsx(Mail, { size: 15 }), "Contact Support"] }), runtimeMode === 'local' && !isAuthenticated && !isAuthBootstrapPending && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
3010
+ }, role: "menuitem", children: [_jsx(HelpCircle, { size: 15 }), "Help & Support"] }), runtimeMode === 'local' && !isAuthenticated && !isAuthBootstrapPending && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2438
3011
  openSharedLoginRoute('login');
2439
3012
  }, role: "menuitem", children: [_jsx(User, { size: 15 }), "Sign In / Register"] })), isAuthenticated && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: async () => {
2440
3013
  setShowAccountMenu(false);
@@ -2474,6 +3047,8 @@ export function StandaloneLayout(props) {
2474
3047
  setPlanningDraftTitle('');
2475
3048
  setPlanningDraftDescription('');
2476
3049
  setPlanningDraftOwner('');
3050
+ setPlanningDraftIcon(null);
3051
+ setPlanningDraftColor(null);
2477
3052
  const selectedInitiative = editor.entityType === 'workstream' && selectedPlanningInitiativeId
2478
3053
  ? planningStructure.initiativeById.get(selectedPlanningInitiativeId) || null
2479
3054
  : null;
@@ -2488,6 +3063,8 @@ export function StandaloneLayout(props) {
2488
3063
  setPlanningDraftTitle('');
2489
3064
  setPlanningDraftDescription('');
2490
3065
  setPlanningDraftOwner('');
3066
+ setPlanningDraftIcon(null);
3067
+ setPlanningDraftColor(null);
2491
3068
  const selectedInitiative = editor.entityType === 'workstream'
2492
3069
  ? ((initiativeId ? planningStructure.initiativeById.get(initiativeId) : null)
2493
3070
  || (selectedPlanningInitiativeId ? planningStructure.initiativeById.get(selectedPlanningInitiativeId) || null : null))
@@ -2502,6 +3079,8 @@ export function StandaloneLayout(props) {
2502
3079
  setPlanningDraftTitle('');
2503
3080
  setPlanningDraftDescription('');
2504
3081
  setPlanningDraftOwner('');
3082
+ setPlanningDraftIcon(null);
3083
+ setPlanningDraftColor(null);
2505
3084
  setPlanningDraftInitiativeId('');
2506
3085
  }, []);
2507
3086
  const closePlanningSecondaryEditor = useCallback(() => {
@@ -2511,12 +3090,17 @@ export function StandaloneLayout(props) {
2511
3090
  setPlanningDraftTitle('');
2512
3091
  setPlanningDraftDescription('');
2513
3092
  setPlanningDraftOwner('');
3093
+ setPlanningDraftIcon(null);
3094
+ setPlanningDraftColor(null);
2514
3095
  setPlanningDraftInitiativeId('');
2515
3096
  }, []);
2516
3097
  const submitPlanningEditor = useCallback(async () => {
2517
3098
  const activeEditor = planningSecondaryEditor || planningEditor;
2518
3099
  if (!activeEditor || planningEditorSubmitInFlightRef.current)
2519
3100
  return;
3101
+ const title = planningDraftTitle.trim();
3102
+ if (!title)
3103
+ return;
2520
3104
  planningEditorSubmitInFlightRef.current = true;
2521
3105
  setIsSubmittingPlanningEditor(true);
2522
3106
  const isSecondaryEditor = Boolean(planningSecondaryEditor);
@@ -2525,19 +3109,21 @@ export function StandaloneLayout(props) {
2525
3109
  if (activeEditor.entityType === 'initiative') {
2526
3110
  if (activeEditor.mode === 'edit') {
2527
3111
  await props.updateInitiative(activeEditor.targetId, {
2528
- title: planningDraftTitle.trim() || 'Untitled Initiative',
3112
+ title,
2529
3113
  description: planningDraftDescription.trim() || null,
2530
- ownerId,
2531
3114
  });
2532
3115
  setPlanningDrawerDetail({ type: 'initiative', id: activeEditor.targetId });
2533
- setPlanningNestedWorkstreamDetailId(null);
2534
3116
  pushNotice('Initiative updated', 'success');
2535
3117
  }
2536
3118
  else {
2537
3119
  const created = await props.createInitiative({
2538
- title: planningDraftTitle.trim() || 'Untitled Initiative',
3120
+ title,
2539
3121
  description: planningDraftDescription.trim() || null,
2540
3122
  ownerId,
3123
+ ...(planningDraftIcon || planningDraftColor ? {
3124
+ icon: planningDraftIcon,
3125
+ color: planningDraftColor,
3126
+ } : {}),
2541
3127
  });
2542
3128
  setPlanningDrawerDetail({ type: 'initiative', id: created.id });
2543
3129
  setPlanningNestedWorkstreamDetailId(null);
@@ -2545,19 +3131,16 @@ export function StandaloneLayout(props) {
2545
3131
  }
2546
3132
  }
2547
3133
  else {
2548
- const nextInitiativeRaw = planningDraftInitiativeId.trim();
2549
- const resolvedInitiative = nextInitiativeRaw.length === 0
2550
- ? null
2551
- : resolveInitiativeReference(planningStructure.initiatives, nextInitiativeRaw);
2552
- if (nextInitiativeRaw.length > 0 && !resolvedInitiative) {
3134
+ const resolvedInitiative = resolveWorkstreamCreateInitiativeId(planningStructure.allInitiatives, activeEditor.mode === 'create' ? activeEditor.initiativeId : null, planningDraftInitiativeId);
3135
+ if (resolvedInitiative.invalid) {
2553
3136
  pushNotice('Initiative not found by that reference.', 'error');
2554
3137
  return;
2555
3138
  }
2556
3139
  const patch = {
2557
- title: planningDraftTitle.trim() || 'Untitled Workstream',
3140
+ title,
2558
3141
  description: planningDraftDescription.trim() || null,
2559
- ownerId,
2560
- initiativeId: resolvedInitiative?.id || null,
3142
+ initiativeId: resolvedInitiative.initiativeId,
3143
+ ...(activeEditor.mode === 'create' ? { ownerId } : {}),
2561
3144
  };
2562
3145
  if (activeEditor.mode === 'edit') {
2563
3146
  await props.updateWorkstream(activeEditor.targetId, patch);
@@ -2571,7 +3154,13 @@ export function StandaloneLayout(props) {
2571
3154
  pushNotice('Workstream updated', 'success');
2572
3155
  }
2573
3156
  else {
2574
- const created = await props.createWorkstream(patch);
3157
+ const created = await props.createWorkstream({
3158
+ ...patch,
3159
+ ...(planningDraftIcon || planningDraftColor ? {
3160
+ icon: planningDraftIcon,
3161
+ color: planningDraftColor,
3162
+ } : {}),
3163
+ });
2575
3164
  if (isSecondaryEditor) {
2576
3165
  setPlanningNestedWorkstreamDetailId(created.id);
2577
3166
  }
@@ -2601,11 +3190,13 @@ export function StandaloneLayout(props) {
2601
3190
  closePlanningSecondaryEditor,
2602
3191
  planningDraftDescription,
2603
3192
  planningDraftInitiativeId,
3193
+ planningDraftIcon,
3194
+ planningDraftColor,
2604
3195
  planningDraftOwner,
2605
3196
  planningDraftTitle,
2606
3197
  planningEditor,
2607
3198
  planningSecondaryEditor,
2608
- planningStructure.initiatives,
3199
+ planningStructure.allInitiatives,
2609
3200
  props,
2610
3201
  pushNotice,
2611
3202
  ]);
@@ -2653,9 +3244,193 @@ export function StandaloneLayout(props) {
2653
3244
  setPlanningSecondaryCollapsed(false);
2654
3245
  setPlanningNestedWorkstreamDetailId(workstreamId);
2655
3246
  }, []);
3247
+ const handleCanonicalEntityReference = useCallback((reference) => {
3248
+ if (reference.kind === 'initiative' || reference.kind === 'workstream') {
3249
+ const entity = reference.kind === 'initiative'
3250
+ ? props.initiatives.find((initiative) => initiative.referenceNumber === reference.referenceNumber)
3251
+ : props.workstreams.find((workstream) => workstream.referenceNumber === reference.referenceNumber);
3252
+ if (!entity) {
3253
+ pushNotice(`${reference.token} could not be found.`, 'error');
3254
+ return;
3255
+ }
3256
+ handoffTaskModalToWorkspace(() => {
3257
+ setActiveWorkspaceModule('planning');
3258
+ setPlanningDrawerOpen(true);
3259
+ if (reference.kind === 'initiative')
3260
+ openInitiativeDetails(entity.id);
3261
+ else
3262
+ openWorkstreamDetails(entity.id);
3263
+ });
3264
+ return;
3265
+ }
3266
+ const workspaceId = String(currentWorkspaceId || 'default').trim() || 'default';
3267
+ const preview = (attachment) => {
3268
+ dispatchPreviewContextAttachment(attachment, {
3269
+ ownerType: 'task',
3270
+ ownerId: editingTaskId,
3271
+ ownerReferenceLabel: getTaskReferenceLabel(currentTask),
3272
+ workspaceId,
3273
+ });
3274
+ };
3275
+ void resolveCanonicalAttachmentReference(reference, {
3276
+ workspaceId,
3277
+ headers: workspaceUiStateHeaders,
3278
+ }).then(preview).catch(() => {
3279
+ pushNotice(`${reference.token} could not be opened.`, 'error');
3280
+ });
3281
+ }, [
3282
+ currentTask,
3283
+ currentWorkspaceId,
3284
+ editingTaskId,
3285
+ handoffTaskModalToWorkspace,
3286
+ openInitiativeDetails,
3287
+ openWorkstreamDetails,
3288
+ props.initiatives,
3289
+ props.workstreams,
3290
+ pushNotice,
3291
+ setActiveWorkspaceModule,
3292
+ workspaceUiStateHeaders,
3293
+ ]);
3294
+ const taskTextReferences = useMemo(() => ({
3295
+ ...taskReferences,
3296
+ entityReferences: {
3297
+ resolve: parseCanonicalEntityReference,
3298
+ activate: handleCanonicalEntityReference,
3299
+ },
3300
+ }), [handleCanonicalEntityReference, taskReferences]);
3301
+ useEffect(() => {
3302
+ const initiativeId = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.initiative) || '').trim();
3303
+ const workstreamId = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.workstream) || '').trim();
3304
+ const documentAssetId = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.document) || '').trim();
3305
+ const imageReference = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.image) || '').trim();
3306
+ const target = initiativeId
3307
+ ? `initiative:${initiativeId}`
3308
+ : workstreamId
3309
+ ? `workstream:${workstreamId}`
3310
+ : documentAssetId
3311
+ ? `document:${documentAssetId}`
3312
+ : imageReference
3313
+ ? `image:${imageReference}`
3314
+ : '';
3315
+ if (!target || handledEntityDeepLinkRef.current === target)
3316
+ return;
3317
+ if (initiativeId || workstreamId) {
3318
+ const entity = initiativeId
3319
+ ? props.initiatives.find((initiative) => initiative.id === initiativeId)
3320
+ : props.workstreams.find((workstream) => workstream.id === workstreamId);
3321
+ if (!entity)
3322
+ return;
3323
+ handledEntityDeepLinkRef.current = target;
3324
+ handoffTaskModalToWorkspace(() => {
3325
+ setActiveWorkspaceModule('planning');
3326
+ setPlanningDrawerOpen(true);
3327
+ if (initiativeId)
3328
+ openInitiativeDetails(entity.id);
3329
+ else
3330
+ openWorkstreamDetails(entity.id);
3331
+ });
3332
+ return;
3333
+ }
3334
+ if (documentAssetId) {
3335
+ if (!documentsWorkspaceEnabled)
3336
+ return;
3337
+ handledEntityDeepLinkRef.current = target;
3338
+ handoffTaskModalToWorkspace(() => {
3339
+ setRequestedDocPath(null);
3340
+ setRequestedDocAssetId(documentAssetId);
3341
+ setActiveWorkspaceModule('docs');
3342
+ });
3343
+ return;
3344
+ }
3345
+ if (!annotatedAttachmentsWorkspaceEnabled)
3346
+ return;
3347
+ handledEntityDeepLinkRef.current = target;
3348
+ const workspaceId = String(currentWorkspaceId || 'default').trim() || 'default';
3349
+ const query = new URLSearchParams({ workspaceId });
3350
+ void fetch(`/api/taskforce/annotated-attachments/images/${encodeURIComponent(imageReference)}?${query.toString()}`, { credentials: 'include', headers: workspaceUiStateHeaders }).then(async (response) => {
3351
+ if (!response.ok)
3352
+ throw new Error('Image not found');
3353
+ const payload = await response.json();
3354
+ if (!payload.target?.assetId || !payload.target.path)
3355
+ throw new Error('Image target is unavailable');
3356
+ handoffTaskModalToWorkspace(() => {
3357
+ const target = payload.target;
3358
+ requestedAnnotatedTargetRef.current = target;
3359
+ requestedAnnotatedSessionIdRef.current = null;
3360
+ setRequestedAnnotatedTarget(target);
3361
+ setRequestedAnnotatedSessionId(null);
3362
+ setRequestedAnnotatedOpenVersion((current) => current + 1);
3363
+ setActiveWorkspaceModule('annotate');
3364
+ });
3365
+ }).catch(() => {
3366
+ pushNotice(`Image ${imageReference} could not be opened.`, 'error');
3367
+ });
3368
+ }, [
3369
+ annotatedAttachmentsWorkspaceEnabled,
3370
+ currentWorkspaceId,
3371
+ documentsWorkspaceEnabled,
3372
+ handoffTaskModalToWorkspace,
3373
+ openInitiativeDetails,
3374
+ openWorkstreamDetails,
3375
+ props.initiatives,
3376
+ props.workstreams,
3377
+ pushNotice,
3378
+ routeQuery,
3379
+ setActiveWorkspaceModule,
3380
+ workspaceUiStateHeaders,
3381
+ ]);
3382
+ const hydratePlanningEntity = useCallback(async (target) => {
3383
+ const key = `${target.type}:${target.id}`;
3384
+ setPlanningHydrationStateByEntity((current) => ({
3385
+ ...current,
3386
+ [key]: { status: 'loading', error: null },
3387
+ }));
3388
+ try {
3389
+ await props.fetchPlanningEntityDetail(target.type, target.id);
3390
+ setPlanningHydrationStateByEntity((current) => ({
3391
+ ...current,
3392
+ [key]: { status: 'ready', error: null },
3393
+ }));
3394
+ }
3395
+ catch (error) {
3396
+ setPlanningHydrationStateByEntity((current) => ({
3397
+ ...current,
3398
+ [key]: {
3399
+ status: 'error',
3400
+ error: error instanceof Error ? error.message : 'Failed to load the latest planning details.',
3401
+ },
3402
+ }));
3403
+ }
3404
+ }, [props.fetchPlanningEntityDetail]);
3405
+ useEffect(() => {
3406
+ const targets = new Map();
3407
+ if (planningDrawerDetail?.id) {
3408
+ targets.set(`${planningDrawerDetail.type}:${planningDrawerDetail.id}`, planningDrawerDetail);
3409
+ }
3410
+ if (planningNestedWorkstreamDetailId) {
3411
+ targets.set(`workstream:${planningNestedWorkstreamDetailId}`, {
3412
+ type: 'workstream',
3413
+ id: planningNestedWorkstreamDetailId,
3414
+ });
3415
+ }
3416
+ if (targets.size === 0)
3417
+ return;
3418
+ for (const target of targets.values()) {
3419
+ void hydratePlanningEntity(target);
3420
+ }
3421
+ }, [
3422
+ hydratePlanningEntity,
3423
+ planningDrawerDetail?.id,
3424
+ planningDrawerDetail?.type,
3425
+ planningNestedWorkstreamDetailId,
3426
+ ]);
2656
3427
  const openPlanningCreateEditor = useCallback((type, initiativeId) => {
2657
3428
  if (type === 'workstream' && initiativeId) {
2658
- openPlanningSecondaryEditor({ mode: 'create', entityType: 'workstream' }, initiativeId);
3429
+ openPlanningSecondaryEditor({
3430
+ mode: 'create',
3431
+ entityType: 'workstream',
3432
+ initiativeId,
3433
+ }, initiativeId);
2659
3434
  return;
2660
3435
  }
2661
3436
  openPlanningEditor({ mode: 'create', entityType: type });
@@ -2667,30 +3442,68 @@ export function StandaloneLayout(props) {
2667
3442
  }
2668
3443
  }, [openPlanningEditor, openPlanningSecondaryEditor, planningStructure.initiativeById, selectedPlanningInitiativeId]);
2669
3444
  const openPlanningEditDialog = useCallback((type, id) => {
3445
+ planningEditorSubmitInFlightRef.current = false;
3446
+ setIsSubmittingPlanningEditor(false);
2670
3447
  if (type === 'initiative') {
2671
- const item = planningStructure.initiativeById.get(id);
3448
+ const item = planningStructure.allInitiativeById.get(id);
2672
3449
  if (!item)
2673
3450
  return;
3451
+ setPlanningSecondaryEditor(null);
2674
3452
  setPlanningEditor({ mode: 'edit', entityType: 'initiative', targetId: id });
2675
3453
  setPlanningDraftTitle(item.title);
2676
3454
  setPlanningDraftDescription(item.description || '');
2677
3455
  setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
2678
3456
  setPlanningDraftInitiativeId('');
3457
+ return;
2679
3458
  }
2680
3459
  else {
2681
- const item = planningStructure.workstreamById.get(id)
2682
- || planningStructure.standaloneWorkstreams.find((workstream) => workstream.id === id);
3460
+ const item = planningStructure.allWorkstreamById.get(id);
2683
3461
  if (!item)
2684
3462
  return;
2685
- setPlanningEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
3463
+ const isNestedDetail = planningNestedWorkstreamDetailId === id;
3464
+ if (isNestedDetail) {
3465
+ setPlanningEditor(null);
3466
+ setPlanningSecondaryEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
3467
+ }
3468
+ else {
3469
+ setPlanningSecondaryEditor(null);
3470
+ setPlanningEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
3471
+ }
2686
3472
  setPlanningDraftTitle(item.title);
2687
3473
  setPlanningDraftDescription(item.description || '');
2688
3474
  setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
2689
- const initiative = item.initiativeId ? planningStructure.initiativeById.get(item.initiativeId) || null : null;
3475
+ const initiative = item.initiativeId ? planningStructure.allInitiativeById.get(item.initiativeId) || null : null;
2690
3476
  setPlanningDraftInitiativeId(initiative ? formatInitiativeReference(initiative) : '');
3477
+ if (isNestedDetail)
3478
+ return;
2691
3479
  }
2692
3480
  setPlanningNestedWorkstreamDetailId(null);
2693
- }, [planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
3481
+ }, [planningNestedWorkstreamDetailId, planningStructure.allInitiativeById, planningStructure.allWorkstreamById]);
3482
+ const handleChangePlanningOwner = useCallback(async (entityType, entityId, nextOwnerId) => {
3483
+ const ownerId = nextOwnerId.trim() || null;
3484
+ try {
3485
+ if (entityType === 'initiative') {
3486
+ await props.updateInitiative(entityId, { ownerId });
3487
+ }
3488
+ else {
3489
+ await props.updateWorkstream(entityId, { ownerId });
3490
+ }
3491
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} owner updated`, 'success');
3492
+ }
3493
+ catch (error) {
3494
+ pushNotice(error instanceof Error ? error.message : 'Failed to update owner.', 'error');
3495
+ throw error;
3496
+ }
3497
+ }, [props, pushNotice]);
3498
+ const handleChangePlanningIdentity = useCallback(async (entityType, entityId, patch) => {
3499
+ try {
3500
+ await props.updatePlanningIdentity(entityType, entityId, patch);
3501
+ }
3502
+ catch (error) {
3503
+ pushNotice(error instanceof Error ? error.message : 'Failed to update visual identity.', 'error');
3504
+ throw error;
3505
+ }
3506
+ }, [props.updatePlanningIdentity, pushNotice]);
2694
3507
  const handleAssignInitiativeToWorkstream = useCallback(async (workstreamId, initiativeReferenceOverride) => {
2695
3508
  const workstream = props.workstreams.find((item) => item.id === workstreamId);
2696
3509
  if (!workstream) {
@@ -2704,7 +3517,7 @@ export function StandaloneLayout(props) {
2704
3517
  : planningDraftInitiativeId.trim();
2705
3518
  const resolvedInitiative = nextInitiativeRaw.length === 0
2706
3519
  ? null
2707
- : resolveInitiativeReference(planningStructure.initiatives, nextInitiativeRaw);
3520
+ : resolveInitiativeReference(planningStructure.allInitiatives, nextInitiativeRaw);
2708
3521
  if (nextInitiativeRaw.length > 0 && !resolvedInitiative) {
2709
3522
  pushNotice('Initiative not found by that reference.', 'error');
2710
3523
  return false;
@@ -2724,7 +3537,7 @@ export function StandaloneLayout(props) {
2724
3537
  pushNotice('Failed to set initiative.', 'error');
2725
3538
  return false;
2726
3539
  }
2727
- }, [planningDraftInitiativeId, planningStructure.initiatives, props, pushNotice]);
3540
+ }, [planningDraftInitiativeId, planningStructure.allInitiatives, props, pushNotice]);
2728
3541
  const handleAssignTaskToWorkstream = useCallback(async (taskId, workstreamId) => {
2729
3542
  const task = hierarchyTaskById.get(taskId);
2730
3543
  if (!task) {
@@ -2745,18 +3558,10 @@ export function StandaloneLayout(props) {
2745
3558
  return false;
2746
3559
  }
2747
3560
  try {
2748
- const res = await fetch(`/api/taskforce/task/${taskId}`, {
2749
- method: 'PATCH',
2750
- headers: { 'Content-Type': 'application/json' },
2751
- body: JSON.stringify({ workstreamId: normalizedWorkstreamId })
2752
- });
2753
- if (!res.ok) {
2754
- const data = await res.json().catch(() => ({}));
2755
- pushNotice(data?.error || 'Failed to set workstream.', 'error');
3561
+ const saved = await props.handleUpdateTask(taskId, { workstreamId: normalizedWorkstreamId });
3562
+ if (saved === false)
2756
3563
  return false;
2757
- }
2758
- await res.json().catch(() => null);
2759
- await fetchTasks(true);
3564
+ await props.fetchPlanningEntities();
2760
3565
  pushNotice(normalizedWorkstreamId ? 'Workstream set' : 'Workstream removed', 'success');
2761
3566
  return true;
2762
3567
  }
@@ -2764,7 +3569,7 @@ export function StandaloneLayout(props) {
2764
3569
  pushNotice('Failed to set workstream.', 'error');
2765
3570
  return false;
2766
3571
  }
2767
- }, [fetchTasks, hierarchyTaskById, planningStructure.initiativeById, planningStructure.workstreamById, pushNotice]);
3572
+ }, [hierarchyTaskById, planningStructure.initiativeById, planningStructure.workstreamById, props, pushNotice]);
2768
3573
  const handleAttachTaskToWorkstreamByReference = useCallback(async (workstreamId, taskReference) => {
2769
3574
  const needle = taskReference.trim();
2770
3575
  if (!needle) {
@@ -2787,7 +3592,7 @@ export function StandaloneLayout(props) {
2787
3592
  pushNotice('Enter a workstream reference.', 'error');
2788
3593
  return false;
2789
3594
  }
2790
- const initiative = planningStructure.initiativeById.get(initiativeId);
3595
+ const initiative = planningStructure.allInitiativeById.get(initiativeId);
2791
3596
  if (!initiative) {
2792
3597
  pushNotice('Initiative not found.', 'error');
2793
3598
  return false;
@@ -2801,7 +3606,7 @@ export function StandaloneLayout(props) {
2801
3606
  return false;
2802
3607
  }
2803
3608
  return handleAssignInitiativeToWorkstream(matchedWorkstream.id, formatInitiativeReference(initiative));
2804
- }, [handleAssignInitiativeToWorkstream, planningStructure.initiativeById, props.workstreams, pushNotice]);
3609
+ }, [handleAssignInitiativeToWorkstream, planningStructure.allInitiativeById, props.workstreams, pushNotice]);
2805
3610
  const getPlanningContextAttachmentDraft = useCallback((entityType, entityId) => {
2806
3611
  const key = `${entityType}:${entityId}`;
2807
3612
  const draft = planningContextAttachmentDraftsRef.current.get(key);
@@ -2865,12 +3670,21 @@ export function StandaloneLayout(props) {
2865
3670
  pushNotice(`${unavailableLabel} is not available in this build yet.`, 'error');
2866
3671
  return;
2867
3672
  }
3673
+ if (resolvedWorkspaceModule === 'workflowManager'
3674
+ && nextModule !== 'workflowManager'
3675
+ && workflowManagerHasUnsavedChanges
3676
+ && !workflowDiscardBypassRef.current) {
3677
+ setPendingWorkflowDiscardAction(() => () => handleModuleChange(nextModuleId));
3678
+ return;
3679
+ }
2868
3680
  clearTaskOriginWorkspaceModule();
2869
3681
  setActiveWorkspaceModule(nextModule);
2870
3682
  }, [
2871
3683
  clearTaskOriginWorkspaceModule,
2872
3684
  pushNotice,
3685
+ resolvedWorkspaceModule,
2873
3686
  setActiveWorkspaceModule,
3687
+ workflowManagerHasUnsavedChanges,
2874
3688
  workspaceModules,
2875
3689
  ]);
2876
3690
  const handlePlanningToolToggle = useCallback(() => {
@@ -2905,13 +3719,87 @@ export function StandaloneLayout(props) {
2905
3719
  setImageTrayOpen((current) => !current);
2906
3720
  }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
2907
3721
  const handleAgentTrayToggle = useCallback(() => {
2908
- if (resolvedWorkspaceModule !== 'agents') {
2909
- setActiveWorkspaceModule('agents');
3722
+ if (resolvedWorkspaceModule !== 'aiProfiles') {
3723
+ setActiveWorkspaceModule('aiProfiles');
2910
3724
  setAgentTrayOpen(true);
2911
3725
  return;
2912
3726
  }
2913
3727
  setAgentTrayOpen((current) => !current);
2914
3728
  }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
3729
+ const handleTaskforceAgentRosterTrayToggle = useCallback(() => {
3730
+ if (resolvedWorkspaceModule !== 'taskforceAgents') {
3731
+ setActiveWorkspaceModule('taskforceAgents');
3732
+ setTaskforceAgentRosterTrayOpen(true);
3733
+ return;
3734
+ }
3735
+ setTaskforceAgentRosterTrayOpen((current) => !current);
3736
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
3737
+ const handleWorkflowLibraryTrayToggle = useCallback(() => {
3738
+ if (resolvedWorkspaceModule !== 'workflowManager') {
3739
+ setActiveWorkspaceModule('workflowManager');
3740
+ setWorkflowLibraryTrayOpen(true);
3741
+ return;
3742
+ }
3743
+ setWorkflowLibraryTrayOpen((current) => !current);
3744
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
3745
+ const handleCloseTaskforceAgentDrawer = useCallback(() => {
3746
+ setTaskforceAgentDrawerOpen(false);
3747
+ setTaskforceAgentsLaunchContext(null);
3748
+ setTaskforceAgentDrawerHeaderContent(null);
3749
+ }, []);
3750
+ const handleAskTaskforceAgentForTask = useCallback((task) => {
3751
+ if (!workspaceFeatureAccess[TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]?.allowed) {
3752
+ pushNotice('Taskforce Agents are unavailable for this workspace.', 'error');
3753
+ return;
3754
+ }
3755
+ const taskReference = getTaskReferenceLabel(task) || task.id;
3756
+ setTaskforceAgentsLaunchContext({
3757
+ taskId: task.id,
3758
+ taskReference,
3759
+ taskTitle: task.title,
3760
+ });
3761
+ setTaskforceAgentPanelCollapsed(false);
3762
+ setTaskforceAgentDrawerOpen(true);
3763
+ setTaskModalFullscreen(false);
3764
+ }, [
3765
+ pushNotice,
3766
+ workspaceFeatureAccess,
3767
+ ]);
3768
+ const handleOpenTaskforceAgentDrawer = useCallback(() => {
3769
+ if (currentTask && editingTaskId) {
3770
+ handleAskTaskforceAgentForTask(currentTask);
3771
+ return;
3772
+ }
3773
+ if (!workspaceFeatureAccess[TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]?.allowed) {
3774
+ pushNotice('Taskforce Agents are unavailable for this workspace.', 'error');
3775
+ return;
3776
+ }
3777
+ setTaskforceAgentsLaunchContext(null);
3778
+ setTaskforceAgentPanelCollapsed(false);
3779
+ setTaskforceAgentDrawerOpen(true);
3780
+ }, [
3781
+ currentTask,
3782
+ editingTaskId,
3783
+ handleAskTaskforceAgentForTask,
3784
+ pushNotice,
3785
+ workspaceFeatureAccess,
3786
+ ]);
3787
+ const handleOpenTaskforceAgentConversation = useCallback((agentId) => {
3788
+ const normalizedAgentId = String(agentId || '').trim();
3789
+ if (!normalizedAgentId)
3790
+ return;
3791
+ handleRememberTaskforceAgentSelection({
3792
+ agentId: normalizedAgentId,
3793
+ conversationId: taskforceAgentConversationByAgentId[normalizedAgentId] || null,
3794
+ });
3795
+ setTaskforceAgentsLaunchContext(null);
3796
+ setTaskforceAgentPanelCollapsed(false);
3797
+ setTaskforceAgentDrawerOpen(true);
3798
+ }, [handleRememberTaskforceAgentSelection, taskforceAgentConversationByAgentId]);
3799
+ const handleOpenTaskforceAgentTaskContext = useCallback((taskId) => {
3800
+ handleOpenTaskById(taskId);
3801
+ setTaskModalFullscreen(false);
3802
+ }, [handleOpenTaskById]);
2915
3803
  const handleBackToTaskFromAnnotatedAttachment = useCallback((taskId) => {
2916
3804
  clearTaskOriginWorkspaceModule();
2917
3805
  setActiveWorkspaceModule('tasks');
@@ -2923,12 +3811,17 @@ export function StandaloneLayout(props) {
2923
3811
  handleOpenTaskById(taskId);
2924
3812
  }, [clearTaskOriginWorkspaceModule, handleOpenTaskById, setActiveWorkspaceModule]);
2925
3813
  const handleAnnotatedAttachmentOpenTarget = useCallback((target, options) => {
3814
+ const sessionId = options?.sessionId ?? null;
3815
+ requestedAnnotatedTargetRef.current = target;
3816
+ requestedAnnotatedSessionIdRef.current = sessionId;
2926
3817
  setRequestedAnnotatedTarget(target);
2927
- setRequestedAnnotatedSessionId(options?.sessionId ?? null);
3818
+ setRequestedAnnotatedSessionId(sessionId);
2928
3819
  setRequestedAnnotatedOpenVersion((current) => current + 1);
2929
3820
  setActiveWorkspaceModule('annotate');
2930
3821
  }, [setActiveWorkspaceModule]);
2931
3822
  const handleAnnotatedAttachmentContextChange = useCallback(({ target, sessionId }) => {
3823
+ requestedAnnotatedTargetRef.current = target;
3824
+ requestedAnnotatedSessionIdRef.current = sessionId;
2932
3825
  setRequestedAnnotatedTarget((current) => {
2933
3826
  if (!current && !target)
2934
3827
  return current;
@@ -2946,6 +3839,41 @@ export function StandaloneLayout(props) {
2946
3839
  });
2947
3840
  setRequestedAnnotatedSessionId((current) => (current === sessionId ? current : sessionId));
2948
3841
  }, []);
3842
+ const handleDocumentScrollChange = useCallback((docId, scrollTop) => {
3843
+ const normalizedDocId = docId.trim();
3844
+ const normalizedScrollTop = Math.max(0, Math.round(scrollTop));
3845
+ if (!normalizedDocId)
3846
+ return;
3847
+ setDocumentScrollByDocId((current) => {
3848
+ if (current[normalizedDocId] === normalizedScrollTop)
3849
+ return current;
3850
+ return withBoundedRecordEntry(current, normalizedDocId, normalizedScrollTop);
3851
+ });
3852
+ }, []);
3853
+ const handleDocumentListScrollChange = useCallback((scrollTop) => {
3854
+ const normalizedScrollTop = Math.max(0, Math.round(scrollTop));
3855
+ setDocumentListScrollTop((current) => (current === normalizedScrollTop ? current : normalizedScrollTop));
3856
+ }, []);
3857
+ const handleAnnotatedViewportChange = useCallback((contextKey, viewport) => {
3858
+ const normalizedContextKey = contextKey.trim();
3859
+ if (!normalizedContextKey)
3860
+ return;
3861
+ const normalizedViewport = {
3862
+ zoomLevel: Math.min(4, Math.max(0.25, viewport.zoomLevel)),
3863
+ scrollLeft: Math.max(0, Math.round(viewport.scrollLeft)),
3864
+ scrollTop: Math.max(0, Math.round(viewport.scrollTop)),
3865
+ };
3866
+ setAnnotatedViewportByContextKey((current) => {
3867
+ const currentViewport = current[normalizedContextKey];
3868
+ if (currentViewport
3869
+ && currentViewport.zoomLevel === normalizedViewport.zoomLevel
3870
+ && currentViewport.scrollLeft === normalizedViewport.scrollLeft
3871
+ && currentViewport.scrollTop === normalizedViewport.scrollTop) {
3872
+ return current;
3873
+ }
3874
+ return withBoundedRecordEntry(current, normalizedContextKey, normalizedViewport);
3875
+ });
3876
+ }, []);
2949
3877
  const sortOptions = useMemo(() => [
2950
3878
  { value: 'created', label: t('standalone.sortCreated') },
2951
3879
  { value: 'updated', label: t('standalone.sortUpdated') },
@@ -2994,59 +3922,73 @@ export function StandaloneLayout(props) {
2994
3922
  cycleEmptyColumnVisibility,
2995
3923
  emptyColumnMode,
2996
3924
  ]);
2997
- const universalFilterActions = useMemo(() => [{
2998
- key: 'filter-toggle',
2999
- icon: _jsx(Filter, { size: 16 }),
3000
- title: t('standalone.toggleFilters'),
3001
- onClick: () => setShowFilters(!showFilters),
3002
- active: showFilters,
3003
- className: hasActiveWorkspaceFilterControls ? styles.filterGlow : '',
3004
- }], [hasActiveWorkspaceFilterControls, setShowFilters, showFilters]);
3005
- const workspaceFilterBar = useMemo(() => {
3006
- switch (workspaceChromeDefinition.filterBar.kind) {
3007
- case 'task-filters':
3008
- return (_jsx(FilterToolbar, { categoryFilterOptions: categoryFilterOptions, typeFilterOptions: typeFilterOptions, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, filterCategories: filterCategories, setFilterCategories: setFilterCategories, filterTypes: filterTypes, setFilterTypes: setFilterTypes, filterPriorities: filterPriorities, setFilterPriorities: setFilterPriorities, filterStatus: filterStatus, setFilterStatus: setFilterStatus, filterAssignees: filterAssignees, setFilterAssignees: setFilterAssignees, assigneeOptions: assigneeOptions, initiativeFilterOptions: initiativeFilterOptions, selectedInitiativeId: selectedPlanningInitiativeId, setSelectedInitiativeId: handleInitiativeFilterChange, workstreamFilterOptions: workstreamFilterOptions, selectedWorkstreamId: selectedPlanningWorkstreamId, setSelectedWorkstreamId: handleWorkstreamFilterChange, taskScope: taskScope, setTaskScope: setTaskScope, showArchive: showArchive, setShowArchive: setShowArchive, fetchArchive: fetchArchive, onDeleteAllDeleted: () => {
3009
- const deletedCount = deletedScopeAllTasks.length;
3010
- if (deletedCount === 0)
3011
- return;
3012
- const confirmed = window.confirm(`Permanently delete ${deletedCount} deleted task${deletedCount === 1 ? '' : 's'}? This cannot be undone.`);
3013
- if (!confirmed)
3014
- return;
3015
- void handleEmptyDeletedTasks();
3016
- }, clearFilters: () => {
3017
- clearFilters();
3018
- setSelectedPlanningInitiativeId('');
3019
- setSelectedPlanningWorkstreamId('');
3020
- } }));
3021
- case 'document-filters':
3022
- return (_jsx(DocumentFilterToolbar, { typeFilters: documentTypeFilters, setTypeFilters: setDocumentTypeFilters, attachmentFilters: documentAttachmentFilters, setAttachmentFilters: setDocumentAttachmentFilters, clearFilters: () => {
3023
- setDocumentTypeFilters(DOCUMENT_TYPE_FILTER_OPTIONS.map((option) => option.value));
3024
- setDocumentAttachmentFilters(DOCUMENT_ATTACHMENT_FILTER_OPTIONS.map((option) => option.value));
3025
- } }));
3026
- case 'empty':
3027
- default:
3028
- return _jsx(EmptyWorkspaceFilterBar, {});
3925
+ const taskFilterActions = useMemo(() => {
3926
+ if (workspaceChromeDefinition.moduleId !== 'tasks')
3927
+ return [];
3928
+ return [
3929
+ {
3930
+ key: 'filter-toggle',
3931
+ icon: _jsx(Filter, { size: 16 }),
3932
+ title: t('standalone.toggleFilters'),
3933
+ onClick: () => setShowFilters(!showFilters),
3934
+ active: showFilters,
3935
+ ariaExpanded: showFilters,
3936
+ ariaControls: 'task-workspace-filters',
3937
+ className: hasActiveWorkspaceFilterControls ? styles.filterGlow : '',
3938
+ },
3939
+ ];
3940
+ }, [
3941
+ hasActiveWorkspaceFilterControls,
3942
+ setShowFilters,
3943
+ showFilters,
3944
+ workspaceChromeDefinition.moduleId,
3945
+ ]);
3946
+ const universalAgentActions = useMemo(() => {
3947
+ const actions = [];
3948
+ if (taskforceAgentsWorkspaceEnabled) {
3949
+ actions.push({
3950
+ key: 'ask-agent',
3951
+ icon: _jsx(Bot, { size: 16 }),
3952
+ title: taskforceAgentDrawerOpen ? 'Close Taskforce Agent' : 'Ask Taskforce Agent',
3953
+ onClick: taskforceAgentDrawerOpen ? handleCloseTaskforceAgentDrawer : handleOpenTaskforceAgentDrawer,
3954
+ active: taskforceAgentDrawerOpen,
3955
+ });
3029
3956
  }
3957
+ return actions;
3958
+ }, [
3959
+ handleCloseTaskforceAgentDrawer,
3960
+ handleOpenTaskforceAgentDrawer,
3961
+ taskforceAgentDrawerOpen,
3962
+ taskforceAgentsWorkspaceEnabled,
3963
+ ]);
3964
+ const taskFilterBar = useMemo(() => {
3965
+ return (_jsx(FilterToolbar, { id: "task-workspace-filters", categoryFilterOptions: categoryFilterOptions, typeFilterOptions: typeFilterOptions, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, filterCategories: filterCategories, setFilterCategories: setFilterCategories, filterTypes: filterTypes, setFilterTypes: setFilterTypes, filterPriorities: filterPriorities, setFilterPriorities: setFilterPriorities, filterStatus: filterStatus, setFilterStatus: setFilterStatus, filterAssignees: filterAssignees, setFilterAssignees: setFilterAssignees, assigneeOptions: assigneeOptions, initiativeFilterOptions: initiativeFilterOptions, selectedInitiativeId: selectedPlanningInitiativeId, setSelectedInitiativeId: handleInitiativeFilterChange, workstreamFilterOptions: workstreamFilterOptions, selectedWorkstreamId: selectedPlanningWorkstreamId, setSelectedWorkstreamId: handleWorkstreamFilterChange, taskScope: taskScope, setTaskScope: setTaskScope, showArchive: showArchive, setShowArchive: setShowArchive, clearFiltersDisabled: !hasSearchFilter
3966
+ && !hasDropdownFilters
3967
+ && sortBy === 'created'
3968
+ && props.sortOrder === 'desc', clearFilters: () => {
3969
+ clearFilters();
3970
+ clearTaskHeaderQuickFilter();
3971
+ setSelectedPlanningInitiativeId('');
3972
+ setSelectedPlanningWorkstreamId('');
3973
+ } }));
3030
3974
  }, [
3031
3975
  assigneeOptions,
3032
3976
  categoryFilterOptions,
3033
3977
  clearFilters,
3034
- deletedScopeAllTasks.length,
3035
- documentAttachmentFilters,
3036
- documentTypeFilters,
3037
3978
  filterAssignees,
3038
3979
  filterCategories,
3039
3980
  filterPriorities,
3040
3981
  filterStatus,
3041
3982
  filterTypes,
3983
+ hasDropdownFilters,
3984
+ hasSearchFilter,
3042
3985
  handleInitiativeFilterChange,
3043
3986
  handleWorkstreamFilterChange,
3044
3987
  initiativeFilterOptions,
3045
3988
  priorities,
3989
+ props.sortOrder,
3046
3990
  selectedPlanningInitiativeId,
3047
3991
  selectedPlanningWorkstreamId,
3048
- setDocumentAttachmentFilters,
3049
- setDocumentTypeFilters,
3050
3992
  setFilterAssignees,
3051
3993
  setFilterCategories,
3052
3994
  setFilterPriorities,
@@ -3056,14 +3998,13 @@ export function StandaloneLayout(props) {
3056
3998
  setSelectedPlanningWorkstreamId,
3057
3999
  setShowArchive,
3058
4000
  setTaskScope,
4001
+ sortBy,
4002
+ clearTaskHeaderQuickFilter,
3059
4003
  showArchive,
3060
4004
  taskScope,
3061
4005
  taxonomyDisplayLabels,
3062
4006
  typeFilterOptions,
3063
4007
  workstreamFilterOptions,
3064
- workspaceChromeDefinition.filterBar.kind,
3065
- fetchArchive,
3066
- handleEmptyDeletedTasks,
3067
4008
  ]);
3068
4009
  const universalDisplayActions = useMemo(() => {
3069
4010
  const actions = [{
@@ -3075,8 +4016,8 @@ export function StandaloneLayout(props) {
3075
4016
  }];
3076
4017
  return actions;
3077
4018
  }, [
3078
- zenMode,
3079
4019
  setZenMode,
4020
+ zenMode,
3080
4021
  ]);
3081
4022
  const headerSectionRegistry = useMemo(() => ({
3082
4023
  search: (_jsx(WorkspaceHeaderSearch, { value: searchQuery, placeholder: t('standalone.searchPlaceholder'), active: hasSearchFilter, onChange: setSearchQuery, onClear: () => setSearchQuery(''), clearTitle: t('standalone.clearSearchTitle') })),
@@ -3105,52 +4046,210 @@ export function StandaloneLayout(props) {
3105
4046
  'add-document': null,
3106
4047
  }), [openAddTaskModal]);
3107
4048
  const workspaceToolRail = useMemo(() => {
4049
+ const workspaceToolButtonClass = `${shellStyles.workspaceToolButton} tf-control-icon tf-control-icon-quiet`;
4050
+ const workspaceToolButtonActiveClass = `${workspaceToolButtonClass} tf-control-icon-active`;
3108
4051
  const moduleIcons = {
3109
4052
  tasks: _jsx(ClipboardCheck, { size: 18 }),
4053
+ planning: _jsx(Layers, { size: 18 }),
3110
4054
  docs: _jsx(FileText, { size: 18 }),
3111
4055
  annotate: _jsx(Image, { size: 18 }),
3112
- workflows: _jsx(Workflow, { size: 18 }),
3113
- agents: _jsx(Bot, { size: 18 }),
4056
+ workflowManager: _jsx(Workflow, { size: 18 }),
4057
+ taskforceAgents: _jsx(Bot, { size: 18 }),
4058
+ aiProfiles: _jsx(Users, { size: 18 }),
3114
4059
  };
3115
- const trayButtonDisabledClass = shellStyles.workspaceToolButtonDisabled || '';
3116
4060
  const workspaceTrayButton = (() => {
4061
+ if (resolvedWorkspaceModule === 'planning') {
4062
+ return _jsx("span", { className: shellStyles.workspaceToolButton, "aria-hidden": "true" });
4063
+ }
3117
4064
  if (resolvedWorkspaceModule === 'docs') {
3118
- return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${documentTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleDocumentTrayToggle, title: documentTrayOpen ? 'Collapse document tray' : 'Document tray', "aria-label": documentTrayOpen ? 'Collapse document tray' : 'Document tray', children: documentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
4065
+ return (_jsx("button", { type: "button", className: documentTrayOpen ? workspaceToolButtonActiveClass : workspaceToolButtonClass, onClick: handleDocumentTrayToggle, title: documentTrayOpen ? 'Collapse document tray' : 'Document tray', "aria-label": documentTrayOpen ? 'Collapse document tray' : 'Document tray', children: documentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
3119
4066
  }
3120
4067
  if (resolvedWorkspaceModule === 'annotate') {
3121
- return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${imageTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleImageTrayToggle, title: imageTrayOpen ? 'Collapse image tray' : 'Image tray', "aria-label": imageTrayOpen ? 'Collapse image tray' : 'Image tray', children: imageTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
4068
+ return (_jsx("button", { type: "button", className: imageTrayOpen ? workspaceToolButtonActiveClass : workspaceToolButtonClass, onClick: handleImageTrayToggle, title: imageTrayOpen ? 'Collapse image tray' : 'Image tray', "aria-label": imageTrayOpen ? 'Collapse image tray' : 'Image tray', children: imageTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Folder, { size: 18 }) }));
3122
4069
  }
3123
- if (resolvedWorkspaceModule === 'agents') {
3124
- return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${agentTrayOpen ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handleAgentTrayToggle, title: agentTrayOpen ? 'Collapse agent tray' : 'MCP settings tray', "aria-label": agentTrayOpen ? 'Collapse agent tray' : 'MCP settings tray', children: agentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Plug, { size: 18 }) }));
4070
+ if (resolvedWorkspaceModule === 'aiProfiles') {
4071
+ return (_jsx("button", { type: "button", className: agentTrayOpen ? workspaceToolButtonActiveClass : workspaceToolButtonClass, onClick: handleAgentTrayToggle, title: agentTrayOpen ? 'Collapse AI Profile tray' : 'MCP settings tray', "aria-label": agentTrayOpen ? 'Collapse AI Profile tray' : 'MCP settings tray', children: agentTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Plug, { size: 18 }) }));
3125
4072
  }
3126
- if (resolvedWorkspaceModule === 'workflows') {
3127
- return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${trayButtonDisabledClass}`.trim(), title: "Workflow tray coming soon", "aria-label": "Workflow tray coming soon", disabled: true, children: _jsx(Workflow, { size: 18 }) }));
4073
+ if (resolvedWorkspaceModule === 'taskforceAgents') {
4074
+ return (_jsx("button", { type: "button", className: taskforceAgentRosterTrayOpen ? workspaceToolButtonActiveClass : workspaceToolButtonClass, onClick: handleTaskforceAgentRosterTrayToggle, title: taskforceAgentRosterTrayOpen ? 'Collapse builder library' : 'Builder library', "aria-label": taskforceAgentRosterTrayOpen ? 'Collapse builder library' : 'Builder library', children: taskforceAgentRosterTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Users, { size: 18 }) }));
3128
4075
  }
3129
- return (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${(resolvedWorkspaceModule === 'tasks' && planningDrawerOpen) ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: handlePlanningToolToggle, title: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', "aria-label": resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', children: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(NotebookTabs, { size: 18 }) }));
4076
+ if (resolvedWorkspaceModule === 'workflowManager') {
4077
+ return (_jsx("button", { type: "button", className: workflowLibraryTrayOpen ? workspaceToolButtonActiveClass : workspaceToolButtonClass, onClick: handleWorkflowLibraryTrayToggle, title: workflowLibraryTrayOpen ? 'Collapse workflow library' : 'Workflow library', "aria-label": workflowLibraryTrayOpen ? 'Collapse workflow library' : 'Workflow library', children: workflowLibraryTrayOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(Workflow, { size: 18 }) }));
4078
+ }
4079
+ return (_jsx("button", { ref: planningDrawerLauncherRef, type: "button", className: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen
4080
+ ? workspaceToolButtonActiveClass
4081
+ : workspaceToolButtonClass, onClick: handlePlanningToolToggle, title: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', "aria-label": resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? 'Collapse planning trays' : 'Planning', children: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen ? _jsx(ChevronLeft, { size: 18 }) : _jsx(NotebookTabs, { size: 18 }) }));
3130
4082
  })();
3131
- return (_jsxs("aside", { className: shellStyles.workspaceToolRail, "aria-label": "Workspace tools", children: [_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [workspaceTrayButton, _jsx("div", { className: shellStyles.workspaceToolRailDivider }), workspaceToolModules.map((module) => (_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${resolvedWorkspaceModule === module.id ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => handleModuleChange(module.id), title: module.label, "aria-label": module.label, children: moduleIcons[module.id] }, module.id)))] }), _jsxs("div", { className: shellStyles.workspaceToolRailBottom, children: [_jsx("div", { className: shellStyles.workspaceToolRailDivider }), _jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} ${activeTab === 'settings' ? shellStyles.workspaceToolButtonActive : ''}`.trim(), onClick: () => {
4083
+ return (_jsxs("aside", { className: `${shellStyles.workspaceToolRail} ${shellStyles.workspaceToolRailLeft}`, "aria-label": "Workspace tools", children: [_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [workspaceTrayButton && (_jsxs(_Fragment, { children: [workspaceTrayButton, _jsx("div", { className: shellStyles.workspaceToolRailDivider })] })), workspaceToolModules.map((module) => (_jsx("button", { type: "button", className: resolvedWorkspaceModule === module.id
4084
+ ? workspaceToolButtonActiveClass
4085
+ : workspaceToolButtonClass, onClick: () => handleModuleChange(module.id), title: module.label, "aria-label": module.label, children: moduleIcons[module.id] }, module.id)))] }), _jsxs("div", { className: shellStyles.workspaceToolRailBottom, children: [_jsx("div", { className: shellStyles.workspaceToolRailDivider }), _jsx("button", { type: "button", className: activeTab === 'settings'
4086
+ ? workspaceToolButtonActiveClass
4087
+ : workspaceToolButtonClass, onClick: () => {
4088
+ if (resolvedWorkspaceModule === 'workflowManager' && workflowManagerHasUnsavedChanges && !workflowDiscardBypassRef.current) {
4089
+ setPendingWorkflowDiscardAction(() => () => {
4090
+ setSettingsSection('general');
4091
+ setActiveTab('settings');
4092
+ });
4093
+ return;
4094
+ }
3132
4095
  setSettingsSection('general');
3133
4096
  setActiveTab('settings');
3134
4097
  }, title: "Workspace Settings", "aria-label": "Workspace Settings", children: _jsx(Settings, { size: 18 }) })] })] }));
3135
- }, [activeTab, agentTrayOpen, documentTrayOpen, handleAgentTrayToggle, handleDocumentTrayToggle, handleImageTrayToggle, handleModuleChange, handlePlanningToolToggle, imageTrayOpen, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, workspaceToolModules]);
4098
+ }, [activeTab, agentTrayOpen, documentTrayOpen, handleAgentTrayToggle, handleDocumentTrayToggle, handleImageTrayToggle, handleModuleChange, handlePlanningToolToggle, handleTaskforceAgentRosterTrayToggle, handleWorkflowLibraryTrayToggle, imageTrayOpen, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, taskforceAgentRosterTrayOpen, workflowLibraryTrayOpen, workflowManagerHasUnsavedChanges, workspaceToolModules]);
3136
4099
  const [planningDrawerPortalElement, setPlanningDrawerPortalElement] = useState(null);
3137
4100
  const setPlanningDrawerPortalRef = useCallback((node) => {
3138
4101
  setPlanningDrawerPortalElement(node);
3139
4102
  }, []);
3140
- const planningDrawerNode = (_jsx(PlanningDrawer, { open: planningDrawerOpen, leftOffset: WORKSPACE_TOOL_RAIL_WIDTH, initiatives: planningStructure.initiatives, standaloneWorkstreams: planningStructure.standaloneWorkstreams, allStandaloneWorkstreams: planningStructure.allStandaloneWorkstreams, activeInitiativeId: selectedPlanningInitiativeId, activeWorkstreamId: selectedPlanningWorkstreamId, expandedInitiativeIds: expandedPlanningInitiativeIds, detail: planningDrawerItem, editor: planningEditor, secondaryPane: planningSecondaryPane, currentWorkspaceId: currentWorkspaceId, assigneeOptions: assigneeOptions.map((option) => ({
4103
+ const hydratePlanningWorkspaceEntity = useCallback((entityType, entityId) => hydratePlanningEntity({ type: entityType, id: entityId }), [hydratePlanningEntity]);
4104
+ const createPlanningWorkspaceEntity = useCallback(async (entityType, input) => {
4105
+ const title = input.title.trim();
4106
+ if (!title)
4107
+ throw new Error(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} title is required.`);
4108
+ try {
4109
+ if (entityType === 'initiative') {
4110
+ const created = await props.createInitiative({
4111
+ title,
4112
+ description: input.description?.trim() || null,
4113
+ ownerId: input.ownerId?.trim() || null,
4114
+ ...(input.icon || input.color ? { icon: input.icon ?? null, color: input.color ?? null } : {}),
4115
+ });
4116
+ pushNotice('Initiative created', 'success');
4117
+ return { id: created.id };
4118
+ }
4119
+ const created = await props.createWorkstream({
4120
+ title,
4121
+ description: input.description?.trim() || null,
4122
+ ownerId: input.ownerId?.trim() || null,
4123
+ initiativeId: input.initiativeId?.trim() || null,
4124
+ ...(input.icon || input.color ? { icon: input.icon ?? null, color: input.color ?? null } : {}),
4125
+ });
4126
+ pushNotice('Workstream created', 'success');
4127
+ return { id: created.id };
4128
+ }
4129
+ catch (error) {
4130
+ pushNotice(error instanceof Error ? error.message : 'Failed to create planning item.', 'error');
4131
+ throw error;
4132
+ }
4133
+ }, [props.createInitiative, props.createWorkstream, pushNotice]);
4134
+ const updatePlanningWorkspaceEntity = useCallback(async (entityType, entityId, input) => {
4135
+ const title = input.title.trim();
4136
+ if (!title)
4137
+ throw new Error(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} title is required.`);
4138
+ try {
4139
+ const patch = { title, description: input.description?.trim() || null };
4140
+ if (entityType === 'initiative') {
4141
+ await props.updateInitiative(entityId, patch);
4142
+ pushNotice('Initiative updated', 'success');
4143
+ return;
4144
+ }
4145
+ await props.updateWorkstream(entityId, patch);
4146
+ pushNotice('Workstream updated', 'success');
4147
+ }
4148
+ catch (error) {
4149
+ pushNotice(error instanceof Error ? error.message : 'Failed to update planning item.', 'error');
4150
+ throw error;
4151
+ }
4152
+ }, [props.updateInitiative, props.updateWorkstream, pushNotice]);
4153
+ const reorderPlanningWorkstreamTasks = useCallback(async (workstreamId, taskIds) => {
4154
+ try {
4155
+ await props.reorderWorkstreamTasks(workstreamId, taskIds);
4156
+ }
4157
+ catch (error) {
4158
+ pushNotice(error instanceof Error ? error.message : 'Failed to reorder workstream tasks.', 'error');
4159
+ throw error;
4160
+ }
4161
+ }, [props.reorderWorkstreamTasks, pushNotice]);
4162
+ const planningWorkspaceModel = useMemo(() => ({
4163
+ initiatives: planningStructure.allInitiatives,
4164
+ standaloneWorkstreams: planningStructure.allStandaloneWorkstreams,
4165
+ assigneeOptions,
4166
+ currentOwnerId: normalizedAuthUserId === 'anonymous' ? null : normalizedAuthUserId,
4167
+ currentWorkspaceId,
4168
+ theme: currentTheme,
4169
+ taskReferences,
4170
+ loadState: props.planningLoadState,
4171
+ hydrationStateByEntity: planningHydrationStateByEntity,
4172
+ hydrateEntity: hydratePlanningWorkspaceEntity,
4173
+ retry: () => { void props.fetchPlanningEntities(); },
4174
+ openTask: handleOpenTaskById,
4175
+ setTaskStatus: handleSetPlanningTaskStatus,
4176
+ setTaskAssignee: handleChangePlanningTaskAssignee,
4177
+ linkOptions: planningLinkOptions,
4178
+ assignWorkstreamToInitiative: handleAssignInitiativeToWorkstream,
4179
+ assignTaskToWorkstream: handleAssignTaskToWorkstream,
4180
+ attachWorkstreamToInitiative: handleAttachWorkstreamToInitiativeByReference,
4181
+ attachTaskToWorkstream: handleAttachTaskToWorkstreamByReference,
4182
+ archiveEntity: handleArchivePlanningEntity,
4183
+ unarchiveEntity: handleUnarchivePlanningEntity,
4184
+ changeOwner: handleChangePlanningOwner,
4185
+ changeIdentity: handleChangePlanningIdentity,
4186
+ createEntity: createPlanningWorkspaceEntity,
4187
+ updateEntity: updatePlanningWorkspaceEntity,
4188
+ addContextFile: handleAddPlanningContextFile,
4189
+ removeContextFile: handleRemovePlanningContextFile,
4190
+ updateContextCaption: handleUpdatePlanningContextCaption,
4191
+ showTaskCardStatusLabel,
4192
+ taskArrangeMode: planningTaskArrangeMode,
4193
+ setTaskArrangeMode: setPlanningTaskArrangeMode,
4194
+ reorderWorkstreamTasks: reorderPlanningWorkstreamTasks,
4195
+ }), [
4196
+ currentWorkspaceId,
4197
+ currentTheme,
4198
+ handleChangePlanningOwner,
4199
+ handleChangePlanningIdentity,
4200
+ handleAssignInitiativeToWorkstream,
4201
+ handleAssignTaskToWorkstream,
4202
+ handleAttachTaskToWorkstreamByReference,
4203
+ handleAttachWorkstreamToInitiativeByReference,
4204
+ handleArchivePlanningEntity,
4205
+ handleUnarchivePlanningEntity,
4206
+ createPlanningWorkspaceEntity,
4207
+ handleAddPlanningContextFile,
4208
+ handleOpenTaskById,
4209
+ handleRemovePlanningContextFile,
4210
+ handleSetPlanningTaskStatus,
4211
+ handleChangePlanningTaskAssignee,
4212
+ handleUpdatePlanningContextCaption,
4213
+ hydratePlanningWorkspaceEntity,
4214
+ assigneeOptions,
4215
+ normalizedAuthUserId,
4216
+ planningStructure.allInitiatives,
4217
+ planningStructure.allStandaloneWorkstreams,
4218
+ planningLinkOptions,
4219
+ planningHydrationStateByEntity,
4220
+ props.fetchPlanningEntities,
4221
+ props.planningLoadState,
4222
+ showTaskCardStatusLabel,
4223
+ planningTaskArrangeMode,
4224
+ reorderPlanningWorkstreamTasks,
4225
+ taskReferences,
4226
+ updatePlanningWorkspaceEntity,
4227
+ ]);
4228
+ const planningDrawerNode = (_jsx(PlanningDrawer, { open: planningDrawerOpen, leftOffset: WORKSPACE_TOOL_RAIL_WIDTH, returnFocusRef: planningDrawerLauncherRef, theme: currentTheme, initiatives: planningWorkspaceModel.initiatives, standaloneWorkstreams: planningWorkspaceModel.standaloneWorkstreams, planningLoadState: planningWorkspaceModel.loadState, onRetryPlanning: planningWorkspaceModel.retry, taskScope: taskScope, activeInitiativeId: selectedPlanningInitiativeId, activeWorkstreamId: selectedPlanningWorkstreamId, navigatorSort: planningNavigatorSort, navigatorSortReady: layoutUiStateReady, onNavigatorSortChange: setPlanningNavigatorSort, taskArrangeMode: planningTaskArrangeMode, onTaskArrangeModeChange: setPlanningTaskArrangeMode, onReorderWorkstreamTasks: reorderPlanningWorkstreamTasks, planningFavorites: layoutUiStateReady ? planningFavorites : [], onTogglePlanningFavorite: (favorite) => {
4229
+ setPlanningFavorites((current) => togglePlanningFavorite(current, favorite));
4230
+ }, favoritesSectionCollapsed: planningFavoritesSectionCollapsed, initiativesSectionCollapsed: planningInitiativesSectionCollapsed, workstreamsSectionCollapsed: planningWorkstreamsSectionCollapsed, onToggleFavoritesSection: () => setPlanningFavoritesSectionCollapsed((current) => !current), onToggleInitiativesSection: () => setPlanningInitiativesSectionCollapsed((current) => !current), onToggleWorkstreamsSection: () => setPlanningWorkstreamsSectionCollapsed((current) => !current), expandedInitiativeIds: expandedPlanningInitiativeIds, detail: planningDrawerItem, editor: planningEditor, secondaryEditor: planningSecondaryEditor, secondaryPane: planningSecondaryPane, primaryHydrationState: primaryPlanningHydrationState, secondaryHydrationState: secondaryPlanningHydrationState, onRetryPrimaryHydration: planningDrawerDetail
4231
+ ? () => { void hydratePlanningEntity(planningDrawerDetail); }
4232
+ : undefined, onRetrySecondaryHydration: planningNestedWorkstreamDetailId
4233
+ ? () => { void hydratePlanningEntity({ type: 'workstream', id: planningNestedWorkstreamDetailId }); }
4234
+ : undefined, onWidthChange: setPlanningDrawerWidthPx, currentWorkspaceId: currentWorkspaceId, currentOwnerId: normalizedAuthUserId === 'anonymous' ? '' : normalizedAuthUserId, linkOptions: planningLinkOptions, showTaskCardStatusLabel: showTaskCardStatusLabel, assigneeOptions: assigneeOptions.map((option) => ({
3141
4235
  value: String(option.value),
3142
4236
  label: option.label,
4237
+ icon: option.icon,
4238
+ color: option.color,
3143
4239
  kind: option.kind,
4240
+ avatarUrl: option.avatarUrl ?? null,
4241
+ avatarRevision: option.avatarRevision ?? null,
4242
+ avatarUpdatedAt: option.avatarUpdatedAt ?? null,
3144
4243
  username: option.username ?? null,
4244
+ surfaceType: option.surfaceType ?? null,
4245
+ providerMetadata: option.providerMetadata ?? null,
3145
4246
  archivedAt: option.archivedAt ?? null
3146
- })), draftInitiativeSummary: planningDraftInitiativeSummary, draftTitle: planningDraftTitle, draftDescription: planningDraftDescription, draftOwner: planningDraftOwner, draftInitiativeId: planningDraftInitiativeId, onChangeDraftTitle: setPlanningDraftTitle, onChangeDraftDescription: setPlanningDraftDescription, onChangeDraftOwner: setPlanningDraftOwner, onChangeDraftInitiativeId: setPlanningDraftInitiativeId, onCollapseTreePane: () => setPlanningTreeCollapsed(true), onExpandTreePane: () => setPlanningTreeCollapsed(false), onCollapsePrimaryPane: () => setPlanningPrimaryCollapsed(true), onExpandPrimaryPane: () => setPlanningPrimaryCollapsed(false), onCollapseSecondaryPane: () => setPlanningSecondaryCollapsed(true), onExpandSecondaryPane: () => setPlanningSecondaryCollapsed(false), onBackFromSecondary: () => {
4247
+ })), draftInitiativeSummary: planningDraftInitiativeSummary, draftTitle: planningDraftTitle, draftDescription: planningDraftDescription, draftOwner: planningDraftOwner, draftInitiativeId: planningDraftInitiativeId, draftIcon: planningDraftIcon, draftColor: planningDraftColor, onChangeDraftTitle: setPlanningDraftTitle, onChangeDraftDescription: setPlanningDraftDescription, onChangeDraftOwner: setPlanningDraftOwner, onChangeDraftInitiativeId: setPlanningDraftInitiativeId, onChangeDraftIcon: setPlanningDraftIcon, onChangeDraftColor: setPlanningDraftColor, onCollapseTreePane: () => setPlanningTreeCollapsed(true), onExpandTreePane: () => setPlanningTreeCollapsed(false), onCollapsePrimaryPane: () => setPlanningPrimaryCollapsed(true), onExpandPrimaryPane: () => setPlanningPrimaryCollapsed(false), onCollapseSecondaryPane: () => setPlanningSecondaryCollapsed(true), onExpandSecondaryPane: () => setPlanningSecondaryCollapsed(false), onBackFromSecondary: () => {
3147
4248
  planningEditorSubmitInFlightRef.current = false;
3148
4249
  setIsSubmittingPlanningEditor(false);
3149
4250
  setPlanningSecondaryEditor(null);
3150
4251
  setPlanningNestedWorkstreamDetailId(null);
3151
- }, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: handleOpenTaskById, onRemoveTaskFromWorkstream: (taskId) => {
3152
- void handleAssignTaskToWorkstream(taskId, null);
3153
- }, onAttachTaskToWorkstreamByReference: handleAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference: handleAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile: handleAddPlanningContextFile, onRemovePlanningContextFile: handleRemovePlanningContextFile, onUpdatePlanningContextCaption: handleUpdatePlanningContextCaption, onToggleInitiative: togglePlanningInitiative, onSelectInitiative: selectPlanningInitiative, onSelectWorkstream: selectPlanningWorkstream, onOpenInitiativeDetails: openInitiativeDetails, onOpenWorkstreamDetails: openWorkstreamDetails, onOpenNestedWorkstreamDetails: openNestedWorkstreamDetails, onEditInitiative: (initiativeId) => openPlanningEditDialog('initiative', initiativeId), onEditWorkstream: (workstreamId) => openPlanningEditDialog('workstream', workstreamId), onArchiveInitiative: (initiativeId) => {
4252
+ }, treeCollapsed: planningTreeCollapsed, primaryCollapsed: planningPrimaryCollapsed, secondaryCollapsed: planningSecondaryCollapsed, onCancelEditor: closePlanningEditor, onCancelSecondaryEditor: closePlanningSecondaryEditor, onSubmitEditor: submitPlanningEditor, isSubmittingEditor: isSubmittingPlanningEditor, onCreateInitiative: () => openPlanningCreateEditor('initiative'), onCreateWorkstream: () => openPlanningCreateEditor('workstream'), onCreateTaskInWorkstream: openAddTaskModalForWorkstream, onCreateWorkstreamInInitiative: (initiativeId) => openPlanningCreateEditor('workstream', initiativeId), onAssignInitiativeToWorkstream: handleAssignInitiativeToWorkstream, onOpenTaskById: planningWorkspaceModel.openTask, onSetTaskStatus: handleSetPlanningTaskStatus, onChangeTaskAssignee: handleChangePlanningTaskAssignee, onArchivePlanningTask: handleArchivePlanningTask, onArchiveResolvedWorkstream: handleArchiveResolvedWorkstream, onArchiveResolvedInitiative: handleArchiveResolvedInitiative, taskReferences: taskReferences, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, onAttachTaskToWorkstreamByReference: handleAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference: handleAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile: handleAddPlanningContextFile, onRemovePlanningContextFile: handleRemovePlanningContextFile, onUpdatePlanningContextCaption: handleUpdatePlanningContextCaption, onToggleInitiative: togglePlanningInitiative, onSelectInitiative: selectPlanningInitiative, onSelectWorkstream: selectPlanningWorkstream, onOpenInitiativeDetails: openInitiativeDetails, onOpenWorkstreamDetails: openWorkstreamDetails, onOpenNestedWorkstreamDetails: openNestedWorkstreamDetails, onEditInitiative: (initiativeId) => openPlanningEditDialog('initiative', initiativeId), onEditWorkstream: (workstreamId) => openPlanningEditDialog('workstream', workstreamId), onChangePlanningOwner: handleChangePlanningOwner, onChangePlanningIdentity: handleChangePlanningIdentity, onArchiveInitiative: (initiativeId) => {
3154
4253
  void props.archiveInitiative(initiativeId).then(() => {
3155
4254
  pushNotice('Initiative archived', 'success');
3156
4255
  }).catch((error) => {
@@ -3185,123 +4284,125 @@ export function StandaloneLayout(props) {
3185
4284
  const workspacePrimaryAction = workspaceChromeDefinition.primaryAction
3186
4285
  ? primaryActionRegistry[workspaceChromeDefinition.primaryAction]
3187
4286
  : null;
3188
- return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, onBrandClick: handleOpenKanbanFromBrand, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("span", { className: styles.taskCountBadge, title: "Tasks assigned to me", children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("span", { className: `${styles.taskCountBadge} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''}`.trim(), title: "Tasks overdue", children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${syncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
3189
- marginLeft: '6px',
3190
- height: '24px',
3191
- width: '24px',
3192
- padding: 0,
3193
- borderRadius: '999px',
3194
- border: `1px solid ${syncStatusMeta.border}`,
3195
- background: syncStatusMeta.background,
3196
- color: syncStatusMeta.color,
3197
- display: 'inline-flex',
3198
- alignItems: 'center',
3199
- justifyContent: 'center'
3200
- }, children: syncStatusMeta.icon === 'off' ? (_jsx(CloudOff, { size: 16 })) : (_jsx(Cloud, { size: 16 })) }))] })), actions: (_jsxs(_Fragment, { children: [isPlansScreen && (_jsxs(_Fragment, { children: [isAuthenticated && accountProfileSummary?.stripeCustomerId && (_jsx("button", { className: "tf-control-icon", onClick: () => { void handleOpenBillingPortal(); }, title: "Manage billing", disabled: billingActionBusy, children: "Manage billing" })), _jsx("button", { className: "tf-control-icon", onClick: () => {
3201
- if (hasActiveCommercialEntitlement) {
3202
- void handlePlansBack();
3203
- return;
3204
- }
3205
- closePlansScreen();
3206
- }, title: hasActiveCommercialEntitlement ? 'Continue to Taskforce' : 'Back', disabled: plansNavigationBusy, children: hasActiveCommercialEntitlement ? 'Take Me to Taskforce' : 'Back' })] })), !isPlansScreen && (_jsxs(_Fragment, { children: [workspaceHeaderSections, workspacePrimaryAction] })), _jsx(WorkspaceHeaderActions, { actions: universalDisplayActions }), !isPlansScreen && _jsx(WorkspaceHeaderActions, { actions: universalFilterActions }), accountMenuControl] })) }), _jsx(TopNoticeLayer, { notice: uiNotice, onDismiss: clearNotice }), authBlocked && (_jsx("div", { className: authStyles.authBlockedBanner, children: "Authentication required for this environment. Use the Account menu to sign in." })), !isPlansScreen && showFilters && workspaceFilterBar, isPlansScreen ? (_jsx("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} ${styles.appScrollbar} tf-scrollbar`, style: {
3207
- position: 'relative',
3208
- display: 'flex',
3209
- flex: 1,
3210
- minHeight: 0,
3211
- overflowY: 'auto',
3212
- overflowX: 'hidden',
3213
- scrollbarGutter: 'stable',
3214
- background: 'var(--surface-page)'
3215
- }, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { tasks: tasks, runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, documentTrayOpen: documentTrayOpen, onCloseDocumentTray: () => setDocumentTrayOpen(false), requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
3216
- setRequestedDocPath(null);
3217
- setRequestedDocAssetId(null);
3218
- }, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: requestedAnnotatedTarget, requestedSessionId: requestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflows' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowsModule, { availableWorkflows: availableWorkflows, availableEnvironments: availableEnvironments, exportEnvironment: exportEnvironment, exportWorkflowsPath: props.exportWorkflowsPath, exportingResource: exportingResource, exportResult: exportResult, onExportEnvironmentChange: props.setExportEnvironment, onExportWorkflows: onExportWorkflows, onRefreshWorkflows: fetchWorkflows, onFetchWorkflowTemplate: props.fetchWorkflowTemplate, onFetchWorkflowOverrideNames: props.fetchWorkflowOverrideNames, onSaveWorkflowTemplateDraft: props.saveWorkflowTemplateDraft, onResetWorkflowTemplateDraft: props.resetWorkflowTemplateDraft }) })] })) : resolvedWorkspaceModule === 'agents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AgentsModule, { workspaceId: currentWorkspaceId, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
3219
- ...settingsModel,
3220
- initialSection: 'mcp',
3221
- onOpenCloudAuth: openSharedLoginRoute
3222
- }, renderMode: "mcp-only" }) }) })] })) : (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} `, style: {
3223
- position: 'relative',
3224
- opacity: props.loadingTasks ? 0.7 : 1,
3225
- transition: 'opacity 0.2s ease, padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
3226
- display: 'flex',
3227
- flex: 1,
3228
- minHeight: 0,
3229
- paddingLeft: planningDrawerOpen
3230
- ? `${WORKSPACE_TOOL_RAIL_WIDTH + planningDrawerWidthPx + WORKSPACE_CONTENT_GUTTER}px`
3231
- : `${WORKSPACE_TOOL_RAIL_WIDTH + WORKSPACE_CONTENT_GUTTER}px`,
3232
- paddingRight: (groupBy === 'schedule' && scheduleSidebarOpen) ? `${SCHEDULE_SIDEBAR_WIDTH_PX}px` : 0
3233
- }, children: [workspaceToolRail, _jsx("div", { ref: setPlanningDrawerPortalRef, style: {
3234
- position: 'absolute',
3235
- inset: 0,
3236
- zIndex: 35,
3237
- pointerEvents: 'none',
3238
- } }), _jsxs("div", { style: { position: 'relative', width: '100%', minWidth: 0, flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }, children: [props.loadingTasks && boardVisibleTasks.length > 0 && (_jsx("div", { className: styles.boardRefreshIndicator, "aria-live": "polite", "aria-label": "Refreshing tasks", children: _jsx(Loader2, { size: 14, className: styles.spinner }) })), _jsx(TaskKanban, { tasks: scopedBoardVisibleTasks, allTasks: scopedKanbanAllTasks, columns: kanbanColumns, groupBy: groupBy, scheduleDates: scheduleDates, searchQuery: searchQuery, filterCategories: filterCategories, filterTypes: filterTypes, filterPriorities: filterPriorities, filterStatus: filterStatus, filterAssignees: filterAssignees, filtersReady: hasInitedFilters, assigneeOptions: assigneeOptions, scheduleFilteredTaskIds: Array.from(scheduleFilteredTaskIds), copiedId: copiedId, taxonomies: taxonomies, types: activeTypes, priorities: priorities, onUpdateTask: handleUpdateTask, onTaskClick: (task) => handleEdit(task), onOpenTaskById: handleOpenTaskById, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onAddTaskToColumn: handleAddTaskToColumn, showTaskCardStatusLabel: showTaskCardStatusLabel, onScheduleDaySelected: (dateOnly) => {
3239
- setScheduleSelectedDate(dateOnly);
3240
- const parsed = parseDateOnlyLocal(dateOnly);
3241
- if (parsed) {
3242
- setScheduleCalendarMonth(`${parsed.getFullYear()}-${String(parsed.getMonth() + 1).padStart(2, '0')}`);
3243
- }
3244
- }, persistedScrollLeft: groupBy === 'schedule' ? scheduleScrollLeft : undefined, onScrollLeftChange: (scrollLeft) => {
3245
- if (groupBy !== 'schedule')
3246
- return;
3247
- setScheduleScrollLeft(scrollLeft);
3248
- }, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalElement
3249
- ? createPortal(planningDrawerNode, planningDrawerPortalElement)
3250
- : null, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, onAssignWorkstreamToInitiative: handleAssignInitiativeToWorkstream, workstreams: props.workstreams, initiatives: props.initiatives, onUnarchive: (taskId) => {
3251
- if (taskScope === 'deleted') {
4287
+ const taskforceAgentDrawerNode = taskforceAgentDrawerOpen ? (_jsx("div", { className: `${styles.taskforceAgentDrawerOverlay} ${taskforceAgentPanelCollapsed ? styles.taskforceAgentDrawerOverlayCollapsed : ''}`.trim(), style: { top: `${taskforceAgentDrawerTop}px` }, "data-theme": currentTheme, "aria-label": "Taskforce Agent chat", children: _jsx("aside", { className: taskforceAgentPanelCollapsed
4288
+ ? `${shellStyles.workspaceToolRail} ${shellStyles.workspaceToolRailRight}`
4289
+ : styles.taskforceAgentDrawerPanel, children: taskforceAgentPanelCollapsed ? (_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} tf-control-icon tf-control-icon-quiet tf-control-icon-active`, onClick: () => setTaskforceAgentPanelCollapsed(false), title: "Expand agent chat", "aria-label": "Expand agent chat", children: _jsx(Bot, { size: 16 }) }), _jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} tf-control-icon tf-control-icon-quiet`, onClick: handleCloseTaskforceAgentDrawer, title: "Close agent chat", "aria-label": "Close agent chat", children: _jsx(X, { size: 16 }) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: styles.taskforceAgentDrawerHeader, children: [taskforceAgentDrawerHeaderContent || (_jsxs("div", { className: styles.taskforceAgentDrawerHeaderFallback, children: [_jsx("span", { className: styles.taskforceAgentDrawerFallbackAvatar, "aria-hidden": "true", children: _jsx(Bot, { size: 16 }) }), _jsx("strong", { children: "Loading agent..." })] })), _jsxs("div", { className: styles.taskforceAgentDrawerHeaderActions, children: [_jsx("button", { type: "button", className: "tf-control-icon", onClick: () => setTaskforceAgentPanelCollapsed(true), title: "Collapse agent chat", "aria-label": "Collapse agent chat", children: _jsx(ChevronRight, { size: 16 }) }), _jsx("button", { type: "button", className: "tf-control-icon", onClick: handleCloseTaskforceAgentDrawer, title: "Close agent chat", "aria-label": "Close agent chat", children: _jsx(X, { size: 16 }) })] })] }), _jsx(Suspense, { fallback: _jsx("div", { className: styles.taskforceAgentDrawerLoading, children: _jsx(Loader2, { size: 18, className: styles.spinner }) }), children: _jsx(TaskforceAgentsModule, { workspaceId: currentWorkspaceId, launchContext: taskforceAgentsLaunchContext, onClearLaunchContext: handleCloseTaskforceAgentDrawer, onOpenTaskContext: handleOpenTaskforceAgentTaskContext, taskReferences: taskReferences, surface: "taskDrawer", runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, rememberedAgentId: taskforceAgentId, rememberedConversationId: taskforceAgentConversationId, rememberedConversationByAgentId: taskforceAgentConversationByAgentId, rememberedSelectionReady: uiStateReady, onRememberSelection: handleRememberTaskforceAgentSelection, onRenderDrawerHeader: handleRenderTaskforceAgentDrawerHeader }) })] })) }) })) : null;
4290
+ return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx("div", { ref: appShellHeaderRef, style: { flexShrink: 0 }, children: _jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, onBrandClick: handleOpenKanbanFromBrand, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: `${styles.taskCountBadge} ${styles.taskCountBadgeButton} ${taskHeaderQuickFilter === 'assigned-to-me' ? styles.taskCountBadgeActive : ''}`.trim(), onClick: () => handleTaskHeaderQuickFilter('assigned-to-me'), title: taskHeaderQuickFilter === 'assigned-to-me' ? 'Clear assigned-to-me quick filter' : 'Filter to my open tasks', "aria-label": `${taskHeaderQuickFilter === 'assigned-to-me' ? 'Clear' : 'Apply'} assigned to me quick filter (${assignedTaskCount} task${assignedTaskCount === 1 ? '' : 's'})`, "aria-pressed": taskHeaderQuickFilter === 'assigned-to-me', children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("button", { type: "button", className: `${styles.taskCountBadge} ${styles.taskCountBadgeButton} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''} ${taskHeaderQuickFilter === 'overdue' ? styles.taskCountBadgeActive : ''}`.trim(), onClick: () => handleTaskHeaderQuickFilter('overdue'), title: taskHeaderQuickFilter === 'overdue' ? 'Clear my-overdue-tasks quick filter' : 'Filter to my overdue tasks', "aria-label": `${taskHeaderQuickFilter === 'overdue' ? 'Clear' : 'Apply'} my overdue tasks quick filter (${assignedOverdueTaskCount} task${assignedOverdueTaskCount === 1 ? '' : 's'})`, "aria-pressed": taskHeaderQuickFilter === 'overdue', children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${headerSyncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
4291
+ marginLeft: '6px',
4292
+ height: '24px',
4293
+ width: '24px',
4294
+ padding: 0,
4295
+ borderRadius: '999px',
4296
+ border: `1px solid ${headerSyncStatusMeta.border}`,
4297
+ background: headerSyncStatusMeta.background,
4298
+ color: headerSyncStatusMeta.color,
4299
+ display: 'inline-flex',
4300
+ alignItems: 'center',
4301
+ justifyContent: 'center'
4302
+ }, children: headerSyncStatusMeta.icon === 'off' ? (_jsx(CloudOff, { size: 16 })) : (_jsx(Cloud, { size: 16 })) }))] })), actions: (_jsxs(_Fragment, { children: [isPlansScreen && (_jsxs(_Fragment, { children: [isAuthenticated && accountProfileSummary?.stripeCustomerId && (_jsx("button", { className: "tf-control-icon", onClick: () => { void handleOpenBillingPortal(); }, title: "Manage billing", disabled: billingActionBusy, children: "Manage billing" })), _jsx("button", { className: "tf-control-icon", onClick: () => {
4303
+ if (hasActiveCommercialEntitlement) {
4304
+ void handlePlansBack();
4305
+ return;
4306
+ }
4307
+ closePlansScreen();
4308
+ }, title: hasActiveCommercialEntitlement ? 'Continue to Taskforce' : 'Back', disabled: plansNavigationBusy, children: hasActiveCommercialEntitlement ? 'Take Me to Taskforce' : 'Back' })] })), !isPlansScreen && (_jsxs(_Fragment, { children: [workspaceHeaderSections, _jsx(WorkspaceHeaderActions, { actions: taskFilterActions }), workspacePrimaryAction] })), _jsx(WorkspaceHeaderActions, { actions: universalDisplayActions }), !isPlansScreen && _jsx(WorkspaceHeaderActions, { actions: universalAgentActions }), accountMenuControl] })) }) }), _jsx(TopNoticeLayer, { notice: activeTab === 'add' ? null : uiNotice, onDismiss: clearNotice }), _jsx(AttachmentPreviewHost, { theme: currentTheme }), authBlocked && (_jsx("div", { className: authStyles.authBlockedBanner, children: "Authentication required for this environment. Use the Account menu to sign in." })), _jsx("div", { className: `${styles.taskforceAssistantWorkspace} ${taskforceAgentDrawerOpen ? styles.taskforceAssistantWorkspaceOpen : ''} ${taskforceAgentPanelCollapsed ? styles.taskforceAssistantWorkspaceCollapsed : ''}`.trim(), children: _jsx("div", { className: styles.taskforceAssistantWorkspaceContent, children: isPlansScreen ? (_jsx("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} ${styles.appScrollbar} tf-scrollbar`, style: {
4309
+ position: 'relative',
4310
+ display: 'flex',
4311
+ flex: 1,
4312
+ minHeight: 0,
4313
+ overflowY: 'auto',
4314
+ overflowX: 'hidden',
4315
+ scrollbarGutter: 'stable',
4316
+ background: 'var(--surface-page)'
4317
+ }, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'planning' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlanningModule, { model: planningWorkspaceModel }) })] })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { taskReferences: taskReferences, tasks: tasks, runtimeMode: runtimeMode, workspaceId: currentWorkspaceId, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, sortField: documentSortField, sortOrder: documentSortOrder, onSortFieldChange: setDocumentSortField, onSortOrderChange: setDocumentSortOrder, pinnedDocIds: documentPinnedDocIds, onPinnedDocIdsChange: setDocumentPinnedDocIds, searchQuery: documentSearchQuery, onSearchQueryChange: setDocumentSearchQuery, selectedDocId: documentSelectedDocId, onSelectedDocIdChange: setDocumentSelectedDocId, selectionReady: layoutUiStateReady, documentScrollByDocId: documentScrollByDocId, onDocumentScrollChange: handleDocumentScrollChange, documentListScrollTop: documentListScrollTop, onDocumentListScrollChange: handleDocumentListScrollChange, documentTrayOpen: documentTrayOpen, onCloseDocumentTray: () => setDocumentTrayOpen(false), requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
4318
+ setRequestedDocPath(null);
4319
+ setRequestedDocAssetId(null);
4320
+ }, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: scopedRequestedAnnotatedTarget, requestedSessionId: scopedRequestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, viewportByContextKey: annotatedViewportByContextKey, onViewportChange: handleAnnotatedViewportChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflowManager' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowManagerModule, { workspaceId: currentWorkspaceId, libraryTrayOpen: workflowLibraryTrayOpen, onCloseLibraryTray: () => setWorkflowLibraryTrayOpen(false), assigneeOptions: assigneeOptions, theme: currentTheme, onUnsavedChangesChange: setWorkflowManagerHasUnsavedChanges }) })] })) : resolvedWorkspaceModule === 'taskforceAgents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskforceAgentsModule, { workspaceId: currentWorkspaceId, taskReferences: taskReferences, agentRosterTrayOpen: taskforceAgentRosterTrayOpen, onCloseAgentRosterTray: () => setTaskforceAgentRosterTrayOpen(false), runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, rememberedAgentId: taskforceAgentId, rememberedConversationId: taskforceAgentConversationId, rememberedConversationByAgentId: taskforceAgentConversationByAgentId, rememberedSelectionReady: uiStateReady, onRememberSelection: handleRememberTaskforceAgentSelection, onOpenConversation: handleOpenTaskforceAgentConversation }) })] })) : resolvedWorkspaceModule === 'aiProfiles' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AiProfilesModule, { workspaceId: currentWorkspaceId, runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, onNotice: pushNotice, mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
4321
+ ...settingsModel,
4322
+ initialSection: 'mcp',
4323
+ onOpenCloudAuth: openSharedLoginRoute
4324
+ }, renderMode: "mcp-only" }) }) })] })) : (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} `, style: {
4325
+ position: 'relative',
4326
+ opacity: props.loadingTasks ? 0.7 : 1,
4327
+ transition: 'opacity 0.2s ease, padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
4328
+ display: 'flex',
4329
+ flex: 1,
4330
+ minHeight: 0,
4331
+ paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px`,
4332
+ }, children: [workspaceToolRail, _jsxs("div", { style: { position: 'relative', width: '100%', minWidth: 0, flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }, children: [showFilters && taskFilterBar, _jsxs("div", { style: {
4333
+ position: 'relative',
4334
+ width: '100%',
4335
+ minWidth: 0,
4336
+ flex: 1,
4337
+ minHeight: 0,
4338
+ display: 'flex',
4339
+ flexDirection: 'column',
4340
+ overflow: 'hidden',
4341
+ transition: 'padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
4342
+ paddingLeft: planningDrawerOpen
4343
+ ? `${planningDrawerWidthPx + WORKSPACE_CONTENT_GUTTER}px`
4344
+ : `${WORKSPACE_CONTENT_GUTTER}px`,
4345
+ paddingRight: (groupBy === 'schedule' && scheduleSidebarOpen)
4346
+ ? `${SCHEDULE_SIDEBAR_WIDTH_PX}px`
4347
+ : 0,
4348
+ }, children: [_jsx("div", { ref: setPlanningDrawerPortalRef, style: {
4349
+ position: 'absolute',
4350
+ top: 0,
4351
+ right: 0,
4352
+ bottom: 0,
4353
+ left: `-${WORKSPACE_TOOL_RAIL_WIDTH}px`,
4354
+ zIndex: 35,
4355
+ pointerEvents: 'none',
4356
+ } }), props.loadingTasks && boardVisibleTasks.length > 0 && (_jsx("div", { className: styles.boardRefreshIndicator, "aria-live": "polite", "aria-label": "Refreshing tasks", children: _jsx(Loader2, { size: 14, className: styles.spinner }) })), taskScope === 'deleted' && (_jsx(TrashRestoreControls, { theme: currentTheme, selectedRecords: trashSelection.selectedRecords, matchingCount: trashSelection.matchingRecords.length, allMatchingSelected: trashSelection.allMatchingSelected, someMatchingSelected: trashSelection.someMatchingSelected, fullTrashCount: props.deletedTasks.length, onSelectAllMatching: trashSelection.selectAllMatching, onClearSelection: trashSelection.clear, onRestore: handleRestoreSelectedDeletedTasks, onEmptyEntireTrash: () => {
4357
+ const count = props.deletedTasks.length;
4358
+ if (count > 0 && window.confirm(`Permanently delete all ${count} tasks in Trash? Filters and selection do not limit this action. This cannot be undone.`)) {
4359
+ void handleEmptyDeletedTasks();
4360
+ }
4361
+ } })), _jsx(TaskKanban, { tasks: scopedBoardVisibleTasks, allTasks: scopedKanbanAllTasks, columns: kanbanColumns, groupBy: groupBy, scheduleDates: scheduleDates, searchQuery: searchQuery, filterCategories: filterCategories, filterTypes: filterTypes, filterPriorities: filterPriorities, filterStatus: filterStatus, filterAssignees: filterAssignees, filtersReady: hasInitedFilters, assigneeOptions: assigneeOptions, scheduleFilteredTaskIds: scheduleFilteredTaskIdList, copiedId: copiedId, taxonomies: taxonomies, types: activeTypes, priorities: priorities, workspaceId: currentWorkspaceId, deletedTaskRecordByTaskId: deletedTaskRecordByTaskId, selectedDeletedRecordIds: trashSelection.selectedIds, onDeletedSelectionChange: trashSelection.toggle, onUpdateTask: handleUpdateTask, onTaskClick: handleEdit, taskReferences: taskTextReferences, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onAddTaskToColumn: handleAddTaskToColumn, showTaskCardStatusLabel: showTaskCardStatusLabel, onScheduleDaySelected: handleBoardScheduleDaySelected, persistedScrollLeft: groupBy === 'schedule' ? scheduleScrollLeft : undefined, onScrollLeftChange: handleBoardScrollLeftChange, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalElement
4362
+ ? createPortal(planningDrawerNode, planningDrawerPortalElement)
4363
+ : null, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, onAssignWorkstreamToInitiative: handleAssignInitiativeToWorkstream, workstreams: props.workstreams, initiatives: props.initiatives, onUnarchive: handleBoardUnarchive, onDelete: handleBoardDelete }, `${groupBy}-${kanbanColumns.map(c => String(c.value)).join('|')}-${scheduleDates.mon}`), groupBy === 'schedule' && !scheduleSidebarOpen && (_jsx("button", { type: "button", className: "tf-control-icon", onClick: () => {
4364
+ setPlanningDrawerDetail(null);
4365
+ setScheduleSidebarOpen(true);
4366
+ }, title: "Show Schedule Sidebar", style: {
4367
+ position: 'absolute',
4368
+ top: '10px',
4369
+ right: '10px',
4370
+ zIndex: 20,
4371
+ }, children: _jsx(ChevronLeft, { size: 16 }) })), groupBy === 'schedule' && (_jsx(ScheduleSidebar, { open: scheduleSidebarOpen, onClose: () => setScheduleSidebarOpen(false), scheduleSelectedDate: scheduleSelectedDate, setScheduleSelectedDate: setScheduleSelectedDate, scheduleCalendarMonth: scheduleCalendarMonth, setScheduleCalendarMonth: setScheduleCalendarMonth, scheduleShowWeekends: scheduleShowWeekends, setScheduleShowWeekends: setScheduleShowWeekends, scheduleShowBacklog: scheduleShowBacklog, setScheduleShowBacklog: setScheduleShowBacklog, scheduleOnlyExpired: scheduleOnlyExpired, setScheduleOnlyExpired: setScheduleOnlyExpired, expiredScheduledCount: expiredScheduledCount, overdueDueCount: overdueDueCount, expiredLeafCandidates: expiredLeafCandidates, expiredRecoveryCandidates: expiredRecoveryCandidates, onMoveExpiredToSelectedWeek: handleMoveExpiredToSelectedWeek, onMoveExpiredToBacklog: handleMoveExpiredToBacklog, scheduleBulkBusy: scheduleBulkBusy, globalWeekStartsOn: globalWeekStartsOn, resolvedLocale: resolvedLocale, todayDateOnly: todayDateOnly, scheduleBaseTasks: scheduleBaseTasks, scheduleWeekStart: scheduleWeekStart, scheduleWeekLabel: scheduleWeekLabel }))] })] })] })) }) }), taskforceAgentDrawerNode && typeof document !== 'undefined'
4372
+ ? createPortal(taskforceAgentDrawerNode, document.body)
4373
+ : taskforceAgentDrawerNode, _jsxs(Modal, { isOpen: activeTab === 'add', onClose: handleCloseModal, title: editingTaskId ? (currentTask?.isDeleted ? 'Deleted Task' : 'Edit Task') : 'New Task', size: taskModalFullscreen ? 'full' : 'xl', theme: currentTheme, className: `${styles.taskforceTaskModalOverlay} ${taskforceAgentDrawerOpen ? styles.taskforceModalWithAssistantPanel : ''} ${taskforceAgentPanelCollapsed ? styles.taskforceModalWithAssistantPanelCollapsed : ''}`.trim(), overlayStyle: {
4374
+ '--taskforce-task-modal-backdrop-top': `${taskforceAgentDrawerTop}px`,
4375
+ '--taskforce-task-modal-backdrop-left': `${WORKSPACE_TOOL_RAIL_WIDTH}px`,
4376
+ }, headerActions: (_jsxs(_Fragment, { children: [!editingTaskId ? (_jsxs("button", { type: "button", onClick: (event) => handleSubmit(event), disabled: loading || !title.trim(), className: styles.primaryUpdateBtn, title: t('actionHeader.addTaskTitle'), children: [loading ? _jsx(Loader2, { size: 16, className: styles.spinner }) : _jsx(Plus, { size: 16 }), t('actionHeader.addTask')] })) : null, _jsx("button", { className: "tf-control-icon", onClick: () => setTaskModalFullscreen((value) => !value), title: taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', "aria-label": taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', children: taskModalFullscreen ? _jsx(Minimize2, { size: 18 }) : _jsx(Maximize2, { size: 18 }) })] })), draggable: !taskModalFullscreen, closeOnOverlayClick: false, children: [_jsxs("div", { className: styles.taskNoticeAnchor, children: [_jsx(TaskActionHeader, { editingTaskId: editingTaskId, loading: loading, submitDisabled: descriptionImageUploadPending, autoSaveState: autoSaveState, title: title, status: status, onStatusChange: setStatus, showCreateSubmit: false, currentTask: currentTask, currentTaskWorkstream: currentTaskWorkstream, currentTaskInitiative: currentTaskInitiative, workstreams: props.workstreams, onWorkstreamInputChange: setWorkstreamInput, onSetWorkstreamForCurrentTask: handleSetWorkstreamForCurrentTask, handleSubmit: handleSubmit, handleCopyId: handleCopyId, copiedId: copiedId, tasks: tasks, handleToggleInProgress: handleToggleInProgress, handleToggleReview: handleToggleReview, handleToggleComplete: handleToggleComplete, handleToggleCancel: handleToggleCancel, handleSetStatus: handleSetStatus, handleArchiveTask: handleArchiveTask, handleUnarchiveTask: (taskId) => {
4377
+ if (currentTask?.isDeleted) {
3252
4378
  const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3253
4379
  if (!deletedRecord)
3254
4380
  return;
3255
- void handleRestoreDeletedTask(deletedRecord.id);
4381
+ void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
3256
4382
  return;
3257
4383
  }
3258
4384
  void handleUnarchive(taskId);
3259
- }, onDelete: (taskId) => {
3260
- if (taskScope === 'deleted') {
3261
- const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3262
- if (!deletedRecord)
3263
- return;
4385
+ }, handleRestoreDeletedTask: currentTask?.deletedRecordId
4386
+ ? (deletedRecordId) => {
4387
+ const deletedRecord = props.deletedTasks.find((entry) => entry.id === deletedRecordId);
4388
+ void handleRestoreDeletedTask(deletedRecordId, deletedRecord?.taskId);
4389
+ }
4390
+ : undefined, handlePermanentlyDeleteDeletedTask: currentTask?.deletedRecordId
4391
+ ? (deletedRecordId) => {
3264
4392
  const confirmed = window.confirm('Permanently delete this task? This cannot be undone.');
3265
4393
  if (!confirmed)
3266
4394
  return;
3267
- void handlePermanentlyDeleteDeletedTask(deletedRecord.id);
3268
- return;
4395
+ void handlePermanentlyDeleteDeletedTask(deletedRecordId);
4396
+ resetForm();
4397
+ setActiveTab('tasks');
3269
4398
  }
3270
- void handleDelete(taskId);
3271
- } }, `${groupBy}-${kanbanColumns.map(c => String(c.value)).join('|')}-${scheduleDates.mon}`), groupBy === 'schedule' && !scheduleSidebarOpen && (_jsx("button", { type: "button", className: "tf-control-icon", onClick: () => {
3272
- setPlanningDrawerDetail(null);
3273
- setScheduleSidebarOpen(true);
3274
- }, title: "Show Schedule Sidebar", style: {
3275
- position: 'absolute',
3276
- top: '10px',
3277
- right: '10px',
3278
- zIndex: 20,
3279
- }, children: _jsx(ChevronLeft, { size: 16 }) }))] }), groupBy === 'schedule' && (_jsx(ScheduleSidebar, { open: scheduleSidebarOpen, onClose: () => setScheduleSidebarOpen(false), scheduleSelectedDate: scheduleSelectedDate, setScheduleSelectedDate: setScheduleSelectedDate, scheduleCalendarMonth: scheduleCalendarMonth, setScheduleCalendarMonth: setScheduleCalendarMonth, scheduleShowWeekends: scheduleShowWeekends, setScheduleShowWeekends: setScheduleShowWeekends, scheduleShowBacklog: scheduleShowBacklog, setScheduleShowBacklog: setScheduleShowBacklog, scheduleOnlyExpired: scheduleOnlyExpired, setScheduleOnlyExpired: setScheduleOnlyExpired, expiredScheduledCount: expiredScheduledCount, overdueDueCount: overdueDueCount, expiredLeafCandidates: expiredLeafCandidates, expiredRecoveryCandidates: expiredRecoveryCandidates, onMoveExpiredToSelectedWeek: handleMoveExpiredToSelectedWeek, onMoveExpiredToBacklog: handleMoveExpiredToBacklog, scheduleBulkBusy: scheduleBulkBusy, globalWeekStartsOn: globalWeekStartsOn, resolvedLocale: resolvedLocale, todayDateOnly: todayDateOnly, scheduleBaseTasks: scheduleBaseTasks, scheduleWeekStart: scheduleWeekStart, scheduleWeekLabel: scheduleWeekLabel }))] })), _jsxs(Modal, { isOpen: activeTab === 'add', onClose: handleCloseModal, title: editingTaskId ? (currentTask?.isDeleted ? 'Deleted Task' : 'Edit Task') : 'New Task', size: taskModalFullscreen ? 'full' : 'xl', theme: currentTheme, headerActions: (_jsx("button", { className: "tf-control-icon", onClick: () => setTaskModalFullscreen((value) => !value), title: taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', "aria-label": taskModalFullscreen ? 'Exit full screen' : 'Enter full screen', children: taskModalFullscreen ? _jsx(Minimize2, { size: 18 }) : _jsx(Maximize2, { size: 18 }) })), draggable: !taskModalFullscreen, closeOnOverlayClick: false, children: [_jsx(TaskActionHeader, { editingTaskId: editingTaskId, loading: loading, autoSaveState: autoSaveState, title: title, currentTask: currentTask, currentTaskWorkstream: currentTaskWorkstream, currentTaskInitiative: currentTaskInitiative, workstreamInput: workstreamInput, onWorkstreamInputChange: setWorkstreamInput, onSetWorkstreamForCurrentTask: handleSetWorkstreamForCurrentTask, handleSubmit: handleSubmit, resetForm: resetForm, handleCopyId: handleCopyId, copiedId: copiedId, tasks: tasks, handleToggleInProgress: handleToggleInProgress, handleToggleReview: handleToggleReview, handleToggleComplete: handleToggleComplete, handleToggleCancel: handleToggleCancel, handleSetStatus: handleSetStatus, handleArchiveTask: handleArchiveTask, handleUnarchiveTask: (taskId) => {
3280
- if (currentTask?.isDeleted) {
3281
- const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3282
- if (!deletedRecord)
3283
- return;
3284
- void handleRestoreDeletedTask(deletedRecord.id);
3285
- return;
3286
- }
3287
- void handleUnarchive(taskId);
3288
- }, handleRestoreDeletedTask: currentTask?.deletedRecordId
3289
- ? (deletedRecordId) => {
3290
- void handleRestoreDeletedTask(deletedRecordId);
3291
- }
3292
- : undefined, handlePermanentlyDeleteDeletedTask: currentTask?.deletedRecordId
3293
- ? (deletedRecordId) => {
3294
- const confirmed = window.confirm('Permanently delete this task? This cannot be undone.');
3295
- if (!confirmed)
3296
- return;
3297
- void handlePermanentlyDeleteDeletedTask(deletedRecordId);
3298
- resetForm();
3299
- setActiveTab('tasks');
3300
- }
3301
- : undefined }), _jsx(TaskForm, { editingTaskId: editingTaskId, error: error, title: title, description: description, checklistItems: checklistItems, category: category, type: type, priority: priority, complexity: complexity, manualComplexityEnabled: manualComplexityEnabled, approach: approach, assignee: assignee, scheduledDate: scheduledDate, dueDate: dueDate, workstreamInput: workstreamInput, formTaxonomies: formTaxonomies, onTaxonomyChange: (id, val) => setFormTaxonomies(prev => ({ ...prev, [id]: val })), taxonomies: taxonomies, comments: comments, newCommentText: newCommentText, contextFiles: attachments, currentWorkspaceId: currentWorkspaceId, apiBaseUrl: apiBaseUrl, descriptionFocused: descriptionFocused, showMarkdownHelp: showMarkdownHelp, showChecklist: showChecklist, checklistEnabled: checklistDropdownEnabled, showComments: showComments, categories: activeCategories, types: activeTypes, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, assigneeOptions: assigneeOptions, workstreams: props.workstreams, initiatives: props.initiatives, copiedId: copiedId, onTitleChange: setTitle, onDescriptionChange: setDescription, onChecklistItemsChange: setChecklistItems, onCategoryChange: setCategory, onTypeChange: setType, onPriorityChange: setPriority, onComplexityChange: setComplexity, onApproachChange: (val) => { setApproach(val); setFormTaxonomies(prev => ({ ...prev, approach: val })); }, onAssigneeChange: setAssignee, onScheduledDateChange: setScheduledDate, onDueDateChange: setDueDate, onWorkstreamInputChange: setWorkstreamInput, onNewCommentTextChange: setNewCommentText, onDescriptionFocusedChange: setDescriptionFocused, onShowMarkdownHelpChange: setShowMarkdownHelp, onShowChecklistChange: setShowChecklist, onShowCommentsChange: setShowComments, onOpenSettings: (section) => {
4399
+ : undefined, onAskAgent: handleAskTaskforceAgentForTask }), _jsx(TopNoticeLayer, { notice: error ? { message: error, tone: 'error' } : uiNotice, onDismiss: () => {
4400
+ clearTaskError();
4401
+ clearNotice();
4402
+ }, placement: "task" })] }), _jsx(TaskForm, { editingTaskId: editingTaskId, initialActivityEntryId: props.initialActivityEntryId, title: title, description: description, checklistItems: checklistItems, category: category, type: type, priority: priority, complexity: complexity, manualComplexityEnabled: manualComplexityEnabled, assignee: assignee, scheduledDate: scheduledDate, dueDate: dueDate, formTaxonomies: formTaxonomies, onTaxonomyChange: (id, val) => setFormTaxonomies(prev => ({ ...prev, [id]: val })), taxonomies: taxonomies, comments: comments, newCommentText: newCommentText, contextFiles: attachments, currentWorkspaceId: currentWorkspaceId, descriptionImageDraftId: descriptionImageDraftId, currentActorId: authUserId, apiBaseUrl: apiBaseUrl, runtimeMode: runtimeMode, showImageReviews: true, descriptionFocused: descriptionFocused, showMarkdownHelp: showMarkdownHelp, checklistEnabled: checklistDropdownEnabled, categories: activeCategories, types: activeTypes, priorities: priorities, taxonomyDisplayLabels: taxonomyDisplayLabels, assigneeOptions: assigneeOptions, workstreams: props.workstreams, initiatives: props.initiatives, copiedId: copiedId, onTitleChange: setTitle, onTitleDraftChange: setTitleDraft, onDescriptionChange: setDescription, onDescriptionDraftChange: setDescriptionDraft, onChecklistItemsChange: setChecklistItems, onCategoryChange: setCategory, onTypeChange: setType, onPriorityChange: setPriority, onComplexityChange: setComplexity, onAssigneeChange: setAssignee, onScheduledDateChange: setScheduledDate, onDueDateChange: setDueDate, onNewCommentTextChange: setNewCommentText, onDescriptionFocusedChange: setDescriptionFocused, onShowMarkdownHelpChange: setShowMarkdownHelp, onOpenSettings: (section) => {
3302
4403
  setSettingsSection(section);
3303
4404
  setActiveTab('settings');
3304
- }, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), onOpenTaskById: handleOpenTaskById, onAddContextFile: (file) => {
4405
+ }, onSubmit: handleSubmit, onDescriptionImageUploadStart: registerDescriptionImageUpload, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), taskReferences: taskTextReferences, onAddContextFile: (file) => {
3305
4406
  updateTaskContextAttachments((current) => [...current, file]);
3306
4407
  }, onRemoveContextFile: async (index) => {
3307
4408
  updateTaskContextAttachments((current) => current.filter((_, i) => i !== index));
@@ -3313,12 +4414,26 @@ export function StandaloneLayout(props) {
3313
4414
  return { path: s, caption, timestamp: new Date().toISOString() };
3314
4415
  return { ...s, caption };
3315
4416
  }));
4417
+ }, onSetCardCover: async (assetId) => {
4418
+ if (!editingTaskId)
4419
+ return;
4420
+ const saved = await handleUpdateTask(editingTaskId, { cardCoverAssetId: assetId });
4421
+ if (saved === false) {
4422
+ throw new Error('Unable to update the task card image.');
4423
+ }
4424
+ }, cardCoverDisabled: attachmentsDirty, onOpenContextImage: (attachment) => {
4425
+ dispatchPreviewContextAttachment(attachment, {
4426
+ ownerType: 'task',
4427
+ ownerId: editingTaskId,
4428
+ ownerReferenceLabel: getTaskReferenceLabel(currentTask),
4429
+ workspaceId: currentWorkspaceId,
4430
+ });
3316
4431
  }, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onUnarchive: (taskId) => {
3317
4432
  if (currentTask?.isDeleted) {
3318
4433
  const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3319
4434
  if (!deletedRecord)
3320
4435
  return;
3321
- void handleRestoreDeletedTask(deletedRecord.id);
4436
+ void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
3322
4437
  return;
3323
4438
  }
3324
4439
  void handleUnarchive(taskId);
@@ -3329,22 +4444,14 @@ export function StandaloneLayout(props) {
3329
4444
  setShowHelpModal(false);
3330
4445
  setActiveTab('settings');
3331
4446
  setSettingsSection('general');
3332
- }, onOpenAccountHub: () => {
3333
- setShowHelpModal(false);
3334
- startAccountSurfaceTiming('account_hub');
3335
- setShowAccountHub(true);
3336
- } }), _jsx(EditProfileModal, { isOpen: showEditProfileModal, theme: currentTheme, onClose: closeEditProfileModal, onSave: () => { void handleSaveProfile(); }, displayName: profileDisplayNameDraft, email: authEmailLabel, avatarDisplayUrl: profileAvatarDisplayUrl, accountBadgeInitial: accountBadgeInitial, saveBusy: profileSaveBusy, avatarBusy: profileAvatarBusy, saveError: profileSaveError, saveNotice: profileSaveNotice, onDisplayNameChange: setProfileDisplayNameDraft, onOpenAvatarManager: () => {
4447
+ } }), _jsx(AccountSettingsModal, { isOpen: showAccountSettings, theme: currentTheme, displayName: profileDisplayNameDraft, email: authEmailLabel, avatarDisplayUrl: profileAvatarDisplayUrl, accountBadgeInitial: accountBadgeInitial, profileSaveBusy: profileSaveBusy, profileAvatarBusy: profileAvatarBusy, profileSaveError: profileSaveError, profileSaveNotice: profileSaveNotice, cloudAuthEnabled: cloudAuthConfigured, availableAuthProviders: availableAuthProviders, billingLoading: billingLoading, billingError: billingError, billingActionError: billingActionError, billingNotice: billingNotice, billingActionBusy: billingActionBusy, billingIntervalChoice: billingIntervalChoice, accountProfileSummary: accountProfileSummary, onClose: closeAccountSettingsModal, onSaveProfile: () => { void handleSaveProfile(); }, onDisplayNameChange: setProfileDisplayNameDraft, onOpenAvatarManager: () => {
3337
4448
  setProfileSaveError(null);
3338
4449
  setProfileSaveNotice(null);
3339
4450
  setShowAvatarPhotoManager(true);
3340
- } }), _jsx(AvatarImageManagerModal, { isOpen: showAvatarPhotoManager, theme: currentTheme, title: "Edit Profile Photo", currentImageUrl: profileAvatarDisplayUrl, fallbackInitial: accountBadgeInitial, accept: PROFILE_AVATAR_ACCEPT, busy: profileAvatarBusy, hasPendingImage: Boolean(profileAvatarDraftId), canRemove: Boolean(profileAvatarDisplayUrl), error: profileSaveError, notice: profileSaveNotice, onClose: () => setShowAvatarPhotoManager(false), onApplyImage: handleProfileAvatarSelected, onRemoveImage: handleRemoveProfileAvatar, onDiscardPendingImage: handleDiscardPendingProfileAvatar }), _jsx(AccountHubModal, { isOpen: showAccountHub, theme: currentTheme, runtimeMode: runtimeMode, authRequiredForApi: authRequiredForApi, isAuthenticated: isAuthenticated, hasAuthIdentity: hasAuthIdentity, authIdentityLabel: authIdentityLabel, billingLoading: billingLoading, billingError: billingError, billingActionError: billingActionError, billingNotice: billingNotice, billingActionBusy: billingActionBusy, billingIntervalChoice: billingIntervalChoice, accountProfileSummary: accountProfileSummary, currentWorkspaceId: currentWorkspaceId, canOpenTeamManagement: canOpenTeamManagement, canManageWorkspaceSync: canManageWorkspaceSync, workspaceCloudSyncEnabled: workspaceCloudSyncEnabled, syncStatusLabel: syncStatusMeta.label, workspaceSyncError: workspaceSyncError, syncControlBusy: syncControlBusy, cloudAuthEnabled: cloudAuthConfigured, availableAuthProviders: availableAuthProviders, onFetchLoginMethods: fetchLoginMethods, onUnlinkLoginMethod: unlinkLoginMethod, onAddPassword: addPasswordToAccount, onLinkProvider: (provider) => beginOAuthLink(provider), onClose: () => setShowAccountHub(false), onOpenWorkspaceAudit: () => {
3341
- setShowAccountHub(false);
3342
- void openTeamManagementModal();
3343
- setTeamManagementTab('audit');
3344
- }, onBillingIntervalChange: setBillingIntervalChoice, onRefreshBilling: () => { void loadAccountProfileSummary(); }, onUpdateInterval: () => { void handleSwitchSubscriptionInterval(); }, onManageBilling: () => { void handleOpenBillingPortal(); }, onStartCheckout: () => { void handleStartCheckout(); }, onToggleWorkspaceSync: (enabled) => { void handleWorkspaceSyncToggle(enabled); }, onOpenHelp: () => {
3345
- setShowAccountHub(false);
3346
- setShowHelpModal(true);
3347
- } }), _jsx(TeamManagementModal, { isOpen: showTeamManagementModal, theme: currentTheme, teamPlanMode: teamPlanMode, teamMgmtError: teamMgmtError, teamManagementTab: teamManagementTab, teamUsersLoading: teamUsersLoading, teamUsers: teamUsers, teamActionBusyUserId: teamActionBusyUserId, teamInviteFeedback: teamInviteFeedback, teamInviteEmail: teamInviteEmail, teamInviteRole: teamInviteRole, teamInvitePermissionMode: teamInvitePermissionMode, teamInviteBusy: teamInviteBusy, pendingInvites: pendingInvites, teamAuditLoading: teamAuditLoading, teamAuditEvents: teamAuditEvents, teamAuditPage: teamAuditPage, teamAuditPages: teamAuditPages, teamAuditHasMore: teamAuditHasMore, onClose: () => setShowTeamManagementModal(false), onOpenMembersTab: () => {
4451
+ }, onFetchLoginMethods: fetchLoginMethods, onUnlinkLoginMethod: unlinkLoginMethod, onAddPassword: addPasswordToAccount, onChangePassword: changePassword, onLinkProvider: (provider) => beginOAuthLink(provider), onBillingIntervalChange: setBillingIntervalChoice, onRefreshBilling: () => { void loadAccountProfileSummary(); }, onUpdateInterval: () => { void handleSwitchSubscriptionInterval(); }, onManageBilling: () => { void handleOpenBillingPortal(); }, onOpenPlans: () => {
4452
+ setShowAccountSettings(false);
4453
+ void handleStartCheckout();
4454
+ } }), _jsx(AvatarImageManagerModal, { isOpen: showAvatarPhotoManager, theme: currentTheme, title: "Edit Profile Photo", currentImageUrl: profileAvatarDisplayUrl, fallbackInitial: accountBadgeInitial, accept: PROFILE_AVATAR_ACCEPT, busy: profileAvatarBusy, hasPendingImage: Boolean(profileAvatarDraftId), canRemove: Boolean(profileAvatarDisplayUrl), error: profileSaveError, notice: profileSaveNotice, onClose: () => setShowAvatarPhotoManager(false), onApplyImage: handleProfileAvatarSelected, onRemoveImage: handleRemoveProfileAvatar, onDiscardPendingImage: handleDiscardPendingProfileAvatar }), _jsx(TeamManagementModal, { isOpen: showTeamManagementModal, theme: currentTheme, teamPlanMode: teamPlanMode, teamMgmtError: teamMgmtError, teamManagementTab: teamManagementTab, teamUsersLoading: teamUsersLoading, teamUsers: teamUsers, teamActionBusyUserId: teamActionBusyUserId, teamInviteFeedback: teamInviteFeedback, teamInviteEmail: teamInviteEmail, teamInviteRole: teamInviteRole, teamInvitePermissionMode: teamInvitePermissionMode, teamInviteBusy: teamInviteBusy, pendingInvites: pendingInvites, teamAuditLoading: teamAuditLoading, teamAuditEvents: teamAuditEvents, teamAuditPage: teamAuditPage, teamAuditPages: teamAuditPages, teamAuditHasMore: teamAuditHasMore, onClose: () => setShowTeamManagementModal(false), onOpenMembersTab: () => {
3348
4455
  setTeamManagementTab('members');
3349
4456
  void loadTeamUsers();
3350
4457
  }, onOpenInvitesTab: () => setTeamManagementTab('invites'), onOpenAuditTab: () => {
@@ -3393,11 +4500,21 @@ export function StandaloneLayout(props) {
3393
4500
  headers: teamAdminHeaders(),
3394
4501
  credentials: 'include'
3395
4502
  }));
3396
- }, onInviteEmailChange: setTeamInviteEmail, onInviteRoleChange: setTeamInviteRole, onInvitePermissionModeChange: setTeamInvitePermissionMode, onSubmitInvite: () => { void submitTeamInvite(); }, onLoadAuditPrevious: () => { void loadTeamAuditPage(teamAuditPage - 1); }, onLoadAuditNext: () => { void loadTeamAuditPage(teamAuditPage + 1); } }), _jsx(CreateWorkspaceConfirmModal, { isOpen: showCreateWorkspaceConfirm, theme: currentTheme, onClose: () => setShowCreateWorkspaceConfirm(false), onConfirm: () => openWorkspaceSetup({ intent: 'create-workspace' }) }), _jsx(SyncStatusModal, { isOpen: showSyncStatusModal, theme: currentTheme, currentWorkspaceLabel: currentWorkspaceLabel, syncStatusMeta: syncStatusMeta, workspaceCloudSyncEnabled: workspaceCloudSyncEnabled, syncControlBusy: syncControlBusy, canManageWorkspaceSync: canManageWorkspaceSync, workspaceSyncSummary: headerSyncPresentation.summary, workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction, workspaceSyncRepairBusy: workspaceSyncRepairBusy, referenceMismatchCount: referenceMismatchCount, syncStageLabel: syncStageLabel, workspaceSyncPendingChanges: workspaceSyncPendingChanges, formattedLastSyncTime: formattedLastSyncTime, formattedLastPullTime: formattedLastPullTime, formattedLastPushTime: formattedLastPushTime, syncLastError: syncLastError, workspaceSyncDiagnostics: workspaceSyncDiagnostics, activeReferenceMismatchSummaries: activeReferenceMismatchSummaries, syncDiagnosticsSummary: syncDiagnosticsSummary, syncEventRows: syncEventRows, syncEventsListRef: syncEventsListRef, workspaceSyncRepairQueued: workspaceSyncRepairQueued, workspaceSyncBusy: workspaceSyncBusy, workspaceSyncCopied: workspaceSyncCopied, runtimeMode: runtimeMode, isAuthenticated: isAuthenticated, onClose: closeSyncStatusModal, onToggleWorkspaceSync: (enabled) => {
4503
+ }, onInviteEmailChange: setTeamInviteEmail, onInviteRoleChange: setTeamInviteRole, onInvitePermissionModeChange: setTeamInvitePermissionMode, onSubmitInvite: () => { void submitTeamInvite(); }, onLoadAuditPrevious: () => { void loadTeamAuditPage(teamAuditPage - 1); }, onLoadAuditNext: () => { void loadTeamAuditPage(teamAuditPage + 1); } }), _jsx(CreateWorkspaceConfirmModal, { isOpen: showCreateWorkspaceConfirm, theme: currentTheme, onClose: () => setShowCreateWorkspaceConfirm(false), onConfirm: () => openWorkspaceSetup({ intent: 'create-workspace' }) }), _jsx(SyncStatusModal, { isOpen: showSyncStatusModal, theme: currentTheme, currentWorkspaceLabel: currentWorkspaceLabel, syncStatus: headerSyncStatus, syncStatusMeta: syncStatusMeta, workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled, syncControlBusy: syncControlBusy, canManageWorkspaceSync: canManageWorkspaceSync, workspaceSyncSummary: headerSyncPresentation.summary, workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction, workspaceSyncRepairBusy: effectiveWorkspaceSyncRepairBusy, referenceMismatchCount: referenceMismatchCount, syncStageLabel: syncStageLabel, workspaceSyncPendingChanges: effectivePendingLocalChanges, incomingCloudChanges: coordinatorSyncPresentation?.incomingCloudChanges || 'Unknown', formattedLastSyncTime: effectiveFormattedLastSyncTime, formattedLastPullTime: effectiveFormattedLastPullTime, formattedLastPushTime: effectiveFormattedLastPushTime, syncLastError: syncLastError, activeReferenceMismatchSummaries: activeReferenceMismatchSummaries, syncDiagnosticsSummary: syncDiagnosticsSummary, syncEventRows: syncEventRows, syncEventsListRef: syncEventsListRef, workspaceSyncRepairQueued: workspaceSyncRepairQueued, workspaceSyncBusy: effectiveWorkspaceSyncBusy, workspaceSyncCopied: workspaceSyncCopied, coordinatorOwnershipMode: coordinatorOwnershipMode, coordinatorOwnershipTransferBusy: coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled: coordinatorOwnershipTransferDisabled, onClose: closeSyncStatusModal, onToggleWorkspaceSync: (enabled) => {
3397
4504
  void handleWorkspaceSyncToggle(enabled);
3398
- }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onOpenLogin: () => {
3399
- openSharedLoginRoute('login');
3400
- }, onRetrySync: () => { void retryWorkspaceCloudSync(); } }), unsavedModalOpen && createPortal(_jsx("div", { className: `${modalStyles.overlay} ${modalStyles.unsavedOverlay}`, style: { zIndex: 2000 }, children: _jsxs("div", { className: `tf-surface-modal tf-modal-shell ${modalStyles.modal} ${modalStyles.unsavedModal}`, "data-theme": currentTheme, children: [_jsx("div", { className: `tf-modal-header ${modalStyles.unsavedHeader}`, children: _jsxs("div", { className: `tf-modal-title ${modalStyles.unsavedTitle}`, children: [_jsx(AlertTriangle, { size: 20 }), "Unsaved Changes"] }) }), _jsx("div", { className: `${modalStyles.form} ${modalStyles.unsavedContent}`, children: _jsx("p", { className: modalStyles.unsavedText, children: "You have unsaved changes. Would you like to save them?" }) }), _jsxs("div", { className: `${modalStyles.formActions} ${modalStyles.unsavedActions}`, children: [_jsx("button", { className: styles.cancelBtn, onClick: () => setUnsavedModalOpen(false), title: "Close dialog and continue editing", children: "Keep Editing" }), _jsx("button", { className: styles.destructiveBtn, onClick: handleDiscard, title: "Discard unsaved changes and leave", children: "Discard" }), _jsxs("button", { className: styles.submitBtn, onClick: handleSaveAndNavigate, disabled: loading, title: "Save changes and leave", children: [loading ? _jsx(Loader2, { size: 16, className: styles.spinner }) : _jsx(Save, { size: 16 }), "Save"] })] })] }) }), document.body), showFolderBrowser && createPortal(_jsx("div", { className: folderBrowserStyles.overlay, children: _jsxs("div", { className: folderBrowserStyles.browser, children: [_jsxs("div", { className: folderBrowserStyles.header, children: [_jsxs("div", { className: folderBrowserStyles.pathInfo, children: [_jsx(Folder, { size: 14 }), _jsx("span", { children: currentBrowsePath || 'Project Root' })] }), _jsxs("div", { className: folderBrowserStyles.actions, children: [currentBrowsePath && (_jsx("button", { className: styles.helpLink, onClick: () => {
4505
+ }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onRetrySync: () => {
4506
+ void retryWorkspaceCloudSync().catch(() => {
4507
+ // Coordinator status owns the durable error and retry presentation.
4508
+ });
4509
+ }, onTransferCoordinatorOwnership: () => {
4510
+ void handleCoordinatorOwnershipTransfer();
4511
+ } }), _jsx(DiscardChangesDialog, { isOpen: Boolean(pendingWorkflowDiscardAction), onKeepEditing: () => setPendingWorkflowDiscardAction(null), onDiscard: () => {
4512
+ const action = pendingWorkflowDiscardAction;
4513
+ setPendingWorkflowDiscardAction(null);
4514
+ workflowDiscardBypassRef.current = true;
4515
+ action?.();
4516
+ window.setTimeout(() => { workflowDiscardBypassRef.current = false; }, 0);
4517
+ }, theme: currentTheme }), unsavedModalOpen && createPortal(_jsx("div", { className: `${modalStyles.overlay} ${modalStyles.unsavedOverlay}`, style: { zIndex: 2000 }, children: _jsxs("div", { className: `tf-surface-modal tf-modal-shell ${modalStyles.modal} ${modalStyles.unsavedModal}`, "data-theme": currentTheme, children: [_jsx("div", { className: `tf-modal-header ${modalStyles.unsavedHeader}`, children: _jsxs("div", { className: `tf-modal-title ${modalStyles.unsavedTitle}`, children: [_jsx(AlertTriangle, { size: 20 }), "Unsaved Changes"] }) }), _jsx("div", { className: `${modalStyles.form} ${modalStyles.unsavedContent}`, children: _jsx("p", { className: modalStyles.unsavedText, children: "You have unsaved changes. Would you like to save them?" }) }), _jsxs("div", { className: `${modalStyles.formActions} ${modalStyles.unsavedActions}`, children: [_jsx("button", { className: styles.cancelBtn, onClick: () => setUnsavedModalOpen(false), title: "Close dialog and continue editing", children: "Keep Editing" }), _jsx("button", { className: styles.destructiveBtn, onClick: handleDiscard, title: "Discard unsaved changes and leave", children: "Discard" }), _jsxs("button", { className: styles.submitBtn, onClick: handleSaveAndNavigate, disabled: loading, title: "Save changes and leave", children: [loading ? _jsx(Loader2, { size: 16, className: styles.spinner }) : _jsx(Save, { size: 16 }), "Save"] })] })] }) }), document.body), showFolderBrowser && createPortal(_jsx("div", { className: folderBrowserStyles.overlay, children: _jsxs("div", { className: folderBrowserStyles.browser, children: [_jsxs("div", { className: folderBrowserStyles.header, children: [_jsxs("div", { className: folderBrowserStyles.pathInfo, children: [_jsx(Folder, { size: 14 }), _jsx("span", { children: currentBrowsePath || 'Project Root' })] }), _jsxs("div", { className: folderBrowserStyles.actions, children: [currentBrowsePath && (_jsx("button", { className: styles.helpLink, onClick: () => {
3401
4518
  const parts = currentBrowsePath.split('/').filter(Boolean);
3402
4519
  parts.pop();
3403
4520
  fetchFolders(parts.length ? parts.join('/') + '/' : '');