@taskforcehq/taskforce 0.3.328 → 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 (264) hide show
  1. package/dist/Taskforce.module.css +233 -34
  2. package/dist/TaskforceCore.js +237 -230
  3. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
  4. package/dist/cli.js +34 -0
  5. package/dist/cliCloudTargetGuard.d.ts +5 -0
  6. package/dist/cliCloudTargetGuard.js +11 -0
  7. package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
  8. package/dist/components/features/TaskSettings.d.ts +12 -1
  9. package/dist/components/features/TaskSettings.js +147 -40
  10. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
  11. package/dist/components/features/planning/PlanningModule.js +2 -5
  12. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
  13. package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
  14. package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
  15. package/dist/components/features/planning/planningTaskArrangement.js +5 -5
  16. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  17. package/dist/components/task/TaskCard.d.ts +5 -0
  18. package/dist/components/task/TaskCard.js +65 -10
  19. package/dist/components/task/TaskImageReviews.js +14 -5
  20. package/dist/components/task/TaskKanban.d.ts +6 -1
  21. package/dist/components/task/TaskKanban.js +152 -6
  22. package/dist/components/task/TaskList.d.ts +5 -0
  23. package/dist/components/task/TaskList.js +3 -3
  24. package/dist/components/ui/PasswordInput.d.ts +6 -0
  25. package/dist/components/ui/PasswordInput.js +11 -0
  26. package/dist/components/ui/TopNoticeLayer.js +1 -1
  27. package/dist/components/views/AppShellHeader.js +32 -11
  28. package/dist/components/views/PlanComparisonPage.js +12 -0
  29. package/dist/components/views/StandaloneLayout.js +7 -31
  30. package/dist/components/views/WidgetView.js +3 -3
  31. package/dist/components/views/panels/PlanningDrawer.js +5 -12
  32. package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
  33. package/dist/config/envSchema.js +12 -0
  34. package/dist/config/localServiceRuntimeContract.d.ts +13 -0
  35. package/dist/config/localServiceRuntimeContract.js +135 -0
  36. package/dist/core/AiProfileService.js +46 -8
  37. package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
  38. package/dist/core/DeletedTaskLifecycleService.js +37 -6
  39. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
  40. package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
  41. package/dist/core/Taskforce.d.ts +62 -2
  42. package/dist/core/Taskforce.js +635 -32
  43. package/dist/core/types.d.ts +6 -0
  44. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
  45. package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
  46. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
  47. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
  48. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
  49. package/dist/hooks/tasks/taskHttpMutation.js +1 -0
  50. package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
  51. package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
  52. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
  53. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
  54. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
  55. package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
  56. package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
  57. package/dist/hooks/tasks/useTaskFormActions.js +65 -12
  58. package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
  59. package/dist/hooks/ui/useSettingsModel.js +13 -2
  60. package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
  61. package/dist/hooks/ui/useSettingsPersistence.js +74 -47
  62. package/dist/hooks/useFilterSort.d.ts +7 -3
  63. package/dist/hooks/useFilterSort.js +15 -5
  64. package/dist/hooks/useTaskData.d.ts +10 -1
  65. package/dist/hooks/useTaskData.js +216 -7
  66. package/dist/hooks/useTaskMutations.d.ts +10 -2
  67. package/dist/hooks/useTaskMutations.js +223 -43
  68. package/dist/hooks/useTaskforce.d.ts +37 -9
  69. package/dist/hooks/useTaskforce.js +349 -39
  70. package/dist/hooks/useUiNotice.d.ts +4 -0
  71. package/dist/hooks/useUiNotice.js +4 -0
  72. package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
  73. package/dist/mcp/documentAssetRegistrar.js +44 -35
  74. package/dist/mcp/documentHelpers.d.ts +1 -0
  75. package/dist/mcp/documentHelpers.js +7 -3
  76. package/dist/mcp/runtime.js +172 -42
  77. package/dist/mcp/taskPlanningRegistrar.js +41 -38
  78. package/dist/mcp/toolCallCompatibility.js +38 -1
  79. package/dist/mcp/toolCatalog.d.ts +1 -0
  80. package/dist/migrations/taskSchemaMigrations.js +12 -0
  81. package/dist/runtime/appGateDefinitions.d.ts +30 -6
  82. package/dist/runtime/appGateDefinitions.js +6 -6
  83. package/dist/runtime/appGates.d.ts +12 -13
  84. package/dist/runtime/appGates.js +29 -13
  85. package/dist/runtime/nodeAppGates.d.ts +8 -0
  86. package/dist/runtime/nodeAppGates.js +27 -0
  87. package/dist/server/cloudCollectionRead.d.ts +1 -1
  88. package/dist/server/cloudCollectionRead.js +2 -2
  89. package/dist/server/index.d.ts +3 -0
  90. package/dist/server/index.js +15 -3
  91. package/dist/server/localServiceLease.d.ts +3 -0
  92. package/dist/server/localServiceLease.js +9 -1
  93. package/dist/server/localWorkspaceSyncServerRuntime.js +10 -3
  94. package/dist/server/rateLimit.d.ts +1 -0
  95. package/dist/server/rateLimit.js +4 -0
  96. package/dist/server/realtimeSyncWs.js +36 -12
  97. package/dist/server/routes/admin.js +1 -0
  98. package/dist/server/routes/agentRoles.js +3 -2
  99. package/dist/server/routes/agentSkills.js +3 -2
  100. package/dist/server/routes/agents.js +118 -16
  101. package/dist/server/routes/annotatedAttachments.js +3 -2
  102. package/dist/server/routes/auth.js +3 -1
  103. package/dist/server/routes/durableTaskHttpRouters.d.ts +9 -2
  104. package/dist/server/routes/localService.js +2 -0
  105. package/dist/server/routes/primitives.d.ts +2 -0
  106. package/dist/server/routes/syncAuxRoutes.js +5 -2
  107. package/dist/server/routes/syncPullApplyRoutes.js +23 -4
  108. package/dist/server/routes/syncV3FeedRoutes.js +18 -16
  109. package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
  110. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
  111. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
  112. package/dist/server/routes/syncV3OperationRoutes.js +10 -0
  113. package/dist/server/routes/tasks.js +103 -11
  114. package/dist/server/routes/workspaces.js +43 -1
  115. package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
  116. package/dist/server/workspaceDeletionAdmission.js +50 -0
  117. package/dist/service/localServiceCli.js +16 -0
  118. package/dist/service/localServiceClientLifecycle.js +36 -10
  119. package/dist/services/codexAppServerModelGateway.d.ts +112 -0
  120. package/dist/services/codexAppServerModelGateway.js +438 -0
  121. package/dist/services/taskforceAgentMcpBridge.d.ts +7 -1
  122. package/dist/services/taskforceAgentMcpBridge.js +23 -3
  123. package/dist/shared/taskforceAgentDefinition.js +7 -1
  124. package/dist/shared/taskforceAgentModels.d.ts +1 -0
  125. package/dist/shared/taskforceAgentModels.js +30 -1
  126. package/dist/storage/postgresAdapter.d.ts +20 -3
  127. package/dist/storage/postgresAdapter.js +106 -14
  128. package/dist/storage/postgresWorker.js +13 -4
  129. package/dist/storage/postgresWorkerProtocol.d.ts +29 -0
  130. package/dist/storage/postgresWorkerProtocol.js +30 -0
  131. package/dist/sync/cloudSyncApi.d.ts +4 -1
  132. package/dist/sync/cloudSyncApi.js +7 -2
  133. package/dist/sync/contentSyncState.d.ts +1 -1
  134. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
  135. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +7 -1
  136. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
  137. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
  138. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
  139. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
  140. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +11 -0
  141. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
  142. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
  143. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
  144. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +25 -8
  145. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
  146. package/dist/sync/engine/workspaceSyncEngineTransfers.js +8 -3
  147. package/dist/sync/syncService.d.ts +2 -0
  148. package/dist/sync/syncService.js +4 -1
  149. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  150. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +2 -0
  151. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +11 -1
  152. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -0
  153. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +4 -0
  154. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
  155. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
  156. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
  157. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +27 -2
  158. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +2 -0
  159. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
  160. package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
  161. package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
  162. package/dist/sync/v3/localTaskMetadataClient.js +1 -0
  163. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
  164. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
  165. package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
  166. package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
  167. package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
  168. package/dist/sync/v3/localTaskStatusClient.js +6 -1
  169. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +2 -0
  170. package/dist/sync/v3/localTaskStatusOutboxService.js +54 -13
  171. package/dist/sync/v3/syncDurabilityStore.d.ts +7 -0
  172. package/dist/sync/v3/syncDurabilityStore.js +31 -11
  173. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
  174. package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
  175. package/dist/sync/v3/taskChecklistMutationService.d.ts +4 -2
  176. package/dist/sync/v3/taskChecklistMutationService.js +4 -0
  177. package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
  178. package/dist/sync/v3/taskCreateMutationService.js +7 -4
  179. package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
  180. package/dist/sync/v3/taskMetadataMutationService.js +4 -0
  181. package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
  182. package/dist/sync/v3/taskRestoreMutationService.js +7 -4
  183. package/dist/sync/v3/taskStatusMutationService.d.ts +2 -0
  184. package/dist/sync/v3/taskStatusMutationService.js +4 -0
  185. package/dist/sync/v3/workflowAssignmentSync.d.ts +1 -0
  186. package/dist/sync/v3/workflowAssignmentSync.js +3 -0
  187. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
  188. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
  189. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
  190. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
  191. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
  192. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
  193. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -1
  194. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
  195. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
  196. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
  197. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +30 -18
  198. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -4
  199. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +98 -47
  200. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  201. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +58 -21
  202. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +3 -1
  203. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +18 -0
  204. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  205. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
  206. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
  207. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
  208. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
  209. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
  210. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
  211. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
  212. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
  213. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
  214. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
  215. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
  216. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +2 -0
  217. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +2 -0
  218. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +19 -7
  219. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
  220. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
  221. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
  222. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
  223. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
  224. package/dist/sync/workspacePullFeed.js +2 -1
  225. package/dist/sync/workspaceRepair.d.ts +3 -0
  226. package/dist/sync/workspaceRepair.js +67 -6
  227. package/dist/types.d.ts +47 -1
  228. package/dist/types.js +6 -0
  229. package/dist/ui/assets/{AiIdentityRosterCard-MZs7lVED.js → AiIdentityRosterCard-BZM4aQnM.js} +1 -1
  230. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +1 -0
  231. package/dist/ui/assets/AnnotatedAttachmentWorkspace-B68Wg-RV.js +3 -0
  232. package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
  233. package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-C8Rztyal.js} +1 -1
  234. package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Cj3c7X9y.js} +2 -2
  235. package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-B5uvzems.js} +1 -1
  236. package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-BVFvCB5R.js} +1 -1
  237. package/dist/ui/assets/PlanningModule-B5DWQOGz.js +1 -0
  238. package/dist/ui/assets/PlansPage-AY4cGWco.js +1 -0
  239. package/dist/ui/assets/TaskContextUpload-DZxTVesW.js +1 -0
  240. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +12 -0
  241. package/dist/ui/assets/{TaskforceAgentsModule-BazdUwxZ.js → TaskforceAgentsModule-BifCYtjR.js} +6 -6
  242. package/dist/ui/assets/{WorkflowManagerModule-DWFspC-o.js → WorkflowManagerModule-DEr5di_r.js} +1 -1
  243. package/dist/ui/assets/index-I5zhdtgt.js +7 -0
  244. package/dist/ui/assets/index-VRFsx3wz.css +1 -0
  245. package/dist/ui/assets/{vendor-icons-BkFLXavV.js → vendor-icons-D9Lpw-j4.js} +1 -1
  246. package/dist/ui/index.html +3 -3
  247. package/dist/utils/taskActivity.d.ts +3 -2
  248. package/dist/utils/taskActivity.js +19 -2
  249. package/dist/utils/taskEditorReconciliation.d.ts +40 -0
  250. package/dist/utils/taskEditorReconciliation.js +217 -0
  251. package/dist/utils/taskNormalization.d.ts +1 -0
  252. package/dist/utils/taskNormalization.js +39 -0
  253. package/dist/utils/taskSearch.js +2 -2
  254. package/dist/utils/uiNotice.d.ts +4 -0
  255. package/package.json +16 -4
  256. package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
  257. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
  258. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
  259. package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
  260. package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
  261. package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
  262. package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
  263. package/dist/ui/assets/index-BUplSsv_.js +0 -7
  264. package/dist/ui/assets/index-gz2EXuoK.css +0 -1
@@ -36,11 +36,12 @@ function taskHttpObservedPrecondition(task, taskId) {
36
36
  return {
37
37
  taskId,
38
38
  updatedAt: task?.updatedAt ?? null,
39
+ detailRevision: task?.detailRevision ?? null,
39
40
  status: task?.status ?? null,
40
41
  isArchived: task?.isArchived === true,
41
42
  };
42
43
  }
43
- export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks, setArchivedTasks, setDeletedTasks, setError, resetForm, setActiveTab, fetchTasks, fetchArchive, fetchDeletedTasks, mergeTaskFromServer, pushNotice, cloudAuthConfigured, runtimeMode, isAuthenticated, workspaceCloudSyncEnabled, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, workspacePendingSignatureRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, mutateTaskMetadata, mutateTaskStatus, mutateTaskLifecycle, mutateTaskDelete, mutateTaskRestore, durableTaskMetadataActivationEnabled = false, durableTaskStatusActivationEnabled = false, durableTaskDeleteActivationEnabled = false, durableTaskHttpRootActivationEnabled = false, workspaceId = 'default', taskHttpMutationClient, }) {
44
+ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, editingTaskDetailRevision = null, setTasks, setArchivedTasks, setDeletedTasks, setError, resetForm, setActiveTab, fetchTasks, fetchArchive, fetchDeletedTasks, mergeTaskFromServer, pushNotice, cloudAuthConfigured, runtimeMode, isAuthenticated, workspaceCloudSyncEnabled, buildWorkspaceSyncSignature, pushWorkspaceChangesToCloud, workspacePendingSignatureRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, mutateTaskMetadata, mutateTaskStatus, mutateTaskLifecycle, mutateTaskDelete, mutateTaskRestore, durableTaskMetadataActivationEnabled = false, durableTaskStatusActivationEnabled = false, durableTaskDeleteActivationEnabled = false, durableTaskHttpRootActivationEnabled = false, workspaceId = 'default', taskHttpMutationClient, onTaskRevisionConflict, onTaskMutationAccepted, }) {
44
45
  const authoritativeTaskSnapshotsRef = useRef(new Map());
45
46
  useEffect(() => {
46
47
  if (typeof window === 'undefined')
@@ -418,8 +419,10 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
418
419
  pushNotice(message, 'error');
419
420
  return true;
420
421
  }
421
- if ('task' in result && result.task)
422
+ if ('task' in result && result.task) {
422
423
  mergeTaskFromServer(result.task);
424
+ onTaskMutationAccepted?.(result.task);
425
+ }
423
426
  if (result.state === 'accepted') {
424
427
  setError('');
425
428
  }
@@ -441,8 +444,10 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
441
444
  pushNotice(message, 'error');
442
445
  }
443
446
  return true;
444
- }, [mergeTaskFromServer, pushNotice, setArchivedTasks, setError, setTasks]);
445
- const handleSetStatus = useCallback(async (task, status, updates = {}) => {
447
+ }, [mergeTaskFromServer, onTaskMutationAccepted, pushNotice, setArchivedTasks, setError, setTasks]);
448
+ const handleSetStatus = useCallback(async (task, status, updates = {}, expectedDetailRevisionOverride) => {
449
+ const expectedDetailRevision = expectedDetailRevisionOverride
450
+ ?? (task.id === editingTaskId ? editingTaskDetailRevision : null);
446
451
  const containsDurableMetadata = Object.keys(updates)
447
452
  .some((key) => DURABLE_TASK_METADATA_FIELD_NAMES.has(key));
448
453
  const unsupportedFields = Object.keys(updates).filter((key) => (!TASK_STATUS_CONTROL_FIELDS.has(key) && !DURABLE_TASK_METADATA_FIELD_NAMES.has(key)));
@@ -468,17 +473,55 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
468
473
  setArchivedTasks((current) => current.map((item) => item.id === task.id ? { ...item, ...optimisticPatch } : item));
469
474
  if (mutateTaskStatus) {
470
475
  try {
471
- const assigneeIntent = Object.prototype.hasOwnProperty.call(updates, 'assignee')
472
- ? { kind: 'set', value: updates.assignee ?? null }
473
- : { kind: 'preserve' };
474
- const metadataPatch = selectDurableTaskMetadataPatch(updates);
475
- delete metadataPatch.assignee;
476
- const durableResult = await mutateTaskStatus(task.id, {
477
- status,
478
- assigneeIntent,
479
- canceledReason: status === 'cancelled' ? (updates.canceledReason ?? null) : null,
480
- metadataPatch,
481
- });
476
+ const buildDurablePayload = (targetStatus, targetUpdates, detailRevision) => {
477
+ const assigneeIntent = Object.prototype.hasOwnProperty.call(targetUpdates, 'assignee')
478
+ ? { kind: 'set', value: targetUpdates.assignee ?? null }
479
+ : { kind: 'preserve' };
480
+ const metadataPatch = selectDurableTaskMetadataPatch(targetUpdates);
481
+ delete metadataPatch.assignee;
482
+ return {
483
+ status: targetStatus,
484
+ assigneeIntent,
485
+ canceledReason: targetStatus === 'cancelled'
486
+ ? (targetUpdates.canceledReason ?? null)
487
+ : null,
488
+ metadataPatch,
489
+ ...(detailRevision ? { expectedDetailRevision: detailRevision } : {}),
490
+ };
491
+ };
492
+ let durableResult = await mutateTaskStatus(task.id, buildDurablePayload(status, updates, expectedDetailRevision));
493
+ if (durableResult
494
+ && (durableResult.state === 'rejected' || durableResult.state === 'failed')
495
+ && durableResult.errorCode === 'TASK_DETAIL_REVISION_CONFLICT') {
496
+ const previousTask = previousTasks.find((item) => item.id === task.id)
497
+ || previousArchivedTasks.find((item) => item.id === task.id);
498
+ setTasks((current) => rollbackTargetTaskPatch(current, previousTask, task.id, optimisticPatch));
499
+ setArchivedTasks((current) => rollbackTargetTaskPatch(current, previousTask, task.id, optimisticPatch));
500
+ const resolution = await onTaskRevisionConflict?.(task.id, null);
501
+ if (resolution?.retryDetailRevision) {
502
+ const retryPatch = Object.fromEntries(Object.entries(updates).map(([key, value]) => [
503
+ key,
504
+ resolution.retryPatch && Object.prototype.hasOwnProperty.call(resolution.retryPatch, key)
505
+ ? resolution.retryPatch[key]
506
+ : value,
507
+ ]));
508
+ const retryStatus = (resolution.retryPatch?.status || status);
509
+ durableResult = await mutateTaskStatus(task.id, buildDurablePayload(retryStatus, retryPatch, resolution.retryDetailRevision));
510
+ if (durableResult
511
+ && (durableResult.state === 'rejected' || durableResult.state === 'failed')
512
+ && durableResult.errorCode === 'TASK_DETAIL_REVISION_CONFLICT') {
513
+ const secondResolution = await onTaskRevisionConflict?.(task.id, null);
514
+ if (secondResolution?.handled) {
515
+ setError('');
516
+ return;
517
+ }
518
+ }
519
+ }
520
+ else if (resolution?.handled) {
521
+ setError('');
522
+ return;
523
+ }
524
+ }
482
525
  if (durableResult && finishDurableTaskMutation(durableResult, task.id, optimisticPatch, previousTasks, previousArchivedTasks))
483
526
  return;
484
527
  if (!durableResult && durableTaskStatusActivationEnabled) {
@@ -515,15 +558,54 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
515
558
  return;
516
559
  }
517
560
  try {
518
- const legacyPatch = { ...updates, status, completedAt: optimisticPatch.completedAt };
519
- const requestInit = {
520
- method: 'PATCH',
521
- headers: { 'Content-Type': 'application/json' },
522
- body: JSON.stringify(legacyPatch),
561
+ const legacyPatch = {
562
+ ...updates,
563
+ status,
564
+ completedAt: optimisticPatch.completedAt,
565
+ ...(expectedDetailRevision ? { expectedDetailRevision } : {}),
523
566
  };
524
- const res = await fetchCloudTaskRootPatch(`/api/taskforce/task/${task.id}`, requestInit, legacyPatch, task.id, taskHttpObservedPrecondition(task, task.id));
567
+ let activePatch = legacyPatch;
568
+ let res;
569
+ let data = {};
570
+ for (let attempt = 0;; attempt += 1) {
571
+ res = await fetchCloudTaskRootPatch(`/api/taskforce/task/${task.id}`, {
572
+ method: 'PATCH',
573
+ headers: { 'Content-Type': 'application/json' },
574
+ body: JSON.stringify(activePatch),
575
+ }, activePatch, task.id, taskHttpObservedPrecondition(task, task.id));
576
+ if (res.ok)
577
+ break;
578
+ data = await res.json().catch(() => ({}));
579
+ if (data.code !== 'TASK_DETAIL_REVISION_CONFLICT')
580
+ break;
581
+ setTasks(previousTasks);
582
+ setArchivedTasks(previousArchivedTasks);
583
+ const currentDetailRevision = typeof data?.details?.currentDetailRevision === 'string'
584
+ ? data.details.currentDetailRevision
585
+ : null;
586
+ const resolution = await onTaskRevisionConflict?.(task.id, currentDetailRevision);
587
+ if (attempt === 0 && resolution?.retryDetailRevision) {
588
+ const retryPatch = Object.fromEntries(Object.entries(legacyPatch).map(([key, value]) => [
589
+ key,
590
+ resolution.retryPatch && Object.prototype.hasOwnProperty.call(resolution.retryPatch, key)
591
+ ? resolution.retryPatch[key]
592
+ : value,
593
+ ]));
594
+ activePatch = {
595
+ ...retryPatch,
596
+ expectedDetailRevision: resolution.retryDetailRevision,
597
+ };
598
+ continue;
599
+ }
600
+ if (resolution?.handled) {
601
+ setError('');
602
+ return;
603
+ }
604
+ break;
605
+ }
525
606
  if (!res.ok) {
526
- const data = await res.json().catch(() => ({}));
607
+ if (Object.keys(data).length === 0)
608
+ data = await res.json().catch(() => ({}));
527
609
  const message = data.error || 'Failed to update task status.';
528
610
  setError(message);
529
611
  pushNotice(message, 'error');
@@ -532,8 +614,10 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
532
614
  return;
533
615
  }
534
616
  const updatedTask = await res.json().catch(() => null);
535
- if (updatedTask)
617
+ if (updatedTask) {
536
618
  mergeTaskFromServer(updatedTask);
619
+ onTaskMutationAccepted?.(updatedTask);
620
+ }
537
621
  else
538
622
  await fetchTasks(true);
539
623
  queueWorkspaceSyncFromAuthoritativeTaskState();
@@ -549,6 +633,8 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
549
633
  }, [
550
634
  archivedTasks,
551
635
  durableTaskMetadataActivationEnabled,
636
+ editingTaskDetailRevision,
637
+ editingTaskId,
552
638
  durableTaskHttpRootActivationEnabled,
553
639
  durableTaskStatusActivationEnabled,
554
640
  fetchTasks,
@@ -556,6 +642,8 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
556
642
  finishDurableTaskMutation,
557
643
  mergeTaskFromServer,
558
644
  mutateTaskStatus,
645
+ onTaskMutationAccepted,
646
+ onTaskRevisionConflict,
559
647
  pushNotice,
560
648
  queueWorkspaceSyncFromAuthoritativeTaskState,
561
649
  setArchivedTasks,
@@ -564,8 +652,14 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
564
652
  tasks,
565
653
  ]);
566
654
  const handleUpdateTask = useCallback(async (id, updates) => {
567
- const saveSource = updates.saveSource;
568
- updates = Object.fromEntries(Object.entries(updates).filter(([key]) => key !== 'saveSource'));
655
+ const specialFields = updates;
656
+ const saveSource = specialFields.saveSource;
657
+ const expectedDetailRevision = typeof specialFields.expectedDetailRevision === 'string'
658
+ ? specialFields.expectedDetailRevision
659
+ : id === editingTaskId
660
+ ? editingTaskDetailRevision
661
+ : null;
662
+ updates = Object.fromEntries(Object.entries(updates).filter(([key]) => (key !== 'saveSource' && key !== 'expectedDetailRevision')));
569
663
  if (Object.keys(updates).length === 0)
570
664
  return true;
571
665
  const authoritativeTask = authoritativeTaskSnapshotsRef.current.get(id);
@@ -589,7 +683,7 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
589
683
  if (updates.status) {
590
684
  const target = tasks.find((task) => task.id === id) || archivedTasks.find((task) => task.id === id);
591
685
  if (target) {
592
- await handleSetStatus(target, updates.status, updates);
686
+ await handleSetStatus(target, updates.status, updates, expectedDetailRevision);
593
687
  return;
594
688
  }
595
689
  if (durableTaskStatusActivationEnabled) {
@@ -610,10 +704,58 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
610
704
  let durableMetadataHandled = false;
611
705
  if (hasDurableMetadata && mutateTaskMetadata) {
612
706
  try {
613
- const durableResult = saveSource
614
- ? await mutateTaskMetadata(id, durableMetadataPatch, { saveSource })
707
+ const initialMutationOptions = {
708
+ ...(saveSource ? { saveSource } : {}),
709
+ ...(expectedDetailRevision ? { expectedDetailRevision } : {}),
710
+ };
711
+ let durableResult = Object.keys(initialMutationOptions).length > 0
712
+ ? await mutateTaskMetadata(id, durableMetadataPatch, initialMutationOptions)
615
713
  : await mutateTaskMetadata(id, durableMetadataPatch);
616
714
  if (durableResult && durableResult.state !== 'disabled') {
715
+ if ((durableResult.state === 'rejected' || durableResult.state === 'failed')
716
+ && durableResult.errorCode === 'TASK_DETAIL_REVISION_CONFLICT') {
717
+ const previousTask = previousTasks.find((task) => task.id === id)
718
+ || previousArchivedTasks.find((task) => task.id === id);
719
+ setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
720
+ setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
721
+ const resolution = await onTaskRevisionConflict?.(id, null);
722
+ if (resolution?.retryDetailRevision) {
723
+ const reconciledPatch = resolution.retryPatch;
724
+ const retryMetadataPatch = Object.fromEntries(Object.entries(durableMetadataPatch).map(([key, value]) => [
725
+ key,
726
+ reconciledPatch && Object.prototype.hasOwnProperty.call(reconciledPatch, key)
727
+ ? reconciledPatch[key]
728
+ : value,
729
+ ]));
730
+ durableResult = await mutateTaskMetadata(id, retryMetadataPatch, {
731
+ ...(saveSource ? { saveSource } : {}),
732
+ expectedDetailRevision: resolution.retryDetailRevision,
733
+ });
734
+ if (durableResult
735
+ && (durableResult.state === 'rejected' || durableResult.state === 'failed')
736
+ && durableResult.errorCode === 'TASK_DETAIL_REVISION_CONFLICT') {
737
+ const secondResolution = await onTaskRevisionConflict?.(id, null);
738
+ if (secondResolution?.handled) {
739
+ setError('');
740
+ return false;
741
+ }
742
+ }
743
+ }
744
+ else if (resolution?.handled) {
745
+ setError('');
746
+ return false;
747
+ }
748
+ }
749
+ if (!durableResult || durableResult.state === 'disabled') {
750
+ const previousTask = previousTasks.find((task) => task.id === id)
751
+ || previousArchivedTasks.find((task) => task.id === id);
752
+ setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
753
+ setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, updates));
754
+ const message = 'Task was not saved because durable metadata capture became unavailable during retry.';
755
+ setError(message);
756
+ pushNotice(message, 'error');
757
+ return false;
758
+ }
617
759
  if (durableResult.state === 'rejected' || durableResult.state === 'failed') {
618
760
  const previousTask = previousTasks.find((task) => task.id === id)
619
761
  || previousArchivedTasks.find((task) => task.id === id);
@@ -629,8 +771,10 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
629
771
  return false;
630
772
  }
631
773
  durableMetadataHandled = true;
632
- if ('task' in durableResult && durableResult.task)
774
+ if ('task' in durableResult && durableResult.task) {
633
775
  mergeTaskFromServer(durableResult.task);
776
+ onTaskMutationAccepted?.(durableResult.task);
777
+ }
634
778
  if (durableResult.state === 'accepted') {
635
779
  setError('');
636
780
  }
@@ -708,32 +852,68 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
708
852
  const legacyRequestPatch = {
709
853
  ...legacyCarrierPatch,
710
854
  ...(saveSource ? { saveSource } : {}),
855
+ ...(expectedDetailRevision ? { expectedDetailRevision } : {}),
711
856
  };
712
857
  const requestInit = {
713
858
  method: 'PATCH',
714
859
  headers: { 'Content-Type': 'application/json' },
715
860
  body: JSON.stringify(legacyRequestPatch),
716
861
  };
717
- const res = await fetchCloudTaskRootPatch(`/api/taskforce/task/${id}`, requestInit, legacyRequestPatch, id, taskHttpObservedPrecondition(previousTasks.find((task) => task.id === id)
718
- || previousArchivedTasks.find((task) => task.id === id), id));
719
- if (!res.ok) {
862
+ let activeRequestPatch = legacyRequestPatch;
863
+ for (let attempt = 0; attempt < 2; attempt += 1) {
864
+ const activeRequestInit = attempt === 0 ? requestInit : {
865
+ ...requestInit,
866
+ body: JSON.stringify(activeRequestPatch),
867
+ };
868
+ const res = await fetchCloudTaskRootPatch(`/api/taskforce/task/${id}`, activeRequestInit, activeRequestPatch, id, taskHttpObservedPrecondition(previousTasks.find((task) => task.id === id)
869
+ || previousArchivedTasks.find((task) => task.id === id), id));
870
+ if (res.ok) {
871
+ const updatedTask = await res.json().catch(() => null);
872
+ mergeTaskFromServer(updatedTask);
873
+ if (updatedTask && typeof updatedTask === 'object' && typeof updatedTask.id === 'string') {
874
+ onTaskMutationAccepted?.(updatedTask);
875
+ }
876
+ // Attachment saves also depend on the canonical asset snapshot refresh. Give that
877
+ // snapshot a brief head start so the next push includes both task metadata and bytes.
878
+ queueWorkspaceSyncFromAuthoritativeTaskState(updates.attachments !== undefined ? 150 : 0);
879
+ setError('');
880
+ return true;
881
+ }
720
882
  const data = await res.json().catch(() => ({}));
721
- const message = data.error || `Failed to update task ${id}.`;
722
- setError(message);
723
- pushNotice(message, 'error');
724
883
  const previousTask = previousTasks.find((task) => task.id === id)
725
884
  || previousArchivedTasks.find((task) => task.id === id);
726
885
  setTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, legacyCarrierPatch));
727
886
  setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, legacyCarrierPatch));
887
+ if (data.code === 'TASK_DETAIL_REVISION_CONFLICT') {
888
+ const currentDetailRevision = typeof data?.details?.currentDetailRevision === 'string'
889
+ ? data.details.currentDetailRevision
890
+ : null;
891
+ const resolution = await onTaskRevisionConflict?.(id, currentDetailRevision);
892
+ if (attempt === 0 && resolution?.retryDetailRevision) {
893
+ const reconciledPatch = resolution.retryPatch;
894
+ const retryPatch = Object.fromEntries(Object.entries(legacyRequestPatch).map(([key, value]) => [
895
+ key,
896
+ reconciledPatch && Object.prototype.hasOwnProperty.call(reconciledPatch, key)
897
+ ? reconciledPatch[key]
898
+ : value,
899
+ ]));
900
+ activeRequestPatch = {
901
+ ...retryPatch,
902
+ expectedDetailRevision: resolution.retryDetailRevision,
903
+ };
904
+ continue;
905
+ }
906
+ if (resolution?.handled) {
907
+ setError('');
908
+ return false;
909
+ }
910
+ }
911
+ const message = data.error || `Failed to update task ${id}.`;
912
+ setError(message);
913
+ pushNotice(message, 'error');
728
914
  return false;
729
915
  }
730
- const updatedTask = await res.json().catch(() => null);
731
- mergeTaskFromServer(updatedTask);
732
- // Attachment saves also depend on the canonical asset snapshot refresh. Give that
733
- // snapshot a brief head start so the next push includes both task metadata and bytes.
734
- queueWorkspaceSyncFromAuthoritativeTaskState(updates.attachments !== undefined ? 150 : 0);
735
- setError('');
736
- return true;
916
+ return false;
737
917
  }
738
918
  catch (err) {
739
919
  console.error("Failed to update task", err);
@@ -746,7 +926,7 @@ export function useTaskMutations({ tasks, archivedTasks, editingTaskId, setTasks
746
926
  setArchivedTasks((currentTasks) => rollbackTargetTaskPatch(currentTasks, previousTask, id, legacyCarrierPatch));
747
927
  return false;
748
928
  }
749
- }, [tasks, archivedTasks, pushNotice, mergeTaskFromServer, mutateTaskMetadata, queueWorkspaceSyncFromAuthoritativeTaskState, handleSetStatus, durableTaskMetadataActivationEnabled, durableTaskStatusActivationEnabled, fetchCloudTaskRootPatch]);
929
+ }, [tasks, archivedTasks, editingTaskDetailRevision, editingTaskId, pushNotice, mergeTaskFromServer, mutateTaskMetadata, onTaskMutationAccepted, onTaskRevisionConflict, queueWorkspaceSyncFromAuthoritativeTaskState, handleSetStatus, durableTaskMetadataActivationEnabled, durableTaskStatusActivationEnabled, fetchCloudTaskRootPatch]);
750
930
  const handleToggleComplete = async (task) => {
751
931
  const newStatus = task.status === 'done' ? 'task' : 'done';
752
932
  await handleSetStatus(task, newStatus);
@@ -38,6 +38,7 @@ import type { PlanningIdentityColor, PlanningIdentityIcon } from '../shared/plan
38
38
  import type { UiNotice } from '../utils/uiNotice';
39
39
  import type { TaskAssigneeOption } from '../utils/assignees';
40
40
  import { type WorkspaceModuleId } from './workspace/workspaceLocalState';
41
+ export declare function buildRelationshipTasks(tasks: TaskItem[], archivedTasks: TaskItem[], taskDetails: TaskItem[], editingTaskId: string | null): TaskItem[];
41
42
  export interface UseTaskforceProps {
42
43
  config?: Partial<TaskforceConfig>;
43
44
  initialTaskId?: string;
@@ -108,6 +109,7 @@ export declare function sanitizePlanningBootstrapPayload(input: unknown): Planni
108
109
  export declare function useTaskforce({ config, initialTaskId, initialActivityEntryId, requestedWorkspaceId, onTaskCountChange, onClose }: UseTaskforceProps): {
109
110
  config: {
110
111
  cloudEnvironment: any;
112
+ appGates: any;
111
113
  apiBaseUrl: string | undefined;
112
114
  cloudAuthBaseUrl: string | undefined;
113
115
  wsBaseUrl: string | undefined;
@@ -136,6 +138,11 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
136
138
  manualComplexityEnabled: boolean;
137
139
  checklistDropdownEnabled: boolean;
138
140
  showTaskCardStatusLabel: boolean;
141
+ showTaskCardDescription: boolean;
142
+ showTaskCardAttachments: boolean;
143
+ showTaskCardChecklistProgress: boolean;
144
+ showTaskCardLatestActivity: boolean;
145
+ tintTaskCardActivityBackground: boolean;
139
146
  };
140
147
  isOpen: boolean;
141
148
  setIsOpen: Dispatch<SetStateAction<boolean>>;
@@ -158,11 +165,16 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
158
165
  manualComplexityEnabled: boolean;
159
166
  checklistDropdownEnabled: boolean;
160
167
  showTaskCardStatusLabel: boolean;
168
+ showTaskCardDescription: boolean;
169
+ showTaskCardAttachments: boolean;
170
+ showTaskCardChecklistProgress: boolean;
171
+ showTaskCardLatestActivity: boolean;
172
+ tintTaskCardActivityBackground: boolean;
161
173
  setManualComplexityEnabled: Dispatch<SetStateAction<boolean>>;
162
174
  mcpHostRoot: string;
163
175
  setMcpHostRoot: Dispatch<SetStateAction<string>>;
164
- settingsSection: "mcp" | "categories" | "types" | "general" | "agents" | "taxonomy" | "documents" | "appearance-application" | "appearance-task-cards" | "appearance-task-forms" | "integrations" | null;
165
- setSettingsSection: Dispatch<SetStateAction<"mcp" | "categories" | "types" | "general" | "agents" | "taxonomy" | "documents" | "appearance-application" | "appearance-task-cards" | "appearance-task-forms" | "integrations" | null>>;
176
+ settingsSection: "mcp" | "categories" | "types" | "general" | "documents" | "taxonomy" | "agents" | "appearance-application" | "appearance-task-cards" | "appearance-task-forms" | "integrations" | null;
177
+ setSettingsSection: Dispatch<SetStateAction<"mcp" | "categories" | "types" | "general" | "documents" | "taxonomy" | "agents" | "appearance-application" | "appearance-task-cards" | "appearance-task-forms" | "integrations" | null>>;
166
178
  runtimeMode: "local" | "cloud";
167
179
  workspaceMode: "single-local" | "multi-cloud";
168
180
  workspaceSwitchingEnabled: boolean;
@@ -244,7 +256,7 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
244
256
  realtimeSyncEnabled: boolean;
245
257
  realtimeSyncFlagSource: "default" | "unknown" | "settings" | "env";
246
258
  currentWorkspaceId: string;
247
- currentWorkspaceRole: "member" | "owner" | "admin" | "read-only" | null;
259
+ currentWorkspaceRole: "owner" | "member" | "admin" | "read-only" | null;
248
260
  availableWorkspaces: WorkspaceSummary[];
249
261
  assigneeOptions: TaskAssigneeOption[];
250
262
  workspaceCloudSyncEnabled: boolean;
@@ -446,8 +458,8 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
446
458
  type: "category";
447
459
  value: string;
448
460
  } | null>>;
449
- groupBy: "category" | "type" | "priority" | "status" | "complexity" | "assignee" | "schedule";
450
- setGroupBy: Dispatch<SetStateAction<"category" | "type" | "priority" | "status" | "complexity" | "assignee" | "schedule">>;
461
+ groupBy: "category" | "type" | "priority" | "complexity" | "status" | "assignee" | "schedule";
462
+ setGroupBy: Dispatch<SetStateAction<"category" | "type" | "priority" | "complexity" | "status" | "assignee" | "schedule">>;
451
463
  activeWorkspaceModule: WorkspaceModuleId;
452
464
  setActiveWorkspaceModule: Dispatch<SetStateAction<WorkspaceModuleId>>;
453
465
  emptyColumnMode: "show" | "collapse" | "hide";
@@ -553,6 +565,7 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
553
565
  reorderWorkstreamTasks: (workstreamId: string, taskIds: string[]) => Promise<void>;
554
566
  handleEdit: (task: TaskItem, options?: {
555
567
  preserveReturnTrail?: boolean;
568
+ adoptAsBaseline?: boolean;
556
569
  }) => void;
557
570
  handleDelete: (id: string, archive?: boolean, options?: {
558
571
  skipConfirm?: boolean;
@@ -573,7 +586,7 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
573
586
  handlePermanentlyDeleteDeletedTask: (id: string) => Promise<boolean>;
574
587
  handleEmptyDeletedTasks: () => Promise<number | null>;
575
588
  handleUpdateTask: (id: string, updates: Partial<TaskItem>) => Promise<boolean | undefined>;
576
- handleSetStatus: (task: TaskItem, status: import("../core/TaskDurableStatusMutationService").DurableTaskTargetStatus, updates?: Partial<TaskItem>) => Promise<void>;
589
+ handleSetStatus: (task: TaskItem, status: import("../core/TaskDurableStatusMutationService").DurableTaskTargetStatus, updates?: Partial<TaskItem>, expectedDetailRevisionOverride?: string | null) => Promise<void>;
577
590
  editingTaskId: string | null;
578
591
  loading: boolean;
579
592
  error: string;
@@ -639,6 +652,10 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
639
652
  pushNotice: (message: string, tone?: UiNotice["tone"], ttlMs?: number, action?: {
640
653
  label: string;
641
654
  onAction: () => void;
655
+ primary?: boolean;
656
+ secondaryLabel?: string;
657
+ onSecondaryAction?: () => void;
658
+ dismissible?: boolean;
642
659
  ownerKey?: string;
643
660
  }) => void;
644
661
  clearNotice: () => void;
@@ -735,8 +752,13 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
735
752
  manualComplexityEnabled: boolean;
736
753
  checklistDropdownEnabled: boolean;
737
754
  showTaskCardStatusLabel: boolean;
755
+ showTaskCardDescription: boolean;
756
+ showTaskCardAttachments: boolean;
757
+ showTaskCardChecklistProgress: boolean;
758
+ showTaskCardLatestActivity: boolean;
759
+ tintTaskCardActivityBackground: boolean;
738
760
  pathSaved: boolean;
739
- initialSection: "mcp" | "categories" | "types" | "priorities" | "general" | "agents" | "taxonomy" | "initiatives" | "documents" | "appearance-application" | "appearance-task-cards" | "appearance-task-forms" | "integrations" | null;
761
+ initialSection: "mcp" | "categories" | "types" | "priorities" | "general" | "documents" | "taxonomy" | "agents" | "initiatives" | "appearance-application" | "appearance-task-cards" | "appearance-task-forms" | "integrations" | null;
740
762
  setupState: any;
741
763
  buildInfo: any;
742
764
  onSaveSetupMode: (...args: any[]) => any;
@@ -744,15 +766,21 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
744
766
  onThemeChange: (value: any) => void;
745
767
  onSaveTheme: (...args: any[]) => any;
746
768
  onSaveGlobalTheme: (...args: any[]) => any;
769
+ onUseGlobalThemeDefault: (...args: any[]) => any;
747
770
  onKeyShortcutChange: (value: string) => void;
748
771
  onJsonBackupEnabledChange: (...args: any[]) => any;
749
772
  onSaveGlobalJsonBackupEnabled: (...args: any[]) => any;
773
+ onUseGlobalJsonBackupDefault: (...args: any[]) => any;
750
774
  onSaveGlobalWeekStartsOn: (...args: any[]) => any;
751
775
  onSaveLocale: (...args: any[]) => any;
752
776
  onManualComplexityEnabledChange: (...args: any[]) => any;
753
777
  onChecklistDropdownEnabledChange: (...args: any[]) => any;
754
778
  onShowTaskCardStatusLabelChange: (...args: any[]) => any;
755
- onResetProjectToGlobal: (...args: any[]) => any;
779
+ onShowTaskCardDescriptionChange: (...args: any[]) => any;
780
+ onShowTaskCardAttachmentsChange: (...args: any[]) => any;
781
+ onShowTaskCardChecklistProgressChange: (...args: any[]) => any;
782
+ onShowTaskCardLatestActivityChange: (...args: any[]) => any;
783
+ onTintTaskCardActivityBackgroundChange: (...args: any[]) => any;
756
784
  onSaveSettings: (...args: any[]) => any;
757
785
  initiativeTemplates: any[];
758
786
  onRefreshInitiativeTemplates: (...args: any[]) => any;
@@ -796,7 +824,7 @@ export declare function useTaskforce({ config, initialTaskId, initialActivityEnt
796
824
  cloudAuthBaseUrl: string | undefined;
797
825
  cloudMcpBaseUrl: string | undefined;
798
826
  workspaceSwitchingEnabled: boolean;
799
- currentWorkspaceRole: "member" | "owner" | "admin" | "read-only";
827
+ currentWorkspaceRole: "owner" | "member" | "admin" | "read-only";
800
828
  currentWorkspaceName: string;
801
829
  onDeleteWorkspace: (...args: any[]) => any;
802
830
  onMcpHostRootChange: (value: string) => void;