@taskforcehq/taskforce 0.3.329 → 0.3.332

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 (363) hide show
  1. package/README.md +7 -2
  2. package/dist/Taskforce.module.css +290 -45
  3. package/dist/components/features/AiProfilesModule.js +3 -5
  4. package/dist/components/features/TaskSettings.js +70 -14
  5. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  6. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  7. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
  8. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
  9. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  10. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  11. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  12. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  13. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  14. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  15. package/dist/components/features/planning/PlanningModule.js +15 -3
  16. package/dist/components/features/planning/planningMetadata.d.ts +10 -0
  17. package/dist/components/features/planning/planningMetadata.js +8 -0
  18. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  19. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  20. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  21. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  22. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  23. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  24. package/dist/components/views/StandaloneLayout.js +62 -27
  25. package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
  26. package/dist/components/views/panels/PlanningDrawer.js +12 -8
  27. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  28. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  29. package/dist/config/envSchema.js +55 -1
  30. package/dist/core/McpTokenService.d.ts +25 -1
  31. package/dist/core/McpTokenService.js +106 -15
  32. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  33. package/dist/core/TaskChecklistCommandService.js +83 -5
  34. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  35. package/dist/core/TaskLifecycleCommandService.js +6 -2
  36. package/dist/core/Taskforce.d.ts +43 -3
  37. package/dist/core/Taskforce.js +158 -7
  38. package/dist/core/types.d.ts +9 -0
  39. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
  40. package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
  41. package/dist/documentReviews/commandService.d.ts +2 -1
  42. package/dist/documentReviews/commandService.js +6 -3
  43. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  44. package/dist/hooks/sync/orchestratorShared.js +2 -0
  45. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  46. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  47. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  48. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  49. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  50. package/dist/hooks/useSyncOrchestrator.js +111 -2
  51. package/dist/hooks/useTaskData.d.ts +31 -1
  52. package/dist/hooks/useTaskData.js +29 -7
  53. package/dist/hooks/useTaskMutations.d.ts +3 -1
  54. package/dist/hooks/useTaskMutations.js +46 -12
  55. package/dist/hooks/useTaskforce.d.ts +2 -0
  56. package/dist/hooks/useTaskforce.js +11 -2
  57. package/dist/mcp/clientRegistry.d.ts +2 -2
  58. package/dist/mcp/clientRegistry.js +1 -1
  59. package/dist/mcp/documentAssetRegistrar.js +9 -6
  60. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  61. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  62. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  63. package/dist/mcp/httpProtocolRouting.d.ts +11 -0
  64. package/dist/mcp/httpProtocolRouting.js +22 -0
  65. package/dist/mcp/localCliHealth.d.ts +2 -2
  66. package/dist/mcp/localCliHealth.js +2 -2
  67. package/dist/mcp/localServiceProxy.d.ts +1 -0
  68. package/dist/mcp/localServiceProxy.js +530 -68
  69. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  70. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  71. package/dist/mcp/runtime.d.ts +54 -79
  72. package/dist/mcp/runtime.js +408 -102
  73. package/dist/mcp/taskPlanningRegistrar.js +25 -6
  74. package/dist/mcp/toolProfiles.d.ts +2 -0
  75. package/dist/mcp/toolProfiles.js +11 -0
  76. package/dist/mcp/toolRegistry.d.ts +1 -0
  77. package/dist/mcp/toolRegistry.js +9 -8
  78. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  79. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  80. package/dist/migrations/taskSchemaMigrations.js +415 -0
  81. package/dist/runtime/appGates.d.ts +2 -1
  82. package/dist/runtime/appGates.js +7 -0
  83. package/dist/server/buildInfo.d.ts +1 -0
  84. package/dist/server/buildInfo.js +5 -1
  85. package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
  86. package/dist/server/cloudMcpCapacityTelemetry.js +221 -0
  87. package/dist/server/index.d.ts +3 -0
  88. package/dist/server/index.js +108 -11
  89. package/dist/server/localDatabaseIdentity.js +4 -1
  90. package/dist/server/localServiceLease.js +2 -1
  91. package/dist/server/localServiceSessions.d.ts +14 -17
  92. package/dist/server/localServiceSessions.js +308 -94
  93. package/dist/server/localWorkspaceSyncServerRuntime.js +25 -19
  94. package/dist/server/routes/admin.d.ts +4 -0
  95. package/dist/server/routes/admin.js +126 -5
  96. package/dist/server/routes/agents.d.ts +7 -0
  97. package/dist/server/routes/agents.js +277 -24
  98. package/dist/server/routes/billing.js +5 -1
  99. package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
  100. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  101. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  102. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  103. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  104. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  105. package/dist/server/routes/githubReviewEvidence.js +116 -0
  106. package/dist/server/routes/localService.d.ts +15 -4
  107. package/dist/server/routes/localService.js +136 -40
  108. package/dist/server/routes/modelConnections.d.ts +24 -0
  109. package/dist/server/routes/modelConnections.js +205 -0
  110. package/dist/server/routes/shared.d.ts +22 -0
  111. package/dist/server/routes/shared.js +298 -182
  112. package/dist/server/routes/sync.js +1 -0
  113. package/dist/server/routes/syncAuxRoutes.js +5 -1
  114. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  115. package/dist/server/routes/syncPushRoutes.js +1 -0
  116. package/dist/server/routes/syncV3FeedRoutes.js +10 -1
  117. package/dist/server/routes/syncV3OperationRoutes.js +35 -9
  118. package/dist/server/routes/tasks.js +21 -2
  119. package/dist/server/routes/workflows.js +9 -1
  120. package/dist/server/routes.js +59 -0
  121. package/dist/service/localServiceCli.d.ts +2 -2
  122. package/dist/service/localServiceCli.js +4 -3
  123. package/dist/services/codexAppServerModelGateway.d.ts +54 -5
  124. package/dist/services/codexAppServerModelGateway.js +246 -21
  125. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  126. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  127. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  128. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  129. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  130. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  131. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  132. package/dist/services/executorPhaseAApprovalService.js +609 -0
  133. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  134. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  135. package/dist/services/executorPhaseAIssuerCore.d.ts +139 -0
  136. package/dist/services/executorPhaseAIssuerCore.js +402 -0
  137. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  138. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  139. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  140. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  141. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  142. package/dist/services/githubReviewEvidenceService.js +336 -0
  143. package/dist/services/modelGateway.d.ts +7 -0
  144. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  145. package/dist/services/modelProviderConnectionService.js +279 -0
  146. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  147. package/dist/services/modelProviderCredentialHome.js +271 -0
  148. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  149. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  150. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  151. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  152. package/dist/services/taskforceAgentMcpBridge.d.ts +2 -2
  153. package/dist/services/taskforceAgentMcpBridge.js +42 -29
  154. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  155. package/dist/shared/adminEdgeProxy.js +94 -0
  156. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  157. package/dist/shared/adminProxySessionCookies.js +86 -0
  158. package/dist/shared/aiProfileColors.d.ts +31 -1
  159. package/dist/shared/aiProfileColors.js +14 -6
  160. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  161. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  162. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  163. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  164. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  165. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  166. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  167. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  168. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  169. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  170. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  171. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  172. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  173. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  174. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  175. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  176. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  177. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  178. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  179. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  180. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  181. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  182. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  183. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  184. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  185. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  186. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  187. package/dist/shared/executorPhaseATiming.js +1 -0
  188. package/dist/shared/planningIdentity.js +1 -1
  189. package/dist/shared/productLogoKeys.d.ts +2 -0
  190. package/dist/shared/productLogoKeys.js +18 -0
  191. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  192. package/dist/shared/taskforceAgentDefinition.js +6 -9
  193. package/dist/shared/taskforceAgentModels.js +7 -3
  194. package/dist/shared/userFeatureGrants.d.ts +4 -0
  195. package/dist/shared/userFeatureGrants.js +7 -0
  196. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  197. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  198. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  199. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  200. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  201. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  202. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  203. package/dist/storage/modelProviderConnectionStore.js +446 -0
  204. package/dist/storage/postgresAdapter.d.ts +4 -0
  205. package/dist/storage/postgresAdapter.js +14 -1
  206. package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
  207. package/dist/storage/postgresRequestDiagnostics.js +15 -2
  208. package/dist/storage/postgresWorker.js +20 -2
  209. package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
  210. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  211. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  212. package/dist/storage/workflowStore.d.ts +2 -0
  213. package/dist/storage/workflowStore.js +39 -2
  214. package/dist/sync/cloudSyncApi.js +4 -2
  215. package/dist/sync/collaborationSyncState.js +5 -0
  216. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
  217. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  218. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  219. package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +3 -1
  220. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -0
  221. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  222. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  223. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  224. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  225. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  226. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  227. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  228. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  229. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  230. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  231. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  232. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  233. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  234. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
  235. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  236. package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
  237. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  238. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +31 -0
  239. package/dist/sync/syncApplyHandlers.d.ts +3 -0
  240. package/dist/sync/syncApplyHandlers.js +81 -15
  241. package/dist/sync/syncService.d.ts +15 -0
  242. package/dist/sync/syncService.js +83 -18
  243. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  244. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  245. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  246. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  247. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  248. package/dist/sync/v3/durableOperationReplay.js +18 -0
  249. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
  250. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
  251. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
  252. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  253. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
  254. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
  255. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  256. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +18 -7
  257. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
  258. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  259. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  260. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  261. package/dist/sync/v3/localOutboxRecoveryPreparationService.js +8 -2
  262. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  263. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  264. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  265. package/dist/sync/v3/localTaskCreateOutboxService.d.ts +3 -1
  266. package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
  267. package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
  268. package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
  269. package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
  270. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
  271. package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
  272. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
  273. package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
  274. package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
  275. package/dist/sync/v3/syncDurabilityStore.js +202 -8
  276. package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
  277. package/dist/sync/v3/taskChecklistMutationService.js +44 -1
  278. package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
  279. package/dist/sync/v3/taskStatusMutationService.js +119 -3
  280. package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
  281. package/dist/sync/v3/workflowAssignmentSync.js +27 -0
  282. package/dist/sync/v3/workflowRuntimeMutationService.d.ts +5 -0
  283. package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
  284. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  285. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  286. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  287. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  288. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
  289. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +25 -3
  290. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
  291. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
  292. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
  293. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
  294. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  295. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
  296. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
  297. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
  298. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  299. package/dist/sync/v3/workspaceSyncV3Feed.d.ts +1 -0
  300. package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
  301. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
  302. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
  303. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
  304. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
  305. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
  306. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  307. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  308. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
  309. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
  310. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  311. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  312. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  313. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  314. package/dist/sync/workspaceRepair.d.ts +5 -2
  315. package/dist/sync/workspaceRepair.js +161 -6
  316. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  317. package/dist/sync/workspaceSyncModel.js +35 -7
  318. package/dist/sync/workspaceSyncState.d.ts +1 -0
  319. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  320. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  321. package/dist/ui/assets/AiIdentityRosterCard-CDMPtnbC.js +1 -0
  322. package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
  323. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
  324. package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
  325. package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
  326. package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
  327. package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
  328. package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
  329. package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
  330. package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
  331. package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
  332. package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
  333. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  334. package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
  335. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  336. package/dist/ui/assets/index-DSQINwt9.js +7 -0
  337. package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
  338. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  339. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  340. package/dist/ui/branding/logos/signature_dark.png +0 -0
  341. package/dist/ui/branding/logos/signature_light.png +0 -0
  342. package/dist/ui/index.html +3 -3
  343. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  344. package/dist/utils/httpSetCookie.d.ts +1 -0
  345. package/dist/utils/httpSetCookie.js +4 -1
  346. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  347. package/dist/utils/localRuntimeUrl.js +14 -0
  348. package/dist/utils/productLogoRegistry.d.ts +2 -0
  349. package/dist/utils/productLogoRegistry.js +36 -0
  350. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  351. package/dist/utils/syncStatusPresentation.js +17 -0
  352. package/dist/utils/taskEvents.d.ts +2 -0
  353. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  354. package/dist/utils/workspaceSyncPresentation.js +23 -17
  355. package/package.json +24 -4
  356. package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
  357. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
  358. package/dist/ui/assets/PlanningModule-B5DWQOGz.js +0 -1
  359. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
  360. package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
  361. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  362. package/dist/ui/assets/index-I5zhdtgt.js +0 -7
  363. package/dist/ui/assets/index-VRFsx3wz.css +0 -1
@@ -1,5 +1,5 @@
1
1
  import type { WorkflowExecutionAction, WorkflowStepCompletionActorType } from '../../core/WorkflowExecutionService.js';
2
- import { type WorkflowExecutionStatus } from '../../storage/workflowStore.js';
2
+ import { type WorkflowExecutionEventRecord, type WorkflowExecutionStatus } from '../../storage/workflowStore.js';
3
3
  import { type LocalWorkflowRuntimeOutboxCore } from './localWorkflowRuntimeOutboxService.js';
4
4
  import { type DurableWorkflowRuntimeServiceCore } from './workflowRuntimeMutationService.js';
5
5
  export type DurableWorkflowRuntimeSurface = 'http' | 'mcp';
@@ -15,11 +15,22 @@ export declare class DurableWorkflowRuntimeRouterInProgressError extends Error {
15
15
  readonly statusCode = 409;
16
16
  constructor(retryAt: string);
17
17
  }
18
+ export declare class DurableWorkflowRuntimeExecutionNotFoundError extends Error {
19
+ readonly code = "execution_not_found";
20
+ readonly statusCode = 404;
21
+ constructor();
22
+ }
23
+ export declare function areWorkflowRuntimeMutationsFenced(env?: NodeJS.ProcessEnv): boolean;
18
24
  export declare function resolveWorkflowRuntimeMutationCapability(input: {
19
25
  runtimeMode: 'local' | 'cloud';
20
26
  surface: DurableWorkflowRuntimeSurface;
21
27
  env?: NodeJS.ProcessEnv;
22
28
  }): boolean;
29
+ export declare function resolveWorkflowRuntimeDurableTransportCapability(input: {
30
+ runtimeMode: 'local' | 'cloud';
31
+ surface: DurableWorkflowRuntimeSurface;
32
+ env?: NodeJS.ProcessEnv;
33
+ }): boolean;
23
34
  export declare function createDurableWorkflowRuntimeMutationRouter(input: {
24
35
  core: DurableWorkflowRuntimeMutationRouterCore;
25
36
  runtimeMode: 'local' | 'cloud';
@@ -42,11 +53,11 @@ export declare function createDurableWorkflowRuntimeMutationRouter(input: {
42
53
  details?: Record<string, unknown>;
43
54
  }): {
44
55
  state: "pending" | "committed";
45
- route: "local-outbox" | "cloud-acceptance";
56
+ route: "local-outbox" | "cloud-acceptance" | "local-projection-replay";
46
57
  operationId: string;
47
58
  execution: import("../../storage/workflowStore.js").WorkflowExecutionRecord;
48
- events: import("../../storage/workflowStore.js").WorkflowExecutionEventRecord[];
49
- event: import("../../storage/workflowStore.js").WorkflowExecutionEventRecord | null;
59
+ events: WorkflowExecutionEventRecord[];
60
+ event: WorkflowExecutionEventRecord | null;
50
61
  completedStep: import("../../storage/workflowStore.js").WorkflowStepRecord | null;
51
62
  nextStep: import("../../storage/workflowStore.js").WorkflowStepRecord | null;
52
63
  taskAssignee: string | null;
@@ -61,11 +72,11 @@ export declare function createDurableWorkflowRuntimeMutationRouter(input: {
61
72
  evidenceCommentId?: string;
62
73
  }): {
63
74
  state: "pending" | "committed";
64
- route: "local-outbox" | "cloud-acceptance";
75
+ route: "local-outbox" | "cloud-acceptance" | "local-projection-replay";
65
76
  operationId: string;
66
77
  execution: import("../../storage/workflowStore.js").WorkflowExecutionRecord;
67
- events: import("../../storage/workflowStore.js").WorkflowExecutionEventRecord[];
68
- event: import("../../storage/workflowStore.js").WorkflowExecutionEventRecord | null;
78
+ events: WorkflowExecutionEventRecord[];
79
+ event: WorkflowExecutionEventRecord | null;
69
80
  completedStep: import("../../storage/workflowStore.js").WorkflowStepRecord | null;
70
81
  nextStep: import("../../storage/workflowStore.js").WorkflowStepRecord | null;
71
82
  taskAssignee: string | null;
@@ -1,4 +1,4 @@
1
- import { WorkflowStore } from '../../storage/workflowStore.js';
1
+ import { WorkflowStore, } from '../../storage/workflowStore.js';
2
2
  import { LocalSyncIdentityStore } from './localSyncIdentityStore.js';
3
3
  import { canonicalWorkspaceSyncJson } from './canonicalWorkspaceSyncJson.js';
4
4
  import { enqueueLocalWorkflowRuntimeMutation, } from './localWorkflowRuntimeOutboxService.js';
@@ -7,6 +7,7 @@ import { WorkspaceSyncDurabilityStore, } from './syncDurabilityStore.js';
7
7
  import { runDurableWorkflowRuntimeMutation, } from './workflowRuntimeMutationService.js';
8
8
  import { validateWorkflowRuntimeAuthoritativeResult, validateWorkflowRuntimeMutationCommand, } from './workflowRuntimeSync.js';
9
9
  import { WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowWireContract.js';
10
+ import { WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR, } from './workspaceSyncV3WorkflowTaskCoverWireContract.js';
10
11
  const OPERATION_LEASE_MS = 30_000;
11
12
  export class DurableWorkflowRuntimeRouterDisabledError extends Error {
12
13
  code = 'WORKSPACE_SYNC_V3_WORKFLOW_RUNTIME_ROUTER_DISABLED';
@@ -26,31 +27,55 @@ export class DurableWorkflowRuntimeRouterInProgressError extends Error {
26
27
  this.name = 'DurableWorkflowRuntimeRouterInProgressError';
27
28
  }
28
29
  }
30
+ export class DurableWorkflowRuntimeExecutionNotFoundError extends Error {
31
+ code = 'execution_not_found';
32
+ statusCode = 404;
33
+ constructor() {
34
+ super('Workflow execution not found.');
35
+ this.name = 'DurableWorkflowRuntimeExecutionNotFoundError';
36
+ }
37
+ }
38
+ export function areWorkflowRuntimeMutationsFenced(env = process.env) {
39
+ return String(env.TASKFORCE_SYNC_V3_WORKFLOW_RUNTIME_MUTATIONS_FENCED || '')
40
+ .trim()
41
+ .toLowerCase() === 'true';
42
+ }
29
43
  function required(value, label) {
30
44
  const normalized = String(value || '').trim();
31
45
  if (!normalized)
32
46
  throw new Error(`${label} is required.`);
33
47
  return normalized;
34
48
  }
35
- function isWorkflowCoverageSelected(env) {
49
+ const WORKFLOW_RUNTIME_COVERAGE_SELECTORS = [
50
+ WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR,
51
+ WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR,
52
+ ];
53
+ function resolveSelectedWorkflowCoverage(env) {
36
54
  try {
37
55
  const coverage = resolveRequestedCombinedFeedCoverage(env);
38
- return coverage.coverageProfileId === WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR.coverageProfileId
39
- && coverage.coverageVersion === WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR.coverageVersion
40
- && coverage.coverageDigest === WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR.coverageDigest;
56
+ return WORKFLOW_RUNTIME_COVERAGE_SELECTORS.find((candidate) => (coverage.coverageProfileId === candidate.coverageProfileId
57
+ && coverage.coverageVersion === candidate.coverageVersion
58
+ && coverage.coverageDigest === candidate.coverageDigest)) || null;
41
59
  }
42
60
  catch {
43
- return false;
61
+ return null;
44
62
  }
45
63
  }
46
64
  export function resolveWorkflowRuntimeMutationCapability(input) {
47
65
  const env = input.env || process.env;
48
- if (!isWorkflowCoverageSelected(env))
66
+ if (areWorkflowRuntimeMutationsFenced(env))
67
+ return false;
68
+ return resolveWorkflowRuntimeDurableTransportCapability(input);
69
+ }
70
+ export function resolveWorkflowRuntimeDurableTransportCapability(input) {
71
+ const env = input.env || process.env;
72
+ const coverage = resolveSelectedWorkflowCoverage(env);
73
+ if (!coverage)
49
74
  return false;
50
75
  const capability = resolveCombinedFeedCapability({
51
76
  runtimeMode: input.runtimeMode,
52
77
  env,
53
- coverage: WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR,
78
+ coverage,
54
79
  }).combinedFeed;
55
80
  return capability.activationReady;
56
81
  }
@@ -62,7 +87,11 @@ function parseExistingLocalCommand(store, identity) {
62
87
  throw new Error('Operation identity is assigned to another local mutation.');
63
88
  }
64
89
  try {
65
- return validateWorkflowRuntimeMutationCommand(JSON.parse(existing.payloadJson));
90
+ const command = validateWorkflowRuntimeMutationCommand(JSON.parse(existing.payloadJson));
91
+ store.assertOutboxOperationIdentity(existing, {
92
+ domain: 'workflow-execution', entityId: command.executionId, mutationKind: command.kind,
93
+ });
94
+ return command;
66
95
  }
67
96
  catch {
68
97
  throw new Error('Captured workflow runtime command is invalid.');
@@ -81,6 +110,31 @@ function taskTarget(input) {
81
110
  baseLifecycleRevision: coordinates.lifecycleRevision,
82
111
  };
83
112
  }
113
+ function matchCompletedStepReplay(input) {
114
+ const completedEvent = input.events.find((event) => event.idempotencyKey === `${input.operationId}:step-completed`);
115
+ const terminalEvent = input.events.find((event) => (event.idempotencyKey === `${input.operationId}:step-started`
116
+ || event.idempotencyKey === `${input.operationId}:execution-completed`));
117
+ if (!completedEvent && !terminalEvent)
118
+ return 'absent';
119
+ if (!completedEvent
120
+ || !terminalEvent
121
+ || completedEvent.eventType !== 'step-completed'
122
+ || (terminalEvent.eventType !== 'step-started'
123
+ && terminalEvent.eventType !== 'execution-completed')
124
+ || completedEvent.actorId !== input.actorId
125
+ || terminalEvent.actorId !== input.actorId
126
+ || (input.expectedStepId !== undefined && completedEvent.stepId !== input.expectedStepId)) {
127
+ return 'conflict';
128
+ }
129
+ const evidence = completedEvent.details.evidence;
130
+ const replayCommentId = evidence
131
+ && typeof evidence === 'object'
132
+ && !Array.isArray(evidence)
133
+ && evidence.type === 'comment'
134
+ ? String(evidence.commentId || '')
135
+ : '';
136
+ return (input.evidenceCommentId || '') === replayCommentId ? 'exact' : 'conflict';
137
+ }
84
138
  function buildResult(input) {
85
139
  const workflowStore = new WorkflowStore(input.core.getDatabaseAdapter(), input.core.getTenantId());
86
140
  const assignmentSnapshot = workflowStore.getAssignmentForExecutionSync(input.workspaceId, input.executionId);
@@ -91,7 +145,8 @@ function buildResult(input) {
91
145
  const completedStep = completedEvent?.stepId
92
146
  ? assignmentSnapshot.steps.find((step) => step.id === completedEvent.stepId) || null
93
147
  : null;
94
- const nextStep = assignmentSnapshot.execution.currentStepId
148
+ const nextStep = assignmentSnapshot.execution.status === 'running'
149
+ && assignmentSnapshot.execution.currentStepId
95
150
  ? assignmentSnapshot.steps.find((step) => step.id === assignmentSnapshot.execution.currentStepId) || null
96
151
  : null;
97
152
  const taskSnapshot = input.core.getTask(assignmentSnapshot.execution.taskId, input.workspaceId);
@@ -254,7 +309,7 @@ export function createDurableWorkflowRuntimeMutationRouter(input) {
254
309
  const workflowStore = new WorkflowStore(input.core.getDatabaseAdapter(), tenantId);
255
310
  const snapshot = workflowStore.getExecutionStateSnapshot(workspaceId, args.executionId);
256
311
  if (!snapshot)
257
- throw new Error('Workflow execution not found.');
312
+ throw new DurableWorkflowRuntimeExecutionNotFoundError();
258
313
  const committed = readCommittedCloudResponse();
259
314
  if (committed) {
260
315
  const event = snapshot.events.find((candidate) => candidate.idempotencyKey === operationId);
@@ -307,20 +362,17 @@ export function createDurableWorkflowRuntimeMutationRouter(input) {
307
362
  const workflowStore = new WorkflowStore(input.core.getDatabaseAdapter(), tenantId);
308
363
  const snapshot = workflowStore.getExecutionStateSnapshot(workspaceId, args.executionId);
309
364
  if (!snapshot)
310
- throw new Error('Workflow execution not found.');
365
+ throw new DurableWorkflowRuntimeExecutionNotFoundError();
311
366
  const committed = readCommittedCloudResponse();
367
+ const replayMatch = matchCompletedStepReplay({
368
+ events: snapshot.events,
369
+ operationId,
370
+ actorId,
371
+ expectedStepId: args.expectedStepId,
372
+ evidenceCommentId: args.evidenceCommentId,
373
+ });
312
374
  if (committed) {
313
- const completedEvent = snapshot.events.find((event) => event.idempotencyKey === `${operationId}:step-completed`);
314
- const terminalEvent = snapshot.events.find((event) => (event.idempotencyKey === `${operationId}:step-started`
315
- || event.idempotencyKey === `${operationId}:execution-completed`));
316
- if (!completedEvent
317
- || !terminalEvent
318
- || completedEvent.actorId !== actorId
319
- || terminalEvent.actorId !== actorId
320
- || (args.expectedStepId !== undefined && completedEvent.stepId !== args.expectedStepId)
321
- || (args.evidenceCommentId !== undefined
322
- && completedEvent.details.evidence?.commentId
323
- !== args.evidenceCommentId)) {
375
+ if (replayMatch !== 'exact') {
324
376
  throw new Error('Operation identity is assigned to a different workflow step command.');
325
377
  }
326
378
  return buildResult({
@@ -334,6 +386,20 @@ export function createDurableWorkflowRuntimeMutationRouter(input) {
334
386
  replayed: true,
335
387
  });
336
388
  }
389
+ if (!existing && replayMatch !== 'absent') {
390
+ if (replayMatch === 'conflict') {
391
+ throw new Error('Operation identity is assigned to a different workflow step command.');
392
+ }
393
+ return buildResult({
394
+ core: input.core,
395
+ workspaceId,
396
+ executionId: args.executionId,
397
+ operationId,
398
+ state: 'committed',
399
+ route: 'local-projection-replay',
400
+ replayed: true,
401
+ });
402
+ }
337
403
  const expectedStepId = args.expectedStepId || snapshot.execution.currentStepId;
338
404
  if (!expectedStepId)
339
405
  throw new Error('Workflow execution current step is unavailable.');
@@ -7,6 +7,7 @@ import { enqueueLocalWorkstreamMutation, } from './localWorkstreamOutboxService.
7
7
  import { isWorkspaceSyncV3PlanningActivationEnabled } from './planningActivation.js';
8
8
  import { serializeEntityActivityForSync } from './taskActivityJournal.js';
9
9
  import { WorkspaceSyncDurabilityStore, WorkspaceSyncIdempotencyConflictError } from './syncDurabilityStore.js';
10
+ import { readDurableOperationReplay } from './durableOperationReplay.js';
10
11
  import { buildWorkstreamActivityEventId } from './workstreamActivityIdentity.js';
11
12
  const OPERATION_LEASE_MS = 30_000;
12
13
  export class DurableWorkstreamMutationRouterDisabledError extends Error {
@@ -85,6 +86,9 @@ export function createDurableWorkstreamMutationRouter(input) {
85
86
  if (persistedOutbox.domain !== 'workstream' || persistedOutbox.entityId !== workstreamId) {
86
87
  throw new WorkspaceSyncIdempotencyConflictError();
87
88
  }
89
+ store.assertOutboxOperationIdentity(persistedOutbox, {
90
+ domain: 'workstream', entityId: workstreamId, mutationKind: persistedOutbox.mutationKind,
91
+ });
88
92
  return {
89
93
  revisions: {
90
94
  entityRevision: persistedOutbox.baseEntityRevision,
@@ -99,18 +103,22 @@ export function createDurableWorkstreamMutationRouter(input) {
99
103
  if (operationState?.status === 'committed') {
100
104
  if (!operationState.responseJson)
101
105
  throw new Error('Committed operation is missing its response.');
102
- const response = JSON.parse(operationState.responseJson);
103
- if (response.authoritative.entityId !== workstreamId) {
104
- throw new WorkspaceSyncIdempotencyConflictError();
105
- }
106
- const lifecycleMutation = response.authoritative.mutationKind === 'archive'
107
- || response.authoritative.mutationKind === 'unarchive';
106
+ const parsed = JSON.parse(operationState.responseJson);
107
+ const lifecycleMutation = parsed.authoritative.mutationKind === 'archive'
108
+ || parsed.authoritative.mutationKind === 'unarchive';
109
+ const replay = readDurableOperationReplay({
110
+ responseJson: operationState.responseJson,
111
+ operationId,
112
+ domain: 'workstream',
113
+ entityId: workstreamId,
114
+ mutationKind: parsed.authoritative.mutationKind,
115
+ revisionMode: lifecycleMutation ? 'both' : 'metadata',
116
+ });
117
+ const response = replay.response;
108
118
  return {
109
119
  revisions: {
110
- entityRevision: String(BigInt(response.authoritative.entityRevision) - 1n),
111
- lifecycleRevision: lifecycleMutation
112
- ? String(BigInt(response.authoritative.lifecycleRevision) - 1n)
113
- : response.authoritative.lifecycleRevision,
120
+ entityRevision: replay.baseEntityRevision,
121
+ lifecycleRevision: replay.baseLifecycleRevision,
114
122
  },
115
123
  persistedOutbox: null,
116
124
  committedResponse: response,
@@ -5,6 +5,7 @@ import { enqueueLocalWorkstreamTaskOrderReplacement } from './localWorkstreamTas
5
5
  import { DurableWorkstreamTaskOrderError, runDurableWorkstreamTaskOrderReplace, } from './workstreamTaskOrderMutationService.js';
6
6
  import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
7
7
  import { serializeWorkstreamTaskOrderForSync } from './workstreamTaskOrderSync.js';
8
+ import { readDurableOperationReplay } from './durableOperationReplay.js';
8
9
  const OPERATION_LEASE_MS = 30_000;
9
10
  function enabled(value) {
10
11
  return /^(1|true|on|yes)$/i.test(String(value || '').trim());
@@ -68,6 +69,9 @@ export function createDurableWorkstreamTaskOrderMutationRouter(input) {
68
69
  || canonicalWorkspaceSyncJson(prior.taskIds || []) !== canonicalWorkspaceSyncJson(payload.taskIds)) {
69
70
  throw new DurableWorkstreamTaskOrderError('Operation identity is assigned to a different workstream task order.', 'WORKSTREAM_TASK_ORDER_IDENTITY_CONFLICT', 409);
70
71
  }
72
+ store.assertOutboxOperationIdentity(existing, {
73
+ domain: 'workstream-task-order', entityId: payload.workstreamId, mutationKind: 'replace',
74
+ });
71
75
  return { state: 'pending', route: 'local-outbox', operationId,
72
76
  taskIds: input.core.getWorkstreamTaskOrderForSync(payload.workstreamId, input.workspaceId) };
73
77
  }
@@ -85,14 +89,21 @@ export function createDurableWorkstreamTaskOrderMutationRouter(input) {
85
89
  }
86
90
  const committed = store.readCommittedOperationResponse(identity);
87
91
  if (committed) {
88
- const response = JSON.parse(committed);
89
- if (response.authoritative?.entityId !== payload.workstreamId
90
- || canonicalWorkspaceSyncJson(response.authoritative.payload.taskIds)
91
- !== canonicalWorkspaceSyncJson(payload.taskIds)) {
92
+ const replay = readDurableOperationReplay({
93
+ responseJson: committed,
94
+ operationId,
95
+ domain: 'workstream-task-order',
96
+ entityId: payload.workstreamId,
97
+ mutationKind: 'replace',
98
+ revisionMode: 'metadata',
99
+ requirePayload: true,
100
+ });
101
+ if (canonicalWorkspaceSyncJson(replay.authoritative.payload?.taskIds)
102
+ !== canonicalWorkspaceSyncJson(payload.taskIds)) {
92
103
  throw new DurableWorkstreamTaskOrderError('Operation identity is assigned to a different workstream task order.', 'WORKSTREAM_TASK_ORDER_IDENTITY_CONFLICT', 409);
93
104
  }
94
105
  return { state: 'committed', route: 'cloud-acceptance', operationId,
95
- taskIds: response.authoritative.payload.taskIds };
106
+ taskIds: replay.authoritative.payload.taskIds };
96
107
  }
97
108
  const coordinates = store.readEntityRevisionCoordinates({
98
109
  tenantId: input.tenantId,
@@ -20,7 +20,7 @@ import { serializeTaskRootForSync } from './workspaceSyncV3TaskRootProjection.js
20
20
  import { createLocalWorkflowRuntimeOutboxHandler } from './localWorkflowRuntimeOutboxHandler.js';
21
21
  import { createLocalWorkstreamOutboxHandler } from './localWorkstreamOutboxHandler.js';
22
22
  import { createLocalWorkstreamTaskOrderOutboxHandler } from './localWorkstreamTaskOrderOutboxHandler.js';
23
- import { resolveWorkflowRuntimeMutationCapability } from './durableWorkflowRuntimeMutationRouter.js';
23
+ import { resolveWorkflowRuntimeDurableTransportCapability } from './durableWorkflowRuntimeMutationRouter.js';
24
24
  import { createLocalEntityEventLegacyAdoptionHandler, enqueueNextLegacyEntityEventAdoption, } from './localEntityEventLegacyAdoption.js';
25
25
  export function createLocalOutboxDispatchHandlers(input) {
26
26
  return [
@@ -40,7 +40,7 @@ export function createLocalOutboxDispatchHandlers(input) {
40
40
  createLocalInitiativeOutboxHandler(input),
41
41
  createLocalWorkstreamOutboxHandler(input),
42
42
  createLocalWorkstreamTaskOrderOutboxHandler(input),
43
- ...(resolveWorkflowRuntimeMutationCapability({
43
+ ...(resolveWorkflowRuntimeDurableTransportCapability({
44
44
  runtimeMode: 'local',
45
45
  surface: 'http',
46
46
  env: input.env || process.env,
@@ -43,11 +43,14 @@ function appendEligibleBlockedChains(input) {
43
43
  workspaceId: input.workspaceId,
44
44
  })) {
45
45
  try {
46
+ const blocked = input.store.readOutboxOperation(identity);
46
47
  input.store.supersedeBlockedOutboxChain({
47
48
  identity,
48
49
  recoveryBatchId: input.recovery.recoveryBatchId,
49
50
  now: input.now,
50
- replayPolicy: 'task-root',
51
+ replayPolicy: blocked?.lastErrorCode === 'WORKFLOW_RUNTIME_SEMANTIC_REPLAY_REQUIRED'
52
+ ? 'authoritative-workflow-runtime'
53
+ : 'task-root',
51
54
  appendToExistingRecovery: true,
52
55
  });
53
56
  }
@@ -104,11 +107,14 @@ export function prepareLocalOutboxRecovery(input) {
104
107
  for (const root of blockedRoots) {
105
108
  const candidateBatchId = input.createRecoveryBatchId();
106
109
  try {
110
+ const blocked = input.store.readOutboxOperation(root);
107
111
  input.store.supersedeBlockedOutboxChain({
108
112
  identity: root,
109
113
  recoveryBatchId: candidateBatchId,
110
114
  now: input.now,
111
- replayPolicy: 'task-root',
115
+ replayPolicy: blocked?.lastErrorCode === 'WORKFLOW_RUNTIME_SEMANTIC_REPLAY_REQUIRED'
116
+ ? 'authoritative-workflow-runtime'
117
+ : 'task-root',
112
118
  });
113
119
  recoveryBatchId = candidateBatchId;
114
120
  break;
@@ -2,6 +2,7 @@ import { EntityEventIdentityCollisionError } from '../../core/TaskActivityServic
2
2
  import { applyAuthoritativeTaskChecklistAndAck, LocalAuthoritativeTaskChecklistError, } from './localTaskChecklistOutboxService.js';
3
3
  import { fingerprintWorkspaceSyncPayload, WorkspaceSyncIdempotencyConflictError, WorkspaceSyncRevisionConflictError, } from './syncDurabilityStore.js';
4
4
  import { validateWorkspaceSyncV3TaskChecklistPayload } from './workspaceSyncV3NestedTaskCodecs.js';
5
+ import { validateTaskChecklistItemUpdateIntent } from './taskChecklistMutationService.js';
5
6
  import { parseWorkspaceSyncV3OriginActor } from './workspaceSyncV3OriginActor.js';
6
7
  export function buildTaskChecklistEnvelope(record) {
7
8
  let payload;
@@ -17,9 +18,20 @@ export function buildTaskChecklistEnvelope(record) {
17
18
  }
18
19
  const source = payload;
19
20
  if (!Object.prototype.hasOwnProperty.call(source, 'items')
20
- || Object.keys(source).some((key) => key !== 'items' && key !== 'originActor')) {
21
- throw new Error('Local task checklist outbox payload must contain items and optional originActor.');
21
+ || Object.keys(source).some((key) => ![
22
+ 'items', 'expectedDetailRevision', 'itemUpdateIntent', 'originActor',
23
+ ].includes(key))) {
24
+ throw new Error('Local task checklist outbox payload must contain items and optional expectedDetailRevision/originActor.');
22
25
  }
26
+ const expectedDetailRevision = source.expectedDetailRevision === undefined
27
+ ? undefined
28
+ : String(source.expectedDetailRevision).trim();
29
+ if (source.expectedDetailRevision !== undefined && !expectedDetailRevision) {
30
+ throw new Error('Local task checklist expectedDetailRevision is invalid.');
31
+ }
32
+ const itemUpdateIntent = source.itemUpdateIntent === undefined
33
+ ? undefined
34
+ : validateTaskChecklistItemUpdateIntent(source.itemUpdateIntent);
23
35
  const checklist = validateWorkspaceSyncV3TaskChecklistPayload({ taskId: record.entityId, items: source.items });
24
36
  return {
25
37
  contractVersion: 3,
@@ -31,6 +43,8 @@ export function buildTaskChecklistEnvelope(record) {
31
43
  baseEntityRevision: record.baseEntityRevision, baseLifecycleRevision: '0',
32
44
  payload: {
33
45
  items: checklist.items,
46
+ ...(expectedDetailRevision ? { expectedDetailRevision } : {}),
47
+ ...(itemUpdateIntent ? { itemUpdateIntent } : {}),
34
48
  ...(source.originActor !== undefined
35
49
  ? { originActor: parseWorkspaceSyncV3OriginActor(source.originActor) }
36
50
  : {}),
@@ -1,4 +1,5 @@
1
1
  import type { ChecklistItem, TaskEvent, TaskItem } from '../../core/Taskforce.js';
2
+ import { type TaskChecklistItemUpdateIntent } from './taskChecklistMutationService.js';
2
3
  import { WorkspaceSyncDurabilityStore, type WorkspaceSyncOperationIdentity } from './syncDurabilityStore.js';
3
4
  export interface LocalTaskChecklistOutboxCore {
4
5
  getTask(id: string, workspaceId?: string): TaskItem | null;
@@ -17,6 +18,7 @@ export interface LocalTaskChecklistOutboxCore {
17
18
  allowAuthoritativeReplacement?: boolean;
18
19
  }): unknown;
19
20
  notifyDurableTaskMetadataCommitted(workspaceId: string, taskId: string): void;
21
+ assertTaskDetailRevisionForUpdate?(id: string, expectedDetailRevision: string, workspaceId?: string): void;
20
22
  }
21
23
  export declare class LocalAuthoritativeTaskChecklistError extends Error {
22
24
  readonly code = "WORKSPACE_SYNC_AUTHORITATIVE_RESPONSE_INVALID";
@@ -30,6 +32,8 @@ export declare function enqueueLocalTaskChecklistMutation(input: {
30
32
  items: readonly Partial<ChecklistItem>[];
31
33
  now: string;
32
34
  actorRef: string;
35
+ expectedDetailRevision?: string;
36
+ itemUpdateIntent?: TaskChecklistItemUpdateIntent;
33
37
  requireV3CombinedOwnership?: boolean;
34
38
  onPostCommitError?: (error: unknown) => void;
35
39
  }): {
@@ -1,5 +1,6 @@
1
1
  import { canonicalWorkspaceSyncJson } from './canonicalWorkspaceSyncJson.js';
2
2
  import { buildTaskChecklistActivityEventId } from './taskChecklistActivityIdentity.js';
3
+ import { DurableTaskChecklistMutationError, } from './taskChecklistMutationService.js';
3
4
  import { selectDurableTaskMetadataPatch } from '../../core/TaskDurableSyncMutationService.js';
4
5
  import { serializeTaskRootForSync } from './workspaceSyncV3TaskRootProjection.js';
5
6
  import { serializeTaskActivityForSync } from './taskActivityJournal.js';
@@ -48,7 +49,13 @@ export function enqueueLocalTaskChecklistMutation(input) {
48
49
  const result = input.store.enqueueLocalOperation({
49
50
  identity: input.identity,
50
51
  domain: 'task-checklist', entityId: input.taskId, mutationKind: 'replace',
51
- revisionSource: 'current', payload: withOriginActorPayload({ items }, input.actorRef),
52
+ revisionSource: 'current', payload: withOriginActorPayload({
53
+ items,
54
+ ...(input.expectedDetailRevision
55
+ ? { expectedDetailRevision: input.expectedDetailRevision }
56
+ : {}),
57
+ ...(input.itemUpdateIntent ? { itemUpdateIntent: input.itemUpdateIntent } : {}),
58
+ }, input.actorRef),
52
59
  additionalTargets: [{
53
60
  domain: 'task', entityId: input.taskId, mutationKind: 'metadata-update',
54
61
  baseEntityRevision: rootRevision.entityRevision, baseLifecycleRevision: rootRevision.lifecycleRevision,
@@ -58,6 +65,12 @@ export function enqueueLocalTaskChecklistMutation(input) {
58
65
  ...(input.requireV3CombinedOwnership ? { requireV3PlanningOwnership: 'combined' } : {}),
59
66
  now: input.now,
60
67
  applyLocalMutation: () => {
68
+ if (input.expectedDetailRevision) {
69
+ if (!input.core.assertTaskDetailRevisionForUpdate) {
70
+ throw new DurableTaskChecklistMutationError('Task detail revision checks are unavailable.', 'TASK_CHECKLIST_INVALID', 500);
71
+ }
72
+ input.core.assertTaskDetailRevisionForUpdate(input.taskId, input.expectedDetailRevision, input.identity.workspaceId);
73
+ }
61
74
  const existing = input.core.getTask(input.taskId, input.identity.workspaceId);
62
75
  if (!existing)
63
76
  throw new LocalAuthoritativeTaskChecklistError('Task not found.');
@@ -16,7 +16,9 @@ export interface LocalTaskCreateOutboxCore {
16
16
  allowV3OwnedCreate?: boolean;
17
17
  preferExplicitAttachmentAssetId?: boolean;
18
18
  }): TaskItem;
19
- installDurableTaskCreateAuthoritativeForSync(task: TaskItem, workspaceId: string): TaskItem;
19
+ installDurableTaskCreateAuthoritativeForSync(task: TaskItem, workspaceId: string, options?: {
20
+ preserveDeletedSuccessor?: boolean;
21
+ }): TaskItem;
20
22
  upsertEntityEventForSync(event: EntityEvent, options?: {
21
23
  allowAuthoritativeReplacement?: boolean;
22
24
  }): unknown;
@@ -356,10 +356,15 @@ export function applyAuthoritativeTaskCreateAndAck(input) {
356
356
  canonicalFingerprint: fingerprintWorkspaceSyncPayload(canonicalDependentActivities[index]),
357
357
  }))],
358
358
  applyAuthoritative: () => {
359
+ const hasDeletedSuccessor = input.store.listActiveOutboxSuccessors(input.identity).some((successor) => (successor.domain === 'task'
360
+ && successor.entityId === task.id
361
+ && successor.mutationKind === 'delete'));
359
362
  const updated = input.core.installDurableTaskCreateAuthoritativeForSync({
360
363
  ...task,
361
364
  localReferenceNumber: null,
362
- }, input.identity.workspaceId);
365
+ }, input.identity.workspaceId, {
366
+ preserveDeletedSuccessor: hasDeletedSuccessor,
367
+ });
363
368
  const installedWithAttachments = canonicalAttachmentProjection
364
369
  ? input.core.updateTask(task.id, {
365
370
  attachments: input.core.resolveTaskAttachmentLinksForDurableSync(canonicalAttachmentProjection.links, input.identity.workspaceId, { adoptAuthoritativeReferenceNumber: true }),
@@ -99,6 +99,7 @@ export function enqueueLocalTaskDeleteMutation(input) {
99
99
  entityId: taskId,
100
100
  mutationKind: 'delete',
101
101
  revisionSource: 'current',
102
+ queuedTaskSuccessor: true,
102
103
  ownership: { taskMetadata: true, taskLifecycle: true },
103
104
  payload: { relationships },
104
105
  now: input.now,
@@ -1,4 +1,4 @@
1
- import type { TaskEvent, TaskItem } from '../../core/Taskforce.js';
1
+ import type { DeletedTaskRecord, TaskEvent, TaskItem } from '../../core/Taskforce.js';
2
2
  import { type DurableTaskLifecycleMutationCore, type DurableTaskLifecycleMutationKind } from '../../core/TaskDurableLifecycleMutationService.js';
3
3
  import { type DurableTaskWorkflowMutationCore, type DurableTaskWorkflowMutationKind } from '../../core/TaskDurableWorkflowMutationService.js';
4
4
  import { WorkspaceSyncDurabilityStore, type WorkspaceSyncOperationIdentity, type WorkspaceSyncOutboxRecord } from './syncDurabilityStore.js';
@@ -16,6 +16,7 @@ export declare function normalizeLocalTaskLifecyclePayload(mutationKind: LocalTa
16
16
  };
17
17
  };
18
18
  export interface LocalTaskLifecycleOutboxCore extends DurableTaskLifecycleMutationCore, DurableTaskWorkflowMutationCore {
19
+ getDeletedTask(id: string, workspaceId?: string): DeletedTaskRecord | null;
19
20
  installDurableTaskLifecycleAuthoritativeForSync(task: TaskItem, mutationKind: LocalTaskLifecycleMutationKind, workspaceId: string): TaskItem;
20
21
  upsertEntityEventForSync(event: TaskEvent, options?: {
21
22
  allowAuthoritativeReplacement?: boolean;
@@ -276,9 +276,13 @@ export function applyAuthoritativeTaskLifecycleAndAck(input) {
276
276
  canonicalFingerprint: fingerprintWorkspaceSyncPayload(serializeTaskActivityForSync(activity)),
277
277
  }] : [])],
278
278
  applyAuthoritative: () => {
279
- const hasSuccessor = input.store.hasActiveOutboxSuccessor(input.identity);
279
+ const successors = input.store.listActiveOutboxSuccessors(input.identity);
280
+ const hasSuccessor = successors.length > 0;
280
281
  const updated = hasSuccessor
281
282
  ? input.core.getTask(task.id, input.identity.workspaceId)
283
+ || (successors.some((successor) => successor.mutationKind === 'delete')
284
+ ? input.core.getDeletedTask(task.id, input.identity.workspaceId)?.taskSnapshot
285
+ : null)
282
286
  : input.core.installDurableTaskLifecycleAuthoritativeForSync(task, input.mutationKind, input.identity.workspaceId);
283
287
  if (!updated)
284
288
  throw new LocalAuthoritativeTaskLifecycleError('Local task lifecycle projection is missing.');
@@ -1,7 +1,8 @@
1
- import type { EntityEvent, TaskItem } from '../../core/Taskforce.js';
1
+ import type { DeletedTaskRecord, EntityEvent, TaskItem } from '../../core/Taskforce.js';
2
2
  import { WorkspaceSyncDurabilityStore, type WorkspaceSyncOperationIdentity } from './syncDurabilityStore.js';
3
3
  export interface LocalTaskMetadataOutboxCore {
4
4
  getTask(id: string, workspaceId?: string): TaskItem | null | undefined;
5
+ getDeletedTask(id: string, workspaceId?: string): DeletedTaskRecord | null;
5
6
  updateTask(id: string, updates: Partial<TaskItem>, workspaceId?: string, options?: {
6
7
  persistBackup?: boolean;
7
8
  emitRealtime?: boolean;
@@ -196,8 +196,12 @@ export function applyAuthoritativeTaskMetadataAndAck(input) {
196
196
  for (const dependentActivity of canonicalDependentActivities) {
197
197
  input.core.upsertEntityEventForSync(dependentActivity, { allowAuthoritativeReplacement: true });
198
198
  }
199
- if (input.store.hasActiveOutboxSuccessor(input.identity)) {
200
- const provisional = input.core.getTask(taskId, input.identity.workspaceId);
199
+ const successors = input.store.listActiveOutboxSuccessors(input.identity);
200
+ if (successors.length > 0) {
201
+ const provisional = input.core.getTask(taskId, input.identity.workspaceId)
202
+ || (successors.some((successor) => successor.mutationKind === 'delete')
203
+ ? input.core.getDeletedTask(taskId, input.identity.workspaceId)?.taskSnapshot
204
+ : null);
201
205
  if (!provisional)
202
206
  throw new DurableTaskMetadataMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
203
207
  return provisional;
@@ -1,8 +1,9 @@
1
- import type { EntityEvent, TaskEvent, TaskItem } from '../../core/Taskforce.js';
1
+ import type { DeletedTaskRecord, EntityEvent, TaskEvent, TaskItem } from '../../core/Taskforce.js';
2
2
  import { type DurableTaskStatusMutationCore, type DurableTaskStatusMutationPayload } from '../../core/TaskDurableStatusMutationService.js';
3
3
  import { WorkspaceSyncDurabilityStore, type WorkspaceSyncOperationIdentity, type WorkspaceSyncOutboxRecord } from './syncDurabilityStore.js';
4
4
  import type { DatabaseAdapter } from '../../storage/databaseAdapter.js';
5
5
  export interface LocalTaskStatusOutboxCore extends DurableTaskStatusMutationCore {
6
+ getDeletedTask(id: string, workspaceId?: string): DeletedTaskRecord | null;
6
7
  assertTaskDetailRevisionForUpdate?(id: string, expectedDetailRevision: string, workspaceId?: string): void;
7
8
  getDatabaseAdapter(): DatabaseAdapter;
8
9
  getTenantId(): string;
@@ -23,6 +24,14 @@ export interface LocalTaskStatusOutboxCore extends DurableTaskStatusMutationCore
23
24
  activity: TaskEvent | null;
24
25
  }): boolean;
25
26
  notifyDurableTaskLifecycleCommitted(workspaceId: string, taskId: string): void;
27
+ addTaskCommentEventForDurableSync(event: {
28
+ taskId: string;
29
+ workspaceId: string;
30
+ actor: string;
31
+ eventId: string;
32
+ createdAt: string;
33
+ comment: NonNullable<TaskItem['comments']>[number];
34
+ }): void;
26
35
  }
27
36
  export declare class LocalAuthoritativeTaskStatusError extends Error {
28
37
  readonly code = "WORKSPACE_SYNC_AUTHORITATIVE_RESPONSE_INVALID";