@taskforcehq/taskforce 0.3.329 → 0.3.330
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Taskforce.module.css +290 -45
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/TaskSettings.js +70 -14
- package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
- package/dist/components/features/TaskforceAgentsModule.js +586 -116
- package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
- package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/views/StandaloneLayout.js +27 -26
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
- package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
- package/dist/config/envSchema.js +48 -1
- package/dist/core/McpTokenService.d.ts +23 -1
- package/dist/core/McpTokenService.js +93 -10
- package/dist/core/TaskChecklistCommandService.d.ts +27 -0
- package/dist/core/TaskChecklistCommandService.js +83 -5
- package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
- package/dist/core/TaskLifecycleCommandService.js +6 -2
- package/dist/core/Taskforce.d.ts +32 -0
- package/dist/core/Taskforce.js +125 -4
- package/dist/core/types.d.ts +8 -0
- package/dist/documentReviews/commandService.d.ts +2 -1
- package/dist/documentReviews/commandService.js +6 -3
- package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.js +2 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
- package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
- package/dist/hooks/sync/useSyncStatusControls.js +47 -11
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +31 -1
- package/dist/hooks/useTaskData.js +29 -7
- package/dist/hooks/useTaskMutations.d.ts +3 -1
- package/dist/hooks/useTaskMutations.js +46 -12
- package/dist/hooks/useTaskforce.d.ts +2 -0
- package/dist/hooks/useTaskforce.js +11 -2
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +9 -6
- package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
- package/dist/mcp/durableTaskMutationRouter.js +10 -0
- package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
- package/dist/mcp/httpProtocolRouting.d.ts +10 -0
- package/dist/mcp/httpProtocolRouting.js +19 -0
- package/dist/mcp/localCliHealth.d.ts +2 -2
- package/dist/mcp/localCliHealth.js +2 -2
- package/dist/mcp/localServiceProxy.d.ts +1 -0
- package/dist/mcp/localServiceProxy.js +530 -68
- package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
- package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
- package/dist/mcp/runtime.d.ts +54 -79
- package/dist/mcp/runtime.js +384 -97
- package/dist/mcp/taskPlanningRegistrar.js +23 -4
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +10 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +1 -0
- package/dist/mcp/workflowExecutionRegistrar.js +4 -4
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +415 -0
- package/dist/runtime/appGates.d.ts +2 -1
- package/dist/runtime/appGates.js +7 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +108 -11
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.js +2 -1
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +12 -14
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +112 -3
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +277 -24
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
- package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
- package/dist/server/routes/executorPhaseAApprovals.js +140 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
- package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
- package/dist/server/routes/githubReviewEvidence.js +116 -0
- package/dist/server/routes/localService.d.ts +15 -4
- package/dist/server/routes/localService.js +136 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/shared.d.ts +19 -0
- package/dist/server/routes/shared.js +95 -19
- package/dist/server/routes/sync.js +1 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -1
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +10 -1
- package/dist/server/routes/syncV3OperationRoutes.js +35 -9
- package/dist/server/routes/tasks.js +21 -2
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes.js +59 -0
- package/dist/services/codexAppServerModelGateway.d.ts +54 -5
- package/dist/services/codexAppServerModelGateway.js +246 -21
- package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
- package/dist/services/codexDeviceCodeLoginManager.js +265 -0
- package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
- package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
- package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
- package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
- package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
- package/dist/services/executorPhaseAApprovalService.js +609 -0
- package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
- package/dist/services/executorPhaseADriftEvaluator.js +93 -0
- package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
- package/dist/services/executorPhaseAIssuerCore.js +295 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
- package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
- package/dist/services/githubReviewEvidenceRuntime.js +30 -0
- package/dist/services/githubReviewEvidenceService.d.ts +93 -0
- package/dist/services/githubReviewEvidenceService.js +336 -0
- package/dist/services/modelGateway.d.ts +7 -0
- package/dist/services/modelProviderConnectionService.d.ts +71 -0
- package/dist/services/modelProviderConnectionService.js +279 -0
- package/dist/services/modelProviderCredentialHome.d.ts +32 -0
- package/dist/services/modelProviderCredentialHome.js +271 -0
- package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
- package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
- package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
- package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +1 -1
- package/dist/services/taskforceAgentMcpBridge.js +7 -24
- package/dist/shared/adminEdgeProxy.d.ts +5 -0
- package/dist/shared/adminEdgeProxy.js +94 -0
- package/dist/shared/adminProxySessionCookies.d.ts +16 -0
- package/dist/shared/adminProxySessionCookies.js +86 -0
- package/dist/shared/aiProfileColors.d.ts +31 -1
- package/dist/shared/aiProfileColors.js +14 -6
- package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
- package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
- package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
- package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
- package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
- package/dist/shared/executorPhaseADriftContracts.js +63 -0
- package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
- package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
- package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
- package/dist/shared/executorPhaseARunAuthorization.js +232 -0
- package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
- package/dist/shared/executorPhaseASchemaValidation.js +53 -0
- package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
- package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
- package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
- package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
- package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
- package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
- package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
- package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
- package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
- package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
- package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
- package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
- package/dist/shared/executorPhaseATiming.d.ts +1 -0
- package/dist/shared/executorPhaseATiming.js +1 -0
- package/dist/shared/planningIdentity.js +1 -1
- package/dist/shared/productLogoKeys.d.ts +2 -0
- package/dist/shared/productLogoKeys.js +18 -0
- package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
- package/dist/shared/taskforceAgentDefinition.js +6 -9
- package/dist/shared/taskforceAgentModels.js +7 -3
- package/dist/shared/userFeatureGrants.d.ts +4 -0
- package/dist/shared/userFeatureGrants.js +7 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
- package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
- package/dist/storage/modelProviderConnectionStore.js +446 -0
- package/dist/storage/postgresAdapter.d.ts +4 -0
- package/dist/storage/postgresAdapter.js +11 -0
- package/dist/storage/postgresWorker.js +9 -1
- package/dist/storage/postgresWorkerProtocol.d.ts +1 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
- package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
- package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
- package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
- package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
- package/dist/sync/syncApplyHandlers.d.ts +2 -0
- package/dist/sync/syncApplyHandlers.js +10 -1
- package/dist/sync/syncService.d.ts +15 -0
- package/dist/sync/syncService.js +83 -18
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
- package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
- package/dist/sync/v3/durableOperationReplay.js +18 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
- package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
- package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
- package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
- package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
- package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
- package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
- package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +8 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +219 -12
- package/dist/sync/v3/syncDurabilityStore.d.ts +34 -0
- package/dist/sync/v3/syncDurabilityStore.js +168 -2
- package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
- package/dist/sync/v3/taskChecklistMutationService.js +44 -1
- package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
- package/dist/sync/v3/taskStatusMutationService.js +119 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
- package/dist/sync/v3/workflowAssignmentSync.js +27 -0
- package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
- package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
- package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
- package/dist/sync/workspaceRepair.d.ts +5 -2
- package/dist/sync/workspaceRepair.js +161 -6
- package/dist/sync/workspaceSyncModel.d.ts +21 -0
- package/dist/sync/workspaceSyncModel.js +35 -7
- package/dist/sync/workspaceSyncState.d.ts +1 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
- package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
- package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-BTM6nIg_.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-DabEG8L4.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-Coa8yVGM.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-BB0qhdix.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
- package/dist/ui/assets/{PlanningModule-B5DWQOGz.js → PlanningModule-pRPjR7v5.js} +1 -1
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-D86pZSSl.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-BVIkU9yT.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-CTsDBaef.js +7 -0
- package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
- package/dist/ui/branding/logos/letterhead_dark.png +0 -0
- package/dist/ui/branding/logos/letterhead_light.png +0 -0
- package/dist/ui/branding/logos/signature_dark.png +0 -0
- package/dist/ui/branding/logos/signature_light.png +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/aiProfileDefaultLogo.js +16 -48
- package/dist/utils/httpSetCookie.d.ts +1 -0
- package/dist/utils/httpSetCookie.js +4 -1
- package/dist/utils/localRuntimeUrl.d.ts +1 -0
- package/dist/utils/localRuntimeUrl.js +14 -0
- package/dist/utils/productLogoRegistry.d.ts +2 -0
- package/dist/utils/productLogoRegistry.js +36 -0
- package/dist/utils/syncStatusPresentation.d.ts +4 -0
- package/dist/utils/syncStatusPresentation.js +17 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +22 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-I5zhdtgt.js +0 -7
- package/dist/ui/assets/index-VRFsx3wz.css +0 -1
|
@@ -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
|
+
}
|
|
@@ -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';
|
|
@@ -1407,36 +1407,67 @@ export class LocalSyncExecutionPermitStore {
|
|
|
1407
1407
|
const requiredAction = mutationReplay
|
|
1408
1408
|
? 'replay-operation-then-reconcile'
|
|
1409
1409
|
: 'refetch-from-committed-cursor';
|
|
1410
|
-
const
|
|
1410
|
+
const coalescesLegacyApplyFailure = errorCode === 'WORKSPACE_SYNC_V3_APPLY_NOT_COMMITTED'
|
|
1411
1411
|
|| errorCode === 'WORKSPACE_SYNC_V3_ATTACHMENT_HYDRATION_NOT_COMMITTED';
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
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;
|
|
1430
1459
|
}
|
|
1460
|
+
if (inserted || !coalescingKey)
|
|
1461
|
+
return;
|
|
1431
1462
|
this.db.prepare(`
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
?
|
|
1440
|
-
|
|
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);
|
|
1441
1472
|
}
|
|
1442
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
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from '../../storage/databaseAdapter.js';
|
|
2
|
-
import type { WorkspaceSyncDeltaDiagnostics, WorkspaceSyncPayload } from '../workspaceSyncModel.js';
|
|
2
|
+
import type { WorkspaceSyncDeltaDiagnostics, WorkspaceSyncDurableTaskRevision, WorkspaceSyncPayload, WorkspaceSyncTaskSnapshot } from '../workspaceSyncModel.js';
|
|
3
3
|
import { type WorkspacePushPreparedPlan } from '../workspacePushPreparedPlan.js';
|
|
4
4
|
import type { WorkspaceSyncPhase, WorkspaceSyncPushBaselineSnapshot } from '../workspaceSyncState.js';
|
|
5
5
|
import type { LocalSyncCoordinatorCommandStatus } from './localSyncCoordinatorTypes.js';
|
|
@@ -30,6 +30,7 @@ export interface EncodedWorkspaceSyncPayload {
|
|
|
30
30
|
currentInitiativeWatermarks: EncodedStringMap;
|
|
31
31
|
currentWorkstreamIds: string[];
|
|
32
32
|
currentWorkstreamWatermarks: EncodedStringMap;
|
|
33
|
+
currentPlanningIdentityWatermarks?: EncodedStringMap;
|
|
33
34
|
currentAiProfileIds: string[];
|
|
34
35
|
currentAiProfileWatermarks: EncodedStringMap;
|
|
35
36
|
currentAiProfileChangeKeys?: EncodedStringMap;
|
|
@@ -68,8 +69,20 @@ export interface LocalWorkspaceSyncPendingV2Push {
|
|
|
68
69
|
preparedPlan: WorkspacePushPreparedPlan | null;
|
|
69
70
|
preparedPlanFingerprint: string | null;
|
|
70
71
|
acknowledgedNonApplyingBatchOperationIdentities: string[];
|
|
72
|
+
settlementVersion?: 1;
|
|
73
|
+
settledBatchOperationIdentities?: string[];
|
|
74
|
+
settledBatchContributions?: LocalWorkspaceSyncSettledV2PushBatch[];
|
|
71
75
|
lastBatchProgress: LocalWorkspaceSyncPendingV2PushBatchProgress | null;
|
|
72
76
|
}
|
|
77
|
+
export interface LocalWorkspaceSyncSettledV2PushBatch {
|
|
78
|
+
operationIdentity: string;
|
|
79
|
+
settlementIdentityFingerprint: string;
|
|
80
|
+
appliedTaskUpserts: Array<{
|
|
81
|
+
archived: boolean;
|
|
82
|
+
task: WorkspaceSyncTaskSnapshot;
|
|
83
|
+
durableRevision?: WorkspaceSyncDurableTaskRevision;
|
|
84
|
+
}>;
|
|
85
|
+
}
|
|
73
86
|
export interface LocalWorkspaceSyncPendingV2PushBatchProgress {
|
|
74
87
|
totalBatches: number;
|
|
75
88
|
completedBatches: number;
|
|
@@ -144,6 +157,7 @@ export declare function createLocalWorkspaceSyncPendingV2Push(input: {
|
|
|
144
157
|
repairMode: boolean;
|
|
145
158
|
}): LocalWorkspaceSyncPendingV2Push;
|
|
146
159
|
export declare function fingerprintLocalWorkspaceSyncPreparedPlan(plan: WorkspacePushPreparedPlan): string;
|
|
160
|
+
export declare function upgradeLocalWorkspaceSyncPendingV2PushSettlement(pending: LocalWorkspaceSyncPendingV2Push): LocalWorkspaceSyncPendingV2Push;
|
|
147
161
|
export declare function createDefaultLocalWorkspaceSyncRunnerCheckpoint(): LocalWorkspaceSyncRunnerCheckpoint;
|
|
148
162
|
export declare class LocalWorkspaceSyncRunnerStateStore {
|
|
149
163
|
private readonly db;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fingerprintWorkspaceSyncPayload, } from '../v3/syncDurabilityStore.js';
|
|
2
2
|
import { canonicalWorkspaceSyncJson } from '../v3/canonicalWorkspaceSyncJson.js';
|
|
3
3
|
import { WORKSPACE_SYNC_V2_EXCLUDABLE_PROJECTIONS, } from '../v3/workspaceSyncV2ProjectionExclusions.js';
|
|
4
|
+
import { createWorkspaceSyncEngineV2SettlementIdentityProjection } from '../engine/workspaceSyncEnginePushCompletion.js';
|
|
4
5
|
import { WORKSPACE_PUSH_PREPARED_PLAN_VERSION, } from '../workspacePushPreparedPlan.js';
|
|
5
6
|
import { LOCAL_SYNC_COORDINATOR_ID } from './localSyncCoordinatorTypes.js';
|
|
6
7
|
export const LOCAL_WORKSPACE_SYNC_RUNNER_STATE_VERSION = 1;
|
|
@@ -123,6 +124,7 @@ const ENCODED_PAYLOAD_OPTIONAL_KEYS = [
|
|
|
123
124
|
'currentTaskChangeKeys',
|
|
124
125
|
'currentTaskRelationshipChangeKeys',
|
|
125
126
|
'currentTaxonomyChangeKey',
|
|
127
|
+
'currentPlanningIdentityWatermarks',
|
|
126
128
|
'currentAiProfileChangeKeys',
|
|
127
129
|
'currentTaskforceAgentIds',
|
|
128
130
|
'currentTaskforceAgentWatermarks',
|
|
@@ -176,6 +178,7 @@ const OPTIONAL_DIAGNOSTIC_DOMAINS = [
|
|
|
176
178
|
'taskforceAgents',
|
|
177
179
|
'taskforceAgentSkills',
|
|
178
180
|
'agentConversations',
|
|
181
|
+
'planningIdentities',
|
|
179
182
|
];
|
|
180
183
|
function isDeltaDiagnostics(value) {
|
|
181
184
|
if (!isRecord(value) || !hasExactKeys(value, [
|
|
@@ -240,6 +243,7 @@ function isEncodedWorkspaceSyncPayload(value) {
|
|
|
240
243
|
'currentTaskWatermarks',
|
|
241
244
|
'currentTaskChangeKeys',
|
|
242
245
|
'currentTaskRelationshipChangeKeys',
|
|
246
|
+
'currentPlanningIdentityWatermarks',
|
|
243
247
|
'currentAiProfileChangeKeys',
|
|
244
248
|
'currentTaskforceAgentWatermarks',
|
|
245
249
|
'currentTaskforceAgentSkillWatermarks',
|
|
@@ -302,6 +306,7 @@ export function encodeWorkspaceSyncPayload(payload) {
|
|
|
302
306
|
currentInitiativeWatermarks: encodeStringMap(payload.currentInitiativeWatermarks, 'Initiative watermarks'),
|
|
303
307
|
currentWorkstreamIds: encodeStringSet(payload.currentWorkstreamIds, 'Current workstream ids'),
|
|
304
308
|
currentWorkstreamWatermarks: encodeStringMap(payload.currentWorkstreamWatermarks, 'Workstream watermarks'),
|
|
309
|
+
currentPlanningIdentityWatermarks: encodeStringMap(payload.currentPlanningIdentityWatermarks || new Map(), 'Planning identity watermarks'),
|
|
305
310
|
currentAiProfileIds: encodeStringSet(payload.currentAiProfileIds, 'Current AI profile ids'),
|
|
306
311
|
currentAiProfileWatermarks: encodeStringMap(payload.currentAiProfileWatermarks, 'AI profile watermarks'),
|
|
307
312
|
currentAiProfileChangeKeys: encodeOptionalStringMap(payload.currentAiProfileChangeKeys, 'AI profile change keys'),
|
|
@@ -356,6 +361,7 @@ export function decodeWorkspaceSyncPayload(encoded) {
|
|
|
356
361
|
currentInitiativeWatermarks: new Map(encoded.currentInitiativeWatermarks),
|
|
357
362
|
currentWorkstreamIds: new Set(encoded.currentWorkstreamIds),
|
|
358
363
|
currentWorkstreamWatermarks: new Map(encoded.currentWorkstreamWatermarks),
|
|
364
|
+
currentPlanningIdentityWatermarks: new Map(encoded.currentPlanningIdentityWatermarks || []),
|
|
359
365
|
currentAiProfileIds: new Set(encoded.currentAiProfileIds),
|
|
360
366
|
currentAiProfileWatermarks: new Map(encoded.currentAiProfileWatermarks),
|
|
361
367
|
currentAiProfileChangeKeys: encoded.currentAiProfileChangeKeys
|
|
@@ -411,6 +417,21 @@ export function createLocalWorkspaceSyncPendingV2Push(input) {
|
|
|
411
417
|
export function fingerprintLocalWorkspaceSyncPreparedPlan(plan) {
|
|
412
418
|
return fingerprintWorkspaceSyncPayload(plan);
|
|
413
419
|
}
|
|
420
|
+
export function upgradeLocalWorkspaceSyncPendingV2PushSettlement(pending) {
|
|
421
|
+
if (pending.settlementVersion === 1)
|
|
422
|
+
return structuredClone(pending);
|
|
423
|
+
if (!pending.preparedPlan || !pending.preparedPlanFingerprint) {
|
|
424
|
+
throw new Error('The frozen V2 push must have a prepared plan before settlement activation.');
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
...structuredClone(pending),
|
|
428
|
+
settlementVersion: 1,
|
|
429
|
+
settledBatchOperationIdentities: [
|
|
430
|
+
...pending.acknowledgedNonApplyingBatchOperationIdentities,
|
|
431
|
+
],
|
|
432
|
+
settledBatchContributions: [],
|
|
433
|
+
};
|
|
434
|
+
}
|
|
414
435
|
function isPushBaseline(value) {
|
|
415
436
|
if (!isRecord(value))
|
|
416
437
|
return false;
|
|
@@ -421,6 +442,7 @@ function isPushBaseline(value) {
|
|
|
421
442
|
'taskRelationshipChangeKeys',
|
|
422
443
|
'initiativeWatermarks',
|
|
423
444
|
'workstreamWatermarks',
|
|
445
|
+
'planningIdentityWatermarks',
|
|
424
446
|
'aiProfileWatermarks',
|
|
425
447
|
'aiProfileChangeKeys',
|
|
426
448
|
'taskforceAgentWatermarks',
|
|
@@ -458,6 +480,7 @@ function isPushBaseline(value) {
|
|
|
458
480
|
'taskforceAgentWatermarks',
|
|
459
481
|
'taskforceAgentSkillWatermarks',
|
|
460
482
|
'agentConversationWatermarks',
|
|
483
|
+
'planningIdentityWatermarks',
|
|
461
484
|
];
|
|
462
485
|
if (optionalPairs.some((key) => value[key] !== undefined && !isStringPairArray(value[key])))
|
|
463
486
|
return false;
|
|
@@ -470,7 +493,9 @@ function isPushBaseline(value) {
|
|
|
470
493
|
return true;
|
|
471
494
|
}
|
|
472
495
|
function isPendingV2Push(value) {
|
|
473
|
-
if (!isRecord(value)
|
|
496
|
+
if (!isRecord(value))
|
|
497
|
+
return false;
|
|
498
|
+
const legacyKeys = [
|
|
474
499
|
'signature',
|
|
475
500
|
'payloadFingerprint',
|
|
476
501
|
'frozenPayload',
|
|
@@ -480,8 +505,71 @@ function isPendingV2Push(value) {
|
|
|
480
505
|
'preparedPlanFingerprint',
|
|
481
506
|
'acknowledgedNonApplyingBatchOperationIdentities',
|
|
482
507
|
'lastBatchProgress',
|
|
483
|
-
]
|
|
508
|
+
];
|
|
509
|
+
const settlementKeys = [
|
|
510
|
+
...legacyKeys,
|
|
511
|
+
'settlementVersion',
|
|
512
|
+
'settledBatchOperationIdentities',
|
|
513
|
+
'settledBatchContributions',
|
|
514
|
+
];
|
|
515
|
+
const hasLegacyShape = hasExactKeys(value, legacyKeys);
|
|
516
|
+
const hasSettlementShape = hasExactKeys(value, settlementKeys);
|
|
517
|
+
if (!hasLegacyShape && !hasSettlementShape)
|
|
484
518
|
return false;
|
|
519
|
+
const settledBatchOperationIdentities = isStringArray(value.settledBatchOperationIdentities) ? value.settledBatchOperationIdentities : null;
|
|
520
|
+
const settledBatchContributions = Array.isArray(value.settledBatchContributions) ? value.settledBatchContributions : null;
|
|
521
|
+
const preparedPlan = isPreparedV2PushPlan(value.preparedPlan)
|
|
522
|
+
? value.preparedPlan
|
|
523
|
+
: null;
|
|
524
|
+
const settlementValid = hasLegacyShape || (value.settlementVersion === 1
|
|
525
|
+
&& settledBatchOperationIdentities !== null
|
|
526
|
+
&& new Set(settledBatchOperationIdentities).size
|
|
527
|
+
=== settledBatchOperationIdentities.length
|
|
528
|
+
&& settledBatchOperationIdentities.every((identity) => /^[a-f0-9]{64}$/.test(identity))
|
|
529
|
+
&& settledBatchContributions !== null
|
|
530
|
+
&& settledBatchContributions.every((entry) => (isRecord(entry)
|
|
531
|
+
&& hasExactKeys(entry, [
|
|
532
|
+
'operationIdentity',
|
|
533
|
+
'settlementIdentityFingerprint',
|
|
534
|
+
'appliedTaskUpserts',
|
|
535
|
+
])
|
|
536
|
+
&& typeof entry.operationIdentity === 'string'
|
|
537
|
+
&& /^[a-f0-9]{64}$/.test(entry.operationIdentity)
|
|
538
|
+
&& typeof entry.settlementIdentityFingerprint === 'string'
|
|
539
|
+
&& /^[a-f0-9]{64}$/.test(entry.settlementIdentityFingerprint)
|
|
540
|
+
&& Array.isArray(entry.appliedTaskUpserts)
|
|
541
|
+
&& entry.appliedTaskUpserts.every((upsert) => (isRecord(upsert)
|
|
542
|
+
&& hasRequiredAndAllowedKeys(upsert, ['archived', 'task'], ['durableRevision'])
|
|
543
|
+
&& typeof upsert.archived === 'boolean'
|
|
544
|
+
&& isRecord(upsert.task)
|
|
545
|
+
&& isNonEmptyText(upsert.task.id)
|
|
546
|
+
&& isJson(upsert.task)
|
|
547
|
+
&& (upsert.durableRevision === undefined
|
|
548
|
+
|| (isRecord(upsert.durableRevision) && isJson(upsert.durableRevision)))))))
|
|
549
|
+
&& new Set(settledBatchContributions.map((entry) => entry.operationIdentity)).size === settledBatchContributions.length
|
|
550
|
+
&& settledBatchContributions.every((entry) => (settledBatchOperationIdentities.includes(entry.operationIdentity))));
|
|
551
|
+
const settlementContributionsMatchPlan = hasLegacyShape || (preparedPlan !== null
|
|
552
|
+
&& settledBatchContributions !== null
|
|
553
|
+
&& settledBatchContributions.every((rawEntry) => {
|
|
554
|
+
const entry = rawEntry;
|
|
555
|
+
const batchIndex = preparedPlan.batchOperationIdentities.indexOf(entry.operationIdentity);
|
|
556
|
+
if (batchIndex < 0)
|
|
557
|
+
return false;
|
|
558
|
+
const changes = preparedPlan.batches[batchIndex].map((planEntry) => (planEntry.preparedChange
|
|
559
|
+
|| value.frozenPayload
|
|
560
|
+
.changes[planEntry.sourceChangeIndex]));
|
|
561
|
+
try {
|
|
562
|
+
return fingerprintWorkspaceSyncPayload(createWorkspaceSyncEngineV2SettlementIdentityProjection({
|
|
563
|
+
operationIdentity: entry.operationIdentity,
|
|
564
|
+
changes,
|
|
565
|
+
appliedTaskUpserts: entry.appliedTaskUpserts,
|
|
566
|
+
excludedProjections: preparedPlan.ownership.combinedExcludedProjections,
|
|
567
|
+
})) === entry.settlementIdentityFingerprint;
|
|
568
|
+
}
|
|
569
|
+
catch {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
}));
|
|
485
573
|
return isNonEmptyText(value.signature)
|
|
486
574
|
&& typeof value.payloadFingerprint === 'string'
|
|
487
575
|
&& /^[a-f0-9]{64}$/.test(value.payloadFingerprint)
|
|
@@ -499,6 +587,12 @@ function isPendingV2Push(value) {
|
|
|
499
587
|
< value.frozenPayload.changes.length))))
|
|
500
588
|
&& isStringArray(value.acknowledgedNonApplyingBatchOperationIdentities)
|
|
501
589
|
&& value.acknowledgedNonApplyingBatchOperationIdentities.every((identity) => /^[a-f0-9]{64}$/.test(identity))
|
|
590
|
+
&& settlementValid
|
|
591
|
+
&& settlementContributionsMatchPlan
|
|
592
|
+
&& (!hasSettlementShape
|
|
593
|
+
|| (preparedPlan !== null
|
|
594
|
+
&& settledBatchOperationIdentities !== null
|
|
595
|
+
&& settledBatchOperationIdentities.every((identity) => preparedPlan.batchOperationIdentities.includes(identity))))
|
|
502
596
|
&& (value.lastBatchProgress === null
|
|
503
597
|
|| (isPendingV2PushBatchProgress(value.lastBatchProgress)
|
|
504
598
|
&& value.lastBatchProgress.completedChanges <= value.frozenPayload.changes.length
|
|
@@ -582,6 +676,9 @@ function normalizePendingV2Push(value) {
|
|
|
582
676
|
'preparedPlan',
|
|
583
677
|
'preparedPlanFingerprint',
|
|
584
678
|
'acknowledgedNonApplyingBatchOperationIdentities',
|
|
679
|
+
'settlementVersion',
|
|
680
|
+
'settledBatchOperationIdentities',
|
|
681
|
+
'settledBatchContributions',
|
|
585
682
|
'lastBatchProgress',
|
|
586
683
|
])) {
|
|
587
684
|
return value;
|
|
@@ -43,6 +43,7 @@ export declare class WorkspaceSyncCredentialBrokerError extends Error {
|
|
|
43
43
|
export declare class WorkspaceSyncCredentialBroker {
|
|
44
44
|
private readonly options;
|
|
45
45
|
private capability;
|
|
46
|
+
private boundIdentity;
|
|
46
47
|
private blockedReason;
|
|
47
48
|
constructor(options: {
|
|
48
49
|
sessionCookieName: string;
|
|
@@ -12,6 +12,9 @@ export class WorkspaceSyncCredentialBrokerError extends Error {
|
|
|
12
12
|
export class WorkspaceSyncCredentialBroker {
|
|
13
13
|
options;
|
|
14
14
|
capability = null;
|
|
15
|
+
// Retain the non-secret principal fence while auth is blocked so a logout or
|
|
16
|
+
// expired cookie cannot let another account adopt the live coordinator.
|
|
17
|
+
boundIdentity = null;
|
|
15
18
|
blockedReason = 'server-restart';
|
|
16
19
|
constructor(options) {
|
|
17
20
|
this.options = options;
|
|
@@ -39,16 +42,21 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
39
42
|
throw new WorkspaceSyncCredentialBrokerError('The Taskforce session is not valid for the requested workspace.', 'SYNC_COORDINATOR_AUTH_INVALID');
|
|
40
43
|
}
|
|
41
44
|
const existing = this.capability;
|
|
45
|
+
const identity = existing || this.boundIdentity;
|
|
42
46
|
const samePrincipal = existing
|
|
43
47
|
&& existing.workspaceId === validated.workspaceId
|
|
44
48
|
&& existing.principal.userId === validated.principal.userId
|
|
45
49
|
&& existing.principal.tenantId === validated.principal.tenantId;
|
|
46
|
-
|
|
50
|
+
const sameBoundIdentity = identity
|
|
51
|
+
&& identity.workspaceId === validated.workspaceId
|
|
52
|
+
&& identity.principal.userId === validated.principal.userId
|
|
53
|
+
&& identity.principal.tenantId === validated.principal.tenantId;
|
|
54
|
+
if (identity && !sameBoundIdentity && !input.allowPrincipalRebind) {
|
|
47
55
|
throw new WorkspaceSyncCredentialBrokerError('A different Taskforce principal is already bound to this workspace coordinator.', 'SYNC_COORDINATOR_PRINCIPAL_CONFLICT');
|
|
48
56
|
}
|
|
49
|
-
if (
|
|
50
|
-
&& input.coordinatorGeneration <
|
|
51
|
-
throw new WorkspaceSyncCredentialBrokerError(`Coordinator generation ${input.coordinatorGeneration} is stale; current generation is ${
|
|
57
|
+
if (sameBoundIdentity
|
|
58
|
+
&& input.coordinatorGeneration < identity.coordinatorGeneration) {
|
|
59
|
+
throw new WorkspaceSyncCredentialBrokerError(`Coordinator generation ${input.coordinatorGeneration} is stale; current generation is ${identity.coordinatorGeneration}.`, 'SYNC_COORDINATOR_STALE_GENERATION');
|
|
52
60
|
}
|
|
53
61
|
const authorizedCookies = samePrincipal
|
|
54
62
|
? new Map(existing.authorizedCookies)
|
|
@@ -67,6 +75,11 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
67
75
|
cookieHeader,
|
|
68
76
|
authorizedCookies,
|
|
69
77
|
};
|
|
78
|
+
this.boundIdentity = {
|
|
79
|
+
workspaceId: validated.workspaceId,
|
|
80
|
+
coordinatorGeneration: input.coordinatorGeneration,
|
|
81
|
+
principal: validated.principal,
|
|
82
|
+
};
|
|
70
83
|
this.blockedReason = null;
|
|
71
84
|
return this.readSnapshot();
|
|
72
85
|
}
|
|
@@ -143,6 +156,11 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
143
156
|
cookieHeader: prepared.cookieHeader,
|
|
144
157
|
authorizedCookies: new Map([[cookieValue, prepared.validation]]),
|
|
145
158
|
};
|
|
159
|
+
this.boundIdentity = {
|
|
160
|
+
workspaceId: prepared.targetWorkspaceId,
|
|
161
|
+
coordinatorGeneration: prepared.targetCoordinatorGeneration,
|
|
162
|
+
principal: prepared.principal,
|
|
163
|
+
};
|
|
146
164
|
prepared.activated = true;
|
|
147
165
|
this.blockedReason = null;
|
|
148
166
|
return this.readSnapshot();
|
|
@@ -159,6 +177,11 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
159
177
|
coordinatorGeneration,
|
|
160
178
|
authorizedCookies: new Map(prepared.sourceCapability.authorizedCookies),
|
|
161
179
|
};
|
|
180
|
+
this.boundIdentity = {
|
|
181
|
+
workspaceId: prepared.sourceWorkspaceId,
|
|
182
|
+
coordinatorGeneration,
|
|
183
|
+
principal: prepared.sourceCapability.principal,
|
|
184
|
+
};
|
|
162
185
|
prepared.activated = false;
|
|
163
186
|
this.blockedReason = null;
|
|
164
187
|
}
|
|
@@ -175,6 +198,9 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
175
198
|
throw new WorkspaceSyncCredentialBrokerError('The coordinator generation transition is invalid.', 'SYNC_COORDINATOR_STALE_GENERATION');
|
|
176
199
|
}
|
|
177
200
|
this.capability.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
201
|
+
if (this.boundIdentity) {
|
|
202
|
+
this.boundIdentity.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
203
|
+
}
|
|
178
204
|
return this.readSnapshot();
|
|
179
205
|
}
|
|
180
206
|
/**
|
|
@@ -197,6 +223,9 @@ export class WorkspaceSyncCredentialBroker {
|
|
|
197
223
|
throw new WorkspaceSyncCredentialBrokerError('The coordinator generation transition is stale or non-adjacent.', 'SYNC_COORDINATOR_STALE_GENERATION');
|
|
198
224
|
}
|
|
199
225
|
capability.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
226
|
+
if (this.boundIdentity) {
|
|
227
|
+
this.boundIdentity.coordinatorGeneration = input.toCoordinatorGeneration;
|
|
228
|
+
}
|
|
200
229
|
return this.readSnapshot();
|
|
201
230
|
}
|
|
202
231
|
authorizeCookieHeader(input) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type WorkspaceSyncContentHead, type WorkspaceSyncContentKind, type WorkspaceSyncContentScope, type WorkspaceSyncContentVersionStore } from './workspaceSyncContentVersionStore.js';
|
|
1
|
+
import { type WorkspaceSyncContentHead, type WorkspaceSyncContentKind, type WorkspaceSyncContentScope, type WorkspaceSyncContentTombstoneProvenance, type WorkspaceSyncContentVersionStore } from './workspaceSyncContentVersionStore.js';
|
|
2
2
|
export type WorkspaceSyncContentTombstoneInput = WorkspaceSyncContentScope & {
|
|
3
3
|
kind: WorkspaceSyncContentKind;
|
|
4
4
|
logicalPath: string;
|
|
@@ -6,6 +6,7 @@ export type WorkspaceSyncContentTombstoneInput = WorkspaceSyncContentScope & {
|
|
|
6
6
|
publishedAt: string;
|
|
7
7
|
deletedAt: string;
|
|
8
8
|
retireGcAfter?: string | null;
|
|
9
|
+
provenance?: WorkspaceSyncContentTombstoneProvenance;
|
|
9
10
|
};
|
|
10
11
|
export interface WorkspaceSyncContentLifecyclePort {
|
|
11
12
|
tombstone(input: WorkspaceSyncContentTombstoneInput): WorkspaceSyncContentHead;
|
|
@@ -48,6 +48,36 @@ export type WorkspaceSyncContentHead = WorkspaceSyncContentScope & {
|
|
|
48
48
|
publishedAt: string;
|
|
49
49
|
deletedAt: string | null;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Durable, queryable attribution for an accepted content tombstone. operationId/
|
|
53
|
+
* actorId are optional because the current WorkspaceSyncChange wire format and
|
|
54
|
+
* apply pipeline don't yet carry per-change requester identity from origin
|
|
55
|
+
* through to this layer — threading that through is a larger, separate change
|
|
56
|
+
* (it would mean extending the delete-change payload and every intermediate
|
|
57
|
+
* outbox/apply layer, not just this store). What IS reliably knowable at the
|
|
58
|
+
* point a tombstone is admitted is recorded: which admission path produced it,
|
|
59
|
+
* the source revision it was admitted at, which runtime applied it, and
|
|
60
|
+
* whether workspace repair was involved.
|
|
61
|
+
*/
|
|
62
|
+
export type WorkspaceSyncContentTombstoneProvenance = {
|
|
63
|
+
source: 'explicit-delete' | 'synchronized-tombstone' | 'repair';
|
|
64
|
+
operationId?: string | null;
|
|
65
|
+
actorId?: string | null;
|
|
66
|
+
sourceRuntime?: string | null;
|
|
67
|
+
repairInvolved?: boolean;
|
|
68
|
+
};
|
|
69
|
+
export type WorkspaceSyncContentTombstoneProvenanceRecord = WorkspaceSyncContentScope & {
|
|
70
|
+
id: string;
|
|
71
|
+
kind: WorkspaceSyncContentKind;
|
|
72
|
+
logicalPath: string;
|
|
73
|
+
source: string;
|
|
74
|
+
operationId: string | null;
|
|
75
|
+
actorId: string | null;
|
|
76
|
+
sourceRuntime: string | null;
|
|
77
|
+
sourceUpdatedAt: string;
|
|
78
|
+
repairInvolved: boolean;
|
|
79
|
+
recordedAt: string;
|
|
80
|
+
};
|
|
51
81
|
export type WorkspaceSyncContentLegacyFallback = {
|
|
52
82
|
source: 'legacy';
|
|
53
83
|
};
|
|
@@ -141,7 +171,15 @@ export declare class WorkspaceSyncContentVersionStore {
|
|
|
141
171
|
publishedAt: string;
|
|
142
172
|
deletedAt: string;
|
|
143
173
|
retireGcAfter?: string | null;
|
|
174
|
+
provenance?: WorkspaceSyncContentTombstoneProvenance;
|
|
144
175
|
}): WorkspaceSyncContentHead;
|
|
176
|
+
private recordTombstoneProvenance;
|
|
177
|
+
/** Queryable read side for tombstone provenance — most recent admission first. */
|
|
178
|
+
listTombstoneProvenance(input: WorkspaceSyncContentScope & {
|
|
179
|
+
kind?: WorkspaceSyncContentKind;
|
|
180
|
+
logicalPath?: string;
|
|
181
|
+
limit?: number;
|
|
182
|
+
}): WorkspaceSyncContentTombstoneProvenanceRecord[];
|
|
145
183
|
resolveHead(input: WorkspaceSyncContentScope & {
|
|
146
184
|
kind: WorkspaceSyncContentKind;
|
|
147
185
|
logicalPath: string;
|