@taskforcehq/taskforce 0.3.329 → 0.3.330

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 (321) hide show
  1. package/dist/Taskforce.module.css +290 -45
  2. package/dist/components/features/AiProfilesModule.js +3 -5
  3. package/dist/components/features/TaskSettings.js +70 -14
  4. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  5. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  6. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  7. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  8. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  9. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  10. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  11. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  12. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  13. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  14. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  15. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  16. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  17. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  18. package/dist/components/views/StandaloneLayout.js +27 -26
  19. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  20. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  21. package/dist/config/envSchema.js +48 -1
  22. package/dist/core/McpTokenService.d.ts +23 -1
  23. package/dist/core/McpTokenService.js +93 -10
  24. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  25. package/dist/core/TaskChecklistCommandService.js +83 -5
  26. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  27. package/dist/core/TaskLifecycleCommandService.js +6 -2
  28. package/dist/core/Taskforce.d.ts +32 -0
  29. package/dist/core/Taskforce.js +125 -4
  30. package/dist/core/types.d.ts +8 -0
  31. package/dist/documentReviews/commandService.d.ts +2 -1
  32. package/dist/documentReviews/commandService.js +6 -3
  33. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  34. package/dist/hooks/sync/orchestratorShared.js +2 -0
  35. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  36. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  37. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  38. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  39. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  40. package/dist/hooks/useSyncOrchestrator.js +111 -2
  41. package/dist/hooks/useTaskData.d.ts +31 -1
  42. package/dist/hooks/useTaskData.js +29 -7
  43. package/dist/hooks/useTaskMutations.d.ts +3 -1
  44. package/dist/hooks/useTaskMutations.js +46 -12
  45. package/dist/hooks/useTaskforce.d.ts +2 -0
  46. package/dist/hooks/useTaskforce.js +11 -2
  47. package/dist/mcp/clientRegistry.d.ts +2 -2
  48. package/dist/mcp/clientRegistry.js +1 -1
  49. package/dist/mcp/documentAssetRegistrar.js +9 -6
  50. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  51. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  52. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  53. package/dist/mcp/httpProtocolRouting.d.ts +10 -0
  54. package/dist/mcp/httpProtocolRouting.js +19 -0
  55. package/dist/mcp/localCliHealth.d.ts +2 -2
  56. package/dist/mcp/localCliHealth.js +2 -2
  57. package/dist/mcp/localServiceProxy.d.ts +1 -0
  58. package/dist/mcp/localServiceProxy.js +530 -68
  59. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  60. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  61. package/dist/mcp/runtime.d.ts +54 -79
  62. package/dist/mcp/runtime.js +384 -97
  63. package/dist/mcp/taskPlanningRegistrar.js +23 -4
  64. package/dist/mcp/toolProfiles.d.ts +2 -0
  65. package/dist/mcp/toolProfiles.js +10 -0
  66. package/dist/mcp/toolRegistry.d.ts +1 -0
  67. package/dist/mcp/toolRegistry.js +1 -0
  68. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  69. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  70. package/dist/migrations/taskSchemaMigrations.js +415 -0
  71. package/dist/runtime/appGates.d.ts +2 -1
  72. package/dist/runtime/appGates.js +7 -0
  73. package/dist/server/index.d.ts +3 -0
  74. package/dist/server/index.js +108 -11
  75. package/dist/server/localDatabaseIdentity.js +4 -1
  76. package/dist/server/localServiceLease.js +2 -1
  77. package/dist/server/localServiceSessions.d.ts +14 -17
  78. package/dist/server/localServiceSessions.js +308 -94
  79. package/dist/server/localWorkspaceSyncServerRuntime.js +12 -14
  80. package/dist/server/routes/admin.d.ts +4 -0
  81. package/dist/server/routes/admin.js +112 -3
  82. package/dist/server/routes/agents.d.ts +7 -0
  83. package/dist/server/routes/agents.js +277 -24
  84. package/dist/server/routes/billing.js +5 -1
  85. package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
  86. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  87. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  88. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  89. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  90. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  91. package/dist/server/routes/githubReviewEvidence.js +116 -0
  92. package/dist/server/routes/localService.d.ts +15 -4
  93. package/dist/server/routes/localService.js +136 -40
  94. package/dist/server/routes/modelConnections.d.ts +24 -0
  95. package/dist/server/routes/modelConnections.js +205 -0
  96. package/dist/server/routes/shared.d.ts +19 -0
  97. package/dist/server/routes/shared.js +95 -19
  98. package/dist/server/routes/sync.js +1 -0
  99. package/dist/server/routes/syncAuxRoutes.js +5 -1
  100. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  101. package/dist/server/routes/syncPushRoutes.js +1 -0
  102. package/dist/server/routes/syncV3FeedRoutes.js +10 -1
  103. package/dist/server/routes/syncV3OperationRoutes.js +35 -9
  104. package/dist/server/routes/tasks.js +21 -2
  105. package/dist/server/routes/workflows.js +9 -1
  106. package/dist/server/routes.js +59 -0
  107. package/dist/services/codexAppServerModelGateway.d.ts +54 -5
  108. package/dist/services/codexAppServerModelGateway.js +246 -21
  109. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  110. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  111. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  112. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  113. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  114. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  115. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  116. package/dist/services/executorPhaseAApprovalService.js +609 -0
  117. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  118. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  119. package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
  120. package/dist/services/executorPhaseAIssuerCore.js +295 -0
  121. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  122. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  123. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  124. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  125. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  126. package/dist/services/githubReviewEvidenceService.js +336 -0
  127. package/dist/services/modelGateway.d.ts +7 -0
  128. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  129. package/dist/services/modelProviderConnectionService.js +279 -0
  130. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  131. package/dist/services/modelProviderCredentialHome.js +271 -0
  132. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  133. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  134. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  135. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  136. package/dist/services/taskforceAgentMcpBridge.d.ts +1 -1
  137. package/dist/services/taskforceAgentMcpBridge.js +7 -24
  138. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  139. package/dist/shared/adminEdgeProxy.js +94 -0
  140. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  141. package/dist/shared/adminProxySessionCookies.js +86 -0
  142. package/dist/shared/aiProfileColors.d.ts +31 -1
  143. package/dist/shared/aiProfileColors.js +14 -6
  144. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  145. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  146. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  147. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  148. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  149. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  150. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  151. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  152. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  153. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  154. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  155. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  156. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  157. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  158. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  159. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  160. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  161. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  162. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  163. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  164. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  165. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  166. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  167. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  168. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  169. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  170. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  171. package/dist/shared/executorPhaseATiming.js +1 -0
  172. package/dist/shared/planningIdentity.js +1 -1
  173. package/dist/shared/productLogoKeys.d.ts +2 -0
  174. package/dist/shared/productLogoKeys.js +18 -0
  175. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  176. package/dist/shared/taskforceAgentDefinition.js +6 -9
  177. package/dist/shared/taskforceAgentModels.js +7 -3
  178. package/dist/shared/userFeatureGrants.d.ts +4 -0
  179. package/dist/shared/userFeatureGrants.js +7 -0
  180. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  181. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  182. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  183. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  184. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  185. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  186. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  187. package/dist/storage/modelProviderConnectionStore.js +446 -0
  188. package/dist/storage/postgresAdapter.d.ts +4 -0
  189. package/dist/storage/postgresAdapter.js +11 -0
  190. package/dist/storage/postgresWorker.js +9 -1
  191. package/dist/storage/postgresWorkerProtocol.d.ts +1 -0
  192. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  193. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  194. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
  195. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  196. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  197. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  198. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  199. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  200. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  201. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  202. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  203. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  204. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  205. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  206. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  207. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  208. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  209. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  210. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
  211. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  212. package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
  213. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  214. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
  215. package/dist/sync/syncApplyHandlers.d.ts +2 -0
  216. package/dist/sync/syncApplyHandlers.js +10 -1
  217. package/dist/sync/syncService.d.ts +15 -0
  218. package/dist/sync/syncService.js +83 -18
  219. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  220. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  221. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  222. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  223. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  224. package/dist/sync/v3/durableOperationReplay.js +18 -0
  225. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
  226. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
  227. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
  228. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  229. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
  230. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
  231. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  232. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
  233. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
  234. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  235. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  236. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  237. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  238. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  239. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  240. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +8 -0
  241. package/dist/sync/v3/localTaskStatusOutboxService.js +219 -12
  242. package/dist/sync/v3/syncDurabilityStore.d.ts +34 -0
  243. package/dist/sync/v3/syncDurabilityStore.js +168 -2
  244. package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
  245. package/dist/sync/v3/taskChecklistMutationService.js +44 -1
  246. package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
  247. package/dist/sync/v3/taskStatusMutationService.js +119 -3
  248. package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
  249. package/dist/sync/v3/workflowAssignmentSync.js +27 -0
  250. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  251. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  252. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  253. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  254. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
  255. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
  256. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
  257. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
  258. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
  259. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  260. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
  261. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
  262. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
  263. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  264. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
  265. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
  266. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
  267. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  268. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  269. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  270. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  271. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  272. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  273. package/dist/sync/workspaceRepair.d.ts +5 -2
  274. package/dist/sync/workspaceRepair.js +161 -6
  275. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  276. package/dist/sync/workspaceSyncModel.js +35 -7
  277. package/dist/sync/workspaceSyncState.d.ts +1 -0
  278. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  279. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  280. package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
  281. package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
  282. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-BTM6nIg_.js} +1 -1
  283. package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-DabEG8L4.js} +1 -1
  284. package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-Coa8yVGM.js} +1 -1
  285. package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-BB0qhdix.js} +1 -1
  286. package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
  287. package/dist/ui/assets/{PlanningModule-B5DWQOGz.js → PlanningModule-pRPjR7v5.js} +1 -1
  288. package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-D86pZSSl.js} +1 -1
  289. package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-BVIkU9yT.js} +1 -1
  290. package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
  291. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  292. package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
  293. package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
  294. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  295. package/dist/ui/assets/index-CTsDBaef.js +7 -0
  296. package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
  297. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  298. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  299. package/dist/ui/branding/logos/signature_dark.png +0 -0
  300. package/dist/ui/branding/logos/signature_light.png +0 -0
  301. package/dist/ui/index.html +3 -3
  302. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  303. package/dist/utils/httpSetCookie.d.ts +1 -0
  304. package/dist/utils/httpSetCookie.js +4 -1
  305. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  306. package/dist/utils/localRuntimeUrl.js +14 -0
  307. package/dist/utils/productLogoRegistry.d.ts +2 -0
  308. package/dist/utils/productLogoRegistry.js +36 -0
  309. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  310. package/dist/utils/syncStatusPresentation.js +17 -0
  311. package/dist/utils/taskEvents.d.ts +2 -0
  312. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  313. package/dist/utils/workspaceSyncPresentation.js +23 -17
  314. package/package.json +22 -4
  315. package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
  316. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
  317. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
  318. package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
  319. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  320. package/dist/ui/assets/index-I5zhdtgt.js +0 -7
  321. package/dist/ui/assets/index-VRFsx3wz.css +0 -1
@@ -1,7 +1,7 @@
1
1
  import { canonicalWorkspaceSyncJson } from './canonicalWorkspaceSyncJson.js';
2
2
  import { LocalSyncIdentityStore } from './localSyncIdentityStore.js';
3
3
  import { enqueueLocalTaskChecklistMutation, } from './localTaskChecklistOutboxService.js';
4
- import { DurableTaskChecklistMutationError, runDurableTaskChecklistReplace, } from './taskChecklistMutationService.js';
4
+ import { DurableTaskChecklistMutationError, runDurableTaskChecklistReplace, validateTaskChecklistItemUpdateIntent, } from './taskChecklistMutationService.js';
5
5
  import { WorkspaceSyncDurabilityStore, WorkspaceSyncEntityBusyError } from './syncDurabilityStore.js';
6
6
  import { serializeWorkspaceSyncV3TaskChecklistPayload } from './workspaceSyncV3NestedTaskCodecs.js';
7
7
  const OPERATION_LEASE_MS = 30_000;
@@ -82,6 +82,18 @@ export function createDurableTaskChecklistMutationRouter(input) {
82
82
  catch (error) {
83
83
  throw new DurableTaskChecklistMutationError(error instanceof Error ? error.message : 'Task checklist is invalid.', 'TASK_CHECKLIST_INVALID', 400);
84
84
  }
85
+ const itemUpdateIntent = args.itemUpdateIntent
86
+ ? validateTaskChecklistItemUpdateIntent(args.itemUpdateIntent)
87
+ : undefined;
88
+ if (itemUpdateIntent) {
89
+ const target = items.find((item) => item.id === itemUpdateIntent.itemId);
90
+ if (!target
91
+ || (itemUpdateIntent.patch.text !== undefined && target.title !== itemUpdateIntent.patch.text)
92
+ || (itemUpdateIntent.patch.done !== undefined && target.isCompleted !== itemUpdateIntent.patch.done)
93
+ || (itemUpdateIntent.patch.order !== undefined && target.order !== itemUpdateIntent.patch.order)) {
94
+ throw new DurableTaskChecklistMutationError('Task checklist item update intent does not match the replacement aggregate.', 'TASK_CHECKLIST_INVALID', 400);
95
+ }
96
+ }
85
97
  const acceptedAt = now();
86
98
  const acceptedAtIso = acceptedAt.toISOString();
87
99
  const operationId = operationIdRequired(input.operationId);
@@ -109,25 +121,43 @@ export function createDurableTaskChecklistMutationRouter(input) {
109
121
  catch {
110
122
  throw new DurableTaskChecklistMutationError('Captured task checklist payload is invalid.', 'TASK_CHECKLIST_IDENTITY_CONFLICT', 409);
111
123
  }
112
- if (canonicalWorkspaceSyncJson(frozen) !== canonicalWorkspaceSyncJson(items)) {
124
+ const capturedIntent = payload.itemUpdateIntent
125
+ ? validateTaskChecklistItemUpdateIntent(payload.itemUpdateIntent)
126
+ : undefined;
127
+ const requestedIntent = itemUpdateIntent;
128
+ if (capturedIntent || requestedIntent
129
+ ? canonicalWorkspaceSyncJson(capturedIntent) !== canonicalWorkspaceSyncJson(requestedIntent)
130
+ : canonicalWorkspaceSyncJson(frozen) !== canonicalWorkspaceSyncJson(items)) {
113
131
  throw new DurableTaskChecklistMutationError('Operation identity is assigned to a different task checklist.', 'TASK_CHECKLIST_IDENTITY_CONFLICT', 409);
114
132
  }
133
+ if ((payload.expectedDetailRevision || undefined) !== (args.expectedDetailRevision || undefined)) {
134
+ throw new DurableTaskChecklistMutationError('Operation identity is assigned to a different task checklist precondition.', 'TASK_CHECKLIST_IDENTITY_CONFLICT', 409);
135
+ }
136
+ store.assertOutboxOperationIdentity(existing, {
137
+ domain: 'task-checklist', entityId: taskId, mutationKind: 'replace',
138
+ });
115
139
  const task = input.core.getTask(taskId, workspaceId);
116
140
  if (!task)
117
141
  throw new DurableTaskChecklistMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
118
142
  const installed = serializeWorkspaceSyncV3TaskChecklistPayload({
119
143
  taskId, items: task.checklistItems || [],
120
144
  }).items;
121
- if (canonicalWorkspaceSyncJson(installed) !== canonicalWorkspaceSyncJson(frozen)) {
145
+ if (!capturedIntent
146
+ && canonicalWorkspaceSyncJson(installed) !== canonicalWorkspaceSyncJson(frozen)) {
122
147
  throw new DurableTaskChecklistMutationError('Captured task checklist does not match local state.', 'TASK_CHECKLIST_IDENTITY_CONFLICT', 409);
123
148
  }
124
- return { state: 'pending', route: 'local-outbox', operationId, task };
149
+ return {
150
+ state: 'pending', route: 'local-outbox', operationId,
151
+ task: capturedIntent ? { ...task, checklistItems: frozen } : task,
152
+ };
125
153
  }
126
154
  let result;
127
155
  try {
128
156
  result = enqueueLocalTaskChecklistMutation({
129
157
  store, core: input.core, identity, taskId, items, now: acceptedAtIso,
130
158
  actorRef, onPostCommitError: input.onPostCommitError,
159
+ expectedDetailRevision: args.expectedDetailRevision,
160
+ itemUpdateIntent,
131
161
  requireV3CombinedOwnership: persistedOwnershipChecked,
132
162
  });
133
163
  }
@@ -142,6 +172,7 @@ export function createDurableTaskChecklistMutationRouter(input) {
142
172
  return { state: 'pending', route: 'local-outbox', operationId, task };
143
173
  }
144
174
  const committed = store.readCommittedOperationResponse(identity);
175
+ let coordinates;
145
176
  if (committed) {
146
177
  let response;
147
178
  try {
@@ -150,27 +181,33 @@ export function createDurableTaskChecklistMutationRouter(input) {
150
181
  catch {
151
182
  throw new DurableTaskChecklistMutationError('Committed task checklist response is invalid.', 'TASK_CHECKLIST_IDENTITY_CONFLICT', 409);
152
183
  }
184
+ const projection = response.authoritative?.checklist;
185
+ const acceptedRevision = String(projection?.entityRevision || '');
186
+ const lifecycleRevision = String(projection?.lifecycleRevision || '');
153
187
  if (response.workspaceId !== workspaceId || response.clientId !== clientId
154
188
  || response.operationId !== operationId || response.authoritative?.root?.entityId !== taskId
155
- || response.authoritative?.checklist?.entityId !== taskId
156
- || canonicalWorkspaceSyncJson(response.authoritative.checklist.payload?.items || [])
157
- !== canonicalWorkspaceSyncJson(items)) {
189
+ || projection?.entityId !== taskId
190
+ || !/^[1-9]\d*$/.test(acceptedRevision)
191
+ || !/^(0|[1-9]\d*)$/.test(lifecycleRevision)) {
158
192
  throw new DurableTaskChecklistMutationError('Operation identity is assigned to a different task checklist.', 'TASK_CHECKLIST_IDENTITY_CONFLICT', 409);
159
193
  }
160
- const task = input.core.getTask(taskId, workspaceId);
161
- if (!task)
162
- throw new DurableTaskChecklistMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
163
- return { state: 'committed', route: 'cloud-acceptance', operationId, task };
194
+ coordinates = {
195
+ entityRevision: String(BigInt(acceptedRevision) - 1n),
196
+ lifecycleRevision,
197
+ };
198
+ }
199
+ else {
200
+ coordinates = store.readEntityRevisionCoordinates({
201
+ tenantId, workspaceId, domain: 'task-checklist', entityId: taskId,
202
+ });
164
203
  }
165
- const coordinates = store.readEntityRevisionCoordinates({
166
- tenantId, workspaceId, domain: 'task-checklist', entityId: taskId,
167
- });
168
204
  const result = runDurableTaskChecklistReplace({
169
205
  store, core: input.core, tenantId, workspaceId, clientId, operationId, taskId, items,
170
206
  baseEntityRevision: coordinates.entityRevision, baseLifecycleRevision: coordinates.lifecycleRevision,
171
207
  now: acceptedAtIso, leaseExpiresAt: new Date(acceptedAt.getTime() + OPERATION_LEASE_MS).toISOString(),
172
208
  actorRef, onPostCommitError: input.onPostCommitError,
173
209
  expectedDetailRevision: args.expectedDetailRevision,
210
+ itemUpdateIntent,
174
211
  assertPrecondition: args.expectedDetailRevision
175
212
  ? () => input.core.assertTaskDetailRevisionForUpdate(taskId, args.expectedDetailRevision, workspaceId)
176
213
  : undefined,
@@ -180,7 +217,13 @@ export function createDurableTaskChecklistMutationRouter(input) {
180
217
  const task = input.core.getTask(taskId, workspaceId);
181
218
  if (!task)
182
219
  throw new DurableTaskChecklistMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
183
- return { state: 'committed', route: 'cloud-acceptance', operationId, task };
220
+ return {
221
+ state: 'committed', route: 'cloud-acceptance', operationId,
222
+ task: {
223
+ ...task,
224
+ checklistItems: result.response.authoritative.checklist.payload.items,
225
+ },
226
+ };
184
227
  },
185
228
  };
186
229
  }
@@ -113,6 +113,9 @@ export function createDurableTaskCommentMutationRouter(input) {
113
113
  if (!sameCommentRetryIntent(existingPayload.comment, canonical)) {
114
114
  throw new DurableTaskCommentMutationError('Operation identity is assigned to a different task comment.', 'TASK_COMMENT_IDENTITY_CONFLICT', 409);
115
115
  }
116
+ store.assertOutboxOperationIdentity(existing, {
117
+ domain: 'task-comments', entityId: taskId, mutationKind: 'append',
118
+ });
116
119
  const frozenComment = serializeWorkspaceSyncV3TaskCommentsPayload({
117
120
  taskId, comments: [existingPayload.comment],
118
121
  }).comments[0];
@@ -38,5 +38,5 @@ export declare function createDurableTaskHttpRootMutationRouter(input: {
38
38
  restore(deletedRecordIdInput: string, restoreDestination?: TaskRestoreDestination): TaskItem;
39
39
  delete(taskIdInput: string): DeletedTaskRecord;
40
40
  };
41
- type TaskforceCoreForHttpRootMutation = Pick<import('../../core/Taskforce.js').TaskforceCore, 'getDatabaseAdapter' | 'getTask' | 'getTaskDetailRevision' | 'assertTaskDetailRevisionForUpdate' | 'listAssignableActors' | 'getDeletedTask' | 'updateTask' | 'hasTaskDeletionMarkerForSync' | 'createTask' | 'listTaskAttachmentLinksForDurableSync' | 'resolveTaskAttachmentLinksForDurableSync' | 'normalizeTaskAttachmentDescriptorsForDurableSync' | 'notifyDurableTaskCreateCommitted' | 'notifyDurableTaskBatchCommitted' | 'notifyDurableTaskMetadataCommitted' | 'notifyDurableTaskLifecycleCommitted' | 'notifyDurableTaskDeleteCommitted' | 'getTaskEventForSync' | 'getEntityEventForSync' | 'lockTaskLifecycleMutationDomain' | 'archiveTask' | 'unarchiveTask' | 'restoreDeletedTask' | 'addTaskStatusEventsForDurableSync' | 'lockTaskRelationshipMutationDomain' | 'listTaskRelationships' | 'getTaskRelationshipForSync' | 'deleteTaskForSync'>;
41
+ type TaskforceCoreForHttpRootMutation = Pick<import('../../core/Taskforce.js').TaskforceCore, 'getDatabaseAdapter' | 'getTask' | 'getTaskDetailRevision' | 'assertTaskDetailRevisionForUpdate' | 'listAssignableActors' | 'getDeletedTask' | 'updateTask' | 'hasTaskDeletionMarkerForSync' | 'createTask' | 'listTaskAttachmentLinksForDurableSync' | 'resolveTaskAttachmentLinksForDurableSync' | 'normalizeTaskAttachmentDescriptorsForDurableSync' | 'notifyDurableTaskCreateCommitted' | 'notifyDurableTaskBatchCommitted' | 'notifyDurableTaskMetadataCommitted' | 'notifyDurableTaskLifecycleCommitted' | 'notifyDurableTaskDeleteCommitted' | 'getTaskEventForSync' | 'getEntityEventForSync' | 'lockTaskLifecycleMutationDomain' | 'archiveTask' | 'unarchiveTask' | 'restoreDeletedTask' | 'addTaskStatusEventsForDurableSync' | 'addTaskCommentEventForDurableSync' | 'lockTaskRelationshipMutationDomain' | 'listTaskRelationships' | 'getTaskRelationshipForSync' | 'deleteTaskForSync'>;
42
42
  export {};
@@ -2,6 +2,7 @@ import { selectDurableTaskMetadataPatch } from '../../core/TaskDurableSyncMutati
2
2
  import { prepareTaskDeleteForDurableSync } from '../../core/TaskDurableDeleteMutationService.js';
3
3
  import { selectTaskCreateActivationInput } from './taskCreateActivation.js';
4
4
  import { resolveTaskAttachmentLinksMutationCapability } from './durableTaskAttachmentLinksMutationRouter.js';
5
+ import { areWorkflowRuntimeMutationsFenced, resolveWorkflowRuntimeDurableTransportCapability, } from './durableWorkflowRuntimeMutationRouter.js';
5
6
  import { runDurableTaskCreate } from './taskCreateMutationService.js';
6
7
  import { runDurableTaskDelete } from './taskDeleteMutationService.js';
7
8
  import { runDurableTaskLifecycleMutation } from './taskLifecycleMutationService.js';
@@ -59,6 +60,13 @@ export function createDurableTaskHttpRootMutationRouter(input) {
59
60
  surface: 'http',
60
61
  env: input.env,
61
62
  });
63
+ const workflowRuntimeJournalEnabled = resolveWorkflowRuntimeDurableTransportCapability({
64
+ runtimeMode: input.runtimeMode,
65
+ surface: 'http',
66
+ env: input.env,
67
+ });
68
+ const rejectWorkflowRuntimeActivation = workflowRuntimeJournalEnabled
69
+ && areWorkflowRuntimeMutationsFenced(input.env);
62
70
  const store = new WorkspaceSyncDurabilityStore(input.core.getDatabaseAdapter());
63
71
  const now = input.now || (() => new Date());
64
72
  const notificationMethods = new Set([
@@ -237,6 +245,8 @@ export function createDurableTaskHttpRootMutationRouter(input) {
237
245
  now: operation.acceptedAtIso,
238
246
  leaseExpiresAt: new Date(operation.acceptedAt.getTime() + OPERATION_LEASE_MS).toISOString(),
239
247
  actorRef: input.actorRef,
248
+ includeWorkflowRuntimeJournal: workflowRuntimeJournalEnabled,
249
+ rejectWorkflowRuntimeActivation,
240
250
  expectedDetailRevision,
241
251
  assertPrecondition: detailRevisionPrecondition(taskId, expectedDetailRevision),
242
252
  onPostCommitError: input.onPostCommitError,
@@ -185,6 +185,11 @@ export function createDurableTaxonomyMutationRouter(input) {
185
185
  if (!sameTaxonomyState(storedPayload.state, canonicalState) || !Array.isArray(storedPayload.taskPatches)) {
186
186
  throw new WorkspaceSyncIdempotencyConflictError();
187
187
  }
188
+ store.assertOutboxOperationIdentity(existingOutbox, {
189
+ domain: WORKSPACE_SYNC_TAXONOMY_DOMAIN,
190
+ entityId: WORKSPACE_SYNC_TAXONOMY_ENTITY_ID,
191
+ mutationKind: WORKSPACE_SYNC_TAXONOMY_REPLACE_WITH_REMAPS,
192
+ });
188
193
  enqueueLocalTaxonomyCompositeReplacement({
189
194
  store,
190
195
  core: input.core,
@@ -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';
@@ -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.');
@@ -254,7 +283,7 @@ export function createDurableWorkflowRuntimeMutationRouter(input) {
254
283
  const workflowStore = new WorkflowStore(input.core.getDatabaseAdapter(), tenantId);
255
284
  const snapshot = workflowStore.getExecutionStateSnapshot(workspaceId, args.executionId);
256
285
  if (!snapshot)
257
- throw new Error('Workflow execution not found.');
286
+ throw new DurableWorkflowRuntimeExecutionNotFoundError();
258
287
  const committed = readCommittedCloudResponse();
259
288
  if (committed) {
260
289
  const event = snapshot.events.find((candidate) => candidate.idempotencyKey === operationId);
@@ -307,7 +336,7 @@ export function createDurableWorkflowRuntimeMutationRouter(input) {
307
336
  const workflowStore = new WorkflowStore(input.core.getDatabaseAdapter(), tenantId);
308
337
  const snapshot = workflowStore.getExecutionStateSnapshot(workspaceId, args.executionId);
309
338
  if (!snapshot)
310
- throw new Error('Workflow execution not found.');
339
+ throw new DurableWorkflowRuntimeExecutionNotFoundError();
311
340
  const committed = readCommittedCloudResponse();
312
341
  if (committed) {
313
342
  const completedEvent = snapshot.events.find((event) => event.idempotencyKey === `${operationId}:step-completed`);
@@ -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,
@@ -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.');
@@ -23,6 +23,14 @@ export interface LocalTaskStatusOutboxCore extends DurableTaskStatusMutationCore
23
23
  activity: TaskEvent | null;
24
24
  }): boolean;
25
25
  notifyDurableTaskLifecycleCommitted(workspaceId: string, taskId: string): void;
26
+ addTaskCommentEventForDurableSync(event: {
27
+ taskId: string;
28
+ workspaceId: string;
29
+ actor: string;
30
+ eventId: string;
31
+ createdAt: string;
32
+ comment: NonNullable<TaskItem['comments']>[number];
33
+ }): void;
26
34
  }
27
35
  export declare class LocalAuthoritativeTaskStatusError extends Error {
28
36
  readonly code = "WORKSPACE_SYNC_AUTHORITATIVE_RESPONSE_INVALID";