@taskforcehq/taskforce 0.3.328 → 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 +523 -79
- package/dist/TaskforceCore.js +237 -230
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
- package/dist/cli.js +34 -0
- package/dist/cliCloudTargetGuard.d.ts +5 -0
- package/dist/cliCloudTargetGuard.js +11 -0
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
- package/dist/components/features/TaskSettings.d.ts +12 -1
- package/dist/components/features/TaskSettings.js +217 -54
- 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 +1 -1
- 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 +2 -5
- package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
- package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
- package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
- package/dist/components/features/planning/planningTaskArrangement.js +5 -5
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +5 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskCard.d.ts +5 -0
- package/dist/components/task/TaskCard.js +65 -10
- package/dist/components/task/TaskImageReviews.js +14 -5
- package/dist/components/task/TaskKanban.d.ts +6 -1
- package/dist/components/task/TaskKanban.js +152 -6
- package/dist/components/task/TaskList.d.ts +5 -0
- package/dist/components/task/TaskList.js +3 -3
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/ui/PasswordInput.d.ts +6 -0
- package/dist/components/ui/PasswordInput.js +11 -0
- package/dist/components/ui/TopNoticeLayer.js +1 -1
- package/dist/components/views/AppShellHeader.js +32 -11
- package/dist/components/views/PlanComparisonPage.js +12 -0
- package/dist/components/views/StandaloneLayout.js +32 -55
- package/dist/components/views/WidgetView.js +3 -3
- package/dist/components/views/panels/PlanningDrawer.js +5 -12
- package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
- 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 +60 -1
- package/dist/config/localServiceRuntimeContract.d.ts +13 -0
- package/dist/config/localServiceRuntimeContract.js +135 -0
- package/dist/core/AiProfileService.js +46 -8
- package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
- package/dist/core/DeletedTaskLifecycleService.js +37 -6
- package/dist/core/McpTokenService.d.ts +23 -1
- package/dist/core/McpTokenService.js +93 -10
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
- 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 +94 -2
- package/dist/core/Taskforce.js +760 -36
- package/dist/core/types.d.ts +14 -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/useDurableLocalOutboxDrain.d.ts +1 -1
- package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
- package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
- package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
- package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -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/tasks/taskHttpMutation.js +1 -0
- package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
- package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
- package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
- package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
- package/dist/hooks/tasks/useTaskFormActions.js +65 -12
- package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
- package/dist/hooks/ui/useSettingsModel.js +13 -2
- package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
- package/dist/hooks/ui/useSettingsPersistence.js +74 -47
- package/dist/hooks/useFilterSort.d.ts +7 -3
- package/dist/hooks/useFilterSort.js +15 -5
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +40 -1
- package/dist/hooks/useTaskData.js +240 -9
- package/dist/hooks/useTaskMutations.d.ts +12 -2
- package/dist/hooks/useTaskMutations.js +266 -52
- package/dist/hooks/useTaskforce.d.ts +39 -9
- package/dist/hooks/useTaskforce.js +359 -40
- package/dist/hooks/useUiNotice.d.ts +4 -0
- package/dist/hooks/useUiNotice.js +4 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +53 -41
- package/dist/mcp/documentHelpers.d.ts +1 -0
- package/dist/mcp/documentHelpers.js +7 -3
- 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 +556 -139
- package/dist/mcp/taskPlanningRegistrar.js +64 -42
- package/dist/mcp/toolCallCompatibility.js +38 -1
- package/dist/mcp/toolCatalog.d.ts +1 -0
- 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 +427 -0
- package/dist/runtime/appGateDefinitions.d.ts +30 -6
- package/dist/runtime/appGateDefinitions.js +6 -6
- package/dist/runtime/appGates.d.ts +13 -13
- package/dist/runtime/appGates.js +36 -13
- package/dist/runtime/nodeAppGates.d.ts +8 -0
- package/dist/runtime/nodeAppGates.js +27 -0
- package/dist/server/cloudCollectionRead.d.ts +1 -1
- package/dist/server/cloudCollectionRead.js +2 -2
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.js +123 -14
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.d.ts +3 -0
- package/dist/server/localServiceLease.js +11 -2
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +12 -7
- package/dist/server/rateLimit.d.ts +1 -0
- package/dist/server/rateLimit.js +4 -0
- package/dist/server/realtimeSyncWs.js +36 -12
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +113 -3
- package/dist/server/routes/agentRoles.js +3 -2
- package/dist/server/routes/agentSkills.js +3 -2
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +394 -39
- package/dist/server/routes/annotatedAttachments.js +3 -2
- package/dist/server/routes/auth.js +3 -1
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
- 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 +138 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/primitives.d.ts +2 -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 +9 -2
- package/dist/server/routes/syncPullApplyRoutes.js +23 -4
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +27 -16
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
- package/dist/server/routes/syncV3OperationRoutes.js +45 -9
- package/dist/server/routes/tasks.js +124 -13
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes/workspaces.js +43 -1
- package/dist/server/routes.js +59 -0
- package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
- package/dist/server/workspaceDeletionAdmission.js +50 -0
- package/dist/service/localServiceCli.js +16 -0
- package/dist/service/localServiceClientLifecycle.js +36 -10
- package/dist/services/codexAppServerModelGateway.d.ts +161 -0
- package/dist/services/codexAppServerModelGateway.js +663 -0
- 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 +8 -2
- package/dist/services/taskforceAgentMcpBridge.js +30 -27
- 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 -3
- package/dist/shared/taskforceAgentModels.d.ts +1 -0
- package/dist/shared/taskforceAgentModels.js +36 -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 +24 -3
- package/dist/storage/postgresAdapter.js +117 -14
- package/dist/storage/postgresWorker.js +22 -5
- package/dist/storage/postgresWorkerProtocol.d.ts +30 -0
- package/dist/storage/postgresWorkerProtocol.js +30 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/sync/cloudSyncApi.d.ts +4 -1
- package/dist/sync/cloudSyncApi.js +7 -2
- package/dist/sync/contentSyncState.d.ts +1 -1
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +67 -30
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
- 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/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
- package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
- 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/workspaceSyncEngineRemoteServices.d.ts +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +134 -43
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +11 -4
- 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 +17 -0
- package/dist/sync/syncService.js +87 -19
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +8 -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.d.ts +2 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +14 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +4 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +62 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +37 -2
- 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/localTaskAttachmentLinksOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
- 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.js +15 -6
- package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
- package/dist/sync/v3/localTaskMetadataClient.js +1 -0
- package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
- package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
- package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
- package/dist/sync/v3/localTaskStatusClient.js +6 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +272 -24
- package/dist/sync/v3/syncDurabilityStore.d.ts +41 -0
- package/dist/sync/v3/syncDurabilityStore.js +199 -13
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
- package/dist/sync/v3/taskChecklistMutationService.d.ts +15 -2
- package/dist/sync/v3/taskChecklistMutationService.js +48 -1
- package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
- package/dist/sync/v3/taskCreateMutationService.js +7 -4
- package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
- package/dist/sync/v3/taskMetadataMutationService.js +4 -0
- package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
- package/dist/sync/v3/taskRestoreMutationService.js +7 -4
- package/dist/sync/v3/taskStatusMutationService.d.ts +31 -1
- package/dist/sync/v3/taskStatusMutationService.js +123 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +6 -0
- package/dist/sync/v3/workflowAssignmentSync.js +30 -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/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +18 -3
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +14 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +49 -25
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +13 -4
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -57
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +20 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +106 -30
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +4 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +34 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +12 -0
- package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +55 -9
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -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/workspacePullFeed.js +2 -1
- package/dist/sync/workspaceRepair.d.ts +8 -2
- package/dist/sync/workspaceRepair.js +222 -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/types.d.ts +47 -1
- package/dist/types.js +6 -0
- package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
- package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTM6nIg_.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
- package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-DabEG8L4.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Coa8yVGM.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-BB0qhdix.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
- package/dist/ui/assets/PlanningModule-pRPjR7v5.js +1 -0
- package/dist/ui/assets/PlansPage-D86pZSSl.js +1 -0
- package/dist/ui/assets/TaskContextUpload-BVIkU9yT.js +1 -0
- 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-DWFspC-o.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-BkFLXavV.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/taskActivity.d.ts +3 -2
- package/dist/utils/taskActivity.js +19 -2
- package/dist/utils/taskEditorReconciliation.d.ts +40 -0
- package/dist/utils/taskEditorReconciliation.js +217 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/taskNormalization.d.ts +1 -0
- package/dist/utils/taskNormalization.js +39 -0
- package/dist/utils/taskSearch.js +2 -2
- package/dist/utils/uiNotice.d.ts +4 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +36 -6
- package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +0 -1
- package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
- package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
- package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
- package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
- package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-BUplSsv_.js +0 -7
- package/dist/ui/assets/index-gz2EXuoK.css +0 -1
|
@@ -35,6 +35,9 @@ export function runDurableTaskMetadataUpdate(input) {
|
|
|
35
35
|
...(input.activityAction && input.activityAction !== 'task-updated'
|
|
36
36
|
? { activityAction: input.activityAction }
|
|
37
37
|
: {}),
|
|
38
|
+
...(input.expectedDetailRevision
|
|
39
|
+
? { expectedDetailRevision: input.expectedDetailRevision }
|
|
40
|
+
: {}),
|
|
38
41
|
},
|
|
39
42
|
});
|
|
40
43
|
const activityEventId = buildTaskMetadataActivityEventId({
|
|
@@ -112,6 +115,7 @@ export function runDurableTaskMetadataUpdate(input) {
|
|
|
112
115
|
})),
|
|
113
116
|
}],
|
|
114
117
|
applyMutation: () => {
|
|
118
|
+
input.assertPrecondition?.();
|
|
115
119
|
const actorRef = resolveDeferredMutationActorRef(input);
|
|
116
120
|
if (!carriers)
|
|
117
121
|
return applyTaskMetadataUpdateForDurableSync({
|
|
@@ -2,7 +2,7 @@ import type { TaskEvent } from '../../core/Taskforce.js';
|
|
|
2
2
|
import type { TaskRestoreDestination } from '../../shared/taskRestoreDestination.js';
|
|
3
3
|
import { type DurableTaskRestoreCore } from '../../core/TaskDurableRestoreMutationService.js';
|
|
4
4
|
import { serializeTaskForSync } from '../taskSyncPayload.js';
|
|
5
|
-
import {
|
|
5
|
+
import { serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, type WorkspaceSyncV3TaskAttachmentLink } from './workspaceSyncV3NestedTaskCodecs.js';
|
|
6
6
|
import { type WorkspaceSyncActivityRevision } from './taskActivityJournal.js';
|
|
7
7
|
import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
|
|
8
8
|
export interface DurableTaskRestoreServiceCore extends DurableTaskRestoreCore {
|
|
@@ -57,7 +57,7 @@ export type DurableTaskRestoreResponse = {
|
|
|
57
57
|
sequence: string;
|
|
58
58
|
entityRevision: string;
|
|
59
59
|
lifecycleRevision: string;
|
|
60
|
-
payload: ReturnType<typeof
|
|
60
|
+
payload: ReturnType<typeof serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload>;
|
|
61
61
|
};
|
|
62
62
|
activity: TaskEvent;
|
|
63
63
|
activityRevision: WorkspaceSyncActivityRevision;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { applyTaskRestoreForDurableSync, } from '../../core/TaskDurableRestoreMutationService.js';
|
|
2
2
|
import { serializeTaskForSync } from '../taskSyncPayload.js';
|
|
3
3
|
import { buildTaskLifecycleActivityEventId } from './taskLifecycleActivityIdentity.js';
|
|
4
|
-
import {
|
|
4
|
+
import { serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload, serializeWorkspaceSyncV3TaskChecklistPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
|
|
5
5
|
import { asWorkspaceSyncActivityRevision, buildTaskActivityJournalEntry, } from './taskActivityJournal.js';
|
|
6
6
|
import { fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
|
|
7
7
|
export function runDurableTaskRestore(input) {
|
|
@@ -90,13 +90,15 @@ export function runDurableTaskRestore(input) {
|
|
|
90
90
|
domain: 'task-attachment-links', entityId: input.taskId, mutationKind: 'replace', revisionKind: 'metadata',
|
|
91
91
|
baseEntityRevision: 0, baseLifecycleRevision: 0,
|
|
92
92
|
baseRevisionPolicy: 'current',
|
|
93
|
-
buildCanonicalFingerprint: (task) => fingerprintWorkspaceSyncPayload(
|
|
93
|
+
buildCanonicalFingerprint: (task) => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
|
|
94
94
|
taskId: task.id,
|
|
95
95
|
links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
|
|
96
|
+
cardCoverAssetId: task.cardCoverAssetId ?? null,
|
|
96
97
|
})),
|
|
97
|
-
buildAuthoritativePayload: (task) =>
|
|
98
|
+
buildAuthoritativePayload: (task) => serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
|
|
98
99
|
taskId: task.id,
|
|
99
100
|
links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
|
|
101
|
+
cardCoverAssetId: task.cardCoverAssetId ?? null,
|
|
100
102
|
}),
|
|
101
103
|
}, buildTaskActivityJournalEntry({ eventId: activityEventId, readEvent: readActivity })],
|
|
102
104
|
applyMutation: () => applyTaskRestoreForDurableSync({
|
|
@@ -151,9 +153,10 @@ export function runDurableTaskRestore(input) {
|
|
|
151
153
|
domain: 'task-attachment-links', entityId: task.id, mutationKind: 'replace',
|
|
152
154
|
sequence: attachmentRevision.sequence, entityRevision: attachmentRevision.entityRevision,
|
|
153
155
|
lifecycleRevision: attachmentRevision.lifecycleRevision,
|
|
154
|
-
payload:
|
|
156
|
+
payload: serializeWorkspaceSyncV3TaskAttachmentLinksV2Payload({
|
|
155
157
|
taskId: task.id,
|
|
156
158
|
links: input.core.listTaskAttachmentLinksForDurableSync(task.id, input.workspaceId),
|
|
159
|
+
cardCoverAssetId: task.cardCoverAssetId ?? null,
|
|
157
160
|
}),
|
|
158
161
|
},
|
|
159
162
|
activity: readActivity(),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityEvent, TaskEvent } from '../../core/Taskforce.js';
|
|
1
|
+
import type { Comment, EntityEvent, TaskEvent } from '../../core/Taskforce.js';
|
|
2
2
|
import type { DatabaseAdapter } from '../../storage/databaseAdapter.js';
|
|
3
3
|
import type { TaskActor } from '../../types.js';
|
|
4
4
|
import { type DurableTaskStatusMutationCore } from '../../core/TaskDurableStatusMutationService.js';
|
|
@@ -6,6 +6,7 @@ import { serializeTaskForSync } from '../taskSyncPayload.js';
|
|
|
6
6
|
import type { WorkflowAssignmentSyncRecord } from '../../storage/workflowStore.js';
|
|
7
7
|
import { type WorkspaceSyncActivityRevision } from './taskActivityJournal.js';
|
|
8
8
|
import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
|
|
9
|
+
import { type WorkspaceSyncV3TaskCommentsPayload } from './workspaceSyncV3NestedTaskCodecs.js';
|
|
9
10
|
export interface DurableTaskStatusServiceCore extends DurableTaskStatusMutationCore {
|
|
10
11
|
notifyDurableTaskLifecycleCommitted(workspaceId: string, taskId: string): void;
|
|
11
12
|
getTaskEventForSync(input: {
|
|
@@ -19,6 +20,14 @@ export interface DurableTaskStatusServiceCore extends DurableTaskStatusMutationC
|
|
|
19
20
|
}): EntityEvent | null;
|
|
20
21
|
listAssignableActors(workspaceId: string): TaskActor[];
|
|
21
22
|
getDatabaseAdapter(): DatabaseAdapter;
|
|
23
|
+
addTaskCommentEventForDurableSync(event: {
|
|
24
|
+
taskId: string;
|
|
25
|
+
workspaceId: string;
|
|
26
|
+
actor: string;
|
|
27
|
+
eventId: string;
|
|
28
|
+
createdAt: string;
|
|
29
|
+
comment: Comment;
|
|
30
|
+
}): void;
|
|
22
31
|
}
|
|
23
32
|
export type DurableTaskStatusResponse = {
|
|
24
33
|
success: true;
|
|
@@ -45,7 +54,25 @@ export type DurableTaskStatusResponse = {
|
|
|
45
54
|
dependentActivities?: EntityEvent[];
|
|
46
55
|
dependentActivityRevisions?: WorkspaceSyncActivityRevision[];
|
|
47
56
|
workflowAssignment?: WorkflowAssignmentSyncRecord;
|
|
57
|
+
reviewHandoff?: {
|
|
58
|
+
comments: {
|
|
59
|
+
domain: 'task-comments';
|
|
60
|
+
entityId: string;
|
|
61
|
+
mutationKind: 'append';
|
|
62
|
+
sequence: string;
|
|
63
|
+
entityRevision: string;
|
|
64
|
+
lifecycleRevision: string;
|
|
65
|
+
payload: WorkspaceSyncV3TaskCommentsPayload;
|
|
66
|
+
};
|
|
67
|
+
activity: TaskEvent;
|
|
68
|
+
activityRevision: WorkspaceSyncActivityRevision;
|
|
69
|
+
};
|
|
48
70
|
};
|
|
71
|
+
export declare class WorkflowRuntimeActivationFencedError extends Error {
|
|
72
|
+
readonly code = "WORKFLOW_RUNTIME_MUTATIONS_FENCED";
|
|
73
|
+
readonly statusCode = 503;
|
|
74
|
+
constructor();
|
|
75
|
+
}
|
|
49
76
|
export declare function runDurableTaskStatusMutation(input: {
|
|
50
77
|
store: WorkspaceSyncDurabilityStore;
|
|
51
78
|
core: DurableTaskStatusServiceCore;
|
|
@@ -64,6 +91,9 @@ export declare function runDurableTaskStatusMutation(input: {
|
|
|
64
91
|
resolveActorRef?: () => string;
|
|
65
92
|
originActorRef?: string;
|
|
66
93
|
includeWorkflowRuntimeJournal?: boolean;
|
|
94
|
+
rejectWorkflowRuntimeActivation?: boolean;
|
|
95
|
+
expectedDetailRevision?: string;
|
|
96
|
+
assertPrecondition?: () => void;
|
|
67
97
|
onPostCommitError?: (error: unknown) => void;
|
|
68
98
|
}): {
|
|
69
99
|
state: 'in_progress';
|
|
@@ -8,7 +8,27 @@ import { asWorkspaceSyncActivityRevision, buildEntityActivityJournalEntry, build
|
|
|
8
8
|
import { fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
|
|
9
9
|
import { resolveDeferredMutationActorRef } from './workspaceSyncV3OriginActor.js';
|
|
10
10
|
import { buildWorkflowRuntimeEventId } from './workflowRuntimeOperationIdentity.js';
|
|
11
|
+
import { buildTaskCommentActivityEventId } from './taskCommentActivityIdentity.js';
|
|
12
|
+
import { serializeWorkspaceSyncV3TaskCommentAppendPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
|
|
11
13
|
import { fingerprintWorkflowRuntimePayload, serializeWorkflowExecutionEventSyncPayload, serializeWorkflowExecutionRootSyncPayload, serializeWorkflowPublishedDefinitionSyncPayload, } from './workflowRuntimeSync.js';
|
|
14
|
+
export class WorkflowRuntimeActivationFencedError extends Error {
|
|
15
|
+
code = 'WORKFLOW_RUNTIME_MUTATIONS_FENCED';
|
|
16
|
+
statusCode = 503;
|
|
17
|
+
constructor() {
|
|
18
|
+
super('Workflow execution changes are temporarily paused.');
|
|
19
|
+
this.name = 'WorkflowRuntimeActivationFencedError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function nextTaskUpdatedAt(current, requested) {
|
|
23
|
+
const currentMs = Date.parse(current);
|
|
24
|
+
const requestedMs = Date.parse(requested);
|
|
25
|
+
if (!Number.isFinite(requestedMs) || new Date(requestedMs).toISOString() !== requested) {
|
|
26
|
+
throw new Error('Task status operation timestamp is invalid.');
|
|
27
|
+
}
|
|
28
|
+
return Number.isFinite(currentMs) && currentMs >= requestedMs
|
|
29
|
+
? new Date(currentMs + 1).toISOString()
|
|
30
|
+
: requested;
|
|
31
|
+
}
|
|
12
32
|
export function runDurableTaskStatusMutation(input) {
|
|
13
33
|
const operationPayload = normalizeTaskStatusOperationWithWorkflowAssignment(input.payload);
|
|
14
34
|
const payload = validateDurableTaskStatusMutationPayload({
|
|
@@ -34,6 +54,9 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
34
54
|
baseLifecycleRevision: String(input.baseLifecycleRevision),
|
|
35
55
|
payload: operationPayload,
|
|
36
56
|
...(input.originActorRef ? { originActorRef: input.originActorRef } : {}),
|
|
57
|
+
...(input.expectedDetailRevision
|
|
58
|
+
? { expectedDetailRevision: input.expectedDetailRevision }
|
|
59
|
+
: {}),
|
|
37
60
|
},
|
|
38
61
|
});
|
|
39
62
|
const activityEventId = buildTaskLifecycleActivityEventId({
|
|
@@ -45,10 +68,24 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
45
68
|
});
|
|
46
69
|
const membershipRemovedEventId = `${activityEventId}:workstream-removed`;
|
|
47
70
|
const membershipAddedEventId = `${activityEventId}:workstream-added`;
|
|
71
|
+
const requestedReviewComment = operationPayload.reviewHandoff?.comment || null;
|
|
72
|
+
let reviewComment = null;
|
|
73
|
+
const reviewCommentActivityEventId = requestedReviewComment ? buildTaskCommentActivityEventId({
|
|
74
|
+
workspaceId: input.workspaceId,
|
|
75
|
+
clientId: input.clientId,
|
|
76
|
+
operationId: input.operationId,
|
|
77
|
+
taskId: input.taskId,
|
|
78
|
+
commentId: requestedReviewComment.id,
|
|
79
|
+
}) : null;
|
|
48
80
|
const workflowStore = new WorkflowStore(input.core.getDatabaseAdapter(), input.tenantId);
|
|
49
81
|
const workflowActivationService = new WorkflowTaskActivationService(workflowStore, (workspaceId) => input.core.listAssignableActors(workspaceId));
|
|
50
82
|
const pendingAssignment = operationPayload.workflowAssignment
|
|
51
83
|
|| workflowStore.getAssignmentForTaskSync(input.workspaceId, input.taskId);
|
|
84
|
+
if (input.rejectWorkflowRuntimeActivation === true
|
|
85
|
+
&& payload.status === 'in-progress'
|
|
86
|
+
&& pendingAssignment?.execution.status === 'pending') {
|
|
87
|
+
throw new WorkflowRuntimeActivationFencedError();
|
|
88
|
+
}
|
|
52
89
|
const workflowStartEventId = buildWorkflowRuntimeEventId({
|
|
53
90
|
workspaceId: input.workspaceId,
|
|
54
91
|
clientId: input.clientId,
|
|
@@ -92,6 +129,16 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
92
129
|
throw new Error('Task status activity was not committed.');
|
|
93
130
|
return activity;
|
|
94
131
|
};
|
|
132
|
+
const readReviewCommentActivity = () => {
|
|
133
|
+
const activity = input.core.getTaskEventForSync({
|
|
134
|
+
workspaceId: input.workspaceId,
|
|
135
|
+
taskId: input.taskId,
|
|
136
|
+
eventId: reviewCommentActivityEventId,
|
|
137
|
+
});
|
|
138
|
+
if (!activity)
|
|
139
|
+
throw new Error('Review handoff comment activity was not committed.');
|
|
140
|
+
return activity;
|
|
141
|
+
};
|
|
95
142
|
const workflowAssignmentAfterMutation = () => {
|
|
96
143
|
const assignment = workflowStore.getAssignmentForTaskSync(input.workspaceId, input.taskId);
|
|
97
144
|
if (!assignment || assignment.execution.id !== pendingAssignment?.execution.id) {
|
|
@@ -155,7 +202,22 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
155
202
|
reopenAssigneeOwned: (result) => result.assigneeOwned,
|
|
156
203
|
buildCanonicalFingerprint: (result) => (fingerprintWorkspaceSyncPayload(serializeTaskForSync(result.task))),
|
|
157
204
|
buildAuthoritativePayload: (result) => serializeTaskForSync(result.task),
|
|
158
|
-
}, {
|
|
205
|
+
}, ...(requestedReviewComment ? [{
|
|
206
|
+
domain: 'task-comments', entityId: input.taskId, mutationKind: 'append', revisionKind: 'metadata',
|
|
207
|
+
baseEntityRevision: 0, baseLifecycleRevision: 0, baseRevisionPolicy: 'current',
|
|
208
|
+
buildCanonicalFingerprint: (result) => fingerprintWorkspaceSyncPayload(serializeWorkspaceSyncV3TaskCommentsPayload({
|
|
209
|
+
taskId: result.task.id,
|
|
210
|
+
comments: result.task.comments || [],
|
|
211
|
+
})),
|
|
212
|
+
buildAuthoritativePayload: (result) => (serializeWorkspaceSyncV3TaskCommentAppendPayload({
|
|
213
|
+
taskId: result.task.id,
|
|
214
|
+
comment: reviewComment,
|
|
215
|
+
commentsAfterAppend: result.task.comments || [],
|
|
216
|
+
})),
|
|
217
|
+
}, buildTaskActivityJournalEntry({
|
|
218
|
+
eventId: reviewCommentActivityEventId,
|
|
219
|
+
readEvent: readReviewCommentActivity,
|
|
220
|
+
})] : []), {
|
|
159
221
|
...buildTaskActivityJournalEntry({ eventId: activityEventId, readEvent: readActivity }),
|
|
160
222
|
include: (result) => !result.noOp,
|
|
161
223
|
}, {
|
|
@@ -184,6 +246,7 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
184
246
|
})),
|
|
185
247
|
}, ...workflowEntries],
|
|
186
248
|
applyMutation: () => {
|
|
249
|
+
input.assertPrecondition?.();
|
|
187
250
|
const currentTask = input.core.getTask(input.taskId, input.workspaceId);
|
|
188
251
|
if (operationPayload.workflowAssignment) {
|
|
189
252
|
if (payload.status !== 'in-progress'
|
|
@@ -204,7 +267,7 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
204
267
|
})
|
|
205
268
|
: null;
|
|
206
269
|
const actorRef = resolveDeferredMutationActorRef(input);
|
|
207
|
-
|
|
270
|
+
let result = applyTaskStatusMutationForDurableSync({
|
|
208
271
|
core: input.core,
|
|
209
272
|
workspaceId: input.workspaceId,
|
|
210
273
|
taskId: input.taskId,
|
|
@@ -220,6 +283,42 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
220
283
|
actorRef,
|
|
221
284
|
taskEventId: activityEventId,
|
|
222
285
|
});
|
|
286
|
+
if (requestedReviewComment) {
|
|
287
|
+
const authoritativeReviewComment = {
|
|
288
|
+
...requestedReviewComment,
|
|
289
|
+
author: actorRef,
|
|
290
|
+
submittedAuthor: actorRef,
|
|
291
|
+
timestamp: input.now,
|
|
292
|
+
};
|
|
293
|
+
reviewComment = authoritativeReviewComment;
|
|
294
|
+
const existingComments = serializeWorkspaceSyncV3TaskCommentsPayload({
|
|
295
|
+
taskId: result.task.id,
|
|
296
|
+
comments: result.task.comments || [],
|
|
297
|
+
}).comments;
|
|
298
|
+
const collision = existingComments.find((comment) => comment.id === authoritativeReviewComment.id);
|
|
299
|
+
if (collision) {
|
|
300
|
+
throw new Error(`Review handoff comment identity conflict: ${authoritativeReviewComment.id}.`);
|
|
301
|
+
}
|
|
302
|
+
const updatedAt = nextTaskUpdatedAt(String(result.task.updatedAt || result.task.createdAt), input.now);
|
|
303
|
+
const updated = input.core.updateTask(result.task.id, { comments: [...existingComments, authoritativeReviewComment] }, input.workspaceId, {
|
|
304
|
+
persistBackup: false,
|
|
305
|
+
emitRealtime: false,
|
|
306
|
+
skipTaskEvents: true,
|
|
307
|
+
syncUpdatedAt: updatedAt,
|
|
308
|
+
allowV3OwnedMetadataWrite: true,
|
|
309
|
+
});
|
|
310
|
+
if (!updated)
|
|
311
|
+
throw new Error('Review handoff task disappeared during comment persistence.');
|
|
312
|
+
input.core.addTaskCommentEventForDurableSync({
|
|
313
|
+
taskId: updated.id,
|
|
314
|
+
workspaceId: input.workspaceId,
|
|
315
|
+
actor: actorRef,
|
|
316
|
+
eventId: reviewCommentActivityEventId,
|
|
317
|
+
createdAt: String(updated.updatedAt),
|
|
318
|
+
comment: authoritativeReviewComment,
|
|
319
|
+
});
|
|
320
|
+
result = { ...result, task: updated };
|
|
321
|
+
}
|
|
223
322
|
if (activation) {
|
|
224
323
|
workflowActivationService.start({
|
|
225
324
|
workspaceId: input.workspaceId,
|
|
@@ -257,6 +356,9 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
257
356
|
throw new Error('Dependent task status activity was not committed.');
|
|
258
357
|
return event;
|
|
259
358
|
});
|
|
359
|
+
const reviewCommentsRevision = reviewComment ? revisions.find((revision) => (revision.domain === 'task-comments' && revision.entityId === input.taskId)) : null;
|
|
360
|
+
const reviewActivityRevisionValue = reviewComment ? revisions.find((revision) => (revision.domain === 'entity-event' && revision.entityId === reviewCommentActivityEventId)) : null;
|
|
361
|
+
const reviewActivity = reviewComment ? readReviewCommentActivity() : null;
|
|
260
362
|
return {
|
|
261
363
|
success: true,
|
|
262
364
|
contractVersion: WORKSPACE_SYNC_CONTRACT_VERSION,
|
|
@@ -281,6 +383,24 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
281
383
|
activityRevision,
|
|
282
384
|
...(dependentActivities.length > 0 ? { dependentActivities } : {}),
|
|
283
385
|
...(dependentActivityRevisions.length > 0 ? { dependentActivityRevisions } : {}),
|
|
386
|
+
...(reviewComment && reviewCommentsRevision && reviewActivityRevisionValue && reviewActivity ? {
|
|
387
|
+
reviewHandoff: {
|
|
388
|
+
comments: {
|
|
389
|
+
domain: 'task-comments',
|
|
390
|
+
entityId: result.task.id,
|
|
391
|
+
mutationKind: 'append',
|
|
392
|
+
sequence: reviewCommentsRevision.sequence,
|
|
393
|
+
entityRevision: reviewCommentsRevision.entityRevision,
|
|
394
|
+
lifecycleRevision: reviewCommentsRevision.lifecycleRevision,
|
|
395
|
+
payload: serializeWorkspaceSyncV3TaskCommentsPayload({
|
|
396
|
+
taskId: result.task.id,
|
|
397
|
+
comments: result.task.comments || [],
|
|
398
|
+
}),
|
|
399
|
+
},
|
|
400
|
+
activity: reviewActivity,
|
|
401
|
+
activityRevision: asWorkspaceSyncActivityRevision(reviewActivityRevisionValue),
|
|
402
|
+
},
|
|
403
|
+
} : {}),
|
|
284
404
|
...(workflowStore.getAssignmentForTaskSync(input.workspaceId, result.task.id)
|
|
285
405
|
? { workflowAssignment: workflowStore.getAssignmentForTaskSync(input.workspaceId, result.task.id) }
|
|
286
406
|
: {}),
|
|
@@ -288,7 +408,7 @@ export function runDurableTaskStatusMutation(input) {
|
|
|
288
408
|
},
|
|
289
409
|
});
|
|
290
410
|
const response = JSON.parse(accepted.responseJson);
|
|
291
|
-
if (response.activity) {
|
|
411
|
+
if (response.activity || response.reviewHandoff) {
|
|
292
412
|
try {
|
|
293
413
|
input.core.notifyDurableTaskLifecycleCommitted(input.workspaceId, input.taskId);
|
|
294
414
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { WorkflowAssignmentSyncRecord, WorkflowExecutionEventRecord, WorkflowExecutionRecord, WorkflowStepRecord, WorkflowTemplateRecord, WorkflowVersionRecord } from '../../storage/workflowStore.js';
|
|
2
|
+
import type { Comment } from '../../core/Taskforce.js';
|
|
2
3
|
import { type DurableTaskStatusMutationPayload } from '../../core/TaskDurableStatusMutationService.js';
|
|
4
|
+
export type TaskStatusReviewHandoff = {
|
|
5
|
+
comment: Pick<Comment, 'id' | 'author' | 'submittedAuthor' | 'text'>;
|
|
6
|
+
};
|
|
3
7
|
export type TaskStatusOperationWithWorkflowAssignment = DurableTaskStatusMutationPayload & {
|
|
4
8
|
workflowAssignment?: WorkflowAssignmentSyncRecord;
|
|
9
|
+
expectedDetailRevision?: string;
|
|
10
|
+
reviewHandoff?: TaskStatusReviewHandoff;
|
|
5
11
|
};
|
|
6
12
|
export declare class WorkflowAssignmentSyncError extends Error {
|
|
7
13
|
readonly code = "WORKFLOW_ASSIGNMENT_SYNC_INVALID";
|
|
@@ -203,11 +203,41 @@ export function normalizeTaskStatusOperationWithWorkflowAssignment(raw) {
|
|
|
203
203
|
}
|
|
204
204
|
originActor = { kind: 'ai-profile', profileId };
|
|
205
205
|
}
|
|
206
|
+
let reviewHandoff;
|
|
207
|
+
if (source.reviewHandoff !== undefined) {
|
|
208
|
+
if (status.status !== 'review') {
|
|
209
|
+
throw new WorkflowAssignmentSyncError('reviewHandoff is valid only when status is review.');
|
|
210
|
+
}
|
|
211
|
+
const handoff = object(source.reviewHandoff, 'reviewHandoff');
|
|
212
|
+
if (Object.keys(handoff).join(',') !== 'comment') {
|
|
213
|
+
throw new WorkflowAssignmentSyncError('reviewHandoff must contain exactly comment.');
|
|
214
|
+
}
|
|
215
|
+
const comment = object(handoff.comment, 'reviewHandoff.comment');
|
|
216
|
+
if (Object.keys(comment).sort().join(',') !== 'author,id,submittedAuthor,text') {
|
|
217
|
+
throw new WorkflowAssignmentSyncError('reviewHandoff.comment must contain exactly id, author, submittedAuthor, and text.');
|
|
218
|
+
}
|
|
219
|
+
const author = text(comment.author, 'reviewHandoff.comment.author');
|
|
220
|
+
const submittedAuthor = text(comment.submittedAuthor, 'reviewHandoff.comment.submittedAuthor');
|
|
221
|
+
const commentText = text(comment.text, 'reviewHandoff.comment.text');
|
|
222
|
+
if (author !== submittedAuthor) {
|
|
223
|
+
throw new WorkflowAssignmentSyncError('reviewHandoff comment authorship is invalid.');
|
|
224
|
+
}
|
|
225
|
+
reviewHandoff = { comment: {
|
|
226
|
+
id: text(comment.id, 'reviewHandoff.comment.id'),
|
|
227
|
+
author,
|
|
228
|
+
submittedAuthor,
|
|
229
|
+
text: commentText,
|
|
230
|
+
} };
|
|
231
|
+
}
|
|
206
232
|
return {
|
|
207
233
|
...status,
|
|
208
234
|
...(source.workflowAssignment === undefined
|
|
209
235
|
? {}
|
|
210
236
|
: { workflowAssignment: normalizeWorkflowAssignmentSyncRecord(source.workflowAssignment) }),
|
|
237
|
+
...(reviewHandoff ? { reviewHandoff } : {}),
|
|
211
238
|
...(originActor ? { originActor } : {}),
|
|
239
|
+
...(typeof source.expectedDetailRevision === 'string' && source.expectedDetailRevision.trim()
|
|
240
|
+
? { expectedDetailRevision: source.expectedDetailRevision.trim() }
|
|
241
|
+
: {}),
|
|
212
242
|
};
|
|
213
243
|
}
|
|
@@ -31,7 +31,7 @@ export class WorkspaceSyncJournalReader {
|
|
|
31
31
|
CAST(lifecycle_revision AS TEXT) AS lifecycle_revision, content_sha256,
|
|
32
32
|
CAST(size_bytes AS TEXT) AS size_bytes, payload_json, occurred_at FROM workspace_sync_journal
|
|
33
33
|
WHERE tenant_id = ? AND workspace_id = ? AND sequence > ? AND sequence <= ?
|
|
34
|
-
ORDER BY sequence ASC LIMIT ?`).all(input.tenantId, input.workspaceId, sequence(input.afterSequence), sequence(input.throughSequence), Math.max(1, Math.min(10_101, Math.floor(input.limit))));
|
|
34
|
+
ORDER BY workspace_sync_journal.sequence ASC LIMIT ?`).all(input.tenantId, input.workspaceId, sequence(input.afterSequence), sequence(input.throughSequence), Math.max(1, Math.min(10_101, Math.floor(input.limit))));
|
|
35
35
|
return rows.map((row) => ({
|
|
36
36
|
sequence: sequence(row.sequence), contractVersion: Number(row.contract_version), clientId: String(row.client_id || ''),
|
|
37
37
|
operationId: String(row.operation_id || ''), domain: String(row.domain || ''),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from '../../storage/databaseAdapter.js';
|
|
2
|
+
export declare const WORKSPACE_SYNC_OPERATION_RETENTION_DAYS = 90;
|
|
3
|
+
export declare const WORKSPACE_SYNC_OPERATION_RETENTION_INTERVAL_MS: number;
|
|
4
|
+
export declare const WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE = 100;
|
|
5
|
+
export declare const WORKSPACE_SYNC_OPERATION_RETENTION_WORKSPACE_LIMIT = 100;
|
|
6
|
+
export interface WorkspaceSyncOperationRetentionResult {
|
|
7
|
+
deletedOutbox: number;
|
|
8
|
+
deletedResults: number;
|
|
9
|
+
remainingEligible: number;
|
|
10
|
+
workspacesProcessed: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function pruneRetainedWorkspaceSyncOperations(input: {
|
|
13
|
+
db: DatabaseAdapter;
|
|
14
|
+
tenantId: string;
|
|
15
|
+
now?: Date;
|
|
16
|
+
}): WorkspaceSyncOperationRetentionResult;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
|
|
2
|
+
export const WORKSPACE_SYNC_OPERATION_RETENTION_DAYS = 90;
|
|
3
|
+
export const WORKSPACE_SYNC_OPERATION_RETENTION_INTERVAL_MS = 24 * 60 * 60_000;
|
|
4
|
+
export const WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE = 100;
|
|
5
|
+
export const WORKSPACE_SYNC_OPERATION_RETENTION_WORKSPACE_LIMIT = 100;
|
|
6
|
+
export function pruneRetainedWorkspaceSyncOperations(input) {
|
|
7
|
+
const now = input.now || new Date();
|
|
8
|
+
const cutoff = new Date(now.getTime() - WORKSPACE_SYNC_OPERATION_RETENTION_DAYS * 24 * 60 * 60_000).toISOString();
|
|
9
|
+
const workspaceRows = input.db.prepare(`
|
|
10
|
+
SELECT eligible.workspace_id
|
|
11
|
+
FROM (
|
|
12
|
+
SELECT candidate.workspace_id, candidate.updated_at AS terminal_at
|
|
13
|
+
FROM workspace_sync_outbox AS candidate
|
|
14
|
+
WHERE candidate.tenant_id = ?
|
|
15
|
+
AND candidate.status IN ('accepted', 'superseded')
|
|
16
|
+
AND candidate.updated_at < ?
|
|
17
|
+
AND NOT EXISTS (
|
|
18
|
+
SELECT 1
|
|
19
|
+
FROM workspace_sync_outbox AS replay
|
|
20
|
+
WHERE replay.tenant_id = candidate.tenant_id
|
|
21
|
+
AND replay.workspace_id = candidate.workspace_id
|
|
22
|
+
AND replay.replay_of_client_id = candidate.client_id
|
|
23
|
+
AND replay.replay_of_operation_id = candidate.operation_id
|
|
24
|
+
)
|
|
25
|
+
UNION ALL
|
|
26
|
+
SELECT workspace_id, updated_at AS terminal_at
|
|
27
|
+
FROM workspace_sync_operation_results
|
|
28
|
+
WHERE tenant_id = ? AND status = 'committed' AND updated_at < ?
|
|
29
|
+
) AS eligible
|
|
30
|
+
GROUP BY eligible.workspace_id
|
|
31
|
+
ORDER BY MIN(eligible.terminal_at), eligible.workspace_id
|
|
32
|
+
LIMIT ?
|
|
33
|
+
`).all(input.tenantId, cutoff, input.tenantId, cutoff, WORKSPACE_SYNC_OPERATION_RETENTION_WORKSPACE_LIMIT);
|
|
34
|
+
const store = new WorkspaceSyncDurabilityStore(input.db);
|
|
35
|
+
let deletedOutbox = 0;
|
|
36
|
+
let deletedResults = 0;
|
|
37
|
+
for (const row of workspaceRows) {
|
|
38
|
+
const workspaceId = String(row.workspace_id || '').trim();
|
|
39
|
+
if (!workspaceId)
|
|
40
|
+
continue;
|
|
41
|
+
const outboxResult = store.pruneTerminalOutboxOperations({
|
|
42
|
+
tenantId: input.tenantId,
|
|
43
|
+
workspaceId,
|
|
44
|
+
terminalBefore: cutoff,
|
|
45
|
+
limit: WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE,
|
|
46
|
+
});
|
|
47
|
+
deletedOutbox += outboxResult.deleted;
|
|
48
|
+
const result = store.pruneCommittedOperationResults({
|
|
49
|
+
tenantId: input.tenantId,
|
|
50
|
+
workspaceId,
|
|
51
|
+
terminalBefore: cutoff,
|
|
52
|
+
limit: WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE,
|
|
53
|
+
});
|
|
54
|
+
deletedResults += result.deleted;
|
|
55
|
+
}
|
|
56
|
+
const remaining = input.db.prepare(`
|
|
57
|
+
SELECT (
|
|
58
|
+
SELECT COUNT(*)
|
|
59
|
+
FROM workspace_sync_outbox AS candidate
|
|
60
|
+
WHERE candidate.tenant_id = ?
|
|
61
|
+
AND candidate.status IN ('accepted', 'superseded')
|
|
62
|
+
AND candidate.updated_at < ?
|
|
63
|
+
AND NOT EXISTS (
|
|
64
|
+
SELECT 1
|
|
65
|
+
FROM workspace_sync_outbox AS replay
|
|
66
|
+
WHERE replay.tenant_id = candidate.tenant_id
|
|
67
|
+
AND replay.workspace_id = candidate.workspace_id
|
|
68
|
+
AND replay.replay_of_client_id = candidate.client_id
|
|
69
|
+
AND replay.replay_of_operation_id = candidate.operation_id
|
|
70
|
+
)
|
|
71
|
+
) + (
|
|
72
|
+
SELECT COUNT(*)
|
|
73
|
+
FROM workspace_sync_operation_results
|
|
74
|
+
WHERE tenant_id = ? AND status = 'committed' AND updated_at < ?
|
|
75
|
+
) AS count
|
|
76
|
+
`).get(input.tenantId, cutoff, input.tenantId, cutoff);
|
|
77
|
+
return {
|
|
78
|
+
deletedOutbox,
|
|
79
|
+
deletedResults,
|
|
80
|
+
remainingEligible: Number(remaining?.count || 0),
|
|
81
|
+
workspacesProcessed: workspaceRows.length,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { WorkspaceSyncIncomingTaskApplyModel } from '../syncApplyHandlers.js';
|
|
2
2
|
import type { WorkspaceSyncChange } from '../workspaceSyncModel.js';
|
|
3
|
-
export declare const WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS: readonly ["task/root-v1", "task-relationship/full-v1", "taxonomy/full-v1", "initiative/full-v1", "workstream/full-v1", "task-comments/full-v1", "task-checklist/full-v1", "task-attachment-links/full-v1", "entity-event/full-v1", "workstream-task-order/full-v1"];
|
|
3
|
+
export declare const WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS: readonly ["task/root-v1", "task-relationship/full-v1", "taxonomy/full-v1", "initiative/full-v1", "workstream/full-v1", "task-comments/full-v1", "task-checklist/full-v1", "task-attachment-links/full-v1", "task-attachment-links/full-v2", "entity-event/full-v1", "workstream-task-order/full-v1"];
|
|
4
4
|
export type WorkspaceSyncV2ProjectionExclusion = typeof WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS[number];
|
|
5
5
|
export declare const WORKSPACE_SYNC_V3_COMBINED_V2_EXCLUSIONS: readonly WorkspaceSyncV2ProjectionExclusion[];
|
|
6
6
|
export declare function normalizeWorkspaceSyncV2ProjectionExclusions(values: Iterable<unknown> | null | undefined): WorkspaceSyncV2ProjectionExclusion[];
|
|
@@ -8,6 +8,7 @@ export const WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS = Object.freeze([
|
|
|
8
8
|
'task-comments/full-v1',
|
|
9
9
|
'task-checklist/full-v1',
|
|
10
10
|
'task-attachment-links/full-v1',
|
|
11
|
+
'task-attachment-links/full-v2',
|
|
11
12
|
'entity-event/full-v1',
|
|
12
13
|
'workstream-task-order/full-v1',
|
|
13
14
|
]);
|
|
@@ -49,7 +50,9 @@ export function prepareWorkspaceSyncV2TaskCarriers(taskMutations, excludedProjec
|
|
|
49
50
|
return taskMutations;
|
|
50
51
|
const commentsOwned = excludedProjections.has('task-comments/full-v1');
|
|
51
52
|
const checklistOwned = excludedProjections.has('task-checklist/full-v1');
|
|
52
|
-
const
|
|
53
|
+
const cardCoverOwned = excludedProjections.has('task-attachment-links/full-v2');
|
|
54
|
+
const attachmentsOwned = excludedProjections.has('task-attachment-links/full-v1')
|
|
55
|
+
|| cardCoverOwned;
|
|
53
56
|
return {
|
|
54
57
|
upserts: taskMutations.upserts.map(({ archived, task }) => {
|
|
55
58
|
const existing = readExistingTask?.(String(task.id || '').trim());
|
|
@@ -63,6 +66,7 @@ export function prepareWorkspaceSyncV2TaskCarriers(taskMutations, excludedProjec
|
|
|
63
66
|
...(commentsOwned ? { comments: existing.comments || [] } : {}),
|
|
64
67
|
...(checklistOwned ? { checklistItems: existing.checklistItems || [] } : {}),
|
|
65
68
|
...(attachmentsOwned ? { attachments: existing.attachments || [] } : {}),
|
|
69
|
+
...(cardCoverOwned ? { cardCoverAssetId: existing.cardCoverAssetId ?? null } : {}),
|
|
66
70
|
},
|
|
67
71
|
};
|
|
68
72
|
}),
|
|
@@ -100,7 +104,10 @@ export function partitionWorkspaceSyncV2LegacyChanges(changes, excludedProjectio
|
|
|
100
104
|
if (change.op === 'upsert') {
|
|
101
105
|
const commentsOwned = excludedProjections.has('task-comments/full-v1');
|
|
102
106
|
const checklistOwned = excludedProjections.has('task-checklist/full-v1');
|
|
103
|
-
const
|
|
107
|
+
const attachmentProjection = excludedProjections.has('task-attachment-links/full-v2')
|
|
108
|
+
? 'task-attachment-links/full-v2'
|
|
109
|
+
: 'task-attachment-links/full-v1';
|
|
110
|
+
const attachmentsOwned = excludedProjections.has(attachmentProjection);
|
|
104
111
|
if (excludedProjections.has('task/root-v1'))
|
|
105
112
|
suppress('task/root-v1');
|
|
106
113
|
if (commentsOwned || checklistOwned || attachmentsOwned) {
|
|
@@ -115,7 +122,10 @@ export function partitionWorkspaceSyncV2LegacyChanges(changes, excludedProjectio
|
|
|
115
122
|
}
|
|
116
123
|
if (attachmentsOwned) {
|
|
117
124
|
delete task.attachments;
|
|
118
|
-
|
|
125
|
+
if (attachmentProjection === 'task-attachment-links/full-v2') {
|
|
126
|
+
delete task.cardCoverAssetId;
|
|
127
|
+
}
|
|
128
|
+
suppress(attachmentProjection);
|
|
119
129
|
}
|
|
120
130
|
accepted.push({ ...change, task });
|
|
121
131
|
continue;
|
|
@@ -15,10 +15,13 @@ export interface WorkspaceSyncV3AttachmentApplyObligation {
|
|
|
15
15
|
createdAt: string;
|
|
16
16
|
updatedAt: string;
|
|
17
17
|
nextAttemptAt: string;
|
|
18
|
+
terminalAt: string | null;
|
|
19
|
+
terminalReason: string | null;
|
|
18
20
|
resolvedAt: string | null;
|
|
19
21
|
}
|
|
20
22
|
export interface WorkspaceSyncV3AttachmentApplyObligationSummary {
|
|
21
23
|
open: number;
|
|
24
|
+
terminal: number;
|
|
22
25
|
due: number;
|
|
23
26
|
oldestOpenCreatedAt: string | null;
|
|
24
27
|
nextAttemptAt: string | null;
|
|
@@ -70,6 +73,14 @@ export declare class WorkspaceSyncV3AttachmentApplyObligationStore {
|
|
|
70
73
|
taskId: string;
|
|
71
74
|
now: string;
|
|
72
75
|
}): void;
|
|
76
|
+
markTerminalUnavailable(input: {
|
|
77
|
+
tenantId: string;
|
|
78
|
+
workspaceId: string;
|
|
79
|
+
taskId: string;
|
|
80
|
+
canonicalFingerprint: string;
|
|
81
|
+
reason: string;
|
|
82
|
+
now: string;
|
|
83
|
+
}): void;
|
|
73
84
|
recordAttemptFailure(input: {
|
|
74
85
|
tenantId: string;
|
|
75
86
|
workspaceId: string;
|