@taskforcehq/taskforce 0.3.328 → 0.3.330
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Taskforce.module.css +523 -79
- package/dist/TaskforceCore.js +237 -230
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
- package/dist/cli.js +34 -0
- package/dist/cliCloudTargetGuard.d.ts +5 -0
- package/dist/cliCloudTargetGuard.js +11 -0
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
- package/dist/components/features/TaskSettings.d.ts +12 -1
- package/dist/components/features/TaskSettings.js +217 -54
- package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
- package/dist/components/features/TaskforceAgentsModule.js +586 -116
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
- package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
- package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
- package/dist/components/features/planning/PlanningModule.js +2 -5
- package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
- package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
- package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
- package/dist/components/features/planning/planningTaskArrangement.js +5 -5
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +5 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskCard.d.ts +5 -0
- package/dist/components/task/TaskCard.js +65 -10
- package/dist/components/task/TaskImageReviews.js +14 -5
- package/dist/components/task/TaskKanban.d.ts +6 -1
- package/dist/components/task/TaskKanban.js +152 -6
- package/dist/components/task/TaskList.d.ts +5 -0
- package/dist/components/task/TaskList.js +3 -3
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/ui/PasswordInput.d.ts +6 -0
- package/dist/components/ui/PasswordInput.js +11 -0
- package/dist/components/ui/TopNoticeLayer.js +1 -1
- package/dist/components/views/AppShellHeader.js +32 -11
- package/dist/components/views/PlanComparisonPage.js +12 -0
- package/dist/components/views/StandaloneLayout.js +32 -55
- package/dist/components/views/WidgetView.js +3 -3
- package/dist/components/views/panels/PlanningDrawer.js +5 -12
- package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
- package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
- package/dist/config/envSchema.js +60 -1
- package/dist/config/localServiceRuntimeContract.d.ts +13 -0
- package/dist/config/localServiceRuntimeContract.js +135 -0
- package/dist/core/AiProfileService.js +46 -8
- package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
- package/dist/core/DeletedTaskLifecycleService.js +37 -6
- package/dist/core/McpTokenService.d.ts +23 -1
- package/dist/core/McpTokenService.js +93 -10
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
- package/dist/core/TaskChecklistCommandService.d.ts +27 -0
- package/dist/core/TaskChecklistCommandService.js +83 -5
- package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
- package/dist/core/TaskLifecycleCommandService.js +6 -2
- package/dist/core/Taskforce.d.ts +94 -2
- package/dist/core/Taskforce.js +760 -36
- package/dist/core/types.d.ts +14 -0
- package/dist/documentReviews/commandService.d.ts +2 -1
- package/dist/documentReviews/commandService.js +6 -3
- package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.js +2 -0
- package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
- package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
- package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
- package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
- package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
- package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
- package/dist/hooks/sync/useSyncStatusControls.js +47 -11
- package/dist/hooks/tasks/taskHttpMutation.js +1 -0
- package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
- package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
- package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
- package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
- package/dist/hooks/tasks/useTaskFormActions.js +65 -12
- package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
- package/dist/hooks/ui/useSettingsModel.js +13 -2
- package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
- package/dist/hooks/ui/useSettingsPersistence.js +74 -47
- package/dist/hooks/useFilterSort.d.ts +7 -3
- package/dist/hooks/useFilterSort.js +15 -5
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +40 -1
- package/dist/hooks/useTaskData.js +240 -9
- package/dist/hooks/useTaskMutations.d.ts +12 -2
- package/dist/hooks/useTaskMutations.js +266 -52
- package/dist/hooks/useTaskforce.d.ts +39 -9
- package/dist/hooks/useTaskforce.js +359 -40
- package/dist/hooks/useUiNotice.d.ts +4 -0
- package/dist/hooks/useUiNotice.js +4 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +53 -41
- package/dist/mcp/documentHelpers.d.ts +1 -0
- package/dist/mcp/documentHelpers.js +7 -3
- package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
- package/dist/mcp/durableTaskMutationRouter.js +10 -0
- package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
- package/dist/mcp/httpProtocolRouting.d.ts +10 -0
- package/dist/mcp/httpProtocolRouting.js +19 -0
- package/dist/mcp/localCliHealth.d.ts +2 -2
- package/dist/mcp/localCliHealth.js +2 -2
- package/dist/mcp/localServiceProxy.d.ts +1 -0
- package/dist/mcp/localServiceProxy.js +530 -68
- package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
- package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
- package/dist/mcp/runtime.d.ts +54 -79
- package/dist/mcp/runtime.js +556 -139
- package/dist/mcp/taskPlanningRegistrar.js +64 -42
- package/dist/mcp/toolCallCompatibility.js +38 -1
- package/dist/mcp/toolCatalog.d.ts +1 -0
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +10 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +1 -0
- package/dist/mcp/workflowExecutionRegistrar.js +4 -4
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +427 -0
- package/dist/runtime/appGateDefinitions.d.ts +30 -6
- package/dist/runtime/appGateDefinitions.js +6 -6
- package/dist/runtime/appGates.d.ts +13 -13
- package/dist/runtime/appGates.js +36 -13
- package/dist/runtime/nodeAppGates.d.ts +8 -0
- package/dist/runtime/nodeAppGates.js +27 -0
- package/dist/server/cloudCollectionRead.d.ts +1 -1
- package/dist/server/cloudCollectionRead.js +2 -2
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.js +123 -14
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.d.ts +3 -0
- package/dist/server/localServiceLease.js +11 -2
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +12 -7
- package/dist/server/rateLimit.d.ts +1 -0
- package/dist/server/rateLimit.js +4 -0
- package/dist/server/realtimeSyncWs.js +36 -12
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +113 -3
- package/dist/server/routes/agentRoles.js +3 -2
- package/dist/server/routes/agentSkills.js +3 -2
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +394 -39
- package/dist/server/routes/annotatedAttachments.js +3 -2
- package/dist/server/routes/auth.js +3 -1
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
- package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
- package/dist/server/routes/executorPhaseAApprovals.js +140 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
- package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
- package/dist/server/routes/githubReviewEvidence.js +116 -0
- package/dist/server/routes/localService.d.ts +15 -4
- package/dist/server/routes/localService.js +138 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/primitives.d.ts +2 -0
- package/dist/server/routes/shared.d.ts +19 -0
- package/dist/server/routes/shared.js +95 -19
- package/dist/server/routes/sync.js +1 -0
- package/dist/server/routes/syncAuxRoutes.js +9 -2
- package/dist/server/routes/syncPullApplyRoutes.js +23 -4
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +27 -16
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
- package/dist/server/routes/syncV3OperationRoutes.js +45 -9
- package/dist/server/routes/tasks.js +124 -13
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes/workspaces.js +43 -1
- package/dist/server/routes.js +59 -0
- package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
- package/dist/server/workspaceDeletionAdmission.js +50 -0
- package/dist/service/localServiceCli.js +16 -0
- package/dist/service/localServiceClientLifecycle.js +36 -10
- package/dist/services/codexAppServerModelGateway.d.ts +161 -0
- package/dist/services/codexAppServerModelGateway.js +663 -0
- package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
- package/dist/services/codexDeviceCodeLoginManager.js +265 -0
- package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
- package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
- package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
- package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
- package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
- package/dist/services/executorPhaseAApprovalService.js +609 -0
- package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
- package/dist/services/executorPhaseADriftEvaluator.js +93 -0
- package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
- package/dist/services/executorPhaseAIssuerCore.js +295 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
- package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
- package/dist/services/githubReviewEvidenceRuntime.js +30 -0
- package/dist/services/githubReviewEvidenceService.d.ts +93 -0
- package/dist/services/githubReviewEvidenceService.js +336 -0
- package/dist/services/modelGateway.d.ts +7 -0
- package/dist/services/modelProviderConnectionService.d.ts +71 -0
- package/dist/services/modelProviderConnectionService.js +279 -0
- package/dist/services/modelProviderCredentialHome.d.ts +32 -0
- package/dist/services/modelProviderCredentialHome.js +271 -0
- package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
- package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
- package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
- package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +8 -2
- package/dist/services/taskforceAgentMcpBridge.js +30 -27
- package/dist/shared/adminEdgeProxy.d.ts +5 -0
- package/dist/shared/adminEdgeProxy.js +94 -0
- package/dist/shared/adminProxySessionCookies.d.ts +16 -0
- package/dist/shared/adminProxySessionCookies.js +86 -0
- package/dist/shared/aiProfileColors.d.ts +31 -1
- package/dist/shared/aiProfileColors.js +14 -6
- package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
- package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
- package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
- package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
- package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
- package/dist/shared/executorPhaseADriftContracts.js +63 -0
- package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
- package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
- package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
- package/dist/shared/executorPhaseARunAuthorization.js +232 -0
- package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
- package/dist/shared/executorPhaseASchemaValidation.js +53 -0
- package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
- package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
- package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
- package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
- package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
- package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
- package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
- package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
- package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
- package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
- package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
- package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
- package/dist/shared/executorPhaseATiming.d.ts +1 -0
- package/dist/shared/executorPhaseATiming.js +1 -0
- package/dist/shared/planningIdentity.js +1 -1
- package/dist/shared/productLogoKeys.d.ts +2 -0
- package/dist/shared/productLogoKeys.js +18 -0
- package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
- package/dist/shared/taskforceAgentDefinition.js +6 -3
- package/dist/shared/taskforceAgentModels.d.ts +1 -0
- package/dist/shared/taskforceAgentModels.js +36 -3
- package/dist/shared/userFeatureGrants.d.ts +4 -0
- package/dist/shared/userFeatureGrants.js +7 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
- package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
- package/dist/storage/modelProviderConnectionStore.js +446 -0
- package/dist/storage/postgresAdapter.d.ts +24 -3
- package/dist/storage/postgresAdapter.js +117 -14
- package/dist/storage/postgresWorker.js +22 -5
- package/dist/storage/postgresWorkerProtocol.d.ts +30 -0
- package/dist/storage/postgresWorkerProtocol.js +30 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/sync/cloudSyncApi.d.ts +4 -1
- package/dist/sync/cloudSyncApi.js +7 -2
- package/dist/sync/contentSyncState.d.ts +1 -1
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +67 -30
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
- package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
- package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
- package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
- package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
- package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
- package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +134 -43
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +11 -4
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
- package/dist/sync/syncApplyHandlers.d.ts +2 -0
- package/dist/sync/syncApplyHandlers.js +10 -1
- package/dist/sync/syncService.d.ts +17 -0
- package/dist/sync/syncService.js +87 -19
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +8 -0
- package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
- package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
- package/dist/sync/v3/durableOperationReplay.js +18 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +2 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +14 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +4 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +62 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +37 -2
- package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
- package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
- package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
- package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
- package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
- package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
- package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
- package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
- package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
- package/dist/sync/v3/localTaskMetadataClient.js +1 -0
- package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
- package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
- package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
- package/dist/sync/v3/localTaskStatusClient.js +6 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +272 -24
- package/dist/sync/v3/syncDurabilityStore.d.ts +41 -0
- package/dist/sync/v3/syncDurabilityStore.js +199 -13
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
- package/dist/sync/v3/taskChecklistMutationService.d.ts +15 -2
- package/dist/sync/v3/taskChecklistMutationService.js +48 -1
- package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
- package/dist/sync/v3/taskCreateMutationService.js +7 -4
- package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
- package/dist/sync/v3/taskMetadataMutationService.js +4 -0
- package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
- package/dist/sync/v3/taskRestoreMutationService.js +7 -4
- package/dist/sync/v3/taskStatusMutationService.d.ts +31 -1
- package/dist/sync/v3/taskStatusMutationService.js +123 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +6 -0
- package/dist/sync/v3/workflowAssignmentSync.js +30 -0
- package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
- package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
- package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +18 -3
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +14 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +49 -25
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +13 -4
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -57
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +20 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +106 -30
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +4 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +34 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +12 -0
- package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +55 -9
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
- package/dist/sync/workspacePullFeed.js +2 -1
- package/dist/sync/workspaceRepair.d.ts +8 -2
- package/dist/sync/workspaceRepair.js +222 -6
- package/dist/sync/workspaceSyncModel.d.ts +21 -0
- package/dist/sync/workspaceSyncModel.js +35 -7
- package/dist/sync/workspaceSyncState.d.ts +1 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
- package/dist/types.d.ts +47 -1
- package/dist/types.js +6 -0
- package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
- package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTM6nIg_.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
- package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-DabEG8L4.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Coa8yVGM.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-BB0qhdix.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
- package/dist/ui/assets/PlanningModule-pRPjR7v5.js +1 -0
- package/dist/ui/assets/PlansPage-D86pZSSl.js +1 -0
- package/dist/ui/assets/TaskContextUpload-BVIkU9yT.js +1 -0
- package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
- package/dist/ui/assets/{WorkflowManagerModule-DWFspC-o.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-CTsDBaef.js +7 -0
- package/dist/ui/assets/{vendor-icons-BkFLXavV.js → vendor-icons-Bsq-mcEn.js} +1 -1
- package/dist/ui/branding/logos/letterhead_dark.png +0 -0
- package/dist/ui/branding/logos/letterhead_light.png +0 -0
- package/dist/ui/branding/logos/signature_dark.png +0 -0
- package/dist/ui/branding/logos/signature_light.png +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/aiProfileDefaultLogo.js +16 -48
- package/dist/utils/httpSetCookie.d.ts +1 -0
- package/dist/utils/httpSetCookie.js +4 -1
- package/dist/utils/localRuntimeUrl.d.ts +1 -0
- package/dist/utils/localRuntimeUrl.js +14 -0
- package/dist/utils/productLogoRegistry.d.ts +2 -0
- package/dist/utils/productLogoRegistry.js +36 -0
- package/dist/utils/syncStatusPresentation.d.ts +4 -0
- package/dist/utils/syncStatusPresentation.js +17 -0
- package/dist/utils/taskActivity.d.ts +3 -2
- package/dist/utils/taskActivity.js +19 -2
- package/dist/utils/taskEditorReconciliation.d.ts +40 -0
- package/dist/utils/taskEditorReconciliation.js +217 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/taskNormalization.d.ts +1 -0
- package/dist/utils/taskNormalization.js +39 -0
- package/dist/utils/taskSearch.js +2 -2
- package/dist/utils/uiNotice.d.ts +4 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +36 -6
- package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +0 -1
- package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
- package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
- package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
- package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
- package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-BUplSsv_.js +0 -7
- package/dist/ui/assets/index-gz2EXuoK.css +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class OwnerScopedModelConnectionGateway {
|
|
2
|
+
connectionService;
|
|
3
|
+
ownerUserId;
|
|
4
|
+
connectionId;
|
|
5
|
+
createGateway;
|
|
6
|
+
constructor(connectionService, ownerUserId, connectionId, createGateway) {
|
|
7
|
+
this.connectionService = connectionService;
|
|
8
|
+
this.ownerUserId = ownerUserId;
|
|
9
|
+
this.connectionId = connectionId;
|
|
10
|
+
this.createGateway = createGateway;
|
|
11
|
+
}
|
|
12
|
+
generate(input) {
|
|
13
|
+
return this.connectionService.withConnectionLease({
|
|
14
|
+
ownerUserId: this.ownerUserId,
|
|
15
|
+
connectionId: this.connectionId,
|
|
16
|
+
operation: 'invoke',
|
|
17
|
+
}, async (context) => {
|
|
18
|
+
const result = await this.createGateway(context).generate(input);
|
|
19
|
+
return {
|
|
20
|
+
...result,
|
|
21
|
+
sourceMetadata: {
|
|
22
|
+
modelSource: 'subscription_dev',
|
|
23
|
+
connectionScope: 'personal',
|
|
24
|
+
providerKey: context.connection.providerKey,
|
|
25
|
+
billable: false,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { TaskforceAgentStore } from '../storage/taskforceAgentStore.js';
|
|
2
|
+
import type { ModelProviderConnectionRecord, ModelProviderConnectionStore } from '../storage/modelProviderConnectionStore.js';
|
|
3
|
+
import type { TaskforceAgentConnectionBindingRecord, TaskforceAgentConnectionBindingStore } from '../storage/taskforceAgentConnectionBindingStore.js';
|
|
4
|
+
import type { ModelProviderConnectionService } from './modelProviderConnectionService.js';
|
|
5
|
+
export declare class TaskforceAgentConnectionBindingError extends Error {
|
|
6
|
+
readonly statusCode: number;
|
|
7
|
+
readonly code: string;
|
|
8
|
+
constructor(message: string, statusCode: number, code: string);
|
|
9
|
+
}
|
|
10
|
+
type AgentStore = Pick<TaskforceAgentStore, 'get'>;
|
|
11
|
+
type ConnectionStore = Pick<ModelProviderConnectionStore, 'getOwned'>;
|
|
12
|
+
type BindingStore = Pick<TaskforceAgentConnectionBindingStore, 'get' | 'bind' | 'clear'>;
|
|
13
|
+
type ConnectionRuntime = Pick<ModelProviderConnectionService, 'assertReady' | 'withConnectionLease'>;
|
|
14
|
+
export interface ResolvedTaskforceAgentConnectionBinding {
|
|
15
|
+
binding: TaskforceAgentConnectionBindingRecord;
|
|
16
|
+
connection: ModelProviderConnectionRecord;
|
|
17
|
+
}
|
|
18
|
+
export interface PublicTaskforceAgentConnectionBinding {
|
|
19
|
+
bound: boolean;
|
|
20
|
+
available: boolean;
|
|
21
|
+
providerKey?: string;
|
|
22
|
+
modelSource?: string;
|
|
23
|
+
ownerIsCaller?: boolean;
|
|
24
|
+
connectionId?: string;
|
|
25
|
+
reasonCode?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class TaskforceAgentConnectionBindingService {
|
|
28
|
+
private readonly bindings;
|
|
29
|
+
private readonly agents;
|
|
30
|
+
private readonly connections;
|
|
31
|
+
private readonly connectionRuntime;
|
|
32
|
+
private readonly hasGrant;
|
|
33
|
+
constructor(bindings: BindingStore, agents: AgentStore, connections: ConnectionStore, connectionRuntime: ConnectionRuntime, hasGrant: (userId: string) => boolean);
|
|
34
|
+
inspect(input: {
|
|
35
|
+
workspaceId: string;
|
|
36
|
+
agentId: string;
|
|
37
|
+
callerUserId: string;
|
|
38
|
+
}): PublicTaskforceAgentConnectionBinding;
|
|
39
|
+
bind(input: {
|
|
40
|
+
workspaceId: string;
|
|
41
|
+
agentId: string;
|
|
42
|
+
connectionId: string;
|
|
43
|
+
actorUserId: string;
|
|
44
|
+
}): Promise<TaskforceAgentConnectionBindingRecord>;
|
|
45
|
+
clear(input: {
|
|
46
|
+
workspaceId: string;
|
|
47
|
+
agentId: string;
|
|
48
|
+
actorUserId: string;
|
|
49
|
+
}): boolean;
|
|
50
|
+
resolveSaved(input: {
|
|
51
|
+
workspaceId: string;
|
|
52
|
+
agentId: string;
|
|
53
|
+
callerUserId: string;
|
|
54
|
+
}): ResolvedTaskforceAgentConnectionBinding;
|
|
55
|
+
resolveDraft(input: {
|
|
56
|
+
callerUserId: string;
|
|
57
|
+
connectionId: string;
|
|
58
|
+
providerKey: string;
|
|
59
|
+
}): ModelProviderConnectionRecord;
|
|
60
|
+
private requireBindableAgentSelection;
|
|
61
|
+
private requireOwnedActiveConnection;
|
|
62
|
+
private requireOwnedReadyConnection;
|
|
63
|
+
private assertCompatibleConnection;
|
|
64
|
+
private assertGranted;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
export class TaskforceAgentConnectionBindingError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
code;
|
|
4
|
+
constructor(message, statusCode, code) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.name = 'TaskforceAgentConnectionBindingError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const SUBSCRIPTION_AUTHENTICATION_TYPES = {
|
|
12
|
+
openai: 'chatgpt_device_code',
|
|
13
|
+
};
|
|
14
|
+
function requireIdentity(value) {
|
|
15
|
+
const normalized = String(value || '').trim();
|
|
16
|
+
if (!normalized) {
|
|
17
|
+
throw new TaskforceAgentConnectionBindingError('Authentication is required.', 401, 'AUTH_REQUIRED');
|
|
18
|
+
}
|
|
19
|
+
return normalized;
|
|
20
|
+
}
|
|
21
|
+
export class TaskforceAgentConnectionBindingService {
|
|
22
|
+
bindings;
|
|
23
|
+
agents;
|
|
24
|
+
connections;
|
|
25
|
+
connectionRuntime;
|
|
26
|
+
hasGrant;
|
|
27
|
+
constructor(bindings, agents, connections, connectionRuntime, hasGrant) {
|
|
28
|
+
this.bindings = bindings;
|
|
29
|
+
this.agents = agents;
|
|
30
|
+
this.connections = connections;
|
|
31
|
+
this.connectionRuntime = connectionRuntime;
|
|
32
|
+
this.hasGrant = hasGrant;
|
|
33
|
+
}
|
|
34
|
+
inspect(input) {
|
|
35
|
+
const callerUserId = requireIdentity(input.callerUserId);
|
|
36
|
+
const agent = this.agents.get(input.workspaceId, input.agentId);
|
|
37
|
+
if (!agent || agent.deletedAt) {
|
|
38
|
+
throw new TaskforceAgentConnectionBindingError('Taskforce Agent was not found.', 404, 'TASKFORCE_AGENT_NOT_FOUND');
|
|
39
|
+
}
|
|
40
|
+
const binding = this.bindings.get(input.workspaceId, input.agentId);
|
|
41
|
+
if (!binding)
|
|
42
|
+
return { bound: false, available: false, reasonCode: 'MODEL_CONNECTION_REQUIRED' };
|
|
43
|
+
const selection = agent.definition?.model;
|
|
44
|
+
const ownerIsCaller = binding.ownerUserId === callerUserId;
|
|
45
|
+
const callerGranted = this.hasGrant(callerUserId);
|
|
46
|
+
const ownerGranted = this.hasGrant(binding.ownerUserId);
|
|
47
|
+
let connectionReady = false;
|
|
48
|
+
if (callerGranted && ownerGranted) {
|
|
49
|
+
try {
|
|
50
|
+
const connection = this.requireOwnedReadyConnection(binding.ownerUserId, binding.connectionId, binding.providerKey);
|
|
51
|
+
connectionReady = Boolean(connection);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
connectionReady = false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const available = Boolean(connectionReady
|
|
58
|
+
&& selection?.providerKey === binding.providerKey
|
|
59
|
+
&& selection?.modelSource === binding.modelSource);
|
|
60
|
+
return {
|
|
61
|
+
bound: true,
|
|
62
|
+
available,
|
|
63
|
+
providerKey: binding.providerKey,
|
|
64
|
+
modelSource: binding.modelSource,
|
|
65
|
+
ownerIsCaller,
|
|
66
|
+
...(ownerIsCaller ? { connectionId: binding.connectionId } : {}),
|
|
67
|
+
...(available ? {} : { reasonCode: 'MODEL_CONNECTION_UNAVAILABLE' }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async bind(input) {
|
|
71
|
+
const actorUserId = requireIdentity(input.actorUserId);
|
|
72
|
+
this.assertGranted(actorUserId);
|
|
73
|
+
const selection = this.requireBindableAgentSelection(input.workspaceId, input.agentId);
|
|
74
|
+
const existing = this.bindings.get(input.workspaceId, input.agentId);
|
|
75
|
+
if (existing && existing.ownerUserId !== actorUserId) {
|
|
76
|
+
throw new TaskforceAgentConnectionBindingError('Only the current connection owner can replace this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
77
|
+
}
|
|
78
|
+
return this.connectionRuntime.withConnectionLease({
|
|
79
|
+
ownerUserId: actorUserId,
|
|
80
|
+
connectionId: String(input.connectionId || '').trim(),
|
|
81
|
+
operation: 'invoke',
|
|
82
|
+
}, async (context) => {
|
|
83
|
+
this.assertCompatibleConnection(context.connection, selection.providerKey);
|
|
84
|
+
const binding = this.bindings.bind({
|
|
85
|
+
workspaceId: input.workspaceId,
|
|
86
|
+
agentId: input.agentId,
|
|
87
|
+
connectionId: context.connection.id,
|
|
88
|
+
ownerUserId: actorUserId,
|
|
89
|
+
providerKey: selection.providerKey,
|
|
90
|
+
modelSource: selection.modelSource,
|
|
91
|
+
actorUserId,
|
|
92
|
+
});
|
|
93
|
+
if (!binding) {
|
|
94
|
+
throw new TaskforceAgentConnectionBindingError('Only the current connection owner can replace this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
95
|
+
}
|
|
96
|
+
return binding;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
clear(input) {
|
|
100
|
+
const actorUserId = requireIdentity(input.actorUserId);
|
|
101
|
+
const binding = this.bindings.get(input.workspaceId, input.agentId);
|
|
102
|
+
if (!binding)
|
|
103
|
+
return false;
|
|
104
|
+
if (binding.ownerUserId !== actorUserId) {
|
|
105
|
+
throw new TaskforceAgentConnectionBindingError('Only the connection owner can clear this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
106
|
+
}
|
|
107
|
+
const cleared = this.bindings.clear(input.workspaceId, input.agentId, actorUserId);
|
|
108
|
+
if (cleared)
|
|
109
|
+
return true;
|
|
110
|
+
const current = this.bindings.get(input.workspaceId, input.agentId);
|
|
111
|
+
if (current && current.ownerUserId !== actorUserId) {
|
|
112
|
+
throw new TaskforceAgentConnectionBindingError('Only the connection owner can clear this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
resolveSaved(input) {
|
|
117
|
+
const callerUserId = requireIdentity(input.callerUserId);
|
|
118
|
+
this.assertGranted(callerUserId);
|
|
119
|
+
const selection = this.requireBindableAgentSelection(input.workspaceId, input.agentId);
|
|
120
|
+
const binding = this.bindings.get(input.workspaceId, input.agentId);
|
|
121
|
+
if (!binding) {
|
|
122
|
+
throw new TaskforceAgentConnectionBindingError('Connect this Agent to an eligible model account before running it.', 409, 'AGENT_MODEL_CONNECTION_REQUIRED');
|
|
123
|
+
}
|
|
124
|
+
this.assertGranted(binding.ownerUserId);
|
|
125
|
+
if (binding.providerKey !== selection.providerKey || binding.modelSource !== selection.modelSource) {
|
|
126
|
+
throw new TaskforceAgentConnectionBindingError('The saved Agent model selection no longer matches its local connection.', 409, 'AGENT_MODEL_CONNECTION_MISMATCH');
|
|
127
|
+
}
|
|
128
|
+
const connection = this.requireOwnedReadyConnection(binding.ownerUserId, binding.connectionId, binding.providerKey);
|
|
129
|
+
return { binding, connection };
|
|
130
|
+
}
|
|
131
|
+
resolveDraft(input) {
|
|
132
|
+
const callerUserId = requireIdentity(input.callerUserId);
|
|
133
|
+
this.assertGranted(callerUserId);
|
|
134
|
+
return this.requireOwnedReadyConnection(callerUserId, input.connectionId, input.providerKey);
|
|
135
|
+
}
|
|
136
|
+
requireBindableAgentSelection(workspaceId, agentId) {
|
|
137
|
+
const agent = this.agents.get(workspaceId, agentId);
|
|
138
|
+
if (!agent || agent.deletedAt) {
|
|
139
|
+
throw new TaskforceAgentConnectionBindingError('Taskforce Agent was not found.', 404, 'TASKFORCE_AGENT_NOT_FOUND');
|
|
140
|
+
}
|
|
141
|
+
const model = agent.definition?.model;
|
|
142
|
+
if (!model
|
|
143
|
+
|| model.modelSource !== 'subscription_dev'
|
|
144
|
+
|| (model.connectionScope !== 'personal' && model.connectionScope !== 'local_dev')) {
|
|
145
|
+
throw new TaskforceAgentConnectionBindingError('This Agent does not use a personal subscription model connection.', 409, 'AGENT_MODEL_CONNECTION_NOT_APPLICABLE');
|
|
146
|
+
}
|
|
147
|
+
return model;
|
|
148
|
+
}
|
|
149
|
+
requireOwnedActiveConnection(ownerUserId, connectionIdRaw, providerKey) {
|
|
150
|
+
const connectionId = String(connectionIdRaw || '').trim();
|
|
151
|
+
const connection = connectionId
|
|
152
|
+
? this.connections.getOwned(ownerUserId, connectionId)
|
|
153
|
+
: null;
|
|
154
|
+
if (!connection) {
|
|
155
|
+
throw new TaskforceAgentConnectionBindingError('Model connection was not found.', 404, 'MODEL_CONNECTION_NOT_FOUND');
|
|
156
|
+
}
|
|
157
|
+
if (connection.providerKey !== providerKey) {
|
|
158
|
+
throw new TaskforceAgentConnectionBindingError('The model connection does not match the selected provider.', 409, 'MODEL_CONNECTION_PROVIDER_MISMATCH');
|
|
159
|
+
}
|
|
160
|
+
if (connection.lifecycleStatus !== 'active') {
|
|
161
|
+
throw new TaskforceAgentConnectionBindingError('The model connection is not active.', 409, 'MODEL_CONNECTION_INACTIVE');
|
|
162
|
+
}
|
|
163
|
+
this.assertCompatibleConnection(connection, providerKey);
|
|
164
|
+
return connection;
|
|
165
|
+
}
|
|
166
|
+
requireOwnedReadyConnection(ownerUserId, connectionId, providerKey) {
|
|
167
|
+
this.requireOwnedActiveConnection(ownerUserId, connectionId, providerKey);
|
|
168
|
+
const connection = this.connectionRuntime.assertReady(ownerUserId, connectionId);
|
|
169
|
+
this.assertCompatibleConnection(connection, providerKey);
|
|
170
|
+
return connection;
|
|
171
|
+
}
|
|
172
|
+
assertCompatibleConnection(connection, providerKey) {
|
|
173
|
+
const expectedAuthenticationType = SUBSCRIPTION_AUTHENTICATION_TYPES[providerKey];
|
|
174
|
+
if (!expectedAuthenticationType
|
|
175
|
+
|| connection.providerKey !== providerKey
|
|
176
|
+
|| connection.authenticationType !== expectedAuthenticationType) {
|
|
177
|
+
throw new TaskforceAgentConnectionBindingError('The model connection is not compatible with this subscription model.', 409, 'MODEL_CONNECTION_AUTHENTICATION_MISMATCH');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
assertGranted(userId) {
|
|
181
|
+
if (this.hasGrant(userId))
|
|
182
|
+
return;
|
|
183
|
+
throw new TaskforceAgentConnectionBindingError('Subscription-backed models are not enabled for this account.', 403, 'SUBSCRIPTION_MODEL_ACCESS_REQUIRED');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type TaskforceCore } from '../core/Taskforce.js';
|
|
2
|
+
import { createTaskforceMcpServer } from '../mcp/runtime.js';
|
|
2
3
|
import { type ManagedAgentMcpToolProfile } from '../mcp/toolProfiles.js';
|
|
3
4
|
import { type McpToolName } from '../mcp/toolRegistry.js';
|
|
4
5
|
import type { AgentToolPolicy } from '../shared/taskforceAgentDefinition.js';
|
|
@@ -33,8 +34,12 @@ export type PrepareTaskforceAgentMcpBridgeInput = {
|
|
|
33
34
|
readOnly?: boolean;
|
|
34
35
|
toolProfile?: ManagedAgentMcpToolProfile;
|
|
35
36
|
toolPolicy?: AgentToolPolicy;
|
|
37
|
+
executionRequestId: string;
|
|
36
38
|
system: string;
|
|
37
39
|
};
|
|
40
|
+
type PrepareTaskforceAgentMcpBridgeDependencies = {
|
|
41
|
+
createMcpServer?: typeof createTaskforceMcpServer;
|
|
42
|
+
};
|
|
38
43
|
export declare const MANAGED_AGENT_LIST_TASKS_DEFAULT_LIMIT = 25;
|
|
39
44
|
export declare const MANAGED_AGENT_LIST_TASKS_MAX_LIMIT = 50;
|
|
40
45
|
export declare const MANAGED_AGENT_TOOL_RESULT_MAX_BYTES: number;
|
|
@@ -50,8 +55,9 @@ type McpToolDescriptor = {
|
|
|
50
55
|
export declare function hashTaskforceAgentMcpToolContract(tools: McpToolDescriptor[]): string;
|
|
51
56
|
export declare function isTaskforceAgentMutationToolName(name: string): boolean;
|
|
52
57
|
export declare function taskforceAgentMutationCallKey(name: string, argumentsValue: Record<string, unknown>): string | null;
|
|
58
|
+
export declare function taskforceAgentMcpRequestId(call: TaskforceAgentMcpToolCall): string;
|
|
53
59
|
declare const MANAGED_AGENT_CAPABILITY_TOOLS: Readonly<{
|
|
54
|
-
readonly tasks: readonly ["add_comment", "add_task_checklist_item", "complete_workflow_step", "get_schedule_board", "get_stats", "get_task", "get_task_attachments", "get_task_checklist", "get_task_workflow", "list_task_relationships", "list_tasks", "replace_task_checklist", "search_tasks"];
|
|
60
|
+
readonly tasks: readonly ["add_comment", "add_task_checklist_item", "complete_workflow_step", "get_schedule_board", "get_stats", "get_task", "get_task_attachments", "get_task_checklist", "get_task_workflow", "list_task_relationships", "list_tasks", "replace_task_checklist", "search_tasks", "update_task_checklist_item"];
|
|
55
61
|
readonly planning: readonly ["add_initiative_comment", "add_workstream_comment", "get_initiative", "get_workstream", "list_initiatives", "list_workstreams"];
|
|
56
62
|
readonly documents: readonly ["get_document", "get_document_reviews", "search_documents"];
|
|
57
63
|
readonly images: readonly ["get_image", "get_image_annotations", "search_images"];
|
|
@@ -72,6 +78,6 @@ type BoundedManagedAgentToolResult = {
|
|
|
72
78
|
rejected: boolean;
|
|
73
79
|
};
|
|
74
80
|
export declare function boundManagedAgentMcpToolResult(toolName: string, text: string): BoundedManagedAgentToolResult;
|
|
75
|
-
export declare function prepareTaskforceAgentMcpBridge(input: PrepareTaskforceAgentMcpBridgeInput): Promise<PreparedTaskforceAgentMcpBridge | null>;
|
|
81
|
+
export declare function prepareTaskforceAgentMcpBridge(input: PrepareTaskforceAgentMcpBridgeInput, dependencies?: PrepareTaskforceAgentMcpBridgeDependencies): Promise<PreparedTaskforceAgentMcpBridge | null>;
|
|
76
82
|
export declare function serializeTaskforceAgentMcpToolResult(result: TaskforceAgentMcpToolResult): Record<string, unknown>;
|
|
77
83
|
export {};
|
|
@@ -31,9 +31,19 @@ export function taskforceAgentMutationCallKey(name, argumentsValue) {
|
|
|
31
31
|
return null;
|
|
32
32
|
return `${normalizedName}:${serializeCanonicalJson(argumentsValue || {})}`;
|
|
33
33
|
}
|
|
34
|
+
export function taskforceAgentMcpRequestId(call) {
|
|
35
|
+
return `managed-agent-${createHash('sha256')
|
|
36
|
+
.update(serializeCanonicalJson({
|
|
37
|
+
name: String(call.name || '').trim(),
|
|
38
|
+
arguments: call.arguments || {},
|
|
39
|
+
}))
|
|
40
|
+
.digest('hex')
|
|
41
|
+
.slice(0, 32)}`;
|
|
42
|
+
}
|
|
34
43
|
const TASK_SCOPED_MUTATION_TOOL_NAMES = new Set([
|
|
35
44
|
'add_comment',
|
|
36
45
|
'add_task_checklist_item',
|
|
46
|
+
'update_task_checklist_item',
|
|
37
47
|
'replace_task_checklist',
|
|
38
48
|
'complete_workflow_step',
|
|
39
49
|
]);
|
|
@@ -52,6 +62,7 @@ const MANAGED_AGENT_CAPABILITY_TOOLS = Object.freeze({
|
|
|
52
62
|
'list_tasks',
|
|
53
63
|
'replace_task_checklist',
|
|
54
64
|
'search_tasks',
|
|
65
|
+
'update_task_checklist_item',
|
|
55
66
|
],
|
|
56
67
|
planning: [
|
|
57
68
|
'add_initiative_comment',
|
|
@@ -120,21 +131,8 @@ export function resolveManagedAgentMcpToolNames(toolPolicy, profile = MCP_MANAGE
|
|
|
120
131
|
}
|
|
121
132
|
return Array.from(effective).sort((left, right) => left.localeCompare(right));
|
|
122
133
|
}
|
|
123
|
-
function getRuntimeHandler(runtime, method) {
|
|
124
|
-
const handler = runtime.server._requestHandlers?.get(method);
|
|
125
|
-
if (typeof handler !== 'function') {
|
|
126
|
-
throw new Error(`Taskforce MCP ${method} handler is unavailable.`);
|
|
127
|
-
}
|
|
128
|
-
return handler;
|
|
129
|
-
}
|
|
130
134
|
async function listRuntimeTools(runtime) {
|
|
131
|
-
const
|
|
132
|
-
const result = await handler({
|
|
133
|
-
jsonrpc: '2.0',
|
|
134
|
-
id: 'taskforce-agent-tools-list',
|
|
135
|
-
method: 'tools/list',
|
|
136
|
-
params: {},
|
|
137
|
-
}, {});
|
|
135
|
+
const result = await runtime.listTools();
|
|
138
136
|
return Array.isArray(result?.tools) ? result.tools : [];
|
|
139
137
|
}
|
|
140
138
|
function compactText(value, maxLength) {
|
|
@@ -199,7 +197,7 @@ function buildToolInstructions(baseSystem, tools, allowedMutationTaskId, readOnl
|
|
|
199
197
|
? 'Allowed writes: task comments, checklist changes, and completion of the current owned workflow step. Use complete_workflow_step only after finishing that step.'
|
|
200
198
|
: 'Allowed writes: task comments and checklist changes.',
|
|
201
199
|
...(canCompleteWorkflow && !readOnly ? [
|
|
202
|
-
'For workflow-step work, call get_task_workflow before acting. If requiresCommentEvidence is true, call add_comment and
|
|
200
|
+
'For workflow-step work, call get_task_workflow before acting. Reuse its completionCall arguments exactly; never invent or reuse workflow IDs. If requiresCommentEvidence is true, call add_comment and add its returned comment.id as evidenceCommentId. After all required work succeeds, call complete_workflow_step before answering. A comment or other task mutation does not complete the workflow step.',
|
|
203
201
|
] : []),
|
|
204
202
|
...(taskScope ? [`This run is task-scoped to ${taskScope}. Mutating Taskforce tools must target only this task.`] : []),
|
|
205
203
|
'To use a Taskforce tool, respond with only one JSON object and no prose:',
|
|
@@ -284,6 +282,14 @@ function utf8ByteLength(value) {
|
|
|
284
282
|
return Buffer.byteLength(value, 'utf8');
|
|
285
283
|
}
|
|
286
284
|
export function normalizeManagedAgentMcpToolCall(call) {
|
|
285
|
+
if (call.name === 'get_task_workflow' || call.name === 'complete_workflow_step') {
|
|
286
|
+
const args = { ...call.arguments };
|
|
287
|
+
if (!String(args.taskId || '').trim() && String(args.id || '').trim()) {
|
|
288
|
+
args.taskId = args.id;
|
|
289
|
+
}
|
|
290
|
+
delete args.id;
|
|
291
|
+
return { name: call.name, arguments: args };
|
|
292
|
+
}
|
|
287
293
|
if (call.name !== 'list_tasks')
|
|
288
294
|
return call;
|
|
289
295
|
const args = { ...call.arguments };
|
|
@@ -438,7 +444,7 @@ function buildManagedAgentToolResultMessage(result, workflowReminder) {
|
|
|
438
444
|
'Use a narrower Taskforce read before answering the user.',
|
|
439
445
|
].join('\n');
|
|
440
446
|
}
|
|
441
|
-
export async function prepareTaskforceAgentMcpBridge(input) {
|
|
447
|
+
export async function prepareTaskforceAgentMcpBridge(input, dependencies = {}) {
|
|
442
448
|
if (!input.core)
|
|
443
449
|
return null;
|
|
444
450
|
if (input.runtimeMode !== 'cloud') {
|
|
@@ -454,7 +460,7 @@ export async function prepareTaskforceAgentMcpBridge(input) {
|
|
|
454
460
|
}
|
|
455
461
|
if (!input.agentProfileId)
|
|
456
462
|
managedToolNames.delete('complete_workflow_step');
|
|
457
|
-
const runtime = createTaskforceMcpServer({
|
|
463
|
+
const runtime = (dependencies.createMcpServer || createTaskforceMcpServer)({
|
|
458
464
|
core: input.core,
|
|
459
465
|
workspaceId: input.workspaceId,
|
|
460
466
|
runtimeMode: input.runtimeMode,
|
|
@@ -469,6 +475,7 @@ export async function prepareTaskforceAgentMcpBridge(input) {
|
|
|
469
475
|
aiProfileProvider: input.providerKey || 'taskforce_hq',
|
|
470
476
|
aiProfileModel: input.modelKey || null,
|
|
471
477
|
aiProfileSurfaceType: 'agent',
|
|
478
|
+
requestId: input.executionRequestId,
|
|
472
479
|
},
|
|
473
480
|
});
|
|
474
481
|
const tools = (await listRuntimeTools(runtime))
|
|
@@ -477,7 +484,6 @@ export async function prepareTaskforceAgentMcpBridge(input) {
|
|
|
477
484
|
if (tools.length === 0)
|
|
478
485
|
return null;
|
|
479
486
|
const availableToolNames = new Set(tools.map((tool) => tool.name));
|
|
480
|
-
const callTool = getRuntimeHandler(runtime, 'tools/call');
|
|
481
487
|
return {
|
|
482
488
|
system: buildToolInstructions(input.system, tools, input.allowedMutationTaskId, input.readOnly),
|
|
483
489
|
availableToolNames: Array.from(availableToolNames),
|
|
@@ -491,15 +497,12 @@ export async function prepareTaskforceAgentMcpBridge(input) {
|
|
|
491
497
|
if (scopeFailure)
|
|
492
498
|
return scopeFailure;
|
|
493
499
|
const effectiveCall = normalizeManagedAgentMcpToolCall(call);
|
|
494
|
-
const result = await callTool({
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
arguments: effectiveCall.arguments,
|
|
501
|
-
},
|
|
502
|
-
}, {});
|
|
500
|
+
const result = await runtime.callTool({
|
|
501
|
+
name: effectiveCall.name,
|
|
502
|
+
arguments: effectiveCall.arguments,
|
|
503
|
+
}, {
|
|
504
|
+
requestId: taskforceAgentMcpRequestId(effectiveCall),
|
|
505
|
+
});
|
|
503
506
|
const bounded = boundManagedAgentMcpToolResult(effectiveCall.name, extractToolResultText(result));
|
|
504
507
|
return {
|
|
505
508
|
name: effectiveCall.name,
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { TASKFORCE_CLOUD_ENVIRONMENTS, parseTaskforceCloudEnvironment } from '../config/cloudEnvironment.js';
|
|
2
|
+
import { readSetCookieHeaders, stripSetCookieDomainAttribute } from '../utils/httpSetCookie.js';
|
|
3
|
+
import { resolveAllAdminProxyUpstreamSessionCookieNames, resolveAdminProxyUpstreamSessionCookieName, rewriteAdminProxyRequestCookieHeader, rewriteAdminProxyResponseSetCookie, } from './adminProxySessionCookies.js';
|
|
4
|
+
function readEnvValue(env, key) {
|
|
5
|
+
const value = env[key];
|
|
6
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
7
|
+
}
|
|
8
|
+
function resolveProxyEnvironment(context) {
|
|
9
|
+
const processEnvironment = typeof process !== 'undefined' ? process.env : {};
|
|
10
|
+
return { ...processEnvironment, ...context.env };
|
|
11
|
+
}
|
|
12
|
+
function resolveUpstreamBaseUrl(environment) {
|
|
13
|
+
return TASKFORCE_CLOUD_ENVIRONMENTS[environment].appBaseUrl.replace(/\/+$/, '');
|
|
14
|
+
}
|
|
15
|
+
function isCloudflareAccessRedirect(response) {
|
|
16
|
+
if (response.status < 300 || response.status >= 400)
|
|
17
|
+
return false;
|
|
18
|
+
const location = String(response.headers.get('location') || '').trim();
|
|
19
|
+
if (!location)
|
|
20
|
+
return false;
|
|
21
|
+
try {
|
|
22
|
+
const url = new URL(location);
|
|
23
|
+
return url.hostname.toLowerCase() === 'stratnexus.cloudflareaccess.com'
|
|
24
|
+
|| url.pathname.startsWith('/cdn-cgi/access/login');
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return location.includes('/cdn-cgi/access/login');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function jsonError(status, error, code) {
|
|
31
|
+
return new Response(JSON.stringify({ error, code }), {
|
|
32
|
+
status,
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
'Cache-Control': 'no-store',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export async function handleAdminEdgeProxyRequest(context) {
|
|
40
|
+
const request = context.request;
|
|
41
|
+
const environment = parseTaskforceCloudEnvironment(request.headers.get('x-taskforce-cloud-environment'));
|
|
42
|
+
if (!environment) {
|
|
43
|
+
return jsonError(400, 'A valid admin cloud environment is required.', 'ADMIN_ENVIRONMENT_REQUIRED');
|
|
44
|
+
}
|
|
45
|
+
const proxyEnvironment = resolveProxyEnvironment(context);
|
|
46
|
+
const upstreamSessionCookieName = resolveAdminProxyUpstreamSessionCookieName(environment, proxyEnvironment);
|
|
47
|
+
const requestUrl = new URL(request.url);
|
|
48
|
+
const upstreamUrl = `${resolveUpstreamBaseUrl(environment)}${requestUrl.pathname}${requestUrl.search}`;
|
|
49
|
+
const headers = new Headers(request.headers);
|
|
50
|
+
headers.delete('host');
|
|
51
|
+
const rewrittenCookie = rewriteAdminProxyRequestCookieHeader(headers.get('cookie'), environment, upstreamSessionCookieName, resolveAllAdminProxyUpstreamSessionCookieNames(proxyEnvironment));
|
|
52
|
+
if (rewrittenCookie)
|
|
53
|
+
headers.set('cookie', rewrittenCookie);
|
|
54
|
+
else
|
|
55
|
+
headers.delete('cookie');
|
|
56
|
+
headers.set('x-taskforce-origin-host', requestUrl.host);
|
|
57
|
+
headers.set('x-taskforce-origin-proto', requestUrl.protocol.replace(':', ''));
|
|
58
|
+
headers.set('x-taskforce-origin-base-url', requestUrl.origin);
|
|
59
|
+
headers.set('x-taskforce-origin-runtime', 'admin-edge-proxy');
|
|
60
|
+
const cloudProxyClientId = readEnvValue(proxyEnvironment, 'TASKFORCE_CF_ACCESS_CLIENT_ID')
|
|
61
|
+
|| readEnvValue(proxyEnvironment, 'CF_ACCESS_CLIENT_ID');
|
|
62
|
+
const cloudProxyClientSecret = readEnvValue(proxyEnvironment, 'TASKFORCE_CF_ACCESS_CLIENT_SECRET')
|
|
63
|
+
|| readEnvValue(proxyEnvironment, 'CF_ACCESS_CLIENT_SECRET');
|
|
64
|
+
if (cloudProxyClientId && cloudProxyClientSecret) {
|
|
65
|
+
headers.set('CF-Access-Client-Id', cloudProxyClientId);
|
|
66
|
+
headers.set('CF-Access-Client-Secret', cloudProxyClientSecret);
|
|
67
|
+
}
|
|
68
|
+
const method = request.method.toUpperCase();
|
|
69
|
+
const upstreamResponse = await fetch(upstreamUrl, {
|
|
70
|
+
method,
|
|
71
|
+
headers,
|
|
72
|
+
body: method !== 'GET' && method !== 'HEAD' ? await request.arrayBuffer() : undefined,
|
|
73
|
+
redirect: 'manual',
|
|
74
|
+
});
|
|
75
|
+
if (isCloudflareAccessRedirect(upstreamResponse)) {
|
|
76
|
+
return jsonError(401, 'Cloudflare Access authentication required for the selected environment.', 'CLOUDFLARE_ACCESS_REQUIRED');
|
|
77
|
+
}
|
|
78
|
+
const responseHeaders = new Headers(upstreamResponse.headers);
|
|
79
|
+
responseHeaders.delete('access-control-allow-origin');
|
|
80
|
+
responseHeaders.delete('access-control-allow-credentials');
|
|
81
|
+
responseHeaders.delete('access-control-allow-methods');
|
|
82
|
+
responseHeaders.delete('access-control-allow-headers');
|
|
83
|
+
responseHeaders.set('cache-control', 'no-store');
|
|
84
|
+
const setCookies = readSetCookieHeaders(upstreamResponse.headers);
|
|
85
|
+
responseHeaders.delete('set-cookie');
|
|
86
|
+
for (const setCookie of setCookies) {
|
|
87
|
+
responseHeaders.append('set-cookie', stripSetCookieDomainAttribute(rewriteAdminProxyResponseSetCookie(setCookie, environment, upstreamSessionCookieName)));
|
|
88
|
+
}
|
|
89
|
+
return new Response(upstreamResponse.body, {
|
|
90
|
+
status: upstreamResponse.status,
|
|
91
|
+
statusText: upstreamResponse.statusText,
|
|
92
|
+
headers: responseHeaders,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type TaskforceCloudEnvironment } from '../config/cloudEnvironment.js';
|
|
2
|
+
export declare const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME = "taskforce_session";
|
|
3
|
+
export declare const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV = "TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE";
|
|
4
|
+
export declare function resolveAdminProxyUpstreamSessionCookieName(environment: TaskforceCloudEnvironment, env?: Record<string, unknown>): string;
|
|
5
|
+
export declare function resolveAllAdminProxyUpstreamSessionCookieNames(env?: Record<string, unknown>): string[];
|
|
6
|
+
export declare function adminProxySessionCookieName(environment: TaskforceCloudEnvironment): string;
|
|
7
|
+
/**
|
|
8
|
+
* Replace all browser-visible admin session cookies with the one upstream
|
|
9
|
+
* session cookie expected by the selected cloud environment.
|
|
10
|
+
*/
|
|
11
|
+
export declare function rewriteAdminProxyRequestCookieHeader(cookieHeader: string | null | undefined, environment: TaskforceCloudEnvironment, upstreamSessionCookieName?: string, additionalSessionCookieNames?: readonly string[]): string;
|
|
12
|
+
/**
|
|
13
|
+
* Namespace an upstream cloud session for the admin proxy host. Removing the
|
|
14
|
+
* upstream Domain attribute keeps the isolated session scoped to that proxy.
|
|
15
|
+
*/
|
|
16
|
+
export declare function rewriteAdminProxyResponseSetCookie(setCookie: string, environment: TaskforceCloudEnvironment, upstreamSessionCookieName?: string): string;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { TASKFORCE_CLOUD_ENVIRONMENT_ORDER, } from '../config/cloudEnvironment.js';
|
|
2
|
+
export const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME = 'taskforce_session';
|
|
3
|
+
export const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV = 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE';
|
|
4
|
+
const ADMIN_PROXY_SESSION_COOKIE_PREFIX = '__Host-taskforce_admin_session_';
|
|
5
|
+
const LEGACY_ADMIN_PROXY_SESSION_COOKIE_PREFIX = 'taskforce_admin_session_';
|
|
6
|
+
const TASKFORCE_SESSION_COOKIE_NAMES = new Set([
|
|
7
|
+
ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME,
|
|
8
|
+
'taskforce_session_prod',
|
|
9
|
+
'taskforce_session_staging',
|
|
10
|
+
'taskforce_session_performance',
|
|
11
|
+
]);
|
|
12
|
+
export function resolveAdminProxyUpstreamSessionCookieName(environment, env = {}) {
|
|
13
|
+
const environmentKey = `${ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV}_${environment.toUpperCase()}`;
|
|
14
|
+
const configured = String(env[environmentKey] || env[ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV] || '').trim();
|
|
15
|
+
if (!configured)
|
|
16
|
+
return ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME;
|
|
17
|
+
if (!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(configured)) {
|
|
18
|
+
throw new Error(`Invalid admin proxy upstream session cookie name for ${environment}.`);
|
|
19
|
+
}
|
|
20
|
+
return configured;
|
|
21
|
+
}
|
|
22
|
+
export function resolveAllAdminProxyUpstreamSessionCookieNames(env = {}) {
|
|
23
|
+
return [...new Set(TASKFORCE_CLOUD_ENVIRONMENT_ORDER.map((environment) => resolveAdminProxyUpstreamSessionCookieName(environment, env)))];
|
|
24
|
+
}
|
|
25
|
+
export function adminProxySessionCookieName(environment) {
|
|
26
|
+
return `${ADMIN_PROXY_SESSION_COOKIE_PREFIX}${environment}`;
|
|
27
|
+
}
|
|
28
|
+
function cookiePairName(pair) {
|
|
29
|
+
const separator = pair.indexOf('=');
|
|
30
|
+
return (separator >= 0 ? pair.slice(0, separator) : pair).trim();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Replace all browser-visible admin session cookies with the one upstream
|
|
34
|
+
* session cookie expected by the selected cloud environment.
|
|
35
|
+
*/
|
|
36
|
+
export function rewriteAdminProxyRequestCookieHeader(cookieHeader, environment, upstreamSessionCookieName = ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME, additionalSessionCookieNames = []) {
|
|
37
|
+
const selectedCookieName = adminProxySessionCookieName(environment);
|
|
38
|
+
const pairs = String(cookieHeader || '')
|
|
39
|
+
.split(';')
|
|
40
|
+
.map((part) => part.trim())
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
const selectedPair = pairs.find((pair) => cookiePairName(pair) === selectedCookieName);
|
|
43
|
+
const forwardedPairs = pairs.filter((pair) => {
|
|
44
|
+
const name = cookiePairName(pair);
|
|
45
|
+
return name !== upstreamSessionCookieName
|
|
46
|
+
&& !additionalSessionCookieNames.includes(name)
|
|
47
|
+
&& !TASKFORCE_SESSION_COOKIE_NAMES.has(name)
|
|
48
|
+
&& !name.startsWith(ADMIN_PROXY_SESSION_COOKIE_PREFIX)
|
|
49
|
+
&& !name.startsWith(LEGACY_ADMIN_PROXY_SESSION_COOKIE_PREFIX);
|
|
50
|
+
});
|
|
51
|
+
if (selectedPair) {
|
|
52
|
+
const separator = selectedPair.indexOf('=');
|
|
53
|
+
forwardedPairs.push(`${upstreamSessionCookieName}=${selectedPair.slice(separator + 1)}`);
|
|
54
|
+
}
|
|
55
|
+
return forwardedPairs.join('; ');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Namespace an upstream cloud session for the admin proxy host. Removing the
|
|
59
|
+
* upstream Domain attribute keeps the isolated session scoped to that proxy.
|
|
60
|
+
*/
|
|
61
|
+
export function rewriteAdminProxyResponseSetCookie(setCookie, environment, upstreamSessionCookieName = ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME) {
|
|
62
|
+
const parts = String(setCookie || '')
|
|
63
|
+
.split(';')
|
|
64
|
+
.map((part) => part.trim())
|
|
65
|
+
.filter(Boolean);
|
|
66
|
+
if (parts.length === 0)
|
|
67
|
+
return setCookie;
|
|
68
|
+
const [nameValue, ...attributes] = parts;
|
|
69
|
+
const separator = nameValue.indexOf('=');
|
|
70
|
+
if (separator < 0 || nameValue.slice(0, separator).trim() !== upstreamSessionCookieName) {
|
|
71
|
+
return setCookie;
|
|
72
|
+
}
|
|
73
|
+
const value = nameValue.slice(separator + 1);
|
|
74
|
+
const hostOnlyAttributes = attributes.filter((attribute) => {
|
|
75
|
+
const lower = attribute.toLowerCase();
|
|
76
|
+
return !lower.startsWith('domain=')
|
|
77
|
+
&& !lower.startsWith('path=')
|
|
78
|
+
&& lower !== 'secure';
|
|
79
|
+
});
|
|
80
|
+
return [
|
|
81
|
+
`${adminProxySessionCookieName(environment)}=${value}`,
|
|
82
|
+
'Path=/',
|
|
83
|
+
'Secure',
|
|
84
|
+
...hostOnlyAttributes,
|
|
85
|
+
].join('; ');
|
|
86
|
+
}
|