@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
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { AlertTriangle, ChevronDown, Copy, Loader2
|
|
3
|
+
import { AlertTriangle, ChevronDown, Copy, Loader2 } from 'lucide-react';
|
|
4
4
|
import { Modal } from '../../../ui/Modal';
|
|
5
5
|
import modalStyles from '../../../ui/Modal.module.css';
|
|
6
6
|
import syncStatusStyles from '../../SyncStatusModal.module.css';
|
|
7
7
|
import styles from '../../../../Taskforce.module.css';
|
|
8
8
|
import { isWorkspaceSyncAuthenticationError } from '../../../../utils/workspaceSyncPresentation';
|
|
9
|
-
export function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStatus, syncStatusMeta, workspaceCloudSyncEnabled, syncControlBusy, canManageWorkspaceSync, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncRepairBusy, referenceMismatchCount, syncStageLabel, workspaceSyncPendingChanges, incomingCloudChanges, formattedLastSyncTime, formattedLastPullTime, formattedLastPushTime, syncLastError, activeReferenceMismatchSummaries, syncDiagnosticsSummary, syncEventRows, syncEventsListRef, workspaceSyncRepairQueued, workspaceSyncBusy, workspaceSyncCopied, coordinatorOwnershipMode, coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled, onClose, onToggleWorkspaceSync, onRepairSync, onCopyReport,
|
|
9
|
+
export function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStatus, syncStatusMeta, workspaceCloudSyncEnabled, syncControlBusy, syncControlIntent, canManageWorkspaceSync, workspaceSyncSummary, workspaceSyncRecommendedAction, workspaceSyncRepairBusy, referenceMismatchCount, syncStageLabel, workspaceSyncPendingChanges, incomingCloudChanges, formattedLastSyncTime, formattedLastPullTime, formattedLastPushTime, syncLastError, activeReferenceMismatchSummaries, syncDiagnosticsSummary, syncEventRows, syncEventsListRef, workspaceSyncRepairQueued, workspaceSyncBusy, workspaceSyncCopied, coordinatorOwnershipMode, coordinatorOwnershipTransferBusy, coordinatorOwnershipTransferDisabled, onClose, onToggleWorkspaceSync, onRepairSync, onCopyReport, onTransferCoordinatorOwnership, }) {
|
|
10
10
|
const [eventFilter, setEventFilter] = useState('all');
|
|
11
11
|
useEffect(() => {
|
|
12
12
|
if (isOpen)
|
|
13
13
|
setEventFilter('all');
|
|
14
14
|
}, [isOpen]);
|
|
15
15
|
const needsAttention = syncStatus === 'attention';
|
|
16
|
+
const displayedSyncEnabled = syncControlIntent === 'enabling'
|
|
17
|
+
? true
|
|
18
|
+
: syncControlIntent === 'disabling'
|
|
19
|
+
? false
|
|
20
|
+
: workspaceCloudSyncEnabled;
|
|
21
|
+
const syncControlTransitionLabel = syncControlIntent === 'enabling'
|
|
22
|
+
? 'Turning on…'
|
|
23
|
+
: syncControlIntent === 'disabling'
|
|
24
|
+
? 'Turning off…'
|
|
25
|
+
: null;
|
|
16
26
|
const activeIssue = workspaceSyncRepairBusy
|
|
17
27
|
? referenceMismatchCount > 0
|
|
18
28
|
? `Repair is reconciling cloud state, including ${referenceMismatchCount} reference mismatch${referenceMismatchCount === 1 ? '' : 'es'}.`
|
|
@@ -26,58 +36,43 @@ export function SyncStatusModal({ isOpen, theme, currentWorkspaceLabel, syncStat
|
|
|
26
36
|
const coordinatorOwnedByOtherProcess = /\banother local taskforce process owns workspace synchronization\b/i.test(syncLastError);
|
|
27
37
|
const coordinatorAuthenticationRequired = isWorkspaceSyncAuthenticationError(syncLastError);
|
|
28
38
|
const repairActionAvailable = workspaceCloudSyncEnabled
|
|
39
|
+
&& syncStatus !== 'checking'
|
|
29
40
|
&& !coordinatorOwnedByOtherProcess
|
|
30
41
|
&& !coordinatorAuthenticationRequired
|
|
31
42
|
&& (needsAttention
|
|
32
43
|
|| workspaceSyncBusy
|
|
33
44
|
|| workspaceSyncRepairBusy
|
|
34
45
|
|| workspaceSyncRepairQueued);
|
|
35
|
-
const retryActionAvailable = workspaceCloudSyncEnabled
|
|
36
|
-
&& !coordinatorOwnedByOtherProcess
|
|
37
|
-
&& !coordinatorAuthenticationRequired
|
|
38
|
-
&& (workspaceSyncBusy
|
|
39
|
-
|| needsAttention
|
|
40
|
-
|| /\bpress sync\b/i.test(workspaceSyncRecommendedAction));
|
|
41
46
|
const visibleEventRows = useMemo(() => eventFilter === 'issues'
|
|
42
47
|
? syncEventRows.filter((row) => row.tone === 'error')
|
|
43
48
|
: syncEventRows, [eventFilter, syncEventRows]);
|
|
44
|
-
const footer = (_jsxs("div", { className: syncStatusStyles.syncStatusFooter, children: [_jsxs("button", { className: styles.cancelBtn, onClick: onCopyReport, title: "Copy the current sync manager report for support or AI troubleshooting.", children: [_jsx(Copy, { size: 14 }), _jsx("span", { children: workspaceSyncCopied ? 'Copied' : 'Copy Report' })] }),
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
: !workspaceCloudSyncEnabled
|
|
51
|
-
? 'Turn on workspace sync before running Repair.'
|
|
52
|
-
: coordinatorOwnedByOtherProcess
|
|
53
|
-
? 'Repair is unavailable in this process. Use the Taskforce process that owns workspace synchronization.'
|
|
54
|
-
: coordinatorAuthenticationRequired
|
|
55
|
-
? 'Sign out and sign back in before running Repair.'
|
|
56
|
-
: workspaceSyncBusy
|
|
57
|
-
? 'Queue a repair to start automatically when the current sync finishes.'
|
|
58
|
-
: !repairActionAvailable
|
|
59
|
-
? 'Repair is available when sync needs attention.'
|
|
60
|
-
: 'Advanced recovery: clear the saved pull cursor and re-fetch cloud state from the beginning.', children: workspaceSyncRepairBusy ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 14, className: styles.spinner }), "Repairing..."] })) : workspaceSyncRepairQueued ? ('Repair Queued') : ('Repair') }), _jsx("button", { className: styles.submitBtn, onClick: onRetrySync, disabled: !retryActionAvailable || workspaceSyncBusy, title: workspaceSyncBusy
|
|
61
|
-
? 'A sync request is already running.'
|
|
49
|
+
const footer = (_jsxs("div", { className: syncStatusStyles.syncStatusFooter, children: [_jsxs("button", { className: styles.cancelBtn, onClick: onCopyReport, title: "Copy the current sync manager report for support or AI troubleshooting.", children: [_jsx(Copy, { size: 14 }), _jsx("span", { children: workspaceSyncCopied ? 'Copied' : 'Copy Report' })] }), _jsx("div", { className: syncStatusStyles.syncStatusFooterPrimary, children: _jsx("button", { className: styles.cancelBtn, onClick: onRepairSync, disabled: !repairActionAvailable
|
|
50
|
+
|| workspaceSyncRepairBusy
|
|
51
|
+
|| workspaceSyncRepairQueued, title: workspaceSyncRepairBusy
|
|
52
|
+
? 'Repair is running now.'
|
|
53
|
+
: workspaceSyncRepairQueued
|
|
54
|
+
? 'Repair is queued and will start when the current sync finishes.'
|
|
62
55
|
: !workspaceCloudSyncEnabled
|
|
63
|
-
? 'Turn on workspace sync before
|
|
56
|
+
? 'Turn on workspace sync before running Repair.'
|
|
64
57
|
: coordinatorOwnedByOtherProcess
|
|
65
|
-
? '
|
|
58
|
+
? 'Repair is unavailable in this process. Use the Taskforce process that owns workspace synchronization.'
|
|
66
59
|
: coordinatorAuthenticationRequired
|
|
67
|
-
? 'Sign out and sign back in before
|
|
68
|
-
:
|
|
69
|
-
? '
|
|
70
|
-
:
|
|
60
|
+
? 'Sign out and sign back in before running Repair.'
|
|
61
|
+
: workspaceSyncBusy
|
|
62
|
+
? 'Queue a repair to start automatically when the current sync finishes.'
|
|
63
|
+
: !repairActionAvailable
|
|
64
|
+
? 'Repair is available when sync needs attention.'
|
|
65
|
+
: 'Advanced recovery: clear the saved pull cursor and re-fetch cloud state from the beginning.', children: workspaceSyncRepairBusy ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 14, className: styles.spinner }), "Repairing..."] })) : workspaceSyncRepairQueued ? ('Repair Queued') : ('Repair') }) })] }));
|
|
71
66
|
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: "Sync Manager", size: "mdWide", theme: theme, draggable: true, className: syncStatusStyles.syncStatusOverlay, footer: footer, children: _jsxs("div", { className: `${modalStyles.form} ${syncStatusStyles.syncStatusModal}`, children: [_jsxs("div", { className: syncStatusStyles.syncStatusTop, children: [_jsxs("div", { className: syncStatusStyles.syncStatusMetaHeader, children: [_jsx("div", { className: syncStatusStyles.syncStatusBadge, style: {
|
|
72
67
|
borderColor: syncStatusMeta.border,
|
|
73
68
|
background: syncStatusMeta.background,
|
|
74
69
|
color: syncStatusMeta.color
|
|
75
|
-
}, children: syncStatusMeta.label }), _jsxs("span", { className: syncStatusStyles.syncStatusLabel, children: ["Workspace: ", _jsx("code", { children: currentWorkspaceLabel })] })] }),
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
70
|
+
}, children: syncStatusMeta.label }), _jsxs("span", { className: syncStatusStyles.syncStatusLabel, children: ["Workspace: ", _jsx("code", { children: currentWorkspaceLabel })] })] }), _jsxs("label", { className: syncStatusStyles.syncToggle, children: [syncControlTransitionLabel ? (_jsx("span", { className: syncStatusStyles.syncToggleTransition, "aria-live": "polite", children: syncControlTransitionLabel })) : null, _jsxs("span", { className: [
|
|
71
|
+
syncStatusStyles.syncToggleControl,
|
|
72
|
+
displayedSyncEnabled ? syncStatusStyles.syncToggleControlEnabled : syncStatusStyles.syncToggleControlDisabled,
|
|
73
|
+
syncControlBusy ? syncStatusStyles.syncToggleControlBusy : '',
|
|
74
|
+
!canManageWorkspaceSync ? syncStatusStyles.syncToggleControlBlocked : ''
|
|
75
|
+
].filter(Boolean).join(' '), children: [_jsx("input", { className: syncStatusStyles.syncToggleInput, type: "checkbox", role: "switch", "aria-label": syncControlTransitionLabel || 'Enable Sync', checked: displayedSyncEnabled, disabled: !canManageWorkspaceSync || syncControlBusy, onChange: (event) => onToggleWorkspaceSync(event.target.checked) }), _jsx("span", { className: `${syncStatusStyles.syncToggleState} ${syncStatusStyles.syncToggleStateOn}`, children: "On" }), _jsx("span", { className: `${syncStatusStyles.syncToggleState} ${syncStatusStyles.syncToggleStateOff}`, children: "Off" }), _jsx("span", { className: syncStatusStyles.syncToggleThumb })] })] })] }), _jsxs("section", { className: syncStatusStyles.syncStatusOverview, "aria-label": "Sync status", children: [_jsxs("div", { className: syncStatusStyles.syncStatusOverviewRow, children: [_jsx("span", { className: syncStatusStyles.syncStatusLabel, children: "Health" }), _jsx("span", { className: syncStatusStyles.syncStatusSummaryValue, children: workspaceSyncSummary })] }), _jsxs("div", { className: syncStatusStyles.syncStatusOverviewRow, children: [_jsx("span", { className: syncStatusStyles.syncStatusLabel, children: "Next step" }), _jsx("span", { className: syncStatusStyles.syncStatusSummaryValue, children: workspaceSyncRecommendedAction })] }), _jsxs("div", { className: [
|
|
81
76
|
syncStatusStyles.syncStatusOverviewRow,
|
|
82
77
|
syncStatusStyles.syncStatusIssueRow,
|
|
83
78
|
activeIssueIsError ? syncStatusStyles.syncStatusIssueRowError : '',
|
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,12 @@ 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_REVIEW_APP_ID', description: 'GitHub App identifier used for private-repository review evidence.', category: 'Security', targets: ['server', 'all'] },
|
|
176
|
+
{ 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'] },
|
|
177
|
+
{ key: 'TASKFORCE_PHASE_A_APPROVAL_ISSUER_ENABLED', description: 'Enable performance-cloud Phase A approval receipt issuance.', category: 'Security', defaultValue: 'false', targets: ['server', 'all'] },
|
|
178
|
+
{ 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'] },
|
|
179
|
+
{ 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'] },
|
|
180
|
+
{ 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
181
|
{ key: 'TASKFORCE_STRIPE_SECRET_KEY', description: 'Stripe secret API key used by server-side billing routes.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
169
182
|
{ key: 'TASKFORCE_STRIPE_WEBHOOK_SECRET', description: 'Stripe webhook signing secret used to verify incoming webhooks.', category: 'Security', secret: true, targets: ['server', 'all'] },
|
|
170
183
|
{ key: 'TASKFORCE_BUILD_VERSION', description: 'Build version metadata.', category: 'Build', targets: ['server', 'all'] },
|
|
@@ -206,6 +219,8 @@ const SPECS = [
|
|
|
206
219
|
{ key: 'SYNC_SOAK_OVERNIGHT_MAX_ACTIONS', description: 'Overnight hard cap on action count.', category: 'Soak', defaultValue: '10000', targets: ['soak', 'all'] },
|
|
207
220
|
{ key: 'SYNC_SOAK_OVERNIGHT_MIN_ACTIONS', description: 'Overnight minimum actions expected before pass.', category: 'Soak', defaultValue: '80', targets: ['soak', 'all'] },
|
|
208
221
|
{ key: 'SYNC_SOAK_OVERNIGHT_CLEAN_BASELINE_EVERY_ACTION', description: 'Require coordinator settlement before each accelerated overnight action.', category: 'Soak', defaultValue: 'false', targets: ['soak', 'all'] },
|
|
222
|
+
{ 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'] },
|
|
223
|
+
{ 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
224
|
{ key: 'CF_ACCESS_CLIENT_ID', description: 'Cloudflare Access service token client id (soak).', category: 'Cloudflare', secret: true, targets: ['soak', 'all'] },
|
|
210
225
|
{ key: 'CF_ACCESS_CLIENT_SECRET', description: 'Cloudflare Access service token client secret (soak).', category: 'Cloudflare', secret: true, targets: ['soak', 'all'] }
|
|
211
226
|
];
|
|
@@ -357,6 +372,38 @@ function validateServerEnv(env, errors, warnings) {
|
|
|
357
372
|
if (provider === 'postgres' && !hasValue(env, 'TASKFORCE_DATABASE_URL')) {
|
|
358
373
|
errors.push('TASKFORCE_DATABASE_URL is required when TASKFORCE_DB_PROVIDER=postgres.');
|
|
359
374
|
}
|
|
375
|
+
const hasGitHubReviewAppId = hasValue(env, 'TASKFORCE_GITHUB_REVIEW_APP_ID');
|
|
376
|
+
const hasGitHubReviewPrivateKey = hasValue(env, 'TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64');
|
|
377
|
+
if (hasGitHubReviewAppId !== hasGitHubReviewPrivateKey) {
|
|
378
|
+
errors.push('TASKFORCE_GITHUB_REVIEW_APP_ID and TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64 must be configured together.');
|
|
379
|
+
}
|
|
380
|
+
if (hasGitHubReviewPrivateKey) {
|
|
381
|
+
const encoded = String(env.TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64 || '').trim();
|
|
382
|
+
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
|
|
383
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(encoded) || !decoded.includes('-----BEGIN') || !decoded.includes('PRIVATE KEY-----')) {
|
|
384
|
+
errors.push('TASKFORCE_GITHUB_REVIEW_APP_PRIVATE_KEY_BASE64 must contain a base64-encoded PEM private key.');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const phaseAIssuerEnabled = parseBoolean(env.TASKFORCE_PHASE_A_APPROVAL_ISSUER_ENABLED) === true;
|
|
388
|
+
const phaseARedemptionEnabled = parseBoolean(env.TASKFORCE_PHASE_A_ISSUER_REDEMPTION_ENABLED) === true;
|
|
389
|
+
const hasPhaseAKeyId = hasValue(env, 'TASKFORCE_PHASE_A_APPROVAL_SIGNING_KEY_ID');
|
|
390
|
+
const hasPhaseAPrivateKey = hasValue(env, 'TASKFORCE_PHASE_A_APPROVAL_SIGNING_PRIVATE_KEY_PKCS8_BASE64');
|
|
391
|
+
if (phaseAIssuerEnabled || hasPhaseAKeyId || hasPhaseAPrivateKey) {
|
|
392
|
+
if (runtimeMode !== 'cloud' || deployment.cloudEnvironment !== 'performance') {
|
|
393
|
+
errors.push('Phase A approval receipt signing is allowed only in the performance cloud runtime.');
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
if (phaseARedemptionEnabled && (runtimeMode !== 'cloud' || deployment.cloudEnvironment !== 'performance')) {
|
|
397
|
+
errors.push('Phase A issuer redemption is allowed only in the performance cloud runtime.');
|
|
398
|
+
}
|
|
399
|
+
if (hasValue(env, 'TASKFORCE_PHASE_A_APPROVAL_ISSUER_ENABLED') || hasPhaseAKeyId || hasPhaseAPrivateKey) {
|
|
400
|
+
try {
|
|
401
|
+
resolveExecutorPhaseAApprovalSigningConfig(env);
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
errors.push(String(error?.message || error));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
360
407
|
if (billingEnabled && !hasValue(env, 'TASKFORCE_STRIPE_SECRET_KEY')) {
|
|
361
408
|
errors.push('TASKFORCE_STRIPE_SECRET_KEY is required when TASKFORCE_BILLING_ENABLED=true.');
|
|
362
409
|
}
|
|
@@ -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,6 +19,8 @@ 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;
|
|
@@ -38,6 +40,7 @@ export declare class McpTokenService {
|
|
|
38
40
|
private resolveMcpAccessTokenStatus;
|
|
39
41
|
private rowToMcpAccessTokenRecord;
|
|
40
42
|
private assertCanManageOwnMcpAccessToken;
|
|
43
|
+
private requireMcpToolProfileAdministrator;
|
|
41
44
|
private countActiveMcpAccessTokens;
|
|
42
45
|
revokeMcpCredentialsForUserWorkspace(userId: string, workspaceId: string, revokedByUserId?: string | null): void;
|
|
43
46
|
revokeMcpCredentialsForWorkspace(workspaceId: string, revokedByUserId?: string | null): void;
|
|
@@ -52,6 +55,7 @@ export declare class McpTokenService {
|
|
|
52
55
|
workspaceId: string;
|
|
53
56
|
name: string;
|
|
54
57
|
scopes: unknown;
|
|
58
|
+
toolProfile?: McpCloudToolProfile;
|
|
55
59
|
expiresAt?: string | null;
|
|
56
60
|
createdByIp?: string | null;
|
|
57
61
|
}): McpAccessTokenIssueResult;
|
|
@@ -71,6 +75,15 @@ export declare class McpTokenService {
|
|
|
71
75
|
tokenId: string;
|
|
72
76
|
createdByIp?: string | null;
|
|
73
77
|
}): McpAccessTokenIssueResult;
|
|
78
|
+
updateMcpAccessTokenToolProfile(input: {
|
|
79
|
+
actorUserId: string;
|
|
80
|
+
workspaceId: string;
|
|
81
|
+
tokenId: string;
|
|
82
|
+
toolProfile: unknown;
|
|
83
|
+
}): {
|
|
84
|
+
record: McpAccessTokenRecord;
|
|
85
|
+
previousToolProfile: McpCloudToolProfile;
|
|
86
|
+
};
|
|
74
87
|
authenticateMcpAccessToken(token: string, workspaceId?: string): McpAccessTokenAuthResult | null;
|
|
75
88
|
inspectMcpAccessToken(token: string): McpAccessTokenInspectionResult | null;
|
|
76
89
|
recordMcpAccessTokenUsage(input: {
|
|
@@ -116,6 +129,15 @@ export declare class McpTokenService {
|
|
|
116
129
|
workspaceId: string;
|
|
117
130
|
grantId: string;
|
|
118
131
|
}): McpOAuthConnectorGrantRecord;
|
|
132
|
+
updateMcpOAuthConnectorGrantToolProfile(input: {
|
|
133
|
+
actorUserId: string;
|
|
134
|
+
workspaceId: string;
|
|
135
|
+
grantId: string;
|
|
136
|
+
toolProfile: unknown;
|
|
137
|
+
}): {
|
|
138
|
+
record: McpOAuthConnectorGrantRecord;
|
|
139
|
+
previousToolProfile: McpCloudToolProfile;
|
|
140
|
+
};
|
|
119
141
|
authenticateMcpOAuthAccessToken(token: string, workspaceId?: string): McpOAuthAccessTokenAuthResult | null;
|
|
120
142
|
bindMcpOAuthConnectorGrantAiProfile(input: {
|
|
121
143
|
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
|
}
|
|
@@ -204,6 +218,7 @@ export class McpTokenService {
|
|
|
204
218
|
workspaceId: String(row?.workspace_id || ''),
|
|
205
219
|
userId: String(row?.user_id || ''),
|
|
206
220
|
scopes,
|
|
221
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row?.tool_profile),
|
|
207
222
|
tokenPrefix: String(row?.token_prefix || ''),
|
|
208
223
|
status: this.resolveMcpOAuthGrantStatus(row),
|
|
209
224
|
lastUsedAt: row?.last_used_at ? String(row.last_used_at) : null,
|
|
@@ -286,6 +301,7 @@ export class McpTokenService {
|
|
|
286
301
|
u.email AS user_email,
|
|
287
302
|
t.name,
|
|
288
303
|
t.scopes_json,
|
|
304
|
+
t.tool_profile,
|
|
289
305
|
t.token_prefix,
|
|
290
306
|
t.token_hash,
|
|
291
307
|
t.status,
|
|
@@ -331,6 +347,7 @@ export class McpTokenService {
|
|
|
331
347
|
userEmail: row.user_email ? String(row.user_email) : null,
|
|
332
348
|
name: String(row.name || ''),
|
|
333
349
|
scopes,
|
|
350
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
334
351
|
tokenPrefix: String(row.token_prefix || ''),
|
|
335
352
|
status: this.resolveMcpAccessTokenStatus(row),
|
|
336
353
|
lastUsedAt: row.last_used_at ? String(row.last_used_at) : null,
|
|
@@ -353,6 +370,12 @@ export class McpTokenService {
|
|
|
353
370
|
throw new TaskforceRuleError('Forbidden', 403, 'FORBIDDEN');
|
|
354
371
|
}
|
|
355
372
|
}
|
|
373
|
+
requireMcpToolProfileAdministrator(actorUserId, workspaceId) {
|
|
374
|
+
const member = this.getActiveWorkspaceMemberForMcp(actorUserId, workspaceId);
|
|
375
|
+
if (member.role !== 'owner' && member.role !== 'admin') {
|
|
376
|
+
throw new TaskforceRuleError('Workspace owner or admin access is required', 403, 'MCP_TOOL_PROFILE_ADMIN_REQUIRED');
|
|
377
|
+
}
|
|
378
|
+
}
|
|
356
379
|
countActiveMcpAccessTokens(userId, workspaceId) {
|
|
357
380
|
const now = new Date().toISOString();
|
|
358
381
|
const row = this.db.prepare(`
|
|
@@ -446,6 +469,7 @@ export class McpTokenService {
|
|
|
446
469
|
u.email AS user_email,
|
|
447
470
|
t.name,
|
|
448
471
|
t.scopes_json,
|
|
472
|
+
t.tool_profile,
|
|
449
473
|
t.token_prefix,
|
|
450
474
|
t.token_hash,
|
|
451
475
|
t.status,
|
|
@@ -480,6 +504,7 @@ export class McpTokenService {
|
|
|
480
504
|
throw new TaskforceRuleError('Token name is required', 400, 'MCP_TOKEN_NAME_REQUIRED');
|
|
481
505
|
}
|
|
482
506
|
const scopes = this.normalizeMcpAccessTokenScopes(input.scopes);
|
|
507
|
+
const toolProfile = this.normalizeMcpCloudToolProfile(input.toolProfile);
|
|
483
508
|
const expiresAt = input.expiresAt ? String(input.expiresAt).trim() : null;
|
|
484
509
|
const now = new Date().toISOString();
|
|
485
510
|
if (expiresAt && expiresAt <= now) {
|
|
@@ -501,12 +526,12 @@ export class McpTokenService {
|
|
|
501
526
|
const createdByIp = input.createdByIp ? String(input.createdByIp).trim() : null;
|
|
502
527
|
this.db.prepare(`
|
|
503
528
|
INSERT INTO mcp_access_tokens (
|
|
504
|
-
id, tenant_id, workspace_id, user_id, name, scopes_json, token_prefix, token_hash, status,
|
|
529
|
+
id, tenant_id, workspace_id, user_id, name, scopes_json, tool_profile, token_prefix, token_hash, status,
|
|
505
530
|
last_used_at, last_used_ip, last_used_user_agent, created_by_ip, expires_at, revoked_at,
|
|
506
531
|
revoked_by_user_id, created_at, updated_at
|
|
507
532
|
)
|
|
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);
|
|
533
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NULL, NULL, NULL, ?, ?, NULL, NULL, ?, ?)
|
|
534
|
+
`).run(tokenId, this.tenantId, member.workspaceId, member.userId, name, JSON.stringify(scopes), toolProfile, tokenPrefix, tokenHash, createdByIp, expiresAt, now, now);
|
|
510
535
|
const row = this.getMcpAccessTokenRow(tokenId, member.workspaceId);
|
|
511
536
|
if (!row) {
|
|
512
537
|
throw new TaskforceRuleError('Failed to create MCP token', 500, 'MCP_TOKEN_CREATE_FAILED');
|
|
@@ -573,18 +598,39 @@ export class McpTokenService {
|
|
|
573
598
|
workspaceId: revoked.workspaceId,
|
|
574
599
|
name: revoked.name,
|
|
575
600
|
scopes: revoked.scopes,
|
|
601
|
+
toolProfile: revoked.toolProfile,
|
|
576
602
|
expiresAt: revoked.expiresAt || null,
|
|
577
603
|
createdByIp: input.createdByIp || null,
|
|
578
604
|
});
|
|
579
605
|
});
|
|
580
606
|
return tx();
|
|
581
607
|
}
|
|
608
|
+
updateMcpAccessTokenToolProfile(input) {
|
|
609
|
+
this.requireMcpToolProfileAdministrator(input.actorUserId, input.workspaceId);
|
|
610
|
+
const row = this.getMcpAccessTokenRow(input.tokenId, input.workspaceId);
|
|
611
|
+
if (!row) {
|
|
612
|
+
throw new TaskforceRuleError('MCP token not found', 404, 'MCP_TOKEN_NOT_FOUND');
|
|
613
|
+
}
|
|
614
|
+
const previousToolProfile = this.normalizeMcpCloudToolProfile(row.tool_profile);
|
|
615
|
+
const toolProfile = this.requireMcpCloudToolProfile(input.toolProfile);
|
|
616
|
+
const now = new Date().toISOString();
|
|
617
|
+
this.db.prepare(`
|
|
618
|
+
UPDATE mcp_access_tokens
|
|
619
|
+
SET tool_profile = ?, updated_at = ?
|
|
620
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
621
|
+
`).run(toolProfile, now, this.tenantId, input.workspaceId, row.id);
|
|
622
|
+
const updated = this.getMcpAccessTokenRow(row.id, input.workspaceId);
|
|
623
|
+
if (!updated) {
|
|
624
|
+
throw new TaskforceRuleError('MCP token not found', 404, 'MCP_TOKEN_NOT_FOUND');
|
|
625
|
+
}
|
|
626
|
+
return { record: this.rowToMcpAccessTokenRecord(updated), previousToolProfile };
|
|
627
|
+
}
|
|
582
628
|
authenticateMcpAccessToken(token, workspaceId) {
|
|
583
629
|
const parsed = this.parseMcpAccessToken(token);
|
|
584
630
|
if (!parsed)
|
|
585
631
|
return null;
|
|
586
632
|
const row = this.db.prepare(`
|
|
587
|
-
SELECT id, workspace_id, user_id, scopes_json, token_hash, status, expires_at, revoked_at
|
|
633
|
+
SELECT id, workspace_id, user_id, scopes_json, tool_profile, token_hash, status, expires_at, revoked_at
|
|
588
634
|
FROM mcp_access_tokens
|
|
589
635
|
WHERE tenant_id = ?
|
|
590
636
|
AND token_prefix = ?
|
|
@@ -612,6 +658,7 @@ export class McpTokenService {
|
|
|
612
658
|
workspaceId: row.workspace_id,
|
|
613
659
|
userId: row.user_id,
|
|
614
660
|
scopes,
|
|
661
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
615
662
|
status,
|
|
616
663
|
};
|
|
617
664
|
}
|
|
@@ -620,7 +667,7 @@ export class McpTokenService {
|
|
|
620
667
|
if (!parsed)
|
|
621
668
|
return null;
|
|
622
669
|
const row = this.db.prepare(`
|
|
623
|
-
SELECT id, workspace_id, user_id, name, scopes_json, token_hash, status, expires_at, revoked_at
|
|
670
|
+
SELECT id, workspace_id, user_id, name, scopes_json, tool_profile, token_hash, status, expires_at, revoked_at
|
|
624
671
|
FROM mcp_access_tokens
|
|
625
672
|
WHERE tenant_id = ?
|
|
626
673
|
AND token_prefix = ?
|
|
@@ -644,6 +691,7 @@ export class McpTokenService {
|
|
|
644
691
|
userId: row.user_id,
|
|
645
692
|
name: String(row.name || ''),
|
|
646
693
|
scopes,
|
|
694
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
647
695
|
status: this.resolveMcpAccessTokenStatus(row),
|
|
648
696
|
};
|
|
649
697
|
}
|
|
@@ -783,7 +831,7 @@ export class McpTokenService {
|
|
|
783
831
|
const clientName = String(client.client_name || this.defaultMcpOAuthClientName(provider)).trim() || this.defaultMcpOAuthClientName(provider);
|
|
784
832
|
const tx = this.db.transaction(() => {
|
|
785
833
|
const existingRows = this.db.prepare(`
|
|
786
|
-
SELECT id, ai_profile_id, ai_profile_token, ai_profile_name
|
|
834
|
+
SELECT id, tool_profile, ai_profile_id, ai_profile_token, ai_profile_name
|
|
787
835
|
FROM mcp_oauth_connector_grants
|
|
788
836
|
WHERE tenant_id = ?
|
|
789
837
|
AND provider = ?
|
|
@@ -794,6 +842,7 @@ export class McpTokenService {
|
|
|
794
842
|
ORDER BY created_at DESC
|
|
795
843
|
`).all(this.tenantId, provider, String(client.id), String(row.user_id), String(row.workspace_id));
|
|
796
844
|
const previousBinding = existingRows.find((existing) => existing.ai_profile_id && existing.ai_profile_token && existing.ai_profile_name) || null;
|
|
845
|
+
const toolProfile = this.normalizeMcpCloudToolProfile(existingRows[0]?.tool_profile);
|
|
797
846
|
const revokeTime = new Date().toISOString();
|
|
798
847
|
existingRows.forEach((existing) => {
|
|
799
848
|
if (!existing?.id)
|
|
@@ -819,12 +868,12 @@ export class McpTokenService {
|
|
|
819
868
|
const tokenHash = hashMcpOAuthSecret(secret);
|
|
820
869
|
this.db.prepare(`
|
|
821
870
|
INSERT INTO mcp_oauth_connector_grants (
|
|
822
|
-
id, tenant_id, provider, client_id, client_name, product_client_id, user_id, workspace_id, scopes_json,
|
|
871
|
+
id, tenant_id, provider, client_id, client_name, product_client_id, user_id, workspace_id, scopes_json, tool_profile,
|
|
823
872
|
token_prefix, token_hash, status, last_used_at, revoked_at, revoked_by_user_id,
|
|
824
873
|
ai_profile_id, ai_profile_token, ai_profile_name, created_at, updated_at
|
|
825
874
|
)
|
|
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);
|
|
875
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NULL, NULL, NULL, ?, ?, ?, ?, ?)
|
|
876
|
+
`).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
877
|
this.db.prepare(`
|
|
829
878
|
UPDATE mcp_oauth_auth_codes
|
|
830
879
|
SET used_at = ?
|
|
@@ -909,12 +958,45 @@ export class McpTokenService {
|
|
|
909
958
|
}
|
|
910
959
|
return this.rowToMcpOAuthConnectorGrantRecord(updated);
|
|
911
960
|
}
|
|
961
|
+
updateMcpOAuthConnectorGrantToolProfile(input) {
|
|
962
|
+
this.requireMcpToolProfileAdministrator(input.actorUserId, input.workspaceId);
|
|
963
|
+
const row = this.db.prepare(`
|
|
964
|
+
SELECT *
|
|
965
|
+
FROM mcp_oauth_connector_grants
|
|
966
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
967
|
+
LIMIT 1
|
|
968
|
+
`).get(this.tenantId, input.workspaceId, String(input.grantId || '').trim());
|
|
969
|
+
if (!row?.id) {
|
|
970
|
+
throw new TaskforceRuleError('MCP connector grant not found', 404, 'MCP_OAUTH_GRANT_NOT_FOUND');
|
|
971
|
+
}
|
|
972
|
+
const previousToolProfile = this.normalizeMcpCloudToolProfile(row.tool_profile);
|
|
973
|
+
const toolProfile = this.requireMcpCloudToolProfile(input.toolProfile);
|
|
974
|
+
const now = new Date().toISOString();
|
|
975
|
+
this.db.prepare(`
|
|
976
|
+
UPDATE mcp_oauth_connector_grants
|
|
977
|
+
SET tool_profile = ?, updated_at = ?
|
|
978
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
979
|
+
`).run(toolProfile, now, this.tenantId, input.workspaceId, String(row.id));
|
|
980
|
+
const updated = this.db.prepare(`
|
|
981
|
+
SELECT *
|
|
982
|
+
FROM mcp_oauth_connector_grants
|
|
983
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
984
|
+
LIMIT 1
|
|
985
|
+
`).get(this.tenantId, input.workspaceId, String(row.id));
|
|
986
|
+
if (!updated) {
|
|
987
|
+
throw new TaskforceRuleError('MCP connector grant not found', 404, 'MCP_OAUTH_GRANT_NOT_FOUND');
|
|
988
|
+
}
|
|
989
|
+
return {
|
|
990
|
+
record: this.rowToMcpOAuthConnectorGrantRecord(updated),
|
|
991
|
+
previousToolProfile,
|
|
992
|
+
};
|
|
993
|
+
}
|
|
912
994
|
authenticateMcpOAuthAccessToken(token, workspaceId) {
|
|
913
995
|
const parsed = this.parseMcpOAuthOpaqueSecret(token, 'tfmcpoauth_');
|
|
914
996
|
if (!parsed)
|
|
915
997
|
return null;
|
|
916
998
|
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,
|
|
999
|
+
SELECT id, provider, client_id, product_client_id, user_id, workspace_id, scopes_json, tool_profile, token_hash, status, revoked_at,
|
|
918
1000
|
ai_profile_id, ai_profile_token, ai_profile_name
|
|
919
1001
|
FROM mcp_oauth_connector_grants
|
|
920
1002
|
WHERE tenant_id = ?
|
|
@@ -945,6 +1027,7 @@ export class McpTokenService {
|
|
|
945
1027
|
provider: this.normalizeMcpOAuthProvider(row.provider),
|
|
946
1028
|
productClientId: row?.product_client_id ? String(row.product_client_id) : null,
|
|
947
1029
|
scopes,
|
|
1030
|
+
toolProfile: this.normalizeMcpCloudToolProfile(row.tool_profile),
|
|
948
1031
|
status: this.resolveMcpOAuthGrantStatus(row),
|
|
949
1032
|
aiProfileId: row?.ai_profile_id ? String(row.ai_profile_id) : null,
|
|
950
1033
|
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
|
};
|