@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
|
@@ -3,13 +3,38 @@ import { Worker } from 'worker_threads';
|
|
|
3
3
|
import { performance } from 'node:perf_hooks';
|
|
4
4
|
import { assertSynchronousTransactionResult, } from './databaseAdapter.js';
|
|
5
5
|
import { recordPostgresWorkerWait } from './postgresRequestDiagnostics.js';
|
|
6
|
+
import { resolvePostgresWorkerDeadlines, } from './postgresWorkerProtocol.js';
|
|
6
7
|
const RESPONSE_STATUS_INDEX = 0;
|
|
7
8
|
const RESPONSE_LENGTH_INDEX = 1;
|
|
8
9
|
const RESPONSE_READY = 1;
|
|
9
10
|
const RESPONSE_INITIAL = 0;
|
|
10
|
-
const RESPONSE_TIMEOUT_MS = 20_000;
|
|
11
11
|
const RESPONSE_BUFFER_BYTES = 2 * 1024 * 1024;
|
|
12
12
|
const MAX_RESPONSE_BUFFER_BYTES = 64 * 1024 * 1024;
|
|
13
|
+
export class PostgresWorkerOutcomeUnknownError extends Error {
|
|
14
|
+
code = 'POSTGRES_WORKER_OUTCOME_UNKNOWN';
|
|
15
|
+
operation;
|
|
16
|
+
constructor(operation, detail = 'response deadline exceeded') {
|
|
17
|
+
super(`[Taskforce] Postgres worker ${operation} outcome is unknown (${detail}). `
|
|
18
|
+
+ 'Do not retry a write without the same idempotency identity.');
|
|
19
|
+
this.name = 'PostgresWorkerOutcomeUnknownError';
|
|
20
|
+
this.operation = operation;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class PostgresWorkerUnavailableError extends Error {
|
|
24
|
+
code = 'POSTGRES_WORKER_UNAVAILABLE';
|
|
25
|
+
constructor() {
|
|
26
|
+
super('[Taskforce] Postgres worker is recovering after a failed operation.');
|
|
27
|
+
this.name = 'PostgresWorkerUnavailableError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class PostgresDatabaseError extends Error {
|
|
31
|
+
code;
|
|
32
|
+
constructor(message, code) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.code = code;
|
|
35
|
+
this.name = 'PostgresDatabaseError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
13
38
|
function isPlainObject(value) {
|
|
14
39
|
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
15
40
|
}
|
|
@@ -62,39 +87,102 @@ function toRowCount(result) {
|
|
|
62
87
|
}
|
|
63
88
|
export class PostgresAdapter {
|
|
64
89
|
provider = 'postgres';
|
|
65
|
-
|
|
66
|
-
|
|
90
|
+
worker = null;
|
|
91
|
+
connectionString;
|
|
92
|
+
deadlines;
|
|
93
|
+
retiringWorkers = new WeakSet();
|
|
94
|
+
consecutiveUnexpectedExits = 0;
|
|
95
|
+
closed = false;
|
|
67
96
|
encoder = new TextEncoder();
|
|
68
97
|
decoder = new TextDecoder();
|
|
69
98
|
txId = null;
|
|
70
99
|
savepointCounter = 0;
|
|
71
|
-
constructor(connectionString) {
|
|
100
|
+
constructor(connectionString, deadlineOptions = {}) {
|
|
72
101
|
if (!connectionString || !connectionString.trim()) {
|
|
73
102
|
throw new Error('[Taskforce] Postgres adapter requires a non-empty connection string.');
|
|
74
103
|
}
|
|
75
|
-
this.
|
|
104
|
+
this.connectionString = connectionString;
|
|
105
|
+
this.deadlines = resolvePostgresWorkerDeadlines(deadlineOptions);
|
|
106
|
+
this.worker = this.createWorker();
|
|
107
|
+
}
|
|
108
|
+
get open() {
|
|
109
|
+
return !this.closed;
|
|
110
|
+
}
|
|
111
|
+
createWorker() {
|
|
112
|
+
const worker = new Worker(new URL('./postgresWorker.js', import.meta.url), {
|
|
76
113
|
workerData: {
|
|
77
|
-
connectionString
|
|
114
|
+
connectionString: this.connectionString,
|
|
115
|
+
deadlines: this.deadlines,
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
worker.on('error', () => {
|
|
119
|
+
// The exit handler replaces an unexpectedly failed worker. Keeping an error
|
|
120
|
+
// listener here also prevents Worker from escalating it as an uncaught error.
|
|
121
|
+
});
|
|
122
|
+
worker.on('exit', () => {
|
|
123
|
+
if (this.closed || this.retiringWorkers.has(worker) || this.worker !== worker)
|
|
124
|
+
return;
|
|
125
|
+
this.worker = null;
|
|
126
|
+
if (this.consecutiveUnexpectedExits >= 1)
|
|
127
|
+
return;
|
|
128
|
+
this.consecutiveUnexpectedExits += 1;
|
|
129
|
+
try {
|
|
130
|
+
this.worker = this.createWorker();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Leave the adapter unavailable instead of creating an unbounded restart loop.
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
return worker;
|
|
137
|
+
}
|
|
138
|
+
quarantineWorker(worker) {
|
|
139
|
+
if (this.worker === worker)
|
|
140
|
+
this.worker = null;
|
|
141
|
+
this.txId = null;
|
|
142
|
+
this.retiringWorkers.add(worker);
|
|
143
|
+
void worker.terminate()
|
|
144
|
+
.catch(() => undefined)
|
|
145
|
+
.finally(() => {
|
|
146
|
+
if (this.closed || this.worker)
|
|
147
|
+
return;
|
|
148
|
+
try {
|
|
149
|
+
this.worker = this.createWorker();
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// A later process-level health check can restart a persistently broken runtime.
|
|
78
153
|
}
|
|
79
154
|
});
|
|
80
155
|
}
|
|
81
156
|
callWorker(payload, responseBufferBytes = RESPONSE_BUFFER_BYTES) {
|
|
157
|
+
if (this.closed)
|
|
158
|
+
throw new Error('[Taskforce] Postgres adapter is closed.');
|
|
159
|
+
const worker = this.worker;
|
|
160
|
+
if (!worker)
|
|
161
|
+
throw new PostgresWorkerUnavailableError();
|
|
82
162
|
const statusBuffer = new SharedArrayBuffer(8);
|
|
83
163
|
const status = new Int32Array(statusBuffer);
|
|
84
164
|
status[RESPONSE_STATUS_INDEX] = RESPONSE_INITIAL;
|
|
85
165
|
status[RESPONSE_LENGTH_INDEX] = 0;
|
|
86
166
|
const responseBuffer = new SharedArrayBuffer(responseBufferBytes);
|
|
87
167
|
const responseBytes = new Uint8Array(responseBuffer);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
168
|
+
try {
|
|
169
|
+
worker.postMessage({
|
|
170
|
+
payload,
|
|
171
|
+
statusBuffer,
|
|
172
|
+
responseBuffer
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
this.quarantineWorker(worker);
|
|
177
|
+
const detail = error instanceof Error ? error.message : 'worker transport failed';
|
|
178
|
+
throw new PostgresWorkerOutcomeUnknownError(payload.op, detail);
|
|
179
|
+
}
|
|
93
180
|
const waitStartedAt = performance.now();
|
|
94
|
-
const waitResult = Atomics.wait(status, RESPONSE_STATUS_INDEX, RESPONSE_INITIAL,
|
|
181
|
+
const waitResult = Atomics.wait(status, RESPONSE_STATUS_INDEX, RESPONSE_INITIAL, this.deadlines.responseTimeoutMs);
|
|
95
182
|
recordPostgresWorkerWait(payload.op, performance.now() - waitStartedAt);
|
|
96
183
|
if (waitResult === 'timed-out') {
|
|
97
|
-
|
|
184
|
+
this.quarantineWorker(worker);
|
|
185
|
+
throw new PostgresWorkerOutcomeUnknownError(payload.op);
|
|
98
186
|
}
|
|
99
187
|
const responseLength = status[RESPONSE_LENGTH_INDEX];
|
|
100
188
|
if (!Number.isFinite(responseLength) || responseLength <= 0 || responseLength > responseBufferBytes) {
|
|
@@ -102,6 +190,7 @@ export class PostgresAdapter {
|
|
|
102
190
|
}
|
|
103
191
|
const body = this.decoder.decode(responseBytes.subarray(0, responseLength));
|
|
104
192
|
const parsed = JSON.parse(body);
|
|
193
|
+
this.consecutiveUnexpectedExits = 0;
|
|
105
194
|
if (!parsed.ok && parsed.errorCode === 'RESPONSE_BUFFER_TOO_SMALL') {
|
|
106
195
|
const requiredBytes = Number(parsed.requiredBytes);
|
|
107
196
|
const responseToken = String(parsed.responseToken || '').trim();
|
|
@@ -114,6 +203,9 @@ export class PostgresAdapter {
|
|
|
114
203
|
return this.callWorker({ op: 'read-response', responseToken }, requiredBytes);
|
|
115
204
|
}
|
|
116
205
|
if (!parsed.ok) {
|
|
206
|
+
if (parsed.databaseErrorCode) {
|
|
207
|
+
throw new PostgresDatabaseError(parsed.error || 'Unknown Postgres database error', parsed.databaseErrorCode);
|
|
208
|
+
}
|
|
117
209
|
throw new Error(parsed.error || 'Unknown Postgres worker error');
|
|
118
210
|
}
|
|
119
211
|
return parsed;
|
|
@@ -230,11 +322,22 @@ export class PostgresAdapter {
|
|
|
230
322
|
return options?.simple ? null : [];
|
|
231
323
|
}
|
|
232
324
|
close() {
|
|
325
|
+
if (this.closed)
|
|
326
|
+
return;
|
|
327
|
+
const worker = this.worker;
|
|
328
|
+
if (!worker) {
|
|
329
|
+
this.closed = true;
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
233
332
|
try {
|
|
234
333
|
this.callWorker({ op: 'close' });
|
|
235
334
|
}
|
|
236
335
|
finally {
|
|
237
|
-
this.
|
|
336
|
+
this.closed = true;
|
|
337
|
+
if (this.worker === worker)
|
|
338
|
+
this.worker = null;
|
|
339
|
+
this.retiringWorkers.add(worker);
|
|
340
|
+
void worker.terminate();
|
|
238
341
|
}
|
|
239
342
|
}
|
|
240
343
|
}
|
|
@@ -14,11 +14,16 @@ function pruneRetainedResponses(now = Date.now()) {
|
|
|
14
14
|
retainedResponses.delete(token);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
function createPool(connectionString) {
|
|
17
|
+
function createPool(connectionString, deadlines) {
|
|
18
18
|
const require = createRequire(import.meta.url);
|
|
19
19
|
try {
|
|
20
20
|
const pg = require('pg');
|
|
21
|
-
return new pg.Pool({
|
|
21
|
+
return new pg.Pool({
|
|
22
|
+
connectionString,
|
|
23
|
+
connectionTimeoutMillis: deadlines.connectionTimeoutMs,
|
|
24
|
+
statement_timeout: deadlines.statementTimeoutMs,
|
|
25
|
+
idle_in_transaction_session_timeout: deadlines.idleTransactionTimeoutMs,
|
|
26
|
+
});
|
|
22
27
|
}
|
|
23
28
|
catch (error) {
|
|
24
29
|
const detail = error instanceof Error ? ` (${error.message})` : '';
|
|
@@ -96,11 +101,15 @@ function writeRetainedResponse(statusBuffer, responseBuffer, responseToken) {
|
|
|
96
101
|
Atomics.store(status, RESPONSE_STATUS_INDEX, RESPONSE_READY);
|
|
97
102
|
Atomics.notify(status, RESPONSE_STATUS_INDEX, 1);
|
|
98
103
|
}
|
|
99
|
-
const
|
|
104
|
+
const runtimeOptions = workerData;
|
|
105
|
+
const connectionString = String(runtimeOptions?.connectionString || '').trim();
|
|
100
106
|
if (!connectionString) {
|
|
101
107
|
throw new Error('[Taskforce] Postgres worker requires connection string.');
|
|
102
108
|
}
|
|
103
|
-
|
|
109
|
+
if (!runtimeOptions.deadlines) {
|
|
110
|
+
throw new Error('[Taskforce] Postgres worker requires deadline configuration.');
|
|
111
|
+
}
|
|
112
|
+
const pool = createPool(connectionString, runtimeOptions.deadlines);
|
|
104
113
|
const txClients = new Map();
|
|
105
114
|
async function handleMessage(message) {
|
|
106
115
|
const { payload } = message;
|
|
@@ -169,6 +178,14 @@ parentPort.on('message', async (message) => {
|
|
|
169
178
|
}
|
|
170
179
|
catch (error) {
|
|
171
180
|
const messageText = error instanceof Error ? error.message : String(error);
|
|
172
|
-
|
|
181
|
+
const databaseErrorCode = error && typeof error === 'object'
|
|
182
|
+
&& typeof error.code === 'string'
|
|
183
|
+
? String(error.code)
|
|
184
|
+
: undefined;
|
|
185
|
+
writeResponse(message.statusBuffer, message.responseBuffer, {
|
|
186
|
+
ok: false,
|
|
187
|
+
error: messageText,
|
|
188
|
+
...(databaseErrorCode ? { databaseErrorCode } : {}),
|
|
189
|
+
});
|
|
173
190
|
}
|
|
174
191
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type PostgresWorkerOperation = 'query' | 'begin' | 'commit' | 'rollback' | 'close' | 'read-response';
|
|
2
|
+
export type PostgresWorkerRequestPayload = {
|
|
3
|
+
op: PostgresWorkerOperation;
|
|
4
|
+
sql?: string;
|
|
5
|
+
values?: unknown[];
|
|
6
|
+
txId?: string;
|
|
7
|
+
responseToken?: string;
|
|
8
|
+
};
|
|
9
|
+
export type PostgresWorkerQueryResult = {
|
|
10
|
+
rows: Record<string, unknown>[];
|
|
11
|
+
rowCount?: number;
|
|
12
|
+
};
|
|
13
|
+
export type PostgresWorkerResponsePayload = {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
result?: PostgresWorkerQueryResult;
|
|
16
|
+
error?: string;
|
|
17
|
+
errorCode?: 'RESPONSE_BUFFER_TOO_SMALL';
|
|
18
|
+
databaseErrorCode?: string;
|
|
19
|
+
requiredBytes?: number;
|
|
20
|
+
responseToken?: string;
|
|
21
|
+
};
|
|
22
|
+
export type PostgresWorkerDeadlines = {
|
|
23
|
+
responseTimeoutMs: number;
|
|
24
|
+
statementTimeoutMs: number;
|
|
25
|
+
connectionTimeoutMs: number;
|
|
26
|
+
idleTransactionTimeoutMs: number;
|
|
27
|
+
};
|
|
28
|
+
export type PostgresAdapterDeadlineOptions = Partial<PostgresWorkerDeadlines>;
|
|
29
|
+
export declare const DEFAULT_POSTGRES_WORKER_DEADLINES: PostgresWorkerDeadlines;
|
|
30
|
+
export declare function resolvePostgresWorkerDeadlines(options?: PostgresAdapterDeadlineOptions): PostgresWorkerDeadlines;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const DEFAULT_POSTGRES_WORKER_DEADLINES = {
|
|
2
|
+
responseTimeoutMs: 20_000,
|
|
3
|
+
statementTimeoutMs: 15_000,
|
|
4
|
+
connectionTimeoutMs: 3_000,
|
|
5
|
+
idleTransactionTimeoutMs: 60_000,
|
|
6
|
+
};
|
|
7
|
+
const MIN_RESPONSE_MARGIN_MS = 100;
|
|
8
|
+
function positiveInteger(value, name) {
|
|
9
|
+
const parsed = Number(value);
|
|
10
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
11
|
+
throw new Error(`[Taskforce] ${name} must be a positive integer.`);
|
|
12
|
+
}
|
|
13
|
+
return parsed;
|
|
14
|
+
}
|
|
15
|
+
export function resolvePostgresWorkerDeadlines(options = {}) {
|
|
16
|
+
const deadlines = {
|
|
17
|
+
responseTimeoutMs: positiveInteger(options.responseTimeoutMs ?? DEFAULT_POSTGRES_WORKER_DEADLINES.responseTimeoutMs, 'Postgres worker response timeout'),
|
|
18
|
+
statementTimeoutMs: positiveInteger(options.statementTimeoutMs ?? DEFAULT_POSTGRES_WORKER_DEADLINES.statementTimeoutMs, 'Postgres statement timeout'),
|
|
19
|
+
connectionTimeoutMs: positiveInteger(options.connectionTimeoutMs ?? DEFAULT_POSTGRES_WORKER_DEADLINES.connectionTimeoutMs, 'Postgres connection timeout'),
|
|
20
|
+
idleTransactionTimeoutMs: positiveInteger(options.idleTransactionTimeoutMs ?? DEFAULT_POSTGRES_WORKER_DEADLINES.idleTransactionTimeoutMs, 'Postgres idle transaction timeout'),
|
|
21
|
+
};
|
|
22
|
+
if (deadlines.connectionTimeoutMs
|
|
23
|
+
+ deadlines.statementTimeoutMs
|
|
24
|
+
+ MIN_RESPONSE_MARGIN_MS
|
|
25
|
+
> deadlines.responseTimeoutMs) {
|
|
26
|
+
throw new Error('[Taskforce] Postgres connection and statement timeouts must together leave at least '
|
|
27
|
+
+ `${MIN_RESPONSE_MARGIN_MS}ms before the worker response timeout.`);
|
|
28
|
+
}
|
|
29
|
+
return deadlines;
|
|
30
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from './databaseAdapter.js';
|
|
2
|
+
export interface TaskforceAgentConnectionBindingRecord {
|
|
3
|
+
tenantId: string;
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
connectionId: string;
|
|
7
|
+
ownerUserId: string;
|
|
8
|
+
providerKey: string;
|
|
9
|
+
modelSource: string;
|
|
10
|
+
createdByUserId: string;
|
|
11
|
+
updatedByUserId: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class TaskforceAgentConnectionBindingStore {
|
|
16
|
+
private readonly db;
|
|
17
|
+
private readonly tenantId;
|
|
18
|
+
private readonly now;
|
|
19
|
+
constructor(db: DatabaseAdapter, tenantId: string, now?: () => Date);
|
|
20
|
+
get(workspaceIdRaw: string, agentIdRaw: string): TaskforceAgentConnectionBindingRecord | null;
|
|
21
|
+
bind(input: {
|
|
22
|
+
workspaceId: string;
|
|
23
|
+
agentId: string;
|
|
24
|
+
connectionId: string;
|
|
25
|
+
ownerUserId: string;
|
|
26
|
+
providerKey: string;
|
|
27
|
+
modelSource: string;
|
|
28
|
+
actorUserId: string;
|
|
29
|
+
}): TaskforceAgentConnectionBindingRecord | null;
|
|
30
|
+
clear(workspaceIdRaw: string, agentIdRaw: string, ownerUserIdRaw: string): boolean;
|
|
31
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function normalizeRequired(value, label) {
|
|
2
|
+
const normalized = String(value || '').trim();
|
|
3
|
+
if (!normalized)
|
|
4
|
+
throw new Error(`${label} is required.`);
|
|
5
|
+
return normalized;
|
|
6
|
+
}
|
|
7
|
+
function mapRow(row) {
|
|
8
|
+
return {
|
|
9
|
+
tenantId: String(row.tenant_id || ''),
|
|
10
|
+
workspaceId: String(row.workspace_id || ''),
|
|
11
|
+
agentId: String(row.agent_id || ''),
|
|
12
|
+
connectionId: String(row.connection_id || ''),
|
|
13
|
+
ownerUserId: String(row.owner_user_id || ''),
|
|
14
|
+
providerKey: String(row.provider_key || ''),
|
|
15
|
+
modelSource: String(row.model_source || ''),
|
|
16
|
+
createdByUserId: String(row.created_by_user_id || ''),
|
|
17
|
+
updatedByUserId: String(row.updated_by_user_id || ''),
|
|
18
|
+
createdAt: String(row.created_at || ''),
|
|
19
|
+
updatedAt: String(row.updated_at || ''),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export class TaskforceAgentConnectionBindingStore {
|
|
23
|
+
db;
|
|
24
|
+
tenantId;
|
|
25
|
+
now;
|
|
26
|
+
constructor(db, tenantId, now = () => new Date()) {
|
|
27
|
+
this.db = db;
|
|
28
|
+
this.tenantId = tenantId;
|
|
29
|
+
this.now = now;
|
|
30
|
+
}
|
|
31
|
+
get(workspaceIdRaw, agentIdRaw) {
|
|
32
|
+
const workspaceId = String(workspaceIdRaw || '').trim();
|
|
33
|
+
const agentId = String(agentIdRaw || '').trim();
|
|
34
|
+
if (!workspaceId || !agentId)
|
|
35
|
+
return null;
|
|
36
|
+
const row = this.db.prepare(`
|
|
37
|
+
SELECT *
|
|
38
|
+
FROM taskforce_agent_connection_bindings
|
|
39
|
+
WHERE tenant_id = ? AND workspace_id = ? AND agent_id = ?
|
|
40
|
+
LIMIT 1
|
|
41
|
+
`).get(this.tenantId, workspaceId, agentId);
|
|
42
|
+
return row ? mapRow(row) : null;
|
|
43
|
+
}
|
|
44
|
+
bind(input) {
|
|
45
|
+
const workspaceId = normalizeRequired(input.workspaceId, 'Workspace ID');
|
|
46
|
+
const agentId = normalizeRequired(input.agentId, 'Agent ID');
|
|
47
|
+
const connectionId = normalizeRequired(input.connectionId, 'Connection ID');
|
|
48
|
+
const ownerUserId = normalizeRequired(input.ownerUserId, 'Connection owner');
|
|
49
|
+
const providerKey = normalizeRequired(input.providerKey, 'Provider key');
|
|
50
|
+
const modelSource = normalizeRequired(input.modelSource, 'Model source');
|
|
51
|
+
const actorUserId = normalizeRequired(input.actorUserId, 'Actor user');
|
|
52
|
+
const now = this.now().toISOString();
|
|
53
|
+
const result = this.db.prepare(`
|
|
54
|
+
INSERT INTO taskforce_agent_connection_bindings (
|
|
55
|
+
tenant_id, workspace_id, agent_id, connection_id, owner_user_id,
|
|
56
|
+
provider_key, model_source, created_by_user_id, updated_by_user_id,
|
|
57
|
+
created_at, updated_at
|
|
58
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
59
|
+
ON CONFLICT (tenant_id, workspace_id, agent_id) DO UPDATE SET
|
|
60
|
+
connection_id = excluded.connection_id,
|
|
61
|
+
owner_user_id = excluded.owner_user_id,
|
|
62
|
+
provider_key = excluded.provider_key,
|
|
63
|
+
model_source = excluded.model_source,
|
|
64
|
+
updated_by_user_id = excluded.updated_by_user_id,
|
|
65
|
+
updated_at = excluded.updated_at
|
|
66
|
+
WHERE taskforce_agent_connection_bindings.owner_user_id = excluded.owner_user_id
|
|
67
|
+
`).run(this.tenantId, workspaceId, agentId, connectionId, ownerUserId, providerKey, modelSource, actorUserId, actorUserId, now, now);
|
|
68
|
+
if (Number(result.changes || 0) === 0)
|
|
69
|
+
return null;
|
|
70
|
+
return this.get(workspaceId, agentId);
|
|
71
|
+
}
|
|
72
|
+
clear(workspaceIdRaw, agentIdRaw, ownerUserIdRaw) {
|
|
73
|
+
const workspaceId = String(workspaceIdRaw || '').trim();
|
|
74
|
+
const agentId = String(agentIdRaw || '').trim();
|
|
75
|
+
const ownerUserId = String(ownerUserIdRaw || '').trim();
|
|
76
|
+
if (!workspaceId || !agentId || !ownerUserId)
|
|
77
|
+
return false;
|
|
78
|
+
const result = this.db.prepare(`
|
|
79
|
+
DELETE FROM taskforce_agent_connection_bindings
|
|
80
|
+
WHERE tenant_id = ? AND workspace_id = ? AND agent_id = ? AND owner_user_id = ?
|
|
81
|
+
`).run(this.tenantId, workspaceId, agentId, ownerUserId);
|
|
82
|
+
return Number(result.changes || 0) > 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -23,10 +23,13 @@ export type WorkspaceContentRequest = Pick<WorkspaceContentManifestEntry, 'kind'
|
|
|
23
23
|
kind: 'asset';
|
|
24
24
|
assetId: string;
|
|
25
25
|
};
|
|
26
|
+
export type WorkspaceContentMissingRequest = WorkspaceContentRequest & {
|
|
27
|
+
disposition?: 'retryable' | 'terminal-unavailable';
|
|
28
|
+
};
|
|
26
29
|
export interface WorkspaceContentPullResponse {
|
|
27
30
|
success?: boolean;
|
|
28
31
|
changes?: WorkspaceSyncChange[];
|
|
29
|
-
missing?:
|
|
32
|
+
missing?: WorkspaceContentMissingRequest[];
|
|
30
33
|
remaining?: WorkspaceContentRequest[];
|
|
31
34
|
contentMetadata?: Array<{
|
|
32
35
|
kind: 'document' | 'asset';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { partitionWorkspaceSyncV2LegacyChanges } from './v3/workspaceSyncV2ProjectionExclusions.js';
|
|
1
|
+
import { normalizeWorkspaceSyncV2ProjectionExclusions, partitionWorkspaceSyncV2LegacyChanges, } from './v3/workspaceSyncV2ProjectionExclusions.js';
|
|
2
2
|
import { validateWorkspaceSyncEngineTransferCompletionGroup, } from './engine/workspaceSyncEngineTransferCompletion.js';
|
|
3
3
|
import { WORKSPACE_SYNC_V3_COMBINED_COVERAGE_SELECTOR, resolveWorkspaceSyncV3CombinedCoverageForExclusions, resolveWorkspaceSyncV3CombinedWireContract } from './v3/workspaceSyncV3CombinedWireContract.js';
|
|
4
4
|
const WORKSPACE_PULL_TIMEOUT_MS = 45_000;
|
|
@@ -696,12 +696,17 @@ export async function bootstrapPushWorkspaceSnapshot(resolveCloudAuthUrl, input)
|
|
|
696
696
|
}));
|
|
697
697
|
}
|
|
698
698
|
export async function applyLocalWorkspaceChanges(workspaceId, changes, options) {
|
|
699
|
+
const excludedProjections = normalizeWorkspaceSyncV2ProjectionExclusions(options?.excludedProjections || []);
|
|
700
|
+
const combinedCoverage = excludedProjections.length
|
|
701
|
+
? resolveWorkspaceSyncV3CombinedCoverageForExclusions(excludedProjections)
|
|
702
|
+
: null;
|
|
699
703
|
const applyPayload = JSON.stringify({
|
|
700
704
|
workspaceId,
|
|
701
705
|
changes,
|
|
702
706
|
workspaceMembers: Array.isArray(options?.workspaceMembers) ? options.workspaceMembers : undefined,
|
|
703
707
|
...(options?.repairMode === true ? { repair: true } : {}),
|
|
704
|
-
excludedProjections
|
|
708
|
+
excludedProjections,
|
|
709
|
+
...(combinedCoverage ? { combinedCoverage } : {}),
|
|
705
710
|
contentPullObligations: options?.contentPullObligations,
|
|
706
711
|
contentPullResolutionClaims: options?.contentPullResolutionClaims,
|
|
707
712
|
...localBrowserApplyPermitContext(workspaceId, options),
|
|
@@ -130,7 +130,7 @@ export declare function createContentSyncState(deps: ContentSyncStateDeps): {
|
|
|
130
130
|
activeLinks: WorkspaceAssetLinkEntry[];
|
|
131
131
|
effectiveUpdatedAt: string;
|
|
132
132
|
};
|
|
133
|
-
getCanonicalSyncDocumentMetadata: (relativePath: string, workspaceId: string) => Omit<DocumentSyncPayload, "
|
|
133
|
+
getCanonicalSyncDocumentMetadata: (relativePath: string, workspaceId: string) => Omit<DocumentSyncPayload, "updatedAt" | "path" | "content">;
|
|
134
134
|
hasDocumentSyncMetadataDrift: (workspaceId: string, doc: DocumentSyncPayload, _options?: {
|
|
135
135
|
allowReferenceNumberReassignment?: boolean;
|
|
136
136
|
}) => boolean;
|
|
@@ -152,6 +152,7 @@ export declare class LocalSyncExecutionPermitStore {
|
|
|
152
152
|
coordinatorGeneration: number;
|
|
153
153
|
serverInstanceId: string;
|
|
154
154
|
errorCode?: string;
|
|
155
|
+
readResponseUnavailableBeforeApply?: boolean;
|
|
155
156
|
}): LocalSyncExecutionPermit;
|
|
156
157
|
recoverExpiredPermits(input: {
|
|
157
158
|
currentServerInstanceId: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomUUID } from 'crypto';
|
|
1
|
+
import { createHash, randomUUID } from 'crypto';
|
|
2
2
|
import { assertSynchronousTransactionResult, } from '../../storage/databaseAdapter.js';
|
|
3
3
|
import { validateWorkspaceSyncEngineTransferCompletionGroup, } from '../engine/workspaceSyncEngineTransferCompletion.js';
|
|
4
4
|
import { canonicalWorkspaceSyncJson } from '../v3/canonicalWorkspaceSyncJson.js';
|
|
@@ -619,9 +619,15 @@ export class LocalSyncExecutionPermitStore {
|
|
|
619
619
|
if (current.state === 'local-commit-entered') {
|
|
620
620
|
throw new LocalSyncExecutionPermitError(`Execution permit ${input.permitId} is owned by the server local commit.`, 'SYNC_COORDINATOR_PERMIT_STATE_CONFLICT');
|
|
621
621
|
}
|
|
622
|
+
const cleanReadFailure = input.readResponseUnavailableBeforeApply === true
|
|
623
|
+
&& input.errorCode === 'SYNC_COORDINATOR_GATEWAY_REQUEST_FAILED'
|
|
624
|
+
&& current.state === 'gateway-complete-awaiting-apply'
|
|
625
|
+
&& current.upstreamDisposition === 'unknown'
|
|
626
|
+
&& (current.operationClass === 'pull' || current.operationClass === 'repair');
|
|
622
627
|
const clean = current.state === 'issued-idle'
|
|
623
628
|
|| (current.state === 'gateway-complete-awaiting-apply'
|
|
624
|
-
&& current.upstreamDisposition === 'rejected')
|
|
629
|
+
&& current.upstreamDisposition === 'rejected')
|
|
630
|
+
|| cleanReadFailure;
|
|
625
631
|
const disposition = current.upstreamDisposition === 'accepted'
|
|
626
632
|
? 'accepted'
|
|
627
633
|
: current.upstreamDisposition === 'rejected'
|
|
@@ -1401,36 +1407,67 @@ export class LocalSyncExecutionPermitStore {
|
|
|
1401
1407
|
const requiredAction = mutationReplay
|
|
1402
1408
|
? 'replay-operation-then-reconcile'
|
|
1403
1409
|
: 'refetch-from-committed-cursor';
|
|
1404
|
-
const
|
|
1410
|
+
const coalescesLegacyApplyFailure = errorCode === 'WORKSPACE_SYNC_V3_APPLY_NOT_COMMITTED'
|
|
1405
1411
|
|| errorCode === 'WORKSPACE_SYNC_V3_ATTACHMENT_HYDRATION_NOT_COMMITTED';
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1412
|
+
const coalescingKey = mutationReplay || coalescesLegacyApplyFailure
|
|
1413
|
+
? createHash('sha256').update(canonicalWorkspaceSyncJson(mutationReplay ? {
|
|
1414
|
+
workspaceId: permit.workspaceId,
|
|
1415
|
+
operationClass: permit.operationClass,
|
|
1416
|
+
operationIdentity: permit.operationIdentity || null,
|
|
1417
|
+
lastCommittedCursor: permit.lastCommittedCursor,
|
|
1418
|
+
requiredAction,
|
|
1419
|
+
} : {
|
|
1420
|
+
workspaceId: permit.workspaceId,
|
|
1421
|
+
operationClass: permit.operationClass,
|
|
1422
|
+
operationIdentity: permit.operationIdentity || null,
|
|
1423
|
+
upstreamDisposition: disposition,
|
|
1424
|
+
lastCommittedCursor: permit.lastCommittedCursor,
|
|
1425
|
+
requiredAction,
|
|
1426
|
+
errorCode,
|
|
1427
|
+
})).digest('hex')
|
|
1428
|
+
: null;
|
|
1429
|
+
// This store method normally runs inside the permit transition
|
|
1430
|
+
// transaction. The nested transaction gives PostgreSQL a savepoint
|
|
1431
|
+
// boundary while the partial unique index arbitrates concurrent
|
|
1432
|
+
// equivalent inserts without poisoning the outer transaction.
|
|
1433
|
+
let inserted = false;
|
|
1434
|
+
try {
|
|
1435
|
+
this.db.transaction(() => {
|
|
1436
|
+
this.db.prepare(`
|
|
1437
|
+
INSERT INTO local_sync_recovery_obligations (
|
|
1438
|
+
obligation_id, permit_id, workspace_id, operation_class,
|
|
1439
|
+
operation_identity, upstream_disposition,
|
|
1440
|
+
last_committed_cursor_json, required_action, coalescing_key,
|
|
1441
|
+
created_at, resolved_at
|
|
1442
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)
|
|
1443
|
+
`).run(this.createId(), permit.permitId, permit.workspaceId, permit.operationClass, permit.operationIdentity, disposition, permit.lastCommittedCursor === null
|
|
1444
|
+
? null
|
|
1445
|
+
: JSON.stringify(permit.lastCommittedCursor), requiredAction, coalescingKey, this.now());
|
|
1446
|
+
inserted = true;
|
|
1447
|
+
})();
|
|
1448
|
+
}
|
|
1449
|
+
catch (error) {
|
|
1450
|
+
const existing = coalescingKey
|
|
1451
|
+
? this.db.prepare(`
|
|
1452
|
+
SELECT obligation_id
|
|
1453
|
+
FROM local_sync_recovery_obligations
|
|
1454
|
+
WHERE coalescing_key = ? AND resolved_at IS NULL
|
|
1455
|
+
`).get(coalescingKey)
|
|
1456
|
+
: undefined;
|
|
1457
|
+
if (!existing?.obligation_id)
|
|
1458
|
+
throw error;
|
|
1424
1459
|
}
|
|
1460
|
+
if (inserted || !coalescingKey)
|
|
1461
|
+
return;
|
|
1425
1462
|
this.db.prepare(`
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
?
|
|
1434
|
-
|
|
1463
|
+
UPDATE local_sync_recovery_obligations
|
|
1464
|
+
SET upstream_disposition = CASE
|
|
1465
|
+
WHEN upstream_disposition = 'accepted' OR ? = 'accepted' THEN 'accepted'
|
|
1466
|
+
WHEN upstream_disposition = 'unknown' OR ? = 'unknown' THEN 'unknown'
|
|
1467
|
+
WHEN upstream_disposition = 'rejected' OR ? = 'rejected' THEN 'rejected'
|
|
1468
|
+
ELSE upstream_disposition
|
|
1469
|
+
END
|
|
1470
|
+
WHERE coalescing_key = ? AND resolved_at IS NULL
|
|
1471
|
+
`).run(disposition, disposition, disposition, coalescingKey);
|
|
1435
1472
|
}
|
|
1436
1473
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LocalWorkspaceSyncPendingV2Push } from './localWorkspaceSyncRunnerState.js';
|
|
2
|
+
export interface LocalWorkspaceSyncPendingV2PushProgress {
|
|
3
|
+
effectiveTotalBatches: number;
|
|
4
|
+
settledBatches: number;
|
|
5
|
+
effectiveTotalChanges: number;
|
|
6
|
+
settledChanges: number;
|
|
7
|
+
remainingChanges: number;
|
|
8
|
+
firstUnsettledBatchIndex: number | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function resolveLocalWorkspaceSyncPendingV2PushProgress(pending: LocalWorkspaceSyncPendingV2Push | null | undefined): LocalWorkspaceSyncPendingV2PushProgress | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function resolveLocalWorkspaceSyncPendingV2PushProgress(pending) {
|
|
2
|
+
const plan = pending?.preparedPlan;
|
|
3
|
+
const settledIdentities = pending?.settledBatchOperationIdentities;
|
|
4
|
+
if (pending?.settlementVersion !== 1
|
|
5
|
+
|| !plan
|
|
6
|
+
|| !Array.isArray(settledIdentities)
|
|
7
|
+
|| plan.batches.length !== plan.batchOperationIdentities.length
|
|
8
|
+
|| new Set(plan.batchOperationIdentities).size !== plan.batchOperationIdentities.length
|
|
9
|
+
|| new Set(settledIdentities).size !== settledIdentities.length
|
|
10
|
+
|| settledIdentities.some((identity) => !plan.batchOperationIdentities.includes(identity))) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const settled = new Set(settledIdentities);
|
|
14
|
+
const effectiveTotalChanges = plan.batches.reduce((total, batch) => total + batch.length, 0);
|
|
15
|
+
const settledChanges = plan.batches.reduce((total, batch, index) => (settled.has(plan.batchOperationIdentities[index])
|
|
16
|
+
? total + batch.length
|
|
17
|
+
: total), 0);
|
|
18
|
+
const firstUnsettledBatchIndex = plan.batchOperationIdentities.findIndex((identity) => !settled.has(identity));
|
|
19
|
+
return {
|
|
20
|
+
effectiveTotalBatches: plan.batches.length,
|
|
21
|
+
settledBatches: settled.size,
|
|
22
|
+
effectiveTotalChanges,
|
|
23
|
+
settledChanges,
|
|
24
|
+
remainingChanges: effectiveTotalChanges - settledChanges,
|
|
25
|
+
firstUnsettledBatchIndex: firstUnsettledBatchIndex < 0
|
|
26
|
+
? null
|
|
27
|
+
: firstUnsettledBatchIndex,
|
|
28
|
+
};
|
|
29
|
+
}
|