@taskforcehq/taskforce 0.3.329 → 0.3.332
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/dist/Taskforce.module.css +290 -45
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/TaskSettings.js +70 -14
- package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
- package/dist/components/features/TaskforceAgentsModule.js +586 -116
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
- package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
- package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
- package/dist/components/features/planning/PlanningModule.js +15 -3
- package/dist/components/features/planning/planningMetadata.d.ts +10 -0
- package/dist/components/features/planning/planningMetadata.js +8 -0
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/views/StandaloneLayout.js +62 -27
- package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
- package/dist/components/views/panels/PlanningDrawer.js +12 -8
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
- package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
- package/dist/config/envSchema.js +55 -1
- package/dist/core/McpTokenService.d.ts +25 -1
- package/dist/core/McpTokenService.js +106 -15
- package/dist/core/TaskChecklistCommandService.d.ts +27 -0
- package/dist/core/TaskChecklistCommandService.js +83 -5
- package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
- package/dist/core/TaskLifecycleCommandService.js +6 -2
- package/dist/core/Taskforce.d.ts +43 -3
- package/dist/core/Taskforce.js +158 -7
- package/dist/core/types.d.ts +9 -0
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
- package/dist/documentReviews/commandService.d.ts +2 -1
- package/dist/documentReviews/commandService.js +6 -3
- package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.js +2 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
- package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
- package/dist/hooks/sync/useSyncStatusControls.js +47 -11
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +31 -1
- package/dist/hooks/useTaskData.js +29 -7
- package/dist/hooks/useTaskMutations.d.ts +3 -1
- package/dist/hooks/useTaskMutations.js +46 -12
- package/dist/hooks/useTaskforce.d.ts +2 -0
- package/dist/hooks/useTaskforce.js +11 -2
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +9 -6
- package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
- package/dist/mcp/durableTaskMutationRouter.js +10 -0
- package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
- package/dist/mcp/httpProtocolRouting.d.ts +11 -0
- package/dist/mcp/httpProtocolRouting.js +22 -0
- package/dist/mcp/localCliHealth.d.ts +2 -2
- package/dist/mcp/localCliHealth.js +2 -2
- package/dist/mcp/localServiceProxy.d.ts +1 -0
- package/dist/mcp/localServiceProxy.js +530 -68
- package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
- package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
- package/dist/mcp/runtime.d.ts +54 -79
- package/dist/mcp/runtime.js +408 -102
- package/dist/mcp/taskPlanningRegistrar.js +25 -6
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +11 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +9 -8
- package/dist/mcp/workflowExecutionRegistrar.js +4 -4
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +415 -0
- package/dist/runtime/appGates.d.ts +2 -1
- package/dist/runtime/appGates.js +7 -0
- package/dist/server/buildInfo.d.ts +1 -0
- package/dist/server/buildInfo.js +5 -1
- package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
- package/dist/server/cloudMcpCapacityTelemetry.js +221 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +108 -11
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.js +2 -1
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +25 -19
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +126 -5
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +277 -24
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
- package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
- package/dist/server/routes/executorPhaseAApprovals.js +140 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
- package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
- package/dist/server/routes/githubReviewEvidence.js +116 -0
- package/dist/server/routes/localService.d.ts +15 -4
- package/dist/server/routes/localService.js +136 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/shared.d.ts +22 -0
- package/dist/server/routes/shared.js +298 -182
- package/dist/server/routes/sync.js +1 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -1
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +10 -1
- package/dist/server/routes/syncV3OperationRoutes.js +35 -9
- package/dist/server/routes/tasks.js +21 -2
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes.js +59 -0
- package/dist/service/localServiceCli.d.ts +2 -2
- package/dist/service/localServiceCli.js +4 -3
- package/dist/services/codexAppServerModelGateway.d.ts +54 -5
- package/dist/services/codexAppServerModelGateway.js +246 -21
- package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
- package/dist/services/codexDeviceCodeLoginManager.js +265 -0
- package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
- package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
- package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
- package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
- package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
- package/dist/services/executorPhaseAApprovalService.js +609 -0
- package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
- package/dist/services/executorPhaseADriftEvaluator.js +93 -0
- package/dist/services/executorPhaseAIssuerCore.d.ts +139 -0
- package/dist/services/executorPhaseAIssuerCore.js +402 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
- package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
- package/dist/services/githubReviewEvidenceRuntime.js +30 -0
- package/dist/services/githubReviewEvidenceService.d.ts +93 -0
- package/dist/services/githubReviewEvidenceService.js +336 -0
- package/dist/services/modelGateway.d.ts +7 -0
- package/dist/services/modelProviderConnectionService.d.ts +71 -0
- package/dist/services/modelProviderConnectionService.js +279 -0
- package/dist/services/modelProviderCredentialHome.d.ts +32 -0
- package/dist/services/modelProviderCredentialHome.js +271 -0
- package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
- package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
- package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
- package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +2 -2
- package/dist/services/taskforceAgentMcpBridge.js +42 -29
- package/dist/shared/adminEdgeProxy.d.ts +5 -0
- package/dist/shared/adminEdgeProxy.js +94 -0
- package/dist/shared/adminProxySessionCookies.d.ts +16 -0
- package/dist/shared/adminProxySessionCookies.js +86 -0
- package/dist/shared/aiProfileColors.d.ts +31 -1
- package/dist/shared/aiProfileColors.js +14 -6
- package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
- package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
- package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
- package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
- package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
- package/dist/shared/executorPhaseADriftContracts.js +63 -0
- package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
- package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
- package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
- package/dist/shared/executorPhaseARunAuthorization.js +232 -0
- package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
- package/dist/shared/executorPhaseASchemaValidation.js +53 -0
- package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
- package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
- package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
- package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
- package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
- package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
- package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
- package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
- package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
- package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
- package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
- package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
- package/dist/shared/executorPhaseATiming.d.ts +1 -0
- package/dist/shared/executorPhaseATiming.js +1 -0
- package/dist/shared/planningIdentity.js +1 -1
- package/dist/shared/productLogoKeys.d.ts +2 -0
- package/dist/shared/productLogoKeys.js +18 -0
- package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
- package/dist/shared/taskforceAgentDefinition.js +6 -9
- package/dist/shared/taskforceAgentModels.js +7 -3
- package/dist/shared/userFeatureGrants.d.ts +4 -0
- package/dist/shared/userFeatureGrants.js +7 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
- package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
- package/dist/storage/modelProviderConnectionStore.js +446 -0
- package/dist/storage/postgresAdapter.d.ts +4 -0
- package/dist/storage/postgresAdapter.js +14 -1
- package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
- package/dist/storage/postgresRequestDiagnostics.js +15 -2
- package/dist/storage/postgresWorker.js +20 -2
- package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/storage/workflowStore.d.ts +2 -0
- package/dist/storage/workflowStore.js +39 -2
- package/dist/sync/cloudSyncApi.js +4 -2
- package/dist/sync/collaborationSyncState.js +5 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +3 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
- package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
- package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
- package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
- package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +31 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -0
- package/dist/sync/syncApplyHandlers.js +81 -15
- package/dist/sync/syncService.d.ts +15 -0
- package/dist/sync/syncService.js +83 -18
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
- package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
- package/dist/sync/v3/durableOperationReplay.js +18 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
- package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +18 -7
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
- package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
- package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
- package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
- package/dist/sync/v3/localOutboxRecoveryPreparationService.js +8 -2
- package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
- package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
- package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
- package/dist/sync/v3/localTaskCreateOutboxService.d.ts +3 -1
- package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
- package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
- package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
- package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
- package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
- package/dist/sync/v3/syncDurabilityStore.js +202 -8
- package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
- package/dist/sync/v3/taskChecklistMutationService.js +44 -1
- package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
- package/dist/sync/v3/taskStatusMutationService.js +119 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
- package/dist/sync/v3/workflowAssignmentSync.js +27 -0
- package/dist/sync/v3/workflowRuntimeMutationService.d.ts +5 -0
- package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
- package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
- package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
- package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +25 -3
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3Feed.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
- package/dist/sync/workspaceRepair.d.ts +5 -2
- package/dist/sync/workspaceRepair.js +161 -6
- package/dist/sync/workspaceSyncModel.d.ts +21 -0
- package/dist/sync/workspaceSyncModel.js +35 -7
- package/dist/sync/workspaceSyncState.d.ts +1 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
- package/dist/ui/assets/AiIdentityRosterCard-CDMPtnbC.js +1 -0
- package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
- package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-DSQINwt9.js +7 -0
- package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
- package/dist/ui/branding/logos/letterhead_dark.png +0 -0
- package/dist/ui/branding/logos/letterhead_light.png +0 -0
- package/dist/ui/branding/logos/signature_dark.png +0 -0
- package/dist/ui/branding/logos/signature_light.png +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/aiProfileDefaultLogo.js +16 -48
- package/dist/utils/httpSetCookie.d.ts +1 -0
- package/dist/utils/httpSetCookie.js +4 -1
- package/dist/utils/localRuntimeUrl.d.ts +1 -0
- package/dist/utils/localRuntimeUrl.js +14 -0
- package/dist/utils/productLogoRegistry.d.ts +2 -0
- package/dist/utils/productLogoRegistry.js +36 -0
- package/dist/utils/syncStatusPresentation.d.ts +4 -0
- package/dist/utils/syncStatusPresentation.js +17 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +24 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/PlanningModule-B5DWQOGz.js +0 -1
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-I5zhdtgt.js +0 -7
- package/dist/ui/assets/index-VRFsx3wz.css +0 -1
package/dist/config/envSchema.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveDeploymentConfig } from './deployment.js';
|
|
2
2
|
import { MIGRATION_COMPAT_ENABLED } from '../runtime/migrationFlags.js';
|
|
3
3
|
import { parseWorkspaceSyncV3FeedCursorKeyring } from '../sync/v3/workspaceSyncV3FeedCursorKeys.js';
|
|
4
|
+
import { resolveExecutorPhaseAApprovalSigningConfig } from '../services/executorPhaseAApprovalService.js';
|
|
4
5
|
const SPECS = [
|
|
5
6
|
{ key: 'PORT', description: 'Standalone server port.', category: 'Core', defaultValue: '8080', targets: ['server', 'all'] },
|
|
6
7
|
{ key: 'TASKFORCE_TENANT_ID', description: 'Tenant identifier.', category: 'Core', defaultValue: 'default', targets: ['server', 'all'] },
|
|
@@ -66,7 +67,7 @@ const SPECS = [
|
|
|
66
67
|
{ key: 'TASKFORCE_SYNC_V3_LOCAL_FEED_APPLY_ENABLED', description: 'Enable the local-only atomic v3 initiative feed apply boundary.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
67
68
|
{ key: 'TASKFORCE_SYNC_V3_COMBINED_FEED_ENABLED', description: 'Expose registered task-planning-metadata cloud feed and repair contracts.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
68
69
|
{ key: 'TASKFORCE_SYNC_V3_COMBINED_FEED_ACTIVATION_ENABLED', description: 'Request combined coordinator activation; activation still requires exact local prerequisites and a matching ready cloud capability attestation.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
69
|
-
{ key: 'TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION', description: 'Request a frozen combined-feed coverage profile by registered version. Omit for version 3; version 4 adds nested task and entity-event coverage; version 5 adds workflow runtime coverage; version 6
|
|
70
|
+
{ key: 'TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION', description: 'Request a frozen combined-feed coverage profile by registered version. Omit for version 3; version 4 adds nested task and entity-event coverage; version 5 adds workflow runtime coverage; version 6 adds workstream task order; version 7 adds explicit task card covers; version 8 composes workflow runtime with version 7.', category: 'Core', defaultValue: '3', targets: ['server', 'all'] },
|
|
70
71
|
{ key: 'TASKFORCE_SYNC_V3_COMBINED_LOCAL_FEED_APPLY_ENABLED', description: 'Enable local atomic apply for registered task-planning-metadata coverage profiles.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
71
72
|
{ key: 'TASKFORCE_SYNC_V3_COMBINED_LEGACY_FENCE_ENABLED', description: 'Configure the combined stale-v2 fence; it becomes effective only after every covered cloud HTTP and MCP writer boundary is ready.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
72
73
|
{ key: 'TASKFORCE_SYNC_V3_NESTED_LEGACY_FENCE_ENABLED', description: 'Fence the four v4-only legacy projections after every nested cloud writer boundary is ready.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
@@ -75,6 +76,7 @@ const SPECS = [
|
|
|
75
76
|
{ key: 'TASKFORCE_SYNC_V3_WORKFLOW_RUNTIME_DISPATCH_ENABLED', description: 'Enable local durable workflow runtime outbox dispatch when the shared dispatcher is enabled.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
76
77
|
{ key: 'TASKFORCE_SYNC_V3_WORKFLOW_RUNTIME_HTTP_ACTIVATION_ENABLED', description: 'Route workflow runtime HTTP commands through durable v3 acceptance or local capture.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
77
78
|
{ key: 'TASKFORCE_SYNC_V3_WORKFLOW_RUNTIME_MCP_ACTIVATION_ENABLED', description: 'Route workflow runtime MCP commands through durable v3 acceptance or local capture.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
79
|
+
{ key: 'TASKFORCE_SYNC_V3_WORKFLOW_RUNTIME_MUTATIONS_FENCED', description: 'Temporarily reject workflow execution mutations during projection rollback.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
78
80
|
{ key: 'TASKFORCE_SYNC_V3_WORKFLOW_RUNTIME_CARRIER_COEXISTENCE_ENABLED', description: 'Acknowledge that task-status workflow activation remains the v5 bootstrap and rollback carrier.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
79
81
|
{ key: 'TASKFORCE_SYNC_V3_WORKSTREAM_TASK_ORDER_ENABLED', description: 'Enable cloud acceptance for durable v3 workstream task-order operations.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
80
82
|
{ key: 'TASKFORCE_SYNC_V3_WORKSTREAM_TASK_ORDER_CAPTURE_ENABLED', description: 'Enable local durable workstream task-order capture when the shared local capture and dispatch boundaries are enabled.', category: 'Core', defaultValue: 'false', targets: ['server', 'all'] },
|
|
@@ -89,6 +91,10 @@ const SPECS = [
|
|
|
89
91
|
{ key: 'TASKFORCE_AUTH_EXCLUDED_PATHS', description: 'Comma-separated API paths excluded from auth checks.', category: 'Auth', defaultValue: '/api/taskforce/health,/api/taskforce/version,/api/taskforce/auth,/api/taskforce/public/pricing,/api/taskforce/public/site-config,/api/taskforce/public/site-config-script', targets: ['server', 'all'] },
|
|
90
92
|
{ key: 'TASKFORCE_AUTH_DEFAULT_ROLE', description: 'Default role for unauthenticated context (owner|admin|member|read-only).', category: 'Auth', defaultValue: 'member', targets: ['server', 'all'] },
|
|
91
93
|
{ key: 'TASKFORCE_AUTH_SESSION_COOKIE', description: 'Session cookie name.', category: 'Auth', defaultValue: 'taskforce_session', targets: ['server', 'all'] },
|
|
94
|
+
{ key: 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE', description: 'Upstream cloud session cookie name used by every admin proxy target unless overridden per environment.', category: 'Auth', defaultValue: 'taskforce_session', targets: ['server', 'all'] },
|
|
95
|
+
{ key: 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_PRODUCTION', description: 'Optional Production upstream session cookie name override for the admin proxy.', category: 'Auth', targets: ['server', 'all'] },
|
|
96
|
+
{ key: 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_STAGING', description: 'Optional Staging upstream session cookie name override for the admin proxy.', category: 'Auth', targets: ['server', 'all'] },
|
|
97
|
+
{ key: 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_PERFORMANCE', description: 'Optional Performance upstream session cookie name override for the admin proxy.', category: 'Auth', targets: ['server', 'all'] },
|
|
92
98
|
{ key: 'TASKFORCE_AUTH_SESSION_SECRET', description: 'Session signing secret.', category: 'Auth', secret: true, targets: ['server', 'all'] },
|
|
93
99
|
{ key: 'TASKFORCE_AUTH_SESSION_TTL_SECONDS', description: 'Session max age in seconds.', category: 'Auth', defaultValue: '2592000', targets: ['server', 'all'] },
|
|
94
100
|
{ key: 'TASKFORCE_AUTH_SESSION_SAMESITE', description: 'SameSite policy (Lax|Strict|None).', category: 'Auth', defaultValue: 'None', targets: ['server', 'all'] },
|
|
@@ -146,6 +152,7 @@ const SPECS = [
|
|
|
146
152
|
{ key: 'TASKFORCE_AGENT_SUBSCRIPTION_DEV_MODELS', description: 'Enable internal local-development-only Taskforce Agent subscription-auth model adapters such as OpenAI Codex app-server.', category: 'AI', defaultValue: 'false', targets: ['server', 'all'] },
|
|
147
153
|
{ key: 'TASKFORCE_CODEX_APP_SERVER_COMMAND', description: 'Optional Codex CLI command path for the internal OpenAI Codex app-server Taskforce Agent adapter.', category: 'AI', defaultValue: 'codex', targets: ['server', 'all'] },
|
|
148
154
|
{ key: 'TASKFORCE_CODEX_APP_SERVER_CWD', description: 'Optional working directory for the internal Codex app-server subprocess. Defaults to the system temp directory.', category: 'AI', targets: ['server', 'all'] },
|
|
155
|
+
{ key: 'TASKFORCE_MODEL_CONNECTION_STORAGE_PATH', description: 'Restricted durable volume root for isolated user-owned model provider credential homes.', category: 'AI', targets: ['server', 'all'] },
|
|
149
156
|
{ key: 'TASKFORCE_ALLOWED_ORIGINS', description: 'Allowed CORS origins (comma-separated).', category: 'Security', targets: ['server', 'all'] },
|
|
150
157
|
{ key: 'TASKFORCE_API_RATE_LIMIT_ENABLED', description: 'Enable API rate limiter.', category: 'Security', defaultValue: 'true', targets: ['server', 'all'] },
|
|
151
158
|
{ key: 'TASKFORCE_API_RATE_LIMIT_MAX_REQUESTS', description: 'API rate limit max requests per window.', category: 'Security', defaultValue: '120', targets: ['server', 'all'] },
|
|
@@ -165,6 +172,18 @@ const SPECS = [
|
|
|
165
172
|
{ key: 'TASKFORCE_ADMIN_AUDIT_SYNC_RETENTION_DAYS', description: 'Retention period for non-routine sync audit failures and exceptional events.', category: 'Security', defaultValue: '30', targets: ['server', 'all'] },
|
|
166
173
|
{ key: 'TASKFORCE_ADMIN_AUDIT_RETENTION_DAYS', description: 'Default retention period for administrative and security audit events.', category: 'Security', defaultValue: '365', targets: ['server', 'all'] },
|
|
167
174
|
{ key: 'TASKFORCE_SYNC_KEY', description: 'Optional sync encryption key.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
175
|
+
{ key: 'TASKFORCE_GITHUB_APP_ID', description: 'GitHub App identifier for the Taskforce GitHub integration.', category: 'Security', targets: ['server', 'all'] },
|
|
176
|
+
{ key: 'TASKFORCE_GITHUB_APP_PRIVATE_KEY_BASE64', description: 'Base64-encoded private key for the Taskforce GitHub App.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
177
|
+
{ key: 'TASKFORCE_GITHUB_APP_SLUG', description: 'Public slug for the Taskforce GitHub App.', category: 'Security', targets: ['server', 'all'] },
|
|
178
|
+
{ key: 'TASKFORCE_GITHUB_APP_CLIENT_ID', description: 'OAuth client identifier for the Taskforce GitHub App.', category: 'Security', targets: ['server', 'all'] },
|
|
179
|
+
{ key: 'TASKFORCE_GITHUB_APP_CLIENT_SECRET', description: 'OAuth client secret for the Taskforce GitHub App.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
180
|
+
{ key: 'TASKFORCE_GITHUB_APP_WEBHOOK_SECRET', description: 'Webhook signature secret for the Taskforce GitHub App.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
181
|
+
{ key: 'TASKFORCE_GITHUB_REVIEW_APP_ID', description: 'GitHub App identifier used for private-repository review evidence.', category: 'Security', targets: ['server', 'all'] },
|
|
182
|
+
{ key: 'TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64', description: 'Base64-encoded GitHub App private key used only to mint short-lived installation tokens.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
183
|
+
{ key: 'TASKFORCE_PHASE_A_APPROVAL_ISSUER_ENABLED', description: 'Enable performance-cloud Phase A approval receipt issuance.', category: 'Security', defaultValue: 'false', targets: ['server', 'all'] },
|
|
184
|
+
{ key: 'TASKFORCE_PHASE_A_ISSUER_REDEMPTION_ENABLED', description: 'Expose the disabled performance-cloud Phase A issuer redemption boundary.', category: 'Security', defaultValue: 'false', targets: ['server', 'all'] },
|
|
185
|
+
{ key: 'TASKFORCE_PHASE_A_APPROVAL_SIGNING_KEY_ID', description: 'Active source-pinned Ed25519 key ID for performance Phase A approval receipts.', category: 'Security', targets: ['server', 'all'] },
|
|
186
|
+
{ key: 'TASKFORCE_PHASE_A_APPROVAL_SIGNING_PRIVATE_KEY_PKCS8_BASE64', description: 'Base64-encoded PKCS#8 Ed25519 private key for performance Phase A approval receipts.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
168
187
|
{ key: 'TASKFORCE_STRIPE_SECRET_KEY', description: 'Stripe secret API key used by server-side billing routes.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
169
188
|
{ key: 'TASKFORCE_STRIPE_WEBHOOK_SECRET', description: 'Stripe webhook signing secret used to verify incoming webhooks.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
170
189
|
{ key: 'TASKFORCE_BUILD_VERSION', description: 'Build version metadata.', category: 'Build', targets: ['server', 'all'] },
|
|
@@ -193,6 +212,7 @@ const SPECS = [
|
|
|
193
212
|
{ key: 'SYNC_SOAK_DURATION_MIN', description: 'Soak duration in minutes.', category: 'Soak', defaultValue: '60', targets: ['soak', 'all'] },
|
|
194
213
|
{ key: 'SYNC_SOAK_SEED', description: 'Deterministic soak seed.', category: 'Soak', example: '4242', targets: ['soak', 'all'] },
|
|
195
214
|
{ key: 'SYNC_SOAK_TASK_ID_NAMESPACE', description: 'Optional per-run namespace for deterministic generated soak task IDs.', category: 'Soak', targets: ['soak', 'all'] },
|
|
215
|
+
{ key: 'SYNC_SOAK_RUNTIME_ROOT', description: 'Root directory for isolated local soak runtimes and cleanup verification.', category: 'Soak', targets: ['soak', 'all'] },
|
|
196
216
|
{ key: 'SYNC_SOAK_ARTIFACT_DIR', description: 'Soak artifacts output directory.', category: 'Soak', defaultValue: '.taskforce/soak-artifacts', targets: ['soak', 'all'] },
|
|
197
217
|
{ key: 'SYNC_SOAK_ENABLE_SYNC_DEBUG', description: 'Enable sync debug diagnostics during soak.', category: 'Soak', defaultValue: 'false', targets: ['soak', 'all'] },
|
|
198
218
|
{ key: 'SYNC_SOAK_STRESS_ACTIONS', description: 'Stress action count.', category: 'Soak', defaultValue: '150', targets: ['soak', 'all'] },
|
|
@@ -206,6 +226,8 @@ const SPECS = [
|
|
|
206
226
|
{ key: 'SYNC_SOAK_OVERNIGHT_MAX_ACTIONS', description: 'Overnight hard cap on action count.', category: 'Soak', defaultValue: '10000', targets: ['soak', 'all'] },
|
|
207
227
|
{ key: 'SYNC_SOAK_OVERNIGHT_MIN_ACTIONS', description: 'Overnight minimum actions expected before pass.', category: 'Soak', defaultValue: '80', targets: ['soak', 'all'] },
|
|
208
228
|
{ key: 'SYNC_SOAK_OVERNIGHT_CLEAN_BASELINE_EVERY_ACTION', description: 'Require coordinator settlement before each accelerated overnight action.', category: 'Soak', defaultValue: 'false', targets: ['soak', 'all'] },
|
|
229
|
+
{ key: 'SYNC_SOAK_SERVER_FAULT_PROFILE', description: 'Deterministic server-owned sync transport fault profile (none|operation-response-loss-once).', category: 'Soak', defaultValue: 'none', targets: ['soak', 'all'] },
|
|
230
|
+
{ key: 'SYNC_SOAK_CLEAN_BASELINE_TIMEOUT_MS', description: 'Bounded wait for coordinator recovery and clean-baseline settlement.', category: 'Soak', defaultValue: '180000', targets: ['soak', 'all'] },
|
|
209
231
|
{ key: 'CF_ACCESS_CLIENT_ID', description: 'Cloudflare Access service token client id (soak).', category: 'Cloudflare', secret: true, targets: ['soak', 'all'] },
|
|
210
232
|
{ key: 'CF_ACCESS_CLIENT_SECRET', description: 'Cloudflare Access service token client secret (soak).', category: 'Cloudflare', secret: true, targets: ['soak', 'all'] }
|
|
211
233
|
];
|
|
@@ -357,6 +379,38 @@ function validateServerEnv(env, errors, warnings) {
|
|
|
357
379
|
if (provider === 'postgres' && !hasValue(env, 'TASKFORCE_DATABASE_URL')) {
|
|
358
380
|
errors.push('TASKFORCE_DATABASE_URL is required when TASKFORCE_DB_PROVIDER=postgres.');
|
|
359
381
|
}
|
|
382
|
+
const hasGitHubReviewAppId = hasValue(env, 'TASKFORCE_GITHUB_REVIEW_APP_ID');
|
|
383
|
+
const hasGitHubReviewPrivateKey = hasValue(env, 'TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64');
|
|
384
|
+
if (hasGitHubReviewAppId !== hasGitHubReviewPrivateKey) {
|
|
385
|
+
errors.push('TASKFORCE_GITHUB_REVIEW_APP_ID and TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64 must be configured together.');
|
|
386
|
+
}
|
|
387
|
+
if (hasGitHubReviewPrivateKey) {
|
|
388
|
+
const encoded = String(env.TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64 || '').trim();
|
|
389
|
+
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
|
|
390
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(encoded) || !decoded.includes('-----BEGIN') || !decoded.includes('PRIVATE KEY-----')) {
|
|
391
|
+
errors.push('TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64 must contain a base64-encoded PEM private key.');
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const phaseAIssuerEnabled = parseBoolean(env.TASKFORCE_PHASE_A_APPROVAL_ISSUER_ENABLED) === true;
|
|
395
|
+
const phaseARedemptionEnabled = parseBoolean(env.TASKFORCE_PHASE_A_ISSUER_REDEMPTION_ENABLED) === true;
|
|
396
|
+
const hasPhaseAKeyId = hasValue(env, 'TASKFORCE_PHASE_A_APPROVAL_SIGNING_KEY_ID');
|
|
397
|
+
const hasPhaseAPrivateKey = hasValue(env, 'TASKFORCE_PHASE_A_APPROVAL_SIGNING_PRIVATE_KEY_PKCS8_BASE64');
|
|
398
|
+
if (phaseAIssuerEnabled || hasPhaseAKeyId || hasPhaseAPrivateKey) {
|
|
399
|
+
if (runtimeMode !== 'cloud' || deployment.cloudEnvironment !== 'performance') {
|
|
400
|
+
errors.push('Phase A approval receipt signing is allowed only in the performance cloud runtime.');
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (phaseARedemptionEnabled && (runtimeMode !== 'cloud' || deployment.cloudEnvironment !== 'performance')) {
|
|
404
|
+
errors.push('Phase A issuer redemption is allowed only in the performance cloud runtime.');
|
|
405
|
+
}
|
|
406
|
+
if (hasValue(env, 'TASKFORCE_PHASE_A_APPROVAL_ISSUER_ENABLED') || hasPhaseAKeyId || hasPhaseAPrivateKey) {
|
|
407
|
+
try {
|
|
408
|
+
resolveExecutorPhaseAApprovalSigningConfig(env);
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
errors.push(String(error?.message || error));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
360
414
|
if (billingEnabled && !hasValue(env, 'TASKFORCE_STRIPE_SECRET_KEY')) {
|
|
361
415
|
errors.push('TASKFORCE_STRIPE_SECRET_KEY is required when TASKFORCE_BILLING_ENABLED=true.');
|
|
362
416
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from '../storage/databaseAdapter.js';
|
|
2
|
-
import type { McpOAuthProvider, McpAccessTokenRecord, McpAccessTokenListResult, McpAccessTokenIssueResult, McpAccessTokenAuthResult, McpAccessTokenInspectionResult, McpOAuthClientRecord, McpOAuthConnectorGrantRecord, McpOAuthTokenExchangeResult, McpOAuthAccessTokenAuthResult } from './types.js';
|
|
2
|
+
import type { McpCloudToolProfile, McpOAuthProvider, McpAccessTokenRecord, McpAccessTokenListResult, McpAccessTokenIssueResult, McpAccessTokenAuthResult, McpAccessTokenInspectionResult, McpOAuthClientRecord, McpOAuthConnectorGrantRecord, McpOAuthTokenExchangeResult, McpOAuthAccessTokenAuthResult } from './types.js';
|
|
3
3
|
export interface McpTokenServiceDeps {
|
|
4
4
|
/** Resolve plan/account access state for a given user */
|
|
5
5
|
getAccountAccessStatus: (userId: string) => {
|
|
@@ -19,9 +19,12 @@ export declare class McpTokenService {
|
|
|
19
19
|
private normalizeAccessRole;
|
|
20
20
|
private normalizePermissionMode;
|
|
21
21
|
private normalizeMcpAccessTokenScopes;
|
|
22
|
+
private normalizeMcpCloudToolProfile;
|
|
23
|
+
private requireMcpCloudToolProfile;
|
|
22
24
|
private createMcpAccessTokenPrefix;
|
|
23
25
|
private parseMcpAccessToken;
|
|
24
26
|
private normalizeMcpOAuthProvider;
|
|
27
|
+
private normalizeMcpOAuthApplicationType;
|
|
25
28
|
private defaultMcpOAuthClientName;
|
|
26
29
|
private createMcpOAuthCodePrefix;
|
|
27
30
|
private createMcpOAuthAccessTokenPrefix;
|
|
@@ -38,6 +41,7 @@ export declare class McpTokenService {
|
|
|
38
41
|
private resolveMcpAccessTokenStatus;
|
|
39
42
|
private rowToMcpAccessTokenRecord;
|
|
40
43
|
private assertCanManageOwnMcpAccessToken;
|
|
44
|
+
private requireMcpToolProfileAdministrator;
|
|
41
45
|
private countActiveMcpAccessTokens;
|
|
42
46
|
revokeMcpCredentialsForUserWorkspace(userId: string, workspaceId: string, revokedByUserId?: string | null): void;
|
|
43
47
|
revokeMcpCredentialsForWorkspace(workspaceId: string, revokedByUserId?: string | null): void;
|
|
@@ -52,6 +56,7 @@ export declare class McpTokenService {
|
|
|
52
56
|
workspaceId: string;
|
|
53
57
|
name: string;
|
|
54
58
|
scopes: unknown;
|
|
59
|
+
toolProfile?: McpCloudToolProfile;
|
|
55
60
|
expiresAt?: string | null;
|
|
56
61
|
createdByIp?: string | null;
|
|
57
62
|
}): McpAccessTokenIssueResult;
|
|
@@ -71,6 +76,15 @@ export declare class McpTokenService {
|
|
|
71
76
|
tokenId: string;
|
|
72
77
|
createdByIp?: string | null;
|
|
73
78
|
}): McpAccessTokenIssueResult;
|
|
79
|
+
updateMcpAccessTokenToolProfile(input: {
|
|
80
|
+
actorUserId: string;
|
|
81
|
+
workspaceId: string;
|
|
82
|
+
tokenId: string;
|
|
83
|
+
toolProfile: unknown;
|
|
84
|
+
}): {
|
|
85
|
+
record: McpAccessTokenRecord;
|
|
86
|
+
previousToolProfile: McpCloudToolProfile;
|
|
87
|
+
};
|
|
74
88
|
authenticateMcpAccessToken(token: string, workspaceId?: string): McpAccessTokenAuthResult | null;
|
|
75
89
|
inspectMcpAccessToken(token: string): McpAccessTokenInspectionResult | null;
|
|
76
90
|
recordMcpAccessTokenUsage(input: {
|
|
@@ -83,6 +97,7 @@ export declare class McpTokenService {
|
|
|
83
97
|
provider: McpOAuthProvider | string;
|
|
84
98
|
clientName: string;
|
|
85
99
|
redirectUris: unknown;
|
|
100
|
+
applicationType?: unknown;
|
|
86
101
|
productClientId?: string | null;
|
|
87
102
|
}): McpOAuthClientRecord;
|
|
88
103
|
getMcpOAuthClient(clientId: string, provider?: McpOAuthProvider | string | null): McpOAuthClientRecord | null;
|
|
@@ -116,6 +131,15 @@ export declare class McpTokenService {
|
|
|
116
131
|
workspaceId: string;
|
|
117
132
|
grantId: string;
|
|
118
133
|
}): McpOAuthConnectorGrantRecord;
|
|
134
|
+
updateMcpOAuthConnectorGrantToolProfile(input: {
|
|
135
|
+
actorUserId: string;
|
|
136
|
+
workspaceId: string;
|
|
137
|
+
grantId: string;
|
|
138
|
+
toolProfile: unknown;
|
|
139
|
+
}): {
|
|
140
|
+
record: McpOAuthConnectorGrantRecord;
|
|
141
|
+
previousToolProfile: McpCloudToolProfile;
|
|
142
|
+
};
|
|
119
143
|
authenticateMcpOAuthAccessToken(token: string, workspaceId?: string): McpOAuthAccessTokenAuthResult | null;
|
|
120
144
|
bindMcpOAuthConnectorGrantAiProfile(input: {
|
|
121
145
|
grantId: string;
|
|
@@ -7,6 +7,7 @@ const MCP_ACCESS_TOKEN_DEFAULT_PAGE_SIZE = 20;
|
|
|
7
7
|
const MCP_ACCESS_TOKEN_MAX_PAGE_SIZE = 100;
|
|
8
8
|
const MCP_ACCESS_TOKEN_ALLOWED_SCOPES = ['tasks:read', 'tasks:write', 'workspace:read'];
|
|
9
9
|
const MCP_OAUTH_AUTH_CODE_TTL_MS = 10 * 60 * 1000;
|
|
10
|
+
const MCP_CLOUD_TOOL_PROFILES = ['default', 'extended'];
|
|
10
11
|
/**
|
|
11
12
|
* Handles MCP direct-access tokens and MCP OAuth connector flow
|
|
12
13
|
* (client registration, authorization codes, token exchange, grant lifecycle).
|
|
@@ -52,6 +53,19 @@ export class McpTokenService {
|
|
|
52
53
|
}
|
|
53
54
|
return unique;
|
|
54
55
|
}
|
|
56
|
+
normalizeMcpCloudToolProfile(value, fallback = 'default') {
|
|
57
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
58
|
+
return MCP_CLOUD_TOOL_PROFILES.includes(normalized)
|
|
59
|
+
? normalized
|
|
60
|
+
: fallback;
|
|
61
|
+
}
|
|
62
|
+
requireMcpCloudToolProfile(value) {
|
|
63
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
64
|
+
if (!MCP_CLOUD_TOOL_PROFILES.includes(normalized)) {
|
|
65
|
+
throw new TaskforceRuleError('toolProfile must be default or extended', 400, 'MCP_TOOL_PROFILE_INVALID');
|
|
66
|
+
}
|
|
67
|
+
return normalized;
|
|
68
|
+
}
|
|
55
69
|
createMcpAccessTokenPrefix() {
|
|
56
70
|
return `tfmcp_${randomBytes(6).toString('hex')}`;
|
|
57
71
|
}
|
|
@@ -84,6 +98,12 @@ export class McpTokenService {
|
|
|
84
98
|
return 'perplexity';
|
|
85
99
|
throw new TaskforceRuleError('Unsupported MCP OAuth provider', 400, 'MCP_OAUTH_PROVIDER_INVALID');
|
|
86
100
|
}
|
|
101
|
+
normalizeMcpOAuthApplicationType(raw) {
|
|
102
|
+
const normalized = String(raw || 'web').trim().toLowerCase();
|
|
103
|
+
if (normalized === 'native' || normalized === 'web')
|
|
104
|
+
return normalized;
|
|
105
|
+
throw new TaskforceRuleError('application_type must be native or web', 400, 'MCP_OAUTH_APPLICATION_TYPE_INVALID');
|
|
106
|
+
}
|
|
87
107
|
defaultMcpOAuthClientName(provider) {
|
|
88
108
|
if (provider === 'claude')
|
|
89
109
|
return 'Claude Chat Connector';
|
|
@@ -155,14 +175,14 @@ export class McpTokenService {
|
|
|
155
175
|
return null;
|
|
156
176
|
if (provider) {
|
|
157
177
|
return this.db.prepare(`
|
|
158
|
-
SELECT id, provider, client_name, redirect_uris_json, product_client_id, status, created_at, updated_at
|
|
178
|
+
SELECT id, provider, client_name, redirect_uris_json, application_type, product_client_id, status, created_at, updated_at
|
|
159
179
|
FROM mcp_oauth_clients
|
|
160
180
|
WHERE tenant_id = ? AND id = ? AND provider = ?
|
|
161
181
|
LIMIT 1
|
|
162
182
|
`).get(this.tenantId, normalizedClientId, provider) || null;
|
|
163
183
|
}
|
|
164
184
|
return this.db.prepare(`
|
|
165
|
-
SELECT id, provider, client_name, redirect_uris_json, product_client_id, status, created_at, updated_at
|
|
185
|
+
SELECT id, provider, client_name, redirect_uris_json, application_type, product_client_id, status, created_at, updated_at
|
|
166
186
|
FROM mcp_oauth_clients
|
|
167
187
|
WHERE tenant_id = ? AND id = ?
|
|
168
188
|
LIMIT 1
|
|
@@ -180,6 +200,7 @@ export class McpTokenService {
|
|
|
180
200
|
id: String(row?.id || ''),
|
|
181
201
|
provider: this.normalizeMcpOAuthProvider(row?.provider),
|
|
182
202
|
clientName: String(row?.client_name || ''),
|
|
203
|
+
applicationType: this.normalizeMcpOAuthApplicationType(row?.application_type),
|
|
183
204
|
productClientId: row?.product_client_id ? String(row.product_client_id) : null,
|
|
184
205
|
redirectUris,
|
|
185
206
|
status: String(row?.status || '').trim().toLowerCase() === 'revoked' ? 'revoked' : 'active',
|
|
@@ -204,6 +225,7 @@ export class McpTokenService {
|
|
|
204
225
|
workspaceId: String(row?.workspace_id || ''),
|
|
205
226
|
userId: String(row?.user_id || ''),
|
|
206
227
|
scopes,
|
|
228
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row?.tool_profile),
|
|
207
229
|
tokenPrefix: String(row?.token_prefix || ''),
|
|
208
230
|
status: this.resolveMcpOAuthGrantStatus(row),
|
|
209
231
|
lastUsedAt: row?.last_used_at ? String(row.last_used_at) : null,
|
|
@@ -286,6 +308,7 @@ export class McpTokenService {
|
|
|
286
308
|
u.email AS user_email,
|
|
287
309
|
t.name,
|
|
288
310
|
t.scopes_json,
|
|
311
|
+
t.tool_profile,
|
|
289
312
|
t.token_prefix,
|
|
290
313
|
t.token_hash,
|
|
291
314
|
t.status,
|
|
@@ -331,6 +354,7 @@ export class McpTokenService {
|
|
|
331
354
|
userEmail: row.user_email ? String(row.user_email) : null,
|
|
332
355
|
name: String(row.name || ''),
|
|
333
356
|
scopes,
|
|
357
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
334
358
|
tokenPrefix: String(row.token_prefix || ''),
|
|
335
359
|
status: this.resolveMcpAccessTokenStatus(row),
|
|
336
360
|
lastUsedAt: row.last_used_at ? String(row.last_used_at) : null,
|
|
@@ -353,6 +377,12 @@ export class McpTokenService {
|
|
|
353
377
|
throw new TaskforceRuleError('Forbidden', 403, 'FORBIDDEN');
|
|
354
378
|
}
|
|
355
379
|
}
|
|
380
|
+
requireMcpToolProfileAdministrator(actorUserId, workspaceId) {
|
|
381
|
+
const member = this.getActiveWorkspaceMemberForMcp(actorUserId, workspaceId);
|
|
382
|
+
if (member.role !== 'owner' && member.role !== 'admin') {
|
|
383
|
+
throw new TaskforceRuleError('Workspace owner or admin access is required', 403, 'MCP_TOOL_PROFILE_ADMIN_REQUIRED');
|
|
384
|
+
}
|
|
385
|
+
}
|
|
356
386
|
countActiveMcpAccessTokens(userId, workspaceId) {
|
|
357
387
|
const now = new Date().toISOString();
|
|
358
388
|
const row = this.db.prepare(`
|
|
@@ -446,6 +476,7 @@ export class McpTokenService {
|
|
|
446
476
|
u.email AS user_email,
|
|
447
477
|
t.name,
|
|
448
478
|
t.scopes_json,
|
|
479
|
+
t.tool_profile,
|
|
449
480
|
t.token_prefix,
|
|
450
481
|
t.token_hash,
|
|
451
482
|
t.status,
|
|
@@ -480,6 +511,7 @@ export class McpTokenService {
|
|
|
480
511
|
throw new TaskforceRuleError('Token name is required', 400, 'MCP_TOKEN_NAME_REQUIRED');
|
|
481
512
|
}
|
|
482
513
|
const scopes = this.normalizeMcpAccessTokenScopes(input.scopes);
|
|
514
|
+
const toolProfile = this.normalizeMcpCloudToolProfile(input.toolProfile);
|
|
483
515
|
const expiresAt = input.expiresAt ? String(input.expiresAt).trim() : null;
|
|
484
516
|
const now = new Date().toISOString();
|
|
485
517
|
if (expiresAt && expiresAt <= now) {
|
|
@@ -501,12 +533,12 @@ export class McpTokenService {
|
|
|
501
533
|
const createdByIp = input.createdByIp ? String(input.createdByIp).trim() : null;
|
|
502
534
|
this.db.prepare(`
|
|
503
535
|
INSERT INTO mcp_access_tokens (
|
|
504
|
-
id, tenant_id, workspace_id, user_id, name, scopes_json, token_prefix, token_hash, status,
|
|
536
|
+
id, tenant_id, workspace_id, user_id, name, scopes_json, tool_profile, token_prefix, token_hash, status,
|
|
505
537
|
last_used_at, last_used_ip, last_used_user_agent, created_by_ip, expires_at, revoked_at,
|
|
506
538
|
revoked_by_user_id, created_at, updated_at
|
|
507
539
|
)
|
|
508
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'active', NULL, NULL, NULL, ?, ?, NULL, NULL, ?, ?)
|
|
509
|
-
`).run(tokenId, this.tenantId, member.workspaceId, member.userId, name, JSON.stringify(scopes), tokenPrefix, tokenHash, createdByIp, expiresAt, now, now);
|
|
540
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NULL, NULL, NULL, ?, ?, NULL, NULL, ?, ?)
|
|
541
|
+
`).run(tokenId, this.tenantId, member.workspaceId, member.userId, name, JSON.stringify(scopes), toolProfile, tokenPrefix, tokenHash, createdByIp, expiresAt, now, now);
|
|
510
542
|
const row = this.getMcpAccessTokenRow(tokenId, member.workspaceId);
|
|
511
543
|
if (!row) {
|
|
512
544
|
throw new TaskforceRuleError('Failed to create MCP token', 500, 'MCP_TOKEN_CREATE_FAILED');
|
|
@@ -573,18 +605,39 @@ export class McpTokenService {
|
|
|
573
605
|
workspaceId: revoked.workspaceId,
|
|
574
606
|
name: revoked.name,
|
|
575
607
|
scopes: revoked.scopes,
|
|
608
|
+
toolProfile: revoked.toolProfile,
|
|
576
609
|
expiresAt: revoked.expiresAt || null,
|
|
577
610
|
createdByIp: input.createdByIp || null,
|
|
578
611
|
});
|
|
579
612
|
});
|
|
580
613
|
return tx();
|
|
581
614
|
}
|
|
615
|
+
updateMcpAccessTokenToolProfile(input) {
|
|
616
|
+
this.requireMcpToolProfileAdministrator(input.actorUserId, input.workspaceId);
|
|
617
|
+
const row = this.getMcpAccessTokenRow(input.tokenId, input.workspaceId);
|
|
618
|
+
if (!row) {
|
|
619
|
+
throw new TaskforceRuleError('MCP token not found', 404, 'MCP_TOKEN_NOT_FOUND');
|
|
620
|
+
}
|
|
621
|
+
const previousToolProfile = this.normalizeMcpCloudToolProfile(row.tool_profile);
|
|
622
|
+
const toolProfile = this.requireMcpCloudToolProfile(input.toolProfile);
|
|
623
|
+
const now = new Date().toISOString();
|
|
624
|
+
this.db.prepare(`
|
|
625
|
+
UPDATE mcp_access_tokens
|
|
626
|
+
SET tool_profile = ?, updated_at = ?
|
|
627
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
628
|
+
`).run(toolProfile, now, this.tenantId, input.workspaceId, row.id);
|
|
629
|
+
const updated = this.getMcpAccessTokenRow(row.id, input.workspaceId);
|
|
630
|
+
if (!updated) {
|
|
631
|
+
throw new TaskforceRuleError('MCP token not found', 404, 'MCP_TOKEN_NOT_FOUND');
|
|
632
|
+
}
|
|
633
|
+
return { record: this.rowToMcpAccessTokenRecord(updated), previousToolProfile };
|
|
634
|
+
}
|
|
582
635
|
authenticateMcpAccessToken(token, workspaceId) {
|
|
583
636
|
const parsed = this.parseMcpAccessToken(token);
|
|
584
637
|
if (!parsed)
|
|
585
638
|
return null;
|
|
586
639
|
const row = this.db.prepare(`
|
|
587
|
-
SELECT id, workspace_id, user_id, scopes_json, token_hash, status, expires_at, revoked_at
|
|
640
|
+
SELECT id, workspace_id, user_id, scopes_json, tool_profile, token_hash, status, expires_at, revoked_at
|
|
588
641
|
FROM mcp_access_tokens
|
|
589
642
|
WHERE tenant_id = ?
|
|
590
643
|
AND token_prefix = ?
|
|
@@ -612,6 +665,7 @@ export class McpTokenService {
|
|
|
612
665
|
workspaceId: row.workspace_id,
|
|
613
666
|
userId: row.user_id,
|
|
614
667
|
scopes,
|
|
668
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
615
669
|
status,
|
|
616
670
|
};
|
|
617
671
|
}
|
|
@@ -620,7 +674,7 @@ export class McpTokenService {
|
|
|
620
674
|
if (!parsed)
|
|
621
675
|
return null;
|
|
622
676
|
const row = this.db.prepare(`
|
|
623
|
-
SELECT id, workspace_id, user_id, name, scopes_json, token_hash, status, expires_at, revoked_at
|
|
677
|
+
SELECT id, workspace_id, user_id, name, scopes_json, tool_profile, token_hash, status, expires_at, revoked_at
|
|
624
678
|
FROM mcp_access_tokens
|
|
625
679
|
WHERE tenant_id = ?
|
|
626
680
|
AND token_prefix = ?
|
|
@@ -644,6 +698,7 @@ export class McpTokenService {
|
|
|
644
698
|
userId: row.user_id,
|
|
645
699
|
name: String(row.name || ''),
|
|
646
700
|
scopes,
|
|
701
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
647
702
|
status: this.resolveMcpAccessTokenStatus(row),
|
|
648
703
|
};
|
|
649
704
|
}
|
|
@@ -668,15 +723,16 @@ export class McpTokenService {
|
|
|
668
723
|
const provider = this.normalizeMcpOAuthProvider(input.provider);
|
|
669
724
|
const clientName = String(input.clientName || '').trim() || this.defaultMcpOAuthClientName(provider);
|
|
670
725
|
const redirectUris = this.normalizeRedirectUris(input.redirectUris);
|
|
726
|
+
const applicationType = this.normalizeMcpOAuthApplicationType(input.applicationType);
|
|
671
727
|
const productClientId = String(input.productClientId || '').trim() || null;
|
|
672
728
|
const now = new Date().toISOString();
|
|
673
729
|
const clientId = this.generateEntityId(`mcp-oauth-client-${provider}`);
|
|
674
730
|
this.db.prepare(`
|
|
675
731
|
INSERT INTO mcp_oauth_clients (
|
|
676
|
-
id, tenant_id, provider, client_name, redirect_uris_json, product_client_id, status, created_at, updated_at
|
|
732
|
+
id, tenant_id, provider, client_name, redirect_uris_json, application_type, product_client_id, status, created_at, updated_at
|
|
677
733
|
)
|
|
678
|
-
VALUES (?, ?, ?, ?, ?, ?, 'active', ?, ?)
|
|
679
|
-
`).run(clientId, this.tenantId, provider, clientName, JSON.stringify(redirectUris), productClientId, now, now);
|
|
734
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, 'active', ?, ?)
|
|
735
|
+
`).run(clientId, this.tenantId, provider, clientName, JSON.stringify(redirectUris), applicationType, productClientId, now, now);
|
|
680
736
|
const row = this.getMcpOAuthClientRow(clientId, provider);
|
|
681
737
|
if (!row) {
|
|
682
738
|
throw new TaskforceRuleError('Failed to register MCP OAuth client', 500, 'MCP_OAUTH_CLIENT_CREATE_FAILED');
|
|
@@ -783,7 +839,7 @@ export class McpTokenService {
|
|
|
783
839
|
const clientName = String(client.client_name || this.defaultMcpOAuthClientName(provider)).trim() || this.defaultMcpOAuthClientName(provider);
|
|
784
840
|
const tx = this.db.transaction(() => {
|
|
785
841
|
const existingRows = this.db.prepare(`
|
|
786
|
-
SELECT id, ai_profile_id, ai_profile_token, ai_profile_name
|
|
842
|
+
SELECT id, tool_profile, ai_profile_id, ai_profile_token, ai_profile_name
|
|
787
843
|
FROM mcp_oauth_connector_grants
|
|
788
844
|
WHERE tenant_id = ?
|
|
789
845
|
AND provider = ?
|
|
@@ -794,6 +850,7 @@ export class McpTokenService {
|
|
|
794
850
|
ORDER BY created_at DESC
|
|
795
851
|
`).all(this.tenantId, provider, String(client.id), String(row.user_id), String(row.workspace_id));
|
|
796
852
|
const previousBinding = existingRows.find((existing) => existing.ai_profile_id && existing.ai_profile_token && existing.ai_profile_name) || null;
|
|
853
|
+
const toolProfile = this.normalizeMcpCloudToolProfile(existingRows[0]?.tool_profile);
|
|
797
854
|
const revokeTime = new Date().toISOString();
|
|
798
855
|
existingRows.forEach((existing) => {
|
|
799
856
|
if (!existing?.id)
|
|
@@ -819,12 +876,12 @@ export class McpTokenService {
|
|
|
819
876
|
const tokenHash = hashMcpOAuthSecret(secret);
|
|
820
877
|
this.db.prepare(`
|
|
821
878
|
INSERT INTO mcp_oauth_connector_grants (
|
|
822
|
-
id, tenant_id, provider, client_id, client_name, product_client_id, user_id, workspace_id, scopes_json,
|
|
879
|
+
id, tenant_id, provider, client_id, client_name, product_client_id, user_id, workspace_id, scopes_json, tool_profile,
|
|
823
880
|
token_prefix, token_hash, status, last_used_at, revoked_at, revoked_by_user_id,
|
|
824
881
|
ai_profile_id, ai_profile_token, ai_profile_name, created_at, updated_at
|
|
825
882
|
)
|
|
826
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NULL, NULL, NULL, ?, ?, ?, ?, ?)
|
|
827
|
-
`).run(grantId, this.tenantId, provider, String(client.id || ''), clientName, client.product_client_id ? String(client.product_client_id) : null, String(row.user_id), String(row.workspace_id), JSON.stringify(scopes), tokenPrefix, tokenHash, previousBinding?.ai_profile_id || null, previousBinding?.ai_profile_token || null, previousBinding?.ai_profile_name || null, now, now);
|
|
883
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NULL, NULL, NULL, ?, ?, ?, ?, ?)
|
|
884
|
+
`).run(grantId, this.tenantId, provider, String(client.id || ''), clientName, client.product_client_id ? String(client.product_client_id) : null, String(row.user_id), String(row.workspace_id), JSON.stringify(scopes), toolProfile, tokenPrefix, tokenHash, previousBinding?.ai_profile_id || null, previousBinding?.ai_profile_token || null, previousBinding?.ai_profile_name || null, now, now);
|
|
828
885
|
this.db.prepare(`
|
|
829
886
|
UPDATE mcp_oauth_auth_codes
|
|
830
887
|
SET used_at = ?
|
|
@@ -909,12 +966,45 @@ export class McpTokenService {
|
|
|
909
966
|
}
|
|
910
967
|
return this.rowToMcpOAuthConnectorGrantRecord(updated);
|
|
911
968
|
}
|
|
969
|
+
updateMcpOAuthConnectorGrantToolProfile(input) {
|
|
970
|
+
this.requireMcpToolProfileAdministrator(input.actorUserId, input.workspaceId);
|
|
971
|
+
const row = this.db.prepare(`
|
|
972
|
+
SELECT *
|
|
973
|
+
FROM mcp_oauth_connector_grants
|
|
974
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
975
|
+
LIMIT 1
|
|
976
|
+
`).get(this.tenantId, input.workspaceId, String(input.grantId || '').trim());
|
|
977
|
+
if (!row?.id) {
|
|
978
|
+
throw new TaskforceRuleError('MCP connector grant not found', 404, 'MCP_OAUTH_GRANT_NOT_FOUND');
|
|
979
|
+
}
|
|
980
|
+
const previousToolProfile = this.normalizeMcpCloudToolProfile(row.tool_profile);
|
|
981
|
+
const toolProfile = this.requireMcpCloudToolProfile(input.toolProfile);
|
|
982
|
+
const now = new Date().toISOString();
|
|
983
|
+
this.db.prepare(`
|
|
984
|
+
UPDATE mcp_oauth_connector_grants
|
|
985
|
+
SET tool_profile = ?, updated_at = ?
|
|
986
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
987
|
+
`).run(toolProfile, now, this.tenantId, input.workspaceId, String(row.id));
|
|
988
|
+
const updated = this.db.prepare(`
|
|
989
|
+
SELECT *
|
|
990
|
+
FROM mcp_oauth_connector_grants
|
|
991
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
992
|
+
LIMIT 1
|
|
993
|
+
`).get(this.tenantId, input.workspaceId, String(row.id));
|
|
994
|
+
if (!updated) {
|
|
995
|
+
throw new TaskforceRuleError('MCP connector grant not found', 404, 'MCP_OAUTH_GRANT_NOT_FOUND');
|
|
996
|
+
}
|
|
997
|
+
return {
|
|
998
|
+
record: this.rowToMcpOAuthConnectorGrantRecord(updated),
|
|
999
|
+
previousToolProfile,
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
912
1002
|
authenticateMcpOAuthAccessToken(token, workspaceId) {
|
|
913
1003
|
const parsed = this.parseMcpOAuthOpaqueSecret(token, 'tfmcpoauth_');
|
|
914
1004
|
if (!parsed)
|
|
915
1005
|
return null;
|
|
916
1006
|
const row = this.db.prepare(`
|
|
917
|
-
SELECT id, provider, client_id, product_client_id, user_id, workspace_id, scopes_json, token_hash, status, revoked_at,
|
|
1007
|
+
SELECT id, provider, client_id, product_client_id, user_id, workspace_id, scopes_json, tool_profile, token_hash, status, revoked_at,
|
|
918
1008
|
ai_profile_id, ai_profile_token, ai_profile_name
|
|
919
1009
|
FROM mcp_oauth_connector_grants
|
|
920
1010
|
WHERE tenant_id = ?
|
|
@@ -945,6 +1035,7 @@ export class McpTokenService {
|
|
|
945
1035
|
provider: this.normalizeMcpOAuthProvider(row.provider),
|
|
946
1036
|
productClientId: row?.product_client_id ? String(row.product_client_id) : null,
|
|
947
1037
|
scopes,
|
|
1038
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
948
1039
|
status: this.resolveMcpOAuthGrantStatus(row),
|
|
949
1040
|
aiProfileId: row?.ai_profile_id ? String(row.ai_profile_id) : null,
|
|
950
1041
|
aiProfileToken: row?.ai_profile_token ? String(row.ai_profile_token) : null,
|
|
@@ -9,11 +9,23 @@ export interface TaskChecklistItem {
|
|
|
9
9
|
}
|
|
10
10
|
export interface TaskChecklistTask {
|
|
11
11
|
id: string;
|
|
12
|
+
checklistItems?: TaskChecklistItem[];
|
|
12
13
|
}
|
|
13
14
|
export interface TaskChecklistReplaceMutation {
|
|
14
15
|
taskId: string;
|
|
15
16
|
items: TaskChecklistItem[];
|
|
16
17
|
operationId: string;
|
|
18
|
+
expectedDetailRevision?: string;
|
|
19
|
+
requireDurableIdempotency?: boolean;
|
|
20
|
+
itemUpdateIntent?: {
|
|
21
|
+
kind: 'item-update';
|
|
22
|
+
itemId: string;
|
|
23
|
+
patch: {
|
|
24
|
+
text?: string;
|
|
25
|
+
done?: boolean;
|
|
26
|
+
order?: number;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
17
29
|
}
|
|
18
30
|
export interface TaskChecklistCommandServiceDependencies {
|
|
19
31
|
resolveTask(identifier: unknown): TaskChecklistTask;
|
|
@@ -35,6 +47,9 @@ export type ReplaceTaskChecklistCommandResult = {
|
|
|
35
47
|
export type AddTaskChecklistItemCommandResult = ReplaceTaskChecklistCommandResult & {
|
|
36
48
|
item: TaskChecklistItem | null;
|
|
37
49
|
};
|
|
50
|
+
export type UpdateTaskChecklistItemCommandResult = ReplaceTaskChecklistCommandResult & {
|
|
51
|
+
item: TaskChecklistItem;
|
|
52
|
+
};
|
|
38
53
|
export declare function createTaskChecklistCommandService(deps: TaskChecklistCommandServiceDependencies): {
|
|
39
54
|
replace(input: {
|
|
40
55
|
taskId: unknown;
|
|
@@ -47,4 +62,16 @@ export declare function createTaskChecklistCommandService(deps: TaskChecklistCom
|
|
|
47
62
|
isCompleted?: unknown;
|
|
48
63
|
done?: unknown;
|
|
49
64
|
}): AddTaskChecklistItemCommandResult;
|
|
65
|
+
update(input: {
|
|
66
|
+
taskId: unknown;
|
|
67
|
+
itemId: unknown;
|
|
68
|
+
title?: unknown;
|
|
69
|
+
text?: unknown;
|
|
70
|
+
isCompleted?: unknown;
|
|
71
|
+
done?: unknown;
|
|
72
|
+
order?: unknown;
|
|
73
|
+
expectedDetailRevision?: unknown;
|
|
74
|
+
operationId?: string;
|
|
75
|
+
requireDurableIdempotency?: boolean;
|
|
76
|
+
}): UpdateTaskChecklistItemCommandResult;
|
|
50
77
|
};
|