@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
@@ -1,9 +1,9 @@
1
- import { projectResolvedTaskAttachmentLinksForDurableSync } from '../../core/TaskAttachmentLinksDurableMutationService.js';
1
+ import { projectResolvedTaskAttachmentLinksForDurableSync, resolveTaskCardCoverAssetIdForLinks, } from '../../core/TaskAttachmentLinksDurableMutationService.js';
2
2
  import { serializeTaskRootForSync } from './workspaceSyncV3TaskRootProjection.js';
3
3
  import { buildTaskAttachmentLinksActivityEventId } from './taskAttachmentLinksActivityIdentity.js';
4
4
  import { asWorkspaceSyncActivityRevision, buildTaskActivityJournalEntry, canonicalizeEntityActivityDetailsForSync, serializeTaskActivityForSync, } from './taskActivityJournal.js';
5
5
  import { fingerprintWorkspaceSyncPayload, runReservedWorkspaceSyncV3Operation, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
6
- import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
6
+ import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, } from './workspaceSyncV3NestedTaskCodecs.js';
7
7
  import { resolveDeferredMutationActorRef } from './workspaceSyncV3OriginActor.js';
8
8
  export class DurableTaskAttachmentLinksMutationError extends Error {
9
9
  code;
@@ -57,7 +57,13 @@ export function runDurableTaskAttachmentLinksReplace(input) {
57
57
  domain: 'task-attachment-links', entityId: input.taskId, mutationKind: 'replace',
58
58
  baseEntityRevision: String(input.baseEntityRevision),
59
59
  baseLifecycleRevision: String(input.baseLifecycleRevision), links: requestedLinks,
60
+ ...(Object.prototype.hasOwnProperty.call(input, 'cardCoverAssetId')
61
+ ? { cardCoverAssetId: input.cardCoverAssetId }
62
+ : {}),
60
63
  ...(input.originActorRef ? { originActorRef: input.originActorRef } : {}),
64
+ ...(input.expectedDetailRevision
65
+ ? { expectedDetailRevision: input.expectedDetailRevision }
66
+ : {}),
61
67
  },
62
68
  });
63
69
  const activityEventId = buildTaskAttachmentLinksActivityEventId({
@@ -71,6 +77,16 @@ export function runDurableTaskAttachmentLinksReplace(input) {
71
77
  throw new Error('Durable task attachment-link activity was not persisted.');
72
78
  return activity;
73
79
  };
80
+ const readAttachmentPayload = () => {
81
+ const task = input.core.getTask(input.taskId, input.workspaceId);
82
+ if (!task)
83
+ throw new DurableTaskAttachmentLinksMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
84
+ return serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
85
+ taskId: input.taskId,
86
+ links: input.core.listTaskAttachmentLinksForDurableSync(input.taskId, input.workspaceId),
87
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
88
+ });
89
+ };
74
90
  const result = runReservedWorkspaceSyncV3Operation({
75
91
  store: input.store, identity, requestFingerprint,
76
92
  now: input.now, leaseExpiresAt: input.leaseExpiresAt, leaseOwner: input.leaseOwner,
@@ -98,21 +114,29 @@ export function runDurableTaskAttachmentLinksReplace(input) {
98
114
  }, {
99
115
  domain: 'task-attachment-links', entityId: input.taskId, mutationKind: 'replace', revisionKind: 'metadata',
100
116
  baseEntityRevision: input.baseEntityRevision, baseLifecycleRevision: input.baseLifecycleRevision,
101
- buildCanonicalFingerprint: () => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
102
- taskId: input.taskId,
103
- links: input.core.listTaskAttachmentLinksForDurableSync(input.taskId, input.workspaceId),
104
- })),
105
- buildAuthoritativePayload: () => serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
106
- taskId: input.taskId,
107
- links: input.core.listTaskAttachmentLinksForDurableSync(input.taskId, input.workspaceId),
108
- }),
117
+ buildCanonicalFingerprint: () => fingerprintWorkspaceSyncPayload(readAttachmentPayload()),
118
+ buildAuthoritativePayload: readAttachmentPayload,
109
119
  }, buildTaskActivityJournalEntry({ eventId: activityEventId, readEvent: readActivity })],
110
120
  applyMutation: () => {
121
+ input.assertPrecondition?.();
111
122
  const existing = input.core.getTask(input.taskId, input.workspaceId);
112
123
  if (!existing)
113
124
  throw new DurableTaskAttachmentLinksMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
114
125
  if (existing.isArchived)
115
126
  throw new DurableTaskAttachmentLinksMutationError('Archived tasks are read-only. Unarchive first to make changes.', 'TASK_ARCHIVED_READ_ONLY', 409);
127
+ let cardCoverAssetId;
128
+ try {
129
+ cardCoverAssetId = resolveTaskCardCoverAssetIdForLinks({
130
+ currentCardCoverAssetId: existing.cardCoverAssetId,
131
+ ...(Object.prototype.hasOwnProperty.call(input, 'cardCoverAssetId')
132
+ ? { requestedCardCoverAssetId: input.cardCoverAssetId }
133
+ : {}),
134
+ links,
135
+ });
136
+ }
137
+ catch (error) {
138
+ throw new DurableTaskAttachmentLinksMutationError(error instanceof Error ? error.message : 'Task card cover is invalid.', 'TASK_ATTACHMENT_LINKS_INVALID', Number(error?.statusCode) || 400);
139
+ }
116
140
  const previousLinks = input.core.listTaskAttachmentLinksForDurableSync(input.taskId, input.workspaceId);
117
141
  let attachments;
118
142
  try {
@@ -126,7 +150,7 @@ export function runDurableTaskAttachmentLinksReplace(input) {
126
150
  }
127
151
  const updatedAt = nextUpdatedAt(String(existing.updatedAt || existing.createdAt), input.now);
128
152
  const actorRef = resolveDeferredMutationActorRef(input);
129
- const task = input.core.updateTask(existing.id, { attachments }, input.workspaceId, {
153
+ const task = input.core.updateTask(existing.id, { attachments, cardCoverAssetId }, input.workspaceId, {
130
154
  persistBackup: false, emitRealtime: false, syncUpdatedAt: updatedAt,
131
155
  actorRef, skipTaskEvents: true,
132
156
  preferExplicitAttachmentRole: true,
@@ -165,9 +189,10 @@ export function runDurableTaskAttachmentLinksReplace(input) {
165
189
  sequence: attachmentLinksRevision.sequence,
166
190
  entityRevision: attachmentLinksRevision.entityRevision,
167
191
  lifecycleRevision: attachmentLinksRevision.lifecycleRevision,
168
- payload: serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
192
+ payload: serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
169
193
  taskId: task.id,
170
194
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
195
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
171
196
  }),
172
197
  },
173
198
  },
@@ -4,13 +4,13 @@ import { serializeTaskActivityForSync, type WorkspaceSyncActivityRevision } from
4
4
  import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
5
5
  import { type WorkspaceSyncV3TaskChecklistPayload } from './workspaceSyncV3NestedTaskCodecs.js';
6
6
  export declare class DurableTaskChecklistMutationError extends Error {
7
- readonly code: 'TASK_NOT_FOUND' | 'TASK_ARCHIVED_READ_ONLY' | 'TASK_CHECKLIST_INVALID' | 'TASK_CHECKLIST_IDENTITY_CONFLICT' | 'WORKSPACE_SYNC_OPERATION_ID_REQUIRED' | 'TASK_CHECKLIST_DEPENDENCY_PENDING';
7
+ readonly code: 'TASK_NOT_FOUND' | 'TASK_ARCHIVED_READ_ONLY' | 'TASK_CHECKLIST_INVALID' | 'TASK_CHECKLIST_IDENTITY_CONFLICT' | 'WORKSPACE_SYNC_OPERATION_ID_REQUIRED' | 'TASK_CHECKLIST_DEPENDENCY_PENDING' | 'TASK_DETAIL_REVISION_CONFLICT';
8
8
  readonly statusCode: number;
9
9
  readonly details?: Record<string, unknown> | undefined;
10
10
  readonly retryable?: boolean | undefined;
11
11
  readonly retryAfterAt?: string | undefined;
12
12
  readonly retryHint?: string | undefined;
13
- constructor(message: string, code: 'TASK_NOT_FOUND' | 'TASK_ARCHIVED_READ_ONLY' | 'TASK_CHECKLIST_INVALID' | 'TASK_CHECKLIST_IDENTITY_CONFLICT' | 'WORKSPACE_SYNC_OPERATION_ID_REQUIRED' | 'TASK_CHECKLIST_DEPENDENCY_PENDING', statusCode: number, details?: Record<string, unknown> | undefined, retryable?: boolean | undefined, retryAfterAt?: string | undefined, retryHint?: string | undefined);
13
+ constructor(message: string, code: 'TASK_NOT_FOUND' | 'TASK_ARCHIVED_READ_ONLY' | 'TASK_CHECKLIST_INVALID' | 'TASK_CHECKLIST_IDENTITY_CONFLICT' | 'WORKSPACE_SYNC_OPERATION_ID_REQUIRED' | 'TASK_CHECKLIST_DEPENDENCY_PENDING' | 'TASK_DETAIL_REVISION_CONFLICT', statusCode: number, details?: Record<string, unknown> | undefined, retryable?: boolean | undefined, retryAfterAt?: string | undefined, retryHint?: string | undefined);
14
14
  }
15
15
  export type DurableTaskChecklistResponse = {
16
16
  success: true;
@@ -88,5 +88,7 @@ export declare function runDurableTaskChecklistReplace(input: {
88
88
  actorRef: string;
89
89
  resolveActorRef?: () => string;
90
90
  originActorRef?: string;
91
+ expectedDetailRevision?: string;
92
+ assertPrecondition?: () => void;
91
93
  onPostCommitError?: (error: unknown) => void;
92
94
  }): DurableTaskChecklistMutationResult;
@@ -58,6 +58,9 @@ export function runDurableTaskChecklistReplace(input) {
58
58
  baseLifecycleRevision: String(input.baseLifecycleRevision),
59
59
  items,
60
60
  ...(input.originActorRef ? { originActorRef: input.originActorRef } : {}),
61
+ ...(input.expectedDetailRevision
62
+ ? { expectedDetailRevision: input.expectedDetailRevision }
63
+ : {}),
61
64
  },
62
65
  });
63
66
  const activityEventId = buildTaskChecklistActivityEventId({
@@ -100,6 +103,7 @@ export function runDurableTaskChecklistReplace(input) {
100
103
  }),
101
104
  }, buildTaskActivityJournalEntry({ eventId: activityEventId, readEvent: readActivity })],
102
105
  applyMutation: () => {
106
+ input.assertPrecondition?.();
103
107
  const existing = input.core.getTask(input.taskId, input.workspaceId);
104
108
  if (!existing)
105
109
  throw new DurableTaskChecklistMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
@@ -2,7 +2,7 @@ import { type DurableTaskCreateMutationCore } from '../../core/TaskDurableCreate
2
2
  import type { EntityEvent, TaskEvent, TaskItem } from '../../core/Taskforce.js';
3
3
  import { serializeTaskForSync } from '../taskSyncPayload.js';
4
4
  import type { WorkspaceSyncTaskEventSnapshot } from '../workspaceSyncModel.js';
5
- import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, type WorkspaceSyncV3TaskAttachmentLink } from './workspaceSyncV3NestedTaskCodecs.js';
5
+ import { serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, type WorkspaceSyncV3TaskAttachmentLink } from './workspaceSyncV3NestedTaskCodecs.js';
6
6
  import { type WorkspaceSyncActivityRevision } from './taskActivityJournal.js';
7
7
  import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
8
8
  export interface DurableTaskCreateServiceCore extends DurableTaskCreateMutationCore {
@@ -64,7 +64,7 @@ export type DurableTaskCreateResponse = {
64
64
  sequence: string;
65
65
  entityRevision: string;
66
66
  lifecycleRevision: string;
67
- payload: ReturnType<typeof serializeWorkspaceSyncV3TaskAttachmentLinksPayload>;
67
+ payload: ReturnType<typeof serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload>;
68
68
  };
69
69
  activity: WorkspaceSyncTaskEventSnapshot;
70
70
  activityRevision: WorkspaceSyncActivityRevision;
@@ -1,7 +1,7 @@
1
1
  import { applyTaskCreateForDurableSync, assertTaskCreateIdentityAvailable, validateDurableTaskCreateInput, } from '../../core/TaskDurableCreateMutationService.js';
2
2
  import { serializeTaskForSync } from '../taskSyncPayload.js';
3
3
  import { buildTaskCreateActivityEventId } from './taskCreateActivityIdentity.js';
4
- import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
4
+ import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
5
5
  import { asWorkspaceSyncActivityRevision, buildEntityActivityJournalEntry, buildTaskActivityJournalEntry, serializeTaskActivityForSync, } from './taskActivityJournal.js';
6
6
  import { fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
7
7
  function requireZeroBaseRevision(value, label) {
@@ -151,13 +151,15 @@ export function runDurableTaskCreate(input) {
151
151
  domain: 'task-attachment-links', entityId: taskId, mutationKind: 'replace', revisionKind: 'metadata',
152
152
  baseEntityRevision: 0, baseLifecycleRevision: 0,
153
153
  include: () => attachmentLinks.length > 0,
154
- buildCanonicalFingerprint: (task) => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
154
+ buildCanonicalFingerprint: (task) => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
155
155
  taskId: task.id,
156
156
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
157
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
157
158
  })),
158
- buildAuthoritativePayload: (task) => serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
159
+ buildAuthoritativePayload: (task) => serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
159
160
  taskId: task.id,
160
161
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
162
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
161
163
  }),
162
164
  }, buildTaskActivityJournalEntry({ eventId: activityEventId, readEvent: readActivity }), {
163
165
  ...buildEntityActivityJournalEntry({
@@ -257,9 +259,10 @@ export function runDurableTaskCreate(input) {
257
259
  sequence: attachmentRevision.sequence,
258
260
  entityRevision: attachmentRevision.entityRevision,
259
261
  lifecycleRevision: attachmentRevision.lifecycleRevision,
260
- payload: serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
262
+ payload: serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
261
263
  taskId: task.id,
262
264
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
265
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
263
266
  }),
264
267
  } } : {}),
265
268
  activity: serializeTaskActivityForSync(activity),
@@ -57,8 +57,12 @@ export function preserveV3OwnedTaskMetadata(incoming, existing) {
57
57
  return merged;
58
58
  }
59
59
  export function preserveV3OwnedTaskRoot(incoming, existing) {
60
+ const hasCardCoverAssetId = Object.prototype.hasOwnProperty.call(incoming, 'cardCoverAssetId');
60
61
  return {
61
62
  ...serializeTaskRootForSync(existing),
63
+ cardCoverAssetId: hasCardCoverAssetId
64
+ ? incoming.cardCoverAssetId ?? null
65
+ : existing.cardCoverAssetId ?? null,
62
66
  comments: incoming.comments ?? existing.comments,
63
67
  attachments: incoming.attachments ?? existing.attachments,
64
68
  checklistItems: incoming.checklistItems ?? existing.checklistItems,
@@ -45,6 +45,7 @@ export interface DurableTaskMetadataServiceCore extends DurableTaskMetadataMutat
45
45
  workspaceId: string;
46
46
  eventId: string;
47
47
  }): EntityEvent | null;
48
+ assertTaskDetailRevisionForUpdate?(id: string, expectedDetailRevision: string, workspaceId?: string): void;
48
49
  }
49
50
  export declare function runDurableTaskMetadataUpdate(input: {
50
51
  store: WorkspaceSyncDurabilityStore;
@@ -67,5 +68,7 @@ export declare function runDurableTaskMetadataUpdate(input: {
67
68
  originActorRef?: string;
68
69
  saveSource?: 'manual' | 'autosave';
69
70
  activityAction?: 'task-updated' | 'task-schedule-changed';
71
+ expectedDetailRevision?: string;
72
+ assertPrecondition?: () => void;
70
73
  onPostCommitError?: (error: unknown) => void;
71
74
  }): DurableTaskMetadataMutationResult;
@@ -35,6 +35,9 @@ export function runDurableTaskMetadataUpdate(input) {
35
35
  ...(input.activityAction && input.activityAction !== 'task-updated'
36
36
  ? { activityAction: input.activityAction }
37
37
  : {}),
38
+ ...(input.expectedDetailRevision
39
+ ? { expectedDetailRevision: input.expectedDetailRevision }
40
+ : {}),
38
41
  },
39
42
  });
40
43
  const activityEventId = buildTaskMetadataActivityEventId({
@@ -112,6 +115,7 @@ export function runDurableTaskMetadataUpdate(input) {
112
115
  })),
113
116
  }],
114
117
  applyMutation: () => {
118
+ input.assertPrecondition?.();
115
119
  const actorRef = resolveDeferredMutationActorRef(input);
116
120
  if (!carriers)
117
121
  return applyTaskMetadataUpdateForDurableSync({
@@ -2,7 +2,7 @@ import type { TaskEvent } from '../../core/Taskforce.js';
2
2
  import type { TaskRestoreDestination } from '../../shared/taskRestoreDestination.js';
3
3
  import { type DurableTaskRestoreCore } from '../../core/TaskDurableRestoreMutationService.js';
4
4
  import { serializeTaskForSync } from '../taskSyncPayload.js';
5
- import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, type WorkspaceSyncV3TaskAttachmentLink } from './workspaceSyncV3NestedTaskCodecs.js';
5
+ import { serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, type WorkspaceSyncV3TaskAttachmentLink } from './workspaceSyncV3NestedTaskCodecs.js';
6
6
  import { type WorkspaceSyncActivityRevision } from './taskActivityJournal.js';
7
7
  import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
8
8
  export interface DurableTaskRestoreServiceCore extends DurableTaskRestoreCore {
@@ -57,7 +57,7 @@ export type DurableTaskRestoreResponse = {
57
57
  sequence: string;
58
58
  entityRevision: string;
59
59
  lifecycleRevision: string;
60
- payload: ReturnType<typeof serializeWorkspaceSyncV3TaskAttachmentLinksPayload>;
60
+ payload: ReturnType<typeof serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload>;
61
61
  };
62
62
  activity: TaskEvent;
63
63
  activityRevision: WorkspaceSyncActivityRevision;
@@ -1,7 +1,7 @@
1
1
  import { applyTaskRestoreForDurableSync, } from '../../core/TaskDurableRestoreMutationService.js';
2
2
  import { serializeTaskForSync } from '../taskSyncPayload.js';
3
3
  import { buildTaskLifecycleActivityEventId } from './taskLifecycleActivityIdentity.js';
4
- import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
4
+ import { serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
5
5
  import { asWorkspaceSyncActivityRevision, buildTaskActivityJournalEntry, } from './taskActivityJournal.js';
6
6
  import { fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
7
7
  export function runDurableTaskRestore(input) {
@@ -90,13 +90,15 @@ export function runDurableTaskRestore(input) {
90
90
  domain: 'task-attachment-links', entityId: input.taskId, mutationKind: 'replace', revisionKind: 'metadata',
91
91
  baseEntityRevision: 0, baseLifecycleRevision: 0,
92
92
  baseRevisionPolicy: 'current',
93
- buildCanonicalFingerprint: (task) => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
93
+ buildCanonicalFingerprint: (task) => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
94
94
  taskId: task.id,
95
95
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
96
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
96
97
  })),
97
- buildAuthoritativePayload: (task) => serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
98
+ buildAuthoritativePayload: (task) => serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
98
99
  taskId: task.id,
99
100
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
101
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
100
102
  }),
101
103
  }, buildTaskActivityJournalEntry({ eventId: activityEventId, readEvent: readActivity })],
102
104
  applyMutation: () => applyTaskRestoreForDurableSync({
@@ -151,9 +153,10 @@ export function runDurableTaskRestore(input) {
151
153
  domain: 'task-attachment-links', entityId: task.id, mutationKind: 'replace',
152
154
  sequence: attachmentRevision.sequence, entityRevision: attachmentRevision.entityRevision,
153
155
  lifecycleRevision: attachmentRevision.lifecycleRevision,
154
- payload: serializeWorkspaceSyncV3TaskAttachmentLinksPayload({
156
+ payload: serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
155
157
  taskId: task.id,
156
158
  links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
159
+ cardCoverAssetId: task.cardCoverAssetId ?? null,
157
160
  }),
158
161
  },
159
162
  activity: readActivity(),
@@ -64,6 +64,8 @@ export declare function runDurableTaskStatusMutation(input: {
64
64
  resolveActorRef?: () => string;
65
65
  originActorRef?: string;
66
66
  includeWorkflowRuntimeJournal?: boolean;
67
+ expectedDetailRevision?: string;
68
+ assertPrecondition?: () => void;
67
69
  onPostCommitError?: (error: unknown) => void;
68
70
  }): {
69
71
  state: 'in_progress';
@@ -34,6 +34,9 @@ export function runDurableTaskStatusMutation(input) {
34
34
  baseLifecycleRevision: String(input.baseLifecycleRevision),
35
35
  payload: operationPayload,
36
36
  ...(input.originActorRef ? { originActorRef: input.originActorRef } : {}),
37
+ ...(input.expectedDetailRevision
38
+ ? { expectedDetailRevision: input.expectedDetailRevision }
39
+ : {}),
37
40
  },
38
41
  });
39
42
  const activityEventId = buildTaskLifecycleActivityEventId({
@@ -184,6 +187,7 @@ export function runDurableTaskStatusMutation(input) {
184
187
  })),
185
188
  }, ...workflowEntries],
186
189
  applyMutation: () => {
190
+ input.assertPrecondition?.();
187
191
  const currentTask = input.core.getTask(input.taskId, input.workspaceId);
188
192
  if (operationPayload.workflowAssignment) {
189
193
  if (payload.status !== 'in-progress'
@@ -2,6 +2,7 @@ import type { WorkflowAssignmentSyncRecord, WorkflowExecutionEventRecord, Workfl
2
2
  import { type DurableTaskStatusMutationPayload } from '../../core/TaskDurableStatusMutationService.js';
3
3
  export type TaskStatusOperationWithWorkflowAssignment = DurableTaskStatusMutationPayload & {
4
4
  workflowAssignment?: WorkflowAssignmentSyncRecord;
5
+ expectedDetailRevision?: string;
5
6
  };
6
7
  export declare class WorkflowAssignmentSyncError extends Error {
7
8
  readonly code = "WORKFLOW_ASSIGNMENT_SYNC_INVALID";
@@ -209,5 +209,8 @@ export function normalizeTaskStatusOperationWithWorkflowAssignment(raw) {
209
209
  ? {}
210
210
  : { workflowAssignment: normalizeWorkflowAssignmentSyncRecord(source.workflowAssignment) }),
211
211
  ...(originActor ? { originActor } : {}),
212
+ ...(typeof source.expectedDetailRevision === 'string' && source.expectedDetailRevision.trim()
213
+ ? { expectedDetailRevision: source.expectedDetailRevision.trim() }
214
+ : {}),
212
215
  };
213
216
  }
@@ -1,6 +1,6 @@
1
1
  import type { WorkspaceSyncIncomingTaskApplyModel } from '../syncApplyHandlers.js';
2
2
  import type { WorkspaceSyncChange } from '../workspaceSyncModel.js';
3
- export declare const WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS: readonly ["task/root-v1", "task-relationship/full-v1", "taxonomy/full-v1", "initiative/full-v1", "workstream/full-v1", "task-comments/full-v1", "task-checklist/full-v1", "task-attachment-links/full-v1", "entity-event/full-v1", "workstream-task-order/full-v1"];
3
+ export declare const WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS: readonly ["task/root-v1", "task-relationship/full-v1", "taxonomy/full-v1", "initiative/full-v1", "workstream/full-v1", "task-comments/full-v1", "task-checklist/full-v1", "task-attachment-links/full-v1", "task-attachment-links/full-v2", "entity-event/full-v1", "workstream-task-order/full-v1"];
4
4
  export type WorkspaceSyncV2ProjectionExclusion = typeof WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS[number];
5
5
  export declare const WORKSPACE_SYNC_V3_COMBINED_V2_EXCLUSIONS: readonly WorkspaceSyncV2ProjectionExclusion[];
6
6
  export declare function normalizeWorkspaceSyncV2ProjectionExclusions(values: Iterable<unknown> | null | undefined): WorkspaceSyncV2ProjectionExclusion[];
@@ -8,6 +8,7 @@ export const WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS = Object.freeze([
8
8
  'task-comments/full-v1',
9
9
  'task-checklist/full-v1',
10
10
  'task-attachment-links/full-v1',
11
+ 'task-attachment-links/full-v2',
11
12
  'entity-event/full-v1',
12
13
  'workstream-task-order/full-v1',
13
14
  ]);
@@ -49,10 +50,9 @@ export function prepareWorkspaceSyncV2TaskCarriers(taskMutations, excludedProjec
49
50
  return taskMutations;
50
51
  const commentsOwned = excludedProjections.has('task-comments/full-v1');
51
52
  const checklistOwned = excludedProjections.has('task-checklist/full-v1');
52
- const attachmentsOwned = excludedProjections.has('task-attachment-links/full-v1');
53
- if (commentsOwned && checklistOwned && attachmentsOwned) {
54
- return { upserts: [], deletes: taskMutations.deletes };
55
- }
53
+ const cardCoverOwned = excludedProjections.has('task-attachment-links/full-v2');
54
+ const attachmentsOwned = excludedProjections.has('task-attachment-links/full-v1')
55
+ || cardCoverOwned;
56
56
  return {
57
57
  upserts: taskMutations.upserts.map(({ archived, task }) => {
58
58
  const existing = readExistingTask?.(String(task.id || '').trim());
@@ -66,6 +66,7 @@ export function prepareWorkspaceSyncV2TaskCarriers(taskMutations, excludedProjec
66
66
  ...(commentsOwned ? { comments: existing.comments || [] } : {}),
67
67
  ...(checklistOwned ? { checklistItems: existing.checklistItems || [] } : {}),
68
68
  ...(attachmentsOwned ? { attachments: existing.attachments || [] } : {}),
69
+ ...(cardCoverOwned ? { cardCoverAssetId: existing.cardCoverAssetId ?? null } : {}),
69
70
  },
70
71
  };
71
72
  }),
@@ -103,14 +104,12 @@ export function partitionWorkspaceSyncV2LegacyChanges(changes, excludedProjectio
103
104
  if (change.op === 'upsert') {
104
105
  const commentsOwned = excludedProjections.has('task-comments/full-v1');
105
106
  const checklistOwned = excludedProjections.has('task-checklist/full-v1');
106
- const attachmentsOwned = excludedProjections.has('task-attachment-links/full-v1');
107
- if (excludedProjections.has('task/root-v1') && commentsOwned && checklistOwned && attachmentsOwned) {
107
+ const attachmentProjection = excludedProjections.has('task-attachment-links/full-v2')
108
+ ? 'task-attachment-links/full-v2'
109
+ : 'task-attachment-links/full-v1';
110
+ const attachmentsOwned = excludedProjections.has(attachmentProjection);
111
+ if (excludedProjections.has('task/root-v1'))
108
112
  suppress('task/root-v1');
109
- suppress('task-comments/full-v1');
110
- suppress('task-checklist/full-v1');
111
- suppress('task-attachment-links/full-v1');
112
- continue;
113
- }
114
113
  if (commentsOwned || checklistOwned || attachmentsOwned) {
115
114
  const task = { ...change.task };
116
115
  if (commentsOwned) {
@@ -123,7 +122,10 @@ export function partitionWorkspaceSyncV2LegacyChanges(changes, excludedProjectio
123
122
  }
124
123
  if (attachmentsOwned) {
125
124
  delete task.attachments;
126
- suppress('task-attachment-links/full-v1');
125
+ if (attachmentProjection === 'task-attachment-links/full-v2') {
126
+ delete task.cardCoverAssetId;
127
+ }
128
+ suppress(attachmentProjection);
127
129
  }
128
130
  accepted.push({ ...change, task });
129
131
  continue;
@@ -15,10 +15,13 @@ export interface WorkspaceSyncV3AttachmentApplyObligation {
15
15
  createdAt: string;
16
16
  updatedAt: string;
17
17
  nextAttemptAt: string;
18
+ terminalAt: string | null;
19
+ terminalReason: string | null;
18
20
  resolvedAt: string | null;
19
21
  }
20
22
  export interface WorkspaceSyncV3AttachmentApplyObligationSummary {
21
23
  open: number;
24
+ terminal: number;
22
25
  due: number;
23
26
  oldestOpenCreatedAt: string | null;
24
27
  nextAttemptAt: string | null;
@@ -70,6 +73,14 @@ export declare class WorkspaceSyncV3AttachmentApplyObligationStore {
70
73
  taskId: string;
71
74
  now: string;
72
75
  }): void;
76
+ markTerminalUnavailable(input: {
77
+ tenantId: string;
78
+ workspaceId: string;
79
+ taskId: string;
80
+ canonicalFingerprint: string;
81
+ reason: string;
82
+ now: string;
83
+ }): void;
73
84
  recordAttemptFailure(input: {
74
85
  tenantId: string;
75
86
  workspaceId: string;
@@ -28,6 +28,8 @@ function mapRow(row) {
28
28
  createdAt: row.created_at,
29
29
  updatedAt: row.updated_at,
30
30
  nextAttemptAt: row.next_attempt_at,
31
+ terminalAt: row.terminal_at,
32
+ terminalReason: row.terminal_reason,
31
33
  resolvedAt: row.resolved_at,
32
34
  };
33
35
  }
@@ -52,8 +54,8 @@ export class WorkspaceSyncV3AttachmentApplyObligationStore {
52
54
  tenant_id, workspace_id, task_id, asset_ids_json, payload_json,
53
55
  canonical_fingerprint, source_sequence, attempts, last_error,
54
56
  entity_revision, lifecycle_revision, revision_fingerprint,
55
- created_at, updated_at, next_attempt_at, resolved_at
56
- ) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?, NULL)
57
+ created_at, updated_at, next_attempt_at, terminal_at, terminal_reason, resolved_at
58
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?, NULL, NULL, NULL)
57
59
  ON CONFLICT (tenant_id, workspace_id, task_id) DO UPDATE SET
58
60
  asset_ids_json = excluded.asset_ids_json,
59
61
  payload_json = excluded.payload_json,
@@ -66,6 +68,8 @@ export class WorkspaceSyncV3AttachmentApplyObligationStore {
66
68
  last_error = excluded.last_error,
67
69
  updated_at = excluded.updated_at,
68
70
  next_attempt_at = excluded.next_attempt_at,
71
+ terminal_at = NULL,
72
+ terminal_reason = NULL,
69
73
  resolved_at = NULL
70
74
  WHERE workspace_sync_v3_attachment_apply_obligations.resolved_at IS NOT NULL
71
75
  OR CAST(excluded.source_sequence AS ${this.db.provider === 'postgres' ? 'BIGINT' : 'INTEGER'})
@@ -77,7 +81,8 @@ export class WorkspaceSyncV3AttachmentApplyObligationStore {
77
81
  const rows = this.db.prepare(`
78
82
  SELECT *
79
83
  FROM workspace_sync_v3_attachment_apply_obligations
80
- WHERE tenant_id = ? AND workspace_id = ? AND resolved_at IS NULL AND next_attempt_at <= ?
84
+ WHERE tenant_id = ? AND workspace_id = ?
85
+ AND resolved_at IS NULL AND terminal_at IS NULL AND next_attempt_at <= ?
81
86
  ORDER BY next_attempt_at ASC, task_id ASC
82
87
  LIMIT ?
83
88
  `).all(input.tenantId, input.workspaceId, input.now, limit);
@@ -87,30 +92,34 @@ export class WorkspaceSyncV3AttachmentApplyObligationStore {
87
92
  const row = this.db.prepare(`
88
93
  SELECT COUNT(*) AS count
89
94
  FROM workspace_sync_v3_attachment_apply_obligations
90
- WHERE tenant_id = ? AND workspace_id = ? AND resolved_at IS NULL
95
+ WHERE tenant_id = ? AND workspace_id = ?
96
+ AND resolved_at IS NULL AND terminal_at IS NULL
91
97
  `).get(input.tenantId, input.workspaceId);
92
98
  return Number(row?.count || 0);
93
99
  }
94
100
  readSummary(input) {
95
101
  const aggregate = this.db.prepare(`
96
- SELECT COUNT(*) AS open,
97
- SUM(CASE WHEN next_attempt_at <= ? THEN 1 ELSE 0 END) AS due,
98
- MIN(created_at) AS oldest_open_created_at,
99
- MIN(next_attempt_at) AS next_attempt_at,
100
- SUM(attempts) AS total_attempts
102
+ SELECT SUM(CASE WHEN terminal_at IS NULL THEN 1 ELSE 0 END) AS open,
103
+ SUM(CASE WHEN terminal_at IS NOT NULL THEN 1 ELSE 0 END) AS terminal,
104
+ SUM(CASE WHEN terminal_at IS NULL AND next_attempt_at <= ? THEN 1 ELSE 0 END) AS due,
105
+ MIN(CASE WHEN terminal_at IS NULL THEN created_at END) AS oldest_open_created_at,
106
+ MIN(CASE WHEN terminal_at IS NULL THEN next_attempt_at END) AS next_attempt_at,
107
+ SUM(CASE WHEN terminal_at IS NULL THEN attempts ELSE 0 END) AS total_attempts
101
108
  FROM workspace_sync_v3_attachment_apply_obligations
102
109
  WHERE tenant_id = ? AND workspace_id = ? AND resolved_at IS NULL
103
110
  `).get(input.now, input.tenantId, input.workspaceId);
104
111
  const latest = this.db.prepare(`
105
112
  SELECT last_error
106
113
  FROM workspace_sync_v3_attachment_apply_obligations
107
- WHERE tenant_id = ? AND workspace_id = ? AND resolved_at IS NULL
114
+ WHERE tenant_id = ? AND workspace_id = ?
115
+ AND resolved_at IS NULL AND terminal_at IS NULL
108
116
  AND last_error IS NOT NULL
109
117
  ORDER BY updated_at DESC, task_id ASC
110
118
  LIMIT 1
111
119
  `).get(input.tenantId, input.workspaceId);
112
120
  return {
113
121
  open: Number(aggregate?.open || 0),
122
+ terminal: Number(aggregate?.terminal || 0),
114
123
  due: Number(aggregate?.due || 0),
115
124
  oldestOpenCreatedAt: aggregate?.oldest_open_created_at || null,
116
125
  nextAttemptAt: aggregate?.next_attempt_at || null,
@@ -142,6 +151,14 @@ export class WorkspaceSyncV3AttachmentApplyObligationStore {
142
151
  WHERE tenant_id = ? AND workspace_id = ? AND task_id = ? AND resolved_at IS NULL
143
152
  `).run(input.now, input.now, input.tenantId, input.workspaceId, input.taskId);
144
153
  }
154
+ markTerminalUnavailable(input) {
155
+ this.db.prepare(`
156
+ UPDATE workspace_sync_v3_attachment_apply_obligations
157
+ SET terminal_at = ?, terminal_reason = ?, last_error = ?, updated_at = ?
158
+ WHERE tenant_id = ? AND workspace_id = ? AND task_id = ?
159
+ AND canonical_fingerprint = ? AND resolved_at IS NULL AND terminal_at IS NULL
160
+ `).run(input.now, String(input.reason || '').slice(0, 500), String(input.reason || '').slice(0, 500), input.now, input.tenantId, input.workspaceId, input.taskId, input.canonicalFingerprint);
161
+ }
145
162
  recordAttemptFailure(input) {
146
163
  this.db.prepare(`
147
164
  UPDATE workspace_sync_v3_attachment_apply_obligations
@@ -7,10 +7,11 @@ export type WorkspaceSyncV3AttachmentAssetHydrationResult = {
7
7
  } | {
8
8
  success: false;
9
9
  error: string;
10
+ disposition?: 'retryable' | 'terminal-unavailable';
10
11
  };
11
12
  export declare function hydrateWorkspaceSyncV3AttachmentAsset(input: {
12
13
  workspaceId: string;
13
14
  assetId: string;
14
- remoteServices: Pick<WorkspaceSyncEngineRemoteServices, 'pullWorkspaceContent' | 'abandonTransferReceipts' | 'buildV2ApplyCompletionGroup'>;
15
+ remoteServices: Pick<WorkspaceSyncEngineRemoteServices, 'pullWorkspaceContent' | 'abandonTransferReceipts' | 'buildIndependentContentApplyCompletionGroup'>;
15
16
  localServices: Pick<WorkspaceSyncEngineLocalServices, 'applyV2Batch'>;
16
17
  }): Promise<WorkspaceSyncV3AttachmentAssetHydrationResult>;