@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
@@ -0,0 +1,197 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ const defaultFetch = (input, init) => globalThis.fetch(input, init);
3
+ export const TASK_DESCRIPTION_IMAGE_DRAFT_RECOVERY_STORAGE_KEY = 'taskforce.task-description-image-draft-recovery.v1';
4
+ const RETRY_DELAYS_MS = [1_000, 5_000, 15_000, 60_000];
5
+ const MAX_AUTOMATIC_RETRY_ATTEMPTS = 8;
6
+ const DORMANT_RETRY_AT = Number.MAX_SAFE_INTEGER;
7
+ export function taskDescriptionImageDraftRetryDelay(attempts) {
8
+ const index = Math.max(0, Math.min(RETRY_DELAYS_MS.length - 1, Math.floor(attempts) - 1));
9
+ return RETRY_DELAYS_MS[index];
10
+ }
11
+ function recordKey(record) {
12
+ return `${record.workspaceId}\u0000${record.createdByUserId}\u0000${record.draftUploadId}`;
13
+ }
14
+ function isRecoveryRecord(value) {
15
+ if (!value || typeof value !== 'object')
16
+ return false;
17
+ const record = value;
18
+ return typeof record.workspaceId === 'string'
19
+ && Boolean(record.workspaceId.trim())
20
+ && typeof record.createdByUserId === 'string'
21
+ && Boolean(record.createdByUserId.trim())
22
+ && typeof record.draftUploadId === 'string'
23
+ && Boolean(record.draftUploadId.trim())
24
+ && (record.resolution === 'promote' || record.resolution === 'discard')
25
+ && Number.isFinite(record.attempts)
26
+ && Number.isFinite(record.nextAttemptAt)
27
+ && Number.isFinite(record.createdAt);
28
+ }
29
+ function readRecoveryRecords(storage) {
30
+ if (!storage)
31
+ return [];
32
+ try {
33
+ const parsed = JSON.parse(storage.getItem(TASK_DESCRIPTION_IMAGE_DRAFT_RECOVERY_STORAGE_KEY) || '[]');
34
+ if (!Array.isArray(parsed))
35
+ return [];
36
+ const records = new Map();
37
+ parsed.filter(isRecoveryRecord).forEach((record) => {
38
+ records.set(recordKey(record), record);
39
+ });
40
+ return [...records.values()];
41
+ }
42
+ catch {
43
+ return [];
44
+ }
45
+ }
46
+ function writeRecoveryRecords(storage, records) {
47
+ if (!storage)
48
+ return;
49
+ try {
50
+ if (records.length === 0) {
51
+ storage.removeItem(TASK_DESCRIPTION_IMAGE_DRAFT_RECOVERY_STORAGE_KEY);
52
+ return;
53
+ }
54
+ storage.setItem(TASK_DESCRIPTION_IMAGE_DRAFT_RECOVERY_STORAGE_KEY, JSON.stringify(records));
55
+ }
56
+ catch {
57
+ // The request still gets an immediate attempt when browser storage is unavailable.
58
+ }
59
+ }
60
+ function updateRecoveryRecords(storage, update) {
61
+ const next = update(readRecoveryRecords(storage));
62
+ writeRecoveryRecords(storage, next);
63
+ return next;
64
+ }
65
+ function defaultStorage() {
66
+ try {
67
+ return globalThis.localStorage || null;
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ export function useTaskDescriptionImageDraftRecovery(workspaceId, createdByUserId, options = {}) {
74
+ const fetchImpl = options.fetchImpl || defaultFetch;
75
+ const storage = options.storage === undefined ? defaultStorage() : options.storage;
76
+ const now = options.now || Date.now;
77
+ const timerRef = useRef(null);
78
+ const inFlightRef = useRef(new Map());
79
+ const drainRef = useRef(async () => { });
80
+ const clearRetryTimer = useCallback(() => {
81
+ if (timerRef.current === null)
82
+ return;
83
+ clearTimeout(timerRef.current);
84
+ timerRef.current = null;
85
+ }, []);
86
+ const scheduleRetry = useCallback(() => {
87
+ clearRetryTimer();
88
+ const nextRecord = readRecoveryRecords(storage)
89
+ .filter((record) => (record.workspaceId === workspaceId
90
+ && record.createdByUserId === createdByUserId
91
+ && record.nextAttemptAt < DORMANT_RETRY_AT))
92
+ .sort((left, right) => left.nextAttemptAt - right.nextAttemptAt)[0];
93
+ if (!nextRecord)
94
+ return;
95
+ const delay = Math.max(0, nextRecord.nextAttemptAt - now());
96
+ timerRef.current = setTimeout(() => {
97
+ timerRef.current = null;
98
+ void drainRef.current(false);
99
+ }, delay);
100
+ }, [clearRetryTimer, createdByUserId, now, storage, workspaceId]);
101
+ const attemptRecovery = useCallback((record) => {
102
+ const key = recordKey(record);
103
+ const existing = inFlightRef.current.get(key);
104
+ if (existing)
105
+ return existing;
106
+ const request = (async () => {
107
+ await Promise.resolve();
108
+ try {
109
+ const response = await fetchImpl(`/api/taskforce/context-upload/draft/${record.resolution}`, {
110
+ method: 'POST',
111
+ headers: { 'Content-Type': 'application/json' },
112
+ body: JSON.stringify({
113
+ workspaceId: record.workspaceId,
114
+ draftUploadId: record.draftUploadId,
115
+ uploadPurpose: 'task-description-draft',
116
+ }),
117
+ });
118
+ if (!response.ok) {
119
+ throw new Error(`Draft upload ${record.resolution} was rejected (${response.status}).`);
120
+ }
121
+ updateRecoveryRecords(storage, (records) => (records.filter((candidate) => recordKey(candidate) !== key)));
122
+ }
123
+ catch (error) {
124
+ updateRecoveryRecords(storage, (records) => records.map((candidate) => {
125
+ if (recordKey(candidate) !== key)
126
+ return candidate;
127
+ const attempts = Math.min(Number.MAX_SAFE_INTEGER, candidate.attempts + 1);
128
+ return {
129
+ ...candidate,
130
+ attempts,
131
+ nextAttemptAt: attempts >= MAX_AUTOMATIC_RETRY_ATTEMPTS
132
+ ? DORMANT_RETRY_AT
133
+ : now() + taskDescriptionImageDraftRetryDelay(attempts),
134
+ };
135
+ }));
136
+ throw error;
137
+ }
138
+ finally {
139
+ inFlightRef.current.delete(key);
140
+ scheduleRetry();
141
+ }
142
+ })();
143
+ inFlightRef.current.set(key, request);
144
+ return request;
145
+ }, [fetchImpl, now, scheduleRetry, storage]);
146
+ const drain = useCallback(async (force = false) => {
147
+ const currentTime = now();
148
+ const dueRecords = readRecoveryRecords(storage).filter((record) => (record.workspaceId === workspaceId
149
+ && record.createdByUserId === createdByUserId
150
+ && (force || record.nextAttemptAt <= currentTime)));
151
+ await Promise.allSettled(dueRecords.map((record) => attemptRecovery(record)));
152
+ scheduleRetry();
153
+ }, [attemptRecovery, createdByUserId, now, scheduleRetry, storage, workspaceId]);
154
+ drainRef.current = drain;
155
+ useEffect(() => {
156
+ void drain(true);
157
+ const retryWhenOnline = () => { void drain(true); };
158
+ const retryWhenVisible = () => {
159
+ if (document.visibilityState === 'visible')
160
+ void drain(true);
161
+ };
162
+ const retryAfterStorageChange = (event) => {
163
+ if (event.key === TASK_DESCRIPTION_IMAGE_DRAFT_RECOVERY_STORAGE_KEY)
164
+ void drain(false);
165
+ };
166
+ window.addEventListener('online', retryWhenOnline);
167
+ window.addEventListener('storage', retryAfterStorageChange);
168
+ document.addEventListener('visibilitychange', retryWhenVisible);
169
+ return () => {
170
+ clearRetryTimer();
171
+ window.removeEventListener('online', retryWhenOnline);
172
+ window.removeEventListener('storage', retryAfterStorageChange);
173
+ document.removeEventListener('visibilitychange', retryWhenVisible);
174
+ };
175
+ }, [clearRetryTimer, drain]);
176
+ const resolveDraft = useCallback(async (input) => {
177
+ const draftUploadId = input.draftUploadId.trim();
178
+ if (!workspaceId || !createdByUserId || !draftUploadId)
179
+ return;
180
+ const queuedAt = now();
181
+ const record = {
182
+ workspaceId,
183
+ createdByUserId,
184
+ draftUploadId,
185
+ resolution: input.resolution,
186
+ attempts: 0,
187
+ nextAttemptAt: queuedAt,
188
+ createdAt: queuedAt,
189
+ };
190
+ updateRecoveryRecords(storage, (records) => [
191
+ ...records.filter((candidate) => recordKey(candidate) !== recordKey(record)),
192
+ record,
193
+ ]);
194
+ await attemptRecovery(record);
195
+ }, [attemptRecovery, createdByUserId, now, storage, workspaceId]);
196
+ return { resolveDraft };
197
+ }
@@ -1,5 +1,12 @@
1
1
  import type { AttachmentItem, CategoryConfig, ChecklistItem, Comment, TaskAssignee, TaskItem, TaskStatus, TaxonomyDefinition, WorkstreamItem } from '../../types';
2
2
  type TaskforceTab = 'add' | 'tasks' | 'settings';
3
+ type ApplyTaskOptions = {
4
+ preserveReturnTrail?: boolean;
5
+ adoptAsBaseline?: boolean;
6
+ };
7
+ type LoadTaskOptions = ApplyTaskOptions & {
8
+ shouldApply?: () => boolean;
9
+ };
3
10
  interface UseTaskEditorNavigationInput {
4
11
  activeCategories: CategoryConfig[];
5
12
  activeTypes: Array<{
@@ -10,6 +17,7 @@ interface UseTaskEditorNavigationInput {
10
17
  attachments: Array<string | AttachmentItem>;
11
18
  checklistItems: ChecklistItem[];
12
19
  comments: Comment[];
20
+ cancelTaskDetailLoad?: () => void;
13
21
  description: string;
14
22
  editingTaskId: string | null;
15
23
  flushPendingAutoSave: () => Promise<boolean>;
@@ -17,7 +25,12 @@ interface UseTaskEditorNavigationInput {
17
25
  getPreferredCategoryValue: (categories: CategoryConfig[]) => string;
18
26
  getTitleDraft?: () => string;
19
27
  lastUsedCategory: string;
28
+ loadTaskDetail?: (task: TaskItem, options?: {
29
+ shouldCommit?: () => boolean;
30
+ force?: boolean;
31
+ }) => Promise<TaskItem | null>;
20
32
  newCommentText: string;
33
+ onTaskApplied?: (task: TaskItem) => void;
21
34
  relationshipTasks: TaskItem[];
22
35
  workstreams: WorkstreamItem[];
23
36
  showArchive: boolean;
@@ -56,9 +69,9 @@ export declare function useTaskEditorNavigation(input: UseTaskEditorNavigationIn
56
69
  resetForm: () => void;
57
70
  resolveTaskIdInput: (value: string) => TaskItem | null;
58
71
  resolveWorkstreamIdInput: (value: string) => WorkstreamItem | null;
59
- handleEdit: (task: TaskItem, options?: {
60
- preserveReturnTrail?: boolean;
61
- }) => void;
72
+ handleEdit: (task: TaskItem, options?: ApplyTaskOptions) => void;
73
+ refreshTaskDetail: (task: TaskItem, options?: LoadTaskOptions) => Promise<TaskItem | null>;
74
+ applyTaskToEditor: (task: TaskItem, options?: ApplyTaskOptions) => void;
62
75
  handleOpenTaskById: (taskId: string) => void;
63
76
  returnToPreviousTask: () => boolean;
64
77
  clearReturnToParentTask: () => void;
@@ -1,17 +1,26 @@
1
- import { useCallback } from 'react';
1
+ import { useCallback, useRef } from 'react';
2
2
  import { DEFAULT_TYPE_VALUE } from '../../shared/taxonomyDefaults.js';
3
3
  import { getTaskReferenceLabel, parseTaskReference } from '../../utils/taskReferences';
4
4
  import { formatWorkstreamReference, parseWorkstreamReference } from '../../utils/planningReferences';
5
5
  import { buildDefaultFormTaxonomies } from '../../utils/taxonomyFormDefaults.js';
6
6
  export function useTaskEditorNavigation(input) {
7
- const { activeCategories, activeTypes, activeTab, attachments, checklistItems, comments, description, editingTaskId, flushPendingAutoSave, getDescriptionDraft, getPreferredCategoryValue, getTitleDraft, lastUsedCategory, newCommentText, relationshipTasks, workstreams, showArchive, taxonomies, setActiveTab, setAssignee, setAttachments, setAttachmentsDirty, setCategory, setChecklistItems, setComments, setComplexity, setDescription, setDueDate, setEditingTaskId, setError, setFormTaxonomies, setIsOpen, setNewCommentText, setPendingNavigation, setWorkstreamInput, setPriority, setScheduledDate, setShowArchive, setStatus, setTaskReturnTrail, setTitle, setType, setUnsavedModalOpen, taskReturnTrail, title, } = input;
7
+ const { activeCategories, activeTypes, activeTab, attachments, checklistItems, comments, cancelTaskDetailLoad, description, editingTaskId, flushPendingAutoSave, getDescriptionDraft, getPreferredCategoryValue, getTitleDraft, lastUsedCategory, loadTaskDetail, newCommentText, onTaskApplied, relationshipTasks, workstreams, showArchive, taxonomies, setActiveTab, setAssignee, setAttachments, setAttachmentsDirty, setCategory, setChecklistItems, setComments, setComplexity, setDescription, setDueDate, setEditingTaskId, setError, setFormTaxonomies, setIsOpen, setNewCommentText, setPendingNavigation, setWorkstreamInput, setPriority, setScheduledDate, setShowArchive, setStatus, setTaskReturnTrail, setTitle, setType, setUnsavedModalOpen, taskReturnTrail, title, } = input;
8
+ const editRequestSequenceRef = useRef(0);
9
+ const invalidatePendingEdit = useCallback(() => {
10
+ editRequestSequenceRef.current += 1;
11
+ cancelTaskDetailLoad?.();
12
+ }, [cancelTaskDetailLoad]);
8
13
  const getPreferredTypeValue = useCallback(() => {
9
14
  return activeTypes.find((entry) => String(entry.value || '').trim().length > 0)?.value || DEFAULT_TYPE_VALUE;
10
15
  }, [activeTypes]);
11
16
  const handleNavigation = useCallback(async (action) => {
17
+ const navigate = () => {
18
+ invalidatePendingEdit();
19
+ action();
20
+ };
12
21
  if (editingTaskId) {
13
22
  if (await flushPendingAutoSave()) {
14
- action();
23
+ navigate();
15
24
  }
16
25
  return;
17
26
  }
@@ -22,10 +31,10 @@ export function useTaskEditorNavigation(input) {
22
31
  comments.length > 0 ||
23
32
  attachments.length > 0;
24
33
  if (!hasChanges) {
25
- action();
34
+ navigate();
26
35
  return;
27
36
  }
28
- setPendingNavigation(() => action);
37
+ setPendingNavigation(() => navigate);
29
38
  setUnsavedModalOpen(true);
30
39
  }, [
31
40
  attachments,
@@ -36,15 +45,18 @@ export function useTaskEditorNavigation(input) {
36
45
  getDescriptionDraft,
37
46
  getTitleDraft,
38
47
  checklistItems,
48
+ invalidatePendingEdit,
39
49
  newCommentText,
40
50
  setPendingNavigation,
41
51
  setUnsavedModalOpen,
42
52
  title,
43
53
  ]);
44
54
  const handleClose = useCallback(() => {
55
+ invalidatePendingEdit();
45
56
  setIsOpen(false);
46
- }, [setIsOpen]);
57
+ }, [invalidatePendingEdit, setIsOpen]);
47
58
  const resetForm = useCallback(() => {
59
+ invalidatePendingEdit();
48
60
  setEditingTaskId(null);
49
61
  setTitle('');
50
62
  setDescription('');
@@ -76,6 +88,7 @@ export function useTaskEditorNavigation(input) {
76
88
  activeCategories,
77
89
  getPreferredCategoryValue,
78
90
  getPreferredTypeValue,
91
+ invalidatePendingEdit,
79
92
  lastUsedCategory,
80
93
  setAssignee,
81
94
  setAttachments,
@@ -134,7 +147,7 @@ export function useTaskEditorNavigation(input) {
134
147
  return exactTitle;
135
148
  return null;
136
149
  }, [workstreams]);
137
- const handleEdit = useCallback((task, options) => {
150
+ const applyTaskToEditor = useCallback((task, options) => {
138
151
  if (!options?.preserveReturnTrail) {
139
152
  setTaskReturnTrail([]);
140
153
  }
@@ -157,6 +170,8 @@ export function useTaskEditorNavigation(input) {
157
170
  setAttachments(task.attachments || []);
158
171
  setAttachmentsDirty(false);
159
172
  setActiveTab('add');
173
+ if (options?.adoptAsBaseline !== false)
174
+ onTaskApplied?.(task);
160
175
  }, [
161
176
  activeCategories,
162
177
  getPreferredCategoryValue,
@@ -179,20 +194,62 @@ export function useTaskEditorNavigation(input) {
179
194
  setTaskReturnTrail,
180
195
  setTitle,
181
196
  setType,
197
+ onTaskApplied,
182
198
  workstreams
183
199
  ]);
200
+ const loadAndApplyTask = useCallback(async (task, options) => {
201
+ const requestSequence = editRequestSequenceRef.current + 1;
202
+ editRequestSequenceRef.current = requestSequence;
203
+ if (!loadTaskDetail) {
204
+ cancelTaskDetailLoad?.();
205
+ applyTaskToEditor(task, { preserveReturnTrail: options?.preserveReturnTrail });
206
+ return task;
207
+ }
208
+ if (!task.isSummary) {
209
+ cancelTaskDetailLoad?.();
210
+ const detail = options?.shouldApply
211
+ ? await loadTaskDetail(task, { shouldCommit: options.shouldApply })
212
+ : await loadTaskDetail(task);
213
+ if (editRequestSequenceRef.current === requestSequence) {
214
+ const taskToApply = detail || task;
215
+ applyTaskToEditor(taskToApply, { preserveReturnTrail: options?.preserveReturnTrail });
216
+ return taskToApply;
217
+ }
218
+ return null;
219
+ }
220
+ const detail = options?.shouldApply
221
+ ? await loadTaskDetail(task, { shouldCommit: options.shouldApply })
222
+ : await loadTaskDetail(task);
223
+ if (detail
224
+ && editRequestSequenceRef.current === requestSequence) {
225
+ applyTaskToEditor(detail, { preserveReturnTrail: options?.preserveReturnTrail });
226
+ return detail;
227
+ }
228
+ return null;
229
+ }, [applyTaskToEditor, cancelTaskDetailLoad, loadTaskDetail]);
230
+ const handleEdit = useCallback((task, options) => {
231
+ void loadAndApplyTask(task, options);
232
+ }, [loadAndApplyTask]);
233
+ const refreshTaskDetail = useCallback((task, options) => loadAndApplyTask(task, options), [loadAndApplyTask]);
184
234
  const handleOpenTaskById = useCallback((taskId) => {
185
235
  const target = relationshipTasks.find((task) => task.id === taskId);
186
236
  if (!target)
187
237
  return;
238
+ const openTarget = () => {
239
+ if (activeTab === 'add' && editingTaskId && editingTaskId !== target.id) {
240
+ setTaskReturnTrail((prev) => prev[prev.length - 1] === editingTaskId ? prev : [...prev, editingTaskId]);
241
+ }
242
+ if (target.isArchived && !showArchive) {
243
+ setShowArchive(true);
244
+ }
245
+ handleEdit(target, { preserveReturnTrail: true });
246
+ };
188
247
  if (activeTab === 'add' && editingTaskId && editingTaskId !== target.id) {
189
- setTaskReturnTrail((prev) => prev[prev.length - 1] === editingTaskId ? prev : [...prev, editingTaskId]);
190
- }
191
- if (target.isArchived && !showArchive) {
192
- setShowArchive(true);
248
+ void handleNavigation(openTarget);
249
+ return;
193
250
  }
194
- handleEdit(target, { preserveReturnTrail: true });
195
- }, [activeTab, editingTaskId, handleEdit, relationshipTasks, setShowArchive, setTaskReturnTrail, showArchive]);
251
+ openTarget();
252
+ }, [activeTab, editingTaskId, handleEdit, handleNavigation, relationshipTasks, setShowArchive, setTaskReturnTrail, showArchive]);
196
253
  const returnToPreviousTask = useCallback(() => {
197
254
  if (activeTab !== 'add' || !editingTaskId || taskReturnTrail.length === 0)
198
255
  return false;
@@ -224,6 +281,8 @@ export function useTaskEditorNavigation(input) {
224
281
  resolveTaskIdInput,
225
282
  resolveWorkstreamIdInput,
226
283
  handleEdit,
284
+ refreshTaskDetail,
285
+ applyTaskToEditor,
227
286
  handleOpenTaskById,
228
287
  returnToPreviousTask,
229
288
  clearReturnToParentTask
@@ -1,6 +1,7 @@
1
1
  import type { AttachmentItem, CategoryConfig, ChecklistItem, TaskAssignee, TaskItem, TaskStatus, TaxonomyDefinition, WorkstreamItem } from '../../types';
2
2
  import type { DurableTaskCreateMutationAdapter } from '../sync/useDurableTaskCreateMutation.js';
3
3
  import { createCloudTaskHttpMutationClient } from './taskHttpMutation.js';
4
+ import type { TaskEditorDraft } from '../../utils/taskEditorReconciliation.js';
4
5
  interface UseTaskFormActionsInput {
5
6
  activeCategories: CategoryConfig[];
6
7
  activeTab: 'add' | 'tasks' | 'settings';
@@ -20,13 +21,18 @@ interface UseTaskFormActionsInput {
20
21
  taskHttpMutationClient?: ReturnType<typeof createCloudTaskHttpMutationClient>;
21
22
  updateTask?: (taskId: string, updates: Partial<TaskItem>) => Promise<boolean | void>;
22
23
  editingTaskId: string | null;
24
+ editorBaselineDraft?: TaskEditorDraft | null;
25
+ revisionConflict?: boolean;
23
26
  fetchTasks: (isSilent?: boolean) => Promise<void>;
24
27
  formTaxonomies: Record<string, string | number | string[] | number[]>;
28
+ getAttachmentsDraft?: () => Array<string | AttachmentItem>;
25
29
  getDescriptionDraft?: () => string;
26
30
  getPreferredCategoryValue: (categories: CategoryConfig[]) => string;
27
31
  getTitleDraft?: () => string;
32
+ awaitPendingDescriptionImageUpload?: () => Promise<void>;
28
33
  mergeTaskFromServer: (task: unknown) => void;
29
34
  onTaskCreated?: (task: TaskItem) => void;
35
+ onTaskCreateAccepted?: (task: TaskItem) => Promise<void> | void;
30
36
  workstreamInput: string;
31
37
  priority: number | string;
32
38
  pushNotice: (message: string, tone?: 'success' | 'error' | 'info') => void;
@@ -52,6 +58,9 @@ interface UseTaskFormActionsInput {
52
58
  export type TaskAutoSaveState = 'idle' | 'saving' | 'saved' | 'error';
53
59
  export declare function useTaskFormActions(input: UseTaskFormActionsInput): {
54
60
  autoSaveState: TaskAutoSaveState;
61
+ hasUnsavedChanges: boolean;
62
+ hasUnsavedChangesNow: () => boolean;
63
+ hasPendingAutoSave: boolean;
55
64
  flushAutoSave: () => Promise<boolean>;
56
65
  scheduleWarningPrompt: {
57
66
  dueDate: string;