@taskforcehq/taskforce 0.3.328 → 0.3.330

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 (485) hide show
  1. package/dist/Taskforce.module.css +523 -79
  2. package/dist/TaskforceCore.js +237 -230
  3. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
  4. package/dist/cli.js +34 -0
  5. package/dist/cliCloudTargetGuard.d.ts +5 -0
  6. package/dist/cliCloudTargetGuard.js +11 -0
  7. package/dist/components/features/AiProfilesModule.js +3 -5
  8. package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
  9. package/dist/components/features/TaskSettings.d.ts +12 -1
  10. package/dist/components/features/TaskSettings.js +217 -54
  11. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  12. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  13. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
  14. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  15. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  16. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  17. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  18. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  19. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  20. package/dist/components/features/planning/PlanningModule.js +2 -5
  21. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
  22. package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
  23. package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
  24. package/dist/components/features/planning/planningTaskArrangement.js +5 -5
  25. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  26. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  27. package/dist/components/features/taskforceAgentEditorModel.js +5 -1
  28. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  29. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  30. package/dist/components/task/TaskCard.d.ts +5 -0
  31. package/dist/components/task/TaskCard.js +65 -10
  32. package/dist/components/task/TaskImageReviews.js +14 -5
  33. package/dist/components/task/TaskKanban.d.ts +6 -1
  34. package/dist/components/task/TaskKanban.js +152 -6
  35. package/dist/components/task/TaskList.d.ts +5 -0
  36. package/dist/components/task/TaskList.js +3 -3
  37. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  38. package/dist/components/ui/PasswordInput.d.ts +6 -0
  39. package/dist/components/ui/PasswordInput.js +11 -0
  40. package/dist/components/ui/TopNoticeLayer.js +1 -1
  41. package/dist/components/views/AppShellHeader.js +32 -11
  42. package/dist/components/views/PlanComparisonPage.js +12 -0
  43. package/dist/components/views/StandaloneLayout.js +32 -55
  44. package/dist/components/views/WidgetView.js +3 -3
  45. package/dist/components/views/panels/PlanningDrawer.js +5 -12
  46. package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
  47. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  48. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  49. package/dist/config/envSchema.js +60 -1
  50. package/dist/config/localServiceRuntimeContract.d.ts +13 -0
  51. package/dist/config/localServiceRuntimeContract.js +135 -0
  52. package/dist/core/AiProfileService.js +46 -8
  53. package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
  54. package/dist/core/DeletedTaskLifecycleService.js +37 -6
  55. package/dist/core/McpTokenService.d.ts +23 -1
  56. package/dist/core/McpTokenService.js +93 -10
  57. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
  58. package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
  59. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  60. package/dist/core/TaskChecklistCommandService.js +83 -5
  61. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  62. package/dist/core/TaskLifecycleCommandService.js +6 -2
  63. package/dist/core/Taskforce.d.ts +94 -2
  64. package/dist/core/Taskforce.js +760 -36
  65. package/dist/core/types.d.ts +14 -0
  66. package/dist/documentReviews/commandService.d.ts +2 -1
  67. package/dist/documentReviews/commandService.js +6 -3
  68. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  69. package/dist/hooks/sync/orchestratorShared.js +2 -0
  70. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
  71. package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
  72. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
  73. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
  74. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
  75. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  76. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  77. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  78. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  79. package/dist/hooks/tasks/taskHttpMutation.js +1 -0
  80. package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
  81. package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
  82. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
  83. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
  84. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
  85. package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
  86. package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
  87. package/dist/hooks/tasks/useTaskFormActions.js +65 -12
  88. package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
  89. package/dist/hooks/ui/useSettingsModel.js +13 -2
  90. package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
  91. package/dist/hooks/ui/useSettingsPersistence.js +74 -47
  92. package/dist/hooks/useFilterSort.d.ts +7 -3
  93. package/dist/hooks/useFilterSort.js +15 -5
  94. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  95. package/dist/hooks/useSyncOrchestrator.js +111 -2
  96. package/dist/hooks/useTaskData.d.ts +40 -1
  97. package/dist/hooks/useTaskData.js +240 -9
  98. package/dist/hooks/useTaskMutations.d.ts +12 -2
  99. package/dist/hooks/useTaskMutations.js +266 -52
  100. package/dist/hooks/useTaskforce.d.ts +39 -9
  101. package/dist/hooks/useTaskforce.js +359 -40
  102. package/dist/hooks/useUiNotice.d.ts +4 -0
  103. package/dist/hooks/useUiNotice.js +4 -0
  104. package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
  105. package/dist/mcp/clientRegistry.d.ts +2 -2
  106. package/dist/mcp/clientRegistry.js +1 -1
  107. package/dist/mcp/documentAssetRegistrar.js +53 -41
  108. package/dist/mcp/documentHelpers.d.ts +1 -0
  109. package/dist/mcp/documentHelpers.js +7 -3
  110. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  111. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  112. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  113. package/dist/mcp/httpProtocolRouting.d.ts +10 -0
  114. package/dist/mcp/httpProtocolRouting.js +19 -0
  115. package/dist/mcp/localCliHealth.d.ts +2 -2
  116. package/dist/mcp/localCliHealth.js +2 -2
  117. package/dist/mcp/localServiceProxy.d.ts +1 -0
  118. package/dist/mcp/localServiceProxy.js +530 -68
  119. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  120. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  121. package/dist/mcp/runtime.d.ts +54 -79
  122. package/dist/mcp/runtime.js +556 -139
  123. package/dist/mcp/taskPlanningRegistrar.js +64 -42
  124. package/dist/mcp/toolCallCompatibility.js +38 -1
  125. package/dist/mcp/toolCatalog.d.ts +1 -0
  126. package/dist/mcp/toolProfiles.d.ts +2 -0
  127. package/dist/mcp/toolProfiles.js +10 -0
  128. package/dist/mcp/toolRegistry.d.ts +1 -0
  129. package/dist/mcp/toolRegistry.js +1 -0
  130. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  131. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  132. package/dist/migrations/taskSchemaMigrations.js +427 -0
  133. package/dist/runtime/appGateDefinitions.d.ts +30 -6
  134. package/dist/runtime/appGateDefinitions.js +6 -6
  135. package/dist/runtime/appGates.d.ts +13 -13
  136. package/dist/runtime/appGates.js +36 -13
  137. package/dist/runtime/nodeAppGates.d.ts +8 -0
  138. package/dist/runtime/nodeAppGates.js +27 -0
  139. package/dist/server/cloudCollectionRead.d.ts +1 -1
  140. package/dist/server/cloudCollectionRead.js +2 -2
  141. package/dist/server/index.d.ts +6 -0
  142. package/dist/server/index.js +123 -14
  143. package/dist/server/localDatabaseIdentity.js +4 -1
  144. package/dist/server/localServiceLease.d.ts +3 -0
  145. package/dist/server/localServiceLease.js +11 -2
  146. package/dist/server/localServiceSessions.d.ts +14 -17
  147. package/dist/server/localServiceSessions.js +308 -94
  148. package/dist/server/localWorkspaceSyncServerRuntime.js +12 -7
  149. package/dist/server/rateLimit.d.ts +1 -0
  150. package/dist/server/rateLimit.js +4 -0
  151. package/dist/server/realtimeSyncWs.js +36 -12
  152. package/dist/server/routes/admin.d.ts +4 -0
  153. package/dist/server/routes/admin.js +113 -3
  154. package/dist/server/routes/agentRoles.js +3 -2
  155. package/dist/server/routes/agentSkills.js +3 -2
  156. package/dist/server/routes/agents.d.ts +7 -0
  157. package/dist/server/routes/agents.js +394 -39
  158. package/dist/server/routes/annotatedAttachments.js +3 -2
  159. package/dist/server/routes/auth.js +3 -1
  160. package/dist/server/routes/billing.js +5 -1
  161. package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
  162. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  163. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  164. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  165. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  166. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  167. package/dist/server/routes/githubReviewEvidence.js +116 -0
  168. package/dist/server/routes/localService.d.ts +15 -4
  169. package/dist/server/routes/localService.js +138 -40
  170. package/dist/server/routes/modelConnections.d.ts +24 -0
  171. package/dist/server/routes/modelConnections.js +205 -0
  172. package/dist/server/routes/primitives.d.ts +2 -0
  173. package/dist/server/routes/shared.d.ts +19 -0
  174. package/dist/server/routes/shared.js +95 -19
  175. package/dist/server/routes/sync.js +1 -0
  176. package/dist/server/routes/syncAuxRoutes.js +9 -2
  177. package/dist/server/routes/syncPullApplyRoutes.js +23 -4
  178. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  179. package/dist/server/routes/syncPushRoutes.js +1 -0
  180. package/dist/server/routes/syncV3FeedRoutes.js +27 -16
  181. package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
  182. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
  183. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
  184. package/dist/server/routes/syncV3OperationRoutes.js +45 -9
  185. package/dist/server/routes/tasks.js +124 -13
  186. package/dist/server/routes/workflows.js +9 -1
  187. package/dist/server/routes/workspaces.js +43 -1
  188. package/dist/server/routes.js +59 -0
  189. package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
  190. package/dist/server/workspaceDeletionAdmission.js +50 -0
  191. package/dist/service/localServiceCli.js +16 -0
  192. package/dist/service/localServiceClientLifecycle.js +36 -10
  193. package/dist/services/codexAppServerModelGateway.d.ts +161 -0
  194. package/dist/services/codexAppServerModelGateway.js +663 -0
  195. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  196. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  197. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  198. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  199. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  200. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  201. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  202. package/dist/services/executorPhaseAApprovalService.js +609 -0
  203. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  204. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  205. package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
  206. package/dist/services/executorPhaseAIssuerCore.js +295 -0
  207. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  208. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  209. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  210. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  211. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  212. package/dist/services/githubReviewEvidenceService.js +336 -0
  213. package/dist/services/modelGateway.d.ts +7 -0
  214. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  215. package/dist/services/modelProviderConnectionService.js +279 -0
  216. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  217. package/dist/services/modelProviderCredentialHome.js +271 -0
  218. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  219. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  220. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  221. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  222. package/dist/services/taskforceAgentMcpBridge.d.ts +8 -2
  223. package/dist/services/taskforceAgentMcpBridge.js +30 -27
  224. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  225. package/dist/shared/adminEdgeProxy.js +94 -0
  226. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  227. package/dist/shared/adminProxySessionCookies.js +86 -0
  228. package/dist/shared/aiProfileColors.d.ts +31 -1
  229. package/dist/shared/aiProfileColors.js +14 -6
  230. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  231. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  232. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  233. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  234. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  235. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  236. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  237. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  238. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  239. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  240. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  241. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  242. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  243. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  244. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  245. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  246. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  247. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  248. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  249. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  250. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  251. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  252. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  253. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  254. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  255. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  256. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  257. package/dist/shared/executorPhaseATiming.js +1 -0
  258. package/dist/shared/planningIdentity.js +1 -1
  259. package/dist/shared/productLogoKeys.d.ts +2 -0
  260. package/dist/shared/productLogoKeys.js +18 -0
  261. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  262. package/dist/shared/taskforceAgentDefinition.js +6 -3
  263. package/dist/shared/taskforceAgentModels.d.ts +1 -0
  264. package/dist/shared/taskforceAgentModels.js +36 -3
  265. package/dist/shared/userFeatureGrants.d.ts +4 -0
  266. package/dist/shared/userFeatureGrants.js +7 -0
  267. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  268. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  269. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  270. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  271. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  272. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  273. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  274. package/dist/storage/modelProviderConnectionStore.js +446 -0
  275. package/dist/storage/postgresAdapter.d.ts +24 -3
  276. package/dist/storage/postgresAdapter.js +117 -14
  277. package/dist/storage/postgresWorker.js +22 -5
  278. package/dist/storage/postgresWorkerProtocol.d.ts +30 -0
  279. package/dist/storage/postgresWorkerProtocol.js +30 -0
  280. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  281. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  282. package/dist/sync/cloudSyncApi.d.ts +4 -1
  283. package/dist/sync/cloudSyncApi.js +7 -2
  284. package/dist/sync/contentSyncState.d.ts +1 -1
  285. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
  286. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +67 -30
  287. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  288. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  289. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
  290. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  291. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  292. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  293. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  294. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  295. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  296. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  297. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
  298. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  299. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
  300. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
  301. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  302. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  303. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  304. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +11 -0
  305. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
  306. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  307. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  308. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
  309. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
  310. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +134 -43
  311. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  312. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
  313. package/dist/sync/engine/workspaceSyncEngineTransfers.js +11 -4
  314. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  315. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
  316. package/dist/sync/syncApplyHandlers.d.ts +2 -0
  317. package/dist/sync/syncApplyHandlers.js +10 -1
  318. package/dist/sync/syncService.d.ts +17 -0
  319. package/dist/sync/syncService.js +87 -19
  320. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  321. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  322. package/dist/sync/v3/combinedFeedCapability.js +8 -0
  323. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  324. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  325. package/dist/sync/v3/durableOperationReplay.js +18 -0
  326. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +2 -0
  327. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +14 -1
  328. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +4 -1
  329. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +62 -15
  330. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  331. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
  332. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
  333. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
  334. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +37 -2
  335. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  336. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
  337. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
  338. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  339. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  340. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  341. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +2 -0
  342. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
  343. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  344. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  345. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  346. package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
  347. package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
  348. package/dist/sync/v3/localTaskMetadataClient.js +1 -0
  349. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
  350. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
  351. package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
  352. package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
  353. package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
  354. package/dist/sync/v3/localTaskStatusClient.js +6 -1
  355. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -0
  356. package/dist/sync/v3/localTaskStatusOutboxService.js +272 -24
  357. package/dist/sync/v3/syncDurabilityStore.d.ts +41 -0
  358. package/dist/sync/v3/syncDurabilityStore.js +199 -13
  359. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
  360. package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
  361. package/dist/sync/v3/taskChecklistMutationService.d.ts +15 -2
  362. package/dist/sync/v3/taskChecklistMutationService.js +48 -1
  363. package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
  364. package/dist/sync/v3/taskCreateMutationService.js +7 -4
  365. package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
  366. package/dist/sync/v3/taskMetadataMutationService.js +4 -0
  367. package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
  368. package/dist/sync/v3/taskRestoreMutationService.js +7 -4
  369. package/dist/sync/v3/taskStatusMutationService.d.ts +31 -1
  370. package/dist/sync/v3/taskStatusMutationService.js +123 -3
  371. package/dist/sync/v3/workflowAssignmentSync.d.ts +6 -0
  372. package/dist/sync/v3/workflowAssignmentSync.js +30 -0
  373. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  374. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  375. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  376. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
  377. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
  378. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
  379. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
  380. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
  381. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
  382. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  383. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +18 -3
  384. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
  385. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
  386. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +14 -0
  387. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +49 -25
  388. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +13 -4
  389. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -57
  390. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +20 -0
  391. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +106 -30
  392. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +4 -1
  393. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +34 -0
  394. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +12 -0
  395. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
  396. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
  397. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
  398. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
  399. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
  400. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
  401. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
  402. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
  403. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
  404. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
  405. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
  406. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +5 -0
  407. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +7 -0
  408. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +55 -9
  409. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  410. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  411. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
  412. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
  413. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
  414. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
  415. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
  416. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  417. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  418. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  419. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  420. package/dist/sync/workspacePullFeed.js +2 -1
  421. package/dist/sync/workspaceRepair.d.ts +8 -2
  422. package/dist/sync/workspaceRepair.js +222 -6
  423. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  424. package/dist/sync/workspaceSyncModel.js +35 -7
  425. package/dist/sync/workspaceSyncState.d.ts +1 -0
  426. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  427. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  428. package/dist/types.d.ts +47 -1
  429. package/dist/types.js +6 -0
  430. package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
  431. package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
  432. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTM6nIg_.js +3 -0
  433. package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
  434. package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-DabEG8L4.js} +1 -1
  435. package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Coa8yVGM.js} +2 -2
  436. package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-BB0qhdix.js} +1 -1
  437. package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
  438. package/dist/ui/assets/PlanningModule-pRPjR7v5.js +1 -0
  439. package/dist/ui/assets/PlansPage-D86pZSSl.js +1 -0
  440. package/dist/ui/assets/TaskContextUpload-BVIkU9yT.js +1 -0
  441. package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
  442. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  443. package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
  444. package/dist/ui/assets/{WorkflowManagerModule-DWFspC-o.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
  445. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  446. package/dist/ui/assets/index-CTsDBaef.js +7 -0
  447. package/dist/ui/assets/{vendor-icons-BkFLXavV.js → vendor-icons-Bsq-mcEn.js} +1 -1
  448. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  449. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  450. package/dist/ui/branding/logos/signature_dark.png +0 -0
  451. package/dist/ui/branding/logos/signature_light.png +0 -0
  452. package/dist/ui/index.html +3 -3
  453. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  454. package/dist/utils/httpSetCookie.d.ts +1 -0
  455. package/dist/utils/httpSetCookie.js +4 -1
  456. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  457. package/dist/utils/localRuntimeUrl.js +14 -0
  458. package/dist/utils/productLogoRegistry.d.ts +2 -0
  459. package/dist/utils/productLogoRegistry.js +36 -0
  460. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  461. package/dist/utils/syncStatusPresentation.js +17 -0
  462. package/dist/utils/taskActivity.d.ts +3 -2
  463. package/dist/utils/taskActivity.js +19 -2
  464. package/dist/utils/taskEditorReconciliation.d.ts +40 -0
  465. package/dist/utils/taskEditorReconciliation.js +217 -0
  466. package/dist/utils/taskEvents.d.ts +2 -0
  467. package/dist/utils/taskNormalization.d.ts +1 -0
  468. package/dist/utils/taskNormalization.js +39 -0
  469. package/dist/utils/taskSearch.js +2 -2
  470. package/dist/utils/uiNotice.d.ts +4 -0
  471. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  472. package/dist/utils/workspaceSyncPresentation.js +23 -17
  473. package/package.json +36 -6
  474. package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +0 -1
  475. package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
  476. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
  477. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
  478. package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
  479. package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
  480. package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
  481. package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
  482. package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +0 -21
  483. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  484. package/dist/ui/assets/index-BUplSsv_.js +0 -7
  485. package/dist/ui/assets/index-gz2EXuoK.css +0 -1
@@ -147,6 +147,12 @@ function readConfiguredFeatureLimit(config, key) {
147
147
  const normalized = Math.max(1, Math.floor(numericValue));
148
148
  return normalized;
149
149
  }
150
+ /**
151
+ * Shown for count-limited features that are enabled with no configured ceiling.
152
+ * Applies to workspaces and AI profiles only — storage keeps an explicit
153
+ * allowance, and team management renders its seat limit instead.
154
+ */
155
+ const UNLIMITED_LIMIT_LABEL = 'Unlimited';
150
156
  function formatLimitedFeatureLabel(baseLabel, limitValue) {
151
157
  if (limitValue !== 1)
152
158
  return baseLabel;
@@ -185,6 +191,9 @@ function getFeatureDisplayParts(feature, seatLimit) {
185
191
  baseLabel: formatLimitedFeatureLabel(baseLabel, maxWorkspaces)
186
192
  };
187
193
  }
194
+ if (feature.access !== 'disabled') {
195
+ return { limitValue: UNLIMITED_LIMIT_LABEL, limitUnit: null, baseLabel };
196
+ }
188
197
  }
189
198
  if (feature.featureKey === 'collaboration.ai_profiles') {
190
199
  const maxAiProfiles = readConfiguredFeatureLimit(config, 'maxAiProfiles');
@@ -195,6 +204,9 @@ function getFeatureDisplayParts(feature, seatLimit) {
195
204
  baseLabel: formatLimitedFeatureLabel(baseLabel, maxAiProfiles)
196
205
  };
197
206
  }
207
+ if (feature.access !== 'disabled') {
208
+ return { limitValue: UNLIMITED_LIMIT_LABEL, limitUnit: null, baseLabel };
209
+ }
198
210
  }
199
211
  if (feature.featureKey === 'collaboration.team_management') {
200
212
  const normalizedSeatLimit = Number(seatLimit);
@@ -41,7 +41,7 @@ import { DEFAULT_TYPE_VALUE } from '../../shared/taxonomyDefaults.js';
41
41
  import { getImageReferenceLabel } from '../../utils/imageReferences';
42
42
  import { TASK_DEEP_LINK_QUERY_KEYS } from '../../shared/taskDeepLinks';
43
43
  import { isPlanningEntityVisibleForScope, scopePlanningSummaries, scopeTasksToPlanningSelection } from './planningScope';
44
- import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, resolveHeaderSyncStatusMeta, } from '../../utils/syncStatusPresentation';
44
+ import { buildReferenceMismatchSummaries, buildSyncDiagnosticsSummary, buildSyncEventRows, getActiveReferenceMismatchCount, resolveSyncStageLabel, resolveSyncStatusMeta, resolveHeaderSyncStatusMeta, resolveEffectiveWorkspaceSyncDiagnostics, } from '../../utils/syncStatusPresentation';
45
45
  import { buildCustomTaxonomySortOptions } from '../../utils/taxonomySorting.js';
46
46
  import { getLocale, t } from '../../localization';
47
47
  import { getAnnotatedAttachmentContextIdentity, resolveAnnotatedAttachmentDetail, shouldApplyPersistedAnnotatedAttachmentContext, } from '../../utils/annotatedAttachments';
@@ -74,7 +74,7 @@ import { useRecentSyncEvents } from '../../hooks/sync/useRecentSyncEvents';
74
74
  import { useSyncStatusActions } from '../../hooks/sync/useSyncStatusActions';
75
75
  import { useSyncStatusControls } from '../../hooks/sync/useSyncStatusControls';
76
76
  import { toDateOnlyLocal, parseDateOnlyLocal, startOfWeek, getDayOffsetFromWeekStart, addDays, dateOnlyToIsoWeekKey, SCHEDULE_DAY_KEYS, SCHEDULE_DAY_LABELS, } from './panels/scheduleUtils';
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';
77
+ import { ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY, DOCUMENT_WORKSPACE_FEATURE_KEY, TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY, resolveClientAppGateAccessMap, } from '../../runtime/appGates';
78
78
  // Heavy feature modules — lazy-loaded to reduce the initial app chunk size.
79
79
  const TaskSettings = React.lazy(() => import('../features/TaskSettings').then(m => ({ default: m.TaskSettings })));
80
80
  const AnnotatedAttachmentWorkspaceShell = React.lazy(() => import('../features/AnnotatedAttachmentWorkspace').then(m => ({ default: m.AnnotatedAttachmentWorkspaceShell })));
@@ -171,7 +171,7 @@ export function StandaloneLayout(props) {
171
171
  // Data & Actions
172
172
  tasks, handleEdit, handleSubmit, resetForm, discardDescriptionImageDraft, handleUpdateTask, handleSetStatus: handleSetStatusDurably,
173
173
  // Form State (destructure all needed for TaskForm)
174
- editingTaskId, loading, error, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, attachmentsDirty, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
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, showTaskCardDescription, showTaskCardAttachments, showTaskCardChecklistProgress, showTaskCardLatestActivity, tintTaskCardActivityBackground, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, attachmentsDirty, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
175
175
  // Form Actions
176
176
  handleAddComment, handleSetWorkstreamForCurrentTask, handleOpenTaskById,
177
177
  // Other Props for Form
@@ -186,7 +186,7 @@ export function StandaloneLayout(props) {
186
186
  // clearFilters, // This was duplicated, removed one instance
187
187
  // activeTypes, // This was duplicated, removed one instance
188
188
  // Settings State & Props
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,
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, resetWorkspaceSyncCursorAndPull, getWorkspaceSyncDiagnostics, currentWorkspaceId, currentWorkspaceRole, availableWorkspaces, switchWorkspace, updateCurrentUserProfile, resolveCloudAuthUrl = resolveSameOriginTaskforcePath, logout, fetchLoginMethods, unlinkLoginMethod, addPasswordToAccount, changePassword, beginOAuthLogin, beginOAuthLink, availableAuthProviders, projectRoot, projectName, mcpScriptPath, serverHostRoot,
190
190
  // Browser Props
191
191
  showFolderBrowser, setShowFolderBrowser, folders, files, currentBrowsePath, fetchFolders, browserTarget, setBrowserTarget, handleSelectPath, handleAddPath, handleRemovePath,
192
192
  // Settings Managers
@@ -401,32 +401,7 @@ export function StandaloneLayout(props) {
401
401
  setRequestedAnnotatedTarget(null);
402
402
  setRequestedAnnotatedSessionId(null);
403
403
  }, [layoutStateWorkspaceKey]);
404
- const workspaceFeatureAccess = useMemo(() => ({
405
- [DOCUMENT_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
406
- featureKey: DOCUMENT_WORKSPACE_FEATURE_KEY,
407
- runtimeMode,
408
- }),
409
- [ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
410
- featureKey: ANNOTATED_ATTACHMENTS_WORKSPACE_FEATURE_KEY,
411
- runtimeMode,
412
- }),
413
- [WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
414
- featureKey: WORKFLOW_MANAGER_WORKSPACE_FEATURE_KEY,
415
- runtimeMode,
416
- }),
417
- [TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
418
- featureKey: TASKFORCE_AGENTS_WORKSPACE_FEATURE_KEY,
419
- runtimeMode,
420
- }),
421
- [AI_PROFILES_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
422
- featureKey: AI_PROFILES_WORKSPACE_FEATURE_KEY,
423
- runtimeMode,
424
- }),
425
- [PLANNING_WORKSPACE_FEATURE_KEY]: resolveFeatureAccess({
426
- featureKey: PLANNING_WORKSPACE_FEATURE_KEY,
427
- runtimeMode,
428
- }),
429
- }), [runtimeMode]);
404
+ const workspaceFeatureAccess = useMemo(() => resolveClientAppGateAccessMap(props.config?.appGates, props.config?.cloudEnvironment), [props.config?.appGates, props.config?.cloudEnvironment]);
430
405
  const workspaceModules = useMemo(() => getWorkspaceModuleDefinitions({ featureAccess: workspaceFeatureAccess }), [workspaceFeatureAccess]);
431
406
  const resolvedWorkspaceModule = useMemo(() => resolveWorkspaceModule(activeWorkspaceModule, workspaceModules), [activeWorkspaceModule, workspaceModules]);
432
407
  const planningSurfaceVisible = planningDrawerOpen || resolvedWorkspaceModule === 'planning';
@@ -1152,7 +1127,8 @@ export function StandaloneLayout(props) {
1152
1127
  prerequisiteTaskIds: prerequisiteTaskIdsByTaskId.get(task.id) || [],
1153
1128
  dependencyState: getDependencyState(task.id),
1154
1129
  assignee: task.assignee || null,
1155
- attachmentCount: Array.isArray(task.attachments) ? task.attachments.length : 0,
1130
+ attachmentCount: task.attachmentCount
1131
+ ?? (Array.isArray(task.attachments) ? task.attachments.length : 0),
1156
1132
  isArchived: Boolean(task.isArchived),
1157
1133
  });
1158
1134
  workstreamTaskPreviewsById.set(workstreamId, current);
@@ -1829,9 +1805,15 @@ export function StandaloneLayout(props) {
1829
1805
  const effectiveWorkspaceCloudSyncEnabled = typeof serverCoordinatorSyncEnabled === 'boolean'
1830
1806
  ? serverCoordinatorSyncEnabled
1831
1807
  : workspaceCloudSyncEnabled;
1832
- const { showSyncStatusModal, showSyncEnableWarning, workspaceSyncError, syncControlBusy, openSyncStatusModal, closeSyncStatusModal, handleWorkspaceSyncToggle, cancelSyncEnableWarning, confirmSyncEnableWarning, } = useSyncStatusControls({
1808
+ const persistedSyncToggleIntent = localCoordinatorStatus?.activePriorityCommandType === 'DisableSync'
1809
+ ? 'disabling'
1810
+ : localCoordinatorStatus?.activeCommandType === 'EnableSync'
1811
+ ? 'enabling'
1812
+ : null;
1813
+ const { showSyncStatusModal, showSyncEnableWarning, workspaceSyncError, syncControlBusy, syncControlIntent, openSyncStatusModal, closeSyncStatusModal, handleWorkspaceSyncToggle, cancelSyncEnableWarning, confirmSyncEnableWarning, } = useSyncStatusControls({
1833
1814
  canManageWorkspaceSync,
1834
1815
  workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled,
1816
+ persistedToggleIntent: persistedSyncToggleIntent,
1835
1817
  saveWorkspaceCloudSyncSettings,
1836
1818
  });
1837
1819
  const currentWorkspaceLabel = useMemo(() => {
@@ -2766,8 +2748,19 @@ export function StandaloneLayout(props) {
2766
2748
  ]);
2767
2749
  const syncLastError = headerSyncPresentation.lastError;
2768
2750
  const [headerSyncStatus, setHeaderSyncStatus] = useState(headerSyncPresentation.status);
2751
+ const effectiveWorkspaceSyncDiagnostics = useMemo(() => resolveEffectiveWorkspaceSyncDiagnostics(workspaceSyncDiagnostics, localCoordinatorStatus?.phase === 'ready'
2752
+ && localCoordinatorStatus.snapshot?.state.ownershipMode === 'server'
2753
+ ? {
2754
+ recoveryObligations: coordinatorRecoveryObligations,
2755
+ outbox: localCoordinatorStatus.snapshot.workspace?.outbox || null,
2756
+ }
2757
+ : null), [
2758
+ coordinatorRecoveryObligations,
2759
+ localCoordinatorStatus,
2760
+ workspaceSyncDiagnostics,
2761
+ ]);
2769
2762
  const syncDiagnosticsSummary = useMemo(() => coordinatorSyncPresentation?.diagnostics
2770
- || buildSyncDiagnosticsSummary({ ...workspaceSyncDiagnostics, coordinatorRecoveryObligations }), [coordinatorSyncPresentation, workspaceSyncDiagnostics, coordinatorRecoveryObligations]);
2763
+ || buildSyncDiagnosticsSummary(effectiveWorkspaceSyncDiagnostics), [coordinatorSyncPresentation, effectiveWorkspaceSyncDiagnostics]);
2771
2764
  const { syncRecentEvents, syncRecentEventsLoading, syncRecentEventsError, syncEventsListRef, loadRecentSyncEvents, } = useRecentSyncEvents({
2772
2765
  isOpen: showSyncStatusModal,
2773
2766
  workspaceId: currentWorkspaceId,
@@ -2809,7 +2802,7 @@ export function StandaloneLayout(props) {
2809
2802
  formattedLastSyncTime: effectiveFormattedLastSyncTime,
2810
2803
  formattedLastPullTime: effectiveFormattedLastPullTime,
2811
2804
  formattedLastPushTime: effectiveFormattedLastPushTime,
2812
- workspaceSyncDiagnostics,
2805
+ workspaceSyncDiagnostics: effectiveWorkspaceSyncDiagnostics,
2813
2806
  workspaceSyncPendingChanges: effectivePendingLocalChanges,
2814
2807
  syncLastError,
2815
2808
  workspaceSyncPhase,
@@ -3784,18 +3777,6 @@ export function StandaloneLayout(props) {
3784
3777
  pushNotice,
3785
3778
  workspaceFeatureAccess,
3786
3779
  ]);
3787
- const handleOpenTaskforceAgentConversation = useCallback((agentId) => {
3788
- const normalizedAgentId = String(agentId || '').trim();
3789
- if (!normalizedAgentId)
3790
- return;
3791
- handleRememberTaskforceAgentSelection({
3792
- agentId: normalizedAgentId,
3793
- conversationId: taskforceAgentConversationByAgentId[normalizedAgentId] || null,
3794
- });
3795
- setTaskforceAgentsLaunchContext(null);
3796
- setTaskforceAgentPanelCollapsed(false);
3797
- setTaskforceAgentDrawerOpen(true);
3798
- }, [handleRememberTaskforceAgentSelection, taskforceAgentConversationByAgentId]);
3799
3780
  const handleOpenTaskforceAgentTaskContext = useCallback((taskId) => {
3800
3781
  handleOpenTaskById(taskId);
3801
3782
  setTaskModalFullscreen(false);
@@ -4287,7 +4268,7 @@ export function StandaloneLayout(props) {
4287
4268
  const taskforceAgentDrawerNode = taskforceAgentDrawerOpen ? (_jsx("div", { className: `${styles.taskforceAgentDrawerOverlay} ${taskforceAgentPanelCollapsed ? styles.taskforceAgentDrawerOverlayCollapsed : ''}`.trim(), style: { top: `${taskforceAgentDrawerTop}px` }, "data-theme": currentTheme, "aria-label": "Taskforce Agent chat", children: _jsx("aside", { className: taskforceAgentPanelCollapsed
4288
4269
  ? `${shellStyles.workspaceToolRail} ${shellStyles.workspaceToolRailRight}`
4289
4270
  : styles.taskforceAgentDrawerPanel, children: taskforceAgentPanelCollapsed ? (_jsxs("div", { className: shellStyles.workspaceToolRailMain, children: [_jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} tf-control-icon tf-control-icon-quiet tf-control-icon-active`, onClick: () => setTaskforceAgentPanelCollapsed(false), title: "Expand agent chat", "aria-label": "Expand agent chat", children: _jsx(Bot, { size: 16 }) }), _jsx("button", { type: "button", className: `${shellStyles.workspaceToolButton} tf-control-icon tf-control-icon-quiet`, onClick: handleCloseTaskforceAgentDrawer, title: "Close agent chat", "aria-label": "Close agent chat", children: _jsx(X, { size: 16 }) })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: styles.taskforceAgentDrawerHeader, children: [taskforceAgentDrawerHeaderContent || (_jsxs("div", { className: styles.taskforceAgentDrawerHeaderFallback, children: [_jsx("span", { className: styles.taskforceAgentDrawerFallbackAvatar, "aria-hidden": "true", children: _jsx(Bot, { size: 16 }) }), _jsx("strong", { children: "Loading agent..." })] })), _jsxs("div", { className: styles.taskforceAgentDrawerHeaderActions, children: [_jsx("button", { type: "button", className: "tf-control-icon", onClick: () => setTaskforceAgentPanelCollapsed(true), title: "Collapse agent chat", "aria-label": "Collapse agent chat", children: _jsx(ChevronRight, { size: 16 }) }), _jsx("button", { type: "button", className: "tf-control-icon", onClick: handleCloseTaskforceAgentDrawer, title: "Close agent chat", "aria-label": "Close agent chat", children: _jsx(X, { size: 16 }) })] })] }), _jsx(Suspense, { fallback: _jsx("div", { className: styles.taskforceAgentDrawerLoading, children: _jsx(Loader2, { size: 18, className: styles.spinner }) }), children: _jsx(TaskforceAgentsModule, { workspaceId: currentWorkspaceId, launchContext: taskforceAgentsLaunchContext, onClearLaunchContext: handleCloseTaskforceAgentDrawer, onOpenTaskContext: handleOpenTaskforceAgentTaskContext, taskReferences: taskReferences, surface: "taskDrawer", runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, rememberedAgentId: taskforceAgentId, rememberedConversationId: taskforceAgentConversationId, rememberedConversationByAgentId: taskforceAgentConversationByAgentId, rememberedSelectionReady: uiStateReady, onRememberSelection: handleRememberTaskforceAgentSelection, onRenderDrawerHeader: handleRenderTaskforceAgentDrawerHeader }) })] })) }) })) : null;
4290
- return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx("div", { ref: appShellHeaderRef, style: { flexShrink: 0 }, children: _jsx(AppShellHeader, { projectName: projectName, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, onBrandClick: handleOpenKanbanFromBrand, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: `${styles.taskCountBadge} ${styles.taskCountBadgeButton} ${taskHeaderQuickFilter === 'assigned-to-me' ? styles.taskCountBadgeActive : ''}`.trim(), onClick: () => handleTaskHeaderQuickFilter('assigned-to-me'), title: taskHeaderQuickFilter === 'assigned-to-me' ? 'Clear assigned-to-me quick filter' : 'Filter to my open tasks', "aria-label": `${taskHeaderQuickFilter === 'assigned-to-me' ? 'Clear' : 'Apply'} assigned to me quick filter (${assignedTaskCount} task${assignedTaskCount === 1 ? '' : 's'})`, "aria-pressed": taskHeaderQuickFilter === 'assigned-to-me', children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("button", { type: "button", className: `${styles.taskCountBadge} ${styles.taskCountBadgeButton} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''} ${taskHeaderQuickFilter === 'overdue' ? styles.taskCountBadgeActive : ''}`.trim(), onClick: () => handleTaskHeaderQuickFilter('overdue'), title: taskHeaderQuickFilter === 'overdue' ? 'Clear my-overdue-tasks quick filter' : 'Filter to my overdue tasks', "aria-label": `${taskHeaderQuickFilter === 'overdue' ? 'Clear' : 'Apply'} my overdue tasks quick filter (${assignedOverdueTaskCount} task${assignedOverdueTaskCount === 1 ? '' : 's'})`, "aria-pressed": taskHeaderQuickFilter === 'overdue', children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${headerSyncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
4271
+ return (_jsxs("div", { className: `${shellStyles.standaloneWrapper} ${zenMode ? styles.zenModeEnabled : ''}`, "data-theme": currentTheme, children: [_jsx("div", { ref: appShellHeaderRef, style: { flexShrink: 0 }, children: _jsx(AppShellHeader, { projectName: currentWorkspaceLabel, currentWorkspaceId: currentWorkspaceId, runtimeMode: runtimeMode, theme: currentTheme, onBrandClick: handleOpenKanbanFromBrand, meta: (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.taskCountBadge, title: activeCountTitle, children: activeCountLabel }), normalizedAuthUserId && normalizedAuthUserId !== 'anonymous' && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: `${styles.taskCountBadge} ${styles.taskCountBadgeButton} ${taskHeaderQuickFilter === 'assigned-to-me' ? styles.taskCountBadgeActive : ''}`.trim(), onClick: () => handleTaskHeaderQuickFilter('assigned-to-me'), title: taskHeaderQuickFilter === 'assigned-to-me' ? 'Clear assigned-to-me quick filter' : 'Filter to my open tasks', "aria-label": `${taskHeaderQuickFilter === 'assigned-to-me' ? 'Clear' : 'Apply'} assigned to me quick filter (${assignedTaskCount} task${assignedTaskCount === 1 ? '' : 's'})`, "aria-pressed": taskHeaderQuickFilter === 'assigned-to-me', children: [_jsx(User, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedTaskCount] }), _jsxs("button", { type: "button", className: `${styles.taskCountBadge} ${styles.taskCountBadgeButton} ${assignedOverdueTaskCount > 0 ? styles.taskCountBadgeAlert : ''} ${taskHeaderQuickFilter === 'overdue' ? styles.taskCountBadgeActive : ''}`.trim(), onClick: () => handleTaskHeaderQuickFilter('overdue'), title: taskHeaderQuickFilter === 'overdue' ? 'Clear my-overdue-tasks quick filter' : 'Filter to my overdue tasks', "aria-label": `${taskHeaderQuickFilter === 'overdue' ? 'Clear' : 'Apply'} my overdue tasks quick filter (${assignedOverdueTaskCount} task${assignedOverdueTaskCount === 1 ? '' : 's'})`, "aria-pressed": taskHeaderQuickFilter === 'overdue', children: [_jsx(ClockAlert, { size: 13, className: styles.taskCountBadgeIcon, "aria-hidden": "true" }), assignedOverdueTaskCount] })] })), shouldShowSyncStatus && (_jsx("button", { className: "tf-control-icon", onClick: openSyncStatusModal, title: `Sync manager: ${headerSyncStatusMeta.label} | Last success: ${formattedLastSyncTime}`, style: {
4291
4272
  marginLeft: '6px',
4292
4273
  height: '24px',
4293
4274
  width: '24px',
@@ -4317,7 +4298,7 @@ export function StandaloneLayout(props) {
4317
4298
  }, children: _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlansPage, { ...props, currentTheme: currentTheme, projectName: projectName, currentWorkspaceId: currentWorkspaceId, authUserId: authUserId, apiBaseUrl: apiBaseUrl, connectedEnvironmentSource: props.config?.cloudAuthBaseUrl || props.config?.apiBaseUrl || '', resolveCloudAuthUrl: resolveCloudAuthUrl, embedded: true, shellOwnsScroll: true, onAccountProfileSummaryChange: applyPlansAccountProfileSummary, onContinueToTaskforce: handlePlansBack, continueBusy: plansNavigationBusy }) }) })) : resolvedWorkspaceModule === 'planning' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(PlanningModule, { model: planningWorkspaceModel }) })] })) : resolvedWorkspaceModule === 'docs' && documentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(DocumentWorkspaceShell, { taskReferences: taskReferences, tasks: tasks, runtimeMode: runtimeMode, workspaceId: currentWorkspaceId, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', typeFilters: documentTypeFilters, attachmentFilters: documentAttachmentFilters, onTypeFiltersChange: setDocumentTypeFilters, onAttachmentFiltersChange: setDocumentAttachmentFilters, sortField: documentSortField, sortOrder: documentSortOrder, onSortFieldChange: setDocumentSortField, onSortOrderChange: setDocumentSortOrder, pinnedDocIds: documentPinnedDocIds, onPinnedDocIdsChange: setDocumentPinnedDocIds, searchQuery: documentSearchQuery, onSearchQueryChange: setDocumentSearchQuery, selectedDocId: documentSelectedDocId, onSelectedDocIdChange: setDocumentSelectedDocId, selectionReady: layoutUiStateReady, documentScrollByDocId: documentScrollByDocId, onDocumentScrollChange: handleDocumentScrollChange, documentListScrollTop: documentListScrollTop, onDocumentListScrollChange: handleDocumentListScrollChange, documentTrayOpen: documentTrayOpen, onCloseDocumentTray: () => setDocumentTrayOpen(false), requestedDocPath: requestedDocPath, requestedDocAssetId: requestedDocAssetId, onRequestedDocHandled: () => {
4318
4299
  setRequestedDocPath(null);
4319
4300
  setRequestedDocAssetId(null);
4320
- }, onBackToTask: handleBackToTaskFromDocument, enableTaskGeneration: true }) })] })) : resolvedWorkspaceModule === 'annotate' && annotatedAttachmentsWorkspaceEnabled ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AnnotatedAttachmentWorkspaceShell, { runtimeMode: runtimeMode, apiBaseUrl: props.config?.apiBaseUrl || '', cloudAuthBaseUrl: props.config?.cloudAuthBaseUrl || '', workspaceId: currentWorkspaceId, sessionLoadReady: annotatedWorkspaceReady, requestedTarget: scopedRequestedAnnotatedTarget, requestedSessionId: scopedRequestedAnnotatedSessionId, requestedOpenVersion: requestedAnnotatedOpenVersion, imageTrayOpen: imageTrayOpen, onCloseImageTray: () => setImageTrayOpen(false), resolveTaskReferenceLabel: resolveAnnotatedTaskReferenceLabel, resolveImageReferenceLabel: resolveAnnotatedImageReferenceLabel, onOpenTarget: handleAnnotatedAttachmentOpenTarget, onContextChange: handleAnnotatedAttachmentContextChange, viewportByContextKey: annotatedViewportByContextKey, onViewportChange: handleAnnotatedViewportChange, onBackToTask: handleBackToTaskFromAnnotatedAttachment }) })] })) : resolvedWorkspaceModule === 'workflowManager' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(WorkflowManagerModule, { workspaceId: currentWorkspaceId, libraryTrayOpen: workflowLibraryTrayOpen, onCloseLibraryTray: () => setWorkflowLibraryTrayOpen(false), assigneeOptions: assigneeOptions, theme: currentTheme, onUnsavedChangesChange: setWorkflowManagerHasUnsavedChanges }) })] })) : resolvedWorkspaceModule === 'taskforceAgents' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(TaskforceAgentsModule, { workspaceId: currentWorkspaceId, taskReferences: taskReferences, agentRosterTrayOpen: taskforceAgentRosterTrayOpen, onCloseAgentRosterTray: () => setTaskforceAgentRosterTrayOpen(false), runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, rememberedAgentId: taskforceAgentId, rememberedConversationId: taskforceAgentConversationId, rememberedConversationByAgentId: taskforceAgentConversationByAgentId, rememberedSelectionReady: uiStateReady, onRememberSelection: handleRememberTaskforceAgentSelection, onOpenConversation: handleOpenTaskforceAgentConversation }) })] })) : resolvedWorkspaceModule === 'aiProfiles' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AiProfilesModule, { workspaceId: currentWorkspaceId, runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, onNotice: pushNotice, mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
4301
+ }, 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 }) })] })) : resolvedWorkspaceModule === 'aiProfiles' ? (_jsxs("div", { className: `${shellStyles.standalonePage} ${shellStyles.standaloneContent}`, style: { position: 'relative', display: 'flex', flex: 1, minHeight: 0, overflow: 'hidden', paddingLeft: `${WORKSPACE_TOOL_RAIL_WIDTH}px` }, children: [workspaceToolRail, _jsx(Suspense, { fallback: _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 1 }, children: _jsx(Loader2, { size: 20, className: styles.spinner }) }), children: _jsx(AiProfilesModule, { workspaceId: currentWorkspaceId, runtimeMode: runtimeMode, cloudAuthConfigured: cloudAuthConfigured, authSessionResolved: authSessionResolved, isAuthenticated: isAuthenticated, cloudAiProfileSeatUsage: accountProfileSummary?.aiProfileSeatUsage ?? null, agentTrayOpen: agentTrayOpen, onCloseAgentTray: () => setAgentTrayOpen(false), resolveCloudAuthUrl: resolveCloudAuthUrl, theme: currentTheme, onNotice: pushNotice, mcpSettingsNode: _jsx(TaskSettings, { settingsModel: {
4321
4302
  ...settingsModel,
4322
4303
  initialSection: 'mcp',
4323
4304
  onOpenCloudAuth: openSharedLoginRoute
@@ -4358,7 +4339,7 @@ export function StandaloneLayout(props) {
4358
4339
  if (count > 0 && window.confirm(`Permanently delete all ${count} tasks in Trash? Filters and selection do not limit this action. This cannot be undone.`)) {
4359
4340
  void handleEmptyDeletedTasks();
4360
4341
  }
4361
- } })), _jsx(TaskKanban, { tasks: scopedBoardVisibleTasks, allTasks: scopedKanbanAllTasks, columns: kanbanColumns, groupBy: groupBy, scheduleDates: scheduleDates, searchQuery: searchQuery, filterCategories: filterCategories, filterTypes: filterTypes, filterPriorities: filterPriorities, filterStatus: filterStatus, filterAssignees: filterAssignees, filtersReady: hasInitedFilters, assigneeOptions: assigneeOptions, scheduleFilteredTaskIds: scheduleFilteredTaskIdList, copiedId: copiedId, taxonomies: taxonomies, types: activeTypes, priorities: priorities, workspaceId: currentWorkspaceId, deletedTaskRecordByTaskId: deletedTaskRecordByTaskId, selectedDeletedRecordIds: trashSelection.selectedIds, onDeletedSelectionChange: trashSelection.toggle, onUpdateTask: handleUpdateTask, onTaskClick: handleEdit, taskReferences: taskTextReferences, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onAddTaskToColumn: handleAddTaskToColumn, showTaskCardStatusLabel: showTaskCardStatusLabel, onScheduleDaySelected: handleBoardScheduleDaySelected, persistedScrollLeft: groupBy === 'schedule' ? scheduleScrollLeft : undefined, onScrollLeftChange: handleBoardScrollLeftChange, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalElement
4342
+ } })), _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, showTaskCardDescription: runtimeMode !== 'cloud' && showTaskCardDescription, showTaskCardAttachments: showTaskCardAttachments, showTaskCardChecklistProgress: showTaskCardChecklistProgress, showTaskCardLatestActivity: showTaskCardLatestActivity, tintTaskCardActivityBackground: tintTaskCardActivityBackground, onScheduleDaySelected: handleBoardScheduleDaySelected, persistedScrollLeft: groupBy === 'schedule' ? scheduleScrollLeft : undefined, onScrollLeftChange: handleBoardScrollLeftChange, emptyColumnMode: emptyColumnMode, categories: activeCategories, compressed: compressedCards, readOnlyMode: taskScope === 'deleted' ? 'deleted' : taskScope === 'archived' ? 'archived' : null, recentlyChangedTaskIds: props.recentlyChangedTaskIds, sortBy: sortBy, sortOrder: props.sortOrder, planningDropTargets: planningDrawerPortalElement
4362
4343
  ? createPortal(planningDrawerNode, planningDrawerPortalElement)
4363
4344
  : null, onAssignTaskToWorkstream: handleAssignTaskToWorkstream, onAssignWorkstreamToInitiative: handleAssignInitiativeToWorkstream, workstreams: props.workstreams, initiatives: props.initiatives, onUnarchive: handleBoardUnarchive, onDelete: handleBoardDelete }, `${groupBy}-${kanbanColumns.map(c => String(c.value)).join('|')}-${scheduleDates.mon}`), groupBy === 'schedule' && !scheduleSidebarOpen && (_jsx("button", { type: "button", className: "tf-control-icon", onClick: () => {
4364
4345
  setPlanningDrawerDetail(null);
@@ -4500,13 +4481,9 @@ export function StandaloneLayout(props) {
4500
4481
  headers: teamAdminHeaders(),
4501
4482
  credentials: 'include'
4502
4483
  }));
4503
- }, onInviteEmailChange: setTeamInviteEmail, onInviteRoleChange: setTeamInviteRole, onInvitePermissionModeChange: setTeamInvitePermissionMode, onSubmitInvite: () => { void submitTeamInvite(); }, onLoadAuditPrevious: () => { void loadTeamAuditPage(teamAuditPage - 1); }, onLoadAuditNext: () => { void loadTeamAuditPage(teamAuditPage + 1); } }), _jsx(CreateWorkspaceConfirmModal, { isOpen: showCreateWorkspaceConfirm, theme: currentTheme, onClose: () => setShowCreateWorkspaceConfirm(false), onConfirm: () => openWorkspaceSetup({ intent: 'create-workspace' }) }), _jsx(SyncStatusModal, { isOpen: showSyncStatusModal, theme: currentTheme, currentWorkspaceLabel: currentWorkspaceLabel, syncStatus: headerSyncStatus, syncStatusMeta: syncStatusMeta, workspaceCloudSyncEnabled: effectiveWorkspaceCloudSyncEnabled, syncControlBusy: syncControlBusy, canManageWorkspaceSync: canManageWorkspaceSync, workspaceSyncSummary: headerSyncPresentation.summary, workspaceSyncRecommendedAction: headerSyncPresentation.recommendedAction, workspaceSyncRepairBusy: effectiveWorkspaceSyncRepairBusy, referenceMismatchCount: referenceMismatchCount, syncStageLabel: syncStageLabel, workspaceSyncPendingChanges: effectivePendingLocalChanges, incomingCloudChanges: coordinatorSyncPresentation?.incomingCloudChanges || 'Unknown', formattedLastSyncTime: effectiveFormattedLastSyncTime, formattedLastPullTime: effectiveFormattedLastPullTime, formattedLastPushTime: effectiveFormattedLastPushTime, syncLastError: syncLastError, activeReferenceMismatchSummaries: activeReferenceMismatchSummaries, syncDiagnosticsSummary: syncDiagnosticsSummary, syncEventRows: syncEventRows, syncEventsListRef: syncEventsListRef, workspaceSyncRepairQueued: workspaceSyncRepairQueued, workspaceSyncBusy: effectiveWorkspaceSyncBusy, workspaceSyncCopied: workspaceSyncCopied, coordinatorOwnershipMode: coordinatorOwnershipMode, coordinatorOwnershipTransferBusy: coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled: coordinatorOwnershipTransferDisabled, onClose: closeSyncStatusModal, onToggleWorkspaceSync: (enabled) => {
4484
+ }, 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, syncControlIntent: syncControlIntent, 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) => {
4504
4485
  void handleWorkspaceSyncToggle(enabled);
4505
- }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onRetrySync: () => {
4506
- void retryWorkspaceCloudSync().catch(() => {
4507
- // Coordinator status owns the durable error and retry presentation.
4508
- });
4509
- }, onTransferCoordinatorOwnership: () => {
4486
+ }, onRepairSync: handleQueueOrRunRepairSync, onCopyReport: () => { void handleCopySyncDetails(); }, onTransferCoordinatorOwnership: () => {
4510
4487
  void handleCoordinatorOwnershipTransfer();
4511
4488
  } }), _jsx(DiscardChangesDialog, { isOpen: Boolean(pendingWorkflowDiscardAction), onKeepEditing: () => setPendingWorkflowDiscardAction(null), onDiscard: () => {
4512
4489
  const action = pendingWorkflowDiscardAction;
@@ -42,7 +42,7 @@ export function WidgetView(props) {
42
42
  // Actions
43
43
  handleEdit, handleDelete, handleCopyId, handleUpdateTask, handleToggleComplete, handleToggleCancel, handleToggleInProgress, handleToggleReview, handleSetStatus, handleArchiveTask, handleBulkArchive, handleUnarchive, handleRestoreDeletedTask, handleRestoreSelectedDeletedTasks, handlePermanentlyDeleteDeletedTask, handleEmptyDeletedTasks, fetchArchive,
44
44
  // Form State
45
- editingTaskId, loading, error, clearTaskError, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
45
+ editingTaskId, loading, error, clearTaskError, title, setTitle, setTitleDraft, description, setDescription, setDescriptionDraft, checklistItems, setChecklistItems, category, setCategory, type, setType, priority, setPriority, complexity, setComplexity, status, setStatus, manualComplexityEnabled, checklistDropdownEnabled, showTaskCardStatusLabel, showTaskCardDescription, showTaskCardAttachments, showTaskCardChecklistProgress, showTaskCardLatestActivity, tintTaskCardActivityBackground, assignee, setAssignee, scheduledDate, setScheduledDate, dueDate, setDueDate, workstreamInput, setWorkstreamInput, formTaxonomies, setFormTaxonomies, comments, newCommentText, setNewCommentText, attachments, setAttachments, setAttachmentsDirty, descriptionImageUploadPending, descriptionImageDraftId, registerDescriptionImageUpload, descriptionFocused, setDescriptionFocused, showMarkdownHelp, setShowMarkdownHelp,
46
46
  // Form Actions
47
47
  handleSubmit, resetForm, discardDescriptionImageDraft, handleAddComment, handleSetWorkstreamForCurrentTask, handleOpenTaskById,
48
48
  // Modals
@@ -54,7 +54,7 @@ export function WidgetView(props) {
54
54
  // Refs
55
55
  commentsEndRef,
56
56
  // Props from Core
57
- currentWorkspaceId, authUserId, settingsModel, onHeaderMouseDown, isDragging } = props;
57
+ currentWorkspaceId, authUserId, runtimeMode, settingsModel, onHeaderMouseDown, isDragging } = props;
58
58
  const taskReferences = useTaskReferenceContract(tasks, handleOpenTaskById);
59
59
  const handleCanonicalEntityReference = useCallback((reference) => {
60
60
  if (reference.kind === 'initiative' || reference.kind === 'workstream') {
@@ -346,7 +346,7 @@ export function WidgetView(props) {
346
346
  if (confirm(`Permanently delete all ${deletedTasks.length} tasks in Trash? Filters and selection do not limit this action. This cannot be undone.`)) {
347
347
  void handleEmptyDeletedTasks();
348
348
  }
349
- } })), copiedId: copiedId, recentlyChangedTaskIds: recentlyChangedTaskIds, showTaskCardStatusLabel: showTaskCardStatusLabel, workstreams: props.workstreams, initiatives: props.initiatives, onSearchChange: setSearchQuery, onFilterCategoriesChange: (vals) => setFilterCategories(vals), onFilterTypesChange: (vals) => setFilterTypes(vals), onFilterPrioritiesChange: setFilterPriorities, onFilterStatusChange: setFilterStatus, onFilterAssigneesChange: (vals) => setFilterAssignees(vals), onTaxonomyFilterChange: (id, values) => setFilterTaxonomies(prev => ({ ...prev, [id]: values })), onSortByChange: handleSortByChange, onSortOrderChange: toggleSortOrder, onShowArchiveChange: setShowArchive, onTaskScopeChange: setTaskScope, onClearFilters: clearFilters, onToggleCategory: (category) => setCollapsedCategories(prev => ({ ...prev, [category]: !prev[category] })), onEditTask: handleEdit, onUpdateTask: handleUpdateTask, taskReferences: taskTextReferences, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onBulkArchive: handleBulkArchive, onUnarchive: (taskId) => {
349
+ } })), copiedId: copiedId, recentlyChangedTaskIds: recentlyChangedTaskIds, showTaskCardStatusLabel: showTaskCardStatusLabel, showTaskCardDescription: runtimeMode !== 'cloud' && showTaskCardDescription, showTaskCardAttachments: showTaskCardAttachments, showTaskCardChecklistProgress: showTaskCardChecklistProgress, showTaskCardLatestActivity: showTaskCardLatestActivity, tintTaskCardActivityBackground: tintTaskCardActivityBackground, workstreams: props.workstreams, initiatives: props.initiatives, onSearchChange: setSearchQuery, onFilterCategoriesChange: (vals) => setFilterCategories(vals), onFilterTypesChange: (vals) => setFilterTypes(vals), onFilterPrioritiesChange: setFilterPriorities, onFilterStatusChange: setFilterStatus, onFilterAssigneesChange: (vals) => setFilterAssignees(vals), onTaxonomyFilterChange: (id, values) => setFilterTaxonomies(prev => ({ ...prev, [id]: values })), onSortByChange: handleSortByChange, onSortOrderChange: toggleSortOrder, onShowArchiveChange: setShowArchive, onTaskScopeChange: setTaskScope, onClearFilters: clearFilters, onToggleCategory: (category) => setCollapsedCategories(prev => ({ ...prev, [category]: !prev[category] })), onEditTask: handleEdit, onUpdateTask: handleUpdateTask, taskReferences: taskTextReferences, onCopyId: handleCopyId, onToggleInProgress: handleToggleInProgress, onToggleReview: handleToggleReview, onToggleComplete: handleToggleComplete, onToggleCancel: handleToggleCancel, onSetStatus: handleSetStatus, onArchiveTask: handleArchiveTask, onBulkArchive: handleBulkArchive, onUnarchive: (taskId) => {
350
350
  const deletedRecord = deletedRecordByTaskId.get(taskId);
351
351
  if (deletedRecord) {
352
352
  void handleRestoreDeletedTask(deletedRecord.id, deletedRecord.taskId);
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import React from 'react';
3
3
  import { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';
4
4
  import { CSS } from '@dnd-kit/utilities';
5
- import { ArrowUpDown, Archive, ChevronDown, ChevronLeft, ChevronRight, Eye, EyeOff, Filter, GripVertical, Kanban, Link2, Pencil, Plus, RotateCcw, Search, Star, Unlink, X, } from 'lucide-react';
5
+ import { ArrowUpDown, Archive, ChevronDown, ChevronLeft, ChevronRight, Eye, EyeOff, Filter, GripVertical, Kanban, Pencil, Plus, RotateCcw, Search, Star, Unlink, X, } from 'lucide-react';
6
6
  import styles from '../../../Taskforce.module.css';
7
7
  import panelStyles from './PlanningDrawer.module.css';
8
8
  import { HierarchyActionBadge } from '../../ui/HierarchyActionBadge';
@@ -500,7 +500,7 @@ function PlanningDrawerList({ initiatives, standaloneWorkstreams, planningLoadSt
500
500
  : expandedInitiativeIds.has(initiative.id);
501
501
  return (_jsxs("li", { children: [_jsx(PlanningRow, { rowId: initiative.id, rowType: "initiative", referenceLabel: formatInitiativeReference(initiative), item: initiative, ownerOption: initiative.ownerId ? assigneeOptionByValue.get(initiative.ownerId) : undefined, ownerOptions: assigneeOptions, onChangeOwner: (ownerId) => onChangePlanningOwner('initiative', initiative.id, ownerId === 'unassigned' ? '' : ownerId), onChangeIdentity: (patch) => onChangePlanningIdentity('initiative', initiative.id, patch), workstreamCount: treeWorkstreams.length, active: activeInitiativeId === initiative.id && !activeWorkstreamId, isArchived: Boolean(initiative.isArchived), detailOpen: detail?.type === 'initiative' && detail.item.id === initiative.id, canExpand: allWorkstreams.length > 0, expanded: expanded, controlsId: `planning-children-${initiative.id}`, onToggleExpand: () => onToggleInitiative(initiative.id), onToggleScope: () => onSelectInitiative(initiative.id), onOpenDetails: () => onOpenInitiativeDetails(initiative.id), favorite: planningFavoriteKeys.has(getPlanningFavoriteKey({ type: 'initiative', id: initiative.id })), favoriteReady: navigatorSortReady, onToggleFavorite: () => onTogglePlanningFavorite({ type: 'initiative', id: initiative.id }), onArchiveReady: onArchiveResolvedInitiative
502
502
  ? () => onArchiveResolvedInitiative(initiative.id)
503
- : undefined }), expanded && displayedWorkstreams.length > 0 && (_jsx("ul", { id: `planning-children-${initiative.id}`, className: panelStyles.treeChildren, "aria-label": `Workstreams in ${initiative.title}`, children: displayedWorkstreams.map((workstream) => (_jsxs("li", { children: [_jsx(PlanningRow, { rowId: workstream.id, rowType: "workstream", referenceLabel: formatWorkstreamReference(workstream), item: workstream, ownerOption: workstream.ownerId ? assigneeOptionByValue.get(workstream.ownerId) : undefined, ownerOptions: assigneeOptions, onChangeOwner: (ownerId) => onChangePlanningOwner('workstream', workstream.id, ownerId === 'unassigned' ? '' : ownerId), onChangeIdentity: (patch) => onChangePlanningIdentity('workstream', workstream.id, patch), active: activeWorkstreamId === workstream.id, isArchived: Boolean(workstream.isArchived), detailOpen: (detail?.type === 'workstream' && detail.item.id === workstream.id)
503
+ : undefined }), expanded && displayedWorkstreams.length > 0 && (_jsx("ul", { id: `planning-children-${initiative.id}`, className: `${panelStyles.treeChildren} ${panelStyles.treeWorkstreamChildren}`.trim(), "aria-label": `Workstreams in ${initiative.title}`, children: displayedWorkstreams.map((workstream) => (_jsxs("li", { children: [_jsx(PlanningRow, { rowId: workstream.id, rowType: "workstream", referenceLabel: formatWorkstreamReference(workstream), item: workstream, ownerOption: workstream.ownerId ? assigneeOptionByValue.get(workstream.ownerId) : undefined, ownerOptions: assigneeOptions, onChangeOwner: (ownerId) => onChangePlanningOwner('workstream', workstream.id, ownerId === 'unassigned' ? '' : ownerId), onChangeIdentity: (patch) => onChangePlanningIdentity('workstream', workstream.id, patch), active: activeWorkstreamId === workstream.id, isArchived: Boolean(workstream.isArchived), detailOpen: (detail?.type === 'workstream' && detail.item.id === workstream.id)
504
504
  || (secondaryPane?.kind === 'detail' && secondaryPane.detail.item.id === workstream.id), canExpand: (workstream.tasks || []).length > 0, expanded: expandedWorkstreamIds.has(workstream.id), controlsId: `planning-tasks-${workstream.id}`, onToggleExpand: () => toggleWorkstreamTasks(workstream.id), onToggleScope: () => onSelectWorkstream(workstream.id, initiative.id), onOpenDetails: () => {
505
505
  onOpenInitiativeDetails(initiative.id);
506
506
  onOpenNestedWorkstreamDetails(workstream.id);
@@ -521,7 +521,6 @@ function PlanningFailureState({ title, message, retrying, onRetry, compact = fal
521
521
  function PlanningDrawerDetailView({ detail, showArchivedChildren, inlineEditor, selectedChildWorkstreamId, currentWorkspaceId, currentActorId, theme, onOpenNestedWorkstreamDetails, onArchivePlanningTask, onArchiveResolvedWorkstream, onArchiveResolvedEntity, onEdit, onChangeOwner, onChangePlanningOwner, onChangePlanningIdentity, onArchive, onUnarchive, onCreateTaskInWorkstream, onCreateWorkstreamInInitiative, onOpenTaskById, onChangeTaskAssignee, taskReferences, onAssignTaskToWorkstream, onAssignInitiativeToWorkstream, onAttachTaskToWorkstreamByReference, onAttachWorkstreamToInitiativeByReference, onAddPlanningContextFile, onRemovePlanningContextFile, onUpdatePlanningContextCaption, parentInitiative = null, assigneeOptions, linkOptions, showTaskCardStatusLabel = false, taskArrangeMode = 'execution', onTaskArrangeModeChange = () => { }, onReorderWorkstreamTasks, onSetTaskStatus, hydrationState, onRetryHydration, }) {
522
522
  const inlineEditorFormId = React.useId();
523
523
  const [isAttachingReference, setIsAttachingReference] = React.useState(false);
524
- const [showParentLinkPicker, setShowParentLinkPicker] = React.useState(false);
525
524
  const [pendingUnlink, setPendingUnlink] = React.useState(null);
526
525
  const [relationshipRecovery, setRelationshipRecovery] = React.useState(null);
527
526
  const [isChangingRelationship, setIsChangingRelationship] = React.useState(false);
@@ -590,7 +589,6 @@ function PlanningDrawerDetailView({ detail, showArchivedChildren, inlineEditor,
590
589
  : `Archive ${detailLabel.toLowerCase()}`;
591
590
  React.useEffect(() => {
592
591
  setIsAttachingReference(false);
593
- setShowParentLinkPicker(false);
594
592
  setPendingUnlink(null);
595
593
  setRelationshipRecovery(null);
596
594
  setIsChangingRelationship(false);
@@ -658,9 +656,7 @@ function PlanningDrawerDetailView({ detail, showArchivedChildren, inlineEditor,
658
656
  return;
659
657
  setIsChangingRelationship(true);
660
658
  try {
661
- const result = await onAssignInitiativeToWorkstream(detail.item.id, option.referenceLabel);
662
- if (result !== false)
663
- setShowParentLinkPicker(false);
659
+ await onAssignInitiativeToWorkstream(detail.item.id, option.referenceLabel);
664
660
  }
665
661
  finally {
666
662
  setIsChangingRelationship(false);
@@ -762,7 +758,7 @@ function PlanningDrawerDetailView({ detail, showArchivedChildren, inlineEditor,
762
758
  });
763
759
  }, title: "Unlink workstream from initiative", ariaLabel: "Unlink workstream from initiative", children: _jsx(Unlink, { size: 14, "aria-hidden": "true" }) })) : null] })) : null })) : null, detail.type === 'workstream'
764
760
  && !parentInitiativeReferenceLabel
765
- && !inlineEditor ? (_jsx(HierarchyActionBadge, { disabled: !onAssignInitiativeToWorkstream, onClick: () => setShowParentLinkPicker(true), title: "Link initiative", ariaLabel: "Link initiative", ariaExpanded: showParentLinkPicker, children: _jsx(Link2, { size: 14, "aria-hidden": "true" }) })) : null, _jsx(PlanningReferenceBadge, { label: detailReferenceLabel || 'Reference pending', entityType: detail.type, entityName: detail.item.title, pending: !detailReferenceLabel })] }), _jsx("div", { className: panelStyles.detailTopActions, children: inlineEditor ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: inlineEditor.onCancel, disabled: inlineEditor.isSubmitting, children: "Cancel" }), _jsx("button", { type: "submit", form: inlineEditorFormId, className: "tf-button-primary tf-button-compact", disabled: inlineEditor.isSubmitting, children: inlineEditor.isSubmitting ? 'Saving…' : 'Save' })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tf-control-icon", disabled: archiveDetailState.mode === 'blocked' || archiveDetailState.mode === 'checking', onClick: () => {
761
+ && !inlineEditor ? (_jsx(PlanningLinkPicker, { options: linkOptions.initiatives, entityLabel: "initiative", onSelect: handleLinkInitiative, disabled: !onAssignInitiativeToWorkstream || isChangingRelationship, iconTrigger: true, triggerTitle: "Link initiative" })) : null, _jsx(PlanningReferenceBadge, { label: detailReferenceLabel || 'Reference pending', entityType: detail.type, entityName: detail.item.title, pending: !detailReferenceLabel })] }), _jsx("div", { className: panelStyles.detailTopActions, children: inlineEditor ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: inlineEditor.onCancel, disabled: inlineEditor.isSubmitting, children: "Cancel" }), _jsx("button", { type: "submit", form: inlineEditorFormId, className: "tf-button-primary tf-button-compact", disabled: inlineEditor.isSubmitting, children: inlineEditor.isSubmitting ? 'Saving…' : 'Save' })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tf-control-icon", disabled: archiveDetailState.mode === 'blocked' || archiveDetailState.mode === 'checking', onClick: () => {
766
762
  if (archiveDetailState.mode === 'archived') {
767
763
  onUnarchive?.();
768
764
  }
@@ -776,10 +772,7 @@ function PlanningDrawerDetailView({ detail, showArchivedChildren, inlineEditor,
776
772
  ? archiveEntityConfirmationVisible
777
773
  : undefined, children: archiveDetailState.mode === 'archived'
778
774
  ? _jsx(RotateCcw, { size: 14, "aria-hidden": "true" })
779
- : _jsx(Archive, { size: 14, "aria-hidden": "true" }) }), _jsx("button", { type: "button", className: "tf-control-icon", onClick: () => {
780
- setShowParentLinkPicker(false);
781
- onEdit();
782
- }, title: `Edit ${detailLabel.toLowerCase()} details`, "aria-label": `Edit ${detailLabel.toLowerCase()} details`, children: _jsx(Pencil, { size: 14, "aria-hidden": "true" }) })] })) })] }), archiveEntityConfirmationVisible && archiveDetailState.mode === 'ready' ? (_jsx(PlanningArchiveConfirmation, { entityType: detail.type, title: detail.item.title, activeTaskCount: detail.item.archiveActiveTaskCount, activeWorkstreamCount: detail.item.archiveActiveWorkstreamCount, busy: archiveEntityBusy, onCancel: () => setArchiveEntityConfirmationVisible(false), onConfirm: () => void handleConfirmArchiveEntity() })) : null, detail.type === 'workstream' ? renderRelationshipFeedback('workstream', detail.item.id) : null, detail.type === 'workstream' && !parentInitiativeReferenceLabel && showParentLinkPicker ? (_jsxs("div", { className: panelStyles.relationshipPickerRow, role: "group", "aria-label": "Link workstream to initiative", children: [_jsx(PlanningLinkPicker, { options: linkOptions.initiatives, entityLabel: "initiative", onSelect: handleLinkInitiative, disabled: !onAssignInitiativeToWorkstream || isChangingRelationship }), _jsx("button", { type: "button", className: "tf-control-icon tf-control-icon-compact", disabled: isChangingRelationship, onClick: () => setShowParentLinkPicker(false), title: "Cancel initiative link", "aria-label": "Cancel initiative link", children: _jsx(X, { size: 14, "aria-hidden": "true" }) })] })) : null, inlineEditor ? (_jsx(PlanningDrawerEditor, { editor: inlineEditor.editor, draftTitle: inlineEditor.draftTitle, draftDescription: inlineEditor.draftDescription, draftOwner: inlineEditor.draftOwner, draftInitiativeId: inlineEditor.draftInitiativeId, assigneeOptions: assigneeOptions, initiativeLinkOptions: linkOptions.initiatives, draftInitiativeSummary: inlineEditor.draftInitiativeSummary, onChangeDraftTitle: inlineEditor.onChangeDraftTitle, onChangeDraftDescription: inlineEditor.onChangeDraftDescription, onChangeDraftOwner: inlineEditor.onChangeDraftOwner, onChangeDraftInitiativeId: inlineEditor.onChangeDraftInitiativeId, onCancel: inlineEditor.onCancel, onSubmit: inlineEditor.onSubmit, isSubmitting: inlineEditor.isSubmitting, inline: true, formId: inlineEditorFormId })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: panelStyles.detailTitleRow, children: [_jsx(PlanningVisualIdentity, { entityType: detail.type, entityId: detail.item.id, icon: detail.item.icon, color: detail.item.color, size: "detail", disabled: Boolean(detail.item.isArchived), onChange: onChangePlanningIdentity
775
+ : _jsx(Archive, { size: 14, "aria-hidden": "true" }) }), _jsx("button", { type: "button", className: "tf-control-icon", onClick: onEdit, title: `Edit ${detailLabel.toLowerCase()} details`, "aria-label": `Edit ${detailLabel.toLowerCase()} details`, children: _jsx(Pencil, { size: 14, "aria-hidden": "true" }) })] })) })] }), archiveEntityConfirmationVisible && archiveDetailState.mode === 'ready' ? (_jsx(PlanningArchiveConfirmation, { entityType: detail.type, title: detail.item.title, activeTaskCount: detail.item.archiveActiveTaskCount, activeWorkstreamCount: detail.item.archiveActiveWorkstreamCount, busy: archiveEntityBusy, onCancel: () => setArchiveEntityConfirmationVisible(false), onConfirm: () => void handleConfirmArchiveEntity() })) : null, detail.type === 'workstream' ? renderRelationshipFeedback('workstream', detail.item.id) : null, inlineEditor ? (_jsx(PlanningDrawerEditor, { editor: inlineEditor.editor, draftTitle: inlineEditor.draftTitle, draftDescription: inlineEditor.draftDescription, draftOwner: inlineEditor.draftOwner, draftInitiativeId: inlineEditor.draftInitiativeId, assigneeOptions: assigneeOptions, initiativeLinkOptions: linkOptions.initiatives, draftInitiativeSummary: inlineEditor.draftInitiativeSummary, onChangeDraftTitle: inlineEditor.onChangeDraftTitle, onChangeDraftDescription: inlineEditor.onChangeDraftDescription, onChangeDraftOwner: inlineEditor.onChangeDraftOwner, onChangeDraftInitiativeId: inlineEditor.onChangeDraftInitiativeId, onCancel: inlineEditor.onCancel, onSubmit: inlineEditor.onSubmit, isSubmitting: inlineEditor.isSubmitting, inline: true, formId: inlineEditorFormId })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: panelStyles.detailTitleRow, children: [_jsx(PlanningVisualIdentity, { entityType: detail.type, entityId: detail.item.id, icon: detail.item.icon, color: detail.item.color, size: "detail", disabled: Boolean(detail.item.isArchived), onChange: onChangePlanningIdentity
783
776
  ? (patch) => onChangePlanningIdentity(detail.type, detail.item.id, patch)
784
777
  : undefined }), _jsx("h3", { className: panelStyles.detailTitle, children: detail.item.title })] }), _jsx(PlanningEntityDescription, { description: detail.item.description, label: detailLabel, taskReferences: taskReferences, className: `${panelStyles.detailDescription} ${styles.appScrollbar} tf-scrollbar`.trim(), markdownClassName: panelStyles.detailDescriptionMarkdown })] })), _jsxs("div", { className: panelStyles.detailOwnerField, children: [_jsx("span", { className: panelStyles.detailOwnerLabel, children: "Owner" }), _jsx(PlanningOwnerDropdown, { value: ownerValue, disabled: !onChangeOwner || isSavingOwner, onChange: (nextOwnerId) => void handleOwnerChange(nextOwnerId), ariaLabel: `${detailLabel} owner`, options: assigneeOptions, className: `${planningDropdownStyles.control} ${panelStyles.ownerSelect}` })] }), detail.item.taskCount > 0 ? (_jsx(PlanningProgress, { value: detail.item.progressPercent, label: `${detail.item.progressPercent}% resolved`, statusCounts: detail.item.statusCounts })) : (_jsx(PlanningNoTasks, {})), _jsx(PlanningSummaryMeta, { item: detail.item, workstreamCount: detail.type === 'initiative'
785
778
  ? detail.item.workstreamCount ?? detail.item.workstreams.length
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
2
+ import { useCallback, useEffect, useState } from 'react';
3
3
  import { CreditCard, KeyRound, Link2, RefreshCw, ShieldCheck, User } from 'lucide-react';
4
4
  import { Modal } from '../../../ui/Modal';
5
5
  import { EditableAvatarButton } from '../../../ui/EditableAvatarButton';
@@ -9,6 +9,7 @@ import styles from '../../../../Taskforce.module.css';
9
9
  import settingsStyles from './AccountSettingsModal.module.css';
10
10
  import { resolveCommercialLifecyclePresentation } from '../../../../utils/commercialLifecyclePresentation';
11
11
  import { getPasswordPolicyGuidance, validatePasswordPolicy } from '../../../../shared/passwordPolicy';
12
+ import { PasswordInput } from '../../../ui/PasswordInput';
12
13
  const PROVIDER_LABELS = {
13
14
  password: 'Email & Password',
14
15
  google: 'Google',
@@ -53,11 +54,7 @@ export function AccountSettingsModal({ isOpen, theme, displayName, email, avatar
53
54
  const linkedProviders = new Set(loginMethods.map((method) => method.provider));
54
55
  const hasPassword = linkedProviders.has('password');
55
56
  const linkableProviders = availableAuthProviders.filter((provider) => provider !== 'password' && !linkedProviders.has(provider));
56
- useEffect(() => {
57
- if (!isOpen)
58
- return;
59
- setActiveSection('profile');
60
- setUnlinkError(null);
57
+ const clearCredentialState = useCallback(() => {
61
58
  setShowAddPassword(false);
62
59
  setAddPasswordValue('');
63
60
  setAddPasswordError(null);
@@ -68,16 +65,28 @@ export function AccountSettingsModal({ isOpen, theme, displayName, email, avatar
68
65
  setConfirmPasswordValue('');
69
66
  setChangePasswordError(null);
70
67
  setChangePasswordDone(false);
71
- }, [isOpen]);
68
+ }, []);
69
+ const handleClose = () => {
70
+ clearCredentialState();
71
+ onClose();
72
+ };
73
+ const handleSectionChange = (section) => {
74
+ if (section !== 'security')
75
+ clearCredentialState();
76
+ setActiveSection(section);
77
+ };
78
+ useEffect(() => {
79
+ setUnlinkError(null);
80
+ clearCredentialState();
81
+ if (!isOpen)
82
+ return;
83
+ setActiveSection('profile');
84
+ }, [clearCredentialState, isOpen]);
72
85
  useEffect(() => {
73
86
  if (activeSection === 'security')
74
87
  return;
75
- setShowChangePassword(false);
76
- setCurrentPasswordValue('');
77
- setNewPasswordValue('');
78
- setConfirmPasswordValue('');
79
- setChangePasswordError(null);
80
- }, [activeSection]);
88
+ clearCredentialState();
89
+ }, [activeSection, clearCredentialState]);
81
90
  useEffect(() => {
82
91
  if (!isOpen || activeSection !== 'security' || !cloudAuthEnabled)
83
92
  return;
@@ -173,7 +182,7 @@ export function AccountSettingsModal({ isOpen, theme, displayName, email, avatar
173
182
  setShowChangePassword(true);
174
183
  setChangePasswordDone(false);
175
184
  setChangePasswordError(null);
176
- }, children: "Change password" }) })), showChangePassword && (_jsxs("div", { className: settingsStyles.addPasswordForm, children: [_jsxs("label", { className: settingsStyles.fieldLabel, children: [_jsx("span", { children: "Current password" }), _jsx("input", { type: "password", className: styles.input, value: currentPasswordValue, onChange: (event) => setCurrentPasswordValue(event.target.value), disabled: changePasswordBusy, autoComplete: "current-password" })] }), _jsxs("label", { className: settingsStyles.fieldLabel, children: [_jsx("span", { children: "New password" }), _jsx("input", { type: "password", className: styles.input, value: newPasswordValue, onChange: (event) => setNewPasswordValue(event.target.value), disabled: changePasswordBusy, autoComplete: "new-password" })] }), _jsxs("label", { className: settingsStyles.fieldLabel, children: [_jsx("span", { children: "Confirm new password" }), _jsx("input", { type: "password", className: styles.input, value: confirmPasswordValue, onChange: (event) => setConfirmPasswordValue(event.target.value), disabled: changePasswordBusy, autoComplete: "new-password" })] }), _jsx("p", { className: "tf-text-helper", children: addPasswordGuidance.join(' ') }), changePasswordError && _jsx("p", { className: "tf-text-error", role: "alert", children: changePasswordError }), _jsxs("div", { className: settingsStyles.inlineActions, children: [_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => {
185
+ }, children: "Change password" }) })), showChangePassword && (_jsxs("div", { className: settingsStyles.addPasswordForm, children: [_jsxs("div", { className: settingsStyles.fieldLabel, children: [_jsx("label", { htmlFor: "account-current-password", children: "Current password" }), _jsx(PasswordInput, { id: "account-current-password", className: styles.input, value: currentPasswordValue, onChange: (event) => setCurrentPasswordValue(event.target.value), disabled: changePasswordBusy, autoComplete: "current-password", visibilityLabel: "current password" })] }), _jsxs("div", { className: settingsStyles.fieldLabel, children: [_jsx("label", { htmlFor: "account-new-password", children: "New password" }), _jsx(PasswordInput, { id: "account-new-password", className: styles.input, value: newPasswordValue, onChange: (event) => setNewPasswordValue(event.target.value), disabled: changePasswordBusy, autoComplete: "new-password", visibilityLabel: "new password" })] }), _jsxs("div", { className: settingsStyles.fieldLabel, children: [_jsx("label", { htmlFor: "account-confirm-password", children: "Confirm new password" }), _jsx(PasswordInput, { id: "account-confirm-password", className: styles.input, value: confirmPasswordValue, onChange: (event) => setConfirmPasswordValue(event.target.value), disabled: changePasswordBusy, autoComplete: "new-password", visibilityLabel: "confirm new password" })] }), _jsx("p", { className: "tf-text-helper", children: addPasswordGuidance.join(' ') }), changePasswordError && _jsx("p", { className: "tf-text-error", role: "alert", children: changePasswordError }), _jsxs("div", { className: settingsStyles.inlineActions, children: [_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => {
177
186
  setShowChangePassword(false);
178
187
  setCurrentPasswordValue('');
179
188
  setNewPasswordValue('');
@@ -183,15 +192,15 @@ export function AccountSettingsModal({ isOpen, theme, displayName, email, avatar
183
192
  setShowAddPassword(true);
184
193
  setAddPasswordDone(false);
185
194
  setAddPasswordError(null);
186
- }, children: "Add password login" }) })), showAddPassword && (_jsxs("div", { className: settingsStyles.addPasswordForm, children: [_jsxs("label", { className: settingsStyles.fieldLabel, children: [_jsx("span", { children: "New password" }), _jsx("input", { type: "password", className: styles.input, placeholder: "Use 12+ characters", value: addPasswordValue, onChange: (event) => setAddPasswordValue(event.target.value), disabled: addPasswordBusy, autoComplete: "new-password" })] }), _jsx("p", { className: "tf-text-helper", children: addPasswordGuidance.join(' ') }), addPasswordError && _jsx("p", { className: "tf-text-error", role: "alert", children: addPasswordError }), _jsxs("div", { className: settingsStyles.inlineActions, children: [_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => {
195
+ }, children: "Add password login" }) })), showAddPassword && (_jsxs("div", { className: settingsStyles.addPasswordForm, children: [_jsxs("div", { className: settingsStyles.fieldLabel, children: [_jsx("label", { htmlFor: "account-add-password", children: "New password" }), _jsx(PasswordInput, { id: "account-add-password", className: styles.input, placeholder: "Use 12+ characters", value: addPasswordValue, onChange: (event) => setAddPasswordValue(event.target.value), disabled: addPasswordBusy, autoComplete: "new-password", visibilityLabel: "new password" })] }), _jsx("p", { className: "tf-text-helper", children: addPasswordGuidance.join(' ') }), addPasswordError && _jsx("p", { className: "tf-text-error", role: "alert", children: addPasswordError }), _jsxs("div", { className: settingsStyles.inlineActions, children: [_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => {
187
196
  setShowAddPassword(false);
188
197
  setAddPasswordValue('');
189
198
  setAddPasswordError(null);
190
199
  }, disabled: addPasswordBusy, children: "Cancel" }), _jsx("button", { type: "button", className: "tf-button-primary tf-button-compact", onClick: () => { void handleAddPassword(); }, disabled: addPasswordBusy || !addPasswordValue, children: addPasswordBusy ? 'Saving…' : 'Save password' })] })] })), !loginMethodsLoading && !loginMethodsError && linkableProviders.length > 0 && (_jsxs("div", { className: settingsStyles.linkProviderBlock, children: [_jsx("p", { className: "tf-label-micro", children: "Link another account" }), _jsx("div", { className: settingsStyles.inlineActions, children: linkableProviders.map((provider) => (_jsxs("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => onLinkProvider(provider), children: [_jsx(Link2, { size: 15 }), PROVIDER_LABELS[provider] || provider] }, provider))) })] }))] })] }));
191
200
  const renderBillingSection = () => (_jsxs("section", { className: settingsStyles.section, "aria-labelledby": "account-billing-heading", children: [_jsxs("div", { className: settingsStyles.sectionHeader, children: [_jsxs("div", { children: [_jsx("h2", { className: "tf-heading-card", id: "account-billing-heading", children: "Plan & Billing" }), _jsx("p", { className: "tf-text-secondary", children: "Review your plan and open the secure billing portal." })] }), _jsxs("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: onRefreshBilling, disabled: billingActionBusy || billingLoading, children: [_jsx(RefreshCw, { size: 14 }), "Refresh"] })] }), _jsxs("div", { className: `${settingsStyles.sectionCard} tf-surface-panel`, children: [billingLoading && _jsx("p", { className: "tf-text-secondary", children: "Loading billing status\u2026" }), billingError && _jsx("p", { className: "tf-text-error", role: "alert", children: billingError }), billingActionError && _jsx("p", { className: "tf-text-error", role: "alert", children: billingActionError }), billingNotice && _jsx("p", { className: "tf-text-secondary", role: "status", children: billingNotice }), _jsxs("div", { className: settingsStyles.planSummary, children: [_jsxs("div", { children: [_jsx("p", { className: "tf-label-micro", children: "Current plan" }), _jsx("strong", { className: settingsStyles.planName, children: resolvedPlanLabel })] }), _jsx("span", { className: `tf-chip ${lifecyclePresentation.isActive ? 'tf-chip-success' : 'tf-chip-neutral'}`, children: formatStatusLabel(accountProfileSummary?.entitlementState) })] }), lifecyclePresentation.message && (_jsx("p", { className: lifecyclePresentation.statusTone === 'error' ? 'tf-text-error' : 'tf-text-secondary', children: lifecyclePresentation.message })), accountProfileSummary?.stripeSubscriptionId && (_jsxs("div", { className: settingsStyles.intervalRow, children: [_jsxs("label", { className: settingsStyles.fieldLabel, children: [_jsx("span", { children: "Billing interval" }), _jsxs("select", { className: styles.input, value: billingIntervalChoice, onChange: (event) => onBillingIntervalChange(event.target.value === 'year' ? 'year' : 'month'), disabled: billingActionBusy, children: [_jsx("option", { value: "month", children: "Monthly" }), _jsx("option", { value: "year", children: "Yearly" })] })] }), _jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: onUpdateInterval, disabled: billingActionBusy, children: "Update interval" })] })), _jsxs("div", { className: settingsStyles.sectionActions, children: [(lifecyclePresentation.primaryAction === 'manage_billing' || lifecyclePresentation.primaryAction === 'none') && (_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: onOpenPlans, disabled: billingActionBusy, children: "View plans" })), lifecyclePresentation.showManageBilling && lifecyclePresentation.primaryAction !== 'manage_billing' && (_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: onManageBilling, disabled: billingActionBusy, children: "Manage billing" })), lifecyclePresentation.primaryLabel && (_jsx("button", { type: "button", className: "tf-button-primary tf-button-compact", onClick: handlePrimaryBillingAction, disabled: billingActionBusy, children: billingActionBusy ? 'Working…' : lifecyclePresentation.primaryLabel }))] })] })] }));
192
- return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: "Account Settings", size: "mdWide", theme: theme, draggable: true, children: _jsx("div", { className: `${modalStyles.form} ${settingsStyles.modalBody}`, children: _jsxs("div", { className: settingsStyles.layout, children: [_jsx("div", { className: settingsStyles.sectionTabs, role: "tablist", "aria-label": "Account settings sections", "aria-orientation": "vertical", children: SECTION_META.map((section) => {
201
+ return (_jsx(Modal, { isOpen: isOpen, onClose: handleClose, title: "Account Settings", size: "mdWide", theme: theme, draggable: true, children: _jsx("div", { className: `${modalStyles.form} ${settingsStyles.modalBody}`, children: _jsxs("div", { className: settingsStyles.layout, children: [_jsx("div", { className: settingsStyles.sectionTabs, role: "tablist", "aria-label": "Account settings sections", "aria-orientation": "vertical", children: SECTION_META.map((section) => {
193
202
  const Icon = section.icon;
194
203
  const selected = section.id === activeSection;
195
- return (_jsxs("button", { type: "button", role: "tab", id: `account-settings-tab-${section.id}`, "aria-controls": `account-settings-panel-${section.id}`, "aria-selected": selected, className: settingsStyles.sectionTab, onClick: () => setActiveSection(section.id), children: [_jsx(Icon, { size: 16 }), _jsx("span", { children: section.label })] }, section.id));
204
+ return (_jsxs("button", { type: "button", role: "tab", id: `account-settings-tab-${section.id}`, "aria-controls": `account-settings-panel-${section.id}`, "aria-selected": selected, className: settingsStyles.sectionTab, onClick: () => handleSectionChange(section.id), children: [_jsx(Icon, { size: 16 }), _jsx("span", { children: section.label })] }, section.id));
196
205
  }) }), _jsxs("div", { className: settingsStyles.sectionPanel, role: "tabpanel", id: `account-settings-panel-${activeSection}`, "aria-labelledby": `account-settings-tab-${activeSection}`, children: [activeSection === 'profile' && renderProfileSection(), activeSection === 'security' && renderSecuritySection(), activeSection === 'billing' && renderBillingSection()] })] }) }) }));
197
206
  }
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { ModalThemeName } from './types';
3
+ import type { WorkspaceSyncToggleIntent } from '../../../../hooks/sync/useSyncStatusControls';
3
4
  interface SyncStatusMeta {
4
5
  label: string;
5
6
  color: string;
@@ -24,10 +25,11 @@ interface SyncStatusModalProps {
24
25
  isOpen: boolean;
25
26
  theme: ModalThemeName;
26
27
  currentWorkspaceLabel: string;
27
- syncStatus: 'off' | 'syncing' | 'attention' | 'healthy';
28
+ syncStatus: 'off' | 'checking' | 'syncing' | 'attention' | 'healthy';
28
29
  syncStatusMeta: SyncStatusMeta;
29
30
  workspaceCloudSyncEnabled: boolean;
30
31
  syncControlBusy: boolean;
32
+ syncControlIntent: WorkspaceSyncToggleIntent;
31
33
  canManageWorkspaceSync: boolean;
32
34
  workspaceSyncSummary: string;
33
35
  workspaceSyncRecommendedAction: string;
@@ -54,8 +56,7 @@ interface SyncStatusModalProps {
54
56
  onToggleWorkspaceSync: (enabled: boolean) => void;
55
57
  onRepairSync: () => void;
56
58
  onCopyReport: () => void;
57
- onRetrySync: () => void;
58
59
  onTransferCoordinatorOwnership: () => void;
59
60
  }
60
- export declare function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStatus, syncStatusMeta, workspaceCloudSyncEnabled, syncControlBusy, canManageWorkspaceSync, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncRepairBusy, referenceMismatchCount, syncStageLabel, workspaceSyncPendingChanges, incomingCloudChanges, formattedLastSyncTime, formattedLastPullTime, formattedLastPushTime, syncLastError, activeReferenceMismatchSummaries, syncDiagnosticsSummary, syncEventRows, syncEventsListRef, workspaceSyncRepairQueued, workspaceSyncBusy, workspaceSyncCopied, coordinatorOwnershipMode, coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled, onClose, onToggleWorkspaceSync, onRepairSync, onCopyReport, onRetrySync, onTransferCoordinatorOwnership, }: SyncStatusModalProps): import("react/jsx-runtime").JSX.Element;
61
+ export declare function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStatus, syncStatusMeta, workspaceCloudSyncEnabled, syncControlBusy, syncControlIntent, canManageWorkspaceSync, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncRepairBusy, referenceMismatchCount, syncStageLabel, workspaceSyncPendingChanges, incomingCloudChanges, formattedLastSyncTime, formattedLastPullTime, formattedLastPushTime, syncLastError, activeReferenceMismatchSummaries, syncDiagnosticsSummary, syncEventRows, syncEventsListRef, workspaceSyncRepairQueued, workspaceSyncBusy, workspaceSyncCopied, coordinatorOwnershipMode, coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled, onClose, onToggleWorkspaceSync, onRepairSync, onCopyReport, onTransferCoordinatorOwnership, }: SyncStatusModalProps): import("react/jsx-runtime").JSX.Element;
61
62
  export {};