@taskforcehq/taskforce 0.3.327 → 0.3.329

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 (360) hide show
  1. package/dist/Taskforce.module.css +257 -87
  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/activity/EntityActivityTimeline.js +15 -5
  8. package/dist/components/context/AttachmentPreviewHost.js +1 -1
  9. package/dist/components/context/ContextAttachmentManager.d.ts +3 -0
  10. package/dist/components/context/ContextAttachmentManager.js +116 -20
  11. package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
  12. package/dist/components/features/TaskSettings.d.ts +12 -1
  13. package/dist/components/features/TaskSettings.js +147 -40
  14. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
  15. package/dist/components/features/planning/PlanningEntitySummary.d.ts +3 -1
  16. package/dist/components/features/planning/PlanningEntitySummary.js +3 -2
  17. package/dist/components/features/planning/PlanningLinkPicker.d.ts +3 -1
  18. package/dist/components/features/planning/PlanningLinkPicker.js +5 -3
  19. package/dist/components/features/planning/PlanningModule.js +28 -14
  20. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
  21. package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
  22. package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
  23. package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
  24. package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
  25. package/dist/components/features/planning/planningTaskArrangement.js +5 -5
  26. package/dist/components/features/planning/planningWorkspaceModel.d.ts +11 -0
  27. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  28. package/dist/components/task/TaskActionHeader.d.ts +2 -1
  29. package/dist/components/task/TaskActionHeader.js +2 -2
  30. package/dist/components/task/TaskCard.d.ts +5 -0
  31. package/dist/components/task/TaskCard.js +101 -13
  32. package/dist/components/task/TaskContextUpload.d.ts +3 -0
  33. package/dist/components/task/TaskContextUpload.js +2 -2
  34. package/dist/components/task/TaskForm.d.ts +4 -0
  35. package/dist/components/task/TaskForm.js +32 -7
  36. package/dist/components/task/TaskImageReviews.js +28 -19
  37. package/dist/components/task/TaskKanban.d.ts +6 -1
  38. package/dist/components/task/TaskKanban.js +152 -6
  39. package/dist/components/task/TaskList.d.ts +5 -0
  40. package/dist/components/task/TaskList.js +3 -3
  41. package/dist/components/task/TaskStatusActions.js +11 -2
  42. package/dist/components/task/TaskWorkstreamPicker.js +2 -1
  43. package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
  44. package/dist/components/ui/DocumentTypeIcon.js +8 -0
  45. package/dist/components/ui/PasswordInput.d.ts +6 -0
  46. package/dist/components/ui/PasswordInput.js +11 -0
  47. package/dist/components/ui/TaxonomyDropdown.d.ts +9 -1
  48. package/dist/components/ui/TaxonomyDropdown.js +30 -3
  49. package/dist/components/ui/TopNoticeLayer.js +1 -1
  50. package/dist/components/views/AppShellHeader.js +32 -11
  51. package/dist/components/views/PlanComparisonPage.js +12 -0
  52. package/dist/components/views/StandaloneLayout.js +68 -39
  53. package/dist/components/views/WidgetView.js +10 -7
  54. package/dist/components/views/panels/PlanningDrawer.d.ts +7 -1
  55. package/dist/components/views/panels/PlanningDrawer.js +51 -54
  56. package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
  57. package/dist/config/envSchema.js +13 -0
  58. package/dist/config/localServiceCloudTarget.d.ts +10 -0
  59. package/dist/config/localServiceCloudTarget.js +76 -0
  60. package/dist/config/localServiceRuntimeContract.d.ts +13 -0
  61. package/dist/config/localServiceRuntimeContract.js +135 -0
  62. package/dist/core/AiProfileService.d.ts +1 -0
  63. package/dist/core/AiProfileService.js +48 -9
  64. package/dist/core/AttachmentLinkService.js +7 -4
  65. package/dist/core/DeletedTaskLifecycleService.d.ts +5 -0
  66. package/dist/core/DeletedTaskLifecycleService.js +55 -3
  67. package/dist/core/McpTokenService.d.ts +4 -0
  68. package/dist/core/McpTokenService.js +52 -0
  69. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +8 -2
  70. package/dist/core/TaskAttachmentLinksDurableMutationService.js +51 -18
  71. package/dist/core/Taskforce.d.ts +124 -2
  72. package/dist/core/Taskforce.js +1175 -87
  73. package/dist/core/types.d.ts +8 -1
  74. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +11 -0
  75. package/dist/documentReviews/DocumentReviewCommentStore.js +35 -2
  76. package/dist/documentReviews/service.d.ts +4 -0
  77. package/dist/documentReviews/service.js +141 -46
  78. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
  79. package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
  80. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
  81. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
  82. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
  83. package/dist/hooks/tasks/taskHttpMutation.js +1 -0
  84. package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
  85. package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
  86. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
  87. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
  88. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
  89. package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
  90. package/dist/hooks/tasks/useTaskFormActions.d.ts +9 -0
  91. package/dist/hooks/tasks/useTaskFormActions.js +96 -17
  92. package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
  93. package/dist/hooks/ui/useSettingsModel.js +13 -2
  94. package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
  95. package/dist/hooks/ui/useSettingsPersistence.js +74 -47
  96. package/dist/hooks/useFilterSort.d.ts +7 -3
  97. package/dist/hooks/useFilterSort.js +15 -5
  98. package/dist/hooks/useTaskData.d.ts +10 -1
  99. package/dist/hooks/useTaskData.js +216 -7
  100. package/dist/hooks/useTaskMutations.d.ts +10 -2
  101. package/dist/hooks/useTaskMutations.js +223 -43
  102. package/dist/hooks/useTaskforce.d.ts +94 -57
  103. package/dist/hooks/useTaskforce.js +428 -16
  104. package/dist/hooks/useUiNotice.d.ts +4 -0
  105. package/dist/hooks/useUiNotice.js +4 -0
  106. package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
  107. package/dist/mcp/canonicalAssetHelpers.d.ts +13 -0
  108. package/dist/mcp/canonicalAssetHelpers.js +39 -5
  109. package/dist/mcp/collaborationRegistrar.js +15 -13
  110. package/dist/mcp/documentAssetRegistrar.js +60 -44
  111. package/dist/mcp/documentHelpers.d.ts +1 -0
  112. package/dist/mcp/documentHelpers.js +7 -3
  113. package/dist/mcp/localServiceProxy.js +4 -1
  114. package/dist/mcp/runtime.d.ts +16 -0
  115. package/dist/mcp/runtime.js +735 -210
  116. package/dist/mcp/taskAttachmentCommandAdapter.d.ts +2 -0
  117. package/dist/mcp/taskAttachmentCommandAdapter.js +14 -8
  118. package/dist/mcp/taskPlanningRegistrar.js +78 -67
  119. package/dist/mcp/toolCallCompatibility.js +38 -1
  120. package/dist/mcp/toolCatalog.d.ts +1 -0
  121. package/dist/mcp/toolRegistry.js +2 -2
  122. package/dist/migrations/taskSchemaMigrations.js +47 -0
  123. package/dist/runtime/appGateDefinitions.d.ts +30 -6
  124. package/dist/runtime/appGateDefinitions.js +6 -6
  125. package/dist/runtime/appGates.d.ts +12 -13
  126. package/dist/runtime/appGates.js +29 -13
  127. package/dist/runtime/nodeAppGates.d.ts +8 -0
  128. package/dist/runtime/nodeAppGates.js +27 -0
  129. package/dist/server/appAccess.d.ts +12 -0
  130. package/dist/server/appAccess.js +21 -0
  131. package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
  132. package/dist/server/authorizedWorkspaceAccess.js +40 -0
  133. package/dist/server/cloudCollectionRead.d.ts +25 -0
  134. package/dist/server/cloudCollectionRead.js +120 -0
  135. package/dist/server/cloudCollectionReadPool.d.ts +52 -0
  136. package/dist/server/cloudCollectionReadPool.js +140 -0
  137. package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
  138. package/dist/server/cloudCollectionReadWorker.js +36 -0
  139. package/dist/server/index.d.ts +6 -11
  140. package/dist/server/index.js +67 -42
  141. package/dist/server/localServiceLease.d.ts +6 -0
  142. package/dist/server/localServiceLease.js +17 -1
  143. package/dist/server/localWorkspaceSyncServerRuntime.js +10 -3
  144. package/dist/server/rateLimit.d.ts +1 -0
  145. package/dist/server/rateLimit.js +4 -0
  146. package/dist/server/realtimeSyncWs.js +36 -12
  147. package/dist/server/routes/admin.js +1 -0
  148. package/dist/server/routes/agentRoles.js +3 -2
  149. package/dist/server/routes/agentSkills.js +3 -2
  150. package/dist/server/routes/agents.js +118 -16
  151. package/dist/server/routes/annotatedAttachments.js +3 -2
  152. package/dist/server/routes/auth.js +3 -1
  153. package/dist/server/routes/documents.d.ts +5 -2
  154. package/dist/server/routes/documents.js +160 -13
  155. package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
  156. package/dist/server/routes/durableTaskHttpRouters.js +2 -2
  157. package/dist/server/routes/localService.js +4 -0
  158. package/dist/server/routes/primitives.d.ts +4 -0
  159. package/dist/server/routes/shared.d.ts +24 -0
  160. package/dist/server/routes/shared.js +114 -18
  161. package/dist/server/routes/sync.js +22 -0
  162. package/dist/server/routes/syncAuxRoutes.js +5 -2
  163. package/dist/server/routes/syncPullApplyRoutes.js +23 -4
  164. package/dist/server/routes/syncV3FeedRoutes.js +22 -18
  165. package/dist/server/routes/syncV3LocalCaptureRoutes.js +48 -4
  166. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
  167. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
  168. package/dist/server/routes/syncV3OperationRoutes.js +27 -2
  169. package/dist/server/routes/tasks.js +299 -97
  170. package/dist/server/routes/workspaces.js +43 -1
  171. package/dist/server/routes.js +35 -7
  172. package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
  173. package/dist/server/workspaceDeletionAdmission.js +50 -0
  174. package/dist/service/localServiceCli.js +52 -25
  175. package/dist/service/localServiceClientLifecycle.js +93 -6
  176. package/dist/services/codexAppServerModelGateway.d.ts +112 -0
  177. package/dist/services/codexAppServerModelGateway.js +438 -0
  178. package/dist/services/taskforceAgentMcpBridge.d.ts +7 -1
  179. package/dist/services/taskforceAgentMcpBridge.js +23 -3
  180. package/dist/shared/planningIdentity.d.ts +20 -0
  181. package/dist/shared/planningIdentity.js +79 -0
  182. package/dist/shared/taskforceAgentDefinition.js +7 -1
  183. package/dist/shared/taskforceAgentModels.d.ts +1 -0
  184. package/dist/shared/taskforceAgentModels.js +30 -1
  185. package/dist/storage/postgresAdapter.d.ts +20 -3
  186. package/dist/storage/postgresAdapter.js +110 -14
  187. package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
  188. package/dist/storage/postgresRequestDiagnostics.js +24 -0
  189. package/dist/storage/postgresWorker.js +13 -4
  190. package/dist/storage/postgresWorkerProtocol.d.ts +29 -0
  191. package/dist/storage/postgresWorkerProtocol.js +30 -0
  192. package/dist/storage/workspaceAssetStore.d.ts +32 -0
  193. package/dist/storage/workspaceAssetStore.js +70 -0
  194. package/dist/sync/cloudSyncApi.d.ts +4 -1
  195. package/dist/sync/cloudSyncApi.js +7 -2
  196. package/dist/sync/contentSyncState.d.ts +1 -1
  197. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +17 -0
  198. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +77 -23
  199. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
  200. package/dist/sync/coordinator/workspaceSyncTransportGateway.js +4 -2
  201. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
  202. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
  203. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
  204. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +16 -0
  205. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
  206. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +1 -1
  207. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +46 -4
  208. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
  209. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +51 -11
  210. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
  211. package/dist/sync/engine/workspaceSyncEngineTransfers.js +8 -3
  212. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +2 -0
  213. package/dist/sync/syncApplyHandlers.d.ts +3 -1
  214. package/dist/sync/syncApplyHandlers.js +29 -0
  215. package/dist/sync/syncService.d.ts +2 -0
  216. package/dist/sync/syncService.js +13 -1
  217. package/dist/sync/taskSyncPayload.d.ts +1 -0
  218. package/dist/sync/taskSyncPayload.js +6 -0
  219. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  220. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +3 -0
  221. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +31 -3
  222. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -0
  223. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +4 -0
  224. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
  225. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +47 -12
  226. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
  227. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +27 -2
  228. package/dist/sync/v3/localInitiativeOutboxService.js +4 -2
  229. package/dist/sync/v3/localOutboxDispatcher.js +5 -1
  230. package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +12 -2
  231. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +3 -0
  232. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +62 -10
  233. package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
  234. package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
  235. package/dist/sync/v3/localTaskMetadataClient.js +1 -0
  236. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
  237. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
  238. package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
  239. package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
  240. package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
  241. package/dist/sync/v3/localTaskStatusClient.js +6 -1
  242. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +2 -0
  243. package/dist/sync/v3/localTaskStatusOutboxService.js +54 -13
  244. package/dist/sync/v3/localWorkstreamOutboxService.js +4 -2
  245. package/dist/sync/v3/syncDurabilityStore.d.ts +15 -0
  246. package/dist/sync/v3/syncDurabilityStore.js +201 -43
  247. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +7 -4
  248. package/dist/sync/v3/taskAttachmentLinksMutationService.js +37 -12
  249. package/dist/sync/v3/taskChecklistMutationService.d.ts +4 -2
  250. package/dist/sync/v3/taskChecklistMutationService.js +4 -0
  251. package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
  252. package/dist/sync/v3/taskCreateMutationService.js +7 -4
  253. package/dist/sync/v3/taskMetadataCoexistence.js +4 -0
  254. package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
  255. package/dist/sync/v3/taskMetadataMutationService.js +4 -0
  256. package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
  257. package/dist/sync/v3/taskRestoreMutationService.js +7 -4
  258. package/dist/sync/v3/taskStatusMutationService.d.ts +2 -0
  259. package/dist/sync/v3/taskStatusMutationService.js +4 -0
  260. package/dist/sync/v3/workflowAssignmentSync.d.ts +1 -0
  261. package/dist/sync/v3/workflowAssignmentSync.js +3 -0
  262. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
  263. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +14 -12
  264. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
  265. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
  266. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
  267. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
  268. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +10 -1
  269. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +15 -4
  270. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +66 -13
  271. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +11 -0
  272. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +57 -22
  273. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +10 -4
  274. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -51
  275. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  276. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +120 -28
  277. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +3 -1
  278. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +18 -0
  279. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  280. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
  281. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
  282. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
  283. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
  284. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
  285. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
  286. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
  287. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
  288. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
  289. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
  290. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
  291. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
  292. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +2 -0
  293. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +19 -7
  294. package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
  295. package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
  296. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
  297. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
  298. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
  299. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
  300. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
  301. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +1 -1
  302. package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +1 -1
  303. package/dist/sync/workspacePullFeed.d.ts +6 -1
  304. package/dist/sync/workspacePullFeed.js +174 -162
  305. package/dist/sync/workspaceRepair.d.ts +3 -0
  306. package/dist/sync/workspaceRepair.js +67 -6
  307. package/dist/sync/workspaceSyncModel.d.ts +11 -0
  308. package/dist/sync/workspaceSyncModel.js +27 -2
  309. package/dist/types.d.ts +55 -1
  310. package/dist/types.js +6 -0
  311. package/dist/ui/assets/{AiIdentityRosterCard-DB1BLO_j.js → AiIdentityRosterCard-BZM4aQnM.js} +1 -1
  312. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +1 -0
  313. package/dist/ui/assets/AnnotatedAttachmentWorkspace-B68Wg-RV.js +3 -0
  314. package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
  315. package/dist/ui/assets/AssetTraySortControl-C8Rztyal.js +1 -0
  316. package/dist/ui/assets/ContextAttachmentManager-Cj3c7X9y.js +3 -0
  317. package/dist/ui/assets/{DocumentWorkspace-BC7sy5TG.js → DocumentWorkspace-B5uvzems.js} +4 -4
  318. package/dist/ui/assets/EntityActivityTimeline-BVFvCB5R.js +1 -0
  319. package/dist/ui/assets/PlanningModule-B5DWQOGz.js +1 -0
  320. package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
  321. package/dist/ui/assets/PlansPage-AY4cGWco.js +1 -0
  322. package/dist/ui/assets/TaskContextUpload-DZxTVesW.js +1 -0
  323. package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
  324. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +12 -0
  325. package/dist/ui/assets/{TaskforceAgentsModule-CkAxW19K.js → TaskforceAgentsModule-BifCYtjR.js} +6 -6
  326. package/dist/ui/assets/WorkflowManagerModule-DEr5di_r.js +1 -0
  327. package/dist/ui/assets/index-I5zhdtgt.js +7 -0
  328. package/dist/ui/assets/index-VRFsx3wz.css +1 -0
  329. package/dist/ui/assets/{vendor-icons-B8ZNsH1g.js → vendor-icons-D9Lpw-j4.js} +1 -1
  330. package/dist/ui/index.html +3 -3
  331. package/dist/utils/constants.d.ts +2 -2
  332. package/dist/utils/constants.js +1 -1
  333. package/dist/utils/contextAttachmentUpload.d.ts +2 -0
  334. package/dist/utils/contextAttachmentUpload.js +7 -0
  335. package/dist/utils/contextFiles.d.ts +1 -1
  336. package/dist/utils/contextFiles.js +4 -4
  337. package/dist/utils/taskActivity.d.ts +3 -2
  338. package/dist/utils/taskActivity.js +19 -2
  339. package/dist/utils/taskEditorReconciliation.d.ts +40 -0
  340. package/dist/utils/taskEditorReconciliation.js +217 -0
  341. package/dist/utils/taskNormalization.d.ts +1 -0
  342. package/dist/utils/taskNormalization.js +39 -0
  343. package/dist/utils/taskSearch.js +2 -2
  344. package/dist/utils/uiNotice.d.ts +4 -0
  345. package/package.json +21 -4
  346. package/dist/ui/assets/AiProfilesModule-DPxQeF9N.js +0 -1
  347. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
  348. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DHNYaNg6.js +0 -3
  349. package/dist/ui/assets/AssetTraySortControl-DphbyHVc.js +0 -1
  350. package/dist/ui/assets/ContextAttachmentManager-CMxSzHqc.js +0 -3
  351. package/dist/ui/assets/EntityActivityTimeline-pJ2ZjZ-k.js +0 -1
  352. package/dist/ui/assets/PlanningModule-CeTqXMMz.css +0 -1
  353. package/dist/ui/assets/PlanningModule-t5GbvVR9.js +0 -1
  354. package/dist/ui/assets/PlansPage-BVH_NfgT.js +0 -1
  355. package/dist/ui/assets/TaskContextUpload-Ds4LnDzV.css +0 -1
  356. package/dist/ui/assets/TaskContextUpload-bl4fOOUz.js +0 -1
  357. package/dist/ui/assets/TaskSettings-xVsxSa0g.js +0 -12
  358. package/dist/ui/assets/WorkflowManagerModule-BKqIGVnF.js +0 -1
  359. package/dist/ui/assets/index-BzJlVnNS.css +0 -1
  360. package/dist/ui/assets/index-Cx7vZJHL.js +0 -7
@@ -17,6 +17,7 @@ import { isLightThemeFamily } from './utils/theme';
17
17
  import { Cloud, LaptopMinimal } from 'lucide-react';
18
18
  import { getPasswordPolicyGuidance, validatePasswordPolicy } from './shared/passwordPolicy';
19
19
  import { TASK_DEEP_LINK_QUERY_KEYS } from './shared/taskDeepLinks';
20
+ import { PasswordInput } from './components/ui/PasswordInput';
20
21
  function isDebugModeEnabled() {
21
22
  const runtimeOverride = globalThis.__DEBUG_MODE__;
22
23
  if (typeof runtimeOverride === 'boolean')
@@ -732,10 +733,10 @@ function TaskforceCoreWithRouter({ config = {}, initialTaskId, initialActivityEn
732
733
  setPendingVerificationRedirectPath(null);
733
734
  }, [authMode, isLoginRoute, loginRouteMode]);
734
735
  useEffect(() => {
735
- if (authMode === 'register')
736
+ if (authMode === 'register' || authMode === 'reset' || (authMode === 'invite' && invitePasswordRequired))
736
737
  return;
737
738
  setLoginPasswordConfirm('');
738
- }, [authMode]);
739
+ }, [authMode, invitePasswordRequired]);
739
740
  useEffect(() => {
740
741
  if (!pendingPostAuthRedirect || !isAuthenticated)
741
742
  return;
@@ -1155,10 +1156,234 @@ function TaskforceCoreWithRouter({ config = {}, initialTaskId, initialActivityEn
1155
1156
  if (shellRenderState === 'app-bootstrap') {
1156
1157
  return (_jsx("div", { className: shellStyles.standaloneWrapper, "data-theme": currentTheme, children: _jsx("div", { className: authStyles.loginView, children: _jsxs("div", { className: authStyles.loginCard, children: [_jsxs("div", { className: authStyles.authBrandRow, children: [_jsx("img", { src: authBrandLogo, alt: "Taskforce", className: authStyles.loginLogo }), _jsx("h1", { className: authStyles.loginTitle, children: "Loading Taskforce" })] }), _jsx("p", { className: authStyles.loginSubtitle, children: bootstrapSubtitle }), bootstrapState.stalled && (_jsxs(_Fragment, { children: [_jsx("p", { className: authStyles.loginError, children: bootstrapState.error || 'Startup checks timed out.' }), _jsx("button", { className: styles.submitBtn, disabled: bootstrapRetryBusy, onClick: handleRetryBootstrap, children: bootstrapRetryBusy ? 'Retrying...' : 'Retry checks' }), isCloudRuntime && (_jsx("button", { className: styles.cancelBtn, disabled: bootstrapRetryBusy, onClick: handleGoToSignIn, children: "Go to sign-in" }))] }))] }) }) }));
1157
1158
  }
1159
+ const handleAuthSubmit = async () => {
1160
+ setLoginBusy(true);
1161
+ setLoginNotice(null);
1162
+ setLoginError(null);
1163
+ setLoginErrorCode(null);
1164
+ if (authMode === 'register' && !loginDisplayName.trim()) {
1165
+ setLoginError('Display name is required.');
1166
+ setLoginBusy(false);
1167
+ return;
1168
+ }
1169
+ if (authMode === 'register' || authMode === 'reset' || (authMode === 'invite' && invitePasswordRequired)) {
1170
+ const validation = validatePasswordPolicy(loginPassword, {
1171
+ email: loginEmail,
1172
+ displayName: loginDisplayName
1173
+ });
1174
+ if (!validation.ok) {
1175
+ setLoginError(validation.message || 'Password does not meet the password policy.');
1176
+ setLoginErrorCode(validation.code || null);
1177
+ setLoginBusy(false);
1178
+ return;
1179
+ }
1180
+ if (loginPassword !== loginPasswordConfirm) {
1181
+ setLoginError('Passwords do not match.');
1182
+ setLoginErrorCode('PASSWORD_CONFIRMATION_MISMATCH');
1183
+ setLoginBusy(false);
1184
+ return;
1185
+ }
1186
+ }
1187
+ let result = { success: false };
1188
+ if (authMode === 'login') {
1189
+ result = await loginWithCredentials(loginEmail, loginPassword);
1190
+ }
1191
+ else if (authMode === 'register') {
1192
+ result = await registerWithCredentials(loginEmail, loginPassword, {
1193
+ displayName: loginDisplayName,
1194
+ planId: selectedSignupPlanId || undefined,
1195
+ planVersionId: selectedSignupPlanVersionId || undefined,
1196
+ interval: selectedSignupInterval || undefined
1197
+ });
1198
+ }
1199
+ else if (authMode === 'verify') {
1200
+ result = await confirmEmailVerification(verificationToken);
1201
+ }
1202
+ else if (authMode === 'forgot') {
1203
+ result = await requestPasswordReset(loginEmail);
1204
+ }
1205
+ else if (authMode === 'reset') {
1206
+ result = await confirmPasswordReset(resetToken, loginPassword);
1207
+ }
1208
+ else if (authMode === 'invite') {
1209
+ if (inviteResolution === 'existing_user_signed_out') {
1210
+ result = await loginWithCredentials(loginEmail, loginPassword);
1211
+ }
1212
+ else {
1213
+ result = invitePasswordRequired
1214
+ ? await acceptInviteWithToken(inviteToken, loginPassword)
1215
+ : await joinInviteWithToken(inviteToken);
1216
+ }
1217
+ }
1218
+ if (!result.success) {
1219
+ if (authMode === 'register'
1220
+ && (result.code === 'SIGNUP_PLAN_NOT_ENABLED'
1221
+ || result.code === 'SIGNUP_PLAN_VERSION_NOT_FOUND'
1222
+ || result.code === 'SIGNUP_PLAN_VERSION_REQUIRED')) {
1223
+ navigate(planSelectionPath, { replace: true });
1224
+ setLoginBusy(false);
1225
+ return;
1226
+ }
1227
+ setLoginError(formatAuthError(result));
1228
+ setLoginErrorCode(result.code || null);
1229
+ if (authMode === 'login' && (result.code === 'WORKSPACE_NOT_FOUND' || result.code === 'WORKSPACE_ID_REQUIRED')) {
1230
+ navigate('/setup?step=workspace', { replace: true });
1231
+ setLoginBusy(false);
1232
+ return;
1233
+ }
1234
+ if (authMode === 'login' && result.code === 'EMAIL_NOT_VERIFIED' && loginEmail.trim()) {
1235
+ const sent = await requestEmailVerification(loginEmail);
1236
+ if (sent.success) {
1237
+ setVerifyCooldownUntil(Date.now() + 30_000);
1238
+ setLoginMode('verify');
1239
+ if (sent.verificationToken)
1240
+ setVerificationToken(sent.verificationToken);
1241
+ setLoginNotice(buildVerificationRequestNotice({
1242
+ ...sent,
1243
+ intro: 'If that account exists and still needs verification, we sent an email.'
1244
+ }));
1245
+ setLoginError(null);
1246
+ setLoginErrorCode(null);
1247
+ }
1248
+ }
1249
+ if (authMode === 'register' && result.code === 'EMAIL_ALREADY_EXISTS_UNVERIFIED' && loginEmail.trim()) {
1250
+ setVerifyCooldownUntil(Date.now() + 30_000);
1251
+ setLoginMode('verify');
1252
+ if (result.verificationToken)
1253
+ setVerificationToken(result.verificationToken);
1254
+ setLoginNotice(result.emailSent === false
1255
+ ? `This email already has an unverified account, but verification email delivery failed. ${result.emailError || 'Try Resend Verification again.'}`
1256
+ : 'This email already has an unverified account. Check your email for verification instructions.');
1257
+ setLoginError(null);
1258
+ setLoginErrorCode(null);
1259
+ }
1260
+ }
1261
+ else if (authMode === 'register') {
1262
+ const postRegistrationPath = resolvePostRegistrationPath(result);
1263
+ const commercialOnboardingGate = hasCommercialOnboardingGate(result);
1264
+ if (result.verificationRequired) {
1265
+ setPendingVerificationWorkspaceSetupRequired(Boolean(result.workspaceSetupRequired));
1266
+ setPendingVerificationCommercialState(commercialOnboardingGate
1267
+ ? String(result.commercialState || '').trim() || (result.planSelectionRequired ? 'pending_plan_selection' : 'checkout_pending')
1268
+ : null);
1269
+ setPendingVerificationRedirectPath(postRegistrationPath);
1270
+ if (result.verificationToken)
1271
+ setVerificationToken(result.verificationToken);
1272
+ setVerifyCooldownUntil(Date.now() + 30_000);
1273
+ setLoginMode('verify');
1274
+ setLoginNotice(result.emailSent === false
1275
+ ? `Account created, but verification email failed to send. ${result.emailError || 'Try Resend Verification again.'}`
1276
+ : 'Account created. Check your email for verification instructions.');
1277
+ }
1278
+ else {
1279
+ setCommercialOnboardingRedirectActive(commercialOnboardingGate);
1280
+ setPendingPostAuthRedirect({
1281
+ path: postRegistrationPath,
1282
+ workspaceSetupRequired: Boolean(result.workspaceSetupRequired),
1283
+ commercialOnboardingGate
1284
+ });
1285
+ }
1286
+ }
1287
+ else if (authMode === 'verify') {
1288
+ await retryBootstrapChecks();
1289
+ const commercialOnboardingGate = pendingVerificationCommercialState === 'pending_plan_selection'
1290
+ || pendingVerificationCommercialState === 'checkout_pending';
1291
+ setCommercialOnboardingRedirectActive(commercialOnboardingGate);
1292
+ setPendingPostAuthRedirect({
1293
+ path: pendingVerificationRedirectPath || nextTarget,
1294
+ workspaceSetupRequired: pendingVerificationWorkspaceSetupRequired,
1295
+ commercialOnboardingGate
1296
+ });
1297
+ }
1298
+ else if (authMode === 'forgot') {
1299
+ const passwordResetDeliveryFailed = result.deliveryAttempted === true && result.emailSent === false;
1300
+ if (result.resetToken)
1301
+ setResetToken(result.resetToken);
1302
+ setLoginNotice(buildPasswordResetNotice(result));
1303
+ if (!passwordResetDeliveryFailed) {
1304
+ setResetCooldownUntil(Date.now() + 30_000);
1305
+ setLoginMode('reset');
1306
+ }
1307
+ }
1308
+ else if (authMode === 'reset') {
1309
+ setLoginMode('login');
1310
+ setLoginNotice('Password updated. Sign in with your new password.');
1311
+ }
1312
+ else if (authMode === 'invite') {
1313
+ if (inviteResolution === 'existing_user_signed_out') {
1314
+ const normalizedInviteEmail = String(inviteEmail || '').trim().toLowerCase();
1315
+ const normalizedLoginEmail = loginEmail.trim().toLowerCase();
1316
+ // Make the invite flow deterministically join-ready as soon as
1317
+ // the invited account signs in successfully, instead of waiting
1318
+ // for a later invite inspection effect to catch up.
1319
+ if (normalizedInviteEmail && normalizedLoginEmail === normalizedInviteEmail) {
1320
+ setAuthMode('invite');
1321
+ setInviteResolution('existing_user_ready');
1322
+ setLoginPassword('');
1323
+ setLoginPasswordConfirm('');
1324
+ setLoginNotice('Signed in. Review the invite details to continue.');
1325
+ setLoginError(null);
1326
+ setLoginErrorCode(null);
1327
+ setLoginBusy(false);
1328
+ return;
1329
+ }
1330
+ if (normalizedInviteEmail) {
1331
+ setLoginEmail(inviteEmail || '');
1332
+ }
1333
+ setInviteResolution('existing_user_signed_out');
1334
+ setLoginPassword('');
1335
+ setLoginPasswordConfirm('');
1336
+ setLoginNotice(normalizedInviteEmail
1337
+ ? `Signed in, but this invite is for ${inviteEmail}. Sign in with that account to continue.`
1338
+ : 'Signed in, but this invite requires the invited account. Sign in with that account to continue.');
1339
+ setLoginError('Sign in with the invited account to join this workspace.');
1340
+ setLoginErrorCode('INVITE_ACCOUNT_MISMATCH');
1341
+ setLoginBusy(false);
1342
+ return;
1343
+ }
1344
+ if (result.workspaceSetupRequired) {
1345
+ navigate(resolveWorkspaceSetupPath(), { replace: true });
1346
+ setLoginBusy(false);
1347
+ return;
1348
+ }
1349
+ navigateToPostAuthTarget(nextTarget, { replace: true });
1350
+ }
1351
+ else if (authMode === 'login') {
1352
+ if (inviteToken.trim()) {
1353
+ setAuthMode('invite');
1354
+ setLoginPassword('');
1355
+ setLoginPasswordConfirm('');
1356
+ setLoginNotice('Signed in. Review the invite details to continue.');
1357
+ setLoginBusy(false);
1358
+ return;
1359
+ }
1360
+ if (result.workspaceSetupRequired) {
1361
+ navigate(resolveWorkspaceSetupPath(), { replace: true });
1362
+ setLoginBusy(false);
1363
+ return;
1364
+ }
1365
+ setLoginEmail('');
1366
+ setLoginDisplayName('');
1367
+ setLoginPassword('');
1368
+ setLoginPasswordConfirm('');
1369
+ navigateToPostAuthTarget(nextTarget, { replace: true });
1370
+ }
1371
+ else {
1372
+ setLoginEmail('');
1373
+ setLoginDisplayName('');
1374
+ setLoginPassword('');
1375
+ setLoginPasswordConfirm('');
1376
+ navigateToPostAuthTarget(nextTarget, { replace: true });
1377
+ }
1378
+ setLoginBusy(false);
1379
+ };
1158
1380
  if (shellRenderState === 'login') {
1159
1381
  return (_jsx("div", { className: shellStyles.standaloneWrapper, "data-theme": currentTheme, children: _jsx("div", { className: authStyles.loginView, style: {
1160
1382
  backgroundImage: `linear-gradient(rgba(15, 15, 26, 0.88), rgba(15, 15, 26, 0.9)), url(${taskforceBg})`
1161
- }, children: _jsxs("div", { className: authStyles.loginCard, children: [!isCloudRuntime && !shouldForceLogin && (_jsx("button", { className: authStyles.loginCloseBtn, "aria-label": "Close sign in", "data-testid": "auth-close-button", onClick: () => navigate(nextPath, { replace: true }), children: "\u00D7" })), _jsxs("div", { className: authStyles.authBrandRow, children: [_jsx("img", { src: authBrandLogo, alt: "Taskforce", className: authStyles.loginLogo }), _jsxs("h1", { className: authStyles.loginTitle, children: ["TASKFORCE ", _jsx("span", { className: authStyles.loginTitleAccent, children: "HQ" })] })] }), _jsxs("p", { className: authStyles.loginSubtitle, children: [authMode === 'login' && 'Sign in with your account credentials.', authMode === 'register' && 'Create your Taskforce account.', authMode === 'verify' && 'Enter your verification token.', authMode === 'forgot' && 'Request a password reset link.', authMode === 'reset' && 'Set a new password using your reset token.', authMode === 'invite' && (inviteResolution === 'existing_user_ready'
1383
+ }, children: _jsxs("form", { className: authStyles.loginCard, onSubmit: (event) => {
1384
+ event.preventDefault();
1385
+ void handleAuthSubmit();
1386
+ }, children: [!isCloudRuntime && !shouldForceLogin && (_jsx("button", { type: "button", className: authStyles.loginCloseBtn, "aria-label": "Close sign in", "data-testid": "auth-close-button", onClick: () => navigate(nextPath, { replace: true }), children: "\u00D7" })), _jsxs("div", { className: authStyles.authBrandRow, children: [_jsx("img", { src: authBrandLogo, alt: "Taskforce", className: authStyles.loginLogo }), _jsxs("h1", { className: authStyles.loginTitle, children: ["TASKFORCE ", _jsx("span", { className: authStyles.loginTitleAccent, children: "HQ" })] })] }), _jsxs("p", { className: authStyles.loginSubtitle, children: [authMode === 'login' && 'Sign in with your account credentials.', authMode === 'register' && 'Create your Taskforce account.', authMode === 'verify' && 'Enter your verification token.', authMode === 'forgot' && 'Request a password reset link.', authMode === 'reset' && 'Set a new password using your reset token.', authMode === 'invite' && (inviteResolution === 'existing_user_ready'
1162
1387
  ? `You've been invited to join ${inviteWorkspaceId || 'this workspace'}.`
1163
1388
  : inviteResolution === 'existing_user_signed_out'
1164
1389
  ? 'Sign in to join this workspace.'
@@ -1169,15 +1394,17 @@ function TaskforceCoreWithRouter({ config = {}, initialTaskId, initialActivityEn
1169
1394
  || (authMode === 'invite' && inviteResolution === 'existing_user_signed_out')) && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Email" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "email", value: loginEmail, placeholder: "Email", autoComplete: "email", "data-testid": "auth-email-input", onChange: (event) => setLoginEmail(event.target.value) })] })), authMode === 'register' && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Display name" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: loginDisplayName, placeholder: "Display name", autoComplete: "nickname", "data-testid": "auth-display-name-input", onChange: (event) => setLoginDisplayName(event.target.value) })] })), (authMode === 'login'
1170
1395
  || authMode === 'register'
1171
1396
  || authMode === 'reset'
1172
- || (authMode === 'invite' && (invitePasswordRequired || inviteResolution === 'existing_user_signed_out'))) && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: authMode === 'reset'
1397
+ || (authMode === 'invite' && (invitePasswordRequired || inviteResolution === 'existing_user_signed_out'))) && (_jsxs("div", { className: authStyles.loginField, children: [_jsx("label", { className: authStyles.loginFieldLabel, htmlFor: "auth-password-input", children: authMode === 'reset'
1173
1398
  ? 'New password'
1174
- : (authMode === 'invite' && invitePasswordRequired ? 'Create password' : 'Password') }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "password", value: loginPassword, placeholder: authMode === 'reset'
1399
+ : (authMode === 'invite' && invitePasswordRequired ? 'Create password' : 'Password') }), _jsx(PasswordInput, { id: "auth-password-input", className: `${styles.input} ${authStyles.loginInput}`, value: loginPassword, placeholder: authMode === 'reset'
1175
1400
  ? 'New password'
1176
1401
  : (authMode === 'invite'
1177
1402
  ? (invitePasswordRequired ? 'Create password' : 'Password')
1178
1403
  : 'Password'), autoComplete: authMode === 'register' || authMode === 'reset' || (authMode === 'invite' && invitePasswordRequired)
1179
1404
  ? 'new-password'
1180
- : 'current-password', "data-testid": "auth-password-input", onChange: (event) => setLoginPassword(event.target.value) })] })), (authMode === 'register' || (authMode === 'invite' && invitePasswordRequired)) && (_jsx(_Fragment, { children: _jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Confirm password" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "password", value: loginPasswordConfirm, placeholder: "Confirm password", autoComplete: "new-password", "data-testid": "auth-confirm-password-input", onChange: (event) => setLoginPasswordConfirm(event.target.value) })] }) })), (authMode === 'register' || (authMode === 'invite' && invitePasswordRequired)) && (_jsx("p", { className: authStyles.loginSubtitle, children: registerPasswordGuidance.join(' ') })), authMode === 'verify' && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Verification token" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: verificationToken, placeholder: "Verification token", autoComplete: "one-time-code", "data-testid": "auth-verification-token-input", onChange: (event) => setVerificationToken(event.target.value) })] })), authMode === 'reset' && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Reset token" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: resetToken, placeholder: "Reset token", autoComplete: "one-time-code", "data-testid": "auth-reset-token-input", onChange: (event) => setResetToken(event.target.value) })] })), authMode === 'invite' && (_jsxs(_Fragment, { children: [_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Invite token" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: inviteToken, placeholder: "Invite token", "data-testid": "auth-invite-token-input", onChange: (event) => setInviteToken(event.target.value) })] }), inviteEmail && (_jsxs("p", { className: authStyles.loginSubtitle, children: ["Invite for: ", _jsx("strong", { children: inviteEmail }), inviteWorkspaceId ? ` · Workspace: ${inviteWorkspaceId}` : ''] }))] })), loginNotice && _jsx("p", { className: authStyles.loginSubtitle, children: loginNotice }), loginError && _jsx("p", { className: authStyles.loginError, children: loginError }), authMode === 'login' && loginErrorCode === 'EMAIL_NOT_VERIFIED' && loginEmail.trim() && (_jsx("button", { className: authStyles.authModeLink, disabled: loginBusy || verifyCooldownActive, onClick: async () => {
1405
+ : 'current-password', visibilityLabel: authMode === 'reset'
1406
+ ? 'new password'
1407
+ : (authMode === 'invite' && invitePasswordRequired ? 'new password' : 'password'), "data-testid": "auth-password-input", visibilityToggleTestId: "auth-password-visibility-toggle", onChange: (event) => setLoginPassword(event.target.value) }, `${authMode}-${invitePasswordRequired ? 'new' : 'current'}`)] })), (authMode === 'register' || authMode === 'reset' || (authMode === 'invite' && invitePasswordRequired)) && (_jsxs("div", { className: authStyles.loginField, children: [_jsx("label", { className: authStyles.loginFieldLabel, htmlFor: "auth-confirm-password-input", children: "Confirm password" }), _jsx(PasswordInput, { id: "auth-confirm-password-input", className: `${styles.input} ${authStyles.loginInput}`, value: loginPasswordConfirm, placeholder: "Confirm password", autoComplete: "new-password", visibilityLabel: "confirm password", "data-testid": "auth-confirm-password-input", visibilityToggleTestId: "auth-confirm-password-visibility-toggle", onChange: (event) => setLoginPasswordConfirm(event.target.value) }, `${authMode}-confirm`)] })), (authMode === 'register' || authMode === 'reset' || (authMode === 'invite' && invitePasswordRequired)) && (_jsx("p", { className: authStyles.loginSubtitle, children: registerPasswordGuidance.join(' ') })), authMode === 'verify' && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Verification token" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: verificationToken, placeholder: "Verification token", autoComplete: "one-time-code", "data-testid": "auth-verification-token-input", onChange: (event) => setVerificationToken(event.target.value) })] })), authMode === 'reset' && (_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Reset token" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: resetToken, placeholder: "Reset token", autoComplete: "one-time-code", "data-testid": "auth-reset-token-input", onChange: (event) => setResetToken(event.target.value) })] })), authMode === 'invite' && (_jsxs(_Fragment, { children: [_jsxs("label", { className: authStyles.loginField, children: [_jsx("span", { className: authStyles.loginFieldLabel, children: "Invite token" }), _jsx("input", { className: `${styles.input} ${authStyles.loginInput}`, type: "text", value: inviteToken, placeholder: "Invite token", "data-testid": "auth-invite-token-input", onChange: (event) => setInviteToken(event.target.value) })] }), inviteEmail && (_jsxs("p", { className: authStyles.loginSubtitle, children: ["Invite for: ", _jsx("strong", { children: inviteEmail }), inviteWorkspaceId ? ` · Workspace: ${inviteWorkspaceId}` : ''] }))] })), loginNotice && _jsx("p", { className: authStyles.loginSubtitle, children: loginNotice }), loginError && _jsx("p", { className: authStyles.loginError, role: "alert", children: loginError }), authMode === 'login' && loginErrorCode === 'EMAIL_NOT_VERIFIED' && loginEmail.trim() && (_jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy || verifyCooldownActive, onClick: async () => {
1181
1408
  setLoginBusy(true);
1182
1409
  setLoginNotice(null);
1183
1410
  const sent = await requestEmailVerification(loginEmail);
@@ -1194,227 +1421,7 @@ function TaskforceCoreWithRouter({ config = {}, initialTaskId, initialActivityEn
1194
1421
  setLoginError(formatAuthError(sent));
1195
1422
  }
1196
1423
  setLoginBusy(false);
1197
- }, children: verifyCooldownActive ? `Resend in ${verifyCooldownSeconds}s` : 'Resend Verification Email' })), _jsx("div", { className: authStyles.authPrimaryActions, role: "group", "aria-label": "Primary authentication action", children: _jsx("button", { className: `${styles.submitBtn} ${authStyles.loginPrimaryBtn}`, disabled: loginBusy || (authMode === 'forgot' && resetCooldownActive), "data-testid": "auth-submit-button", onClick: async () => {
1198
- setLoginBusy(true);
1199
- setLoginNotice(null);
1200
- setLoginError(null);
1201
- setLoginErrorCode(null);
1202
- if (authMode === 'register' && !loginDisplayName.trim()) {
1203
- setLoginError('Display name is required.');
1204
- setLoginBusy(false);
1205
- return;
1206
- }
1207
- if (authMode === 'register') {
1208
- const validation = validatePasswordPolicy(loginPassword, {
1209
- email: loginEmail,
1210
- displayName: loginDisplayName
1211
- });
1212
- if (!validation.ok) {
1213
- setLoginError(validation.message || 'Password does not meet the password policy.');
1214
- setLoginErrorCode(validation.code || null);
1215
- setLoginBusy(false);
1216
- return;
1217
- }
1218
- if (loginPassword !== loginPasswordConfirm) {
1219
- setLoginError('Passwords do not match.');
1220
- setLoginErrorCode('PASSWORD_CONFIRMATION_MISMATCH');
1221
- setLoginBusy(false);
1222
- return;
1223
- }
1224
- }
1225
- let result = { success: false };
1226
- if (authMode === 'login') {
1227
- result = await loginWithCredentials(loginEmail, loginPassword);
1228
- }
1229
- else if (authMode === 'register') {
1230
- result = await registerWithCredentials(loginEmail, loginPassword, {
1231
- displayName: loginDisplayName,
1232
- planId: selectedSignupPlanId || undefined,
1233
- planVersionId: selectedSignupPlanVersionId || undefined,
1234
- interval: selectedSignupInterval || undefined
1235
- });
1236
- }
1237
- else if (authMode === 'verify') {
1238
- result = await confirmEmailVerification(verificationToken);
1239
- }
1240
- else if (authMode === 'forgot') {
1241
- result = await requestPasswordReset(loginEmail);
1242
- }
1243
- else if (authMode === 'reset') {
1244
- result = await confirmPasswordReset(resetToken, loginPassword);
1245
- }
1246
- else if (authMode === 'invite') {
1247
- if (inviteResolution === 'existing_user_signed_out') {
1248
- result = await loginWithCredentials(loginEmail, loginPassword);
1249
- }
1250
- else {
1251
- result = invitePasswordRequired
1252
- ? await acceptInviteWithToken(inviteToken, loginPassword)
1253
- : await joinInviteWithToken(inviteToken);
1254
- }
1255
- }
1256
- if (!result.success) {
1257
- if (authMode === 'register'
1258
- && (result.code === 'SIGNUP_PLAN_NOT_ENABLED'
1259
- || result.code === 'SIGNUP_PLAN_VERSION_NOT_FOUND'
1260
- || result.code === 'SIGNUP_PLAN_VERSION_REQUIRED')) {
1261
- navigate(planSelectionPath, { replace: true });
1262
- setLoginBusy(false);
1263
- return;
1264
- }
1265
- setLoginError(formatAuthError(result));
1266
- setLoginErrorCode(result.code || null);
1267
- if (authMode === 'login' && (result.code === 'WORKSPACE_NOT_FOUND' || result.code === 'WORKSPACE_ID_REQUIRED')) {
1268
- navigate('/setup?step=workspace', { replace: true });
1269
- setLoginBusy(false);
1270
- return;
1271
- }
1272
- if (authMode === 'login' && result.code === 'EMAIL_NOT_VERIFIED' && loginEmail.trim()) {
1273
- const sent = await requestEmailVerification(loginEmail);
1274
- if (sent.success) {
1275
- setVerifyCooldownUntil(Date.now() + 30_000);
1276
- setLoginMode('verify');
1277
- if (sent.verificationToken)
1278
- setVerificationToken(sent.verificationToken);
1279
- setLoginNotice(buildVerificationRequestNotice({
1280
- ...sent,
1281
- intro: 'If that account exists and still needs verification, we sent an email.'
1282
- }));
1283
- setLoginError(null);
1284
- setLoginErrorCode(null);
1285
- }
1286
- }
1287
- if (authMode === 'register' && result.code === 'EMAIL_ALREADY_EXISTS_UNVERIFIED' && loginEmail.trim()) {
1288
- setVerifyCooldownUntil(Date.now() + 30_000);
1289
- setLoginMode('verify');
1290
- if (result.verificationToken)
1291
- setVerificationToken(result.verificationToken);
1292
- setLoginNotice(result.emailSent === false
1293
- ? `This email already has an unverified account, but verification email delivery failed. ${result.emailError || 'Try Resend Verification again.'}`
1294
- : 'This email already has an unverified account. Check your email for verification instructions.');
1295
- setLoginError(null);
1296
- setLoginErrorCode(null);
1297
- }
1298
- }
1299
- else if (authMode === 'register') {
1300
- const postRegistrationPath = resolvePostRegistrationPath(result);
1301
- const commercialOnboardingGate = hasCommercialOnboardingGate(result);
1302
- if (result.verificationRequired) {
1303
- setPendingVerificationWorkspaceSetupRequired(Boolean(result.workspaceSetupRequired));
1304
- setPendingVerificationCommercialState(commercialOnboardingGate
1305
- ? String(result.commercialState || '').trim() || (result.planSelectionRequired ? 'pending_plan_selection' : 'checkout_pending')
1306
- : null);
1307
- setPendingVerificationRedirectPath(postRegistrationPath);
1308
- if (result.verificationToken)
1309
- setVerificationToken(result.verificationToken);
1310
- setVerifyCooldownUntil(Date.now() + 30_000);
1311
- setLoginMode('verify');
1312
- setLoginNotice(result.emailSent === false
1313
- ? `Account created, but verification email failed to send. ${result.emailError || 'Try Resend Verification again.'}`
1314
- : 'Account created. Check your email for verification instructions.');
1315
- }
1316
- else {
1317
- setCommercialOnboardingRedirectActive(commercialOnboardingGate);
1318
- setPendingPostAuthRedirect({
1319
- path: postRegistrationPath,
1320
- workspaceSetupRequired: Boolean(result.workspaceSetupRequired),
1321
- commercialOnboardingGate
1322
- });
1323
- }
1324
- }
1325
- else if (authMode === 'verify') {
1326
- await retryBootstrapChecks();
1327
- const commercialOnboardingGate = pendingVerificationCommercialState === 'pending_plan_selection'
1328
- || pendingVerificationCommercialState === 'checkout_pending';
1329
- setCommercialOnboardingRedirectActive(commercialOnboardingGate);
1330
- setPendingPostAuthRedirect({
1331
- path: pendingVerificationRedirectPath || nextTarget,
1332
- workspaceSetupRequired: pendingVerificationWorkspaceSetupRequired,
1333
- commercialOnboardingGate
1334
- });
1335
- }
1336
- else if (authMode === 'forgot') {
1337
- const passwordResetDeliveryFailed = result.deliveryAttempted === true && result.emailSent === false;
1338
- if (result.resetToken)
1339
- setResetToken(result.resetToken);
1340
- setLoginNotice(buildPasswordResetNotice(result));
1341
- if (!passwordResetDeliveryFailed) {
1342
- setResetCooldownUntil(Date.now() + 30_000);
1343
- setLoginMode('reset');
1344
- }
1345
- }
1346
- else if (authMode === 'reset') {
1347
- setLoginMode('login');
1348
- setLoginNotice('Password updated. Sign in with your new password.');
1349
- }
1350
- else if (authMode === 'invite') {
1351
- if (inviteResolution === 'existing_user_signed_out') {
1352
- const normalizedInviteEmail = String(inviteEmail || '').trim().toLowerCase();
1353
- const normalizedLoginEmail = loginEmail.trim().toLowerCase();
1354
- // Make the invite flow deterministically join-ready as soon as
1355
- // the invited account signs in successfully, instead of waiting
1356
- // for a later invite inspection effect to catch up.
1357
- if (normalizedInviteEmail && normalizedLoginEmail === normalizedInviteEmail) {
1358
- setAuthMode('invite');
1359
- setInviteResolution('existing_user_ready');
1360
- setLoginPassword('');
1361
- setLoginPasswordConfirm('');
1362
- setLoginNotice('Signed in. Review the invite details to continue.');
1363
- setLoginError(null);
1364
- setLoginErrorCode(null);
1365
- setLoginBusy(false);
1366
- return;
1367
- }
1368
- if (normalizedInviteEmail) {
1369
- setLoginEmail(inviteEmail || '');
1370
- }
1371
- setInviteResolution('existing_user_signed_out');
1372
- setLoginPassword('');
1373
- setLoginPasswordConfirm('');
1374
- setLoginNotice(normalizedInviteEmail
1375
- ? `Signed in, but this invite is for ${inviteEmail}. Sign in with that account to continue.`
1376
- : 'Signed in, but this invite requires the invited account. Sign in with that account to continue.');
1377
- setLoginError('Sign in with the invited account to join this workspace.');
1378
- setLoginErrorCode('INVITE_ACCOUNT_MISMATCH');
1379
- setLoginBusy(false);
1380
- return;
1381
- }
1382
- if (result.workspaceSetupRequired) {
1383
- navigate(resolveWorkspaceSetupPath(), { replace: true });
1384
- setLoginBusy(false);
1385
- return;
1386
- }
1387
- navigateToPostAuthTarget(nextTarget, { replace: true });
1388
- }
1389
- else if (authMode === 'login') {
1390
- if (inviteToken.trim()) {
1391
- setAuthMode('invite');
1392
- setLoginPassword('');
1393
- setLoginPasswordConfirm('');
1394
- setLoginNotice('Signed in. Review the invite details to continue.');
1395
- setLoginBusy(false);
1396
- return;
1397
- }
1398
- if (result.workspaceSetupRequired) {
1399
- navigate(resolveWorkspaceSetupPath(), { replace: true });
1400
- setLoginBusy(false);
1401
- return;
1402
- }
1403
- setLoginEmail('');
1404
- setLoginDisplayName('');
1405
- setLoginPassword('');
1406
- setLoginPasswordConfirm('');
1407
- navigateToPostAuthTarget(nextTarget, { replace: true });
1408
- }
1409
- else {
1410
- setLoginEmail('');
1411
- setLoginDisplayName('');
1412
- setLoginPassword('');
1413
- setLoginPasswordConfirm('');
1414
- navigateToPostAuthTarget(nextTarget, { replace: true });
1415
- }
1416
- setLoginBusy(false);
1417
- }, children: loginBusy ? 'Working...' : (authMode === 'login' ? 'Sign In'
1424
+ }, children: verifyCooldownActive ? `Resend in ${verifyCooldownSeconds}s` : 'Resend Verification Email' })), _jsx("div", { className: authStyles.authPrimaryActions, role: "group", "aria-label": "Primary authentication action", children: _jsx("button", { type: "submit", className: `${styles.submitBtn} ${authStyles.loginPrimaryBtn}`, disabled: loginBusy || (authMode === 'forgot' && resetCooldownActive), "data-testid": "auth-submit-button", children: loginBusy ? 'Working...' : (authMode === 'login' ? 'Sign In'
1418
1425
  : authMode === 'register' ? 'Create Account'
1419
1426
  : authMode === 'verify' ? 'Verify Email'
1420
1427
  : authMode === 'forgot'
@@ -1423,12 +1430,12 @@ function TaskforceCoreWithRouter({ config = {}, initialTaskId, initialActivityEn
1423
1430
  ? 'Reset Password'
1424
1431
  : (inviteResolution === 'existing_user_signed_out'
1425
1432
  ? 'Sign In to Continue'
1426
- : (invitePasswordRequired ? 'Create Account and Join' : 'Join Workspace'))) }) }), (authMode === 'login' || authMode === 'register') && availableAuthProviders.length > 0 && (_jsxs("div", { className: authStyles.oauthProviders, children: [_jsx("div", { className: authStyles.oauthDivider, children: _jsx("span", { children: "or continue with" }) }), _jsxs("div", { className: authStyles.oauthButtons, children: [availableAuthProviders.includes('google') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('google', nextTarget), "aria-label": "Continue with Google", children: "Google" })), availableAuthProviders.includes('github') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('github', nextTarget), "aria-label": "Continue with GitHub", children: "GitHub" })), availableAuthProviders.includes('apple') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('apple', nextTarget), "aria-label": "Continue with Apple", children: "Apple" }))] })] })), authMode === 'invite' && inviteResolution === 'new_user' && inviteOAuthProviders.length > 0 && (_jsxs("div", { className: authStyles.oauthProviders, children: [_jsx("div", { className: authStyles.oauthDivider, children: _jsx("span", { children: "or join with" }) }), _jsxs("div", { className: authStyles.oauthButtons, children: [inviteOAuthProviders.includes('google') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('google', '/', inviteToken), "aria-label": "Join with Google", children: "Google" })), inviteOAuthProviders.includes('github') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('github', '/', inviteToken), "aria-label": "Join with GitHub", children: "GitHub" })), inviteOAuthProviders.includes('apple') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('apple', '/', inviteToken), "aria-label": "Join with Apple", children: "Apple" }))] })] })), authMode === 'register' && (_jsxs("p", { className: authStyles.registerConsent, children: ["By creating an account, you agree to the", ' ', _jsx("a", { className: authStyles.registerConsentLink, href: "https://taskforcehq.ai/legal/terms/", target: "_blank", rel: "noopener noreferrer", children: "Terms of Service" }), ' ', "and acknowledge the", ' ', _jsx("a", { className: authStyles.registerConsentLink, href: "https://taskforcehq.ai/legal/privacy/", target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }), "."] })), _jsxs("div", { className: authStyles.authSecondaryActions, role: "group", "aria-label": "Authentication navigation", children: [directRegistrationEnabled && (authMode === 'login' || authMode === 'register') && (_jsxs("p", { className: authStyles.authModeSwitch, children: [authMode === 'login' ? 'Need an account?' : 'Already have an account?', ' ', _jsx("button", { className: authStyles.authModeSwitchLink, disabled: loginBusy, "data-testid": "auth-switch-mode-button", onClick: () => {
1433
+ : (invitePasswordRequired ? 'Create Account and Join' : 'Join Workspace'))) }) }), (authMode === 'login' || authMode === 'register') && availableAuthProviders.length > 0 && (_jsxs("div", { className: authStyles.oauthProviders, children: [_jsx("div", { className: authStyles.oauthDivider, children: _jsx("span", { children: "or continue with" }) }), _jsxs("div", { className: authStyles.oauthButtons, children: [availableAuthProviders.includes('google') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('google', nextTarget), "aria-label": "Continue with Google", children: "Google" })), availableAuthProviders.includes('github') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('github', nextTarget), "aria-label": "Continue with GitHub", children: "GitHub" })), availableAuthProviders.includes('apple') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('apple', nextTarget), "aria-label": "Continue with Apple", children: "Apple" }))] })] })), authMode === 'invite' && inviteResolution === 'new_user' && inviteOAuthProviders.length > 0 && (_jsxs("div", { className: authStyles.oauthProviders, children: [_jsx("div", { className: authStyles.oauthDivider, children: _jsx("span", { children: "or join with" }) }), _jsxs("div", { className: authStyles.oauthButtons, children: [inviteOAuthProviders.includes('google') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('google', '/', inviteToken), "aria-label": "Join with Google", children: "Google" })), inviteOAuthProviders.includes('github') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('github', '/', inviteToken), "aria-label": "Join with GitHub", children: "GitHub" })), inviteOAuthProviders.includes('apple') && (_jsx("button", { type: "button", className: authStyles.oauthButton, disabled: loginBusy, onClick: () => beginOAuthLogin('apple', '/', inviteToken), "aria-label": "Join with Apple", children: "Apple" }))] })] })), authMode === 'register' && (_jsxs("p", { className: authStyles.registerConsent, children: ["By creating an account, you agree to the", ' ', _jsx("a", { className: authStyles.registerConsentLink, href: "https://taskforcehq.ai/legal/terms/", target: "_blank", rel: "noopener noreferrer", children: "Terms of Service" }), ' ', "and acknowledge the", ' ', _jsx("a", { className: authStyles.registerConsentLink, href: "https://taskforcehq.ai/legal/privacy/", target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }), "."] })), _jsxs("div", { className: authStyles.authSecondaryActions, role: "group", "aria-label": "Authentication navigation", children: [directRegistrationEnabled && (authMode === 'login' || authMode === 'register') && (_jsxs("p", { className: authStyles.authModeSwitch, children: [authMode === 'login' ? 'Need an account?' : 'Already have an account?', ' ', _jsx("button", { type: "button", className: authStyles.authModeSwitchLink, disabled: loginBusy, "data-testid": "auth-switch-mode-button", onClick: () => {
1427
1434
  setLoginError(null);
1428
1435
  setLoginErrorCode(null);
1429
1436
  setLoginNotice(null);
1430
1437
  setLoginMode(authMode === 'login' ? 'register' : 'login');
1431
- }, children: authMode === 'login' ? 'Register' : 'Sign In' })] })), _jsxs("div", { className: authStyles.authModeLinks, children: [(authMode === 'login' || authMode === 'register') && (_jsxs(_Fragment, { children: [_jsx("button", { className: authStyles.authModeLink, disabled: loginBusy || resetCooldownActive, "data-testid": "auth-forgot-password-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('forgot'); }, children: resetCooldownActive ? `Forgot Password (${resetCooldownSeconds}s)` : 'Forgot Password' }), _jsx("button", { className: authStyles.authModeLink, disabled: loginBusy || verifyCooldownActive, "data-testid": "auth-resend-verification-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('verify'); }, children: verifyCooldownActive ? `Resend Verification (${verifyCooldownSeconds}s)` : 'Resend Verification' }), _jsx("button", { className: authStyles.authModeLink, disabled: loginBusy, "data-testid": "auth-accept-invite-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('invite'); }, children: "Accept Invite" })] })), (authMode !== 'login' && authMode !== 'register') && (_jsxs(_Fragment, { children: [authMode === 'verify' && (_jsx("button", { className: authStyles.authModeLink, disabled: loginBusy || verifyCooldownActive || !loginEmail.trim(), "data-testid": "auth-resend-verification-button", onClick: async () => {
1438
+ }, children: authMode === 'login' ? 'Register' : 'Sign In' })] })), _jsxs("div", { className: authStyles.authModeLinks, children: [(authMode === 'login' || authMode === 'register') && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy || resetCooldownActive, "data-testid": "auth-forgot-password-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('forgot'); }, children: resetCooldownActive ? `Forgot Password (${resetCooldownSeconds}s)` : 'Forgot Password' }), _jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy || verifyCooldownActive, "data-testid": "auth-resend-verification-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('verify'); }, children: verifyCooldownActive ? `Resend Verification (${verifyCooldownSeconds}s)` : 'Resend Verification' }), _jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy, "data-testid": "auth-accept-invite-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('invite'); }, children: "Accept Invite" })] })), (authMode !== 'login' && authMode !== 'register') && (_jsxs(_Fragment, { children: [authMode === 'verify' && (_jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy || verifyCooldownActive || !loginEmail.trim(), "data-testid": "auth-resend-verification-button", onClick: async () => {
1432
1439
  setLoginBusy(true);
1433
1440
  setLoginNotice(null);
1434
1441
  setLoginError(null);
@@ -1444,7 +1451,7 @@ function TaskforceCoreWithRouter({ config = {}, initialTaskId, initialActivityEn
1444
1451
  setLoginError(formatAuthError(sent));
1445
1452
  }
1446
1453
  setLoginBusy(false);
1447
- }, children: verifyCooldownActive ? `Resend Verification (${verifyCooldownSeconds}s)` : 'Resend Verification' })), _jsx("button", { className: authStyles.authModeLink, disabled: loginBusy, "data-testid": "auth-return-sign-in-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('login'); }, children: authMode === 'verify' ? 'Back to Sign In' : 'Sign In' }), directRegistrationEnabled && authMode !== 'verify' && (_jsx("button", { className: authStyles.authModeLink, disabled: loginBusy, "data-testid": "auth-return-register-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('register'); }, children: "Register" })), authMode === 'reset' && (_jsx("button", { className: authStyles.authModeLink, disabled: loginBusy || resetCooldownActive, "data-testid": "auth-return-forgot-password-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('forgot'); }, children: resetCooldownActive ? `Forgot Password (${resetCooldownSeconds}s)` : 'Forgot Password' }))] }))] })] })] }) }) }));
1454
+ }, children: verifyCooldownActive ? `Resend Verification (${verifyCooldownSeconds}s)` : 'Resend Verification' })), _jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy, "data-testid": "auth-return-sign-in-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('login'); }, children: authMode === 'verify' ? 'Back to Sign In' : 'Sign In' }), directRegistrationEnabled && authMode !== 'verify' && (_jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy, "data-testid": "auth-return-register-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('register'); }, children: "Register" })), authMode === 'reset' && (_jsx("button", { type: "button", className: authStyles.authModeLink, disabled: loginBusy || resetCooldownActive, "data-testid": "auth-return-forgot-password-button", onClick: () => { setLoginError(null); setLoginErrorCode(null); setLoginNotice(null); setLoginMode('forgot'); }, children: resetCooldownActive ? `Forgot Password (${resetCooldownSeconds}s)` : 'Forgot Password' }))] }))] })] })] }) }) }));
1448
1455
  }
1449
1456
  if (shellRenderState === 'login-redirect') {
1450
1457
  return (_jsx("div", { className: shellStyles.standaloneWrapper, "data-theme": currentTheme, children: _jsx("div", { className: authStyles.loginView, children: _jsxs("div", { className: authStyles.loginCard, children: [_jsxs("div", { className: authStyles.authBrandRow, children: [_jsx("img", { src: authBrandLogo, alt: "Taskforce", className: authStyles.loginLogo }), _jsx("h1", { className: authStyles.loginTitle, children: "Loading Taskforce" })] }), _jsx("p", { className: authStyles.loginSubtitle, children: "Redirecting to sign in..." })] }) }) }));
@@ -249,7 +249,7 @@ export class AnnotatedAttachmentSessionStore {
249
249
  WHERE tenant_id = ?
250
250
  AND workspace_id = ?
251
251
  AND id = ?
252
- `).run(normalizeId(input.taskId) || existing.taskId, normalizeId(input.baseImageAssetId) || existing.baseImageAssetId, normalizeNullable(input.title), normalizeNullable(input.globalInstruction), JSON.stringify(Array.isArray(input.annotations) ? input.annotations : []), normalizeNullable(input.createdByActorId), normalizeNullable(input.updatedByActorId), normalizeId(input.createdAt) || existing.createdAt, normalizeId(input.updatedAt) || existing.updatedAt, normalizeNullable(input.deletedAt), this.tenantId, workspaceId, id);
252
+ `).run(normalizeId(input.taskId), normalizeId(input.baseImageAssetId) || existing.baseImageAssetId, normalizeNullable(input.title), normalizeNullable(input.globalInstruction), JSON.stringify(Array.isArray(input.annotations) ? input.annotations : []), normalizeNullable(input.createdByActorId), normalizeNullable(input.updatedByActorId), normalizeId(input.createdAt) || existing.createdAt, normalizeId(input.updatedAt) || existing.updatedAt, normalizeNullable(input.deletedAt), this.tenantId, workspaceId, id);
253
253
  return this.get(id, workspaceId, { includeDeleted: true });
254
254
  }
255
255
  update(input) {