@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
|
@@ -4,6 +4,7 @@ import { resolveWorkspacePullRequestPlan, resolveWorkspacePullSuccessPlan } from
|
|
|
4
4
|
import { runWorkspaceSyncV3InitiativeProjectionCycle } from '../v3/workspaceSyncV3FeedOrchestrator.js';
|
|
5
5
|
import { runWorkspaceSyncV3CombinedProjectionCycle } from '../v3/workspaceSyncV3CombinedFeedOrchestrator.js';
|
|
6
6
|
import { hydrateWorkspaceSyncV3AttachmentAsset } from '../v3/workspaceSyncV3AttachmentAssetHydration.js';
|
|
7
|
+
import { authoritativeV2ApplyFailureMessage, } from './workspaceSyncEngineLocalServices.js';
|
|
7
8
|
import { WORKSPACE_SYNC_V3_APPLY_NOT_COMMITTED } from './workspaceSyncEngineRemoteServices.js';
|
|
8
9
|
export function combinedAttachmentAssetHydrationId(input) {
|
|
9
10
|
if (input.causeCode === 'TASK_ATTACHMENT_ASSET_NOT_READY' && input.causeAssetId) {
|
|
@@ -172,7 +173,7 @@ export function createWorkspaceSyncV3TransferBindings(input) {
|
|
|
172
173
|
};
|
|
173
174
|
}
|
|
174
175
|
export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtimeMode, initiativeFeedActivationEnabled, combinedFeedActivationEnabled, combinedFeedCoverage, workspaceCloudSyncEnabled, currentWorkspaceId, workspaceSyncPhase, isAuthenticated, checkAuthSession, resolveCloudAuthUrl, ensureCloudWorkspaceReadyForSync, ensureWorkspaceSyncReady, handleSyncAuthFailure, clearWorkspaceRetry, clearWorkspaceIssue, isWorkspaceRetryPending, isDurableRecoveryBlockingOrdinaryPush, isExecutionAuthorized = () => true, scheduleWorkspaceSyncRetry, persistWorkspaceSyncPatchSafely, persistWorkspaceSyncPatchBestEffort, persistWorkspaceSyncWatermarksSnapshotBestEffort, refreshWorkspaceAiProfilePushBaselineFromPersistence, reportSyncEvent, acquireWorkspaceSyncLease, releaseWorkspaceSyncLease, recordWorkspaceSyncCompletion, reportWorkspaceWindowContention, refreshWorkspaceSyncMarkdownDocumentsSnapshot, refreshWorkspaceSyncAiProfilesSnapshot, refreshWorkspaceSyncAssetsSnapshot, refreshWorkspaceSyncTaxonomySnapshot, refreshWorkspaceSyncPlanningEntitiesSnapshot, refreshWorkspaceSyncDocumentReviewSessionsSnapshot, refreshWorkspaceSyncAnnotatedAttachmentSessionsSnapshot, refreshWorkspaceSyncTaskforceAgentsSnapshot, refreshLocalWorkspaceTaskCollections, buildWorkspaceSyncPayload, buildWorkspaceSyncSignature, seedWorkspaceSnapshotPushBaseline, shouldSuppressAttachBootstrapPush, recordSuppressedEventIds, runtime, localServices, remoteServices, setWorkspaceSyncBusy, setUserGlobalSyncStatus, setUserGlobalSyncError, setWorkspaceLastErrorMessage, setWorkspaceLastErrorAt, setWorkspaceLastPullAt, setWorkspaceLastPushAt, setWorkspaceSyncPendingChanges, setTasks, setArchivedTasks, now, scheduleTask, logDebug = () => undefined, notifyAiProfilesMutated = () => undefined, notifyAgentsMutated = () => undefined, notifyAgentSkillsMutated = () => undefined }) {
|
|
175
|
-
const { repairMode: workspaceRepairModeRef, forceFullAiProfilePush: workspaceForceFullAiProfilePushRef, pushInFlight: workspacePushInFlightRef, pullInFlight: workspacePullInFlightRef, pullAfterPushRequested: workspacePullAfterPushRequestedRef, pendingPushReplay: workspacePendingPushReplayRef, blockedPushSignature: workspaceBlockedPushSignatureRef, lastPushedSignature: workspaceLastPushedSignatureRef, pendingSignature: workspacePendingSignatureRef, lastPushedTaskIds: workspaceLastPushedTaskIdsRef, deletedTaskIds: workspaceDeletedTaskIdsRef, deletedTaskWatermarks: workspaceDeletedTaskWatermarksRef, pullCursor: workspacePullCursorRef, lastPushedWatermarks: workspaceLastPushedWatermarksRef, lastPushedTaskChangeKeys: workspaceLastPushedTaskChangeKeysRef, lastPushedTaskRelationshipChangeKeys: workspaceLastPushedTaskRelationshipChangeKeysRef, lastPushedTaxonomyChangeKey: workspaceLastPushedTaxonomyChangeKeyRef, lastPushedInitiativeIds: workspaceLastPushedInitiativeIdsRef, lastPushedInitiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef, lastPushedWorkstreamIds: workspaceLastPushedWorkstreamIdsRef, lastPushedWorkstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef, lastPushedAiProfileIds: workspaceLastPushedAiProfileIdsRef, lastPushedAiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef, lastPushedAiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef, lastPushedDocumentPaths: workspaceLastPushedDocumentPathsRef, lastPushedDocumentWatermarks: workspaceLastPushedDocumentWatermarksRef, lastPushedAssetPaths: workspaceLastPushedAssetPathsRef, lastPushedAssetWatermarks: workspaceLastPushedAssetWatermarksRef, lastPushedDocumentReviewSessionIds: workspaceLastPushedDocumentReviewSessionIdsRef, lastPushedDocumentReviewSessionWatermarks: workspaceLastPushedDocumentReviewSessionWatermarksRef, lastPushedDocumentReviewCommentIds: workspaceLastPushedDocumentReviewCommentIdsRef, lastPushedDocumentReviewCommentWatermarks: workspaceLastPushedDocumentReviewCommentWatermarksRef, lastPushedAnnotatedAttachmentSessionIds: workspaceLastPushedAnnotatedAttachmentSessionIdsRef, lastPushedAnnotatedAttachmentSessionWatermarks: workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, lastPushedTaskforceAgentIds: workspaceLastPushedTaskforceAgentIdsRef, lastPushedTaskforceAgentWatermarks: workspaceLastPushedTaskforceAgentWatermarksRef, lastPushedTaskforceAgentSkillIds: workspaceLastPushedTaskforceAgentSkillIdsRef, lastPushedTaskforceAgentSkillWatermarks: workspaceLastPushedTaskforceAgentSkillWatermarksRef, lastPushedAgentConversationIds: workspaceLastPushedAgentConversationIdsRef, lastPushedAgentConversationWatermarks: workspaceLastPushedAgentConversationWatermarksRef, lastPushedTaskEventWatermarks: workspaceLastPushedTaskEventWatermarksRef, baselineResetReason: workspaceBaselineResetReasonRef, captureAttachBootstrapBaseline: workspaceCaptureAttachBootstrapBaselineRef, startupFullReconcileRan: workspaceStartupFullReconcileRanRef, startupFullReconcileRequested: workspaceStartupFullReconcileRequestedRef, fullReconcileInFlight: workspaceFullReconcileInFlightRef, bootstrapLastProgressAtMs: bootstrapLastProgressAtRef, realtimeSuppressedEventQueue: realtimeSuppressedEventQueueRef, } = runtime;
|
|
176
|
+
const { repairMode: workspaceRepairModeRef, forceFullAiProfilePush: workspaceForceFullAiProfilePushRef, pushInFlight: workspacePushInFlightRef, pullInFlight: workspacePullInFlightRef, pullAfterPushRequested: workspacePullAfterPushRequestedRef, pendingPushReplay: workspacePendingPushReplayRef, blockedPushSignature: workspaceBlockedPushSignatureRef, lastPushedSignature: workspaceLastPushedSignatureRef, pendingSignature: workspacePendingSignatureRef, lastPushedTaskIds: workspaceLastPushedTaskIdsRef, deletedTaskIds: workspaceDeletedTaskIdsRef, deletedTaskWatermarks: workspaceDeletedTaskWatermarksRef, pullCursor: workspacePullCursorRef, lastPushedWatermarks: workspaceLastPushedWatermarksRef, lastPushedTaskChangeKeys: workspaceLastPushedTaskChangeKeysRef, lastPushedTaskRelationshipChangeKeys: workspaceLastPushedTaskRelationshipChangeKeysRef, lastPushedTaxonomyChangeKey: workspaceLastPushedTaxonomyChangeKeyRef, lastPushedInitiativeIds: workspaceLastPushedInitiativeIdsRef, lastPushedInitiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef, lastPushedWorkstreamIds: workspaceLastPushedWorkstreamIdsRef, lastPushedWorkstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef, lastPushedPlanningIdentityWatermarks: workspaceLastPushedPlanningIdentityWatermarksRef, lastPushedAiProfileIds: workspaceLastPushedAiProfileIdsRef, lastPushedAiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef, lastPushedAiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef, lastPushedDocumentPaths: workspaceLastPushedDocumentPathsRef, lastPushedDocumentWatermarks: workspaceLastPushedDocumentWatermarksRef, lastPushedAssetPaths: workspaceLastPushedAssetPathsRef, lastPushedAssetWatermarks: workspaceLastPushedAssetWatermarksRef, lastPushedDocumentReviewSessionIds: workspaceLastPushedDocumentReviewSessionIdsRef, lastPushedDocumentReviewSessionWatermarks: workspaceLastPushedDocumentReviewSessionWatermarksRef, lastPushedDocumentReviewCommentIds: workspaceLastPushedDocumentReviewCommentIdsRef, lastPushedDocumentReviewCommentWatermarks: workspaceLastPushedDocumentReviewCommentWatermarksRef, lastPushedAnnotatedAttachmentSessionIds: workspaceLastPushedAnnotatedAttachmentSessionIdsRef, lastPushedAnnotatedAttachmentSessionWatermarks: workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, lastPushedTaskforceAgentIds: workspaceLastPushedTaskforceAgentIdsRef, lastPushedTaskforceAgentWatermarks: workspaceLastPushedTaskforceAgentWatermarksRef, lastPushedTaskforceAgentSkillIds: workspaceLastPushedTaskforceAgentSkillIdsRef, lastPushedTaskforceAgentSkillWatermarks: workspaceLastPushedTaskforceAgentSkillWatermarksRef, lastPushedAgentConversationIds: workspaceLastPushedAgentConversationIdsRef, lastPushedAgentConversationWatermarks: workspaceLastPushedAgentConversationWatermarksRef, lastPushedTaskEventWatermarks: workspaceLastPushedTaskEventWatermarksRef, baselineResetReason: workspaceBaselineResetReasonRef, captureAttachBootstrapBaseline: workspaceCaptureAttachBootstrapBaselineRef, startupFullReconcileRan: workspaceStartupFullReconcileRanRef, startupFullReconcileRequested: workspaceStartupFullReconcileRequestedRef, fullReconcileInFlight: workspaceFullReconcileInFlightRef, bootstrapLastProgressAtMs: bootstrapLastProgressAtRef, realtimeSuppressedEventQueue: realtimeSuppressedEventQueueRef, } = runtime;
|
|
176
177
|
const scheduledTasks = new Map();
|
|
177
178
|
let disposed = false;
|
|
178
179
|
const scheduleCoordinatorTask = (key, callback, delayMs) => {
|
|
@@ -391,6 +392,10 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
|
|
|
391
392
|
}
|
|
392
393
|
let applyResult;
|
|
393
394
|
try {
|
|
395
|
+
const applyOptions = {
|
|
396
|
+
repairMode: replayPayload?.repairMode ?? repairMode,
|
|
397
|
+
excludedProjections: pushResult.effectiveV2ExcludedProjections,
|
|
398
|
+
};
|
|
394
399
|
const authoritativeChanges = appliedTaskUpserts.map((entry) => ({
|
|
395
400
|
op: 'upsert',
|
|
396
401
|
archived: entry.archived === true,
|
|
@@ -398,8 +403,8 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
|
|
|
398
403
|
...(entry.durableRevision ? { durableRevision: entry.durableRevision } : {}),
|
|
399
404
|
}));
|
|
400
405
|
applyResult = completionGroup
|
|
401
|
-
? await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges, { completionGroup })
|
|
402
|
-
: await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges);
|
|
406
|
+
? await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges, { ...applyOptions, completionGroup })
|
|
407
|
+
: await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges, applyOptions);
|
|
403
408
|
}
|
|
404
409
|
catch (error) {
|
|
405
410
|
if (pushTransferReceipts.length > 0) {
|
|
@@ -419,7 +424,7 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
|
|
|
419
424
|
errorCode: 'WORKSPACE_SYNC_V2_PUSH_AUTHORITATIVE_APPLY_FAILED',
|
|
420
425
|
});
|
|
421
426
|
}
|
|
422
|
-
throw new Error(
|
|
427
|
+
throw new Error(authoritativeV2ApplyFailureMessage(applyResult));
|
|
423
428
|
}
|
|
424
429
|
for (const entry of appliedTaskUpserts) {
|
|
425
430
|
const taskId = String(entry.task.id || '').trim();
|
|
@@ -462,6 +467,8 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
|
|
|
462
467
|
workspaceLastPushedInitiativeWatermarksRef.current = new Map(pushResult.currentInitiativeWatermarks);
|
|
463
468
|
workspaceLastPushedWorkstreamIdsRef.current = new Set(pushResult.currentWorkstreamIds);
|
|
464
469
|
workspaceLastPushedWorkstreamWatermarksRef.current = new Map(pushResult.currentWorkstreamWatermarks);
|
|
470
|
+
workspaceLastPushedPlanningIdentityWatermarksRef.current = new Map(pushResult.currentPlanningIdentityWatermarks
|
|
471
|
+
|| payload.currentPlanningIdentityWatermarks);
|
|
465
472
|
workspaceLastPushedAiProfileIdsRef.current = new Set(pushResult.currentAiProfileIds);
|
|
466
473
|
workspaceLastPushedAiProfileWatermarksRef.current = new Map(pushResult.currentAiProfileWatermarks);
|
|
467
474
|
workspaceLastPushedAiProfileChangeKeysRef.current = pushResult.currentAiProfileChangeKeys
|
|
@@ -12,6 +12,7 @@ type SyncCore = TaskforceCore & TaskforceSyncCapable;
|
|
|
12
12
|
type ContentSyncState = ReturnType<typeof createContentSyncState>;
|
|
13
13
|
export interface WorkspaceSyncV2DispatchOptions {
|
|
14
14
|
allowReferenceNumberReassignment?: boolean;
|
|
15
|
+
actorUserId?: string;
|
|
15
16
|
workspaceMembers?: WorkspaceSyncWorkspaceMemberSnapshot[];
|
|
16
17
|
coexistenceDirection?: TaskMetadataCoexistenceDirection;
|
|
17
18
|
assertedActiveV3TaskMetadataIds?: ReadonlySet<string>;
|
|
@@ -7,6 +7,7 @@ import { WorkspaceSyncDurabilityStore } from '../v3/syncDurabilityStore.js';
|
|
|
7
7
|
import { assertWorkspaceSyncV2TaskCarrierRootsExist, prepareWorkspaceSyncV2TaskCarriers, } from '../v3/workspaceSyncV2ProjectionExclusions.js';
|
|
8
8
|
import { resolveV3OwnedTaskDeleteIds, resolveV3OwnedTaskLifecycleIds, resolveV3OwnedTaskMetadataIds, resolveV3OwnedTaskReopenAssigneeIds, resolveV3OwnedTaskTaxonomyIds, } from '../v3/taskMetadataCoexistence.js';
|
|
9
9
|
import { assertWorkspaceSyncV2MetadataOnlyApplyPreflight, } from './workspaceSyncEngineLocalApply.js';
|
|
10
|
+
import { assertTaskforceAgentSyncPushAccess } from '../taskforceAgentSyncAuthorization.js';
|
|
10
11
|
function createSyncRouteError(message, details, options) {
|
|
11
12
|
const error = new Error(message);
|
|
12
13
|
error.code = options?.code || 'SYNC_APPLY_FAILED';
|
|
@@ -132,6 +133,14 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
|
|
|
132
133
|
normalizeTaskEventSyncPayload,
|
|
133
134
|
recordSyncDiagnostic,
|
|
134
135
|
});
|
|
136
|
+
if (options.coexistenceDirection === 'cloud-push') {
|
|
137
|
+
assertTaskforceAgentSyncPushAccess({
|
|
138
|
+
agents: applyModel.collaboration.incomingTaskforceAgents.values(),
|
|
139
|
+
actorUserId: String(options.actorUserId || '').trim() || null,
|
|
140
|
+
hasUserFeatureGrant: (userId, featureKey) => core.hasUserFeatureGrant(userId, featureKey),
|
|
141
|
+
createSyncRouteError,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
135
144
|
if (metadataOnly) {
|
|
136
145
|
assertWorkspaceSyncV2MetadataOnlyApplyPreflight(incomingChanges);
|
|
137
146
|
}
|
|
@@ -304,6 +313,10 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
|
|
|
304
313
|
incomingAgentRoles: applyModel.collaboration.incomingAgentRoles,
|
|
305
314
|
incomingTaskforceAgentSkills: applyModel.collaboration.incomingTaskforceAgentSkills,
|
|
306
315
|
incomingAgentConversations: applyModel.collaboration.incomingAgentConversations,
|
|
316
|
+
...(options.coexistenceDirection === 'cloud-push' ? {
|
|
317
|
+
taskforceAgentPushActorUserId: String(options.actorUserId || '').trim() || null,
|
|
318
|
+
taskforceAgentPushAccessPreflighted: true,
|
|
319
|
+
} : {}),
|
|
307
320
|
recordSyncDiagnostic,
|
|
308
321
|
createSyncRouteError,
|
|
309
322
|
});
|
|
@@ -633,6 +646,18 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
|
|
|
633
646
|
sourceUpdatedAt: intent.sourceUpdatedAt,
|
|
634
647
|
publishedAt: now().toISOString(),
|
|
635
648
|
deletedAt: intent.sourceUpdatedAt,
|
|
649
|
+
// This dispatch path only ever runs from an explicit document-delete/
|
|
650
|
+
// asset-delete WorkspaceSyncChange (see workspaceSyncV2PreparedContent.ts)
|
|
651
|
+
// — never from workspace repair, which is intentionally routed to a
|
|
652
|
+
// durable retry obligation instead (see workspaceRepair.ts) rather than
|
|
653
|
+
// ever reaching this admission boundary. operationId/actorId are not yet
|
|
654
|
+
// threaded through the WorkspaceSyncChange wire format from origin to this
|
|
655
|
+
// layer — see the type's doc comment.
|
|
656
|
+
provenance: {
|
|
657
|
+
source: 'explicit-delete',
|
|
658
|
+
sourceRuntime: 'server',
|
|
659
|
+
repairInvolved: false,
|
|
660
|
+
},
|
|
636
661
|
});
|
|
637
662
|
if (tombstone.versionId !== null
|
|
638
663
|
|| tombstone.sourceUpdatedAt !== intent.sourceUpdatedAt
|
|
@@ -748,6 +773,10 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
|
|
|
748
773
|
incomingAgentRoles: applyModel.collaboration.incomingAgentRoles,
|
|
749
774
|
incomingTaskforceAgentSkills: applyModel.collaboration.incomingTaskforceAgentSkills,
|
|
750
775
|
incomingAgentConversations: applyModel.collaboration.incomingAgentConversations,
|
|
776
|
+
...(options.coexistenceDirection === 'cloud-push' ? {
|
|
777
|
+
taskforceAgentPushActorUserId: String(options.actorUserId || '').trim() || null,
|
|
778
|
+
taskforceAgentPushAccessPreflighted: true,
|
|
779
|
+
} : {}),
|
|
751
780
|
recordSyncDiagnostic,
|
|
752
781
|
createSyncRouteError,
|
|
753
782
|
});
|
|
@@ -255,6 +255,8 @@ export declare function applyCollaborationSyncChanges(input: {
|
|
|
255
255
|
incomingAgentRoles?: Map<string, WorkspaceSyncAgentRoleSnapshot>;
|
|
256
256
|
incomingTaskforceAgentSkills?: Map<string, WorkspaceSyncTaskforceAgentSkillSnapshot>;
|
|
257
257
|
incomingAgentConversations?: Map<string, WorkspaceSyncAgentConversationSnapshot>;
|
|
258
|
+
taskforceAgentPushActorUserId?: string | null;
|
|
259
|
+
taskforceAgentPushAccessPreflighted?: boolean;
|
|
258
260
|
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
259
261
|
createSyncRouteError: CreateSyncRouteError;
|
|
260
262
|
}): void;
|
|
@@ -18,6 +18,7 @@ import { TaskforceAgentStore } from '../storage/taskforceAgentStore.js';
|
|
|
18
18
|
import { TaskforceAgentSkillStore } from '../storage/taskforceAgentSkillStore.js';
|
|
19
19
|
import { TaskforceAgentConversationStore } from '../storage/taskforceAgentConversationStore.js';
|
|
20
20
|
import { AgentRoleStore } from '../storage/agentRoleStore.js';
|
|
21
|
+
import { assertTaskforceAgentSyncPushAccess } from './taskforceAgentSyncAuthorization.js';
|
|
21
22
|
import { preserveV3OwnedTaskRoot, preserveV3OwnedTaskLifecycle, preserveV3OwnedTaskMetadata, preserveV3OwnedTaskReopenAssignee, preserveV3OwnedTaskTaxonomy, } from './v3/taskMetadataCoexistence.js';
|
|
22
23
|
function createIncomingApplyModel() {
|
|
23
24
|
return {
|
|
@@ -1052,7 +1053,15 @@ export async function applyContentSyncChanges(input) {
|
|
|
1052
1053
|
}
|
|
1053
1054
|
}
|
|
1054
1055
|
export function applyCollaborationSyncChanges(input) {
|
|
1055
|
-
const { core, workspaceId, incomingDocumentReviewSessions, incomingDocumentReviewSessionDeletes, incomingDocumentReviewComments, incomingDocumentReviewCommentDeletes, incomingAnnotatedAttachmentSessions, incomingAnnotatedAttachmentSessionDeletes, incomingTaskforceAgents = new Map(), incomingAgentRoles = new Map(), incomingTaskforceAgentSkills = new Map(), incomingAgentConversations = new Map(), recordSyncDiagnostic, createSyncRouteError, } = input;
|
|
1056
|
+
const { core, workspaceId, incomingDocumentReviewSessions, incomingDocumentReviewSessionDeletes, incomingDocumentReviewComments, incomingDocumentReviewCommentDeletes, incomingAnnotatedAttachmentSessions, incomingAnnotatedAttachmentSessionDeletes, incomingTaskforceAgents = new Map(), incomingAgentRoles = new Map(), incomingTaskforceAgentSkills = new Map(), incomingAgentConversations = new Map(), taskforceAgentPushActorUserId, taskforceAgentPushAccessPreflighted = false, recordSyncDiagnostic, createSyncRouteError, } = input;
|
|
1057
|
+
if (taskforceAgentPushActorUserId !== undefined && !taskforceAgentPushAccessPreflighted) {
|
|
1058
|
+
assertTaskforceAgentSyncPushAccess({
|
|
1059
|
+
agents: incomingTaskforceAgents.values(),
|
|
1060
|
+
actorUserId: taskforceAgentPushActorUserId,
|
|
1061
|
+
hasUserFeatureGrant: (userId, featureKey) => core.hasUserFeatureGrant(userId, featureKey),
|
|
1062
|
+
createSyncRouteError,
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1056
1065
|
if (incomingDocumentReviewSessions.size > 0) {
|
|
1057
1066
|
for (const session of incomingDocumentReviewSessions.values()) {
|
|
1058
1067
|
try {
|
|
@@ -52,6 +52,12 @@ export interface WorkspacePushSyncInput {
|
|
|
52
52
|
remoteServices?: WorkspaceSyncEngineRemoteServices;
|
|
53
53
|
localServices?: Pick<WorkspaceSyncEngineLocalServices, 'readPushOwnership'>;
|
|
54
54
|
acknowledgedNonApplyingBatchOperationIdentities?: readonly string[];
|
|
55
|
+
/**
|
|
56
|
+
* Server-owned pages whose remote receipt, authoritative task echo, and
|
|
57
|
+
* runner checkpoint contribution committed atomically. Browser callers
|
|
58
|
+
* must not use this recovery boundary.
|
|
59
|
+
*/
|
|
60
|
+
settledBatchOperationIdentities?: readonly string[];
|
|
55
61
|
preparedPlan?: WorkspacePushPreparedPlan | null;
|
|
56
62
|
onPreparedPlan?: (input: {
|
|
57
63
|
plan: WorkspacePushPreparedPlan;
|
|
@@ -62,6 +68,14 @@ export interface WorkspacePushSyncInput {
|
|
|
62
68
|
operationIdentity: string;
|
|
63
69
|
acknowledgedOperationIdentities: readonly string[];
|
|
64
70
|
}) => void | Promise<void>;
|
|
71
|
+
onAcceptedBatchSettled?: (input: {
|
|
72
|
+
operationIdentity: string;
|
|
73
|
+
settlementIdentityFingerprint: string;
|
|
74
|
+
appliedTaskUpserts: WorkspacePushSyncResult['appliedTaskUpserts'];
|
|
75
|
+
transferReceipt: WorkspaceSyncEngineRemoteTransferReceipt;
|
|
76
|
+
pushBoundary: WorkspaceSyncEngineV2PushBoundary;
|
|
77
|
+
excludedProjections?: readonly WorkspaceSyncV2ProjectionExclusion[];
|
|
78
|
+
}) => void | Promise<void>;
|
|
65
79
|
}
|
|
66
80
|
export interface WorkspacePushSyncResult {
|
|
67
81
|
success: boolean;
|
|
@@ -77,6 +91,8 @@ export interface WorkspacePushSyncResult {
|
|
|
77
91
|
effectiveDeltaDiagnostics?: WorkspaceSyncDeltaDiagnostics & {
|
|
78
92
|
combinedV3SuppressedChangeCount?: number;
|
|
79
93
|
};
|
|
94
|
+
/** Exact V3-owned projections excluded while preparing this V2 attempt. */
|
|
95
|
+
effectiveV2ExcludedProjections?: readonly WorkspaceSyncV2ProjectionExclusion[];
|
|
80
96
|
deleteCount: number;
|
|
81
97
|
currentTaskIds: Set<string>;
|
|
82
98
|
currentTaskWatermarks?: Map<string, string>;
|
|
@@ -88,6 +104,7 @@ export interface WorkspacePushSyncResult {
|
|
|
88
104
|
currentInitiativeWatermarks: Map<string, string>;
|
|
89
105
|
currentWorkstreamIds: Set<string>;
|
|
90
106
|
currentWorkstreamWatermarks: Map<string, string>;
|
|
107
|
+
currentPlanningIdentityWatermarks?: Map<string, string>;
|
|
91
108
|
currentAiProfileIds: Set<string>;
|
|
92
109
|
currentAiProfileWatermarks: Map<string, string>;
|
|
93
110
|
currentAiProfileChangeKeys?: Map<string, string>;
|
package/dist/sync/syncService.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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';
|
|
8
|
-
import { workspaceSyncV2ProjectionExclusionsEqual, } from './v3/workspaceSyncV2ProjectionExclusions.js';
|
|
8
|
+
import { normalizeWorkspaceSyncV2ProjectionExclusions, workspaceSyncV2ProjectionExclusionsEqual, } from './v3/workspaceSyncV2ProjectionExclusions.js';
|
|
9
9
|
import { WORKSPACE_PUSH_PREPARED_PLAN_VERSION, } from './workspacePushPreparedPlan.js';
|
|
10
10
|
import { canonicalWorkspaceSyncJson } from './v3/canonicalWorkspaceSyncJson.js';
|
|
11
11
|
function asObjectRecord(value) {
|
|
@@ -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(),
|
|
@@ -464,6 +470,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
464
470
|
}
|
|
465
471
|
const changeCount = preparedChanges.length;
|
|
466
472
|
const effectiveDeltaDiagnostics = buildEffectiveWorkspacePushDiagnostics(input.payload.deltaDiagnostics, preparedChanges, preparedOwnership);
|
|
473
|
+
const effectiveV2ExcludedProjections = normalizeWorkspaceSyncV2ProjectionExclusions(preparedOwnership.combinedExcludedProjections || []);
|
|
467
474
|
const deleteCount = input.payload.deleteTaskIds.size;
|
|
468
475
|
let requestMs = 0;
|
|
469
476
|
const canElideSteadyStateRequest = changeCount === 0
|
|
@@ -478,6 +485,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
478
485
|
requestMs: 0,
|
|
479
486
|
changeCount: 0,
|
|
480
487
|
effectiveDeltaDiagnostics,
|
|
488
|
+
effectiveV2ExcludedProjections,
|
|
481
489
|
deleteCount,
|
|
482
490
|
currentTaskIds: input.payload.currentTaskIds,
|
|
483
491
|
currentTaskWatermarks: input.payload.currentTaskWatermarks ?? new Map(),
|
|
@@ -489,6 +497,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
489
497
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
490
498
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
491
499
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
500
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
492
501
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
493
502
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
494
503
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -581,6 +590,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
581
590
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
582
591
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
583
592
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
593
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
584
594
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
585
595
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
586
596
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -668,8 +678,18 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
668
678
|
&& acknowledgedNonApplyingBatchOperationIdentities.size !== requestedAcknowledgements.length) {
|
|
669
679
|
throw new Error('Persisted V2 push batch acknowledgement state does not match the frozen push plan.');
|
|
670
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);
|
|
671
690
|
let completedBatchCount = 0;
|
|
672
691
|
let completedChangeCount = 0;
|
|
692
|
+
let firstPushFailure = null;
|
|
673
693
|
const pushTransferReceipts = [];
|
|
674
694
|
const abandonRetainedPushReceipts = async (errorCode) => {
|
|
675
695
|
if (pushTransferReceipts.length === 0)
|
|
@@ -687,7 +707,8 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
687
707
|
const safeBatchChanges = batch.map((entry) => entry.safe);
|
|
688
708
|
const expectedTaskEchoIds = workspaceSyncEngineExpectedTaskEchoIds(plainBatchChanges);
|
|
689
709
|
const idempotencyKey = batchOperationIdentities[batchIndex];
|
|
690
|
-
if (
|
|
710
|
+
if (settledBatchOperationIdentities.has(idempotencyKey)
|
|
711
|
+
|| acknowledgedNonApplyingBatchOperationIdentities.has(idempotencyKey)) {
|
|
691
712
|
completedBatchCount += 1;
|
|
692
713
|
completedChangeCount += plainBatchChanges.length;
|
|
693
714
|
continue;
|
|
@@ -730,7 +751,12 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
730
751
|
const data = asObjectRecord(pushResult.data);
|
|
731
752
|
const failedOperations = Array.from(new Set(plainBatchChanges.map((change) => change.op)));
|
|
732
753
|
const failedContentChanges = plainBatchChanges.filter(isWorkspacePushContentChange).length;
|
|
733
|
-
|
|
754
|
+
const failureDomain = failedContentChanges === plainBatchChanges.length
|
|
755
|
+
? 'content'
|
|
756
|
+
: failedContentChanges === 0
|
|
757
|
+
? 'metadata'
|
|
758
|
+
: 'mixed';
|
|
759
|
+
const failureResult = {
|
|
734
760
|
success: false,
|
|
735
761
|
status: pushResult.status,
|
|
736
762
|
error: typeof data.error === 'string' ? data.error : undefined,
|
|
@@ -742,11 +768,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
742
768
|
failedBatchIndex: batchIndex,
|
|
743
769
|
failedChangeCount: plainBatchChanges.length,
|
|
744
770
|
failedOperations,
|
|
745
|
-
failureDomain
|
|
746
|
-
? 'content'
|
|
747
|
-
: failedContentChanges === 0
|
|
748
|
-
? 'metadata'
|
|
749
|
-
: 'mixed',
|
|
771
|
+
failureDomain,
|
|
750
772
|
},
|
|
751
773
|
retryAfterMs: pushResult.retryAfterMs,
|
|
752
774
|
transient: pushInProgress || isTransientWorkspaceSyncStatus(pushResult.status),
|
|
@@ -763,6 +785,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
763
785
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
764
786
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
765
787
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
788
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
766
789
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
767
790
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
768
791
|
currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
|
|
@@ -791,8 +814,18 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
791
814
|
pushedWatermarks: new Map(),
|
|
792
815
|
pushedTaskChangeKeys: new Map(),
|
|
793
816
|
emittedEventIds: [],
|
|
794
|
-
appliedTaskUpserts: []
|
|
817
|
+
appliedTaskUpserts: [],
|
|
795
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;
|
|
796
829
|
}
|
|
797
830
|
const pushData = asObjectRecord(pushResult.data);
|
|
798
831
|
if (Array.isArray(pushData.emittedEventIds)) {
|
|
@@ -804,7 +837,29 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
804
837
|
}
|
|
805
838
|
const normalizedTaskUpserts = parseWorkspaceSyncEngineAppliedTaskUpserts(pushData, expectedTaskEchoIds);
|
|
806
839
|
appliedTaskUpserts.push(...normalizedTaskUpserts);
|
|
807
|
-
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) {
|
|
808
863
|
await remoteServices.acknowledgeNonApplyingTransferReceipts({
|
|
809
864
|
workspaceId: input.workspaceId,
|
|
810
865
|
receipts: [pushResult.transferReceipt],
|
|
@@ -826,6 +881,17 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
826
881
|
await abandonRetainedPushReceipts('WORKSPACE_SYNC_V2_PUSH_ATTEMPT_FAILED');
|
|
827
882
|
throw error;
|
|
828
883
|
}
|
|
884
|
+
if (firstPushFailure) {
|
|
885
|
+
return {
|
|
886
|
+
...firstPushFailure,
|
|
887
|
+
batchProgress: {
|
|
888
|
+
...firstPushFailure.batchProgress,
|
|
889
|
+
completedBatches: completedBatchCount,
|
|
890
|
+
completedChanges: completedChangeCount,
|
|
891
|
+
},
|
|
892
|
+
requestMs,
|
|
893
|
+
};
|
|
894
|
+
}
|
|
829
895
|
return {
|
|
830
896
|
success: true,
|
|
831
897
|
syncedAt: new Date().toISOString(),
|
|
@@ -841,6 +907,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
841
907
|
failureDomain: null,
|
|
842
908
|
},
|
|
843
909
|
effectiveDeltaDiagnostics,
|
|
910
|
+
effectiveV2ExcludedProjections,
|
|
844
911
|
deleteCount,
|
|
845
912
|
currentTaskIds: input.payload.currentTaskIds,
|
|
846
913
|
currentTaskWatermarks: input.payload.currentTaskWatermarks ?? new Map(),
|
|
@@ -852,6 +919,7 @@ export async function runWorkspacePushSyncService(input) {
|
|
|
852
919
|
currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
|
|
853
920
|
currentWorkstreamIds: input.payload.currentWorkstreamIds,
|
|
854
921
|
currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
|
|
922
|
+
currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
|
|
855
923
|
currentAiProfileIds: input.payload.currentAiProfileIds,
|
|
856
924
|
currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
|
|
857
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
|
+
}
|
|
@@ -3,6 +3,8 @@ import { WORKSPACE_SYNC_V3_COMBINED_CAPABILITY_VERSION, WORKSPACE_SYNC_V3_COMBIN
|
|
|
3
3
|
import { WORKSPACE_SYNC_V3_NESTED_COVERAGE_SELECTOR } from './workspaceSyncV3NestedWireContract.js';
|
|
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
|
+
import { WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3TaskCoverWireContract.js';
|
|
7
|
+
import { WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowTaskCoverWireContract.js';
|
|
6
8
|
export { WORKSPACE_SYNC_V3_COMBINED_CAPABILITY_VERSION } from './workspaceSyncV3CombinedWireContract.js';
|
|
7
9
|
export function resolveRequestedCombinedFeedCoverage(env = process.env) {
|
|
8
10
|
const requestedVersion = String(env.TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION || '').trim();
|
|
@@ -18,6 +20,12 @@ export function resolveRequestedCombinedFeedCoverage(env = process.env) {
|
|
|
18
20
|
if (requestedVersion === String(WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR.coverageVersion)) {
|
|
19
21
|
return WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR;
|
|
20
22
|
}
|
|
23
|
+
if (requestedVersion === String(WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR.coverageVersion)) {
|
|
24
|
+
return WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR;
|
|
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
|
+
}
|
|
21
29
|
throw new Error(`Unsupported TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION: ${requestedVersion}.`);
|
|
22
30
|
}
|
|
23
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*)$/;
|
|
@@ -12,6 +12,7 @@ export declare function resolveTaskAttachmentLinksMutationCapability(input: {
|
|
|
12
12
|
export type DurableTaskAttachmentLinksMutationRouterCore = DurableTaskAttachmentLinksServiceCore & LocalTaskAttachmentLinksOutboxCore & {
|
|
13
13
|
getDatabaseAdapter(): DatabaseAdapter;
|
|
14
14
|
getTask(id: string, workspaceId?: string): TaskItem | null;
|
|
15
|
+
assertTaskDetailRevisionForUpdate(id: string, expected: string, workspaceId?: string): void;
|
|
15
16
|
};
|
|
16
17
|
export declare class DurableTaskAttachmentLinksRouterDisabledError extends Error {
|
|
17
18
|
readonly code = "WORKSPACE_SYNC_V3_TASK_ATTACHMENT_LINKS_ROUTER_DISABLED";
|
|
@@ -41,6 +42,7 @@ export declare function createDurableTaskAttachmentLinksMutationRouter(input: {
|
|
|
41
42
|
taskId: string;
|
|
42
43
|
links: readonly WorkspaceSyncV3TaskAttachmentLink[];
|
|
43
44
|
cardCoverAssetId?: string | null;
|
|
45
|
+
expectedDetailRevision?: string;
|
|
44
46
|
}): {
|
|
45
47
|
state: "pending" | "committed";
|
|
46
48
|
route: "local-outbox" | "cloud-acceptance";
|