@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
@@ -104,7 +104,7 @@ export interface ScheduleBoardResult {
104
104
  }>;
105
105
  };
106
106
  }
107
- export type RealtimeMutationEntityType = 'task' | 'taxonomy' | 'document-metadata';
107
+ export type RealtimeMutationEntityType = 'task' | 'initiative' | 'workstream' | 'taxonomy' | 'document-metadata';
108
108
  export interface RealtimeMutationEvent {
109
109
  eventId: string;
110
110
  workspaceId: string;
@@ -141,6 +141,7 @@ export interface TaskforceConfig {
141
141
  storagePath?: string;
142
142
  tenantId?: string;
143
143
  runtimeMode?: RuntimeMode;
144
+ initializationMode?: 'standard' | 'cloud-read-worker';
144
145
  database?: {
145
146
  provider?: DatabaseProvider;
146
147
  connectionString?: string;
@@ -175,6 +176,12 @@ export interface TaskFile {
175
176
  jsonBackupEnabled?: boolean;
176
177
  manualComplexityEnabled?: boolean;
177
178
  checklistDropdownEnabled?: boolean;
179
+ showTaskCardStatusLabel?: boolean;
180
+ showTaskCardDescription?: boolean;
181
+ showTaskCardAttachments?: boolean;
182
+ showTaskCardChecklistProgress?: boolean;
183
+ showTaskCardLatestActivity?: boolean;
184
+ tintTaskCardActivityBackground?: boolean;
178
185
  taxonomies?: any[];
179
186
  };
180
187
  }
@@ -28,7 +28,18 @@ export declare class DocumentReviewCommentStore {
28
28
  threadStatusUpdatedAt?: string | null;
29
29
  resolvedAt?: string | null;
30
30
  resolvedByActorId?: string | null;
31
+ idempotencyKey?: string | null;
32
+ idempotencyFingerprint?: string | null;
33
+ idempotencyActorScope?: string | null;
31
34
  }): DocumentReviewCommentSyncRecord;
35
+ getByIdempotencyKey(input: {
36
+ workspaceId: string;
37
+ actorScope: string;
38
+ idempotencyKey: string;
39
+ }): {
40
+ comment: DocumentReviewCommentSyncRecord;
41
+ fingerprint: string;
42
+ } | null;
32
43
  get(commentIdRaw: string, workspaceIdRaw: string, options?: {
33
44
  includeDeleted?: boolean;
34
45
  }): DocumentReviewCommentSyncRecord | null;
@@ -149,16 +149,49 @@ export class DocumentReviewCommentStore {
149
149
  thread_status_updated_at,
150
150
  resolved_at,
151
151
  resolved_by_actor_id,
152
+ idempotency_key,
153
+ idempotency_fingerprint,
154
+ idempotency_actor_scope,
152
155
  order_index,
153
156
  created_at,
154
157
  updated_at,
155
158
  deleted_at
156
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
159
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
160
+ ${normalizeNullable(input.idempotencyKey)
161
+ ? 'ON CONFLICT (tenant_id, workspace_id, idempotency_actor_scope, idempotency_key) DO NOTHING'
162
+ : ''}
157
163
  `).run(id, sessionId, this.tenantId, workspaceId, normalizeId(input.body), input.anchor ? JSON.stringify(input.anchor) : null, normalizeNullable(input.authorActorId), normalizeNullable(input.updatedByActorId ?? input.authorActorId), normalizeNullable(input.deletedByActorId), parentCommentId, parentCommentId
158
164
  ? null
159
- : (input.threadStatus === 'resolved' ? 'resolved' : 'open'), parentCommentId ? null : (normalizeNullable(input.threadStatusUpdatedAt) || updatedAt), parentCommentId ? null : normalizeNullable(input.resolvedAt), parentCommentId ? null : normalizeNullable(input.resolvedByActorId), normalizePositiveInteger(input.order) ?? 0, createdAt, updatedAt, normalizeNullable(input.deletedAt));
165
+ : (input.threadStatus === 'resolved' ? 'resolved' : 'open'), parentCommentId ? null : (normalizeNullable(input.threadStatusUpdatedAt) || updatedAt), parentCommentId ? null : normalizeNullable(input.resolvedAt), parentCommentId ? null : normalizeNullable(input.resolvedByActorId), normalizeNullable(input.idempotencyKey), normalizeNullable(input.idempotencyFingerprint), normalizeId(input.idempotencyActorScope), normalizePositiveInteger(input.order) ?? 0, createdAt, updatedAt, normalizeNullable(input.deletedAt));
166
+ if (normalizeNullable(input.idempotencyKey)) {
167
+ const replay = this.getByIdempotencyKey({
168
+ workspaceId,
169
+ actorScope: normalizeId(input.idempotencyActorScope),
170
+ idempotencyKey: normalizeId(input.idempotencyKey),
171
+ });
172
+ if (replay)
173
+ return replay.comment;
174
+ }
160
175
  return this.get(id, workspaceId, { includeDeleted: true });
161
176
  }
177
+ getByIdempotencyKey(input) {
178
+ const workspaceId = normalizeWorkspaceId(input.workspaceId);
179
+ const row = this.db.prepare(`
180
+ SELECT *
181
+ FROM document_review_comments
182
+ WHERE tenant_id = ?
183
+ AND workspace_id = ?
184
+ AND idempotency_actor_scope = ?
185
+ AND idempotency_key = ?
186
+ LIMIT 1
187
+ `).get(this.tenantId, workspaceId, normalizeId(input.actorScope), normalizeId(input.idempotencyKey));
188
+ if (!row)
189
+ return null;
190
+ return {
191
+ comment: mapRow(row),
192
+ fingerprint: normalizeId(row.idempotency_fingerprint),
193
+ };
194
+ }
162
195
  get(commentIdRaw, workspaceIdRaw, options) {
163
196
  const commentId = normalizeId(commentIdRaw);
164
197
  const workspaceId = normalizeWorkspaceId(workspaceIdRaw);
@@ -49,6 +49,8 @@ export declare function addDocumentReviewCommentService(deps: DocumentReviewServ
49
49
  body: string;
50
50
  anchor?: DocumentReviewAnchor | null;
51
51
  actorId?: string | null;
52
+ idempotencyKey?: string | null;
53
+ commentId?: string | null;
52
54
  }): DocumentReviewSession;
53
55
  export declare function addDocumentReviewReplyService(deps: DocumentReviewServiceDeps, input: {
54
56
  workspaceId?: string | null;
@@ -56,6 +58,8 @@ export declare function addDocumentReviewReplyService(deps: DocumentReviewServic
56
58
  parentCommentId: string;
57
59
  body: string;
58
60
  actorId?: string | null;
61
+ idempotencyKey?: string | null;
62
+ commentId?: string | null;
59
63
  }): DocumentReviewSession;
60
64
  export declare function updateDocumentReviewThreadStatusService(deps: DocumentReviewServiceDeps, input: {
61
65
  workspaceId?: string | null;
@@ -1,9 +1,50 @@
1
+ import { createHash } from 'node:crypto';
1
2
  function normalizeId(value) {
2
3
  return String(value || '').trim();
3
4
  }
4
5
  function normalizeCommentBody(value) {
5
6
  return String(value || '').trim();
6
7
  }
8
+ function normalizeIdempotencyKey(value) {
9
+ if (value === undefined || value === null)
10
+ return null;
11
+ const key = String(value).trim();
12
+ if (!key || key.length > 128)
13
+ return null;
14
+ return key;
15
+ }
16
+ function documentReviewCommentFingerprint(input) {
17
+ return createHash('sha256').update(JSON.stringify(input)).digest('hex');
18
+ }
19
+ function resolveDocumentReviewCommentReplay(deps, input) {
20
+ if (!input.idempotencyKey)
21
+ return null;
22
+ const existing = deps.commentStore.getByIdempotencyKey({
23
+ workspaceId: input.workspaceId,
24
+ actorScope: input.actorScope,
25
+ idempotencyKey: input.idempotencyKey,
26
+ });
27
+ const synchronizedCommentId = normalizeId(input.commentId);
28
+ const synchronizedComment = !existing && synchronizedCommentId
29
+ ? deps.commentStore.get(synchronizedCommentId, input.workspaceId, { includeDeleted: true })
30
+ : null;
31
+ const replayComment = existing?.comment || synchronizedComment;
32
+ const replayFingerprint = existing?.fingerprint || (synchronizedComment
33
+ ? documentReviewCommentFingerprint({
34
+ sessionId: synchronizedComment.sessionId,
35
+ parentCommentId: synchronizedComment.parentCommentId,
36
+ body: normalizeCommentBody(synchronizedComment.body),
37
+ anchor: normalizeAnchorInput(synchronizedComment.anchor),
38
+ actorScope: normalizeId(synchronizedComment.authorActorId) || 'anonymous',
39
+ })
40
+ : null);
41
+ if (!replayComment)
42
+ return null;
43
+ if (replayFingerprint !== input.fingerprint || replayComment.deletedAt) {
44
+ throw deps.createRuleError('idempotencyKey is already assigned to a different document review comment.', 409, 'DOCUMENT_REVIEW_IDEMPOTENCY_CONFLICT');
45
+ }
46
+ return replayComment;
47
+ }
7
48
  function normalizeStatus(value) {
8
49
  return String(value || '').trim().toLowerCase() === 'resolved' ? 'resolved' : 'open';
9
50
  }
@@ -194,46 +235,74 @@ export function updateDocumentReviewSessionService(deps, input) {
194
235
  }
195
236
  export function addDocumentReviewCommentService(deps, input) {
196
237
  const workspaceId = deps.normalizeWorkspaceId(input.workspaceId);
197
- const existing = deps.sessionStore.get(input.sessionId, workspaceId);
198
- if (!existing)
199
- throw deps.createRuleError('Document review session not found.', 404, 'DOCUMENT_REVIEW_SESSION_NOT_FOUND');
200
- getRequiredDocumentAsset(deps, workspaceId, existing.assetId);
201
- if (existing.status === 'resolved') {
202
- throw deps.createRuleError('Reopen this review before adding comments.', 409, 'DOCUMENT_REVIEW_RESOLVED');
203
- }
204
- const body = normalizeCommentBody(input.body);
205
- if (!body)
206
- throw deps.createRuleError('Comment body is required.', 400, 'DOCUMENT_REVIEW_COMMENT_REQUIRED');
207
- const anchorError = validateDocumentReviewAnchorInput(input.anchor);
208
- if (anchorError)
209
- throw deps.createRuleError(anchorError, 400, 'DOCUMENT_REVIEW_ANCHOR_INVALID');
210
- const now = new Date().toISOString();
211
- deps.commentStore.create({
212
- id: deps.generateEntityId('document-review-comment'),
213
- sessionId: existing.id,
214
- workspaceId,
215
- order: nextCommentOrder(deps.commentStore.listForSession(existing.id, workspaceId, { includeDeleted: true })),
216
- body,
217
- anchor: normalizeAnchorInput(input.anchor),
218
- authorActorId: normalizeId(input.actorId) || null,
219
- updatedByActorId: normalizeId(input.actorId) || null,
220
- deletedByActorId: null,
221
- parentCommentId: null,
222
- threadStatus: 'open',
223
- threadStatusUpdatedAt: now,
224
- resolvedAt: null,
225
- resolvedByActorId: null,
226
- createdAt: now,
227
- updatedAt: now,
228
- deletedAt: null,
229
- });
230
- const updated = deps.sessionStore.update({
231
- id: existing.id,
232
- workspaceId,
233
- updatedByActorId: normalizeId(input.actorId) || null,
234
- updatedAt: now,
238
+ return inTransaction(deps, () => {
239
+ const existing = deps.sessionStore.get(input.sessionId, workspaceId);
240
+ if (!existing)
241
+ throw deps.createRuleError('Document review session not found.', 404, 'DOCUMENT_REVIEW_SESSION_NOT_FOUND');
242
+ getRequiredDocumentAsset(deps, workspaceId, existing.assetId);
243
+ const body = normalizeCommentBody(input.body);
244
+ if (!body)
245
+ throw deps.createRuleError('Comment body is required.', 400, 'DOCUMENT_REVIEW_COMMENT_REQUIRED');
246
+ const anchorError = validateDocumentReviewAnchorInput(input.anchor);
247
+ if (anchorError)
248
+ throw deps.createRuleError(anchorError, 400, 'DOCUMENT_REVIEW_ANCHOR_INVALID');
249
+ const anchor = normalizeAnchorInput(input.anchor);
250
+ const actorScope = normalizeId(input.actorId) || 'anonymous';
251
+ const idempotencyKey = normalizeIdempotencyKey(input.idempotencyKey);
252
+ const commentId = normalizeId(input.commentId) || null;
253
+ if (input.idempotencyKey != null && !idempotencyKey) {
254
+ throw deps.createRuleError('idempotencyKey must contain 1 to 128 characters.', 400, 'DOCUMENT_REVIEW_IDEMPOTENCY_KEY_INVALID');
255
+ }
256
+ const fingerprint = documentReviewCommentFingerprint({
257
+ sessionId: existing.id, parentCommentId: null, body, anchor, actorScope,
258
+ });
259
+ const replay = resolveDocumentReviewCommentReplay(deps, {
260
+ workspaceId, idempotencyKey, commentId, actorScope, fingerprint,
261
+ });
262
+ if (replay)
263
+ return hydrateSession(deps, existing);
264
+ if (existing.status === 'resolved') {
265
+ throw deps.createRuleError('Reopen this review before adding comments.', 409, 'DOCUMENT_REVIEW_RESOLVED');
266
+ }
267
+ const now = new Date().toISOString();
268
+ const createdCommentId = commentId || deps.generateEntityId('document-review-comment');
269
+ const created = deps.commentStore.create({
270
+ id: createdCommentId,
271
+ sessionId: existing.id,
272
+ workspaceId,
273
+ order: nextCommentOrder(deps.commentStore.listForSession(existing.id, workspaceId, { includeDeleted: true })),
274
+ body,
275
+ anchor,
276
+ authorActorId: normalizeId(input.actorId) || null,
277
+ updatedByActorId: normalizeId(input.actorId) || null,
278
+ deletedByActorId: null,
279
+ parentCommentId: null,
280
+ threadStatus: 'open',
281
+ threadStatusUpdatedAt: now,
282
+ resolvedAt: null,
283
+ resolvedByActorId: null,
284
+ createdAt: now,
285
+ updatedAt: now,
286
+ deletedAt: null,
287
+ idempotencyKey,
288
+ idempotencyFingerprint: idempotencyKey ? fingerprint : null,
289
+ idempotencyActorScope: idempotencyKey ? actorScope : '',
290
+ });
291
+ if (created.id !== createdCommentId) {
292
+ const concurrentReplay = resolveDocumentReviewCommentReplay(deps, {
293
+ workspaceId, idempotencyKey, commentId: createdCommentId, actorScope, fingerprint,
294
+ });
295
+ if (concurrentReplay)
296
+ return hydrateSession(deps, existing);
297
+ }
298
+ const updated = deps.sessionStore.update({
299
+ id: existing.id,
300
+ workspaceId,
301
+ updatedByActorId: normalizeId(input.actorId) || null,
302
+ updatedAt: now,
303
+ });
304
+ return hydrateSession(deps, updated);
235
305
  });
236
- return hydrateSession(deps, updated);
237
306
  }
238
307
  export function addDocumentReviewReplyService(deps, input) {
239
308
  const workspaceId = deps.normalizeWorkspaceId(input.workspaceId);
@@ -242,24 +311,40 @@ export function addDocumentReviewReplyService(deps, input) {
242
311
  if (!session)
243
312
  throw deps.createRuleError('Document review session not found.', 404, 'DOCUMENT_REVIEW_SESSION_NOT_FOUND');
244
313
  getRequiredDocumentAsset(deps, workspaceId, session.assetId);
314
+ const body = normalizeCommentBody(input.body);
315
+ if (!body)
316
+ throw deps.createRuleError('Reply body is required.', 400, 'DOCUMENT_REVIEW_COMMENT_REQUIRED');
317
+ const actorId = normalizeId(input.actorId) || null;
318
+ const actorScope = actorId || 'anonymous';
319
+ const parentCommentId = normalizeId(input.parentCommentId);
320
+ const idempotencyKey = normalizeIdempotencyKey(input.idempotencyKey);
321
+ const commentId = normalizeId(input.commentId) || null;
322
+ if (input.idempotencyKey != null && !idempotencyKey) {
323
+ throw deps.createRuleError('idempotencyKey must contain 1 to 128 characters.', 400, 'DOCUMENT_REVIEW_IDEMPOTENCY_KEY_INVALID');
324
+ }
325
+ const fingerprint = documentReviewCommentFingerprint({
326
+ sessionId: session.id, parentCommentId, body, anchor: null, actorScope,
327
+ });
328
+ const replay = resolveDocumentReviewCommentReplay(deps, {
329
+ workspaceId, idempotencyKey, commentId, actorScope, fingerprint,
330
+ });
331
+ if (replay)
332
+ return hydrateSession(deps, session);
245
333
  if (session.status === 'resolved') {
246
334
  throw deps.createRuleError('Reopen this review before replying.', 409, 'DOCUMENT_REVIEW_RESOLVED');
247
335
  }
248
336
  const comments = deps.commentStore.listForSession(session.id, workspaceId, { includeDeleted: true });
249
- const root = comments.find((comment) => comment.id === normalizeId(input.parentCommentId) && !comment.deletedAt);
337
+ const root = comments.find((comment) => comment.id === parentCommentId && !comment.deletedAt);
250
338
  if (!root || root.parentCommentId) {
251
339
  throw deps.createRuleError('Document review thread not found.', 404, 'DOCUMENT_REVIEW_THREAD_NOT_FOUND');
252
340
  }
253
341
  if (root.threadStatus === 'resolved') {
254
342
  throw deps.createRuleError('Reopen this thread before replying.', 409, 'DOCUMENT_REVIEW_THREAD_RESOLVED');
255
343
  }
256
- const body = normalizeCommentBody(input.body);
257
- if (!body)
258
- throw deps.createRuleError('Reply body is required.', 400, 'DOCUMENT_REVIEW_COMMENT_REQUIRED');
259
- const actorId = normalizeId(input.actorId) || null;
260
344
  const now = new Date().toISOString();
261
- deps.commentStore.create({
262
- id: deps.generateEntityId('document-review-comment'),
345
+ const createdCommentId = commentId || deps.generateEntityId('document-review-comment');
346
+ const created = deps.commentStore.create({
347
+ id: createdCommentId,
263
348
  sessionId: session.id,
264
349
  workspaceId,
265
350
  parentCommentId: root.id,
@@ -276,7 +361,17 @@ export function addDocumentReviewReplyService(deps, input) {
276
361
  createdAt: now,
277
362
  updatedAt: now,
278
363
  deletedAt: null,
364
+ idempotencyKey,
365
+ idempotencyFingerprint: idempotencyKey ? fingerprint : null,
366
+ idempotencyActorScope: idempotencyKey ? actorScope : '',
279
367
  });
368
+ if (created.id !== createdCommentId) {
369
+ const concurrentReplay = resolveDocumentReviewCommentReplay(deps, {
370
+ workspaceId, idempotencyKey, commentId: createdCommentId, actorScope, fingerprint,
371
+ });
372
+ if (concurrentReplay)
373
+ return hydrateSession(deps, session);
374
+ }
280
375
  const updated = deps.sessionStore.update({
281
376
  id: session.id,
282
377
  workspaceId,
@@ -6,7 +6,7 @@ export declare function useDurableLocalOutboxDrain(input: {
6
6
  workspaceId: string;
7
7
  mutationFingerprint: string;
8
8
  authorityScope: object;
9
- remoteServices: Pick<WorkspaceSyncEngineRemoteServices, 'pullWorkspaceContent' | 'abandonTransferReceipts' | 'buildV2ApplyCompletionGroup'> | null;
9
+ remoteServices: Pick<WorkspaceSyncEngineRemoteServices, 'pullWorkspaceContent' | 'abandonTransferReceipts' | 'buildIndependentContentApplyCompletionGroup'> | null;
10
10
  localServices: Pick<WorkspaceSyncEngineLocalServices, 'applyV2Batch'>;
11
11
  isAuthorityCurrent?: (authorityScope: object) => boolean;
12
12
  onHydratedEventIds?: (eventIds: string[]) => void;
@@ -104,7 +104,7 @@ export function useDurableTaskCreateMutation(input) {
104
104
  clientRef.current = input.client || createLocalTaskCreateClient();
105
105
  const participant = await getParticipant(workspaceId);
106
106
  const selected = selectTaskCreateActivationInput(candidate);
107
- const participantId = selected
107
+ const participantId = input.enabled && selected
108
108
  ? participant.prepareForDraft(await fingerprintTaskDraft(selected.localTask))
109
109
  : participant.participantId;
110
110
  let result;
@@ -2,6 +2,7 @@ import type { TaskItem } from '../../types.js';
2
2
  import { createLocalTaskMetadataClient, type LocalTaskMetadataMutationResult } from '../../sync/v3/localTaskMetadataClient.js';
3
3
  export type DurableTaskMetadataMutationAdapter = (taskId: string, patch: Partial<TaskItem>, options?: {
4
4
  saveSource?: 'manual' | 'autosave';
5
+ expectedDetailRevision?: string;
5
6
  }) => Promise<LocalTaskMetadataMutationResult | null>;
6
7
  type LocalTaskMetadataClient = ReturnType<typeof createLocalTaskMetadataClient>;
7
8
  export declare function useDurableTaskMetadataMutation(input: {
@@ -17,6 +17,7 @@ export function useDurableTaskMetadataMutation(input) {
17
17
  entityId,
18
18
  patch: patch,
19
19
  ...(options?.saveSource ? { saveSource: options.saveSource } : {}),
20
+ ...(options?.expectedDetailRevision ? { expectedDetailRevision: options.expectedDetailRevision } : {}),
20
21
  isAuthenticated: input.isAuthenticated,
21
22
  dispatchEnabled: input.dispatchEnabled,
22
23
  });
@@ -6,6 +6,7 @@ export type DurableTaskStatusMutationAdapter = (taskId: string, payload: {
6
6
  assigneeIntent: DurableTaskStatusAssigneeIntent;
7
7
  canceledReason: string | null;
8
8
  metadataPatch?: Partial<TaskItem>;
9
+ expectedDetailRevision?: string;
9
10
  }) => Promise<LocalTaskStatusMutationResult | null>;
10
11
  type LocalTaskStatusClient = ReturnType<typeof createLocalTaskStatusClient>;
11
12
  export declare function useDurableTaskStatusMutation(input: {
@@ -44,6 +44,7 @@ export async function isConclusiveTaskHttpResponse(response) {
44
44
  'TASK_ATTACHMENT_LINKS_INVALID',
45
45
  'TASK_COMMENT_INVALID',
46
46
  'TASK_COMMENT_IDENTITY_CONFLICT',
47
+ 'TASK_DETAIL_REVISION_CONFLICT',
47
48
  ]).has(code);
48
49
  }
49
50
  function stableTaskCreateCandidate(candidate) {
@@ -0,0 +1,12 @@
1
+ interface UseCloudTaskSearchInput {
2
+ query: string;
3
+ runtimeMode: 'local' | 'cloud';
4
+ workspaceId: string;
5
+ enabled: boolean;
6
+ scope: 'active' | 'archive';
7
+ debounceMs?: number;
8
+ pageSize?: number;
9
+ maxMatches?: number;
10
+ }
11
+ export declare function useCloudTaskSearch({ query, runtimeMode, workspaceId, enabled, scope, debounceMs, pageSize, maxMatches, }: UseCloudTaskSearchInput): ReadonlySet<string>;
12
+ export {};
@@ -0,0 +1,71 @@
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
+ import { normalizeTaskSearchQuery } from '../../utils/taskSearch';
3
+ export function useCloudTaskSearch({ query, runtimeMode, workspaceId, enabled, scope, debounceMs = 250, pageSize = 50, maxMatches = 500, }) {
4
+ const [matchIds, setMatchIds] = useState(() => new Set());
5
+ const requestSequenceRef = useRef(0);
6
+ const normalizedQuery = useMemo(() => normalizeTaskSearchQuery(query).raw, [query]);
7
+ useEffect(() => {
8
+ requestSequenceRef.current += 1;
9
+ const requestSequence = requestSequenceRef.current;
10
+ if (!enabled || runtimeMode !== 'cloud' || !normalizedQuery || !workspaceId.trim()) {
11
+ setMatchIds((current) => current.size === 0 ? current : new Set());
12
+ return;
13
+ }
14
+ setMatchIds((current) => current.size === 0 ? current : new Set());
15
+ const abortController = new AbortController();
16
+ const timer = window.setTimeout(() => {
17
+ void (async () => {
18
+ const collected = new Set();
19
+ let offset = 0;
20
+ let scanned = 0;
21
+ const boundedPageSize = Math.max(1, Math.min(50, Math.trunc(pageSize)));
22
+ const boundedMaxMatches = Math.max(1, Math.trunc(maxMatches));
23
+ try {
24
+ while (scanned < boundedMaxMatches) {
25
+ const limit = Math.min(boundedPageSize, boundedMaxMatches - scanned);
26
+ const params = new URLSearchParams({
27
+ query: query.trim(),
28
+ scope,
29
+ limit: String(limit),
30
+ offset: String(offset),
31
+ });
32
+ const response = await fetch(`/api/taskforce/tasks/search?${params.toString()}`, {
33
+ signal: abortController.signal,
34
+ });
35
+ if (!response.ok)
36
+ throw new Error(`Task search failed (${response.status}).`);
37
+ const body = await response.json();
38
+ const matches = body.matches || [];
39
+ scanned += matches.length;
40
+ for (const match of matches) {
41
+ const id = String(match?.id || '').trim();
42
+ if (id)
43
+ collected.add(id);
44
+ }
45
+ if (body.pagination?.hasMore !== true)
46
+ break;
47
+ const nextOffset = Number(body.pagination?.nextOffset);
48
+ if (!Number.isInteger(nextOffset) || nextOffset <= offset)
49
+ break;
50
+ offset = nextOffset;
51
+ }
52
+ if (!abortController.signal.aborted && requestSequenceRef.current === requestSequence) {
53
+ setMatchIds(collected);
54
+ }
55
+ }
56
+ catch (error) {
57
+ if (abortController.signal.aborted || requestSequenceRef.current !== requestSequence)
58
+ return;
59
+ // Server search augments the existing client matcher. On failure, retain
60
+ // the client-visible metadata results instead of blocking the task board.
61
+ setMatchIds(new Set());
62
+ }
63
+ })();
64
+ }, Math.max(0, debounceMs));
65
+ return () => {
66
+ window.clearTimeout(timer);
67
+ abortController.abort('superseded');
68
+ };
69
+ }, [debounceMs, enabled, maxMatches, normalizedQuery, pageSize, query, runtimeMode, scope, workspaceId]);
70
+ return matchIds;
71
+ }
@@ -0,0 +1,16 @@
1
+ export type TaskDescriptionImageDraftResolution = 'promote' | 'discard';
2
+ type DraftRecoveryFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
3
+ interface UseTaskDescriptionImageDraftRecoveryOptions {
4
+ fetchImpl?: DraftRecoveryFetch;
5
+ storage?: Storage | null;
6
+ now?: () => number;
7
+ }
8
+ export declare const TASK_DESCRIPTION_IMAGE_DRAFT_RECOVERY_STORAGE_KEY = "taskforce.task-description-image-draft-recovery.v1";
9
+ export declare function taskDescriptionImageDraftRetryDelay(attempts: number): number;
10
+ export declare function useTaskDescriptionImageDraftRecovery(workspaceId: string, createdByUserId: string, options?: UseTaskDescriptionImageDraftRecoveryOptions): {
11
+ resolveDraft: (input: {
12
+ draftUploadId: string;
13
+ resolution: TaskDescriptionImageDraftResolution;
14
+ }) => Promise<void>;
15
+ };
16
+ export {};