@taskforcehq/taskforce 0.3.329 → 0.3.332
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- 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/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
- 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/planning/PlanningModule.js +15 -3
- package/dist/components/features/planning/planningMetadata.d.ts +10 -0
- package/dist/components/features/planning/planningMetadata.js +8 -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 +62 -27
- package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
- package/dist/components/views/panels/PlanningDrawer.js +12 -8
- 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 +55 -1
- package/dist/core/McpTokenService.d.ts +25 -1
- package/dist/core/McpTokenService.js +106 -15
- 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 +43 -3
- package/dist/core/Taskforce.js +158 -7
- package/dist/core/types.d.ts +9 -0
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
- 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 +11 -0
- package/dist/mcp/httpProtocolRouting.js +22 -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 +408 -102
- package/dist/mcp/taskPlanningRegistrar.js +25 -6
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +11 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +9 -8
- 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/buildInfo.d.ts +1 -0
- package/dist/server/buildInfo.js +5 -1
- package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
- package/dist/server/cloudMcpCapacityTelemetry.js +221 -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 +25 -19
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +126 -5
- 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 +22 -0
- package/dist/server/routes/shared.js +298 -182
- 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/service/localServiceCli.d.ts +2 -2
- package/dist/service/localServiceCli.js +4 -3
- 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 +139 -0
- package/dist/services/executorPhaseAIssuerCore.js +402 -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 +2 -2
- package/dist/services/taskforceAgentMcpBridge.js +42 -29
- 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 +14 -1
- package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
- package/dist/storage/postgresRequestDiagnostics.js +15 -2
- package/dist/storage/postgresWorker.js +20 -2
- package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/storage/workflowStore.d.ts +2 -0
- package/dist/storage/workflowStore.js +39 -2
- package/dist/sync/cloudSyncApi.js +4 -2
- package/dist/sync/collaborationSyncState.js +5 -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/localWorkspaceSyncRunner.d.ts +3 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -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 +31 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -0
- package/dist/sync/syncApplyHandlers.js +81 -15
- 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 +18 -7
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
- 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/localOutboxRecoveryPreparationService.js +8 -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/localTaskCreateOutboxService.d.ts +3 -1
- package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
- package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
- package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
- package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
- package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
- package/dist/sync/v3/syncDurabilityStore.js +202 -8
- 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/workflowRuntimeMutationService.d.ts +5 -0
- package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
- 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/workspaceSyncV3CombinedLocalApply.js +25 -3
- 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/workspaceSyncV3Feed.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
- 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/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
- 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-CDMPtnbC.js +1 -0
- package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
- package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-DSQINwt9.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 +24 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/PlanningModule-B5DWQOGz.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
package/dist/sync/syncService.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { applyLocalWorkspaceChanges, getLocalWorkspaceContentPullObligations, recordLocalWorkspaceContentPullObligationFailures, getLocalWorkspaceContentManifest, pullUserSettings, pushUserSettings, prepareWorkspacePushChanges, } from './cloudSyncApi.js';
|
|
2
2
|
import { workspaceSyncContentPullObligationId, } from './engine/workspaceSyncContentPullObligationStore.js';
|
|
3
3
|
import { createBrowserWorkspaceSyncEngineRemoteServices, } from './engine/workspaceSyncEngineRemoteServices.js';
|
|
4
|
-
import { createWorkspaceSyncEngineV2PushBoundary, parseWorkspaceSyncEngineAppliedTaskUpserts, workspaceSyncEngineExpectedTaskEchoIds, } from './engine/workspaceSyncEnginePushCompletion.js';
|
|
4
|
+
import { createWorkspaceSyncEngineV2SettlementIdentityProjection, createWorkspaceSyncEngineV2PushBoundary, parseWorkspaceSyncEngineAppliedTaskUpserts, workspaceSyncEngineExpectedTaskEchoIds, } from './engine/workspaceSyncEnginePushCompletion.js';
|
|
5
5
|
import { encryptDocument } from './encryptionService.js';
|
|
6
6
|
import { decryptWorkspaceSyncContentChangeInPlace } from './workspaceSyncContentDecryption.js';
|
|
7
7
|
import { decideWorkspaceContentFetch, fingerprintWorkspaceContentBody, } from './workspaceContentManifest.js';
|
|
@@ -181,13 +181,8 @@ function buildEffectiveWorkspacePushDiagnostics(diagnostics, changes, ownership)
|
|
|
181
181
|
: {}),
|
|
182
182
|
};
|
|
183
183
|
}
|
|
184
|
-
async function
|
|
185
|
-
const text = canonicalWorkspaceSyncJson(
|
|
186
|
-
contractVersion: 1,
|
|
187
|
-
workspaceId,
|
|
188
|
-
repairMode,
|
|
189
|
-
changes
|
|
190
|
-
});
|
|
184
|
+
async function computeCanonicalWorkspaceSyncSha256(value, fallbackNamespace) {
|
|
185
|
+
const text = canonicalWorkspaceSyncJson(value);
|
|
191
186
|
try {
|
|
192
187
|
const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
|
|
193
188
|
return Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
@@ -202,9 +197,19 @@ async function computeIdempotencyKey(workspaceId, changes, repairMode) {
|
|
|
202
197
|
hash = Math.imul(hash, 0x01000193);
|
|
203
198
|
}
|
|
204
199
|
const hex = (hash >>> 0).toString(16).padStart(8, '0');
|
|
205
|
-
return
|
|
200
|
+
return fallbackNamespace
|
|
201
|
+
? `${fallbackNamespace}:fallback:${hex}`
|
|
202
|
+
: hex.repeat(8);
|
|
206
203
|
}
|
|
207
204
|
}
|
|
205
|
+
async function computeIdempotencyKey(workspaceId, changes, repairMode) {
|
|
206
|
+
return computeCanonicalWorkspaceSyncSha256({
|
|
207
|
+
contractVersion: 1,
|
|
208
|
+
workspaceId,
|
|
209
|
+
repairMode,
|
|
210
|
+
changes
|
|
211
|
+
}, workspaceId);
|
|
212
|
+
}
|
|
208
213
|
const MAX_WORKSPACE_PUSH_CHANGES_PER_REQUEST = 64;
|
|
209
214
|
const MAX_WORKSPACE_PUSH_BYTES_PER_REQUEST = 4 * 1024 * 1024;
|
|
210
215
|
const MAX_WORKSPACE_PUSH_SINGLE_CHANGE_BYTES = 45 * 1024 * 1024;
|
|
@@ -428,6 +433,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
428
433
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
429
434
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
430
435
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
436
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
431
437
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
432
438
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
433
439
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -491,6 +497,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
491
497
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
492
498
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
493
499
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
500
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
494
501
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
495
502
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
496
503
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -583,6 +590,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
583
590
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
584
591
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
585
592
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
593
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
586
594
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
587
595
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
588
596
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -670,8 +678,18 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
670
678
|
&& acknowledgedNonApplyingBatchOperationIdentities.size !== requestedAcknowledgements.length) {
|
|
671
679
|
throw new Error('Persisted V2 push batch acknowledgement state does not match the frozen push plan.');
|
|
672
680
|
}
|
|
681
|
+
const requestedSettledBatchOperationIdentities = input.settledBatchOperationIdentities || [];
|
|
682
|
+
if ((requestedSettledBatchOperationIdentities.length > 0
|
|
683
|
+
&& !input.onAcceptedBatchSettled)
|
|
684
|
+
|| new Set(requestedSettledBatchOperationIdentities).size
|
|
685
|
+
!== requestedSettledBatchOperationIdentities.length
|
|
686
|
+
|| requestedSettledBatchOperationIdentities.some((identity) => !batchOperationIdentities.includes(identity))) {
|
|
687
|
+
throw new Error('Persisted V2 push batch settlement state does not match the frozen push plan.');
|
|
688
|
+
}
|
|
689
|
+
const settledBatchOperationIdentities = new Set(requestedSettledBatchOperationIdentities);
|
|
673
690
|
let completedBatchCount = 0;
|
|
674
691
|
let completedChangeCount = 0;
|
|
692
|
+
let firstPushFailure = null;
|
|
675
693
|
const pushTransferReceipts = [];
|
|
676
694
|
const abandonRetainedPushReceipts = async (errorCode) => {
|
|
677
695
|
if (pushTransferReceipts.length === 0)
|
|
@@ -689,7 +707,8 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
689
707
|
const safeBatchChanges = batch.map((entry) => entry.safe);
|
|
690
708
|
const expectedTaskEchoIds = workspaceSyncEngineExpectedTaskEchoIds(plainBatchChanges);
|
|
691
709
|
const idempotencyKey = batchOperationIdentities[batchIndex];
|
|
692
|
-
if (
|
|
710
|
+
if (settledBatchOperationIdentities.has(idempotencyKey)
|
|
711
|
+
|| acknowledgedNonApplyingBatchOperationIdentities.has(idempotencyKey)) {
|
|
693
712
|
completedBatchCount += 1;
|
|
694
713
|
completedChangeCount += plainBatchChanges.length;
|
|
695
714
|
continue;
|
|
@@ -732,7 +751,12 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
732
751
|
const data = asObjectRecord(pushResult.data);
|
|
733
752
|
const failedOperations = Array.from(new Set(plainBatchChanges.map((change) => change.op)));
|
|
734
753
|
const failedContentChanges = plainBatchChanges.filter(isWorkspacePushContentChange).length;
|
|
735
|
-
|
|
754
|
+
const failureDomain = failedContentChanges === plainBatchChanges.length
|
|
755
|
+
? 'content'
|
|
756
|
+
: failedContentChanges === 0
|
|
757
|
+
? 'metadata'
|
|
758
|
+
: 'mixed';
|
|
759
|
+
const failureResult = {
|
|
736
760
|
success: false,
|
|
737
761
|
status: pushResult.status,
|
|
738
762
|
error: typeof data.error === 'string' ? data.error : undefined,
|
|
@@ -744,11 +768,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
744
768
|
failedBatchIndex: batchIndex,
|
|
745
769
|
failedChangeCount: plainBatchChanges.length,
|
|
746
770
|
failedOperations,
|
|
747
|
-
failureDomain
|
|
748
|
-
? 'content'
|
|
749
|
-
: failedContentChanges === 0
|
|
750
|
-
? 'metadata'
|
|
751
|
-
: 'mixed',
|
|
771
|
+
failureDomain,
|
|
752
772
|
},
|
|
753
773
|
retryAfterMs: pushResult.retryAfterMs,
|
|
754
774
|
transient: pushInProgress || isTransientWorkspaceSyncStatus(pushResult.status),
|
|
@@ -765,6 +785,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
765
785
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
766
786
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
767
787
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
788
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
768
789
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
769
790
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
770
791
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -793,8 +814,18 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
793
814
|
pushedWatermarks: new Map(),
|
|
794
815
|
pushedTaskChangeKeys: new Map(),
|
|
795
816
|
emittedEventIds: [],
|
|
796
|
-
appliedTaskUpserts: []
|
|
817
|
+
appliedTaskUpserts: [],
|
|
797
818
|
};
|
|
819
|
+
firstPushFailure ||= failureResult;
|
|
820
|
+
// Only content is isolated from later durable projections.
|
|
821
|
+
// Ownership, auth, and metadata failures can invalidate phase
|
|
822
|
+
// dependencies, so they still stop the attempt immediately.
|
|
823
|
+
if (failureDomain !== 'content')
|
|
824
|
+
return failureResult;
|
|
825
|
+
// Later phases contain independent relationships, events, and
|
|
826
|
+
// comments. Let them settle and checkpoint their non-applying
|
|
827
|
+
// receipts even though this attempt reports the content failure.
|
|
828
|
+
continue;
|
|
798
829
|
}
|
|
799
830
|
const pushData = asObjectRecord(pushResult.data);
|
|
800
831
|
if (Array.isArray(pushData.emittedEventIds)) {
|
|
@@ -806,7 +837,29 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
806
837
|
}
|
|
807
838
|
const normalizedTaskUpserts = parseWorkspaceSyncEngineAppliedTaskUpserts(pushData, expectedTaskEchoIds);
|
|
808
839
|
appliedTaskUpserts.push(...normalizedTaskUpserts);
|
|
809
|
-
if (
|
|
840
|
+
if (input.onAcceptedBatchSettled) {
|
|
841
|
+
if (!pushResult.transferReceipt) {
|
|
842
|
+
throw new Error('Accepted V2 push batch is missing its atomic settlement receipt.');
|
|
843
|
+
}
|
|
844
|
+
await input.onAcceptedBatchSettled({
|
|
845
|
+
operationIdentity: idempotencyKey,
|
|
846
|
+
settlementIdentityFingerprint: await computeCanonicalWorkspaceSyncSha256(createWorkspaceSyncEngineV2SettlementIdentityProjection({
|
|
847
|
+
operationIdentity: idempotencyKey,
|
|
848
|
+
changes: plainBatchChanges,
|
|
849
|
+
appliedTaskUpserts: normalizedTaskUpserts,
|
|
850
|
+
excludedProjections: effectiveV2ExcludedProjections,
|
|
851
|
+
})),
|
|
852
|
+
appliedTaskUpserts: normalizedTaskUpserts,
|
|
853
|
+
transferReceipt: pushResult.transferReceipt,
|
|
854
|
+
pushBoundary,
|
|
855
|
+
excludedProjections: effectiveV2ExcludedProjections,
|
|
856
|
+
});
|
|
857
|
+
const receiptIndex = pushTransferReceipts.indexOf(pushResult.transferReceipt);
|
|
858
|
+
if (receiptIndex >= 0)
|
|
859
|
+
pushTransferReceipts.splice(receiptIndex, 1);
|
|
860
|
+
settledBatchOperationIdentities.add(idempotencyKey);
|
|
861
|
+
}
|
|
862
|
+
else if (pushResult.transferReceipt && normalizedTaskUpserts.length === 0) {
|
|
810
863
|
await remoteServices.acknowledgeNonApplyingTransferReceipts({
|
|
811
864
|
workspaceId: input.workspaceId,
|
|
812
865
|
receipts: [pushResult.transferReceipt],
|
|
@@ -828,6 +881,17 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
828
881
|
await abandonRetainedPushReceipts('WORKSPACE_SYNC_V2_PUSH_ATTEMPT_FAILED');
|
|
829
882
|
throw error;
|
|
830
883
|
}
|
|
884
|
+
if (firstPushFailure) {
|
|
885
|
+
return {
|
|
886
|
+
...firstPushFailure,
|
|
887
|
+
batchProgress: {
|
|
888
|
+
...firstPushFailure.batchProgress,
|
|
889
|
+
completedBatches: completedBatchCount,
|
|
890
|
+
completedChanges: completedChangeCount,
|
|
891
|
+
},
|
|
892
|
+
requestMs,
|
|
893
|
+
};
|
|
894
|
+
}
|
|
831
895
|
return {
|
|
832
896
|
success: true,
|
|
833
897
|
syncedAt: new Date().toISOString(),
|
|
@@ -855,6 +919,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
855
919
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
856
920
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
857
921
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
922
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
858
923
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
859
924
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
860
925
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkspaceSyncTaskforceAgentSnapshot } from './workspaceSyncModel.js';
|
|
2
|
+
type SyncAuthorizationError = Error & {
|
|
3
|
+
code?: string;
|
|
4
|
+
statusCode?: number;
|
|
5
|
+
details?: Record<string, unknown>;
|
|
6
|
+
};
|
|
7
|
+
export declare function assertTaskforceAgentSyncPushAccess(input: {
|
|
8
|
+
agents: Iterable<WorkspaceSyncTaskforceAgentSnapshot>;
|
|
9
|
+
actorUserId: string | null;
|
|
10
|
+
hasUserFeatureGrant: (userId: string, featureKey: unknown) => boolean;
|
|
11
|
+
createSyncRouteError: (message: string, details: Record<string, unknown>, options?: {
|
|
12
|
+
code?: string;
|
|
13
|
+
statusCode?: number;
|
|
14
|
+
}) => SyncAuthorizationError;
|
|
15
|
+
}): void;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getTaskforceAgentModel } from '../shared/taskforceAgentModels.js';
|
|
2
|
+
import { INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY } from '../shared/userFeatureGrants.js';
|
|
3
|
+
export function assertTaskforceAgentSyncPushAccess(input) {
|
|
4
|
+
const actorUserId = String(input.actorUserId || '').trim();
|
|
5
|
+
for (const agent of input.agents) {
|
|
6
|
+
if (agent.deletedAt)
|
|
7
|
+
continue;
|
|
8
|
+
const modelKey = String(agent.definition?.model?.modelKey || agent.modelKey || '').trim();
|
|
9
|
+
if (getTaskforceAgentModel(modelKey)?.source !== 'subscription_dev')
|
|
10
|
+
continue;
|
|
11
|
+
if (actorUserId && input.hasUserFeatureGrant(actorUserId, INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY))
|
|
12
|
+
continue;
|
|
13
|
+
throw input.createSyncRouteError(`Subscription-backed Taskforce Agent ${agent.id} requires an internal user grant.`, {
|
|
14
|
+
source: 'apply.taskforceAgentUpsert',
|
|
15
|
+
agentId: agent.id,
|
|
16
|
+
actorUserId: actorUserId || null,
|
|
17
|
+
featureKey: INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY,
|
|
18
|
+
}, { code: 'SUBSCRIPTION_MODEL_ACCESS_REQUIRED', statusCode: 403 });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -4,6 +4,7 @@ import { WORKSPACE_SYNC_V3_NESTED_COVERAGE_SELECTOR } from './workspaceSyncV3Nes
|
|
|
4
4
|
import { WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowWireContract.js';
|
|
5
5
|
import { WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR } from './workspaceSyncV3PlanningOrderWireContract.js';
|
|
6
6
|
import { WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3TaskCoverWireContract.js';
|
|
7
|
+
import { WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowTaskCoverWireContract.js';
|
|
7
8
|
export { WORKSPACE_SYNC_V3_COMBINED_CAPABILITY_VERSION } from './workspaceSyncV3CombinedWireContract.js';
|
|
8
9
|
export function resolveRequestedCombinedFeedCoverage(env = process.env) {
|
|
9
10
|
const requestedVersion = String(env.TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION || '').trim();
|
|
@@ -22,6 +23,9 @@ export function resolveRequestedCombinedFeedCoverage(env = process.env) {
|
|
|
22
23
|
if (requestedVersion === String(WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR.coverageVersion)) {
|
|
23
24
|
return WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR;
|
|
24
25
|
}
|
|
26
|
+
if (requestedVersion === String(WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR.coverageVersion)) {
|
|
27
|
+
return WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR;
|
|
28
|
+
}
|
|
25
29
|
throw new Error(`Unsupported TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION: ${requestedVersion}.`);
|
|
26
30
|
}
|
|
27
31
|
export function resolveCombinedFeedCapability(input) {
|
|
@@ -7,6 +7,7 @@ import { enqueueLocalInitiativeMutation, } from './localInitiativeOutboxService.
|
|
|
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 { buildInitiativeActivityEventId } from './initiativeActivityIdentity.js';
|
|
11
12
|
const OPERATION_LEASE_MS = 30_000;
|
|
12
13
|
export class DurableInitiativeMutationRouterDisabledError extends Error {
|
|
@@ -85,6 +86,9 @@ export function createDurableInitiativeMutationRouter(input) {
|
|
|
85
86
|
if (persistedOutbox.domain !== 'initiative' || persistedOutbox.entityId !== initiativeId) {
|
|
86
87
|
throw new WorkspaceSyncIdempotencyConflictError();
|
|
87
88
|
}
|
|
89
|
+
store.assertOutboxOperationIdentity(persistedOutbox, {
|
|
90
|
+
domain: 'initiative', entityId: initiativeId, mutationKind: persistedOutbox.mutationKind,
|
|
91
|
+
});
|
|
88
92
|
return {
|
|
89
93
|
revisions: {
|
|
90
94
|
entityRevision: persistedOutbox.baseEntityRevision,
|
|
@@ -99,18 +103,22 @@ export function createDurableInitiativeMutationRouter(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: 'initiative',
|
|
113
|
+
entityId: initiativeId,
|
|
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,
|
|
@@ -15,6 +15,20 @@ export declare class DurableOperationReplayIdentityConflictError extends Error {
|
|
|
15
15
|
readonly code = "DURABLE_OPERATION_REPLAY_IDENTITY_CONFLICT";
|
|
16
16
|
constructor(message?: string);
|
|
17
17
|
}
|
|
18
|
+
export interface DurableOperationIdentityRecord {
|
|
19
|
+
operationId: string;
|
|
20
|
+
domain: string;
|
|
21
|
+
entityId: string;
|
|
22
|
+
mutationKind: string;
|
|
23
|
+
payloadFingerprint: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Canonical identity comparison for durable mutation records. Storage lanes may
|
|
27
|
+
* retain different reservation metadata, but an accepted operation can have
|
|
28
|
+
* only one exact domain/entity/mutation/payload meaning.
|
|
29
|
+
*/
|
|
30
|
+
export declare function assertDurableOperationIdentity(actual: Readonly<DurableOperationIdentityRecord>, expected: Readonly<DurableOperationIdentityRecord>): void;
|
|
31
|
+
export declare function assertDurableOperationFingerprint(actual: string, expected: string): void;
|
|
18
32
|
export interface DurableOperationReplayResult<Payload = unknown> {
|
|
19
33
|
response: Readonly<Record<string, unknown>>;
|
|
20
34
|
authoritative: DurableOperationAuthoritativeEntry<Payload>;
|
|
@@ -12,6 +12,24 @@ export class DurableOperationReplayIdentityConflictError extends Error {
|
|
|
12
12
|
this.name = 'DurableOperationReplayIdentityConflictError';
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Canonical identity comparison for durable mutation records. Storage lanes may
|
|
17
|
+
* retain different reservation metadata, but an accepted operation can have
|
|
18
|
+
* only one exact domain/entity/mutation/payload meaning.
|
|
19
|
+
*/
|
|
20
|
+
export function assertDurableOperationIdentity(actual, expected) {
|
|
21
|
+
if (actual.operationId !== expected.operationId
|
|
22
|
+
|| actual.domain !== expected.domain
|
|
23
|
+
|| actual.entityId !== expected.entityId
|
|
24
|
+
|| actual.mutationKind !== expected.mutationKind
|
|
25
|
+
|| actual.payloadFingerprint !== expected.payloadFingerprint) {
|
|
26
|
+
throw new DurableOperationReplayIdentityConflictError();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function assertDurableOperationFingerprint(actual, expected) {
|
|
30
|
+
if (!actual || actual !== expected)
|
|
31
|
+
throw new DurableOperationReplayIdentityConflictError();
|
|
32
|
+
}
|
|
15
33
|
const DEFAULT_MAX_AUTHORITATIVE_ENTRIES = 1_024;
|
|
16
34
|
const POSITIVE_REVISION = /^[1-9]\d*$/;
|
|
17
35
|
const NON_NEGATIVE_REVISION = /^(0|[1-9]\d*)$/;
|
|
@@ -150,6 +150,9 @@ export function createDurableTaskAttachmentLinksMutationRouter(input) {
|
|
|
150
150
|
|| String(payload.cardCoverAssetId || '') !== String(cardCoverAssetId || '')) {
|
|
151
151
|
throw new DurableTaskAttachmentLinksMutationError('Operation identity is assigned to different task attachment links.', 'TASK_ATTACHMENT_LINKS_IDENTITY_CONFLICT', 409);
|
|
152
152
|
}
|
|
153
|
+
store.assertOutboxOperationIdentity(existing, {
|
|
154
|
+
domain: 'task-attachment-links', entityId: taskId, mutationKind: 'replace',
|
|
155
|
+
});
|
|
153
156
|
const task = input.core.getTask(taskId, workspaceId);
|
|
154
157
|
if (!task)
|
|
155
158
|
throw new DurableTaskAttachmentLinksMutationError('Task not found.', 'TASK_NOT_FOUND', 404);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChecklistItem, TaskItem } from '../../core/Taskforce.js';
|
|
2
2
|
import type { DatabaseAdapter } from '../../storage/databaseAdapter.js';
|
|
3
3
|
import { type LocalTaskChecklistOutboxCore } from './localTaskChecklistOutboxService.js';
|
|
4
|
-
import { type DurableTaskChecklistServiceCore } from './taskChecklistMutationService.js';
|
|
4
|
+
import { type DurableTaskChecklistServiceCore, type TaskChecklistItemUpdateIntent } from './taskChecklistMutationService.js';
|
|
5
5
|
export declare function resolveTaskChecklistMutationCapability(input: {
|
|
6
6
|
runtimeMode: 'local' | 'cloud';
|
|
7
7
|
surface: 'http' | 'mcp';
|
|
@@ -40,6 +40,7 @@ export declare function createDurableTaskChecklistMutationRouter(input: {
|
|
|
40
40
|
taskId: string;
|
|
41
41
|
items: readonly Partial<ChecklistItem>[];
|
|
42
42
|
expectedDetailRevision?: string;
|
|
43
|
+
itemUpdateIntent?: TaskChecklistItemUpdateIntent;
|
|
43
44
|
}): {
|
|
44
45
|
state: "pending" | "committed";
|
|
45
46
|
route: "local-outbox" | "cloud-acceptance";
|
|
@@ -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,
|