@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.
- package/dist/Taskforce.module.css +290 -45
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/TaskSettings.js +70 -14
- package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
- package/dist/components/features/TaskforceAgentsModule.js +586 -116
- package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
- package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/views/StandaloneLayout.js +27 -26
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
- package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
- package/dist/config/envSchema.js +48 -1
- package/dist/core/McpTokenService.d.ts +23 -1
- package/dist/core/McpTokenService.js +93 -10
- package/dist/core/TaskChecklistCommandService.d.ts +27 -0
- package/dist/core/TaskChecklistCommandService.js +83 -5
- package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
- package/dist/core/TaskLifecycleCommandService.js +6 -2
- package/dist/core/Taskforce.d.ts +32 -0
- package/dist/core/Taskforce.js +125 -4
- package/dist/core/types.d.ts +8 -0
- package/dist/documentReviews/commandService.d.ts +2 -1
- package/dist/documentReviews/commandService.js +6 -3
- package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.js +2 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
- package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
- package/dist/hooks/sync/useSyncStatusControls.js +47 -11
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +31 -1
- package/dist/hooks/useTaskData.js +29 -7
- package/dist/hooks/useTaskMutations.d.ts +3 -1
- package/dist/hooks/useTaskMutations.js +46 -12
- package/dist/hooks/useTaskforce.d.ts +2 -0
- package/dist/hooks/useTaskforce.js +11 -2
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +9 -6
- package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
- package/dist/mcp/durableTaskMutationRouter.js +10 -0
- package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
- package/dist/mcp/httpProtocolRouting.d.ts +10 -0
- package/dist/mcp/httpProtocolRouting.js +19 -0
- package/dist/mcp/localCliHealth.d.ts +2 -2
- package/dist/mcp/localCliHealth.js +2 -2
- package/dist/mcp/localServiceProxy.d.ts +1 -0
- package/dist/mcp/localServiceProxy.js +530 -68
- package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
- package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
- package/dist/mcp/runtime.d.ts +54 -79
- package/dist/mcp/runtime.js +384 -97
- package/dist/mcp/taskPlanningRegistrar.js +23 -4
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +10 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +1 -0
- package/dist/mcp/workflowExecutionRegistrar.js +4 -4
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +415 -0
- package/dist/runtime/appGates.d.ts +2 -1
- package/dist/runtime/appGates.js +7 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +108 -11
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.js +2 -1
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +12 -14
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +112 -3
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +277 -24
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
- package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
- package/dist/server/routes/executorPhaseAApprovals.js +140 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
- package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
- package/dist/server/routes/githubReviewEvidence.js +116 -0
- package/dist/server/routes/localService.d.ts +15 -4
- package/dist/server/routes/localService.js +136 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/shared.d.ts +19 -0
- package/dist/server/routes/shared.js +95 -19
- package/dist/server/routes/sync.js +1 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -1
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +10 -1
- package/dist/server/routes/syncV3OperationRoutes.js +35 -9
- package/dist/server/routes/tasks.js +21 -2
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes.js +59 -0
- package/dist/services/codexAppServerModelGateway.d.ts +54 -5
- package/dist/services/codexAppServerModelGateway.js +246 -21
- package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
- package/dist/services/codexDeviceCodeLoginManager.js +265 -0
- package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
- package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
- package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
- package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
- package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
- package/dist/services/executorPhaseAApprovalService.js +609 -0
- package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
- package/dist/services/executorPhaseADriftEvaluator.js +93 -0
- package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
- package/dist/services/executorPhaseAIssuerCore.js +295 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
- package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
- package/dist/services/githubReviewEvidenceRuntime.js +30 -0
- package/dist/services/githubReviewEvidenceService.d.ts +93 -0
- package/dist/services/githubReviewEvidenceService.js +336 -0
- package/dist/services/modelGateway.d.ts +7 -0
- package/dist/services/modelProviderConnectionService.d.ts +71 -0
- package/dist/services/modelProviderConnectionService.js +279 -0
- package/dist/services/modelProviderCredentialHome.d.ts +32 -0
- package/dist/services/modelProviderCredentialHome.js +271 -0
- package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
- package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
- package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
- package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +1 -1
- package/dist/services/taskforceAgentMcpBridge.js +7 -24
- package/dist/shared/adminEdgeProxy.d.ts +5 -0
- package/dist/shared/adminEdgeProxy.js +94 -0
- package/dist/shared/adminProxySessionCookies.d.ts +16 -0
- package/dist/shared/adminProxySessionCookies.js +86 -0
- package/dist/shared/aiProfileColors.d.ts +31 -1
- package/dist/shared/aiProfileColors.js +14 -6
- package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
- package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
- package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
- package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
- package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
- package/dist/shared/executorPhaseADriftContracts.js +63 -0
- package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
- package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
- package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
- package/dist/shared/executorPhaseARunAuthorization.js +232 -0
- package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
- package/dist/shared/executorPhaseASchemaValidation.js +53 -0
- package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
- package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
- package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
- package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
- package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
- package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
- package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
- package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
- package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
- package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
- package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
- package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
- package/dist/shared/executorPhaseATiming.d.ts +1 -0
- package/dist/shared/executorPhaseATiming.js +1 -0
- package/dist/shared/planningIdentity.js +1 -1
- package/dist/shared/productLogoKeys.d.ts +2 -0
- package/dist/shared/productLogoKeys.js +18 -0
- package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
- package/dist/shared/taskforceAgentDefinition.js +6 -9
- package/dist/shared/taskforceAgentModels.js +7 -3
- package/dist/shared/userFeatureGrants.d.ts +4 -0
- package/dist/shared/userFeatureGrants.js +7 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
- package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
- package/dist/storage/modelProviderConnectionStore.js +446 -0
- package/dist/storage/postgresAdapter.d.ts +4 -0
- package/dist/storage/postgresAdapter.js +11 -0
- package/dist/storage/postgresWorker.js +9 -1
- package/dist/storage/postgresWorkerProtocol.d.ts +1 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
- package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
- package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
- package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
- package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
- package/dist/sync/syncApplyHandlers.d.ts +2 -0
- package/dist/sync/syncApplyHandlers.js +10 -1
- package/dist/sync/syncService.d.ts +15 -0
- package/dist/sync/syncService.js +83 -18
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
- package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
- package/dist/sync/v3/durableOperationReplay.js +18 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
- package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
- package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
- package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
- package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
- package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
- package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
- package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +8 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +219 -12
- package/dist/sync/v3/syncDurabilityStore.d.ts +34 -0
- package/dist/sync/v3/syncDurabilityStore.js +168 -2
- package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
- package/dist/sync/v3/taskChecklistMutationService.js +44 -1
- package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
- package/dist/sync/v3/taskStatusMutationService.js +119 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
- package/dist/sync/v3/workflowAssignmentSync.js +27 -0
- package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
- package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
- package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
- package/dist/sync/workspaceRepair.d.ts +5 -2
- package/dist/sync/workspaceRepair.js +161 -6
- package/dist/sync/workspaceSyncModel.d.ts +21 -0
- package/dist/sync/workspaceSyncModel.js +35 -7
- package/dist/sync/workspaceSyncState.d.ts +1 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
- package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
- package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-BTM6nIg_.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-DabEG8L4.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-Coa8yVGM.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-BB0qhdix.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
- package/dist/ui/assets/{PlanningModule-B5DWQOGz.js → PlanningModule-pRPjR7v5.js} +1 -1
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-D86pZSSl.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-BVIkU9yT.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-CTsDBaef.js +7 -0
- package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
- package/dist/ui/branding/logos/letterhead_dark.png +0 -0
- package/dist/ui/branding/logos/letterhead_light.png +0 -0
- package/dist/ui/branding/logos/signature_dark.png +0 -0
- package/dist/ui/branding/logos/signature_light.png +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/aiProfileDefaultLogo.js +16 -48
- package/dist/utils/httpSetCookie.d.ts +1 -0
- package/dist/utils/httpSetCookie.js +4 -1
- package/dist/utils/localRuntimeUrl.d.ts +1 -0
- package/dist/utils/localRuntimeUrl.js +14 -0
- package/dist/utils/productLogoRegistry.d.ts +2 -0
- package/dist/utils/productLogoRegistry.js +36 -0
- package/dist/utils/syncStatusPresentation.d.ts +4 -0
- package/dist/utils/syncStatusPresentation.js +17 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +22 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-I5zhdtgt.js +0 -7
- 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
|
-
|
|
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 (
|
|
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 {
|
|
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
|
-
||
|
|
156
|
-
||
|
|
157
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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 {
|
|
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
|
-
|
|
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 ===
|
|
39
|
-
&& coverage.coverageVersion ===
|
|
40
|
-
&& coverage.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
|
|
61
|
+
return null;
|
|
44
62
|
}
|
|
45
63
|
}
|
|
46
64
|
export function resolveWorkflowRuntimeMutationCapability(input) {
|
|
47
65
|
const env = input.env || process.env;
|
|
48
|
-
if (
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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:
|
|
111
|
-
lifecycleRevision:
|
|
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
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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:
|
|
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 {
|
|
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
|
-
...(
|
|
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) =>
|
|
21
|
-
|
|
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({
|
|
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";
|