@taskforcehq/taskforce 0.3.324 → 0.3.327

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 (1361) hide show
  1. package/LICENSE.md +68 -0
  2. package/README.md +19 -0
  3. package/dist/Taskforce.module.css +2191 -540
  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 +73 -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 +4 -0
  27. package/dist/components/context/ContextAttachmentManager.js +418 -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 +257 -151
  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 +44 -0
  60. package/dist/components/features/planning/PlanningEntitySummary.js +97 -0
  61. package/dist/components/features/planning/PlanningLinkPicker.d.ts +9 -0
  62. package/dist/components/features/planning/PlanningLinkPicker.js +26 -0
  63. package/dist/components/features/planning/PlanningModule.d.ts +6 -0
  64. package/dist/components/features/planning/PlanningModule.js +571 -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/planningCreateIntent.d.ts +10 -0
  76. package/dist/components/features/planning/planningCreateIntent.js +16 -0
  77. package/dist/components/features/planning/planningNavigator.d.ts +33 -0
  78. package/dist/components/features/planning/planningNavigator.js +96 -0
  79. package/dist/components/features/planning/planningTaskArrangement.d.ts +18 -0
  80. package/dist/components/features/planning/planningTaskArrangement.js +106 -0
  81. package/dist/components/features/planning/planningWorkspaceModel.d.ts +121 -0
  82. package/dist/components/features/planning/planningWorkspaceModel.js +5 -0
  83. package/dist/components/features/settings/CategoryManager.js +2 -2
  84. package/dist/components/features/settings/TaxonomyEditor.js +1 -1
  85. package/dist/components/features/settings/TaxonomyManager.js +1 -1
  86. package/dist/components/features/settings/TypeManager.js +1 -1
  87. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.d.ts +10 -0
  88. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +175 -0
  89. package/dist/components/features/taskforceAgentAssignments/agentBehaviorCatalogApi.d.ts +27 -0
  90. package/dist/components/features/taskforceAgentAssignments/agentBehaviorCatalogApi.js +24 -0
  91. package/dist/components/features/taskforceAgentEditorModel.d.ts +109 -0
  92. package/dist/components/features/taskforceAgentEditorModel.js +145 -0
  93. package/dist/components/features/useDocumentWorkspaceController.d.ts +20 -1
  94. package/dist/components/features/useDocumentWorkspaceController.js +106 -21
  95. package/dist/components/features/workflowManager/WorkflowManagerModule.d.ts +11 -0
  96. package/dist/components/features/workflowManager/WorkflowManagerModule.js +313 -0
  97. package/dist/components/features/workflowManager/WorkflowPublishDialog.d.ts +11 -0
  98. package/dist/components/features/workflowManager/WorkflowPublishDialog.js +8 -0
  99. package/dist/components/features/workflowManager/types.d.ts +74 -0
  100. package/dist/components/features/workflowManager/types.js +1 -0
  101. package/dist/components/features/workflowManager/useWorkflowManager.d.ts +30 -0
  102. package/dist/components/features/workflowManager/useWorkflowManager.js +213 -0
  103. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +52 -0
  104. package/dist/components/features/workflowManager/workflowManagerApi.js +142 -0
  105. package/dist/components/task/TaskActionHeader.d.ts +6 -3
  106. package/dist/components/task/TaskActionHeader.js +46 -53
  107. package/dist/components/task/TaskCard.d.ts +10 -2
  108. package/dist/components/task/TaskCard.js +103 -54
  109. package/dist/components/task/TaskContextUpload.d.ts +1 -0
  110. package/dist/components/task/TaskContextUpload.js +3 -2
  111. package/dist/components/task/TaskForm.d.ts +12 -17
  112. package/dist/components/task/TaskForm.js +544 -199
  113. package/dist/components/task/TaskImageReviews.d.ts +8 -0
  114. package/dist/components/task/TaskImageReviews.js +47 -0
  115. package/dist/components/task/TaskKanban.d.ts +11 -12
  116. package/dist/components/task/TaskKanban.js +70 -18
  117. package/dist/components/task/TaskList.d.ts +9 -8
  118. package/dist/components/task/TaskList.js +46 -32
  119. package/dist/components/task/TaskReferenceBadge.d.ts +2 -1
  120. package/dist/components/task/TaskReferenceBadge.js +3 -2
  121. package/dist/components/task/TaskStatusActions.d.ts +3 -1
  122. package/dist/components/task/TaskStatusActions.js +17 -6
  123. package/dist/components/task/TaskWorkflowAssignmentField.d.ts +18 -0
  124. package/dist/components/task/TaskWorkflowAssignmentField.js +362 -0
  125. package/dist/components/task/TaskWorkstreamPicker.d.ts +8 -0
  126. package/dist/components/task/TaskWorkstreamPicker.js +24 -0
  127. package/dist/components/task/TrashRestoreControls.d.ts +18 -0
  128. package/dist/components/task/TrashRestoreControls.js +71 -0
  129. package/dist/components/ui/AiIdentityRosterCard.d.ts +20 -0
  130. package/dist/components/ui/AiIdentityRosterCard.js +5 -0
  131. package/dist/components/ui/AssetTraySortControl.d.ts +10 -0
  132. package/dist/components/ui/AssetTraySortControl.js +38 -0
  133. package/dist/components/ui/AssigneeIdentity.d.ts +12 -0
  134. package/dist/components/ui/AssigneeIdentity.js +41 -0
  135. package/dist/components/ui/DiscardChangesDialog.d.ts +10 -0
  136. package/dist/components/ui/DiscardChangesDialog.js +7 -0
  137. package/dist/components/ui/DisclosureSectionHeader.d.ts +4 -1
  138. package/dist/components/ui/DisclosureSectionHeader.js +2 -2
  139. package/dist/components/ui/EditableAvatarButton.d.ts +6 -1
  140. package/dist/components/ui/EditableAvatarButton.js +6 -5
  141. package/dist/components/ui/HierarchyActionBadge.d.ts +2 -1
  142. package/dist/components/ui/HierarchyActionBadge.js +2 -2
  143. package/dist/components/ui/Markdown.d.ts +13 -3
  144. package/dist/components/ui/Markdown.fixture.d.ts +1 -0
  145. package/dist/components/ui/Markdown.fixture.js +23 -0
  146. package/dist/components/ui/Markdown.js +158 -68
  147. package/dist/components/ui/Modal.d.ts +3 -1
  148. package/dist/components/ui/Modal.js +85 -19
  149. package/dist/components/ui/MultiSelectFilter.d.ts +9 -2
  150. package/dist/components/ui/MultiSelectFilter.js +26 -5
  151. package/dist/components/ui/ReferenceBadgeButton.js +2 -3
  152. package/dist/components/ui/TaxonomyDropdown.d.ts +10 -1
  153. package/dist/components/ui/TaxonomyDropdown.js +149 -58
  154. package/dist/components/ui/TopNoticeLayer.d.ts +2 -1
  155. package/dist/components/ui/TopNoticeLayer.js +5 -2
  156. package/dist/components/ui/useFallbackImageUrl.d.ts +4 -0
  157. package/dist/components/ui/useFallbackImageUrl.js +20 -0
  158. package/dist/components/views/AppShellHeader.js +2 -2
  159. package/dist/components/views/StandaloneLayout.d.ts +1 -0
  160. package/dist/components/views/StandaloneLayout.js +1684 -620
  161. package/dist/components/views/WidgetView.d.ts +1 -0
  162. package/dist/components/views/WidgetView.js +95 -30
  163. package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +4 -2
  164. package/dist/components/views/chrome/WorkspaceChromeSections.js +3 -6
  165. package/dist/components/views/chrome/workspaceChrome.d.ts +5 -8
  166. package/dist/components/views/chrome/workspaceChrome.js +62 -27
  167. package/dist/components/views/panels/FilterToolbar.d.ts +4 -3
  168. package/dist/components/views/panels/FilterToolbar.js +8 -5
  169. package/dist/components/views/panels/FilterToolbarControls.d.ts +11 -2
  170. package/dist/components/views/panels/FilterToolbarControls.js +35 -20
  171. package/dist/components/views/panels/PlanningDrawer.d.ts +62 -51
  172. package/dist/components/views/panels/PlanningDrawer.js +993 -314
  173. package/dist/components/views/planningScope.d.ts +4 -0
  174. package/dist/components/views/planningScope.js +12 -1
  175. package/dist/components/views/standalone/modals/AccountSettingsModal.d.ts +62 -0
  176. package/dist/components/views/standalone/modals/AccountSettingsModal.js +197 -0
  177. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +7 -2
  178. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +56 -9
  179. package/dist/components/views/standalone/modals/HelpModal.d.ts +1 -2
  180. package/dist/components/views/standalone/modals/HelpModal.js +3 -4
  181. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +8 -9
  182. package/dist/components/views/standalone/modals/SyncStatusModal.js +85 -25
  183. package/dist/components/views/standalone/modals/TeamManagementModal.js +1 -1
  184. package/dist/config/applicationBaseUrl.d.ts +2 -0
  185. package/dist/config/applicationBaseUrl.js +23 -0
  186. package/dist/config/envSchema.d.ts +1 -1
  187. package/dist/config/envSchema.js +166 -5
  188. package/dist/core/AdminAuditRetentionService.d.ts +43 -0
  189. package/dist/core/AdminAuditRetentionService.js +126 -0
  190. package/dist/core/AiProfileService.d.ts +34 -0
  191. package/dist/core/AiProfileService.js +516 -252
  192. package/dist/core/AttachmentLinkService.d.ts +10 -2
  193. package/dist/core/AttachmentLinkService.js +44 -12
  194. package/dist/core/AuthIdentityService.d.ts +6 -0
  195. package/dist/core/AuthIdentityService.js +38 -0
  196. package/dist/core/AuthTokenService.d.ts +1 -0
  197. package/dist/core/AuthTokenService.js +13 -0
  198. package/dist/core/DeletedTaskLifecycleService.d.ts +4 -2
  199. package/dist/core/DeletedTaskLifecycleService.js +124 -38
  200. package/dist/core/GlobalSettingsService.d.ts +3 -1
  201. package/dist/core/GlobalSettingsService.js +30 -4
  202. package/dist/core/InitiativeDurableMutationService.d.ts +89 -0
  203. package/dist/core/InitiativeDurableMutationService.js +187 -0
  204. package/dist/core/McpTokenService.d.ts +1 -0
  205. package/dist/core/McpTokenService.js +39 -13
  206. package/dist/core/PlanningCommandPreparationService.d.ts +60 -0
  207. package/dist/core/PlanningCommandPreparationService.js +149 -0
  208. package/dist/core/ScheduleCommandService.d.ts +76 -0
  209. package/dist/core/ScheduleCommandService.js +165 -0
  210. package/dist/core/SyncReconciliationService.d.ts +29 -6
  211. package/dist/core/SyncReconciliationService.js +256 -84
  212. package/dist/core/TaskActivityService.d.ts +22 -2
  213. package/dist/core/TaskActivityService.js +177 -29
  214. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +31 -0
  215. package/dist/core/TaskAttachmentLinksDurableMutationService.js +231 -0
  216. package/dist/core/TaskChecklistCommandService.d.ts +50 -0
  217. package/dist/core/TaskChecklistCommandService.js +111 -0
  218. package/dist/core/TaskDurableCreateMutationService.d.ts +38 -0
  219. package/dist/core/TaskDurableCreateMutationService.js +85 -0
  220. package/dist/core/TaskDurableDeleteMutationService.d.ts +47 -0
  221. package/dist/core/TaskDurableDeleteMutationService.js +54 -0
  222. package/dist/core/TaskDurableLifecycleMutationService.d.ts +38 -0
  223. package/dist/core/TaskDurableLifecycleMutationService.js +42 -0
  224. package/dist/core/TaskDurableRelationshipMutationService.d.ts +58 -0
  225. package/dist/core/TaskDurableRelationshipMutationService.js +66 -0
  226. package/dist/core/TaskDurableRestoreMutationService.d.ts +31 -0
  227. package/dist/core/TaskDurableRestoreMutationService.js +33 -0
  228. package/dist/core/TaskDurableStatusMutationService.d.ts +74 -0
  229. package/dist/core/TaskDurableStatusMutationService.js +247 -0
  230. package/dist/core/TaskDurableSyncMutationService.d.ts +34 -0
  231. package/dist/core/TaskDurableSyncMutationService.js +70 -0
  232. package/dist/core/TaskDurableWorkflowMutationService.d.ts +48 -0
  233. package/dist/core/TaskDurableWorkflowMutationService.js +59 -0
  234. package/dist/core/TaskLifecycleCommandService.d.ts +101 -0
  235. package/dist/core/TaskLifecycleCommandService.js +161 -0
  236. package/dist/core/TaskRootCommandPreparationService.d.ts +35 -0
  237. package/dist/core/TaskRootCommandPreparationService.js +103 -0
  238. package/dist/core/Taskforce.d.ts +479 -59
  239. package/dist/core/Taskforce.js +3671 -841
  240. package/dist/core/WorkflowAssignmentService.d.ts +40 -0
  241. package/dist/core/WorkflowAssignmentService.js +158 -0
  242. package/dist/core/WorkflowExecutionService.d.ts +69 -0
  243. package/dist/core/WorkflowExecutionService.js +342 -0
  244. package/dist/core/WorkflowTaskActivationService.d.ts +32 -0
  245. package/dist/core/WorkflowTaskActivationService.js +63 -0
  246. package/dist/core/WorkflowTemplateService.d.ts +64 -0
  247. package/dist/core/WorkflowTemplateService.js +223 -0
  248. package/dist/core/WorkspaceLifecycleService.d.ts +1 -0
  249. package/dist/core/WorkspaceLifecycleService.js +18 -0
  250. package/dist/core/WorkstreamDurableMutationService.d.ts +90 -0
  251. package/dist/core/WorkstreamDurableMutationService.js +184 -0
  252. package/dist/core/planningReferencePolicy.d.ts +14 -0
  253. package/dist/core/planningReferencePolicy.js +53 -0
  254. package/dist/core/taskReferencePolicy.js +24 -3
  255. package/dist/core/types.d.ts +10 -10
  256. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +22 -2
  257. package/dist/documentReviews/DocumentReviewCommentStore.js +92 -8
  258. package/dist/documentReviews/commandService.d.ts +51 -0
  259. package/dist/documentReviews/commandService.js +63 -0
  260. package/dist/documentReviews/service.d.ts +20 -1
  261. package/dist/documentReviews/service.js +234 -24
  262. package/dist/documentReviews/types.d.ts +18 -1
  263. package/dist/hooks/sync/bootstrap.d.ts +3 -7
  264. package/dist/hooks/sync/bootstrap.js +6 -14
  265. package/dist/hooks/sync/browserSyncAuthority.d.ts +21 -0
  266. package/dist/hooks/sync/browserSyncAuthority.js +70 -0
  267. package/dist/hooks/sync/browserSyncRemoteServices.d.ts +29 -0
  268. package/dist/hooks/sync/browserSyncRemoteServices.js +58 -0
  269. package/dist/hooks/sync/controlPlane.d.ts +1 -37
  270. package/dist/hooks/sync/controlPlane.js +1 -78
  271. package/dist/hooks/sync/lifecyclePolicy.d.ts +1 -45
  272. package/dist/hooks/sync/lifecyclePolicy.js +1 -93
  273. package/dist/hooks/sync/orchestratorShared.d.ts +9 -3
  274. package/dist/hooks/sync/orchestratorShared.js +70 -96
  275. package/dist/hooks/sync/pullLifecycle.d.ts +1 -31
  276. package/dist/hooks/sync/pullLifecycle.js +1 -24
  277. package/dist/hooks/sync/realtime.d.ts +4 -1
  278. package/dist/hooks/sync/realtime.js +103 -3
  279. package/dist/hooks/sync/recovery.d.ts +1 -84
  280. package/dist/hooks/sync/recovery.js +1 -245
  281. package/dist/hooks/sync/transfers.d.ts +8 -129
  282. package/dist/hooks/sync/transfers.js +19 -581
  283. package/dist/hooks/sync/useDataVersionRefresh.d.ts +6 -1
  284. package/dist/hooks/sync/useDataVersionRefresh.js +127 -12
  285. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +14 -0
  286. package/dist/hooks/sync/useDurableLocalOutboxDrain.js +208 -0
  287. package/dist/hooks/sync/useDurableTaskCreateMutation.d.ts +15 -0
  288. package/dist/hooks/sync/useDurableTaskCreateMutation.js +152 -0
  289. package/dist/hooks/sync/useDurableTaskDeleteMutation.d.ts +11 -0
  290. package/dist/hooks/sync/useDurableTaskDeleteMutation.js +21 -0
  291. package/dist/hooks/sync/useDurableTaskLifecycleMutation.d.ts +12 -0
  292. package/dist/hooks/sync/useDurableTaskLifecycleMutation.js +22 -0
  293. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +14 -0
  294. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +24 -0
  295. package/dist/hooks/sync/useDurableTaskRestoreMutation.d.ts +12 -0
  296. package/dist/hooks/sync/useDurableTaskRestoreMutation.js +24 -0
  297. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +18 -0
  298. package/dist/hooks/sync/useDurableTaskStatusMutation.js +23 -0
  299. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +23 -0
  300. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +414 -0
  301. package/dist/hooks/sync/useSyncStatusActions.d.ts +2 -1
  302. package/dist/hooks/sync/useSyncStatusActions.js +8 -3
  303. package/dist/hooks/tasks/taskHttpMutation.d.ts +25 -0
  304. package/dist/hooks/tasks/taskHttpMutation.js +134 -0
  305. package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +6 -1
  306. package/dist/hooks/tasks/useCurrentTaskRelations.js +32 -6
  307. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +4 -3
  308. package/dist/hooks/tasks/useTaskEditorNavigation.js +9 -13
  309. package/dist/hooks/tasks/useTaskFormActions.d.ts +17 -2
  310. package/dist/hooks/tasks/useTaskFormActions.js +309 -55
  311. package/dist/hooks/tasks/useTaskReferenceContract.d.ts +5 -0
  312. package/dist/hooks/tasks/useTaskReferenceContract.js +17 -0
  313. package/dist/hooks/tasks/useTaskRelationships.d.ts +1 -3
  314. package/dist/hooks/tasks/useTaskRelationships.js +5 -25
  315. package/dist/hooks/tasks/useTrashSelection.d.ts +12 -0
  316. package/dist/hooks/tasks/useTrashSelection.js +49 -0
  317. package/dist/hooks/ui/useInitiativeTemplates.d.ts +24 -0
  318. package/dist/hooks/ui/useInitiativeTemplates.js +22 -0
  319. package/dist/hooks/ui/useSettingsModel.d.ts +5 -29
  320. package/dist/hooks/ui/useSettingsModel.js +31 -15
  321. package/dist/hooks/ui/useSettingsPersistence.d.ts +0 -1
  322. package/dist/hooks/ui/useSettingsPersistence.js +4 -8
  323. package/dist/hooks/ui/useSettingsTaxonomyManagement.js +31 -0
  324. package/dist/hooks/useFilterSort.d.ts +2 -2
  325. package/dist/hooks/useFilterSort.js +19 -15
  326. package/dist/hooks/useRealtimeSync.d.ts +10 -0
  327. package/dist/hooks/useRealtimeSync.js +57 -4
  328. package/dist/hooks/useSyncOrchestrator.d.ts +32 -1
  329. package/dist/hooks/useSyncOrchestrator.js +963 -287
  330. package/dist/hooks/useTaskData.d.ts +11 -2
  331. package/dist/hooks/useTaskData.js +59 -26
  332. package/dist/hooks/useTaskMutations.d.ts +42 -5
  333. package/dist/hooks/useTaskMutations.js +750 -125
  334. package/dist/hooks/useTaskforce.d.ts +114 -118
  335. package/dist/hooks/useTaskforce.js +1106 -396
  336. package/dist/hooks/useUiNotice.d.ts +5 -1
  337. package/dist/hooks/useUiNotice.js +13 -2
  338. package/dist/hooks/useWorkspaceSyncController.d.ts +9 -0
  339. package/dist/hooks/useWorkspaceSyncController.js +159 -17
  340. package/dist/hooks/workspace/usePersistedAppUiState.d.ts +74 -0
  341. package/dist/hooks/workspace/usePersistedAppUiState.js +325 -0
  342. package/dist/hooks/workspace/usePersistedLayoutUiState.d.ts +76 -0
  343. package/dist/hooks/workspace/usePersistedLayoutUiState.js +479 -0
  344. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +2 -7
  345. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +42 -31
  346. package/dist/hooks/workspace/workspaceLocalState.d.ts +42 -6
  347. package/dist/hooks/workspace/workspaceLocalState.js +213 -5
  348. package/dist/hooks/workstreams/workstreamHttpMutation.d.ts +23 -0
  349. package/dist/hooks/workstreams/workstreamHttpMutation.js +134 -0
  350. package/dist/localization/locales/en-US.d.ts +3 -3
  351. package/dist/localization/locales/en-US.js +3 -3
  352. package/dist/localization/locales/es-419.js +3 -3
  353. package/dist/localization/locales/pt-BR.js +3 -3
  354. package/dist/mcp/adminWorkspaceRegistrar.js +2 -40
  355. package/dist/mcp/aiProfileBootstrap.d.ts +3 -0
  356. package/dist/mcp/aiProfileBootstrap.js +4 -0
  357. package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
  358. package/dist/mcp/canonicalAssetHelpers.js +104 -35
  359. package/dist/mcp/clientIntegrations.d.ts +4 -2
  360. package/dist/mcp/clientIntegrations.js +104 -53
  361. package/dist/mcp/clientRegistry.d.ts +30 -0
  362. package/dist/mcp/clientRegistry.js +134 -0
  363. package/dist/mcp/collaborationRegistrar.js +21 -7
  364. package/dist/mcp/documentAssetRegistrar.js +227 -107
  365. package/dist/mcp/documentContentCommand.d.ts +94 -0
  366. package/dist/mcp/documentContentCommand.js +226 -0
  367. package/dist/mcp/documentHelpers.d.ts +14 -59
  368. package/dist/mcp/documentHelpers.js +52 -61
  369. package/dist/mcp/durableTaskMutationRouter.d.ts +65 -0
  370. package/dist/mcp/durableTaskMutationRouter.js +217 -0
  371. package/dist/mcp/durableTaskRelationshipMutationRouter.d.ts +38 -0
  372. package/dist/mcp/durableTaskRelationshipMutationRouter.js +168 -0
  373. package/dist/mcp/durableTaskRootMutationRouter.d.ts +64 -0
  374. package/dist/mcp/durableTaskRootMutationRouter.js +226 -0
  375. package/dist/mcp/gitWorktreeRoots.d.ts +2 -0
  376. package/dist/mcp/gitWorktreeRoots.js +19 -0
  377. package/dist/mcp/legacyServer.d.ts +1 -0
  378. package/dist/mcp/legacyServer.js +42 -0
  379. package/dist/mcp/localCliHealth.d.ts +56 -0
  380. package/dist/mcp/localCliHealth.js +170 -0
  381. package/dist/mcp/localServiceProxy.d.ts +23 -0
  382. package/dist/mcp/localServiceProxy.js +255 -0
  383. package/dist/mcp/mcpInputValidator.d.ts +17 -0
  384. package/dist/mcp/mcpInputValidator.js +58 -0
  385. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +127 -0
  386. package/dist/mcp/planningAttachmentCommandAdapter.js +188 -0
  387. package/dist/mcp/programScaffoldCommandAdapter.d.ts +6 -0
  388. package/dist/mcp/programScaffoldCommandAdapter.js +39 -0
  389. package/dist/mcp/proxyServer.d.ts +1 -0
  390. package/dist/mcp/proxyServer.js +2 -0
  391. package/dist/mcp/runtime.d.ts +86 -1
  392. package/dist/mcp/runtime.js +4562 -2270
  393. package/dist/mcp/server.js +29 -2
  394. package/dist/mcp/sharedLocalServiceGateD.d.ts +115 -0
  395. package/dist/mcp/sharedLocalServiceGateD.js +344 -0
  396. package/dist/mcp/stdioLifecycle.d.ts +22 -0
  397. package/dist/mcp/stdioLifecycle.js +54 -0
  398. package/dist/mcp/taskAttachmentCommandAdapter.d.ts +190 -0
  399. package/dist/mcp/taskAttachmentCommandAdapter.js +464 -0
  400. package/dist/mcp/taskAttachmentHelpers.d.ts +8 -6
  401. package/dist/mcp/taskAttachmentHelpers.js +74 -2
  402. package/dist/mcp/taskAttachmentTypes.d.ts +26 -5
  403. package/dist/mcp/taskPlanCommand.d.ts +64 -0
  404. package/dist/mcp/taskPlanCommand.js +98 -0
  405. package/dist/mcp/taskPlanningRegistrar.js +253 -101
  406. package/dist/mcp/toolCallCompatibility.d.ts +6 -0
  407. package/dist/mcp/toolCallCompatibility.js +16 -0
  408. package/dist/mcp/toolCatalog.d.ts +3 -1
  409. package/dist/mcp/toolProfiles.d.ts +18 -0
  410. package/dist/mcp/toolProfiles.js +79 -0
  411. package/dist/mcp/toolRegistry.d.ts +102 -609
  412. package/dist/mcp/toolRegistry.js +108 -88
  413. package/dist/mcp/workflowExecutionRegistrar.d.ts +2 -0
  414. package/dist/mcp/workflowExecutionRegistrar.js +51 -0
  415. package/dist/migrations/taskSchemaMigrations.d.ts +35 -0
  416. package/dist/migrations/taskSchemaMigrations.js +1797 -4
  417. package/dist/migrations/taskUpdatedAtSyncDriftMigration.d.ts +20 -0
  418. package/dist/migrations/taskUpdatedAtSyncDriftMigration.js +153 -0
  419. package/dist/migrations/taskforceAgentDefinitionMigration.d.ts +26 -0
  420. package/dist/migrations/taskforceAgentDefinitionMigration.js +116 -0
  421. package/dist/plugins/vite.js +48 -17
  422. package/dist/public/Taskforce_Van.webp +0 -0
  423. package/dist/runtime/appGateDefinitions.d.ts +16 -10
  424. package/dist/runtime/appGateDefinitions.js +16 -10
  425. package/dist/runtime/appGates.d.ts +5 -4
  426. package/dist/runtime/appGates.js +4 -3
  427. package/dist/server/aiProfileAvatarAssets.d.ts +11 -8
  428. package/dist/server/aiProfileAvatarAssets.js +159 -70
  429. package/dist/server/auth.js +15 -1
  430. package/dist/server/cors.d.ts +2 -1
  431. package/dist/server/cors.js +45 -8
  432. package/dist/server/email.d.ts +3 -1
  433. package/dist/server/email.js +46 -8
  434. package/dist/server/index.d.ts +24 -1
  435. package/dist/server/index.js +342 -46
  436. package/dist/server/localDataOwnerPermit.d.ts +18 -0
  437. package/dist/server/localDataOwnerPermit.js +58 -0
  438. package/dist/server/localDatabaseIdentity.d.ts +14 -0
  439. package/dist/server/localDatabaseIdentity.js +69 -0
  440. package/dist/server/localRealtimeFileInvalidation.d.ts +1 -0
  441. package/dist/server/localRealtimeFileInvalidation.js +7 -0
  442. package/dist/server/localServiceLease.d.ts +62 -0
  443. package/dist/server/localServiceLease.js +477 -0
  444. package/dist/server/localServiceOwnershipBootstrap.d.ts +19 -0
  445. package/dist/server/localServiceOwnershipBootstrap.js +84 -0
  446. package/dist/server/localServiceSessions.d.ts +87 -0
  447. package/dist/server/localServiceSessions.js +309 -0
  448. package/dist/server/localServiceWindowsAcl.d.ts +8 -0
  449. package/dist/server/localServiceWindowsAcl.js +60 -0
  450. package/dist/server/localSyncProcessLockBootstrap.d.ts +3 -0
  451. package/dist/server/localSyncProcessLockBootstrap.js +16 -0
  452. package/dist/server/localWorkspaceSyncServerComposition.d.ts +59 -0
  453. package/dist/server/localWorkspaceSyncServerComposition.js +91 -0
  454. package/dist/server/localWorkspaceSyncServerRuntime.d.ts +119 -0
  455. package/dist/server/localWorkspaceSyncServerRuntime.js +1163 -0
  456. package/dist/server/rateLimit.d.ts +1 -0
  457. package/dist/server/rateLimit.js +16 -0
  458. package/dist/server/routes/admin.d.ts +2 -4
  459. package/dist/server/routes/admin.js +199 -337
  460. package/dist/server/routes/agentRoles.d.ts +13 -0
  461. package/dist/server/routes/agentRoles.js +273 -0
  462. package/dist/server/routes/agentSkills.d.ts +16 -0
  463. package/dist/server/routes/agentSkills.js +291 -0
  464. package/dist/server/routes/agents.d.ts +49 -0
  465. package/dist/server/routes/agents.js +1455 -0
  466. package/dist/server/routes/annotatedAttachments.js +46 -9
  467. package/dist/server/routes/assetAccess.d.ts +36 -0
  468. package/dist/server/routes/assetAccess.js +93 -0
  469. package/dist/server/routes/auth.d.ts +4 -3
  470. package/dist/server/routes/auth.js +236 -21
  471. package/dist/server/routes/authSupport.d.ts +3 -1
  472. package/dist/server/routes/authSupport.js +22 -8
  473. package/dist/server/routes/documentReviews.d.ts +2 -0
  474. package/dist/server/routes/documentReviews.js +155 -15
  475. package/dist/server/routes/documents.d.ts +1 -0
  476. package/dist/server/routes/documents.js +335 -141
  477. package/dist/server/routes/durableTaskHttpRouters.d.ts +165 -0
  478. package/dist/server/routes/durableTaskHttpRouters.js +89 -0
  479. package/dist/server/routes/localMcpHealth.d.ts +11 -0
  480. package/dist/server/routes/localMcpHealth.js +29 -0
  481. package/dist/server/routes/localService.d.ts +13 -0
  482. package/dist/server/routes/localService.js +444 -0
  483. package/dist/server/routes/localUpdate.d.ts +11 -0
  484. package/dist/server/routes/localUpdate.js +154 -0
  485. package/dist/server/routes/primitives.d.ts +27 -0
  486. package/dist/server/routes/primitives.js +18 -0
  487. package/dist/server/routes/resources.d.ts +1 -10
  488. package/dist/server/routes/resources.js +1 -153
  489. package/dist/server/routes/shared.d.ts +31 -2
  490. package/dist/server/routes/shared.js +394 -0
  491. package/dist/server/routes/sync.d.ts +2 -0
  492. package/dist/server/routes/sync.js +184 -272
  493. package/dist/server/routes/syncAuxRoutes.d.ts +3 -1
  494. package/dist/server/routes/syncAuxRoutes.js +9 -4
  495. package/dist/server/routes/syncCoordinatorLocalRoutes.d.ts +6 -0
  496. package/dist/server/routes/syncCoordinatorLocalRoutes.js +867 -0
  497. package/dist/server/routes/syncPullApplyRoutes.d.ts +29 -1
  498. package/dist/server/routes/syncPullApplyRoutes.js +520 -17
  499. package/dist/server/routes/syncPushRoutes.d.ts +33 -4
  500. package/dist/server/routes/syncPushRoutes.js +251 -62
  501. package/dist/server/routes/syncRouteTypes.d.ts +1 -1
  502. package/dist/server/routes/syncSnapshotRoutes.d.ts +15 -7
  503. package/dist/server/routes/syncSnapshotRoutes.js +95 -17
  504. package/dist/server/routes/syncV3DiagnosticsRoutes.d.ts +14 -0
  505. package/dist/server/routes/syncV3DiagnosticsRoutes.js +72 -0
  506. package/dist/server/routes/syncV3FeedRoutes.d.ts +20 -0
  507. package/dist/server/routes/syncV3FeedRoutes.js +462 -0
  508. package/dist/server/routes/syncV3LocalCaptureRoutes.d.ts +37 -0
  509. package/dist/server/routes/syncV3LocalCaptureRoutes.js +897 -0
  510. package/dist/server/routes/syncV3LocalDispatchRoutes.d.ts +17 -0
  511. package/dist/server/routes/syncV3LocalDispatchRoutes.js +280 -0
  512. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +17 -0
  513. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +493 -0
  514. package/dist/server/routes/syncV3LocalOwnershipRoutes.d.ts +10 -0
  515. package/dist/server/routes/syncV3LocalOwnershipRoutes.js +51 -0
  516. package/dist/server/routes/syncV3LocalRecoveryRoutes.d.ts +12 -0
  517. package/dist/server/routes/syncV3LocalRecoveryRoutes.js +78 -0
  518. package/dist/server/routes/syncV3OperationRoutes.d.ts +35 -0
  519. package/dist/server/routes/syncV3OperationRoutes.js +1136 -0
  520. package/dist/server/routes/tasks.d.ts +0 -2
  521. package/dist/server/routes/tasks.js +932 -195
  522. package/dist/server/routes/workflows.d.ts +26 -0
  523. package/dist/server/routes/workflows.js +500 -0
  524. package/dist/server/routes.d.ts +1 -6
  525. package/dist/server/routes.js +148 -339
  526. package/dist/server/smtpTransport.d.ts +11 -3
  527. package/dist/server/smtpTransport.js +9 -2
  528. package/dist/server/start.js +42 -10
  529. package/dist/service/localServiceCli.d.ts +33 -0
  530. package/dist/service/localServiceCli.js +365 -0
  531. package/dist/service/localServiceClientLifecycle.d.ts +25 -0
  532. package/dist/service/localServiceClientLifecycle.js +128 -0
  533. package/dist/service/localServiceOpen.d.ts +17 -0
  534. package/dist/service/localServiceOpen.js +27 -0
  535. package/dist/services/agentRoleResolver.d.ts +4 -0
  536. package/dist/services/agentRoleResolver.js +7 -0
  537. package/dist/services/aiProfileAvatarGenerationService.d.ts +41 -0
  538. package/dist/services/aiProfileAvatarGenerationService.js +158 -0
  539. package/dist/services/avatarImageProvider.d.ts +33 -0
  540. package/dist/services/avatarImageProvider.js +140 -0
  541. package/dist/services/bedrockAnthropicMessagesModelGateway.d.ts +24 -0
  542. package/dist/services/bedrockAnthropicMessagesModelGateway.js +95 -0
  543. package/dist/services/bedrockMantleModelGateway.d.ts +43 -0
  544. package/dist/services/bedrockMantleModelGateway.js +81 -0
  545. package/dist/services/bedrockModelGateway.d.ts +26 -0
  546. package/dist/services/bedrockModelGateway.js +94 -0
  547. package/dist/services/modelGateway.d.ts +82 -0
  548. package/dist/services/modelGateway.js +61 -0
  549. package/dist/services/taskforceAgentAvatarImageProvider.d.ts +8 -0
  550. package/dist/services/taskforceAgentAvatarImageProvider.js +24 -0
  551. package/dist/services/taskforceAgentMcpBridge.d.ts +77 -0
  552. package/dist/services/taskforceAgentMcpBridge.js +527 -0
  553. package/dist/shared/agentRoleDefinition.d.ts +34 -0
  554. package/dist/shared/agentRoleDefinition.js +207 -0
  555. package/dist/shared/aiProfileAvatarEligibility.d.ts +10 -0
  556. package/dist/shared/aiProfileAvatarEligibility.js +27 -0
  557. package/dist/shared/aiProfileColors.d.ts +7 -0
  558. package/dist/shared/aiProfileColors.js +33 -0
  559. package/dist/shared/colorPalette.d.ts +3 -0
  560. package/dist/shared/colorPalette.js +20 -0
  561. package/dist/shared/commentProvenance.d.ts +4 -0
  562. package/dist/shared/commentProvenance.js +6 -0
  563. package/dist/shared/deletedTaskRetention.d.ts +2 -0
  564. package/dist/shared/deletedTaskRetention.js +7 -0
  565. package/dist/shared/passwordPolicy.d.ts +2 -1
  566. package/dist/shared/passwordPolicy.js +9 -0
  567. package/dist/shared/taskDeepLinks.d.ts +28 -0
  568. package/dist/shared/taskDeepLinks.js +48 -0
  569. package/dist/shared/taskRestoreDestination.d.ts +2 -0
  570. package/dist/shared/taskRestoreDestination.js +5 -0
  571. package/dist/shared/taskforceAgentDefinition.d.ts +88 -0
  572. package/dist/shared/taskforceAgentDefinition.js +434 -0
  573. package/dist/shared/taskforceAgentExecutionSnapshot.d.ts +50 -0
  574. package/dist/shared/taskforceAgentExecutionSnapshot.js +68 -0
  575. package/dist/shared/taskforceAgentModels.d.ts +56 -0
  576. package/dist/shared/taskforceAgentModels.js +314 -0
  577. package/dist/shared/taskforceAgentRunContext.d.ts +23 -0
  578. package/dist/shared/taskforceAgentRunContext.js +21 -0
  579. package/dist/shared/taskforceAgentRuntimeResolution.d.ts +31 -0
  580. package/dist/shared/taskforceAgentRuntimeResolution.js +72 -0
  581. package/dist/shared/taskforceAgentSkill.d.ts +33 -0
  582. package/dist/shared/taskforceAgentSkill.js +149 -0
  583. package/dist/shared/taxonomyLibrary.js +1 -1
  584. package/dist/storage/agentRoleStore.d.ts +91 -0
  585. package/dist/storage/agentRoleStore.js +385 -0
  586. package/dist/storage/databaseAdapter.d.ts +1 -0
  587. package/dist/storage/databaseAdapter.js +7 -1
  588. package/dist/storage/documentIntegrity.d.ts +12 -3
  589. package/dist/storage/documentIntegrity.js +105 -27
  590. package/dist/storage/objectStorageClient.d.ts +10 -4
  591. package/dist/storage/objectStorageClient.js +73 -43
  592. package/dist/storage/postgresAdapter.d.ts +2 -1
  593. package/dist/storage/postgresAdapter.js +38 -6
  594. package/dist/storage/postgresWorker.js +65 -1
  595. package/dist/storage/sqliteAdapter.d.ts +1 -1
  596. package/dist/storage/sqliteAdapter.js +7 -1
  597. package/dist/storage/sqliteWalHealth.d.ts +71 -0
  598. package/dist/storage/sqliteWalHealth.js +176 -0
  599. package/dist/storage/taskDataPath.d.ts +1 -0
  600. package/dist/storage/taskDataPath.js +20 -0
  601. package/dist/storage/taskforceAgentConversationStore.d.ts +66 -0
  602. package/dist/storage/taskforceAgentConversationStore.js +264 -0
  603. package/dist/storage/taskforceAgentSkillStore.d.ts +93 -0
  604. package/dist/storage/taskforceAgentSkillStore.js +355 -0
  605. package/dist/storage/taskforceAgentStore.d.ts +105 -0
  606. package/dist/storage/taskforceAgentStore.js +549 -0
  607. package/dist/storage/workflowStore.d.ts +223 -0
  608. package/dist/storage/workflowStore.js +1032 -0
  609. package/dist/storage/workspaceAssetStore.d.ts +70 -0
  610. package/dist/storage/workspaceAssetStore.js +418 -25
  611. package/dist/sync/aiProfileAvatarSyncPaths.d.ts +14 -0
  612. package/dist/sync/aiProfileAvatarSyncPaths.js +56 -0
  613. package/dist/sync/cloudSyncApi.d.ts +329 -0
  614. package/dist/sync/cloudSyncApi.js +596 -4
  615. package/dist/sync/collaborationSyncPayload.d.ts +5 -1
  616. package/dist/sync/collaborationSyncPayload.js +213 -1
  617. package/dist/sync/collaborationSyncState.d.ts +23 -3
  618. package/dist/sync/collaborationSyncState.js +92 -3
  619. package/dist/sync/contentSyncPayload.d.ts +9 -0
  620. package/dist/sync/contentSyncPayload.js +29 -0
  621. package/dist/sync/contentSyncState.d.ts +79 -4
  622. package/dist/sync/contentSyncState.js +1113 -313
  623. package/dist/sync/coordinator/localSyncBrowserApplyPermitContext.d.ts +39 -0
  624. package/dist/sync/coordinator/localSyncBrowserApplyPermitContext.js +234 -0
  625. package/dist/sync/coordinator/localSyncBrowserAuthorityCapability.d.ts +7 -0
  626. package/dist/sync/coordinator/localSyncBrowserAuthorityCapability.js +10 -0
  627. package/dist/sync/coordinator/localSyncCommittedApplyPolicy.d.ts +7 -0
  628. package/dist/sync/coordinator/localSyncCommittedApplyPolicy.js +41 -0
  629. package/dist/sync/coordinator/localSyncCoordinatorBrowserClient.d.ts +178 -0
  630. package/dist/sync/coordinator/localSyncCoordinatorBrowserClient.js +131 -0
  631. package/dist/sync/coordinator/localSyncCoordinatorCommandLifecycle.d.ts +25 -0
  632. package/dist/sync/coordinator/localSyncCoordinatorCommandLifecycle.js +200 -0
  633. package/dist/sync/coordinator/localSyncCoordinatorHost.d.ts +84 -0
  634. package/dist/sync/coordinator/localSyncCoordinatorHost.js +435 -0
  635. package/dist/sync/coordinator/localSyncCoordinatorRouteServices.d.ts +33 -0
  636. package/dist/sync/coordinator/localSyncCoordinatorRouteServices.js +1 -0
  637. package/dist/sync/coordinator/localSyncCoordinatorStore.d.ts +122 -0
  638. package/dist/sync/coordinator/localSyncCoordinatorStore.js +1039 -0
  639. package/dist/sync/coordinator/localSyncCoordinatorTypes.d.ts +82 -0
  640. package/dist/sync/coordinator/localSyncCoordinatorTypes.js +9 -0
  641. package/dist/sync/coordinator/localSyncDispatchTracker.d.ts +15 -0
  642. package/dist/sync/coordinator/localSyncDispatchTracker.js +68 -0
  643. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +200 -0
  644. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +1388 -0
  645. package/dist/sync/coordinator/localSyncExecutionPermitTypes.d.ts +52 -0
  646. package/dist/sync/coordinator/localSyncExecutionPermitTypes.js +8 -0
  647. package/dist/sync/coordinator/localSyncOwnershipDrainBarrier.d.ts +33 -0
  648. package/dist/sync/coordinator/localSyncOwnershipDrainBarrier.js +83 -0
  649. package/dist/sync/coordinator/localSyncPermitTransactionHooks.d.ts +9 -0
  650. package/dist/sync/coordinator/localSyncPermitTransactionHooks.js +27 -0
  651. package/dist/sync/coordinator/localSyncProcessLock.d.ts +12 -0
  652. package/dist/sync/coordinator/localSyncProcessLock.js +212 -0
  653. package/dist/sync/coordinator/localSyncV3DispatchRecoveryReconciler.d.ts +17 -0
  654. package/dist/sync/coordinator/localSyncV3DispatchRecoveryReconciler.js +82 -0
  655. package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +134 -0
  656. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +981 -0
  657. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +189 -0
  658. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +961 -0
  659. package/dist/sync/coordinator/workspaceSyncCloudCredentialValidator.d.ts +19 -0
  660. package/dist/sync/coordinator/workspaceSyncCloudCredentialValidator.js +83 -0
  661. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +117 -0
  662. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +323 -0
  663. package/dist/sync/coordinator/workspaceSyncLocalAccessBootstrap.d.ts +11 -0
  664. package/dist/sync/coordinator/workspaceSyncLocalAccessBootstrap.js +51 -0
  665. package/dist/sync/coordinator/workspaceSyncTransportGateway.d.ts +139 -0
  666. package/dist/sync/coordinator/workspaceSyncTransportGateway.js +738 -0
  667. package/dist/sync/engine/localWorkspaceContentManifestService.d.ts +21 -0
  668. package/dist/sync/engine/localWorkspaceContentManifestService.js +44 -0
  669. package/dist/sync/engine/workspaceSyncAtomicLocalPublisher.d.ts +36 -0
  670. package/dist/sync/engine/workspaceSyncAtomicLocalPublisher.js +203 -0
  671. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +21 -0
  672. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.js +13 -0
  673. package/dist/sync/engine/workspaceSyncContentPullObligationStore.d.ts +65 -0
  674. package/dist/sync/engine/workspaceSyncContentPullObligationStore.js +160 -0
  675. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +216 -0
  676. package/dist/sync/engine/workspaceSyncContentVersionStore.js +1068 -0
  677. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.d.ts +28 -0
  678. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +543 -0
  679. package/dist/sync/engine/workspaceSyncEngineContracts.d.ts +78 -0
  680. package/dist/sync/engine/workspaceSyncEngineContracts.js +1 -0
  681. package/dist/sync/engine/workspaceSyncEngineControlPlane.d.ts +37 -0
  682. package/dist/sync/engine/workspaceSyncEngineControlPlane.js +79 -0
  683. package/dist/sync/engine/workspaceSyncEngineIdentity.d.ts +1 -0
  684. package/dist/sync/engine/workspaceSyncEngineIdentity.js +4 -0
  685. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.d.ts +68 -0
  686. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +180 -0
  687. package/dist/sync/engine/workspaceSyncEngineLocalApply.d.ts +72 -0
  688. package/dist/sync/engine/workspaceSyncEngineLocalApply.js +132 -0
  689. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +70 -0
  690. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +25 -0
  691. package/dist/sync/engine/workspaceSyncEngineParity.d.ts +8 -0
  692. package/dist/sync/engine/workspaceSyncEngineParity.js +7 -0
  693. package/dist/sync/engine/workspaceSyncEnginePullPolicy.d.ts +32 -0
  694. package/dist/sync/engine/workspaceSyncEnginePullPolicy.js +27 -0
  695. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +20 -0
  696. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +87 -0
  697. package/dist/sync/engine/workspaceSyncEngineRecovery.d.ts +56 -0
  698. package/dist/sync/engine/workspaceSyncEngineRecovery.js +288 -0
  699. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +104 -0
  700. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +21 -0
  701. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +61 -0
  702. package/dist/sync/engine/workspaceSyncEngineRuntime.js +59 -0
  703. package/dist/sync/engine/workspaceSyncEngineServerApplyBoundary.d.ts +28 -0
  704. package/dist/sync/engine/workspaceSyncEngineServerApplyBoundary.js +86 -0
  705. package/dist/sync/engine/workspaceSyncEngineServerLocalServices.d.ts +73 -0
  706. package/dist/sync/engine/workspaceSyncEngineServerLocalServices.js +452 -0
  707. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +23 -0
  708. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +451 -0
  709. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +125 -0
  710. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +1124 -0
  711. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.d.ts +63 -0
  712. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +276 -0
  713. package/dist/sync/engine/workspaceSyncEngineTransferCompletion.d.ts +20 -0
  714. package/dist/sync/engine/workspaceSyncEngineTransferCompletion.js +37 -0
  715. package/dist/sync/engine/workspaceSyncEngineTransferTypes.d.ts +7 -0
  716. package/dist/sync/engine/workspaceSyncEngineTransferTypes.js +1 -0
  717. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +240 -0
  718. package/dist/sync/engine/workspaceSyncEngineTransfers.js +1184 -0
  719. package/dist/sync/engine/workspaceSyncEngineV3LocalFeedApply.d.ts +39 -0
  720. package/dist/sync/engine/workspaceSyncEngineV3LocalFeedApply.js +39 -0
  721. package/dist/sync/engine/workspaceSyncImmutableContentGcRunner.d.ts +25 -0
  722. package/dist/sync/engine/workspaceSyncImmutableContentGcRunner.js +83 -0
  723. package/dist/sync/engine/workspaceSyncImmutableContentProvider.d.ts +71 -0
  724. package/dist/sync/engine/workspaceSyncImmutableContentProvider.js +209 -0
  725. package/dist/sync/engine/workspaceSyncImmutableContentStager.d.ts +32 -0
  726. package/dist/sync/engine/workspaceSyncImmutableContentStager.js +202 -0
  727. package/dist/sync/engine/workspaceSyncPublishedContentResolver.d.ts +43 -0
  728. package/dist/sync/engine/workspaceSyncPublishedContentResolver.js +142 -0
  729. package/dist/sync/engine/workspaceSyncServerContentRuntime.d.ts +26 -0
  730. package/dist/sync/engine/workspaceSyncServerContentRuntime.js +41 -0
  731. package/dist/sync/engine/workspaceSyncServerDataServices.d.ts +44 -0
  732. package/dist/sync/engine/workspaceSyncServerDataServices.js +143 -0
  733. package/dist/sync/engine/workspaceSyncTransferEvidence.d.ts +39 -0
  734. package/dist/sync/engine/workspaceSyncTransferEvidence.js +45 -0
  735. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +44 -0
  736. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +990 -0
  737. package/dist/sync/engine/workspaceSyncV2PreparedContent.d.ts +82 -0
  738. package/dist/sync/engine/workspaceSyncV2PreparedContent.js +219 -0
  739. package/dist/sync/planningCanonicalFields.d.ts +41 -0
  740. package/dist/sync/planningCanonicalFields.js +211 -0
  741. package/dist/sync/planningSyncPayload.d.ts +5 -1
  742. package/dist/sync/planningSyncPayload.js +88 -4
  743. package/dist/sync/syncApplyHandlers.d.ts +98 -8
  744. package/dist/sync/syncApplyHandlers.js +816 -78
  745. package/dist/sync/syncResourceAdapters.d.ts +10 -0
  746. package/dist/sync/syncResourceAdapters.js +21 -1
  747. package/dist/sync/syncService.d.ts +57 -1
  748. package/dist/sync/syncService.js +1085 -138
  749. package/dist/sync/taskNestedContent.d.ts +2 -0
  750. package/dist/sync/taskNestedContent.js +8 -0
  751. package/dist/sync/taskSyncChangeKey.js +0 -1
  752. package/dist/sync/taskSyncPayload.d.ts +0 -1
  753. package/dist/sync/taskSyncPayload.js +14 -3
  754. package/dist/sync/v3/canonicalWorkspaceSyncJson.d.ts +2 -0
  755. package/dist/sync/v3/canonicalWorkspaceSyncJson.js +26 -0
  756. package/dist/sync/v3/combinedFeedCapability.d.ts +21 -0
  757. package/dist/sync/v3/combinedFeedCapability.js +80 -0
  758. package/dist/sync/v3/combinedFeedPrerequisites.d.ts +18 -0
  759. package/dist/sync/v3/combinedFeedPrerequisites.js +184 -0
  760. package/dist/sync/v3/durableInitiativeMutationRouter.d.ts +61 -0
  761. package/dist/sync/v3/durableInitiativeMutationRouter.js +287 -0
  762. package/dist/sync/v3/durableOperationReplay.d.ts +36 -0
  763. package/dist/sync/v3/durableOperationReplay.js +103 -0
  764. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +49 -0
  765. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +198 -0
  766. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +47 -0
  767. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +182 -0
  768. package/dist/sync/v3/durableTaskCommentMutationRouter.d.ts +47 -0
  769. package/dist/sync/v3/durableTaskCommentMutationRouter.js +191 -0
  770. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +60 -0
  771. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +320 -0
  772. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +40 -0
  773. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +518 -0
  774. package/dist/sync/v3/durableTaxonomyMutationRouter.d.ts +63 -0
  775. package/dist/sync/v3/durableTaxonomyMutationRouter.js +289 -0
  776. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +77 -0
  777. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +361 -0
  778. package/dist/sync/v3/durableWorkstreamMutationRouter.d.ts +61 -0
  779. package/dist/sync/v3/durableWorkstreamMutationRouter.js +287 -0
  780. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.d.ts +42 -0
  781. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +122 -0
  782. package/dist/sync/v3/entityEventLegacyAdoptionContract.d.ts +6 -0
  783. package/dist/sync/v3/entityEventLegacyAdoptionContract.js +6 -0
  784. package/dist/sync/v3/entityEventLegacyAdoptionService.d.ts +62 -0
  785. package/dist/sync/v3/entityEventLegacyAdoptionService.js +180 -0
  786. package/dist/sync/v3/initiativeActivityAuthoritativeRevision.d.ts +11 -0
  787. package/dist/sync/v3/initiativeActivityAuthoritativeRevision.js +23 -0
  788. package/dist/sync/v3/initiativeActivityIdentity.d.ts +8 -0
  789. package/dist/sync/v3/initiativeActivityIdentity.js +14 -0
  790. package/dist/sync/v3/initiativeCoexistence.d.ts +26 -0
  791. package/dist/sync/v3/initiativeCoexistence.js +148 -0
  792. package/dist/sync/v3/initiativeFeedActivationCapability.d.ts +6 -0
  793. package/dist/sync/v3/initiativeFeedActivationCapability.js +16 -0
  794. package/dist/sync/v3/initiativeMutationPayload.d.ts +26 -0
  795. package/dist/sync/v3/initiativeMutationPayload.js +144 -0
  796. package/dist/sync/v3/initiativeMutationService.d.ts +62 -0
  797. package/dist/sync/v3/initiativeMutationService.js +206 -0
  798. package/dist/sync/v3/localEntityEventLegacyAdoption.d.ts +31 -0
  799. package/dist/sync/v3/localEntityEventLegacyAdoption.js +607 -0
  800. package/dist/sync/v3/localInitiativeOutboxHandler.d.ts +8 -0
  801. package/dist/sync/v3/localInitiativeOutboxHandler.js +88 -0
  802. package/dist/sync/v3/localInitiativeOutboxService.d.ts +50 -0
  803. package/dist/sync/v3/localInitiativeOutboxService.js +495 -0
  804. package/dist/sync/v3/localOperationIdentityStore.d.ts +81 -0
  805. package/dist/sync/v3/localOperationIdentityStore.js +388 -0
  806. package/dist/sync/v3/localOutboxDispatchCapability.d.ts +7 -0
  807. package/dist/sync/v3/localOutboxDispatchCapability.js +13 -0
  808. package/dist/sync/v3/localOutboxDispatchRuntime.d.ts +16 -0
  809. package/dist/sync/v3/localOutboxDispatchRuntime.js +269 -0
  810. package/dist/sync/v3/localOutboxDispatcher.d.ts +53 -0
  811. package/dist/sync/v3/localOutboxDispatcher.js +362 -0
  812. package/dist/sync/v3/localOutboxDrainClient.d.ts +50 -0
  813. package/dist/sync/v3/localOutboxDrainClient.js +250 -0
  814. package/dist/sync/v3/localOutboxOperationHandler.d.ts +31 -0
  815. package/dist/sync/v3/localOutboxOperationHandler.js +10 -0
  816. package/dist/sync/v3/localOutboxRecoveryClient.d.ts +14 -0
  817. package/dist/sync/v3/localOutboxRecoveryClient.js +45 -0
  818. package/dist/sync/v3/localOutboxRecoveryPreparationService.d.ts +12 -0
  819. package/dist/sync/v3/localOutboxRecoveryPreparationService.js +151 -0
  820. package/dist/sync/v3/localSyncIdentityStore.d.ts +9 -0
  821. package/dist/sync/v3/localSyncIdentityStore.js +43 -0
  822. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.d.ts +10 -0
  823. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +70 -0
  824. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +45 -0
  825. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +291 -0
  826. package/dist/sync/v3/localTaskChecklistOutboxHandler.d.ts +10 -0
  827. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +54 -0
  828. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +47 -0
  829. package/dist/sync/v3/localTaskChecklistOutboxService.js +221 -0
  830. package/dist/sync/v3/localTaskCommentOutboxHandler.d.ts +10 -0
  831. package/dist/sync/v3/localTaskCommentOutboxHandler.js +94 -0
  832. package/dist/sync/v3/localTaskCommentOutboxService.d.ts +75 -0
  833. package/dist/sync/v3/localTaskCommentOutboxService.js +391 -0
  834. package/dist/sync/v3/localTaskCreateClient.d.ts +27 -0
  835. package/dist/sync/v3/localTaskCreateClient.js +209 -0
  836. package/dist/sync/v3/localTaskCreateOutboxHandler.d.ts +8 -0
  837. package/dist/sync/v3/localTaskCreateOutboxHandler.js +147 -0
  838. package/dist/sync/v3/localTaskCreateOutboxService.d.ts +77 -0
  839. package/dist/sync/v3/localTaskCreateOutboxService.js +397 -0
  840. package/dist/sync/v3/localTaskDeleteClient.d.ts +10 -0
  841. package/dist/sync/v3/localTaskDeleteClient.js +23 -0
  842. package/dist/sync/v3/localTaskDeleteOutboxHandler.d.ts +8 -0
  843. package/dist/sync/v3/localTaskDeleteOutboxHandler.js +54 -0
  844. package/dist/sync/v3/localTaskDeleteOutboxService.d.ts +38 -0
  845. package/dist/sync/v3/localTaskDeleteOutboxService.js +235 -0
  846. package/dist/sync/v3/localTaskLegacyRootAdoption.d.ts +28 -0
  847. package/dist/sync/v3/localTaskLegacyRootAdoption.js +219 -0
  848. package/dist/sync/v3/localTaskLifecycleClient.d.ts +49 -0
  849. package/dist/sync/v3/localTaskLifecycleClient.js +57 -0
  850. package/dist/sync/v3/localTaskLifecycleOutboxHandler.d.ts +8 -0
  851. package/dist/sync/v3/localTaskLifecycleOutboxHandler.js +94 -0
  852. package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +60 -0
  853. package/dist/sync/v3/localTaskLifecycleOutboxService.js +304 -0
  854. package/dist/sync/v3/localTaskMetadataClient.d.ts +13 -0
  855. package/dist/sync/v3/localTaskMetadataClient.js +30 -0
  856. package/dist/sync/v3/localTaskMetadataOutboxHandler.d.ts +8 -0
  857. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +70 -0
  858. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +48 -0
  859. package/dist/sync/v3/localTaskMetadataOutboxService.js +229 -0
  860. package/dist/sync/v3/localTaskOperationClient.d.ts +72 -0
  861. package/dist/sync/v3/localTaskOperationClient.js +195 -0
  862. package/dist/sync/v3/localTaskRelationshipOutboxHandler.d.ts +8 -0
  863. package/dist/sync/v3/localTaskRelationshipOutboxHandler.js +114 -0
  864. package/dist/sync/v3/localTaskRelationshipOutboxService.d.ts +45 -0
  865. package/dist/sync/v3/localTaskRelationshipOutboxService.js +192 -0
  866. package/dist/sync/v3/localTaskRestoreClient.d.ts +13 -0
  867. package/dist/sync/v3/localTaskRestoreClient.js +32 -0
  868. package/dist/sync/v3/localTaskRestoreOutboxHandler.d.ts +8 -0
  869. package/dist/sync/v3/localTaskRestoreOutboxHandler.js +41 -0
  870. package/dist/sync/v3/localTaskRestoreOutboxService.d.ts +56 -0
  871. package/dist/sync/v3/localTaskRestoreOutboxService.js +323 -0
  872. package/dist/sync/v3/localTaskStatusClient.d.ts +17 -0
  873. package/dist/sync/v3/localTaskStatusClient.js +35 -0
  874. package/dist/sync/v3/localTaskStatusOutboxHandler.d.ts +8 -0
  875. package/dist/sync/v3/localTaskStatusOutboxHandler.js +75 -0
  876. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +53 -0
  877. package/dist/sync/v3/localTaskStatusOutboxService.js +422 -0
  878. package/dist/sync/v3/localTaxonomyCompositeOutboxService.d.ts +34 -0
  879. package/dist/sync/v3/localTaxonomyCompositeOutboxService.js +290 -0
  880. package/dist/sync/v3/localTaxonomyOutboxHandler.d.ts +9 -0
  881. package/dist/sync/v3/localTaxonomyOutboxHandler.js +106 -0
  882. package/dist/sync/v3/localTaxonomyOutboxService.d.ts +30 -0
  883. package/dist/sync/v3/localTaxonomyOutboxService.js +181 -0
  884. package/dist/sync/v3/localWorkflowRuntimeOutboxHandler.d.ts +8 -0
  885. package/dist/sync/v3/localWorkflowRuntimeOutboxHandler.js +113 -0
  886. package/dist/sync/v3/localWorkflowRuntimeOutboxService.d.ts +37 -0
  887. package/dist/sync/v3/localWorkflowRuntimeOutboxService.js +330 -0
  888. package/dist/sync/v3/localWorkspaceSyncServerOutboxDispatcher.d.ts +63 -0
  889. package/dist/sync/v3/localWorkspaceSyncServerOutboxDispatcher.js +264 -0
  890. package/dist/sync/v3/localWorkstreamOutboxHandler.d.ts +8 -0
  891. package/dist/sync/v3/localWorkstreamOutboxHandler.js +102 -0
  892. package/dist/sync/v3/localWorkstreamOutboxService.d.ts +52 -0
  893. package/dist/sync/v3/localWorkstreamOutboxService.js +579 -0
  894. package/dist/sync/v3/localWorkstreamTaskOrderOutboxHandler.d.ts +10 -0
  895. package/dist/sync/v3/localWorkstreamTaskOrderOutboxHandler.js +57 -0
  896. package/dist/sync/v3/localWorkstreamTaskOrderOutboxService.d.ts +30 -0
  897. package/dist/sync/v3/localWorkstreamTaskOrderOutboxService.js +128 -0
  898. package/dist/sync/v3/planningActivation.d.ts +13 -0
  899. package/dist/sync/v3/planningActivation.js +33 -0
  900. package/dist/sync/v3/planningAttachmentActivityValidation.d.ts +9 -0
  901. package/dist/sync/v3/planningAttachmentActivityValidation.js +87 -0
  902. package/dist/sync/v3/programScaffoldService.d.ts +143 -0
  903. package/dist/sync/v3/programScaffoldService.js +478 -0
  904. package/dist/sync/v3/syncDurabilityStore.d.ts +773 -0
  905. package/dist/sync/v3/syncDurabilityStore.js +4635 -0
  906. package/dist/sync/v3/taskActivityAuthoritativeRevision.d.ts +16 -0
  907. package/dist/sync/v3/taskActivityAuthoritativeRevision.js +67 -0
  908. package/dist/sync/v3/taskActivityJournal.d.ts +20 -0
  909. package/dist/sync/v3/taskActivityJournal.js +195 -0
  910. package/dist/sync/v3/taskAttachmentLinksActivityIdentity.d.ts +6 -0
  911. package/dist/sync/v3/taskAttachmentLinksActivityIdentity.js +14 -0
  912. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +111 -0
  913. package/dist/sync/v3/taskAttachmentLinksMutationService.js +202 -0
  914. package/dist/sync/v3/taskChecklistActivityIdentity.d.ts +6 -0
  915. package/dist/sync/v3/taskChecklistActivityIdentity.js +14 -0
  916. package/dist/sync/v3/taskChecklistMutationService.d.ts +92 -0
  917. package/dist/sync/v3/taskChecklistMutationService.js +156 -0
  918. package/dist/sync/v3/taskCommentActivityIdentity.d.ts +7 -0
  919. package/dist/sync/v3/taskCommentActivityIdentity.js +15 -0
  920. package/dist/sync/v3/taskCommentMutationService.d.ts +150 -0
  921. package/dist/sync/v3/taskCommentMutationService.js +392 -0
  922. package/dist/sync/v3/taskCommentReconcileProvenance.d.ts +58 -0
  923. package/dist/sync/v3/taskCommentReconcileProvenance.js +170 -0
  924. package/dist/sync/v3/taskCreateActivation.d.ts +19 -0
  925. package/dist/sync/v3/taskCreateActivation.js +84 -0
  926. package/dist/sync/v3/taskCreateActivityIdentity.d.ts +7 -0
  927. package/dist/sync/v3/taskCreateActivityIdentity.js +18 -0
  928. package/dist/sync/v3/taskCreateMutationService.d.ts +103 -0
  929. package/dist/sync/v3/taskCreateMutationService.js +283 -0
  930. package/dist/sync/v3/taskDeleteActivation.d.ts +7 -0
  931. package/dist/sync/v3/taskDeleteActivation.js +14 -0
  932. package/dist/sync/v3/taskDeleteMutationService.d.ts +35 -0
  933. package/dist/sync/v3/taskDeleteMutationService.js +133 -0
  934. package/dist/sync/v3/taskLegacyRootAdoptionService.d.ts +78 -0
  935. package/dist/sync/v3/taskLegacyRootAdoptionService.js +175 -0
  936. package/dist/sync/v3/taskLifecycleActivityIdentity.d.ts +9 -0
  937. package/dist/sync/v3/taskLifecycleActivityIdentity.js +18 -0
  938. package/dist/sync/v3/taskLifecycleMutationPayload.d.ts +5 -0
  939. package/dist/sync/v3/taskLifecycleMutationPayload.js +28 -0
  940. package/dist/sync/v3/taskLifecycleMutationService.d.ts +66 -0
  941. package/dist/sync/v3/taskLifecycleMutationService.js +92 -0
  942. package/dist/sync/v3/taskMetadataActivation.d.ts +12 -0
  943. package/dist/sync/v3/taskMetadataActivation.js +38 -0
  944. package/dist/sync/v3/taskMetadataActivityIdentity.d.ts +7 -0
  945. package/dist/sync/v3/taskMetadataActivityIdentity.js +18 -0
  946. package/dist/sync/v3/taskMetadataCoexistence.d.ts +37 -0
  947. package/dist/sync/v3/taskMetadataCoexistence.js +134 -0
  948. package/dist/sync/v3/taskMetadataMutationService.d.ts +71 -0
  949. package/dist/sync/v3/taskMetadataMutationService.js +199 -0
  950. package/dist/sync/v3/taskRelationshipLegacyAdoptionService.d.ts +48 -0
  951. package/dist/sync/v3/taskRelationshipLegacyAdoptionService.js +164 -0
  952. package/dist/sync/v3/taskRelationshipMutationService.d.ts +50 -0
  953. package/dist/sync/v3/taskRelationshipMutationService.js +148 -0
  954. package/dist/sync/v3/taskRestoreMutationService.d.ts +90 -0
  955. package/dist/sync/v3/taskRestoreMutationService.js +179 -0
  956. package/dist/sync/v3/taskStatusActivation.d.ts +7 -0
  957. package/dist/sync/v3/taskStatusActivation.js +15 -0
  958. package/dist/sync/v3/taskStatusMutationService.d.ts +76 -0
  959. package/dist/sync/v3/taskStatusMutationService.js +308 -0
  960. package/dist/sync/v3/taskWorkflowMutationPayload.d.ts +4 -0
  961. package/dist/sync/v3/taskWorkflowMutationPayload.js +22 -0
  962. package/dist/sync/v3/taskWorkflowMutationService.d.ts +64 -0
  963. package/dist/sync/v3/taskWorkflowMutationService.js +102 -0
  964. package/dist/sync/v3/taxonomyCoexistence.d.ts +10 -0
  965. package/dist/sync/v3/taxonomyCoexistence.js +19 -0
  966. package/dist/sync/v3/taxonomyCompositeMutationService.d.ts +110 -0
  967. package/dist/sync/v3/taxonomyCompositeMutationService.js +304 -0
  968. package/dist/sync/v3/taxonomyMutationService.d.ts +57 -0
  969. package/dist/sync/v3/taxonomyMutationService.js +106 -0
  970. package/dist/sync/v3/taxonomyStateMutation.d.ts +22 -0
  971. package/dist/sync/v3/taxonomyStateMutation.js +49 -0
  972. package/dist/sync/v3/taxonomySyncPayload.d.ts +9 -0
  973. package/dist/sync/v3/taxonomySyncPayload.js +199 -0
  974. package/dist/sync/v3/workflowAssignmentSync.d.ts +22 -0
  975. package/dist/sync/v3/workflowAssignmentSync.js +213 -0
  976. package/dist/sync/v3/workflowRuntimeMutationService.d.ts +89 -0
  977. package/dist/sync/v3/workflowRuntimeMutationService.js +359 -0
  978. package/dist/sync/v3/workflowRuntimeOperationIdentity.d.ts +13 -0
  979. package/dist/sync/v3/workflowRuntimeOperationIdentity.js +35 -0
  980. package/dist/sync/v3/workflowRuntimeSync.d.ts +141 -0
  981. package/dist/sync/v3/workflowRuntimeSync.js +485 -0
  982. package/dist/sync/v3/workspaceSyncJournalReader.d.ts +43 -0
  983. package/dist/sync/v3/workspaceSyncJournalReader.js +45 -0
  984. package/dist/sync/v3/workspaceSyncLocalOwnershipSnapshot.d.ts +28 -0
  985. package/dist/sync/v3/workspaceSyncLocalOwnershipSnapshot.js +81 -0
  986. package/dist/sync/v3/workspaceSyncPayloadFingerprint.d.ts +1 -0
  987. package/dist/sync/v3/workspaceSyncPayloadFingerprint.js +5 -0
  988. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +16 -0
  989. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +161 -0
  990. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +83 -0
  991. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +161 -0
  992. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +16 -0
  993. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +90 -0
  994. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +65 -0
  995. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +356 -0
  996. package/dist/sync/v3/workspaceSyncV3CombinedCoverage.d.ts +51 -0
  997. package/dist/sync/v3/workspaceSyncV3CombinedCoverage.js +171 -0
  998. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.d.ts +43 -0
  999. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +535 -0
  1000. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.d.ts +50 -0
  1001. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +1149 -0
  1002. package/dist/sync/v3/workspaceSyncV3CombinedProjectionState.d.ts +96 -0
  1003. package/dist/sync/v3/workspaceSyncV3CombinedProjectionState.js +672 -0
  1004. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +42 -0
  1005. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +598 -0
  1006. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +65 -0
  1007. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +505 -0
  1008. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +78 -0
  1009. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +511 -0
  1010. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +45 -0
  1011. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +125 -0
  1012. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.d.ts +13 -0
  1013. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +34 -0
  1014. package/dist/sync/v3/workspaceSyncV3CursorEncoding.d.ts +1 -0
  1015. package/dist/sync/v3/workspaceSyncV3CursorEncoding.js +6 -0
  1016. package/dist/sync/v3/workspaceSyncV3DomainAdmission.d.ts +43 -0
  1017. package/dist/sync/v3/workspaceSyncV3DomainAdmission.js +118 -0
  1018. package/dist/sync/v3/workspaceSyncV3Feed.d.ts +95 -0
  1019. package/dist/sync/v3/workspaceSyncV3Feed.js +243 -0
  1020. package/dist/sync/v3/workspaceSyncV3FeedApply.d.ts +13 -0
  1021. package/dist/sync/v3/workspaceSyncV3FeedApply.js +67 -0
  1022. package/dist/sync/v3/workspaceSyncV3FeedClientContract.d.ts +3 -0
  1023. package/dist/sync/v3/workspaceSyncV3FeedClientContract.js +46 -0
  1024. package/dist/sync/v3/workspaceSyncV3FeedCursorKeys.d.ts +10 -0
  1025. package/dist/sync/v3/workspaceSyncV3FeedCursorKeys.js +58 -0
  1026. package/dist/sync/v3/workspaceSyncV3FeedOrchestrator.d.ts +31 -0
  1027. package/dist/sync/v3/workspaceSyncV3FeedOrchestrator.js +228 -0
  1028. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +32 -0
  1029. package/dist/sync/v3/workspaceSyncV3FeedProfile.js +21 -0
  1030. package/dist/sync/v3/workspaceSyncV3InitiativeLocalApply.d.ts +36 -0
  1031. package/dist/sync/v3/workspaceSyncV3InitiativeLocalApply.js +163 -0
  1032. package/dist/sync/v3/workspaceSyncV3InitiativeRepair.d.ts +33 -0
  1033. package/dist/sync/v3/workspaceSyncV3InitiativeRepair.js +118 -0
  1034. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +10 -0
  1035. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +45 -0
  1036. package/dist/sync/v3/workspaceSyncV3LocalOutboxStatus.d.ts +27 -0
  1037. package/dist/sync/v3/workspaceSyncV3LocalOutboxStatus.js +83 -0
  1038. package/dist/sync/v3/workspaceSyncV3NestedCoverage.d.ts +10 -0
  1039. package/dist/sync/v3/workspaceSyncV3NestedCoverage.js +40 -0
  1040. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +83 -0
  1041. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +325 -0
  1042. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +59 -0
  1043. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +302 -0
  1044. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +47 -0
  1045. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +329 -0
  1046. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +19 -0
  1047. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +41 -0
  1048. package/dist/sync/v3/workspaceSyncV3NestedWireContract.d.ts +6 -0
  1049. package/dist/sync/v3/workspaceSyncV3NestedWireContract.js +16 -0
  1050. package/dist/sync/v3/workspaceSyncV3OperationProjection.d.ts +8 -0
  1051. package/dist/sync/v3/workspaceSyncV3OperationProjection.js +52 -0
  1052. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +229 -0
  1053. package/dist/sync/v3/workspaceSyncV3OperationProtocol.js +1 -0
  1054. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +165 -0
  1055. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +414 -0
  1056. package/dist/sync/v3/workspaceSyncV3OriginActor.d.ts +36 -0
  1057. package/dist/sync/v3/workspaceSyncV3OriginActor.js +61 -0
  1058. package/dist/sync/v3/workspaceSyncV3OriginAssertion.d.ts +46 -0
  1059. package/dist/sync/v3/workspaceSyncV3OriginAssertion.js +121 -0
  1060. package/dist/sync/v3/workspaceSyncV3OriginAssertionHeader.d.ts +1 -0
  1061. package/dist/sync/v3/workspaceSyncV3OriginAssertionHeader.js +1 -0
  1062. package/dist/sync/v3/workspaceSyncV3PlanningOrderCoverage.d.ts +10 -0
  1063. package/dist/sync/v3/workspaceSyncV3PlanningOrderCoverage.js +34 -0
  1064. package/dist/sync/v3/workspaceSyncV3PlanningOrderWireContract.d.ts +6 -0
  1065. package/dist/sync/v3/workspaceSyncV3PlanningOrderWireContract.js +10 -0
  1066. package/dist/sync/v3/workspaceSyncV3ProjectionState.d.ts +105 -0
  1067. package/dist/sync/v3/workspaceSyncV3ProjectionState.js +467 -0
  1068. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.d.ts +56 -0
  1069. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +250 -0
  1070. package/dist/sync/v3/workspaceSyncV3TaskRelationshipProjection.d.ts +30 -0
  1071. package/dist/sync/v3/workspaceSyncV3TaskRelationshipProjection.js +142 -0
  1072. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +40 -0
  1073. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +246 -0
  1074. package/dist/sync/v3/workspaceSyncV3TaxonomyFeedProjection.d.ts +39 -0
  1075. package/dist/sync/v3/workspaceSyncV3TaxonomyFeedProjection.js +185 -0
  1076. package/dist/sync/v3/workspaceSyncV3WorkflowCoverage.d.ts +10 -0
  1077. package/dist/sync/v3/workspaceSyncV3WorkflowCoverage.js +36 -0
  1078. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +17 -0
  1079. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +143 -0
  1080. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeProjection.d.ts +9 -0
  1081. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeProjection.js +195 -0
  1082. package/dist/sync/v3/workspaceSyncV3WorkflowWireContract.d.ts +11 -0
  1083. package/dist/sync/v3/workspaceSyncV3WorkflowWireContract.js +12 -0
  1084. package/dist/sync/v3/workspaceSyncV3WorkstreamProjection.d.ts +4 -0
  1085. package/dist/sync/v3/workspaceSyncV3WorkstreamProjection.js +98 -0
  1086. package/dist/sync/v3/workspaceSyncV3WorkstreamTaskOrderProjection.d.ts +9 -0
  1087. package/dist/sync/v3/workspaceSyncV3WorkstreamTaskOrderProjection.js +72 -0
  1088. package/dist/sync/v3/workstreamActivityAuthoritativeRevision.d.ts +11 -0
  1089. package/dist/sync/v3/workstreamActivityAuthoritativeRevision.js +23 -0
  1090. package/dist/sync/v3/workstreamActivityIdentity.d.ts +8 -0
  1091. package/dist/sync/v3/workstreamActivityIdentity.js +14 -0
  1092. package/dist/sync/v3/workstreamCoexistence.d.ts +19 -0
  1093. package/dist/sync/v3/workstreamCoexistence.js +64 -0
  1094. package/dist/sync/v3/workstreamMutationPayload.d.ts +27 -0
  1095. package/dist/sync/v3/workstreamMutationPayload.js +147 -0
  1096. package/dist/sync/v3/workstreamMutationService.d.ts +72 -0
  1097. package/dist/sync/v3/workstreamMutationService.js +256 -0
  1098. package/dist/sync/v3/workstreamTaskOrderMutationService.d.ts +55 -0
  1099. package/dist/sync/v3/workstreamTaskOrderMutationService.js +110 -0
  1100. package/dist/sync/v3/workstreamTaskOrderSync.d.ts +14 -0
  1101. package/dist/sync/v3/workstreamTaskOrderSync.js +25 -0
  1102. package/dist/sync/workspaceContentManifest.d.ts +86 -0
  1103. package/dist/sync/workspaceContentManifest.js +123 -0
  1104. package/dist/sync/workspacePullFeed.d.ts +186 -2
  1105. package/dist/sync/workspacePullFeed.js +513 -136
  1106. package/dist/sync/workspacePushPreparedPlan.d.ts +21 -0
  1107. package/dist/sync/workspacePushPreparedPlan.js +1 -0
  1108. package/dist/sync/workspaceRepair.d.ts +17 -25
  1109. package/dist/sync/workspaceRepair.js +348 -25
  1110. package/dist/sync/workspaceSyncContentDecryption.d.ts +6 -0
  1111. package/dist/sync/workspaceSyncContentDecryption.js +11 -0
  1112. package/dist/sync/workspaceSyncModel.d.ts +216 -5
  1113. package/dist/sync/workspaceSyncModel.js +371 -35
  1114. package/dist/sync/workspaceSyncSnapshotProjection.d.ts +11 -0
  1115. package/dist/sync/workspaceSyncSnapshotProjection.js +101 -0
  1116. package/dist/sync/workspaceSyncState.d.ts +13 -0
  1117. package/dist/sync/workspaceSyncState.js +36 -0
  1118. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +106 -0
  1119. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +193 -0
  1120. package/dist/types.d.ts +23 -15
  1121. package/dist/types.js +2 -4
  1122. package/dist/ui/ai-profile-clients/amazon-nova.svg +1 -0
  1123. package/dist/ui/ai-profile-clients/antigravity.png +0 -0
  1124. package/dist/ui/ai-profile-clients/chatgpt.svg +10 -0
  1125. package/dist/ui/ai-profile-clients/claude-chat.svg +1 -0
  1126. package/dist/ui/ai-profile-clients/claude-code.svg +15 -0
  1127. package/dist/ui/ai-profile-clients/cline-app-icon-light.png +0 -0
  1128. package/dist/ui/ai-profile-clients/cline.svg +16 -0
  1129. package/dist/ui/ai-profile-clients/codex.svg +1 -0
  1130. package/dist/ui/ai-profile-clients/copilot.png +0 -0
  1131. package/dist/ui/ai-profile-clients/cursor.svg +1 -0
  1132. package/dist/ui/ai-profile-clients/deepseek.svg +1 -0
  1133. package/dist/ui/ai-profile-clients/gemini-cli-icon.png +0 -0
  1134. package/dist/ui/ai-profile-clients/gemini.svg +10 -0
  1135. package/dist/ui/ai-profile-clients/grok.svg +31 -0
  1136. package/dist/ui/ai-profile-clients/kiro.svg +11 -0
  1137. package/dist/ui/ai-profile-clients/llama.svg +1 -0
  1138. package/dist/ui/ai-profile-clients/mistral.svg +1 -0
  1139. package/dist/ui/ai-profile-clients/ms_copilot.jpeg +0 -0
  1140. package/dist/ui/ai-profile-clients/openclaw.png +0 -0
  1141. package/dist/ui/ai-profile-clients/perplexity.svg +1 -0
  1142. package/dist/ui/ai-profile-clients/vscode.svg +41 -0
  1143. package/dist/ui/ai-profile-clients/windsurf.svg +11 -0
  1144. package/dist/ui/assets/AiIdentityRosterCard-DB1BLO_j.js +1 -0
  1145. package/dist/ui/assets/AiProfilesModule-DPxQeF9N.js +1 -0
  1146. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +1 -0
  1147. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DHNYaNg6.js +3 -0
  1148. package/dist/ui/assets/AssetTraySortControl-B9k5caQW.css +1 -0
  1149. package/dist/ui/assets/AssetTraySortControl-DphbyHVc.js +1 -0
  1150. package/dist/ui/assets/ContextAttachmentManager-CMxSzHqc.js +3 -0
  1151. package/dist/ui/assets/DocumentWorkspace-BC7sy5TG.js +261 -0
  1152. package/dist/ui/assets/DocumentWorkspace-BIBGBfd7.css +1 -0
  1153. package/dist/ui/assets/EntityActivityTimeline-BfJbZRdl.css +1 -0
  1154. package/dist/ui/assets/EntityActivityTimeline-pJ2ZjZ-k.js +1 -0
  1155. package/dist/ui/assets/PlanningModule-CeTqXMMz.css +1 -0
  1156. package/dist/ui/assets/PlanningModule-t5GbvVR9.js +1 -0
  1157. package/dist/ui/assets/PlansPage-BVH_NfgT.js +1 -0
  1158. package/dist/ui/assets/PlansPage-C2nkK2Bp.css +1 -0
  1159. package/dist/ui/assets/TaskContextUpload-Ds4LnDzV.css +1 -0
  1160. package/dist/ui/assets/TaskContextUpload-bl4fOOUz.js +1 -0
  1161. package/dist/ui/assets/TaskSettings-xVsxSa0g.js +12 -0
  1162. package/dist/ui/assets/TaskforceAgentsModule-CkAxW19K.js +21 -0
  1163. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +1 -0
  1164. package/dist/ui/assets/WorkflowManagerModule-BKqIGVnF.js +1 -0
  1165. package/dist/ui/assets/WorkflowManagerModule-DF10XENz.css +1 -0
  1166. package/dist/ui/assets/antigravity-DRKQga2U.png +0 -0
  1167. package/dist/ui/assets/cursor-BM_3k4Y4.svg +1 -0
  1168. package/dist/ui/assets/gemini-cli-icon-dBAVjCcn.png +0 -0
  1169. package/dist/ui/assets/grok-BuodbWaG.svg +31 -0
  1170. package/dist/ui/assets/index-BzJlVnNS.css +1 -0
  1171. package/dist/ui/assets/index-Cx7vZJHL.js +7 -0
  1172. package/dist/ui/assets/{vendor-dnd-DRzYolkg.js → vendor-dnd-CJ-AjP-Y.js} +1 -1
  1173. package/dist/ui/assets/{vendor-icons-CLnehDTw.js → vendor-icons-B8ZNsH1g.js} +1 -1
  1174. package/dist/ui/assets/{vendor-markdown-BUxTU7dS.js → vendor-markdown-_lhNCyq-.js} +9 -9
  1175. package/dist/ui/assets/vendor-router-AqJMU8Lz.js +3 -0
  1176. package/dist/ui/assets/vscode-C_7wk1WI.svg +41 -0
  1177. package/dist/ui/branding/logos/logo_dark_bg.png +0 -0
  1178. package/dist/ui/branding/logos/logo_favicon_dark.png +0 -0
  1179. package/dist/ui/branding/logos/logo_favicon_dark.svg +56 -0
  1180. package/dist/ui/branding/logos/logo_favicon_light.png +0 -0
  1181. package/dist/ui/branding/logos/logo_light_bg.png +0 -0
  1182. package/dist/ui/images/Taskforce_Van.webp +0 -0
  1183. package/dist/ui/index.html +6 -6
  1184. package/dist/update/uiUpdateService.d.ts +43 -0
  1185. package/dist/update/uiUpdateService.js +149 -0
  1186. package/dist/update/updateCli.d.ts +15 -0
  1187. package/dist/update/updateCli.js +76 -0
  1188. package/dist/update/updateExecutor.d.ts +40 -0
  1189. package/dist/update/updateExecutor.js +474 -0
  1190. package/dist/update/updateStatus.d.ts +83 -0
  1191. package/dist/update/updateStatus.js +703 -0
  1192. package/dist/utils/aiProfileAvatarPaths.d.ts +14 -0
  1193. package/dist/utils/aiProfileAvatarPaths.js +52 -0
  1194. package/dist/utils/aiProfileDefaultLogo.d.ts +7 -0
  1195. package/dist/utils/aiProfileDefaultLogo.js +84 -0
  1196. package/dist/utils/aiProfileEvents.d.ts +9 -1
  1197. package/dist/utils/annotatedAttachments.d.ts +8 -0
  1198. package/dist/utils/annotatedAttachments.js +17 -1
  1199. package/dist/utils/assetTraySorting.d.ts +25 -0
  1200. package/dist/utils/assetTraySorting.js +83 -0
  1201. package/dist/utils/assignees.d.ts +5 -0
  1202. package/dist/utils/assignees.js +14 -9
  1203. package/dist/utils/authLogin.d.ts +10 -0
  1204. package/dist/utils/authLogin.js +8 -0
  1205. package/dist/utils/authSessionEvents.d.ts +2 -0
  1206. package/dist/utils/authSessionEvents.js +6 -0
  1207. package/dist/utils/avatarUpload.js +5 -5
  1208. package/dist/utils/canonicalReferenceAttachments.d.ts +12 -0
  1209. package/dist/utils/canonicalReferenceAttachments.js +42 -0
  1210. package/dist/utils/cloudAssetDisplay.d.ts +2 -0
  1211. package/dist/utils/cloudAssetDisplay.js +8 -0
  1212. package/dist/utils/constants.d.ts +4 -11
  1213. package/dist/utils/constants.js +5 -64
  1214. package/dist/utils/contextAttachmentPreview.d.ts +11 -0
  1215. package/dist/utils/contextAttachmentPreview.js +8 -0
  1216. package/dist/utils/contextAttachmentUpload.d.ts +8 -0
  1217. package/dist/utils/contextAttachmentUpload.js +144 -0
  1218. package/dist/utils/documentNames.js +6 -4
  1219. package/dist/utils/entityReferences.d.ts +14 -0
  1220. package/dist/utils/entityReferences.js +21 -0
  1221. package/dist/utils/httpSetCookie.d.ts +3 -0
  1222. package/dist/utils/httpSetCookie.js +22 -0
  1223. package/dist/utils/imageNoteStoragePaths.d.ts +3 -0
  1224. package/dist/utils/imageNoteStoragePaths.js +19 -0
  1225. package/dist/utils/imageReferences.d.ts +6 -0
  1226. package/dist/utils/imageReferences.js +1 -0
  1227. package/dist/utils/planningArchiveOrchestrator.d.ts +23 -0
  1228. package/dist/utils/planningArchiveOrchestrator.js +37 -0
  1229. package/dist/utils/planningArchivePresentation.d.ts +20 -0
  1230. package/dist/utils/planningArchivePresentation.js +23 -0
  1231. package/dist/utils/planningArchiveReadiness.d.ts +26 -0
  1232. package/dist/utils/planningArchiveReadiness.js +30 -0
  1233. package/dist/utils/planningFavorites.d.ts +7 -0
  1234. package/dist/utils/planningFavorites.js +34 -0
  1235. package/dist/utils/syncEventPresentation.js +53 -0
  1236. package/dist/utils/syncStatusPresentation.d.ts +25 -0
  1237. package/dist/utils/syncStatusPresentation.js +86 -5
  1238. package/dist/utils/taskActivity.d.ts +9 -2
  1239. package/dist/utils/taskActivity.js +61 -0
  1240. package/dist/utils/taskDraftDefaults.d.ts +0 -8
  1241. package/dist/utils/taskDraftDefaults.js +0 -4
  1242. package/dist/utils/taskEvents.d.ts +11 -0
  1243. package/dist/utils/taskEvents.js +6 -0
  1244. package/dist/utils/taskHeaderQuickFilter.d.ts +14 -0
  1245. package/dist/utils/taskHeaderQuickFilter.js +32 -0
  1246. package/dist/utils/taskInvalidation.d.ts +23 -0
  1247. package/dist/utils/taskInvalidation.js +67 -0
  1248. package/dist/utils/taskNormalization.d.ts +2 -1
  1249. package/dist/utils/taskNormalization.js +44 -18
  1250. package/dist/utils/taskReferences.d.ts +16 -0
  1251. package/dist/utils/taskReferences.js +63 -0
  1252. package/dist/utils/taskforceAgentEvents.d.ts +8 -0
  1253. package/dist/utils/taskforceAgentEvents.js +6 -0
  1254. package/dist/utils/taskforceAgentSkillEvents.d.ts +7 -0
  1255. package/dist/utils/taskforceAgentSkillEvents.js +8 -0
  1256. package/dist/utils/theme.js +1 -1
  1257. package/dist/utils/uiNotice.d.ts +3 -0
  1258. package/dist/utils/uiNotice.js +1 -1
  1259. package/dist/utils/workspaceResourceEvents.d.ts +7 -0
  1260. package/dist/utils/workspaceResourceEvents.js +6 -0
  1261. package/dist/utils/workspaceSyncPresentation.d.ts +24 -0
  1262. package/dist/utils/workspaceSyncPresentation.js +243 -6
  1263. package/package.json +69 -21
  1264. package/dist/components/features/AgentsModule.d.ts +0 -18
  1265. package/dist/components/features/AgentsModule.js +0 -479
  1266. package/dist/components/features/InitiativesModule.d.ts +0 -22
  1267. package/dist/components/features/InitiativesModule.js +0 -33
  1268. package/dist/components/features/WorkflowsModule.d.ts +0 -27
  1269. package/dist/components/features/WorkflowsModule.js +0 -21
  1270. package/dist/components/features/settings/WorkflowEditor.d.ts +0 -15
  1271. package/dist/components/features/settings/WorkflowEditor.js +0 -245
  1272. package/dist/components/views/panels/DocumentFilterToolbar.d.ts +0 -10
  1273. package/dist/components/views/panels/DocumentFilterToolbar.js +0 -7
  1274. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +0 -61
  1275. package/dist/components/views/standalone/modals/AccountHubModal.js +0 -108
  1276. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +0 -19
  1277. package/dist/components/views/standalone/modals/EditProfileModal.js +0 -11
  1278. package/dist/hooks/ui/useResourceExport.d.ts +0 -21
  1279. package/dist/hooks/ui/useResourceExport.js +0 -87
  1280. package/dist/hooks/ui/useWorkflowTemplates.d.ts +0 -37
  1281. package/dist/hooks/ui/useWorkflowTemplates.js +0 -116
  1282. package/dist/mcp/clientProfileDefaults.d.ts +0 -12
  1283. package/dist/mcp/clientProfileDefaults.js +0 -37
  1284. package/dist/resources/templates/WORKFLOW_V2_POLICY.md +0 -55
  1285. package/dist/resources/templates/environments/aider.yaml +0 -14
  1286. package/dist/resources/templates/environments/antigravity.yaml +0 -10
  1287. package/dist/resources/templates/environments/claude.yaml +0 -10
  1288. package/dist/resources/templates/environments/cline.yaml +0 -10
  1289. package/dist/resources/templates/environments/codex.yaml +0 -13
  1290. package/dist/resources/templates/environments/copilot.yaml +0 -10
  1291. package/dist/resources/templates/environments/cursor.yaml +0 -9
  1292. package/dist/resources/templates/environments/gemini.yaml +0 -9
  1293. package/dist/resources/templates/environments/windsurf.yaml +0 -10
  1294. package/dist/resources/templates/workflow-sources/README.md +0 -9
  1295. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +0 -530
  1296. package/dist/resources/templates/workflow-sources/workflowEditorOverrides.json +0 -1
  1297. package/dist/resources/templates/workflows/collaborate.yaml +0 -110
  1298. package/dist/resources/templates/workflows/do.yaml +0 -88
  1299. package/dist/resources/templates/workflows/evaluate.yaml +0 -117
  1300. package/dist/resources/templates/workflows/execute.yaml +0 -159
  1301. package/dist/resources/templates/workflows/plan.yaml +0 -119
  1302. package/dist/resources/templates/workflows/review.yaml +0 -115
  1303. package/dist/services/formatTransformers.d.ts +0 -29
  1304. package/dist/services/formatTransformers.js +0 -56
  1305. package/dist/services/templateEngine.d.ts +0 -46
  1306. package/dist/services/templateEngine.js +0 -148
  1307. package/dist/shared/workflowDefaults.d.ts +0 -9
  1308. package/dist/shared/workflowDefaults.js +0 -11
  1309. package/dist/ui/agent-logos/Gemini CLI.jpeg +0 -0
  1310. package/dist/ui/agent-logos/antigravity.jpeg +0 -0
  1311. package/dist/ui/agent-logos/chatgpt.png +0 -0
  1312. package/dist/ui/agent-logos/claude-code.jpeg +0 -0
  1313. package/dist/ui/agent-logos/codex.jpeg +0 -0
  1314. package/dist/ui/agent-logos/cursor.png +0 -0
  1315. package/dist/ui/agent-logos/openclaw.jpeg +0 -0
  1316. package/dist/ui/agent-logos/windsurf.png +0 -0
  1317. package/dist/ui/assets/AgentsModule-DvkbUHi0.js +0 -1
  1318. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +0 -1
  1319. package/dist/ui/assets/AnnotatedAttachmentWorkspace-jhOhxqHT.js +0 -3
  1320. package/dist/ui/assets/ContextAttachmentManager-BAmEyLHL.js +0 -3
  1321. package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +0 -1
  1322. package/dist/ui/assets/DocumentWorkspace-X-CpD5OO.js +0 -252
  1323. package/dist/ui/assets/EntityActivityTimeline-DD33onAC.js +0 -1
  1324. package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +0 -1
  1325. package/dist/ui/assets/InitiativesModule-5nDXtIjf.js +0 -1
  1326. package/dist/ui/assets/PlansPage-B8nDR1hQ.js +0 -1
  1327. package/dist/ui/assets/PlansPage-DeAzWYTb.css +0 -1
  1328. package/dist/ui/assets/TaskContextUpload-DrGrXJHm.js +0 -1
  1329. package/dist/ui/assets/TaskSettings-BXVvZZwH.js +0 -9
  1330. package/dist/ui/assets/WorkflowsModule-DWCGhEWT.js +0 -5
  1331. package/dist/ui/assets/documentReferences-Crup321p.js +0 -1
  1332. package/dist/ui/assets/index-B9k24Aym.js +0 -5
  1333. package/dist/ui/assets/index-DNeR5dYW.css +0 -1
  1334. package/dist/ui/assets/vendor-router-BbWMxlnO.js +0 -3
  1335. package/dist/ui/branding/logos/logo_black_01.png +0 -0
  1336. package/dist/ui/branding/logos/logo_black_02.png +0 -0
  1337. package/dist/ui/branding/logos/logo_white_01.png +0 -0
  1338. package/dist/ui/branding/logos/logo_white_02.png +0 -0
  1339. package/scripts/generate-workflow-templates.mjs +0 -134
  1340. package/src/resources/templates/WORKFLOW_V2_POLICY.md +0 -55
  1341. package/src/resources/templates/environments/aider.yaml +0 -14
  1342. package/src/resources/templates/environments/antigravity.yaml +0 -10
  1343. package/src/resources/templates/environments/claude.yaml +0 -10
  1344. package/src/resources/templates/environments/cline.yaml +0 -10
  1345. package/src/resources/templates/environments/codex.yaml +0 -13
  1346. package/src/resources/templates/environments/copilot.yaml +0 -10
  1347. package/src/resources/templates/environments/cursor.yaml +0 -9
  1348. package/src/resources/templates/environments/gemini.yaml +0 -9
  1349. package/src/resources/templates/environments/windsurf.yaml +0 -10
  1350. package/src/resources/templates/workflow-sources/README.md +0 -9
  1351. package/src/resources/templates/workflow-sources/workflowDocs.mjs +0 -530
  1352. package/src/resources/templates/workflow-sources/workflowEditorOverrides.json +0 -1
  1353. package/src/resources/templates/workflows/collaborate.yaml +0 -110
  1354. package/src/resources/templates/workflows/do.yaml +0 -88
  1355. package/src/resources/templates/workflows/evaluate.yaml +0 -117
  1356. package/src/resources/templates/workflows/execute.yaml +0 -159
  1357. package/src/resources/templates/workflows/plan.yaml +0 -119
  1358. package/src/resources/templates/workflows/review.yaml +0 -115
  1359. /package/dist/ui/branding/logos/{logo_dark.svg → logo_dark_no_bg.svg} +0 -0
  1360. /package/dist/ui/branding/logos/{logo_favicon.svg → logo_favicon_light.svg} +0 -0
  1361. /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';
36
- import { isPlanningEntityVisibleForScope, scopePlanningSummaries } from './planningScope';
37
- import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, } from '../../utils/syncStatusPresentation';
42
+ import { TASK_DEEP_LINK_QUERY_KEYS } from '../../shared/taskDeepLinks';
43
+ import { isPlanningEntityVisibleForScope, scopePlanningSummaries, scopeTasksToPlanningSelection } from './planningScope';
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, 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, setAttachmentsDirty, 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();
@@ -198,8 +226,6 @@ export function StandaloneLayout(props) {
198
226
  pendingNavigation();
199
227
  }
200
228
  };
201
- // State for Card Compression
202
- const [compressedCards, setCompressedCards] = useState(false);
203
229
  const [scheduleShowWeekends, setScheduleShowWeekends] = useState(false);
204
230
  const [scheduleShowBacklog, setScheduleShowBacklog] = useState(true);
205
231
  const [scheduleOnlyExpired, setScheduleOnlyExpired] = useState(false);
@@ -213,17 +239,32 @@ export function StandaloneLayout(props) {
213
239
  const [showFilters, setShowFilters] = useState(false);
214
240
  const [taskModalFullscreen, setTaskModalFullscreen] = useState(false);
215
241
  const [planningDrawerOpen, setPlanningDrawerOpen] = useState(false);
242
+ const planningDrawerLauncherRef = useRef(null);
216
243
  const [documentTrayOpen, setDocumentTrayOpen] = useState(true);
217
244
  const [imageTrayOpen, setImageTrayOpen] = useState(true);
218
245
  const [agentTrayOpen, setAgentTrayOpen] = useState(true);
246
+ const [taskforceAgentRosterTrayOpen, setTaskforceAgentRosterTrayOpen] = useState(true);
247
+ const [workflowLibraryTrayOpen, setWorkflowLibraryTrayOpen] = useState(true);
248
+ const [workflowManagerHasUnsavedChanges, setWorkflowManagerHasUnsavedChanges] = useState(false);
249
+ const [pendingWorkflowDiscardAction, setPendingWorkflowDiscardAction] = useState(null);
250
+ const workflowDiscardBypassRef = useRef(false);
251
+ const appShellHeaderRef = useRef(null);
252
+ const [taskforceAgentDrawerTop, setTaskforceAgentDrawerTop] = useState(TASKFORCE_AGENT_DRAWER_FALLBACK_TOP);
219
253
  const [planningTreeCollapsed, setPlanningTreeCollapsed] = useState(false);
220
254
  const [planningPrimaryCollapsed, setPlanningPrimaryCollapsed] = useState(false);
221
255
  const [planningSecondaryCollapsed, setPlanningSecondaryCollapsed] = useState(false);
256
+ const [planningFavoritesSectionCollapsed, setPlanningFavoritesSectionCollapsed] = useState(false);
257
+ const [planningInitiativesSectionCollapsed, setPlanningInitiativesSectionCollapsed] = useState(false);
258
+ const [planningWorkstreamsSectionCollapsed, setPlanningWorkstreamsSectionCollapsed] = useState(false);
259
+ const [planningNavigatorSort, setPlanningNavigatorSort] = useState('default');
260
+ const [planningTaskArrangeMode, setPlanningTaskArrangeMode] = useState('execution');
261
+ const [planningFavorites, setPlanningFavorites] = useState([]);
222
262
  const [selectedPlanningInitiativeId, setSelectedPlanningInitiativeId] = useState('');
223
263
  const [selectedPlanningWorkstreamId, setSelectedPlanningWorkstreamId] = useState('');
224
264
  const [expandedPlanningInitiativeIds, setExpandedPlanningInitiativeIds] = useState(new Set());
225
265
  const [planningDrawerDetail, setPlanningDrawerDetail] = useState(null);
226
266
  const [planningNestedWorkstreamDetailId, setPlanningNestedWorkstreamDetailId] = useState(null);
267
+ const [planningHydrationStateByEntity, setPlanningHydrationStateByEntity] = useState({});
227
268
  const [planningEditor, setPlanningEditor] = useState(null);
228
269
  const [planningSecondaryEditor, setPlanningSecondaryEditor] = useState(null);
229
270
  const [planningDraftTitle, setPlanningDraftTitle] = useState('');
@@ -235,21 +276,36 @@ export function StandaloneLayout(props) {
235
276
  taskId: null,
236
277
  attachments: [],
237
278
  });
279
+ const todayDateOnly = useMemo(() => toDateOnlyLocal(new Date()), []);
280
+ const normalizedAuthUserId = String(authUserId || '').trim();
281
+ const { taskHeaderQuickFilter, toggleTaskHeaderQuickFilter, clearTaskHeaderQuickFilter, } = useTaskHeaderQuickFilter({
282
+ authUserId: normalizedAuthUserId,
283
+ workspaceId: currentWorkspaceId,
284
+ taskScope,
285
+ });
238
286
  const planningContextAttachmentDraftsRef = useRef(new Map());
239
287
  const planningContextAttachmentUpdateQueueRef = useRef(new Map());
240
288
  const [documentTypeFilters, setDocumentTypeFilters] = useState(() => DOCUMENT_TYPE_FILTER_OPTIONS.map((option) => option.value));
241
289
  const [documentAttachmentFilters, setDocumentAttachmentFilters] = useState(() => DOCUMENT_ATTACHMENT_FILTER_OPTIONS.map((option) => option.value));
290
+ const [documentSortField, setDocumentSortField] = useState('updated');
291
+ const [documentSortOrder, setDocumentSortOrder] = useState('desc');
292
+ const [documentPinnedDocIds, setDocumentPinnedDocIds] = useState([]);
293
+ const [documentSearchQuery, setDocumentSearchQuery] = useState('');
294
+ const [documentSelectedDocId, setDocumentSelectedDocId] = useState(null);
295
+ const [documentScrollByDocId, setDocumentScrollByDocId] = useState({});
296
+ const [documentListScrollTop, setDocumentListScrollTop] = useState(0);
242
297
  const [requestedDocPath, setRequestedDocPath] = useState(null);
243
298
  const [requestedDocAssetId, setRequestedDocAssetId] = useState(null);
244
299
  const [requestedAnnotatedTarget, setRequestedAnnotatedTarget] = useState(null);
245
300
  const [requestedAnnotatedSessionId, setRequestedAnnotatedSessionId] = useState(null);
301
+ const [annotatedViewportByContextKey, setAnnotatedViewportByContextKey] = useState({});
246
302
  const [requestedAnnotatedOpenVersion, setRequestedAnnotatedOpenVersion] = useState(0);
303
+ const handledEntityDeepLinkRef = useRef(null);
247
304
  const [canonicalAnnotatedImageReferenceLabels, setCanonicalAnnotatedImageReferenceLabels] = useState({});
248
- const [layoutStateReady, setLayoutStateReady] = useState(false);
249
305
  const planningEditorSubmitInFlightRef = useRef(false);
250
- const loadedLayoutStateWorkspaceRef = useRef('');
251
306
  const requestedAnnotatedTargetRef = useRef(null);
252
307
  const requestedAnnotatedSessionIdRef = useRef(null);
308
+ const lastHydratedAnnotatedContextIdentityRef = useRef(null);
253
309
  const annotatedImageReferenceFetchesRef = useRef(new Set());
254
310
  useEffect(() => {
255
311
  taskContextAttachmentDraftRef.current = {
@@ -269,7 +325,15 @@ export function StandaloneLayout(props) {
269
325
  setAttachments(nextAttachments);
270
326
  setAttachmentsDirty(true);
271
327
  if (taskId) {
272
- void handleUpdateTask(taskId, { attachments: nextAttachments });
328
+ void handleUpdateTask(taskId, { attachments: nextAttachments }).then((saved) => {
329
+ const latestDraft = taskContextAttachmentDraftRef.current;
330
+ if (saved !== false && latestDraft.taskId === taskId
331
+ && latestDraft.attachments === nextAttachments) {
332
+ setAttachmentsDirty(false);
333
+ }
334
+ }).catch(() => {
335
+ // Keep the attachment draft dirty so the editor can retry it.
336
+ });
273
337
  }
274
338
  }, [attachments, editingTaskId, handleUpdateTask, setAttachments, setAttachmentsDirty]);
275
339
  const workspaceUiStateHeaders = useMemo(() => {
@@ -280,8 +344,15 @@ export function StandaloneLayout(props) {
280
344
  }
281
345
  return headers;
282
346
  }, [runtimeMode, currentWorkspaceId]);
283
- const layoutStateWorkspaceKey = useMemo(() => `${runtimeMode}:${String(currentWorkspaceId || 'default').trim() || 'default'}`, [runtimeMode, currentWorkspaceId]);
284
- const annotatedLayoutCacheKey = useMemo(() => `taskforce:annotate-layout:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
347
+ const layoutStateWorkspaceKey = useMemo(() => buildLayoutUiStateLoadKey({
348
+ runtimeMode,
349
+ workspaceId: currentWorkspaceId,
350
+ userId: normalizedAuthUserId,
351
+ }), [currentWorkspaceId, normalizedAuthUserId, runtimeMode]);
352
+ const annotatedContextScopeRef = useRef(layoutStateWorkspaceKey);
353
+ const annotatedContextMatchesLayoutScope = annotatedContextScopeRef.current === layoutStateWorkspaceKey;
354
+ const scopedRequestedAnnotatedTarget = annotatedContextMatchesLayoutScope ? requestedAnnotatedTarget : null;
355
+ const scopedRequestedAnnotatedSessionId = annotatedContextMatchesLayoutScope ? requestedAnnotatedSessionId : null;
285
356
  const taskOriginWorkspaceModuleKey = useMemo(() => `taskforce:task-origin-workspace-module:${layoutStateWorkspaceKey}`, [layoutStateWorkspaceKey]);
286
357
  const annotatedWorkspaceReady = useMemo(() => (runtimeMode === 'cloud' ? authSessionResolved : configLoaded), [authSessionResolved, configLoaded, runtimeMode]);
287
358
  const openedTaskOriginWorkspaceModuleRef = useRef(false);
@@ -315,6 +386,16 @@ export function StandaloneLayout(props) {
315
386
  useEffect(() => {
316
387
  requestedAnnotatedSessionIdRef.current = requestedAnnotatedSessionId;
317
388
  }, [requestedAnnotatedSessionId]);
389
+ useEffect(() => {
390
+ if (annotatedContextScopeRef.current === layoutStateWorkspaceKey)
391
+ return;
392
+ annotatedContextScopeRef.current = layoutStateWorkspaceKey;
393
+ requestedAnnotatedTargetRef.current = null;
394
+ requestedAnnotatedSessionIdRef.current = null;
395
+ lastHydratedAnnotatedContextIdentityRef.current = null;
396
+ setRequestedAnnotatedTarget(null);
397
+ setRequestedAnnotatedSessionId(null);
398
+ }, [layoutStateWorkspaceKey]);
318
399
  const workspaceFeatureAccess = useMemo(() => ({
319
400
  [DOCUMENT_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
320
401
  featureKey: DOCUMENT_WORKSPACE_FEATURE_KEY,
@@ -324,25 +405,75 @@ export function StandaloneLayout(props) {
324
405
  featureKey: ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY,
325
406
  runtimeMode,
326
407
  }),
327
- [WORKFLOWS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
328
- featureKey: WORKFLOWS_WORKSPACE_FEATURE_KEY,
408
+ [WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
409
+ featureKey: WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY,
410
+ runtimeMode,
411
+ }),
412
+ [TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
413
+ featureKey: TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY,
329
414
  runtimeMode,
330
415
  }),
331
- [AGENTS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
332
- featureKey: AGENTS_WORKSPACE_FEATURE_KEY,
416
+ [AI_PROFILES_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
417
+ featureKey: AI_PROFILES_WORKSPACE_FEATURE_KEY,
333
418
  runtimeMode,
334
419
  }),
335
- [INITIATIVES_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
336
- featureKey: INITIATIVES_WORKSPACE_FEATURE_KEY,
420
+ [PLANNING_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
421
+ featureKey: PLANNING_WORKSPACE_FEATURE_KEY,
337
422
  runtimeMode,
338
423
  }),
339
424
  }), [runtimeMode]);
340
425
  const workspaceModules = useMemo(() => getWorkspaceModuleDefinitions({ featureAccess: workspaceFeatureAccess }), [workspaceFeatureAccess]);
341
426
  const resolvedWorkspaceModule = useMemo(() => resolveWorkspaceModule(activeWorkspaceModule, workspaceModules), [activeWorkspaceModule, workspaceModules]);
427
+ const planningSurfaceVisible = planningDrawerOpen || resolvedWorkspaceModule === 'planning';
428
+ useEffect(() => {
429
+ if (!planningSurfaceVisible)
430
+ return;
431
+ void props.ensureArchiveHydrated(true);
432
+ }, [planningSurfaceVisible, props.ensureArchiveHydrated, currentWorkspaceId]);
433
+ const [taskforceAgentDrawerOpen, setTaskforceAgentDrawerOpen] = useState(false);
434
+ const [taskforceAgentPanelCollapsed, setTaskforceAgentPanelCollapsed] = useState(false);
435
+ const [taskforceAgentsLaunchContext, setTaskforceAgentsLaunchContext] = useState(null);
436
+ const [taskforceAgentDrawerHeaderContent, setTaskforceAgentDrawerHeaderContent] = useState(null);
437
+ const handleRenderTaskforceAgentDrawerHeader = useCallback((content) => {
438
+ setTaskforceAgentDrawerHeaderContent(content);
439
+ }, []);
440
+ const handleRememberTaskforceAgentSelection = useCallback((selection) => {
441
+ const nextAgentId = String(selection.agentId || '').trim();
442
+ const nextConversationId = String(selection.conversationId || '').trim();
443
+ setTaskforceAgentId(nextAgentId);
444
+ setTaskforceAgentConversationId(nextConversationId);
445
+ if (!nextAgentId)
446
+ return;
447
+ setTaskforceAgentConversationByAgentId((current) => {
448
+ if (nextConversationId) {
449
+ if (current[nextAgentId] === nextConversationId)
450
+ return current;
451
+ return { ...current, [nextAgentId]: nextConversationId };
452
+ }
453
+ if (!current[nextAgentId])
454
+ return current;
455
+ const next = { ...current };
456
+ delete next[nextAgentId];
457
+ return next;
458
+ });
459
+ }, [setTaskforceAgentConversationByAgentId, setTaskforceAgentConversationId, setTaskforceAgentId]);
342
460
  const documentsWorkspaceEnabled = workspaceFeatureAccess[DOCUMENT_WORKSPACE_FEATURE_KEY]?.allowed ?? false;
343
461
  const annotatedAttachmentsWorkspaceEnabled = workspaceFeatureAccess[ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY]?.allowed ?? false;
462
+ const taskforceAgentsWorkspaceEnabled = workspaceFeatureAccess[TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]?.allowed ?? false;
344
463
  const documentsWorkspaceUnavailableMessage = 'Documents is not available in this build yet.';
345
464
  const annotatedAttachmentsWorkspaceUnavailableMessage = 'Annotate is not available in this build yet.';
465
+ const handoffTaskModalToWorkspace = useCallback((action) => {
466
+ if (activeTab !== 'add') {
467
+ action();
468
+ return;
469
+ }
470
+ void handleNavigation(() => {
471
+ setTaskModalFullscreen(false);
472
+ resetForm();
473
+ setActiveTab('tasks');
474
+ action();
475
+ });
476
+ }, [activeTab, handleNavigation, resetForm, setActiveTab]);
346
477
  useEffect(() => {
347
478
  const handleOpenMarkdownDocument = (event) => {
348
479
  const customEvent = event;
@@ -355,16 +486,18 @@ export function StandaloneLayout(props) {
355
486
  pushNotice(documentsWorkspaceUnavailableMessage, 'error');
356
487
  return;
357
488
  }
358
- rememberTaskOriginWorkspaceModule(customEvent.detail?.taskId);
359
- setRequestedDocPath(fsPath || null);
360
- setRequestedDocAssetId(assetId);
361
- setActiveWorkspaceModule('docs');
489
+ handoffTaskModalToWorkspace(() => {
490
+ rememberTaskOriginWorkspaceModule(customEvent.detail?.taskId);
491
+ setRequestedDocPath(fsPath || null);
492
+ setRequestedDocAssetId(assetId);
493
+ setActiveWorkspaceModule('docs');
494
+ });
362
495
  };
363
496
  window.addEventListener('taskforce:open-markdown-document', handleOpenMarkdownDocument);
364
497
  return () => {
365
498
  window.removeEventListener('taskforce:open-markdown-document', handleOpenMarkdownDocument);
366
499
  };
367
- }, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, pushNotice, rememberTaskOriginWorkspaceModule, setActiveWorkspaceModule]);
500
+ }, [documentsWorkspaceEnabled, documentsWorkspaceUnavailableMessage, handoffTaskModalToWorkspace, pushNotice, rememberTaskOriginWorkspaceModule, setActiveWorkspaceModule]);
368
501
  useEffect(() => {
369
502
  if (resolvedWorkspaceModule !== activeWorkspaceModule) {
370
503
  setActiveWorkspaceModule(resolvedWorkspaceModule);
@@ -376,25 +509,6 @@ export function StandaloneLayout(props) {
376
509
  setRequestedDocPath(null);
377
510
  setRequestedDocAssetId(null);
378
511
  }, [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
512
  useEffect(() => {
399
513
  if (taskOriginWorkspaceModuleRestoreHandledRef.current)
400
514
  return;
@@ -418,161 +532,166 @@ export function StandaloneLayout(props) {
418
532
  taskOriginWorkspaceModuleRestoreHandledRef.current = false;
419
533
  openedTaskOriginWorkspaceModuleRef.current = false;
420
534
  }, [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,
535
+ const applyPersistedLayoutState = useCallback((state) => {
536
+ if (typeof state.scheduleShowWeekends === 'boolean')
537
+ setScheduleShowWeekends(state.scheduleShowWeekends);
538
+ if (typeof state.scheduleShowBacklog === 'boolean')
539
+ setScheduleShowBacklog(state.scheduleShowBacklog);
540
+ if (typeof state.scheduleOnlyExpired === 'boolean')
541
+ setScheduleOnlyExpired(state.scheduleOnlyExpired);
542
+ if (typeof state.scheduleSidebarOpen === 'boolean')
543
+ setScheduleSidebarOpen(state.scheduleSidebarOpen);
544
+ if (typeof state.scheduleSelectedDate === 'string')
545
+ setScheduleSelectedDate(state.scheduleSelectedDate);
546
+ if (typeof state.scheduleCalendarMonth === 'string')
547
+ setScheduleCalendarMonth(state.scheduleCalendarMonth);
548
+ if (typeof state.scheduleScrollLeft === 'number')
549
+ setScheduleScrollLeft(state.scheduleScrollLeft);
550
+ if (typeof state.showFilters === 'boolean')
551
+ setShowFilters(state.showFilters);
552
+ if (Array.isArray(state.documentTypeFilters)) {
553
+ setDocumentTypeFilters(state.documentTypeFilters);
554
+ }
555
+ if (Array.isArray(state.documentAttachmentFilters)) {
556
+ setDocumentAttachmentFilters(state.documentAttachmentFilters);
557
+ }
558
+ if (state.documentSortField === 'updated'
559
+ || state.documentSortField === 'reference'
560
+ || state.documentSortField === 'name'
561
+ || state.documentSortField === 'size'
562
+ || state.documentSortField === 'created') {
563
+ setDocumentSortField(state.documentSortField);
564
+ }
565
+ if (state.documentSortOrder === 'asc' || state.documentSortOrder === 'desc') {
566
+ setDocumentSortOrder(state.documentSortOrder);
567
+ }
568
+ if (Array.isArray(state.documentPinnedDocIds)) {
569
+ setDocumentPinnedDocIds(state.documentPinnedDocIds);
570
+ }
571
+ if (typeof state.documentSearchQuery === 'string') {
572
+ setDocumentSearchQuery(state.documentSearchQuery);
573
+ }
574
+ if (typeof state.documentSelectedDocId === 'string' || state.documentSelectedDocId === null) {
575
+ setDocumentSelectedDocId(state.documentSelectedDocId);
576
+ }
577
+ setDocumentScrollByDocId(state.documentScrollByDocId && typeof state.documentScrollByDocId === 'object'
578
+ ? state.documentScrollByDocId
579
+ : {});
580
+ if (typeof state.documentListScrollTop === 'number') {
581
+ setDocumentListScrollTop(state.documentListScrollTop);
582
+ }
583
+ if (typeof state.planningDrawerOpen === 'boolean') {
584
+ setPlanningDrawerOpen(state.planningDrawerOpen);
585
+ }
586
+ if (typeof state.documentTrayOpen === 'boolean') {
587
+ setDocumentTrayOpen(state.documentTrayOpen);
588
+ }
589
+ if (typeof state.imageTrayOpen === 'boolean') {
590
+ setImageTrayOpen(state.imageTrayOpen);
591
+ }
592
+ if (typeof state.agentTrayOpen === 'boolean') {
593
+ setAgentTrayOpen(state.agentTrayOpen);
594
+ }
595
+ if (typeof state.taskforceAgentRosterTrayOpen === 'boolean') {
596
+ setTaskforceAgentRosterTrayOpen(state.taskforceAgentRosterTrayOpen);
597
+ }
598
+ if (typeof state.taskforceAgentDrawerOpen === 'boolean') {
599
+ setTaskforceAgentDrawerOpen(state.taskforceAgentDrawerOpen);
600
+ }
601
+ if (typeof state.taskforceAgentPanelCollapsed === 'boolean') {
602
+ setTaskforceAgentPanelCollapsed(state.taskforceAgentPanelCollapsed);
603
+ }
604
+ if (typeof state.planningTreeCollapsed === 'boolean') {
605
+ setPlanningTreeCollapsed(state.planningTreeCollapsed);
606
+ }
607
+ if (typeof state.planningPrimaryCollapsed === 'boolean') {
608
+ setPlanningPrimaryCollapsed(state.planningPrimaryCollapsed);
609
+ }
610
+ if (typeof state.planningSecondaryCollapsed === 'boolean') {
611
+ setPlanningSecondaryCollapsed(state.planningSecondaryCollapsed);
612
+ }
613
+ setPlanningFavoritesSectionCollapsed(Boolean(state.planningFavoritesSectionCollapsed));
614
+ setPlanningInitiativesSectionCollapsed(Boolean(state.planningInitiativesSectionCollapsed));
615
+ setPlanningWorkstreamsSectionCollapsed(Boolean(state.planningWorkstreamsSectionCollapsed));
616
+ if (state.planningNavigatorSort === 'default'
617
+ || state.planningNavigatorSort === 'title'
618
+ || state.planningNavigatorSort === 'owner'
619
+ || state.planningNavigatorSort === 'progress') {
620
+ setPlanningNavigatorSort(state.planningNavigatorSort);
621
+ }
622
+ setPlanningTaskArrangeMode(normalizePlanningTaskArrangeMode(state.planningTaskArrangeMode));
623
+ setPlanningFavorites(Array.isArray(state.planningFavorites) ? state.planningFavorites : []);
624
+ if (Array.isArray(state.planningExpandedInitiativeIds)) {
625
+ setExpandedPlanningInitiativeIds(new Set(state.planningExpandedInitiativeIds));
626
+ }
627
+ if (state.planningDrawerDetail !== undefined) {
628
+ setPlanningDrawerDetail(state.planningDrawerDetail);
629
+ }
630
+ if (typeof state.planningNestedWorkstreamDetailId === 'string' || state.planningNestedWorkstreamDetailId === null) {
631
+ setPlanningNestedWorkstreamDetailId(state.planningNestedWorkstreamDetailId);
632
+ }
633
+ const annotatedTarget = state.annotatedTarget && typeof state.annotatedTarget === 'object'
634
+ ? state.annotatedTarget
635
+ : null;
636
+ const annotatedSessionId = annotatedTarget && typeof state.annotatedSessionId === 'string'
637
+ ? state.annotatedSessionId
638
+ : null;
639
+ if (shouldApplyPersistedAnnotatedAttachmentContext({
640
+ currentTarget: requestedAnnotatedTargetRef.current,
641
+ currentSessionId: requestedAnnotatedSessionIdRef.current,
642
+ lastHydratedIdentity: lastHydratedAnnotatedContextIdentityRef.current,
643
+ })) {
644
+ requestedAnnotatedTargetRef.current = annotatedTarget;
645
+ requestedAnnotatedSessionIdRef.current = annotatedSessionId;
646
+ lastHydratedAnnotatedContextIdentityRef.current = getAnnotatedAttachmentContextIdentity(annotatedTarget, annotatedSessionId);
647
+ setRequestedAnnotatedTarget(annotatedTarget);
648
+ setRequestedAnnotatedSessionId(annotatedSessionId);
649
+ }
650
+ setAnnotatedViewportByContextKey(state.annotatedViewportByContextKey && typeof state.annotatedViewportByContextKey === 'object'
651
+ ? state.annotatedViewportByContextKey
652
+ : {});
653
+ }, []);
654
+ const layoutUiStateSnapshot = useMemo(() => ({
655
+ scheduleShowWeekends,
656
+ scheduleShowBacklog,
657
+ scheduleOnlyExpired,
658
+ scheduleSidebarOpen,
659
+ scheduleSelectedDate,
660
+ scheduleCalendarMonth,
661
+ scheduleScrollLeft,
662
+ showFilters,
663
+ documentTypeFilters,
664
+ documentAttachmentFilters,
665
+ documentSortField,
666
+ documentSortOrder,
667
+ documentPinnedDocIds,
668
+ documentSearchQuery,
669
+ documentSelectedDocId,
670
+ documentScrollByDocId,
671
+ documentListScrollTop,
672
+ documentTrayOpen,
673
+ imageTrayOpen,
674
+ agentTrayOpen,
675
+ taskforceAgentRosterTrayOpen,
676
+ taskforceAgentDrawerOpen,
677
+ taskforceAgentPanelCollapsed,
678
+ planningDrawerOpen,
679
+ planningTreeCollapsed,
680
+ planningPrimaryCollapsed,
681
+ planningSecondaryCollapsed,
682
+ planningFavoritesSectionCollapsed,
683
+ planningInitiativesSectionCollapsed,
684
+ planningWorkstreamsSectionCollapsed,
685
+ planningNavigatorSort,
686
+ planningTaskArrangeMode,
687
+ planningFavorites,
688
+ planningExpandedInitiativeIds: Array.from(expandedPlanningInitiativeIds),
689
+ planningDrawerDetail,
690
+ planningNestedWorkstreamDetailId,
691
+ annotatedTarget: scopedRequestedAnnotatedTarget,
692
+ annotatedSessionId: scopedRequestedAnnotatedSessionId,
693
+ annotatedViewportByContextKey,
694
+ }), [
576
695
  scheduleShowWeekends,
577
696
  scheduleShowBacklog,
578
697
  scheduleOnlyExpired,
@@ -583,33 +702,52 @@ export function StandaloneLayout(props) {
583
702
  showFilters,
584
703
  documentTypeFilters,
585
704
  documentAttachmentFilters,
705
+ documentSortField,
706
+ documentSortOrder,
707
+ documentPinnedDocIds,
708
+ documentSearchQuery,
709
+ documentSelectedDocId,
710
+ documentScrollByDocId,
711
+ documentListScrollTop,
586
712
  documentTrayOpen,
587
713
  imageTrayOpen,
588
714
  agentTrayOpen,
715
+ taskforceAgentRosterTrayOpen,
716
+ taskforceAgentDrawerOpen,
717
+ taskforceAgentPanelCollapsed,
589
718
  planningDrawerOpen,
590
719
  planningTreeCollapsed,
591
720
  planningPrimaryCollapsed,
592
721
  planningSecondaryCollapsed,
722
+ planningFavoritesSectionCollapsed,
723
+ planningInitiativesSectionCollapsed,
724
+ planningWorkstreamsSectionCollapsed,
725
+ planningNavigatorSort,
726
+ planningTaskArrangeMode,
727
+ planningFavorites,
593
728
  expandedPlanningInitiativeIds,
594
729
  planningDrawerDetail,
595
730
  planningNestedWorkstreamDetailId,
596
- requestedAnnotatedTarget,
597
- requestedAnnotatedSessionId,
598
- workspaceUiStateHeaders
731
+ scopedRequestedAnnotatedTarget,
732
+ scopedRequestedAnnotatedSessionId,
733
+ annotatedViewportByContextKey,
599
734
  ]);
600
735
  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]);
736
+ setPlanningFavorites([]);
737
+ }, [layoutStateWorkspaceKey]);
738
+ const { ready: layoutUiStateReady } = usePersistedLayoutUiState({
739
+ currentWorkspaceId,
740
+ loadKey: layoutStateWorkspaceKey,
741
+ enabled: runtimeMode !== 'cloud' || authSessionResolved,
742
+ headers: workspaceUiStateHeaders,
743
+ remotePlanningFavoritesAuthoritative: Boolean(normalizedAuthUserId)
744
+ && normalizedAuthUserId !== 'anonymous',
745
+ useCloudProxy: runtimeMode === 'local'
746
+ && Boolean(normalizedAuthUserId)
747
+ && normalizedAuthUserId !== 'anonymous',
748
+ snapshot: layoutUiStateSnapshot,
749
+ onApplyState: applyPersistedLayoutState,
750
+ });
613
751
  useEffect(() => {
614
752
  if (groupBy === 'schedule') {
615
753
  setScheduleSidebarOpen(true);
@@ -660,11 +798,16 @@ export function StandaloneLayout(props) {
660
798
  pushNotice(annotatedAttachmentsWorkspaceUnavailableMessage, 'error');
661
799
  return;
662
800
  }
663
- setRequestedAnnotatedTarget(detail);
664
- setRequestedAnnotatedSessionId(null);
665
- setRequestedAnnotatedOpenVersion((current) => current + 1);
666
- rememberTaskOriginWorkspaceModule(detail.taskId);
667
- setActiveWorkspaceModule('annotate');
801
+ handoffTaskModalToWorkspace(() => {
802
+ requestedAnnotatedTargetRef.current = detail;
803
+ const sessionId = String(detail.sessionId || '').trim() || null;
804
+ requestedAnnotatedSessionIdRef.current = sessionId;
805
+ setRequestedAnnotatedTarget(detail);
806
+ setRequestedAnnotatedSessionId(sessionId);
807
+ setRequestedAnnotatedOpenVersion((current) => current + 1);
808
+ rememberTaskOriginWorkspaceModule(detail.taskId);
809
+ setActiveWorkspaceModule('annotate');
810
+ });
668
811
  };
669
812
  window.addEventListener('taskforce:open-annotated-attachment', handleOpenAnnotatedAttachment);
670
813
  return () => {
@@ -674,21 +817,22 @@ export function StandaloneLayout(props) {
674
817
  annotatedAttachmentTasks,
675
818
  annotatedAttachmentsWorkspaceEnabled,
676
819
  annotatedAttachmentsWorkspaceUnavailableMessage,
820
+ handoffTaskModalToWorkspace,
677
821
  pushNotice,
678
822
  rememberTaskOriginWorkspaceModule,
679
823
  setActiveWorkspaceModule
680
824
  ]);
681
825
  useEffect(() => {
682
- if (!requestedAnnotatedTarget)
826
+ if (!scopedRequestedAnnotatedTarget)
683
827
  return;
684
- const resolvedTarget = resolveAnnotatedAttachmentDetail(requestedAnnotatedTarget, annotatedAttachmentTasks);
828
+ const resolvedTarget = resolveAnnotatedAttachmentDetail(scopedRequestedAnnotatedTarget, annotatedAttachmentTasks);
685
829
  if (!resolvedTarget)
686
830
  return;
687
- if (resolvedTarget.taskReferenceLabel === requestedAnnotatedTarget.taskReferenceLabel
688
- && resolvedTarget.imageReferenceLabel === requestedAnnotatedTarget.imageReferenceLabel)
831
+ if (resolvedTarget.taskReferenceLabel === scopedRequestedAnnotatedTarget.taskReferenceLabel
832
+ && resolvedTarget.imageReferenceLabel === scopedRequestedAnnotatedTarget.imageReferenceLabel)
689
833
  return;
690
834
  setRequestedAnnotatedTarget(resolvedTarget);
691
- }, [annotatedAttachmentTasks, requestedAnnotatedTarget]);
835
+ }, [annotatedAttachmentTasks, scopedRequestedAnnotatedTarget]);
692
836
  useEffect(() => {
693
837
  const activeTarget = requestedAnnotatedTargetRef.current;
694
838
  const normalizedAssetId = String(activeTarget?.assetId || '').trim();
@@ -707,11 +851,11 @@ export function StandaloneLayout(props) {
707
851
  imageReferenceLabel: canonicalReferenceLabel,
708
852
  };
709
853
  });
710
- }, [canonicalAnnotatedImageReferenceLabels, requestedAnnotatedTarget]);
854
+ }, [canonicalAnnotatedImageReferenceLabels, scopedRequestedAnnotatedTarget]);
711
855
  useEffect(() => {
712
856
  if (!annotatedWorkspaceReady)
713
857
  return;
714
- const activeTarget = requestedAnnotatedTarget;
858
+ const activeTarget = scopedRequestedAnnotatedTarget;
715
859
  const normalizedAssetId = String(activeTarget?.assetId || '').trim();
716
860
  if (!normalizedAssetId)
717
861
  return;
@@ -756,11 +900,13 @@ export function StandaloneLayout(props) {
756
900
  return () => {
757
901
  cancelled = true;
758
902
  };
759
- }, [annotatedWorkspaceReady, canonicalAnnotatedImageReferenceLabels, currentWorkspaceId, requestedAnnotatedTarget, workspaceUiStateHeaders]);
903
+ }, [annotatedWorkspaceReady, canonicalAnnotatedImageReferenceLabels, currentWorkspaceId, scopedRequestedAnnotatedTarget, workspaceUiStateHeaders]);
760
904
  const deletedScopeAllTasks = useMemo(() => props.deletedTasks.map((entry) => ({
761
905
  ...entry.taskSnapshot,
762
906
  isDeleted: true,
763
- deletedRecordId: entry.id
907
+ deletedRecordId: entry.id,
908
+ deletedAt: entry.deletedAt,
909
+ deletedExpiresAt: getDeletedTaskExpiresAt(entry.deletedAt),
764
910
  })), [props.deletedTasks]);
765
911
  const deletedTaskRecordByTaskId = useMemo(() => {
766
912
  const map = new Map();
@@ -825,18 +971,26 @@ export function StandaloneLayout(props) {
825
971
  .map((type) => ({ value: type.value, label: `${type.label} (Retired)` }));
826
972
  return [...activeTypeOptions, ...retiredTypesInUse];
827
973
  }, [activeTypes, taskFilterRecords]);
974
+ const applyTaskHeaderQuickFilter = useCallback((candidateTasks) => {
975
+ if (!taskHeaderQuickFilter)
976
+ return candidateTasks;
977
+ return candidateTasks.filter((task) => matchesTaskHeaderQuickFilter(task, taskHeaderQuickFilter, normalizedAuthUserId, todayDateOnly));
978
+ }, [normalizedAuthUserId, taskHeaderQuickFilter, todayDateOnly]);
979
+ const quickFilteredOpenTasks = useMemo(() => applyTaskHeaderQuickFilter(props.filteredTasks), [applyTaskHeaderQuickFilter, props.filteredTasks]);
828
980
  const kanbanTasks = useMemo(() => {
829
981
  if (taskScope === 'archived')
830
982
  return archivedScopeTasks;
831
983
  if (taskScope === 'deleted')
832
984
  return filteredDeletedTasks;
833
985
  if (!showArchive)
834
- return props.filteredTasks;
835
- return [...props.filteredTasks, ...archivedScopeTasks];
836
- }, [archivedScopeTasks, filteredDeletedTasks, props.filteredTasks, showArchive, taskScope]);
986
+ return quickFilteredOpenTasks;
987
+ return [...quickFilteredOpenTasks, ...archivedScopeTasks];
988
+ }, [archivedScopeTasks, filteredDeletedTasks, quickFilteredOpenTasks, showArchive, taskScope]);
837
989
  const scheduleBaseTasks = useMemo(() => taskScope === 'open'
838
- ? props.tasks.filter(task => !task.isArchived)
839
- : kanbanTasks, [kanbanTasks, props.tasks, taskScope]);
990
+ ? (taskHeaderQuickFilter
991
+ ? quickFilteredOpenTasks
992
+ : props.tasks.filter(task => !task.isArchived))
993
+ : kanbanTasks, [kanbanTasks, props.tasks, quickFilteredOpenTasks, taskHeaderQuickFilter, taskScope]);
840
994
  const scheduleFilteredTaskIds = useMemo(() => new Set(kanbanTasks.map(task => task.id)), [kanbanTasks]);
841
995
  const kanbanAllTasks = useMemo(() => {
842
996
  if (taskScope === 'archived')
@@ -875,16 +1029,34 @@ export function StandaloneLayout(props) {
875
1029
  return map;
876
1030
  }, [assigneeOptions, authUserDisplayName, authUserEmail, authUserId]);
877
1031
  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());
1032
+ const prerequisiteTaskIdsByTaskId = new Map();
1033
+ props.workspaceTaskRelationships.forEach((relationship) => {
1034
+ if (relationship.deletedAt || relationship.kind !== 'dependency')
1035
+ return;
1036
+ const current = prerequisiteTaskIdsByTaskId.get(relationship.sourceTaskId) || [];
1037
+ current.push(relationship.targetTaskId);
1038
+ prerequisiteTaskIdsByTaskId.set(relationship.sourceTaskId, current);
1039
+ });
1040
+ const planningLifetimeTasks = mergePlanningLifetimeTasks(props.tasks, archivedScopeAllTasks);
1041
+ const planningLifetimeTaskById = new Map(planningLifetimeTasks.map((task) => [task.id, task]));
1042
+ const getDependencyState = (taskId) => {
1043
+ const prerequisiteIds = prerequisiteTaskIdsByTaskId.get(taskId) || [];
1044
+ if (prerequisiteIds.length === 0)
1045
+ return 'ready';
1046
+ let invalid = false;
1047
+ for (const prerequisiteId of prerequisiteIds) {
1048
+ const prerequisite = planningLifetimeTaskById.get(prerequisiteId);
1049
+ if (!prerequisite || getStatusDefinition(prerequisite.status).value === 'cancelled') {
1050
+ invalid = true;
1051
+ continue;
1052
+ }
1053
+ if (getStatusDefinition(prerequisite.status).value !== 'done')
1054
+ return 'blocked';
1055
+ }
1056
+ return invalid ? 'invalid' : 'ready';
1057
+ };
1058
+ const planningProgressTasks = planningLifetimeTasks;
1059
+ const planningPreviewTasks = planningLifetimeTasks;
888
1060
  const summarizeTaskCounts = (taskCount, completedTaskCount) => {
889
1061
  return {
890
1062
  progressPercent: taskCount > 0 ? Math.round((completedTaskCount / taskCount) * 100) : 0,
@@ -892,19 +1064,53 @@ export function StandaloneLayout(props) {
892
1064
  completedTaskCount,
893
1065
  };
894
1066
  };
895
- const useBootstrapTaskSummaries = taskScope === 'open'
896
- && props.planningBootstrapTaskSummaries.length > 0
897
- && (props.loadingTasks || props.tasks.length === 0);
1067
+ const summarizeTaskStatuses = (tasks) => {
1068
+ const counts = {
1069
+ task: 0,
1070
+ 'on-hold': 0,
1071
+ 'in-progress': 0,
1072
+ review: 0,
1073
+ done: 0,
1074
+ cancelled: 0,
1075
+ };
1076
+ tasks.forEach((task) => {
1077
+ counts[getStatusDefinition(task.status).value] += 1;
1078
+ });
1079
+ return counts;
1080
+ };
1081
+ const combineTaskStatuses = (workstreams) => {
1082
+ const counts = summarizeTaskStatuses([]);
1083
+ workstreams.forEach((workstream) => {
1084
+ Object.entries(workstream.statusCounts || {}).forEach(([status, count]) => {
1085
+ counts[status] += Number(count) || 0;
1086
+ });
1087
+ });
1088
+ return counts;
1089
+ };
1090
+ const useBootstrapTaskSummaries = shouldUsePlanningBootstrapTaskSummaries({
1091
+ taskScope,
1092
+ summaryCount: props.planningBootstrapTaskSummaries.length,
1093
+ loadingTasks: props.loadingTasks,
1094
+ activeTaskCount: props.tasks.length,
1095
+ archiveHydrated: props.archiveHydratedWorkspaceId === currentWorkspaceId,
1096
+ });
898
1097
  const workstreamTaskSummaryById = new Map();
899
1098
  const workstreamTaskPreviewsById = new Map();
1099
+ const workstreamStatusCountsById = new Map();
900
1100
  if (useBootstrapTaskSummaries) {
901
1101
  props.planningBootstrapTaskSummaries.forEach((summary) => {
902
- workstreamTaskSummaryById.set(summary.workstreamId, summary);
903
- workstreamTaskPreviewsById.set(summary.workstreamId, summary.tasks || []);
1102
+ const tasks = (summary.tasks || []).map((task) => ({
1103
+ ...task,
1104
+ prerequisiteTaskIds: prerequisiteTaskIdsByTaskId.get(task.id) || [],
1105
+ dependencyState: getDependencyState(task.id),
1106
+ }));
1107
+ workstreamTaskSummaryById.set(summary.workstreamId, { ...summary, tasks });
1108
+ workstreamTaskPreviewsById.set(summary.workstreamId, tasks);
1109
+ workstreamStatusCountsById.set(summary.workstreamId, summarizeTaskStatuses(tasks));
904
1110
  });
905
1111
  }
906
1112
  else {
907
- planningScopedTasks.forEach((task) => {
1113
+ planningProgressTasks.forEach((task) => {
908
1114
  const workstreamId = String(task.workstreamId || '').trim();
909
1115
  if (!workstreamId)
910
1116
  return;
@@ -915,9 +1121,12 @@ export function StandaloneLayout(props) {
915
1121
  tasks: [],
916
1122
  };
917
1123
  current.taskCount += 1;
918
- if (task.isArchived || task.status === 'done' || task.status === 'cancelled') {
1124
+ if (task.status === 'done' || task.status === 'cancelled') {
919
1125
  current.completedTaskCount += 1;
920
1126
  }
1127
+ const statusCounts = workstreamStatusCountsById.get(workstreamId) || summarizeTaskStatuses([]);
1128
+ statusCounts[getStatusDefinition(task.status).value] += 1;
1129
+ workstreamStatusCountsById.set(workstreamId, statusCounts);
921
1130
  workstreamTaskSummaryById.set(workstreamId, current);
922
1131
  });
923
1132
  planningPreviewTasks.forEach((task) => {
@@ -928,8 +1137,17 @@ export function StandaloneLayout(props) {
928
1137
  current.push({
929
1138
  id: task.id,
930
1139
  referenceNumber: task.referenceNumber ?? null,
1140
+ localReferenceNumber: task.localReferenceNumber ?? null,
1141
+ referenceLabel: task.referenceLabel,
931
1142
  title: task.title,
1143
+ createdAt: task.createdAt,
932
1144
  status: task.status || null,
1145
+ priority: Number(task.priority) || 0,
1146
+ workstreamOrder: task.workstreamOrder ?? null,
1147
+ prerequisiteTaskIds: prerequisiteTaskIdsByTaskId.get(task.id) || [],
1148
+ dependencyState: getDependencyState(task.id),
1149
+ assignee: task.assignee || null,
1150
+ attachmentCount: Array.isArray(task.attachments) ? task.attachments.length : 0,
933
1151
  isArchived: Boolean(task.isArchived),
934
1152
  });
935
1153
  workstreamTaskPreviewsById.set(workstreamId, current);
@@ -942,6 +1160,12 @@ export function StandaloneLayout(props) {
942
1160
  const buildWorkstreamSummary = (workstream) => {
943
1161
  const taskSummary = workstreamTaskSummaryById.get(workstream.id);
944
1162
  const taskPreviews = workstreamTaskPreviewsById.get(workstream.id) || taskSummary?.tasks || [];
1163
+ const taskCounts = summarizeTaskCounts(taskSummary?.taskCount || 0, taskSummary?.completedTaskCount || 0);
1164
+ const archiveReadiness = resolveWorkstreamArchiveReadiness({
1165
+ isArchived: Boolean(workstream.isArchived),
1166
+ tasks: taskPreviews,
1167
+ dataReady: !useBootstrapTaskSummaries,
1168
+ });
945
1169
  const summary = {
946
1170
  id: workstream.id,
947
1171
  referenceNumber: workstream.referenceNumber ?? null,
@@ -949,12 +1173,18 @@ export function StandaloneLayout(props) {
949
1173
  description: String(workstream.description || '').trim() || undefined,
950
1174
  ownerId: workstream.ownerId ? String(workstream.ownerId) : null,
951
1175
  ownerLabel: workstream.ownerId ? assigneeLabelByValue.get(String(workstream.ownerId)) || String(workstream.ownerId) : null,
952
- ...summarizeTaskCounts(taskSummary?.taskCount || 0, taskSummary?.completedTaskCount || 0),
1176
+ ...taskCounts,
1177
+ statusCounts: workstreamStatusCountsById.get(workstream.id) || summarizeTaskStatuses([]),
953
1178
  initiativeId: workstream.initiativeId || null,
954
1179
  commentCount: Array.isArray(workstream.comments) ? workstream.comments.length : 0,
1180
+ comments: Array.isArray(workstream.comments) ? workstream.comments : [],
1181
+ activity: Array.isArray(workstream.activity) ? workstream.activity : [],
1182
+ entityEvents: Array.isArray(workstream.entityEvents) ? workstream.entityEvents : [],
955
1183
  attachmentCount: Array.isArray(workstream.attachments) ? workstream.attachments.length : 0,
956
1184
  attachments: Array.isArray(workstream.attachments) ? workstream.attachments : [],
957
1185
  isArchived: Boolean(workstream.isArchived),
1186
+ archiveReady: archiveReadiness.archiveReady,
1187
+ archiveActiveTaskCount: archiveReadiness.activeTaskCount,
958
1188
  tasks: taskPreviews,
959
1189
  };
960
1190
  workstreamTaskIds.set(workstream.id, taskPreviews.map((task) => task.id));
@@ -972,8 +1202,14 @@ export function StandaloneLayout(props) {
972
1202
  const allWorkstreamsForInitiative = workstreamsByInitiativeId.get(initiative.id) || [];
973
1203
  const workstreams = allWorkstreamsForInitiative
974
1204
  .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);
1205
+ const taskCount = allWorkstreamsForInitiative.reduce((sum, workstream) => sum + workstream.taskCount, 0);
1206
+ const completedTaskCount = allWorkstreamsForInitiative.reduce((sum, workstream) => sum + workstream.completedTaskCount, 0);
1207
+ const initiativeTaskCounts = summarizeTaskCounts(taskCount, completedTaskCount);
1208
+ const archiveReadiness = resolveInitiativeArchiveReadiness({
1209
+ isArchived: Boolean(initiative.isArchived),
1210
+ workstreams: allWorkstreamsForInitiative,
1211
+ dataReady: !useBootstrapTaskSummaries,
1212
+ });
977
1213
  const initiativeSummary = {
978
1214
  id: initiative.id,
979
1215
  referenceNumber: initiative.referenceNumber ?? null,
@@ -981,14 +1217,21 @@ export function StandaloneLayout(props) {
981
1217
  description: String(initiative.description || '').trim() || undefined,
982
1218
  ownerId: initiative.ownerId ? String(initiative.ownerId) : null,
983
1219
  ownerLabel: initiative.ownerId ? assigneeLabelByValue.get(String(initiative.ownerId)) || String(initiative.ownerId) : null,
984
- ...summarizeTaskCounts(taskCount, completedTaskCount),
1220
+ ...initiativeTaskCounts,
1221
+ statusCounts: combineTaskStatuses(allWorkstreamsForInitiative),
985
1222
  workstreamCount: workstreams.length,
986
1223
  workstreams,
987
1224
  allWorkstreams: allWorkstreamsForInitiative,
988
1225
  commentCount: Array.isArray(initiative.comments) ? initiative.comments.length : 0,
1226
+ comments: Array.isArray(initiative.comments) ? initiative.comments : [],
1227
+ activity: Array.isArray(initiative.activity) ? initiative.activity : [],
1228
+ entityEvents: Array.isArray(initiative.entityEvents) ? initiative.entityEvents : [],
989
1229
  attachmentCount: Array.isArray(initiative.attachments) ? initiative.attachments.length : 0,
990
1230
  attachments: Array.isArray(initiative.attachments) ? initiative.attachments : [],
991
1231
  isArchived: Boolean(initiative.isArchived),
1232
+ archiveReady: archiveReadiness.archiveReady,
1233
+ archiveActiveTaskCount: archiveReadiness.activeTaskCount,
1234
+ archiveActiveWorkstreamCount: archiveReadiness.activeWorkstreamCount,
992
1235
  };
993
1236
  return initiativeSummary;
994
1237
  });
@@ -1000,7 +1243,10 @@ export function StandaloneLayout(props) {
1000
1243
  return {
1001
1244
  initiatives,
1002
1245
  standaloneWorkstreams,
1246
+ allInitiatives,
1003
1247
  allStandaloneWorkstreams,
1248
+ allInitiativeById: new Map(allInitiatives.map((initiative) => [initiative.id, initiative])),
1249
+ allWorkstreamById: new Map(allWorkstreamSummaries.map((workstream) => [workstream.id, workstream])),
1004
1250
  workstreamTaskIds,
1005
1251
  workstreamInitiativeIds,
1006
1252
  initiativeTaskIds,
@@ -1009,11 +1255,13 @@ export function StandaloneLayout(props) {
1009
1255
  };
1010
1256
  }, [
1011
1257
  archivedScopeAllTasks,
1258
+ currentWorkspaceId,
1259
+ props.archiveHydratedWorkspaceId,
1012
1260
  assigneeLabelByValue,
1013
- deletedScopeAllTasks,
1014
1261
  props.initiatives,
1015
1262
  props.loadingTasks,
1016
1263
  props.planningBootstrapTaskSummaries,
1264
+ props.workspaceTaskRelationships,
1017
1265
  props.tasks,
1018
1266
  props.workstreams,
1019
1267
  taskScope,
@@ -1025,6 +1273,41 @@ export function StandaloneLayout(props) {
1025
1273
  label: referenceLabel || initiative.title,
1026
1274
  };
1027
1275
  }), [planningStructure.initiatives]);
1276
+ const planningLinkOptions = useMemo(() => {
1277
+ const sortByTitle = (left, right) => (left.title.localeCompare(right.title, undefined, { sensitivity: 'base' }));
1278
+ const initiatives = Array.from(planningStructure.allInitiativeById.values())
1279
+ .filter((initiative) => !initiative.isArchived)
1280
+ .map((initiative) => ({
1281
+ id: initiative.id,
1282
+ referenceLabel: formatInitiativeReference(initiative) || initiative.id,
1283
+ title: initiative.title,
1284
+ meta: `${initiative.workstreamCount || 0} workstream${initiative.workstreamCount === 1 ? '' : 's'}`,
1285
+ }))
1286
+ .sort(sortByTitle);
1287
+ const workstreams = Array.from(planningStructure.allWorkstreamById.values())
1288
+ .filter((workstream) => !workstream.isArchived)
1289
+ .map((workstream) => ({
1290
+ id: workstream.id,
1291
+ referenceLabel: formatWorkstreamReference(workstream) || workstream.id,
1292
+ title: workstream.title,
1293
+ meta: workstream.initiativeId
1294
+ ? `In ${planningStructure.allInitiativeById.get(workstream.initiativeId)?.title || 'another initiative'}`
1295
+ : 'Standalone workstream',
1296
+ }))
1297
+ .sort(sortByTitle);
1298
+ const tasks = hierarchyTasks
1299
+ .filter((task) => !task.isArchived && !task.isDeleted)
1300
+ .map((task) => ({
1301
+ id: task.id,
1302
+ referenceLabel: getTaskReferenceLabel(task) || task.id,
1303
+ title: task.title,
1304
+ meta: task.workstreamId
1305
+ ? `In ${planningStructure.allWorkstreamById.get(task.workstreamId)?.title || 'another workstream'}`
1306
+ : 'Unassigned to a workstream',
1307
+ }))
1308
+ .sort(sortByTitle);
1309
+ return { initiatives, workstreams, tasks };
1310
+ }, [hierarchyTasks, planningStructure.allInitiativeById, planningStructure.allWorkstreamById]);
1028
1311
  const workstreamFilterOptions = useMemo(() => {
1029
1312
  const visibleInitiativeWorkstreams = selectedPlanningInitiativeId
1030
1313
  ? (planningStructure.initiativeById.get(selectedPlanningInitiativeId)?.workstreams || [])
@@ -1065,22 +1348,20 @@ export function StandaloneLayout(props) {
1065
1348
  if (!planningDrawerDetail)
1066
1349
  return null;
1067
1350
  if (planningDrawerDetail.type === 'initiative') {
1068
- const item = planningStructure.initiativeById.get(planningDrawerDetail.id);
1351
+ const item = planningStructure.allInitiativeById.get(planningDrawerDetail.id);
1069
1352
  return item ? { type: 'initiative', item } : null;
1070
1353
  }
1071
- const item = planningStructure.workstreamById.get(planningDrawerDetail.id)
1072
- || planningStructure.standaloneWorkstreams.find((workstream) => workstream.id === planningDrawerDetail.id);
1354
+ const item = planningStructure.allWorkstreamById.get(planningDrawerDetail.id);
1073
1355
  return item ? { type: 'workstream', item } : null;
1074
- }, [planningDrawerDetail, planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
1356
+ }, [planningDrawerDetail, planningStructure.allInitiativeById, planningStructure.allWorkstreamById]);
1075
1357
  const planningNestedWorkstreamItem = useMemo(() => {
1076
1358
  if (!planningNestedWorkstreamDetailId)
1077
1359
  return null;
1078
- const item = planningStructure.workstreamById.get(planningNestedWorkstreamDetailId)
1079
- || planningStructure.standaloneWorkstreams.find((workstream) => workstream.id === planningNestedWorkstreamDetailId);
1360
+ const item = planningStructure.allWorkstreamById.get(planningNestedWorkstreamDetailId);
1080
1361
  return item ? { type: 'workstream', item } : null;
1081
- }, [planningNestedWorkstreamDetailId, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
1362
+ }, [planningNestedWorkstreamDetailId, planningStructure.allWorkstreamById]);
1082
1363
  const planningSecondaryPane = useMemo(() => {
1083
- if (planningSecondaryEditor) {
1364
+ if (planningSecondaryEditor?.mode === 'create') {
1084
1365
  return { kind: 'editor', editor: planningSecondaryEditor };
1085
1366
  }
1086
1367
  if (planningNestedWorkstreamItem) {
@@ -1088,15 +1369,22 @@ export function StandaloneLayout(props) {
1088
1369
  }
1089
1370
  return null;
1090
1371
  }, [planningNestedWorkstreamItem, planningSecondaryEditor]);
1091
- const planningDrawerWidthPx = getPlanningDrawerWidthPx(planningTreeCollapsed, Boolean(planningDrawerItem || planningEditor), planningPrimaryCollapsed, Boolean(planningSecondaryPane), planningSecondaryCollapsed);
1372
+ const primaryPlanningHydrationState = planningDrawerDetail
1373
+ ? planningHydrationStateByEntity[`${planningDrawerDetail.type}:${planningDrawerDetail.id}`]
1374
+ : undefined;
1375
+ const secondaryPlanningHydrationState = planningNestedWorkstreamDetailId
1376
+ ? planningHydrationStateByEntity[`workstream:${planningNestedWorkstreamDetailId}`]
1377
+ : undefined;
1378
+ const planningDrawerEstimatedWidthPx = getPlanningDrawerWidthPx(planningTreeCollapsed, Boolean(planningDrawerItem || planningEditor), planningPrimaryCollapsed, Boolean(planningSecondaryPane), planningSecondaryCollapsed);
1379
+ const [planningDrawerWidthPx, setPlanningDrawerWidthPx] = useState(planningDrawerEstimatedWidthPx);
1092
1380
  const planningDraftInitiativeSummary = useMemo(() => {
1093
1381
  if (!planningDraftInitiativeId.trim())
1094
1382
  return null;
1095
- const exactInitiative = planningStructure.initiativeById.get(planningDraftInitiativeId);
1383
+ const exactInitiative = planningStructure.allInitiativeById.get(planningDraftInitiativeId);
1096
1384
  if (exactInitiative)
1097
1385
  return exactInitiative;
1098
- return resolveInitiativeReference(planningStructure.initiatives, planningDraftInitiativeId);
1099
- }, [planningDraftInitiativeId, planningStructure.initiativeById, planningStructure.initiatives]);
1386
+ return resolveInitiativeReference(planningStructure.allInitiatives, planningDraftInitiativeId);
1387
+ }, [planningDraftInitiativeId, planningStructure.allInitiativeById, planningStructure.allInitiatives]);
1100
1388
  useEffect(() => {
1101
1389
  if (selectedPlanningInitiativeId && !planningStructure.initiativeById.has(selectedPlanningInitiativeId)) {
1102
1390
  setSelectedPlanningInitiativeId('');
@@ -1115,13 +1403,6 @@ export function StandaloneLayout(props) {
1115
1403
  return scheduleBaseTasks;
1116
1404
  return kanbanTasks;
1117
1405
  }, [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
1406
  const boardVisibleTasks = useMemo(() => {
1126
1407
  if (groupBy !== 'schedule' || !scheduleOnlyExpired)
1127
1408
  return hierarchyVisibleTasks;
@@ -1135,15 +1416,48 @@ export function StandaloneLayout(props) {
1135
1416
  });
1136
1417
  }, [groupBy, scheduleOnlyExpired, hierarchyVisibleTasks, todayDateOnly]);
1137
1418
  const scopedBoardVisibleTasks = useMemo(() => {
1138
- if (!selectedPlanningTaskIds || selectedPlanningTaskIds.size === 0)
1139
- return boardVisibleTasks;
1140
- return boardVisibleTasks.filter((task) => selectedPlanningTaskIds.has(task.id));
1419
+ return scopeTasksToPlanningSelection(boardVisibleTasks, selectedPlanningTaskIds);
1141
1420
  }, [boardVisibleTasks, selectedPlanningTaskIds]);
1421
+ const trashSelection = useTrashSelection(props.deletedTasks, scopedBoardVisibleTasks.map((task) => task.id), taskScope === 'deleted');
1142
1422
  const scopedKanbanAllTasks = useMemo(() => {
1143
- if (!selectedPlanningTaskIds || selectedPlanningTaskIds.size === 0)
1144
- return kanbanAllTasks;
1145
- return kanbanAllTasks.filter((task) => selectedPlanningTaskIds.has(task.id));
1423
+ return scopeTasksToPlanningSelection(kanbanAllTasks, selectedPlanningTaskIds);
1146
1424
  }, [kanbanAllTasks, selectedPlanningTaskIds]);
1425
+ const scheduleFilteredTaskIdList = useMemo(() => Array.from(scheduleFilteredTaskIds), [scheduleFilteredTaskIds]);
1426
+ const handleBoardScheduleDaySelected = useCallback((dateOnly) => {
1427
+ setScheduleSelectedDate(dateOnly);
1428
+ const parsed = parseDateOnlyLocal(dateOnly);
1429
+ if (parsed) {
1430
+ setScheduleCalendarMonth(`${parsed.getFullYear()}-${String(parsed.getMonth() + 1).padStart(2, '0')}`);
1431
+ }
1432
+ }, []);
1433
+ const handleBoardScrollLeftChange = useCallback((scrollLeft) => {
1434
+ if (groupBy !== 'schedule')
1435
+ return;
1436
+ setScheduleScrollLeft(scrollLeft);
1437
+ }, [groupBy]);
1438
+ const handleBoardUnarchive = useCallback((taskId) => {
1439
+ if (taskScope === 'deleted') {
1440
+ const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
1441
+ if (!deletedRecord)
1442
+ return;
1443
+ void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
1444
+ return;
1445
+ }
1446
+ void handleUnarchive(taskId);
1447
+ }, [deletedTaskRecordByTaskId, handleRestoreDeletedTask, handleUnarchive, taskScope]);
1448
+ const handleBoardDelete = useCallback((taskId) => {
1449
+ if (taskScope === 'deleted') {
1450
+ const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
1451
+ if (!deletedRecord)
1452
+ return;
1453
+ const confirmed = window.confirm('Permanently delete this task? This cannot be undone.');
1454
+ if (!confirmed)
1455
+ return;
1456
+ void handlePermanentlyDeleteDeletedTask(deletedRecord.id);
1457
+ return;
1458
+ }
1459
+ void handleDelete(taskId);
1460
+ }, [deletedTaskRecordByTaskId, handleDelete, handlePermanentlyDeleteDeletedTask, taskScope]);
1147
1461
  const expiredRecoveryCandidates = useMemo(() => {
1148
1462
  if (groupBy !== 'schedule')
1149
1463
  return [];
@@ -1176,7 +1490,6 @@ export function StandaloneLayout(props) {
1176
1490
  return !!task.dueDate && task.dueDate < todayDateOnly;
1177
1491
  }).length;
1178
1492
  }, [groupBy, hierarchyVisibleTasks, todayDateOnly]);
1179
- const normalizedAuthUserId = String(authUserId || '').trim();
1180
1493
  const assignedTaskCount = useMemo(() => {
1181
1494
  if (!normalizedAuthUserId || normalizedAuthUserId === 'anonymous')
1182
1495
  return 0;
@@ -1229,35 +1542,179 @@ export function StandaloneLayout(props) {
1229
1542
  setTaskModalFullscreen(false);
1230
1543
  }
1231
1544
  }, [activeTab]);
1232
- const handleSetStatus = useCallback((task, status) => {
1233
- if (task.status === status)
1545
+ const handleSetStatus = useCallback(async (task, status, options) => {
1546
+ if (task.status === status && !options?.allowSameStatus)
1234
1547
  return;
1235
- if (status === 'in-progress') {
1236
- void handleToggleInProgress(task);
1548
+ await handleSetStatusDurably(task, status);
1549
+ }, [handleSetStatusDurably]);
1550
+ const handleSetPlanningTaskStatus = useCallback(async (taskId, status) => {
1551
+ const task = hierarchyTaskById.get(taskId);
1552
+ if (!task) {
1553
+ pushNotice('Task details are still loading.', 'info');
1237
1554
  return;
1238
1555
  }
1239
- if (status === 'review') {
1240
- void handleToggleReview(task);
1241
- return;
1556
+ await handleSetStatus(task, status);
1557
+ await props.fetchPlanningEntities();
1558
+ }, [handleSetStatus, hierarchyTaskById, props.fetchPlanningEntities, pushNotice]);
1559
+ const handleChangePlanningTaskAssignee = useCallback(async (taskId, assignee) => {
1560
+ const saved = await handleUpdateTask(taskId, { assignee });
1561
+ if (saved !== false)
1562
+ await props.fetchPlanningEntities();
1563
+ }, [handleUpdateTask, props.fetchPlanningEntities]);
1564
+ const archivePlanningTaskById = useCallback(async (taskId) => {
1565
+ const task = hierarchyTaskById.get(taskId);
1566
+ if (!task) {
1567
+ pushNotice('Task details are still loading.', 'info');
1568
+ return false;
1242
1569
  }
1243
- if (status === 'done') {
1244
- void handleToggleComplete(task);
1245
- return;
1570
+ if (task.isArchived)
1571
+ return true;
1572
+ if (task.status !== 'done' && task.status !== 'cancelled') {
1573
+ pushNotice('Only completed or cancelled tasks can be archived from Planning.', 'error');
1574
+ return false;
1246
1575
  }
1247
- if (status === 'cancelled') {
1248
- void handleToggleCancel(task);
1249
- return;
1576
+ return handleArchiveTask(task);
1577
+ }, [handleArchiveTask, hierarchyTaskById, pushNotice]);
1578
+ const handleArchivePlanningTask = useCallback(async (taskId) => {
1579
+ const archived = await archivePlanningTaskById(taskId);
1580
+ if (archived) {
1581
+ await props.fetchPlanningEntities();
1582
+ pushNotice('Task archived', 'success');
1583
+ }
1584
+ return archived;
1585
+ }, [archivePlanningTaskById, props.fetchPlanningEntities, pushNotice]);
1586
+ const handleArchiveResolvedWorkstream = useCallback(async (workstreamId) => {
1587
+ const workstream = planningStructure.allWorkstreamById.get(workstreamId);
1588
+ if (!workstream?.archiveReady) {
1589
+ pushNotice('This workstream is no longer ready to archive.', 'error');
1590
+ return false;
1591
+ }
1592
+ try {
1593
+ const archived = await archiveResolvedWorkstreamHierarchy({
1594
+ workstream,
1595
+ archiveTask: archivePlanningTaskById,
1596
+ archiveWorkstream: props.archiveWorkstream,
1597
+ });
1598
+ if (!archived) {
1599
+ pushNotice('Workstream archive stopped safely. Resolve any remaining tasks and retry.', 'error');
1600
+ return false;
1601
+ }
1602
+ pushNotice('Completed tasks and workstream archived', 'success');
1603
+ return true;
1604
+ }
1605
+ catch (error) {
1606
+ pushNotice(error instanceof Error
1607
+ ? `Workstream archive stopped safely: ${error.message}`
1608
+ : 'Workstream archive stopped safely. Retry to archive the remaining items.', 'error');
1609
+ return false;
1610
+ }
1611
+ }, [archivePlanningTaskById, planningStructure.allWorkstreamById, props.archiveWorkstream, pushNotice]);
1612
+ const handleArchiveResolvedInitiative = useCallback(async (initiativeId) => {
1613
+ const initiative = planningStructure.allInitiativeById.get(initiativeId);
1614
+ if (!initiative?.archiveReady) {
1615
+ pushNotice('This initiative is no longer ready to archive.', 'error');
1616
+ return false;
1617
+ }
1618
+ try {
1619
+ const archived = await archiveResolvedInitiativeHierarchy({
1620
+ initiativeId: initiative.id,
1621
+ workstreams: initiative.allWorkstreams || initiative.workstreams,
1622
+ archiveTask: archivePlanningTaskById,
1623
+ archiveWorkstream: props.archiveWorkstream,
1624
+ archiveInitiative: props.archiveInitiative,
1625
+ });
1626
+ if (!archived) {
1627
+ pushNotice('Initiative archive stopped safely. Resolve any remaining tasks and retry.', 'error');
1628
+ return false;
1629
+ }
1630
+ pushNotice('Completed tasks, workstreams, and initiative archived', 'success');
1631
+ return true;
1632
+ }
1633
+ catch (error) {
1634
+ pushNotice(error instanceof Error
1635
+ ? `Initiative archive stopped safely: ${error.message}`
1636
+ : 'Initiative archive stopped safely. Retry to archive the remaining items.', 'error');
1637
+ return false;
1638
+ }
1639
+ }, [
1640
+ archivePlanningTaskById,
1641
+ planningStructure.allInitiativeById,
1642
+ props.archiveInitiative,
1643
+ props.archiveWorkstream,
1644
+ pushNotice,
1645
+ ]);
1646
+ const handleArchivePlanningEntity = useCallback(async (entityType, entityId) => {
1647
+ const item = entityType === 'initiative'
1648
+ ? planningStructure.allInitiativeById.get(entityId)
1649
+ : planningStructure.allWorkstreamById.get(entityId);
1650
+ if (!item) {
1651
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} not found.`, 'error');
1652
+ return false;
1250
1653
  }
1251
- void handleUpdateTask(task.id, {
1252
- status,
1253
- completedAt: null
1654
+ const archiveState = resolvePlanningArchiveDetailState({
1655
+ entityType,
1656
+ isArchived: item.isArchived,
1657
+ taskCount: item.taskCount,
1658
+ completedTaskCount: item.completedTaskCount,
1659
+ archiveReady: item.archiveReady,
1660
+ activeWorkstreamCount: item.archiveActiveWorkstreamCount,
1254
1661
  });
1255
- }, [handleToggleInProgress, handleToggleReview, handleToggleComplete, handleToggleCancel, handleUpdateTask]);
1662
+ if (archiveState.mode === 'archived')
1663
+ return true;
1664
+ if (archiveState.mode === 'ready') {
1665
+ return entityType === 'initiative'
1666
+ ? handleArchiveResolvedInitiative(entityId)
1667
+ : handleArchiveResolvedWorkstream(entityId);
1668
+ }
1669
+ if (archiveState.mode !== 'empty') {
1670
+ pushNotice(archiveState.mode === 'blocked'
1671
+ ? `Archive unavailable while active ${archiveState.remainingKind === 'task' ? 'tasks' : 'workstreams'} remain.`
1672
+ : 'Archive availability is still loading.', 'error');
1673
+ return false;
1674
+ }
1675
+ try {
1676
+ if (entityType === 'initiative') {
1677
+ await props.archiveInitiative(entityId);
1678
+ }
1679
+ else {
1680
+ await props.archiveWorkstream(entityId);
1681
+ }
1682
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} archived`, 'success');
1683
+ return true;
1684
+ }
1685
+ catch (error) {
1686
+ pushNotice(error instanceof Error ? error.message : `Failed to archive ${entityType}.`, 'error');
1687
+ return false;
1688
+ }
1689
+ }, [
1690
+ handleArchiveResolvedInitiative,
1691
+ handleArchiveResolvedWorkstream,
1692
+ planningStructure.allInitiativeById,
1693
+ planningStructure.allWorkstreamById,
1694
+ props.archiveInitiative,
1695
+ props.archiveWorkstream,
1696
+ pushNotice,
1697
+ ]);
1698
+ const handleUnarchivePlanningEntity = useCallback(async (entityType, entityId) => {
1699
+ try {
1700
+ if (entityType === 'initiative') {
1701
+ await props.unarchiveInitiative(entityId);
1702
+ }
1703
+ else {
1704
+ await props.unarchiveWorkstream(entityId);
1705
+ }
1706
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} unarchived`, 'success');
1707
+ return true;
1708
+ }
1709
+ catch (error) {
1710
+ pushNotice(error instanceof Error ? error.message : `Failed to unarchive ${entityType}.`, 'error');
1711
+ return false;
1712
+ }
1713
+ }, [props.unarchiveInitiative, props.unarchiveWorkstream, pushNotice]);
1256
1714
  const handleAddTaskToColumn = useCallback((groupField, value) => {
1257
1715
  resetForm();
1258
1716
  const defaults = resolveDraftDefaultsForGrouping(groupField, value, {
1259
- categories: activeCategories,
1260
- approaches
1717
+ categories: activeCategories
1261
1718
  });
1262
1719
  if (defaults.category)
1263
1720
  setCategory(defaults.category);
@@ -1267,12 +1724,6 @@ export function StandaloneLayout(props) {
1267
1724
  setPriority(defaults.priority);
1268
1725
  if (typeof defaults.complexity === 'number')
1269
1726
  setComplexity(defaults.complexity);
1270
- if (defaults.approach)
1271
- setApproach(defaults.approach);
1272
- const taxonomyApproach = defaults.taxonomyApproach;
1273
- if (typeof taxonomyApproach === 'string' && taxonomyApproach.length > 0) {
1274
- setFormTaxonomies(prev => ({ ...prev, approach: taxonomyApproach }));
1275
- }
1276
1727
  if (defaults.assignee)
1277
1728
  setAssignee(defaults.assignee);
1278
1729
  if (defaults.status)
@@ -1280,7 +1731,7 @@ export function StandaloneLayout(props) {
1280
1731
  if (defaults.scheduledDate)
1281
1732
  setScheduledDate(defaults.scheduledDate);
1282
1733
  setActiveTab('add');
1283
- }, [resetForm, activeCategories, approaches, setCategory, setType, setPriority, setComplexity, setStatus, setApproach, setAssignee, setScheduledDate, setFormTaxonomies, setActiveTab]);
1734
+ }, [resetForm, activeCategories, setCategory, setType, setPriority, setComplexity, setStatus, setAssignee, setScheduledDate, setActiveTab]);
1284
1735
  // Ensure 'done' status is shown by default as requested
1285
1736
  React.useEffect(() => {
1286
1737
  if (filterStatus && !filterStatus.includes('done')) {
@@ -1290,8 +1741,8 @@ export function StandaloneLayout(props) {
1290
1741
  // Local state for filter toolbar
1291
1742
  const [showHelpModal, setShowHelpModal] = useState(false);
1292
1743
  const [showAccountMenu, setShowAccountMenu] = useState(false);
1293
- const [showAccountHub, setShowAccountHub] = useState(false);
1294
- const [showEditProfileModal, setShowEditProfileModal] = useState(false);
1744
+ const [showAccountSettings, setShowAccountSettings] = useState(false);
1745
+ const accountSettingsWasOpenRef = useRef(false);
1295
1746
  const [showAvatarPhotoManager, setShowAvatarPhotoManager] = useState(false);
1296
1747
  const [workspaceActionBusy, setWorkspaceActionBusy] = useState(false);
1297
1748
  const [workspaceActionError, setWorkspaceActionError] = useState('');
@@ -1357,9 +1808,17 @@ export function StandaloneLayout(props) {
1357
1808
  const canManageCloudWorkspaces = runtimeMode === 'cloud' && workspaceSwitchingEnabled && isAuthenticated;
1358
1809
  const canAccessCloudTeamManagement = isAuthenticated && (runtimeMode === 'cloud' || cloudAuthConfigured);
1359
1810
  const canManageWorkspaceSync = runtimeMode === 'local' && isAuthenticated;
1811
+ const serverCoordinatorSyncEnabled = (localCoordinatorStatus?.phase === 'ready'
1812
+ && localCoordinatorStatus.snapshot?.state.ownershipMode === 'server')
1813
+ ? localCoordinatorStatus.snapshot.workspace?.runner?.checkpoint
1814
+ ?.checkpoint.syncEnabled
1815
+ : null;
1816
+ const effectiveWorkspaceCloudSyncEnabled = typeof serverCoordinatorSyncEnabled === 'boolean'
1817
+ ? serverCoordinatorSyncEnabled
1818
+ : workspaceCloudSyncEnabled;
1360
1819
  const { showSyncStatusModal, showSyncEnableWarning, workspaceSyncError, syncControlBusy, openSyncStatusModal, closeSyncStatusModal, handleWorkspaceSyncToggle, cancelSyncEnableWarning, confirmSyncEnableWarning, } = useSyncStatusControls({
1361
1820
  canManageWorkspaceSync,
1362
- workspaceCloudSyncEnabled,
1821
+ workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled,
1363
1822
  saveWorkspaceCloudSyncSettings,
1364
1823
  });
1365
1824
  const currentWorkspaceLabel = useMemo(() => {
@@ -1414,14 +1873,15 @@ export function StandaloneLayout(props) {
1414
1873
  ]);
1415
1874
  const isAuthBootstrapPending = cloudAuthConfigured && !authSessionResolved;
1416
1875
  useEffect(() => {
1417
- if (!showEditProfileModal)
1418
- return;
1419
- setProfileDisplayNameDraft(authDisplayName);
1420
- setProfileAvatarPreviewUrl(authAvatarUrl);
1421
- setProfileAvatarDraftId(null);
1422
- setProfileSaveError(null);
1423
- setProfileSaveNotice(null);
1424
- }, [authAvatarUrl, authDisplayName, showEditProfileModal]);
1876
+ if (showAccountSettings && !accountSettingsWasOpenRef.current) {
1877
+ setProfileDisplayNameDraft(authDisplayName);
1878
+ setProfileAvatarPreviewUrl(authAvatarUrl);
1879
+ setProfileAvatarDraftId(null);
1880
+ setProfileSaveError(null);
1881
+ setProfileSaveNotice(null);
1882
+ }
1883
+ accountSettingsWasOpenRef.current = showAccountSettings;
1884
+ }, [authAvatarUrl, authDisplayName, showAccountSettings]);
1425
1885
  const discardProfileAvatarDraft = useCallback(async (draftId) => {
1426
1886
  const normalizedDraftId = String(draftId || '').trim();
1427
1887
  if (!normalizedDraftId || !cloudAuthConfigured)
@@ -1438,9 +1898,9 @@ export function StandaloneLayout(props) {
1438
1898
  // Best-effort cleanup only.
1439
1899
  }
1440
1900
  }, [cloudAuthConfigured, resolveCloudAuthUrl]);
1441
- const closeEditProfileModal = useCallback(() => {
1901
+ const closeAccountSettingsModal = useCallback(() => {
1442
1902
  const pendingDraftId = profileAvatarDraftId;
1443
- setShowEditProfileModal(false);
1903
+ setShowAccountSettings(false);
1444
1904
  setShowAvatarPhotoManager(false);
1445
1905
  setProfileSaveError(null);
1446
1906
  setProfileSaveNotice(null);
@@ -1578,7 +2038,6 @@ export function StandaloneLayout(props) {
1578
2038
  setProfileAvatarPreviewUrl('');
1579
2039
  setProfileSaveBusy(false);
1580
2040
  setShowAvatarPhotoManager(false);
1581
- setShowEditProfileModal(false);
1582
2041
  }, [authAvatarUrl, profileAvatarDraftId, profileAvatarPreviewUrl, profileDisplayNameDraft, updateCurrentUserProfile]);
1583
2042
  const teamAdminHeaders = useCallback(() => {
1584
2043
  const headers = {};
@@ -1596,7 +2055,7 @@ export function StandaloneLayout(props) {
1596
2055
  }, [currentWorkspaceRole, teamManagementWorkspaceId, teamWorkspaceRole]);
1597
2056
  const startAccountSurfaceTiming = useCallback((surface) => {
1598
2057
  const expectsBilling = isAuthenticated;
1599
- const expectsTeamManagement = canAccessCloudTeamManagement;
2058
+ const expectsTeamManagement = surface === 'account_menu' && canAccessCloudTeamManagement;
1600
2059
  accountSurfaceOpenStartedAtRef.current = getTimingNow();
1601
2060
  accountSurfacePendingRef.current = {
1602
2061
  billing: expectsBilling,
@@ -1626,13 +2085,13 @@ export function StandaloneLayout(props) {
1626
2085
  if (startedAt === null)
1627
2086
  return;
1628
2087
  logBootstrapDebug('account_surface_ready', {
1629
- surface: showAccountHub ? 'account_hub' : (showAccountMenu ? 'account_menu' : 'closed'),
2088
+ surface: showAccountSettings ? 'account_settings' : (showAccountMenu ? 'account_menu' : 'closed'),
1630
2089
  durationMs: Math.round(getTimingNow() - startedAt),
1631
2090
  teamManagementVisible: canOpenTeamManagement,
1632
2091
  billingPlanId: String(accountProfileSummary?.planId || '').trim() || null
1633
2092
  });
1634
2093
  accountSurfaceOpenStartedAtRef.current = null;
1635
- }, [accountProfileSummary?.planId, canOpenTeamManagement, showAccountHub, showAccountMenu]);
2094
+ }, [accountProfileSummary?.planId, canOpenTeamManagement, showAccountMenu, showAccountSettings]);
1636
2095
  const loadAccountProfileSummary = useCallback(async (options) => {
1637
2096
  const accountProfileSummaryUrl = resolveCloudAuthUrl(ACCOUNT_PROFILE_SUMMARY_PATH);
1638
2097
  if (!isAuthenticated) {
@@ -1802,10 +2261,10 @@ export function StandaloneLayout(props) {
1802
2261
  void loadAccountProfileSummary();
1803
2262
  }, [authSessionResolved, isAuthenticated, loadAccountProfileSummary]);
1804
2263
  useEffect(() => {
1805
- if (!showAccountHub && !showAccountMenu)
2264
+ if (!showAccountSettings && !showAccountMenu)
1806
2265
  return;
1807
2266
  void loadAccountProfileSummary();
1808
- }, [loadAccountProfileSummary, showAccountHub, showAccountMenu]);
2267
+ }, [loadAccountProfileSummary, showAccountMenu, showAccountSettings]);
1809
2268
  const loadTeamUsers = useCallback(async () => {
1810
2269
  if (!canManageTeamWorkspace)
1811
2270
  return;
@@ -1895,7 +2354,7 @@ export function StandaloneLayout(props) {
1895
2354
  const targetRaw = `${location.pathname}${location.search}${location.hash}`;
1896
2355
  const target = (!targetRaw || targetRaw === '/login' || !targetRaw.startsWith('/')) ? '/' : targetRaw;
1897
2356
  setShowAccountMenu(false);
1898
- setShowAccountHub(false);
2357
+ setShowAccountSettings(false);
1899
2358
  closeSyncStatusModal();
1900
2359
  navigate(`/login?mode=${mode}&next=${encodeURIComponent(target)}`);
1901
2360
  }, [closeSyncStatusModal, location.hash, location.pathname, location.search, navigate]);
@@ -1988,9 +2447,28 @@ export function StandaloneLayout(props) {
1988
2447
  setActiveTab,
1989
2448
  setActiveWorkspaceModule,
1990
2449
  ]);
2450
+ const handleTaskHeaderQuickFilter = useCallback((filter) => {
2451
+ toggleTaskHeaderQuickFilter(filter);
2452
+ setTaskScope('open');
2453
+ setShowArchive(false);
2454
+ setActiveWorkspaceModule('tasks');
2455
+ if (isPlansScreen)
2456
+ closePlansScreen();
2457
+ }, [
2458
+ closePlansScreen,
2459
+ isPlansScreen,
2460
+ setActiveWorkspaceModule,
2461
+ setShowArchive,
2462
+ setTaskScope,
2463
+ toggleTaskHeaderQuickFilter,
2464
+ ]);
1991
2465
  const handleSwitchWorkspace = useCallback(async (workspaceId) => {
1992
2466
  if (!workspaceId || workspaceActionBusy)
1993
2467
  return;
2468
+ if (workflowManagerHasUnsavedChanges && !workflowDiscardBypassRef.current) {
2469
+ setPendingWorkflowDiscardAction(() => () => { void handleSwitchWorkspace(workspaceId); });
2470
+ return;
2471
+ }
1994
2472
  setWorkspaceActionError('');
1995
2473
  setWorkspaceActionBusy(true);
1996
2474
  try {
@@ -2009,7 +2487,7 @@ export function StandaloneLayout(props) {
2009
2487
  finally {
2010
2488
  setWorkspaceActionBusy(false);
2011
2489
  }
2012
- }, [switchWorkspace, workspaceActionBusy, fetchTasks, openWorkspaceSetup]);
2490
+ }, [switchWorkspace, workspaceActionBusy, fetchTasks, openWorkspaceSetup, workflowManagerHasUnsavedChanges]);
2013
2491
  const openTeamManagementModal = useCallback(async () => {
2014
2492
  setShowAccountMenu(false);
2015
2493
  setShowTeamManagementModal(true);
@@ -2098,6 +2576,7 @@ export function StandaloneLayout(props) {
2098
2576
  const hasPriorityFilter = filterPriorities.length !== priorities.length;
2099
2577
  const hasStatusFilter = filterStatus.length !== STATUS_OPTIONS.length;
2100
2578
  const hasAssigneeFilter = filterAssignees.length !== assigneeOptions.length;
2579
+ const hasHeaderQuickFilter = taskHeaderQuickFilter !== null;
2101
2580
  const hasInitiativeScopeFilter = selectedPlanningInitiativeId.length > 0;
2102
2581
  const hasWorkstreamScopeFilter = selectedPlanningWorkstreamId.length > 0;
2103
2582
  return hasCategoryFilter
@@ -2105,6 +2584,7 @@ export function StandaloneLayout(props) {
2105
2584
  || hasPriorityFilter
2106
2585
  || hasStatusFilter
2107
2586
  || hasAssigneeFilter
2587
+ || hasHeaderQuickFilter
2108
2588
  || hasInitiativeScopeFilter
2109
2589
  || hasWorkstreamScopeFilter;
2110
2590
  }, [
@@ -2119,25 +2599,41 @@ export function StandaloneLayout(props) {
2119
2599
  priorities.length,
2120
2600
  selectedPlanningInitiativeId,
2121
2601
  selectedPlanningWorkstreamId,
2602
+ taskHeaderQuickFilter,
2122
2603
  ]);
2123
- const hasDocumentDropdownFilters = useMemo(() => (documentTypeFilters.length !== DOCUMENT_TYPE_FILTER_OPTIONS.length
2124
- || documentAttachmentFilters.length !== DOCUMENT_ATTACHMENT_FILTER_OPTIONS.length), [documentAttachmentFilters.length, documentTypeFilters.length]);
2125
2604
  const workspaceChromeMode = resolvedWorkspaceModule;
2126
2605
  const workspaceChromeDefinition = useMemo(() => getWorkspaceChromeDefinition(workspaceChromeMode), [workspaceChromeMode]);
2127
- const hasActiveWorkspaceFilterControls = useMemo(() => {
2128
- switch (workspaceChromeDefinition.filterBar.kind) {
2129
- case 'task-filters':
2130
- return hasDropdownFilters;
2131
- case 'document-filters':
2132
- return hasDocumentDropdownFilters;
2133
- default:
2134
- return false;
2606
+ useLayoutEffect(() => {
2607
+ if (!taskforceAgentDrawerOpen && activeTab !== 'add')
2608
+ return;
2609
+ const updateDrawerTop = () => {
2610
+ const appHeader = appShellHeaderRef.current;
2611
+ const headerBottom = appHeader
2612
+ ? Math.ceil(appHeader.getBoundingClientRect().bottom)
2613
+ : TASKFORCE_AGENT_DRAWER_FALLBACK_TOP;
2614
+ setTaskforceAgentDrawerTop(Math.max(TASKFORCE_AGENT_DRAWER_FALLBACK_TOP, headerBottom));
2615
+ };
2616
+ updateDrawerTop();
2617
+ window.addEventListener('resize', updateDrawerTop);
2618
+ const appHeader = appShellHeaderRef.current;
2619
+ const resizeObserver = typeof ResizeObserver !== 'undefined'
2620
+ ? new ResizeObserver(updateDrawerTop)
2621
+ : null;
2622
+ if (resizeObserver) {
2623
+ if (appHeader)
2624
+ resizeObserver.observe(appHeader);
2135
2625
  }
2136
- }, [
2137
- hasDocumentDropdownFilters,
2138
- hasDropdownFilters,
2139
- workspaceChromeDefinition.filterBar.kind,
2140
- ]);
2626
+ return () => {
2627
+ window.removeEventListener('resize', updateDrawerTop);
2628
+ resizeObserver?.disconnect();
2629
+ };
2630
+ }, [activeTab, taskforceAgentDrawerOpen]);
2631
+ useEffect(() => {
2632
+ if (!taskforceAgentsWorkspaceEnabled) {
2633
+ setTaskforceAgentDrawerOpen(false);
2634
+ }
2635
+ }, [taskforceAgentsWorkspaceEnabled]);
2636
+ const hasActiveWorkspaceFilterControls = workspaceChromeDefinition.moduleId === 'tasks' && hasDropdownFilters;
2141
2637
  // Check if any filters are set (search + dropdown filters)
2142
2638
  const isFiltered = hasSearchFilter || hasDropdownFilters;
2143
2639
  const totalActiveCount = taskScope === 'archived'
@@ -2149,11 +2645,13 @@ export function StandaloneLayout(props) {
2149
2645
  ? archivedScopeTasks.length
2150
2646
  : taskScope === 'deleted'
2151
2647
  ? filteredDeletedTasks.length
2152
- : props.filteredTasks.length;
2648
+ : quickFilteredOpenTasks.length;
2153
2649
  const activeCountLabel = isFiltered ? `${visibleActiveCount}/${totalActiveCount}` : `${totalActiveCount}`;
2154
2650
  const activeCountTitle = isFiltered
2155
2651
  ? `${taskScope.charAt(0).toUpperCase() + taskScope.slice(1)} tasks matching current filters`
2156
- : `${taskScope.charAt(0).toUpperCase() + taskScope.slice(1)} tasks`;
2652
+ : taskScope === 'deleted'
2653
+ ? 'Trash tasks — automatically deleted after 90 days'
2654
+ : `${taskScope.charAt(0).toUpperCase() + taskScope.slice(1)} tasks`;
2157
2655
  const shouldShowSyncStatus = runtimeMode === 'local' && isAuthenticated;
2158
2656
  const formatSyncTimestamp = useCallback((value) => {
2159
2657
  if (!value)
@@ -2168,7 +2666,9 @@ export function StandaloneLayout(props) {
2168
2666
  const formattedLastPushTime = useMemo(() => formatSyncTimestamp(workspaceLastPushAt), [formatSyncTimestamp, workspaceLastPushAt]);
2169
2667
  const rawSyncLastError = workspaceSyncError || workspaceLastErrorMessage || userGlobalSyncError || 'None';
2170
2668
  const workspaceSyncDiagnostics = getWorkspaceSyncDiagnostics();
2171
- const headerSyncPresentation = useMemo(() => resolveHeaderWorkspaceSyncPresentation({
2669
+ const coordinatorRecoveryObligations = localCoordinatorStatus?.snapshot
2670
+ ?.permits.recoveryObligations || 0;
2671
+ const browserHeaderSyncPresentation = useMemo(() => resolveHeaderWorkspaceSyncPresentation({
2172
2672
  runtimeMode,
2173
2673
  isAuthenticated,
2174
2674
  workspaceSyncStatus,
@@ -2176,6 +2676,7 @@ export function StandaloneLayout(props) {
2176
2676
  workspaceSyncSummary,
2177
2677
  workspaceSyncRecommendedAction,
2178
2678
  workspaceSyncError: rawSyncLastError,
2679
+ coordinatorRecoveryObligations,
2179
2680
  pushBlockedReason: workspaceSyncDiagnostics.pushBlockedReason || null,
2180
2681
  pullBlockedReason: workspaceSyncDiagnostics.pullBlockedReason || null,
2181
2682
  retryBlockedReason: workspaceSyncDiagnostics.retryBlockedReason || null
@@ -2187,13 +2688,73 @@ export function StandaloneLayout(props) {
2187
2688
  workspaceSyncSummary,
2188
2689
  workspaceSyncRecommendedAction,
2189
2690
  rawSyncLastError,
2691
+ coordinatorRecoveryObligations,
2190
2692
  workspaceSyncDiagnostics.pushBlockedReason,
2191
2693
  workspaceSyncDiagnostics.pullBlockedReason,
2192
2694
  workspaceSyncDiagnostics.retryBlockedReason
2193
2695
  ]);
2696
+ const coordinatorSyncPresentation = useMemo(() => resolveCoordinatorWorkspaceSyncPresentation(localCoordinatorStatus), [localCoordinatorStatus]);
2697
+ const headerSyncPresentation = coordinatorSyncPresentation?.header
2698
+ || browserHeaderSyncPresentation;
2699
+ const effectivePendingLocalChanges = coordinatorSyncPresentation
2700
+ ? coordinatorSyncPresentation.pendingLocalChanges
2701
+ : workspaceSyncPendingChanges;
2702
+ const effectiveLastPullAt = coordinatorSyncPresentation
2703
+ ? coordinatorSyncPresentation.lastPullAt
2704
+ : workspaceLastPullAt;
2705
+ const effectiveLastPushAt = coordinatorSyncPresentation
2706
+ ? coordinatorSyncPresentation.lastPushAt
2707
+ : workspaceLastPushAt;
2708
+ const effectiveLastSyncedAt = coordinatorSyncPresentation
2709
+ ? coordinatorSyncPresentation.lastSyncedAt
2710
+ : workspaceLastSuccessfulSyncAt;
2711
+ const effectiveFormattedLastPullTime = formatSyncTimestamp(effectiveLastPullAt);
2712
+ const effectiveFormattedLastPushTime = formatSyncTimestamp(effectiveLastPushAt);
2713
+ const effectiveFormattedLastSyncTime = formatSyncTimestamp(effectiveLastSyncedAt);
2714
+ const effectiveWorkspaceSyncBusy = coordinatorSyncPresentation
2715
+ ? coordinatorSyncPresentation.busy
2716
+ : workspaceSyncBusy;
2717
+ const coordinatorOwnershipState = localCoordinatorStatus?.snapshot
2718
+ ?.state.ownershipMode || null;
2719
+ const coordinatorOwnershipMode = (coordinatorOwnershipState === 'server'
2720
+ || coordinatorOwnershipState === 'browser-gateway') ? coordinatorOwnershipState : null;
2721
+ const [coordinatorOwnershipTransferBusy, setCoordinatorOwnershipTransferBusy] = useState(false);
2722
+ const coordinatorOwnershipTransferDisabled = (localCoordinatorStatus?.phase !== 'ready'
2723
+ || !localCoordinatorStatus.snapshot
2724
+ || localCoordinatorStatus.snapshot.state.transitionState !== 'idle'
2725
+ || localCoordinatorStatus.snapshot.permits.active > 0
2726
+ || coordinatorRecoveryObligations > 0);
2727
+ const handleCoordinatorOwnershipTransfer = useCallback(async () => {
2728
+ if (!coordinatorOwnershipMode || coordinatorOwnershipTransferBusy)
2729
+ return;
2730
+ setCoordinatorOwnershipTransferBusy(true);
2731
+ try {
2732
+ const targetMode = coordinatorOwnershipMode === 'server'
2733
+ ? 'browser-gateway'
2734
+ : 'server';
2735
+ await transferLocalCoordinatorOwnership(targetMode);
2736
+ pushNotice(targetMode === 'server'
2737
+ ? 'The local Taskforce server now owns background synchronization.'
2738
+ : 'This browser now owns background synchronization.', 'success');
2739
+ }
2740
+ catch (error) {
2741
+ pushNotice(error instanceof Error && error.message.trim()
2742
+ ? error.message
2743
+ : 'Sync ownership could not be transferred.', 'error');
2744
+ }
2745
+ finally {
2746
+ setCoordinatorOwnershipTransferBusy(false);
2747
+ }
2748
+ }, [
2749
+ coordinatorOwnershipMode,
2750
+ coordinatorOwnershipTransferBusy,
2751
+ pushNotice,
2752
+ transferLocalCoordinatorOwnership,
2753
+ ]);
2194
2754
  const syncLastError = headerSyncPresentation.lastError;
2195
2755
  const [headerSyncStatus, setHeaderSyncStatus] = useState(headerSyncPresentation.status);
2196
- const syncDiagnosticsSummary = useMemo(() => buildSyncDiagnosticsSummary(workspaceSyncDiagnostics), [workspaceSyncDiagnostics]);
2756
+ const syncDiagnosticsSummary = useMemo(() => coordinatorSyncPresentation?.diagnostics
2757
+ || buildSyncDiagnosticsSummary({ ...workspaceSyncDiagnostics, coordinatorRecoveryObligations }), [coordinatorSyncPresentation, workspaceSyncDiagnostics, coordinatorRecoveryObligations]);
2197
2758
  const { syncRecentEvents, syncRecentEventsLoading, syncRecentEventsError, syncEventsListRef, loadRecentSyncEvents, } = useRecentSyncEvents({
2198
2759
  isOpen: showSyncStatusModal,
2199
2760
  workspaceId: currentWorkspaceId,
@@ -2207,7 +2768,7 @@ export function StandaloneLayout(props) {
2207
2768
  const shouldDelayHeaderSyncing = headerSyncPresentation.actionable
2208
2769
  && workspaceSyncStatus === 'syncing'
2209
2770
  && workspaceSyncPhase === 'active'
2210
- && workspaceSyncPendingChanges === 0;
2771
+ && effectivePendingLocalChanges === 0;
2211
2772
  useEffect(() => {
2212
2773
  if (!shouldDelayHeaderSyncing) {
2213
2774
  setHeaderSyncStatus(headerSyncPresentation.status);
@@ -2226,16 +2787,17 @@ export function StandaloneLayout(props) {
2226
2787
  const referenceMismatchCount = useMemo(() => getActiveReferenceMismatchCount(syncRecentEvents), [syncRecentEvents]);
2227
2788
  const activeReferenceMismatchSummaries = useMemo(() => buildReferenceMismatchSummaries(syncRecentEvents), [syncRecentEvents]);
2228
2789
  const syncStatusMeta = useMemo(() => resolveSyncStatusMeta(headerSyncStatus), [headerSyncStatus]);
2790
+ const headerSyncStatusMeta = useMemo(() => resolveHeaderSyncStatusMeta(headerSyncStatus, effectiveWorkspaceCloudSyncEnabled), [effectiveWorkspaceCloudSyncEnabled, headerSyncStatus]);
2229
2791
  const { workspaceSyncRepairBusy, workspaceSyncRepairQueued, workspaceSyncCopied, handleCopySyncDetails, handleQueueOrRunRepairSync, } = useSyncStatusActions({
2230
2792
  currentWorkspaceId,
2231
2793
  syncStatusLabel: syncStatusMeta.label,
2232
2794
  workspaceSyncSummary: headerSyncPresentation.summary,
2233
2795
  workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction,
2234
- formattedLastSyncTime,
2235
- formattedLastPullTime,
2236
- formattedLastPushTime,
2796
+ formattedLastSyncTime: effectiveFormattedLastSyncTime,
2797
+ formattedLastPullTime: effectiveFormattedLastPullTime,
2798
+ formattedLastPushTime: effectiveFormattedLastPushTime,
2237
2799
  workspaceSyncDiagnostics,
2238
- workspaceSyncPendingChanges,
2800
+ workspaceSyncPendingChanges: effectivePendingLocalChanges,
2239
2801
  syncLastError,
2240
2802
  workspaceSyncPhase,
2241
2803
  referenceMismatchCount,
@@ -2243,9 +2805,14 @@ export function StandaloneLayout(props) {
2243
2805
  loadRecentSyncEvents,
2244
2806
  pushNotice,
2245
2807
  resetWorkspaceSyncCursorAndPull,
2246
- workspaceSyncBusy,
2808
+ workspaceSyncBusy: effectiveWorkspaceSyncBusy,
2809
+ durableRepairQueueAvailable: coordinatorOwnershipMode === 'server',
2247
2810
  });
2248
- const syncStageLabel = useMemo(() => resolveSyncStageLabel(workspaceSyncPhase, workspaceSyncRepairBusy, workspaceSyncBusy), [workspaceSyncBusy, workspaceSyncPhase, workspaceSyncRepairBusy]);
2811
+ const effectiveWorkspaceSyncRepairBusy = coordinatorSyncPresentation
2812
+ ? coordinatorSyncPresentation.repairBusy
2813
+ : workspaceSyncRepairBusy;
2814
+ const syncStageLabel = useMemo(() => coordinatorSyncPresentation?.stage
2815
+ || resolveSyncStageLabel(workspaceSyncPhase, workspaceSyncRepairBusy, workspaceSyncBusy), [coordinatorSyncPresentation, workspaceSyncBusy, workspaceSyncPhase, workspaceSyncRepairBusy]);
2249
2816
  const selectedDateObj = useMemo(() => parseDateOnlyLocal(scheduleSelectedDate) || new Date(), [scheduleSelectedDate]);
2250
2817
  const scheduleWeekStart = useMemo(() => startOfWeek(selectedDateObj, globalWeekStartsOn), [selectedDateObj, globalWeekStartsOn]);
2251
2818
  const scheduleDates = useMemo(() => {
@@ -2367,8 +2934,6 @@ export function StandaloneLayout(props) {
2367
2934
  { value: 4, label: 'High', icon: 'Gauge', color: '#8b5cf6' },
2368
2935
  { value: 5, label: 'Epic', icon: 'Gauge', color: '#d946ef' }
2369
2936
  ];
2370
- case 'approach':
2371
- return approaches;
2372
2937
  case 'assignee':
2373
2938
  return assigneeOptions.map((option) => ({
2374
2939
  value: option.value,
@@ -2391,7 +2956,7 @@ export function StandaloneLayout(props) {
2391
2956
  default:
2392
2957
  return activeCategories;
2393
2958
  }
2394
- }, [groupBy, activeCategories, activeTypes, priorities, approaches, assigneeOptions, scheduleColumns]);
2959
+ }, [groupBy, activeCategories, activeTypes, priorities, assigneeOptions, scheduleColumns]);
2395
2960
  // === SECTION: AccountMenuControl ===
2396
2961
  // Not extracted: ~25 distinct props from local state would be needed.
2397
2962
  // References: isAuthenticated, authIdentityLabel, accountProfileSummary, runtimeLabel,
@@ -2424,21 +2989,12 @@ export function StandaloneLayout(props) {
2424
2989
  setShowAccountMenu(false);
2425
2990
  }, 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: () => {
2426
2991
  setShowAccountMenu(false);
2427
- setShowEditProfileModal(true);
2428
- }, role: "menuitem", children: [_jsx(User, { size: 15 }), "Edit Profile"] })), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2429
- setShowAccountMenu(false);
2430
- openPlansScreen();
2431
- }, role: "menuitem", children: [_jsx(Layers, { size: 15 }), "Plans"] }), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2432
- setShowAccountMenu(false);
2433
- startAccountSurfaceTiming('account_hub');
2434
- setShowAccountHub(true);
2435
- }, role: "menuitem", children: [_jsx(User, { size: 15 }), "Account Hub"] }), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2436
- setShowAccountMenu(false);
2437
- setShowHelpModal(true);
2438
- }, role: "menuitem", children: [_jsx(HelpCircle, { size: 15 }), "Help & Support"] }), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2992
+ startAccountSurfaceTiming('account_settings');
2993
+ setShowAccountSettings(true);
2994
+ }, role: "menuitem", children: [_jsx(Settings, { size: 15 }), "Account Settings"] })), _jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2439
2995
  setShowAccountMenu(false);
2440
2996
  setShowHelpModal(true);
2441
- }, role: "menuitem", children: [_jsx(Mail, { size: 15 }), "Contact Support"] }), runtimeMode === 'local' && !isAuthenticated && !isAuthBootstrapPending && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2997
+ }, role: "menuitem", children: [_jsx(HelpCircle, { size: 15 }), "Help & Support"] }), runtimeMode === 'local' && !isAuthenticated && !isAuthBootstrapPending && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: () => {
2442
2998
  openSharedLoginRoute('login');
2443
2999
  }, role: "menuitem", children: [_jsx(User, { size: 15 }), "Sign In / Register"] })), isAuthenticated && (_jsxs("button", { className: accountStyles.accountMenuItem, onClick: async () => {
2444
3000
  setShowAccountMenu(false);
@@ -2521,6 +3077,9 @@ export function StandaloneLayout(props) {
2521
3077
  const activeEditor = planningSecondaryEditor || planningEditor;
2522
3078
  if (!activeEditor || planningEditorSubmitInFlightRef.current)
2523
3079
  return;
3080
+ const title = planningDraftTitle.trim();
3081
+ if (!title)
3082
+ return;
2524
3083
  planningEditorSubmitInFlightRef.current = true;
2525
3084
  setIsSubmittingPlanningEditor(true);
2526
3085
  const isSecondaryEditor = Boolean(planningSecondaryEditor);
@@ -2529,17 +3088,15 @@ export function StandaloneLayout(props) {
2529
3088
  if (activeEditor.entityType === 'initiative') {
2530
3089
  if (activeEditor.mode === 'edit') {
2531
3090
  await props.updateInitiative(activeEditor.targetId, {
2532
- title: planningDraftTitle.trim() || 'Untitled Initiative',
3091
+ title,
2533
3092
  description: planningDraftDescription.trim() || null,
2534
- ownerId,
2535
3093
  });
2536
3094
  setPlanningDrawerDetail({ type: 'initiative', id: activeEditor.targetId });
2537
- setPlanningNestedWorkstreamDetailId(null);
2538
3095
  pushNotice('Initiative updated', 'success');
2539
3096
  }
2540
3097
  else {
2541
3098
  const created = await props.createInitiative({
2542
- title: planningDraftTitle.trim() || 'Untitled Initiative',
3099
+ title,
2543
3100
  description: planningDraftDescription.trim() || null,
2544
3101
  ownerId,
2545
3102
  });
@@ -2549,19 +3106,16 @@ export function StandaloneLayout(props) {
2549
3106
  }
2550
3107
  }
2551
3108
  else {
2552
- const nextInitiativeRaw = planningDraftInitiativeId.trim();
2553
- const resolvedInitiative = nextInitiativeRaw.length === 0
2554
- ? null
2555
- : resolveInitiativeReference(planningStructure.initiatives, nextInitiativeRaw);
2556
- if (nextInitiativeRaw.length > 0 && !resolvedInitiative) {
3109
+ const resolvedInitiative = resolveWorkstreamCreateInitiativeId(planningStructure.allInitiatives, activeEditor.mode === 'create' ? activeEditor.initiativeId : null, planningDraftInitiativeId);
3110
+ if (resolvedInitiative.invalid) {
2557
3111
  pushNotice('Initiative not found by that reference.', 'error');
2558
3112
  return;
2559
3113
  }
2560
3114
  const patch = {
2561
- title: planningDraftTitle.trim() || 'Untitled Workstream',
3115
+ title,
2562
3116
  description: planningDraftDescription.trim() || null,
2563
- ownerId,
2564
- initiativeId: resolvedInitiative?.id || null,
3117
+ initiativeId: resolvedInitiative.initiativeId,
3118
+ ...(activeEditor.mode === 'create' ? { ownerId } : {}),
2565
3119
  };
2566
3120
  if (activeEditor.mode === 'edit') {
2567
3121
  await props.updateWorkstream(activeEditor.targetId, patch);
@@ -2609,7 +3163,7 @@ export function StandaloneLayout(props) {
2609
3163
  planningDraftTitle,
2610
3164
  planningEditor,
2611
3165
  planningSecondaryEditor,
2612
- planningStructure.initiatives,
3166
+ planningStructure.allInitiatives,
2613
3167
  props,
2614
3168
  pushNotice,
2615
3169
  ]);
@@ -2657,9 +3211,193 @@ export function StandaloneLayout(props) {
2657
3211
  setPlanningSecondaryCollapsed(false);
2658
3212
  setPlanningNestedWorkstreamDetailId(workstreamId);
2659
3213
  }, []);
3214
+ const handleCanonicalEntityReference = useCallback((reference) => {
3215
+ if (reference.kind === 'initiative' || reference.kind === 'workstream') {
3216
+ const entity = reference.kind === 'initiative'
3217
+ ? props.initiatives.find((initiative) => initiative.referenceNumber === reference.referenceNumber)
3218
+ : props.workstreams.find((workstream) => workstream.referenceNumber === reference.referenceNumber);
3219
+ if (!entity) {
3220
+ pushNotice(`${reference.token} could not be found.`, 'error');
3221
+ return;
3222
+ }
3223
+ handoffTaskModalToWorkspace(() => {
3224
+ setActiveWorkspaceModule('planning');
3225
+ setPlanningDrawerOpen(true);
3226
+ if (reference.kind === 'initiative')
3227
+ openInitiativeDetails(entity.id);
3228
+ else
3229
+ openWorkstreamDetails(entity.id);
3230
+ });
3231
+ return;
3232
+ }
3233
+ const workspaceId = String(currentWorkspaceId || 'default').trim() || 'default';
3234
+ const preview = (attachment) => {
3235
+ dispatchPreviewContextAttachment(attachment, {
3236
+ ownerType: 'task',
3237
+ ownerId: editingTaskId,
3238
+ ownerReferenceLabel: getTaskReferenceLabel(currentTask),
3239
+ workspaceId,
3240
+ });
3241
+ };
3242
+ void resolveCanonicalAttachmentReference(reference, {
3243
+ workspaceId,
3244
+ headers: workspaceUiStateHeaders,
3245
+ }).then(preview).catch(() => {
3246
+ pushNotice(`${reference.token} could not be opened.`, 'error');
3247
+ });
3248
+ }, [
3249
+ currentTask,
3250
+ currentWorkspaceId,
3251
+ editingTaskId,
3252
+ handoffTaskModalToWorkspace,
3253
+ openInitiativeDetails,
3254
+ openWorkstreamDetails,
3255
+ props.initiatives,
3256
+ props.workstreams,
3257
+ pushNotice,
3258
+ setActiveWorkspaceModule,
3259
+ workspaceUiStateHeaders,
3260
+ ]);
3261
+ const taskTextReferences = useMemo(() => ({
3262
+ ...taskReferences,
3263
+ entityReferences: {
3264
+ resolve: parseCanonicalEntityReference,
3265
+ activate: handleCanonicalEntityReference,
3266
+ },
3267
+ }), [handleCanonicalEntityReference, taskReferences]);
3268
+ useEffect(() => {
3269
+ const initiativeId = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.initiative) || '').trim();
3270
+ const workstreamId = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.workstream) || '').trim();
3271
+ const documentAssetId = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.document) || '').trim();
3272
+ const imageReference = String(routeQuery.get(TASK_DEEP_LINK_QUERY_KEYS.image) || '').trim();
3273
+ const target = initiativeId
3274
+ ? `initiative:${initiativeId}`
3275
+ : workstreamId
3276
+ ? `workstream:${workstreamId}`
3277
+ : documentAssetId
3278
+ ? `document:${documentAssetId}`
3279
+ : imageReference
3280
+ ? `image:${imageReference}`
3281
+ : '';
3282
+ if (!target || handledEntityDeepLinkRef.current === target)
3283
+ return;
3284
+ if (initiativeId || workstreamId) {
3285
+ const entity = initiativeId
3286
+ ? props.initiatives.find((initiative) => initiative.id === initiativeId)
3287
+ : props.workstreams.find((workstream) => workstream.id === workstreamId);
3288
+ if (!entity)
3289
+ return;
3290
+ handledEntityDeepLinkRef.current = target;
3291
+ handoffTaskModalToWorkspace(() => {
3292
+ setActiveWorkspaceModule('planning');
3293
+ setPlanningDrawerOpen(true);
3294
+ if (initiativeId)
3295
+ openInitiativeDetails(entity.id);
3296
+ else
3297
+ openWorkstreamDetails(entity.id);
3298
+ });
3299
+ return;
3300
+ }
3301
+ if (documentAssetId) {
3302
+ if (!documentsWorkspaceEnabled)
3303
+ return;
3304
+ handledEntityDeepLinkRef.current = target;
3305
+ handoffTaskModalToWorkspace(() => {
3306
+ setRequestedDocPath(null);
3307
+ setRequestedDocAssetId(documentAssetId);
3308
+ setActiveWorkspaceModule('docs');
3309
+ });
3310
+ return;
3311
+ }
3312
+ if (!annotatedAttachmentsWorkspaceEnabled)
3313
+ return;
3314
+ handledEntityDeepLinkRef.current = target;
3315
+ const workspaceId = String(currentWorkspaceId || 'default').trim() || 'default';
3316
+ const query = new URLSearchParams({ workspaceId });
3317
+ void fetch(`/api/taskforce/annotated-attachments/images/${encodeURIComponent(imageReference)}?${query.toString()}`, { credentials: 'include', headers: workspaceUiStateHeaders }).then(async (response) => {
3318
+ if (!response.ok)
3319
+ throw new Error('Image not found');
3320
+ const payload = await response.json();
3321
+ if (!payload.target?.assetId || !payload.target.path)
3322
+ throw new Error('Image target is unavailable');
3323
+ handoffTaskModalToWorkspace(() => {
3324
+ const target = payload.target;
3325
+ requestedAnnotatedTargetRef.current = target;
3326
+ requestedAnnotatedSessionIdRef.current = null;
3327
+ setRequestedAnnotatedTarget(target);
3328
+ setRequestedAnnotatedSessionId(null);
3329
+ setRequestedAnnotatedOpenVersion((current) => current + 1);
3330
+ setActiveWorkspaceModule('annotate');
3331
+ });
3332
+ }).catch(() => {
3333
+ pushNotice(`Image ${imageReference} could not be opened.`, 'error');
3334
+ });
3335
+ }, [
3336
+ annotatedAttachmentsWorkspaceEnabled,
3337
+ currentWorkspaceId,
3338
+ documentsWorkspaceEnabled,
3339
+ handoffTaskModalToWorkspace,
3340
+ openInitiativeDetails,
3341
+ openWorkstreamDetails,
3342
+ props.initiatives,
3343
+ props.workstreams,
3344
+ pushNotice,
3345
+ routeQuery,
3346
+ setActiveWorkspaceModule,
3347
+ workspaceUiStateHeaders,
3348
+ ]);
3349
+ const hydratePlanningEntity = useCallback(async (target) => {
3350
+ const key = `${target.type}:${target.id}`;
3351
+ setPlanningHydrationStateByEntity((current) => ({
3352
+ ...current,
3353
+ [key]: { status: 'loading', error: null },
3354
+ }));
3355
+ try {
3356
+ await props.fetchPlanningEntityDetail(target.type, target.id);
3357
+ setPlanningHydrationStateByEntity((current) => ({
3358
+ ...current,
3359
+ [key]: { status: 'ready', error: null },
3360
+ }));
3361
+ }
3362
+ catch (error) {
3363
+ setPlanningHydrationStateByEntity((current) => ({
3364
+ ...current,
3365
+ [key]: {
3366
+ status: 'error',
3367
+ error: error instanceof Error ? error.message : 'Failed to load the latest planning details.',
3368
+ },
3369
+ }));
3370
+ }
3371
+ }, [props.fetchPlanningEntityDetail]);
3372
+ useEffect(() => {
3373
+ const targets = new Map();
3374
+ if (planningDrawerDetail?.id) {
3375
+ targets.set(`${planningDrawerDetail.type}:${planningDrawerDetail.id}`, planningDrawerDetail);
3376
+ }
3377
+ if (planningNestedWorkstreamDetailId) {
3378
+ targets.set(`workstream:${planningNestedWorkstreamDetailId}`, {
3379
+ type: 'workstream',
3380
+ id: planningNestedWorkstreamDetailId,
3381
+ });
3382
+ }
3383
+ if (targets.size === 0)
3384
+ return;
3385
+ for (const target of targets.values()) {
3386
+ void hydratePlanningEntity(target);
3387
+ }
3388
+ }, [
3389
+ hydratePlanningEntity,
3390
+ planningDrawerDetail?.id,
3391
+ planningDrawerDetail?.type,
3392
+ planningNestedWorkstreamDetailId,
3393
+ ]);
2660
3394
  const openPlanningCreateEditor = useCallback((type, initiativeId) => {
2661
3395
  if (type === 'workstream' && initiativeId) {
2662
- openPlanningSecondaryEditor({ mode: 'create', entityType: 'workstream' }, initiativeId);
3396
+ openPlanningSecondaryEditor({
3397
+ mode: 'create',
3398
+ entityType: 'workstream',
3399
+ initiativeId,
3400
+ }, initiativeId);
2663
3401
  return;
2664
3402
  }
2665
3403
  openPlanningEditor({ mode: 'create', entityType: type });
@@ -2671,35 +3409,64 @@ export function StandaloneLayout(props) {
2671
3409
  }
2672
3410
  }, [openPlanningEditor, openPlanningSecondaryEditor, planningStructure.initiativeById, selectedPlanningInitiativeId]);
2673
3411
  const openPlanningEditDialog = useCallback((type, id) => {
3412
+ planningEditorSubmitInFlightRef.current = false;
3413
+ setIsSubmittingPlanningEditor(false);
2674
3414
  if (type === 'initiative') {
2675
- const item = planningStructure.initiativeById.get(id);
3415
+ const item = planningStructure.allInitiativeById.get(id);
2676
3416
  if (!item)
2677
3417
  return;
3418
+ setPlanningSecondaryEditor(null);
2678
3419
  setPlanningEditor({ mode: 'edit', entityType: 'initiative', targetId: id });
2679
3420
  setPlanningDraftTitle(item.title);
2680
3421
  setPlanningDraftDescription(item.description || '');
2681
3422
  setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
2682
3423
  setPlanningDraftInitiativeId('');
3424
+ return;
2683
3425
  }
2684
3426
  else {
2685
- const item = planningStructure.workstreamById.get(id)
2686
- || planningStructure.standaloneWorkstreams.find((workstream) => workstream.id === id);
3427
+ const item = planningStructure.allWorkstreamById.get(id);
2687
3428
  if (!item)
2688
3429
  return;
2689
- setPlanningEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
3430
+ const isNestedDetail = planningNestedWorkstreamDetailId === id;
3431
+ if (isNestedDetail) {
3432
+ setPlanningEditor(null);
3433
+ setPlanningSecondaryEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
3434
+ }
3435
+ else {
3436
+ setPlanningSecondaryEditor(null);
3437
+ setPlanningEditor({ mode: 'edit', entityType: 'workstream', targetId: id });
3438
+ }
2690
3439
  setPlanningDraftTitle(item.title);
2691
3440
  setPlanningDraftDescription(item.description || '');
2692
3441
  setPlanningDraftOwner(item.ownerId ? String(item.ownerId) : '');
2693
- const initiative = item.initiativeId ? planningStructure.initiativeById.get(item.initiativeId) || null : null;
3442
+ const initiative = item.initiativeId ? planningStructure.allInitiativeById.get(item.initiativeId) || null : null;
2694
3443
  setPlanningDraftInitiativeId(initiative ? formatInitiativeReference(initiative) : '');
3444
+ if (isNestedDetail)
3445
+ return;
2695
3446
  }
2696
3447
  setPlanningNestedWorkstreamDetailId(null);
2697
- }, [planningStructure.initiativeById, planningStructure.standaloneWorkstreams, planningStructure.workstreamById]);
3448
+ }, [planningNestedWorkstreamDetailId, planningStructure.allInitiativeById, planningStructure.allWorkstreamById]);
3449
+ const handleChangePlanningOwner = useCallback(async (entityType, entityId, nextOwnerId) => {
3450
+ const ownerId = nextOwnerId.trim() || null;
3451
+ try {
3452
+ if (entityType === 'initiative') {
3453
+ await props.updateInitiative(entityId, { ownerId });
3454
+ }
3455
+ else {
3456
+ await props.updateWorkstream(entityId, { ownerId });
3457
+ }
3458
+ pushNotice(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} owner updated`, 'success');
3459
+ }
3460
+ catch (error) {
3461
+ pushNotice(error instanceof Error ? error.message : 'Failed to update owner.', 'error');
3462
+ throw error;
3463
+ }
3464
+ }, [props, pushNotice]);
2698
3465
  const handleAssignInitiativeToWorkstream = useCallback(async (workstreamId, initiativeReferenceOverride) => {
2699
3466
  const workstream = props.workstreams.find((item) => item.id === workstreamId);
2700
3467
  if (!workstream) {
2701
3468
  pushNotice('Workstream not found.', 'error');
2702
- return;
3469
+ return false;
2703
3470
  }
2704
3471
  const nextInitiativeRaw = typeof initiativeReferenceOverride === 'string'
2705
3472
  ? initiativeReferenceOverride.trim()
@@ -2708,68 +3475,64 @@ export function StandaloneLayout(props) {
2708
3475
  : planningDraftInitiativeId.trim();
2709
3476
  const resolvedInitiative = nextInitiativeRaw.length === 0
2710
3477
  ? null
2711
- : resolveInitiativeReference(planningStructure.initiatives, nextInitiativeRaw);
3478
+ : resolveInitiativeReference(planningStructure.allInitiatives, nextInitiativeRaw);
2712
3479
  if (nextInitiativeRaw.length > 0 && !resolvedInitiative) {
2713
3480
  pushNotice('Initiative not found by that reference.', 'error');
2714
- return;
3481
+ return false;
2715
3482
  }
2716
3483
  const normalizedParentId = resolvedInitiative?.id || null;
2717
3484
  if ((workstream.initiativeId || null) === normalizedParentId) {
2718
3485
  pushNotice(normalizedParentId ? 'Workstream already belongs to that initiative.' : 'Workstream is already standalone.', 'info');
2719
- return;
3486
+ return false;
2720
3487
  }
2721
3488
  try {
2722
3489
  await props.updateWorkstream(workstreamId, { initiativeId: normalizedParentId });
2723
3490
  setPlanningDraftInitiativeId(resolvedInitiative ? formatInitiativeReference(resolvedInitiative) : '');
2724
3491
  pushNotice(normalizedParentId ? 'Initiative set' : 'Initiative removed', 'success');
3492
+ return true;
2725
3493
  }
2726
3494
  catch {
2727
3495
  pushNotice('Failed to set initiative.', 'error');
3496
+ return false;
2728
3497
  }
2729
- }, [planningDraftInitiativeId, planningStructure.initiatives, props, pushNotice]);
3498
+ }, [planningDraftInitiativeId, planningStructure.allInitiatives, props, pushNotice]);
2730
3499
  const handleAssignTaskToWorkstream = useCallback(async (taskId, workstreamId) => {
2731
3500
  const task = hierarchyTaskById.get(taskId);
2732
3501
  if (!task) {
2733
3502
  pushNotice('Task not found.', 'error');
2734
- return;
3503
+ return false;
2735
3504
  }
2736
3505
  const normalizedWorkstreamId = workstreamId || null;
2737
3506
  if (planningStructure.initiativeById.has(taskId) || planningStructure.workstreamById.has(taskId)) {
2738
3507
  pushNotice('Only execution tasks can be moved into workstreams.', 'error');
2739
- return;
3508
+ return false;
2740
3509
  }
2741
3510
  if (normalizedWorkstreamId && !planningStructure.workstreamById.has(normalizedWorkstreamId)) {
2742
3511
  pushNotice('Workstream not found.', 'error');
2743
- return;
3512
+ return false;
2744
3513
  }
2745
3514
  if ((task.workstreamId || null) === normalizedWorkstreamId) {
2746
3515
  pushNotice(normalizedWorkstreamId ? 'Task already belongs to that workstream.' : 'Task is already standalone.', 'info');
2747
- return;
3516
+ return false;
2748
3517
  }
2749
3518
  try {
2750
- const res = await fetch(`/api/taskforce/task/${taskId}`, {
2751
- method: 'PATCH',
2752
- headers: { 'Content-Type': 'application/json' },
2753
- body: JSON.stringify({ workstreamId: normalizedWorkstreamId })
2754
- });
2755
- if (!res.ok) {
2756
- const data = await res.json().catch(() => ({}));
2757
- pushNotice(data?.error || 'Failed to set workstream.', 'error');
2758
- return;
2759
- }
2760
- await res.json().catch(() => null);
2761
- await fetchTasks(true);
3519
+ const saved = await props.handleUpdateTask(taskId, { workstreamId: normalizedWorkstreamId });
3520
+ if (saved === false)
3521
+ return false;
3522
+ await props.fetchPlanningEntities();
2762
3523
  pushNotice(normalizedWorkstreamId ? 'Workstream set' : 'Workstream removed', 'success');
3524
+ return true;
2763
3525
  }
2764
3526
  catch {
2765
3527
  pushNotice('Failed to set workstream.', 'error');
3528
+ return false;
2766
3529
  }
2767
- }, [fetchTasks, hierarchyTaskById, planningStructure.initiativeById, planningStructure.workstreamById, pushNotice]);
3530
+ }, [hierarchyTaskById, planningStructure.initiativeById, planningStructure.workstreamById, props, pushNotice]);
2768
3531
  const handleAttachTaskToWorkstreamByReference = useCallback(async (workstreamId, taskReference) => {
2769
3532
  const needle = taskReference.trim();
2770
3533
  if (!needle) {
2771
3534
  pushNotice('Enter a task reference.', 'error');
2772
- return;
3535
+ return false;
2773
3536
  }
2774
3537
  const parsedReference = parseTaskReference(needle);
2775
3538
  const matchedTask = hierarchyTasks.find((task) => (task.id === needle
@@ -2777,20 +3540,20 @@ export function StandaloneLayout(props) {
2777
3540
  || (parsedReference !== null && task.referenceNumber === parsedReference)));
2778
3541
  if (!matchedTask) {
2779
3542
  pushNotice('Task not found by that reference.', 'error');
2780
- return;
3543
+ return false;
2781
3544
  }
2782
- await handleAssignTaskToWorkstream(matchedTask.id, workstreamId);
3545
+ return handleAssignTaskToWorkstream(matchedTask.id, workstreamId);
2783
3546
  }, [handleAssignTaskToWorkstream, hierarchyTasks, pushNotice]);
2784
3547
  const handleAttachWorkstreamToInitiativeByReference = useCallback(async (initiativeId, workstreamReference) => {
2785
3548
  const needle = workstreamReference.trim();
2786
3549
  if (!needle) {
2787
3550
  pushNotice('Enter a workstream reference.', 'error');
2788
- return;
3551
+ return false;
2789
3552
  }
2790
- const initiative = planningStructure.initiativeById.get(initiativeId);
3553
+ const initiative = planningStructure.allInitiativeById.get(initiativeId);
2791
3554
  if (!initiative) {
2792
3555
  pushNotice('Initiative not found.', 'error');
2793
- return;
3556
+ return false;
2794
3557
  }
2795
3558
  const parsedReference = parseWorkstreamReference(needle);
2796
3559
  const matchedWorkstream = props.workstreams.find((workstream) => (workstream.id === needle
@@ -2798,10 +3561,10 @@ export function StandaloneLayout(props) {
2798
3561
  || (parsedReference !== null && workstream.referenceNumber === parsedReference)));
2799
3562
  if (!matchedWorkstream) {
2800
3563
  pushNotice('Workstream not found by that reference.', 'error');
2801
- return;
3564
+ return false;
2802
3565
  }
2803
- await handleAssignInitiativeToWorkstream(matchedWorkstream.id, formatInitiativeReference(initiative));
2804
- }, [handleAssignInitiativeToWorkstream, planningStructure.initiativeById, props.workstreams, pushNotice]);
3566
+ return handleAssignInitiativeToWorkstream(matchedWorkstream.id, formatInitiativeReference(initiative));
3567
+ }, [handleAssignInitiativeToWorkstream, planningStructure.allInitiativeById, props.workstreams, pushNotice]);
2805
3568
  const getPlanningContextAttachmentDraft = useCallback((entityType, entityId) => {
2806
3569
  const key = `${entityType}:${entityId}`;
2807
3570
  const draft = planningContextAttachmentDraftsRef.current.get(key);
@@ -2865,12 +3628,21 @@ export function StandaloneLayout(props) {
2865
3628
  pushNotice(`${unavailableLabel} is not available in this build yet.`, 'error');
2866
3629
  return;
2867
3630
  }
3631
+ if (resolvedWorkspaceModule === 'workflowManager'
3632
+ && nextModule !== 'workflowManager'
3633
+ && workflowManagerHasUnsavedChanges
3634
+ && !workflowDiscardBypassRef.current) {
3635
+ setPendingWorkflowDiscardAction(() => () => handleModuleChange(nextModuleId));
3636
+ return;
3637
+ }
2868
3638
  clearTaskOriginWorkspaceModule();
2869
3639
  setActiveWorkspaceModule(nextModule);
2870
3640
  }, [
2871
3641
  clearTaskOriginWorkspaceModule,
2872
3642
  pushNotice,
3643
+ resolvedWorkspaceModule,
2873
3644
  setActiveWorkspaceModule,
3645
+ workflowManagerHasUnsavedChanges,
2874
3646
  workspaceModules,
2875
3647
  ]);
2876
3648
  const handlePlanningToolToggle = useCallback(() => {
@@ -2905,13 +3677,87 @@ export function StandaloneLayout(props) {
2905
3677
  setImageTrayOpen((current) => !current);
2906
3678
  }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
2907
3679
  const handleAgentTrayToggle = useCallback(() => {
2908
- if (resolvedWorkspaceModule !== 'agents') {
2909
- setActiveWorkspaceModule('agents');
3680
+ if (resolvedWorkspaceModule !== 'aiProfiles') {
3681
+ setActiveWorkspaceModule('aiProfiles');
2910
3682
  setAgentTrayOpen(true);
2911
3683
  return;
2912
3684
  }
2913
3685
  setAgentTrayOpen((current) => !current);
2914
3686
  }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
3687
+ const handleTaskforceAgentRosterTrayToggle = useCallback(() => {
3688
+ if (resolvedWorkspaceModule !== 'taskforceAgents') {
3689
+ setActiveWorkspaceModule('taskforceAgents');
3690
+ setTaskforceAgentRosterTrayOpen(true);
3691
+ return;
3692
+ }
3693
+ setTaskforceAgentRosterTrayOpen((current) => !current);
3694
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
3695
+ const handleWorkflowLibraryTrayToggle = useCallback(() => {
3696
+ if (resolvedWorkspaceModule !== 'workflowManager') {
3697
+ setActiveWorkspaceModule('workflowManager');
3698
+ setWorkflowLibraryTrayOpen(true);
3699
+ return;
3700
+ }
3701
+ setWorkflowLibraryTrayOpen((current) => !current);
3702
+ }, [resolvedWorkspaceModule, setActiveWorkspaceModule]);
3703
+ const handleCloseTaskforceAgentDrawer = useCallback(() => {
3704
+ setTaskforceAgentDrawerOpen(false);
3705
+ setTaskforceAgentsLaunchContext(null);
3706
+ setTaskforceAgentDrawerHeaderContent(null);
3707
+ }, []);
3708
+ const handleAskTaskforceAgentForTask = useCallback((task) => {
3709
+ if (!workspaceFeatureAccess[TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]?.allowed) {
3710
+ pushNotice('Taskforce Agents are unavailable for this workspace.', 'error');
3711
+ return;
3712
+ }
3713
+ const taskReference = getTaskReferenceLabel(task) || task.id;
3714
+ setTaskforceAgentsLaunchContext({
3715
+ taskId: task.id,
3716
+ taskReference,
3717
+ taskTitle: task.title,
3718
+ });
3719
+ setTaskforceAgentPanelCollapsed(false);
3720
+ setTaskforceAgentDrawerOpen(true);
3721
+ setTaskModalFullscreen(false);
3722
+ }, [
3723
+ pushNotice,
3724
+ workspaceFeatureAccess,
3725
+ ]);
3726
+ const handleOpenTaskforceAgentDrawer = useCallback(() => {
3727
+ if (currentTask && editingTaskId) {
3728
+ handleAskTaskforceAgentForTask(currentTask);
3729
+ return;
3730
+ }
3731
+ if (!workspaceFeatureAccess[TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]?.allowed) {
3732
+ pushNotice('Taskforce Agents are unavailable for this workspace.', 'error');
3733
+ return;
3734
+ }
3735
+ setTaskforceAgentsLaunchContext(null);
3736
+ setTaskforceAgentPanelCollapsed(false);
3737
+ setTaskforceAgentDrawerOpen(true);
3738
+ }, [
3739
+ currentTask,
3740
+ editingTaskId,
3741
+ handleAskTaskforceAgentForTask,
3742
+ pushNotice,
3743
+ workspaceFeatureAccess,
3744
+ ]);
3745
+ const handleOpenTaskforceAgentConversation = useCallback((agentId) => {
3746
+ const normalizedAgentId = String(agentId || '').trim();
3747
+ if (!normalizedAgentId)
3748
+ return;
3749
+ handleRememberTaskforceAgentSelection({
3750
+ agentId: normalizedAgentId,
3751
+ conversationId: taskforceAgentConversationByAgentId[normalizedAgentId] || null,
3752
+ });
3753
+ setTaskforceAgentsLaunchContext(null);
3754
+ setTaskforceAgentPanelCollapsed(false);
3755
+ setTaskforceAgentDrawerOpen(true);
3756
+ }, [handleRememberTaskforceAgentSelection, taskforceAgentConversationByAgentId]);
3757
+ const handleOpenTaskforceAgentTaskContext = useCallback((taskId) => {
3758
+ handleOpenTaskById(taskId);
3759
+ setTaskModalFullscreen(false);
3760
+ }, [handleOpenTaskById]);
2915
3761
  const handleBackToTaskFromAnnotatedAttachment = useCallback((taskId) => {
2916
3762
  clearTaskOriginWorkspaceModule();
2917
3763
  setActiveWorkspaceModule('tasks');
@@ -2923,12 +3769,17 @@ export function StandaloneLayout(props) {
2923
3769
  handleOpenTaskById(taskId);
2924
3770
  }, [clearTaskOriginWorkspaceModule, handleOpenTaskById, setActiveWorkspaceModule]);
2925
3771
  const handleAnnotatedAttachmentOpenTarget = useCallback((target, options) => {
3772
+ const sessionId = options?.sessionId ?? null;
3773
+ requestedAnnotatedTargetRef.current = target;
3774
+ requestedAnnotatedSessionIdRef.current = sessionId;
2926
3775
  setRequestedAnnotatedTarget(target);
2927
- setRequestedAnnotatedSessionId(options?.sessionId ?? null);
3776
+ setRequestedAnnotatedSessionId(sessionId);
2928
3777
  setRequestedAnnotatedOpenVersion((current) => current + 1);
2929
3778
  setActiveWorkspaceModule('annotate');
2930
3779
  }, [setActiveWorkspaceModule]);
2931
3780
  const handleAnnotatedAttachmentContextChange = useCallback(({ target, sessionId }) => {
3781
+ requestedAnnotatedTargetRef.current = target;
3782
+ requestedAnnotatedSessionIdRef.current = sessionId;
2932
3783
  setRequestedAnnotatedTarget((current) => {
2933
3784
  if (!current && !target)
2934
3785
  return current;
@@ -2946,6 +3797,41 @@ export function StandaloneLayout(props) {
2946
3797
  });
2947
3798
  setRequestedAnnotatedSessionId((current) => (current === sessionId ? current : sessionId));
2948
3799
  }, []);
3800
+ const handleDocumentScrollChange = useCallback((docId, scrollTop) => {
3801
+ const normalizedDocId = docId.trim();
3802
+ const normalizedScrollTop = Math.max(0, Math.round(scrollTop));
3803
+ if (!normalizedDocId)
3804
+ return;
3805
+ setDocumentScrollByDocId((current) => {
3806
+ if (current[normalizedDocId] === normalizedScrollTop)
3807
+ return current;
3808
+ return withBoundedRecordEntry(current, normalizedDocId, normalizedScrollTop);
3809
+ });
3810
+ }, []);
3811
+ const handleDocumentListScrollChange = useCallback((scrollTop) => {
3812
+ const normalizedScrollTop = Math.max(0, Math.round(scrollTop));
3813
+ setDocumentListScrollTop((current) => (current === normalizedScrollTop ? current : normalizedScrollTop));
3814
+ }, []);
3815
+ const handleAnnotatedViewportChange = useCallback((contextKey, viewport) => {
3816
+ const normalizedContextKey = contextKey.trim();
3817
+ if (!normalizedContextKey)
3818
+ return;
3819
+ const normalizedViewport = {
3820
+ zoomLevel: Math.min(4, Math.max(0.25, viewport.zoomLevel)),
3821
+ scrollLeft: Math.max(0, Math.round(viewport.scrollLeft)),
3822
+ scrollTop: Math.max(0, Math.round(viewport.scrollTop)),
3823
+ };
3824
+ setAnnotatedViewportByContextKey((current) => {
3825
+ const currentViewport = current[normalizedContextKey];
3826
+ if (currentViewport
3827
+ && currentViewport.zoomLevel === normalizedViewport.zoomLevel
3828
+ && currentViewport.scrollLeft === normalizedViewport.scrollLeft
3829
+ && currentViewport.scrollTop === normalizedViewport.scrollTop) {
3830
+ return current;
3831
+ }
3832
+ return withBoundedRecordEntry(current, normalizedContextKey, normalizedViewport);
3833
+ });
3834
+ }, []);
2949
3835
  const sortOptions = useMemo(() => [
2950
3836
  { value: 'created', label: t('standalone.sortCreated') },
2951
3837
  { value: 'updated', label: t('standalone.sortUpdated') },
@@ -2994,59 +3880,73 @@ export function StandaloneLayout(props) {
2994
3880
  cycleEmptyColumnVisibility,
2995
3881
  emptyColumnMode,
2996
3882
  ]);
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, {});
3883
+ const taskFilterActions = useMemo(() => {
3884
+ if (workspaceChromeDefinition.moduleId !== 'tasks')
3885
+ return [];
3886
+ return [
3887
+ {
3888
+ key: 'filter-toggle',
3889
+ icon: _jsx(Filter, { size: 16 }),
3890
+ title: t('standalone.toggleFilters'),
3891
+ onClick: () => setShowFilters(!showFilters),
3892
+ active: showFilters,
3893
+ ariaExpanded: showFilters,
3894
+ ariaControls: 'task-workspace-filters',
3895
+ className: hasActiveWorkspaceFilterControls ? styles.filterGlow : '',
3896
+ },
3897
+ ];
3898
+ }, [
3899
+ hasActiveWorkspaceFilterControls,
3900
+ setShowFilters,
3901
+ showFilters,
3902
+ workspaceChromeDefinition.moduleId,
3903
+ ]);
3904
+ const universalAgentActions = useMemo(() => {
3905
+ const actions = [];
3906
+ if (taskforceAgentsWorkspaceEnabled) {
3907
+ actions.push({
3908
+ key: 'ask-agent',
3909
+ icon: _jsx(Bot, { size: 16 }),
3910
+ title: taskforceAgentDrawerOpen ? 'Close Taskforce Agent' : 'Ask Taskforce Agent',
3911
+ onClick: taskforceAgentDrawerOpen ? handleCloseTaskforceAgentDrawer : handleOpenTaskforceAgentDrawer,
3912
+ active: taskforceAgentDrawerOpen,
3913
+ });
3029
3914
  }
3915
+ return actions;
3916
+ }, [
3917
+ handleCloseTaskforceAgentDrawer,
3918
+ handleOpenTaskforceAgentDrawer,
3919
+ taskforceAgentDrawerOpen,
3920
+ taskforceAgentsWorkspaceEnabled,
3921
+ ]);
3922
+ const taskFilterBar = useMemo(() => {
3923
+ 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
3924
+ && !hasDropdownFilters
3925
+ && sortBy === 'created'
3926
+ && props.sortOrder === 'desc', clearFilters: () => {
3927
+ clearFilters();
3928
+ clearTaskHeaderQuickFilter();
3929
+ setSelectedPlanningInitiativeId('');
3930
+ setSelectedPlanningWorkstreamId('');
3931
+ } }));
3030
3932
  }, [
3031
3933
  assigneeOptions,
3032
3934
  categoryFilterOptions,
3033
3935
  clearFilters,
3034
- deletedScopeAllTasks.length,
3035
- documentAttachmentFilters,
3036
- documentTypeFilters,
3037
3936
  filterAssignees,
3038
3937
  filterCategories,
3039
3938
  filterPriorities,
3040
3939
  filterStatus,
3041
3940
  filterTypes,
3941
+ hasDropdownFilters,
3942
+ hasSearchFilter,
3042
3943
  handleInitiativeFilterChange,
3043
3944
  handleWorkstreamFilterChange,
3044
3945
  initiativeFilterOptions,
3045
3946
  priorities,
3947
+ props.sortOrder,
3046
3948
  selectedPlanningInitiativeId,
3047
3949
  selectedPlanningWorkstreamId,
3048
- setDocumentAttachmentFilters,
3049
- setDocumentTypeFilters,
3050
3950
  setFilterAssignees,
3051
3951
  setFilterCategories,
3052
3952
  setFilterPriorities,
@@ -3056,14 +3956,13 @@ export function StandaloneLayout(props) {
3056
3956
  setSelectedPlanningWorkstreamId,
3057
3957
  setShowArchive,
3058
3958
  setTaskScope,
3959
+ sortBy,
3960
+ clearTaskHeaderQuickFilter,
3059
3961
  showArchive,
3060
3962
  taskScope,
3061
3963
  taxonomyDisplayLabels,
3062
3964
  typeFilterOptions,
3063
3965
  workstreamFilterOptions,
3064
- workspaceChromeDefinition.filterBar.kind,
3065
- fetchArchive,
3066
- handleEmptyDeletedTasks,
3067
3966
  ]);
3068
3967
  const universalDisplayActions = useMemo(() => {
3069
3968
  const actions = [{
@@ -3075,8 +3974,8 @@ export function StandaloneLayout(props) {
3075
3974
  }];
3076
3975
  return actions;
3077
3976
  }, [
3078
- zenMode,
3079
3977
  setZenMode,
3978
+ zenMode,
3080
3979
  ]);
3081
3980
  const headerSectionRegistry = useMemo(() => ({
3082
3981
  search: (_jsx(WorkspaceHeaderSearch, { value: searchQuery, placeholder: t('standalone.searchPlaceholder'), active: hasSearchFilter, onChange: setSearchQuery, onClear: () => setSearchQuery(''), clearTitle: t('standalone.clearSearchTitle') })),
@@ -3105,52 +4004,206 @@ export function StandaloneLayout(props) {
3105
4004
  'add-document': null,
3106
4005
  }), [openAddTaskModal]);
3107
4006
  const workspaceToolRail = useMemo(() => {
4007
+ const workspaceToolButtonClass = `${shellStyles.workspaceToolButton} tf-control-icon tf-control-icon-quiet`;
4008
+ const workspaceToolButtonActiveClass = `${workspaceToolButtonClass} tf-control-icon-active`;
3108
4009
  const moduleIcons = {
3109
4010
  tasks: _jsx(ClipboardCheck, { size: 18 }),
4011
+ planning: _jsx(Layers, { size: 18 }),
3110
4012
  docs: _jsx(FileText, { size: 18 }),
3111
4013
  annotate: _jsx(Image, { size: 18 }),
3112
- workflows: _jsx(Workflow, { size: 18 }),
3113
- agents: _jsx(Bot, { size: 18 }),
4014
+ workflowManager: _jsx(Workflow, { size: 18 }),
4015
+ taskforceAgents: _jsx(Bot, { size: 18 }),
4016
+ aiProfiles: _jsx(Users, { size: 18 }),
3114
4017
  };
3115
- const trayButtonDisabledClass = shellStyles.workspaceToolButtonDisabled || '';
3116
4018
  const workspaceTrayButton = (() => {
4019
+ if (resolvedWorkspaceModule === 'planning') {
4020
+ return _jsx("span", { className: shellStyles.workspaceToolButton, "aria-hidden": "true" });
4021
+ }
3117
4022
  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 }) }));
4023
+ 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
4024
  }
3120
4025
  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 }) }));
4026
+ 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 }) }));
4027
+ }
4028
+ if (resolvedWorkspaceModule === 'aiProfiles') {
4029
+ 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 }) }));
3122
4030
  }
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 }) }));
4031
+ if (resolvedWorkspaceModule === 'taskforceAgents') {
4032
+ 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 }) }));
3125
4033
  }
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 }) }));
4034
+ if (resolvedWorkspaceModule === 'workflowManager') {
4035
+ 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 }) }));
3128
4036
  }
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 }) }));
4037
+ return (_jsx("button", { ref: planningDrawerLauncherRef, type: "button", className: resolvedWorkspaceModule === 'tasks' && planningDrawerOpen
4038
+ ? workspaceToolButtonActiveClass
4039
+ : 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
4040
  })();
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: () => {
4041
+ 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
4042
+ ? workspaceToolButtonActiveClass
4043
+ : 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'
4044
+ ? workspaceToolButtonActiveClass
4045
+ : workspaceToolButtonClass, onClick: () => {
4046
+ if (resolvedWorkspaceModule === 'workflowManager' && workflowManagerHasUnsavedChanges && !workflowDiscardBypassRef.current) {
4047
+ setPendingWorkflowDiscardAction(() => () => {
4048
+ setSettingsSection('general');
4049
+ setActiveTab('settings');
4050
+ });
4051
+ return;
4052
+ }
3132
4053
  setSettingsSection('general');
3133
4054
  setActiveTab('settings');
3134
4055
  }, 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]);
4056
+ }, [activeTab, agentTrayOpen, documentTrayOpen, handleAgentTrayToggle, handleDocumentTrayToggle, handleImageTrayToggle, handleModuleChange, handlePlanningToolToggle, handleTaskforceAgentRosterTrayToggle, handleWorkflowLibraryTrayToggle, imageTrayOpen, planningDrawerOpen, resolvedWorkspaceModule, setSettingsSection, setActiveTab, taskforceAgentRosterTrayOpen, workflowLibraryTrayOpen, workflowManagerHasUnsavedChanges, workspaceToolModules]);
3136
4057
  const [planningDrawerPortalElement, setPlanningDrawerPortalElement] = useState(null);
3137
4058
  const setPlanningDrawerPortalRef = useCallback((node) => {
3138
4059
  setPlanningDrawerPortalElement(node);
3139
4060
  }, []);
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) => ({
4061
+ const hydratePlanningWorkspaceEntity = useCallback((entityType, entityId) => hydratePlanningEntity({ type: entityType, id: entityId }), [hydratePlanningEntity]);
4062
+ const createPlanningWorkspaceEntity = useCallback(async (entityType, input) => {
4063
+ const title = input.title.trim();
4064
+ if (!title)
4065
+ throw new Error(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} title is required.`);
4066
+ try {
4067
+ if (entityType === 'initiative') {
4068
+ const created = await props.createInitiative({
4069
+ title,
4070
+ description: input.description?.trim() || null,
4071
+ ownerId: input.ownerId?.trim() || null,
4072
+ });
4073
+ pushNotice('Initiative created', 'success');
4074
+ return { id: created.id };
4075
+ }
4076
+ const created = await props.createWorkstream({
4077
+ title,
4078
+ description: input.description?.trim() || null,
4079
+ ownerId: input.ownerId?.trim() || null,
4080
+ initiativeId: input.initiativeId?.trim() || null,
4081
+ });
4082
+ pushNotice('Workstream created', 'success');
4083
+ return { id: created.id };
4084
+ }
4085
+ catch (error) {
4086
+ pushNotice(error instanceof Error ? error.message : 'Failed to create planning item.', 'error');
4087
+ throw error;
4088
+ }
4089
+ }, [props.createInitiative, props.createWorkstream, pushNotice]);
4090
+ const updatePlanningWorkspaceEntity = useCallback(async (entityType, entityId, input) => {
4091
+ const title = input.title.trim();
4092
+ if (!title)
4093
+ throw new Error(`${entityType === 'initiative' ? 'Initiative' : 'Workstream'} title is required.`);
4094
+ try {
4095
+ const patch = { title, description: input.description?.trim() || null };
4096
+ if (entityType === 'initiative') {
4097
+ await props.updateInitiative(entityId, patch);
4098
+ pushNotice('Initiative updated', 'success');
4099
+ return;
4100
+ }
4101
+ await props.updateWorkstream(entityId, patch);
4102
+ pushNotice('Workstream updated', 'success');
4103
+ }
4104
+ catch (error) {
4105
+ pushNotice(error instanceof Error ? error.message : 'Failed to update planning item.', 'error');
4106
+ throw error;
4107
+ }
4108
+ }, [props.updateInitiative, props.updateWorkstream, pushNotice]);
4109
+ const reorderPlanningWorkstreamTasks = useCallback(async (workstreamId, taskIds) => {
4110
+ try {
4111
+ await props.reorderWorkstreamTasks(workstreamId, taskIds);
4112
+ }
4113
+ catch (error) {
4114
+ pushNotice(error instanceof Error ? error.message : 'Failed to reorder workstream tasks.', 'error');
4115
+ throw error;
4116
+ }
4117
+ }, [props.reorderWorkstreamTasks, pushNotice]);
4118
+ const planningWorkspaceModel = useMemo(() => ({
4119
+ initiatives: planningStructure.allInitiatives,
4120
+ standaloneWorkstreams: planningStructure.allStandaloneWorkstreams,
4121
+ assigneeOptions,
4122
+ currentOwnerId: normalizedAuthUserId === 'anonymous' ? null : normalizedAuthUserId,
4123
+ currentWorkspaceId,
4124
+ theme: currentTheme,
4125
+ taskReferences,
4126
+ loadState: props.planningLoadState,
4127
+ hydrationStateByEntity: planningHydrationStateByEntity,
4128
+ hydrateEntity: hydratePlanningWorkspaceEntity,
4129
+ retry: () => { void props.fetchPlanningEntities(); },
4130
+ openTask: handleOpenTaskById,
4131
+ setTaskStatus: handleSetPlanningTaskStatus,
4132
+ setTaskAssignee: handleChangePlanningTaskAssignee,
4133
+ linkOptions: planningLinkOptions,
4134
+ assignWorkstreamToInitiative: handleAssignInitiativeToWorkstream,
4135
+ assignTaskToWorkstream: handleAssignTaskToWorkstream,
4136
+ attachWorkstreamToInitiative: handleAttachWorkstreamToInitiativeByReference,
4137
+ attachTaskToWorkstream: handleAttachTaskToWorkstreamByReference,
4138
+ archiveEntity: handleArchivePlanningEntity,
4139
+ unarchiveEntity: handleUnarchivePlanningEntity,
4140
+ changeOwner: handleChangePlanningOwner,
4141
+ createEntity: createPlanningWorkspaceEntity,
4142
+ updateEntity: updatePlanningWorkspaceEntity,
4143
+ addContextFile: handleAddPlanningContextFile,
4144
+ removeContextFile: handleRemovePlanningContextFile,
4145
+ updateContextCaption: handleUpdatePlanningContextCaption,
4146
+ showTaskCardStatusLabel,
4147
+ taskArrangeMode: planningTaskArrangeMode,
4148
+ setTaskArrangeMode: setPlanningTaskArrangeMode,
4149
+ reorderWorkstreamTasks: reorderPlanningWorkstreamTasks,
4150
+ }), [
4151
+ currentWorkspaceId,
4152
+ currentTheme,
4153
+ handleChangePlanningOwner,
4154
+ handleAssignInitiativeToWorkstream,
4155
+ handleAssignTaskToWorkstream,
4156
+ handleAttachTaskToWorkstreamByReference,
4157
+ handleAttachWorkstreamToInitiativeByReference,
4158
+ handleArchivePlanningEntity,
4159
+ handleUnarchivePlanningEntity,
4160
+ createPlanningWorkspaceEntity,
4161
+ handleAddPlanningContextFile,
4162
+ handleOpenTaskById,
4163
+ handleRemovePlanningContextFile,
4164
+ handleSetPlanningTaskStatus,
4165
+ handleChangePlanningTaskAssignee,
4166
+ handleUpdatePlanningContextCaption,
4167
+ hydratePlanningWorkspaceEntity,
4168
+ assigneeOptions,
4169
+ normalizedAuthUserId,
4170
+ planningStructure.allInitiatives,
4171
+ planningStructure.allStandaloneWorkstreams,
4172
+ planningLinkOptions,
4173
+ planningHydrationStateByEntity,
4174
+ props.fetchPlanningEntities,
4175
+ props.planningLoadState,
4176
+ showTaskCardStatusLabel,
4177
+ planningTaskArrangeMode,
4178
+ reorderPlanningWorkstreamTasks,
4179
+ taskReferences,
4180
+ updatePlanningWorkspaceEntity,
4181
+ ]);
4182
+ 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) => {
4183
+ setPlanningFavorites((current) => togglePlanningFavorite(current, favorite));
4184
+ }, 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
4185
+ ? () => { void hydratePlanningEntity(planningDrawerDetail); }
4186
+ : undefined, onRetrySecondaryHydration: planningNestedWorkstreamDetailId
4187
+ ? () => { void hydratePlanningEntity({ type: 'workstream', id: planningNestedWorkstreamDetailId }); }
4188
+ : undefined, onWidthChange: setPlanningDrawerWidthPx, currentWorkspaceId: currentWorkspaceId, currentOwnerId: normalizedAuthUserId === 'anonymous' ? '' : normalizedAuthUserId, linkOptions: planningLinkOptions, showTaskCardStatusLabel: showTaskCardStatusLabel, assigneeOptions: assigneeOptions.map((option) => ({
3141
4189
  value: String(option.value),
3142
4190
  label: option.label,
4191
+ icon: option.icon,
4192
+ color: option.color,
3143
4193
  kind: option.kind,
4194
+ avatarUrl: option.avatarUrl ?? null,
4195
+ avatarRevision: option.avatarRevision ?? null,
4196
+ avatarUpdatedAt: option.avatarUpdatedAt ?? null,
3144
4197
  username: option.username ?? null,
4198
+ surfaceType: option.surfaceType ?? null,
4199
+ providerMetadata: option.providerMetadata ?? null,
3145
4200
  archivedAt: option.archivedAt ?? null
3146
4201
  })), 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: () => {
3147
4202
  planningEditorSubmitInFlightRef.current = false;
3148
4203
  setIsSubmittingPlanningEditor(false);
3149
4204
  setPlanningSecondaryEditor(null);
3150
4205
  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) => {
4206
+ }, 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, onArchiveInitiative: (initiativeId) => {
3154
4207
  void props.archiveInitiative(initiativeId).then(() => {
3155
4208
  pushNotice('Initiative archived', 'success');
3156
4209
  }).catch((error) => {
@@ -3185,123 +4238,125 @@ export function StandaloneLayout(props) {
3185
4238
  const workspacePrimaryAction = workspaceChromeDefinition.primaryAction
3186
4239
  ? primaryActionRegistry[workspaceChromeDefinition.primaryAction]
3187
4240
  : 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') {
4241
+ 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
4242
+ ? `${shellStyles.workspaceToolRail} ${shellStyles.workspaceToolRailRight}`
4243
+ : 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;
4244
+ 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: {
4245
+ marginLeft: '6px',
4246
+ height: '24px',
4247
+ width: '24px',
4248
+ padding: 0,
4249
+ borderRadius: '999px',
4250
+ border: `1px solid ${headerSyncStatusMeta.border}`,
4251
+ background: headerSyncStatusMeta.background,
4252
+ color: headerSyncStatusMeta.color,
4253
+ display: 'inline-flex',
4254
+ alignItems: 'center',
4255
+ justifyContent: 'center'
4256
+ }, 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: () => {
4257
+ if (hasActiveCommercialEntitlement) {
4258
+ void handlePlansBack();
4259
+ return;
4260
+ }
4261
+ closePlansScreen();
4262
+ }, 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: {
4263
+ position: 'relative',
4264
+ display: 'flex',
4265
+ flex: 1,
4266
+ minHeight: 0,
4267
+ overflowY: 'auto',
4268
+ overflowX: 'hidden',
4269
+ scrollbarGutter: 'stable',
4270
+ background: 'var(--surface-page)'
4271
+ }, 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: () => {
4272
+ setRequestedDocPath(null);
4273
+ setRequestedDocAssetId(null);
4274
+ }, 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: {
4275
+ ...settingsModel,
4276
+ initialSection: 'mcp',
4277
+ onOpenCloudAuth: openSharedLoginRoute
4278
+ }, renderMode: "mcp-only" }) }) })] })) : (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent} `, style: {
4279
+ position: 'relative',
4280
+ opacity: props.loadingTasks ? 0.7 : 1,
4281
+ transition: 'opacity 0.2s ease, padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
4282
+ display: 'flex',
4283
+ flex: 1,
4284
+ minHeight: 0,
4285
+ paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px`,
4286
+ }, 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: {
4287
+ position: 'relative',
4288
+ width: '100%',
4289
+ minWidth: 0,
4290
+ flex: 1,
4291
+ minHeight: 0,
4292
+ display: 'flex',
4293
+ flexDirection: 'column',
4294
+ overflow: 'hidden',
4295
+ transition: 'padding 220ms cubic-bezier(0.4, 0, 0.2, 1)',
4296
+ paddingLeft: planningDrawerOpen
4297
+ ? `${planningDrawerWidthPx + WORKSPACE_CONTENT_GUTTER}px`
4298
+ : `${WORKSPACE_CONTENT_GUTTER}px`,
4299
+ paddingRight: (groupBy === 'schedule' && scheduleSidebarOpen)
4300
+ ? `${SCHEDULE_SIDEBAR_WIDTH_PX}px`
4301
+ : 0,
4302
+ }, children: [_jsx("div", { ref: setPlanningDrawerPortalRef, style: {
4303
+ position: 'absolute',
4304
+ top: 0,
4305
+ right: 0,
4306
+ bottom: 0,
4307
+ left: `-${WORKSPACE_TOOL_RAIL_WIDTH}px`,
4308
+ zIndex: 35,
4309
+ pointerEvents: 'none',
4310
+ } }), 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: () => {
4311
+ const count = props.deletedTasks.length;
4312
+ if (count > 0 && window.confirm(`Permanently delete all ${count} tasks in Trash? Filters and selection do not limit this action. This cannot be undone.`)) {
4313
+ void handleEmptyDeletedTasks();
4314
+ }
4315
+ } })), _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
4316
+ ? createPortal(planningDrawerNode, planningDrawerPortalElement)
4317
+ : 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: () => {
4318
+ setPlanningDrawerDetail(null);
4319
+ setScheduleSidebarOpen(true);
4320
+ }, title: "Show Schedule Sidebar", style: {
4321
+ position: 'absolute',
4322
+ top: '10px',
4323
+ right: '10px',
4324
+ zIndex: 20,
4325
+ }, 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'
4326
+ ? createPortal(taskforceAgentDrawerNode, document.body)
4327
+ : 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: {
4328
+ '--taskforce-task-modal-backdrop-top': `${taskforceAgentDrawerTop}px`,
4329
+ '--taskforce-task-modal-backdrop-left': `${WORKSPACE_TOOL_RAIL_WIDTH}px`,
4330
+ }, 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, 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) => {
4331
+ if (currentTask?.isDeleted) {
3252
4332
  const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3253
4333
  if (!deletedRecord)
3254
4334
  return;
3255
- void handleRestoreDeletedTask(deletedRecord.id);
4335
+ void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
3256
4336
  return;
3257
4337
  }
3258
4338
  void handleUnarchive(taskId);
3259
- }, onDelete: (taskId) => {
3260
- if (taskScope === 'deleted') {
3261
- const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3262
- if (!deletedRecord)
3263
- return;
4339
+ }, handleRestoreDeletedTask: currentTask?.deletedRecordId
4340
+ ? (deletedRecordId) => {
4341
+ const deletedRecord = props.deletedTasks.find((entry) => entry.id === deletedRecordId);
4342
+ void handleRestoreDeletedTask(deletedRecordId, deletedRecord?.taskId);
4343
+ }
4344
+ : undefined, handlePermanentlyDeleteDeletedTask: currentTask?.deletedRecordId
4345
+ ? (deletedRecordId) => {
3264
4346
  const confirmed = window.confirm('Permanently delete this task? This cannot be undone.');
3265
4347
  if (!confirmed)
3266
4348
  return;
3267
- void handlePermanentlyDeleteDeletedTask(deletedRecord.id);
3268
- return;
4349
+ void handlePermanentlyDeleteDeletedTask(deletedRecordId);
4350
+ resetForm();
4351
+ setActiveTab('tasks');
3269
4352
  }
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) => {
4353
+ : undefined, onAskAgent: handleAskTaskforceAgentForTask }), _jsx(TopNoticeLayer, { notice: error ? { message: error, tone: 'error' } : uiNotice, onDismiss: () => {
4354
+ clearTaskError();
4355
+ clearNotice();
4356
+ }, 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, 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
4357
  setSettingsSection(section);
3303
4358
  setActiveTab('settings');
3304
- }, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), onOpenTaskById: handleOpenTaskById, onAddContextFile: (file) => {
4359
+ }, onSubmit: handleSubmit, commentsEndRef: commentsEndRef, onAddComment: () => handleAddComment(newCommentText), taskReferences: taskTextReferences, onAddContextFile: (file) => {
3305
4360
  updateTaskContextAttachments((current) => [...current, file]);
3306
4361
  }, onRemoveContextFile: async (index) => {
3307
4362
  updateTaskContextAttachments((current) => current.filter((_, i) => i !== index));
@@ -3313,12 +4368,19 @@ export function StandaloneLayout(props) {
3313
4368
  return { path: s, caption, timestamp: new Date().toISOString() };
3314
4369
  return { ...s, caption };
3315
4370
  }));
4371
+ }, onOpenContextImage: (attachment) => {
4372
+ dispatchPreviewContextAttachment(attachment, {
4373
+ ownerType: 'task',
4374
+ ownerId: editingTaskId,
4375
+ ownerReferenceLabel: getTaskReferenceLabel(currentTask),
4376
+ workspaceId: currentWorkspaceId,
4377
+ });
3316
4378
  }, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onUnarchive: (taskId) => {
3317
4379
  if (currentTask?.isDeleted) {
3318
4380
  const deletedRecord = deletedTaskRecordByTaskId.get(taskId);
3319
4381
  if (!deletedRecord)
3320
4382
  return;
3321
- void handleRestoreDeletedTask(deletedRecord.id);
4383
+ void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
3322
4384
  return;
3323
4385
  }
3324
4386
  void handleUnarchive(taskId);
@@ -3329,22 +4391,14 @@ export function StandaloneLayout(props) {
3329
4391
  setShowHelpModal(false);
3330
4392
  setActiveTab('settings');
3331
4393
  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: () => {
4394
+ } }), _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
4395
  setProfileSaveError(null);
3338
4396
  setProfileSaveNotice(null);
3339
4397
  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: () => {
4398
+ }, onFetchLoginMethods: fetchLoginMethods, onUnlinkLoginMethod: unlinkLoginMethod, onAddPassword: addPasswordToAccount, onChangePassword: changePassword, onLinkProvider: (provider) => beginOAuthLink(provider), onBillingIntervalChange: setBillingIntervalChoice, onRefreshBilling: () => { void loadAccountProfileSummary(); }, onUpdateInterval: () => { void handleSwitchSubscriptionInterval(); }, onManageBilling: () => { void handleOpenBillingPortal(); }, onOpenPlans: () => {
4399
+ setShowAccountSettings(false);
4400
+ void handleStartCheckout();
4401
+ } }), _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
4402
  setTeamManagementTab('members');
3349
4403
  void loadTeamUsers();
3350
4404
  }, onOpenInvitesTab: () => setTeamManagementTab('invites'), onOpenAuditTab: () => {
@@ -3393,11 +4447,21 @@ export function StandaloneLayout(props) {
3393
4447
  headers: teamAdminHeaders(),
3394
4448
  credentials: 'include'
3395
4449
  }));
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) => {
4450
+ }, 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
4451
  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: () => {
4452
+ }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onRetrySync: () => {
4453
+ void retryWorkspaceCloudSync().catch(() => {
4454
+ // Coordinator status owns the durable error and retry presentation.
4455
+ });
4456
+ }, onTransferCoordinatorOwnership: () => {
4457
+ void handleCoordinatorOwnershipTransfer();
4458
+ } }), _jsx(DiscardChangesDialog, { isOpen: Boolean(pendingWorkflowDiscardAction), onKeepEditing: () => setPendingWorkflowDiscardAction(null), onDiscard: () => {
4459
+ const action = pendingWorkflowDiscardAction;
4460
+ setPendingWorkflowDiscardAction(null);
4461
+ workflowDiscardBypassRef.current = true;
4462
+ action?.();
4463
+ window.setTimeout(() => { workflowDiscardBypassRef.current = false; }, 0);
4464
+ }, 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
4465
  const parts = currentBrowsePath.split('/').filter(Boolean);
3402
4466
  parts.pop();
3403
4467
  fetchFolders(parts.length ? parts.join('/') + '/' : '');