@cat-factory/worker 0.6.0
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/LICENSE +21 -0
- package/dist/app.d.ts +22 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +49 -0
- package/dist/app.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/ai/CloudflareModelProvider.d.ts +23 -0
- package/dist/infrastructure/ai/CloudflareModelProvider.d.ts.map +1 -0
- package/dist/infrastructure/ai/CloudflareModelProvider.js +62 -0
- package/dist/infrastructure/ai/CloudflareModelProvider.js.map +1 -0
- package/dist/infrastructure/ai/CompositeAgentExecutor.d.ts +2 -0
- package/dist/infrastructure/ai/CompositeAgentExecutor.d.ts.map +1 -0
- package/dist/infrastructure/ai/CompositeAgentExecutor.js +5 -0
- package/dist/infrastructure/ai/CompositeAgentExecutor.js.map +1 -0
- package/dist/infrastructure/ai/ContainerAgentExecutor.d.ts +2 -0
- package/dist/infrastructure/ai/ContainerAgentExecutor.d.ts.map +1 -0
- package/dist/infrastructure/ai/ContainerAgentExecutor.js +5 -0
- package/dist/infrastructure/ai/ContainerAgentExecutor.js.map +1 -0
- package/dist/infrastructure/ai/ContainerRepoBootstrapper.d.ts +2 -0
- package/dist/infrastructure/ai/ContainerRepoBootstrapper.d.ts.map +1 -0
- package/dist/infrastructure/ai/ContainerRepoBootstrapper.js +5 -0
- package/dist/infrastructure/ai/ContainerRepoBootstrapper.js.map +1 -0
- package/dist/infrastructure/ai/ContainerRepoScanner.d.ts +39 -0
- package/dist/infrastructure/ai/ContainerRepoScanner.d.ts.map +1 -0
- package/dist/infrastructure/ai/ContainerRepoScanner.js +115 -0
- package/dist/infrastructure/ai/ContainerRepoScanner.js.map +1 -0
- package/dist/infrastructure/ai/LlmFragmentSelector.d.ts +2 -0
- package/dist/infrastructure/ai/LlmFragmentSelector.d.ts.map +1 -0
- package/dist/infrastructure/ai/LlmFragmentSelector.js +4 -0
- package/dist/infrastructure/ai/LlmFragmentSelector.js.map +1 -0
- package/dist/infrastructure/ai/RunnerJobClient.d.ts +2 -0
- package/dist/infrastructure/ai/RunnerJobClient.d.ts.map +1 -0
- package/dist/infrastructure/ai/RunnerJobClient.js +5 -0
- package/dist/infrastructure/ai/RunnerJobClient.js.map +1 -0
- package/dist/infrastructure/ai/WorkersAiLlmUpstream.d.ts +28 -0
- package/dist/infrastructure/ai/WorkersAiLlmUpstream.d.ts.map +1 -0
- package/dist/infrastructure/ai/WorkersAiLlmUpstream.js +486 -0
- package/dist/infrastructure/ai/WorkersAiLlmUpstream.js.map +1 -0
- package/dist/infrastructure/ai/providerEndpoints.d.ts +17 -0
- package/dist/infrastructure/ai/providerEndpoints.d.ts.map +1 -0
- package/dist/infrastructure/ai/providerEndpoints.js +42 -0
- package/dist/infrastructure/ai/providerEndpoints.js.map +1 -0
- package/dist/infrastructure/ai/registries.d.ts +11 -0
- package/dist/infrastructure/ai/registries.d.ts.map +1 -0
- package/dist/infrastructure/ai/registries.js +14 -0
- package/dist/infrastructure/ai/registries.js.map +1 -0
- package/dist/infrastructure/auth/GitHubOAuth.d.ts +2 -0
- package/dist/infrastructure/auth/GitHubOAuth.d.ts.map +1 -0
- package/dist/infrastructure/auth/GitHubOAuth.js +3 -0
- package/dist/infrastructure/auth/GitHubOAuth.js.map +1 -0
- package/dist/infrastructure/auth/middleware.d.ts +2 -0
- package/dist/infrastructure/auth/middleware.d.ts.map +1 -0
- package/dist/infrastructure/auth/middleware.js +3 -0
- package/dist/infrastructure/auth/middleware.js.map +1 -0
- package/dist/infrastructure/auth/signing.d.ts +3 -0
- package/dist/infrastructure/auth/signing.d.ts.map +1 -0
- package/dist/infrastructure/auth/signing.js +3 -0
- package/dist/infrastructure/auth/signing.js.map +1 -0
- package/dist/infrastructure/config/agents.d.ts +6 -0
- package/dist/infrastructure/config/agents.d.ts.map +1 -0
- package/dist/infrastructure/config/agents.js +100 -0
- package/dist/infrastructure/config/agents.js.map +1 -0
- package/dist/infrastructure/config/auth.d.ts +13 -0
- package/dist/infrastructure/config/auth.d.ts.map +1 -0
- package/dist/infrastructure/config/auth.js +80 -0
- package/dist/infrastructure/config/auth.js.map +1 -0
- package/dist/infrastructure/config/cors.d.ts +2 -0
- package/dist/infrastructure/config/cors.d.ts.map +1 -0
- package/dist/infrastructure/config/cors.js +3 -0
- package/dist/infrastructure/config/cors.js.map +1 -0
- package/dist/infrastructure/config/datadog.d.ts +6 -0
- package/dist/infrastructure/config/datadog.d.ts.map +1 -0
- package/dist/infrastructure/config/datadog.js +22 -0
- package/dist/infrastructure/config/datadog.js.map +1 -0
- package/dist/infrastructure/config/documents.d.ts +5 -0
- package/dist/infrastructure/config/documents.d.ts.map +1 -0
- package/dist/infrastructure/config/documents.js +36 -0
- package/dist/infrastructure/config/documents.js.map +1 -0
- package/dist/infrastructure/config/email.d.ts +5 -0
- package/dist/infrastructure/config/email.d.ts.map +1 -0
- package/dist/infrastructure/config/email.js +12 -0
- package/dist/infrastructure/config/email.js.map +1 -0
- package/dist/infrastructure/config/environments.d.ts +5 -0
- package/dist/infrastructure/config/environments.d.ts.map +1 -0
- package/dist/infrastructure/config/environments.js +15 -0
- package/dist/infrastructure/config/environments.js.map +1 -0
- package/dist/infrastructure/config/execution.d.ts +5 -0
- package/dist/infrastructure/config/execution.d.ts.map +1 -0
- package/dist/infrastructure/config/execution.js +21 -0
- package/dist/infrastructure/config/execution.js.map +1 -0
- package/dist/infrastructure/config/fragmentLibrary.d.ts +5 -0
- package/dist/infrastructure/config/fragmentLibrary.d.ts.map +1 -0
- package/dist/infrastructure/config/fragmentLibrary.js +7 -0
- package/dist/infrastructure/config/fragmentLibrary.js.map +1 -0
- package/dist/infrastructure/config/github.d.ts +5 -0
- package/dist/infrastructure/config/github.d.ts.map +1 -0
- package/dist/infrastructure/config/github.js +25 -0
- package/dist/infrastructure/config/github.js.map +1 -0
- package/dist/infrastructure/config/index.d.ts +20 -0
- package/dist/infrastructure/config/index.d.ts.map +1 -0
- package/dist/infrastructure/config/index.js +52 -0
- package/dist/infrastructure/config/index.js.map +1 -0
- package/dist/infrastructure/config/langfuse.d.ts +10 -0
- package/dist/infrastructure/config/langfuse.d.ts.map +1 -0
- package/dist/infrastructure/config/langfuse.js +17 -0
- package/dist/infrastructure/config/langfuse.js.map +1 -0
- package/dist/infrastructure/config/observability.d.ts +10 -0
- package/dist/infrastructure/config/observability.d.ts.map +1 -0
- package/dist/infrastructure/config/observability.js +11 -0
- package/dist/infrastructure/config/observability.js.map +1 -0
- package/dist/infrastructure/config/retention.d.ts +5 -0
- package/dist/infrastructure/config/retention.d.ts.map +1 -0
- package/dist/infrastructure/config/retention.js +15 -0
- package/dist/infrastructure/config/retention.js.map +1 -0
- package/dist/infrastructure/config/runners.d.ts +5 -0
- package/dist/infrastructure/config/runners.d.ts.map +1 -0
- package/dist/infrastructure/config/runners.js +13 -0
- package/dist/infrastructure/config/runners.js.map +1 -0
- package/dist/infrastructure/config/slack.d.ts +5 -0
- package/dist/infrastructure/config/slack.d.ts.map +1 -0
- package/dist/infrastructure/config/slack.js +17 -0
- package/dist/infrastructure/config/slack.js.map +1 -0
- package/dist/infrastructure/config/spending.d.ts +4 -0
- package/dist/infrastructure/config/spending.d.ts.map +1 -0
- package/dist/infrastructure/config/spending.js +36 -0
- package/dist/infrastructure/config/spending.js.map +1 -0
- package/dist/infrastructure/config/tasks.d.ts +5 -0
- package/dist/infrastructure/config/tasks.d.ts.map +1 -0
- package/dist/infrastructure/config/tasks.js +31 -0
- package/dist/infrastructure/config/tasks.js.map +1 -0
- package/dist/infrastructure/config/utils.d.ts +6 -0
- package/dist/infrastructure/config/utils.d.ts.map +1 -0
- package/dist/infrastructure/config/utils.js +24 -0
- package/dist/infrastructure/config/utils.js.map +1 -0
- package/dist/infrastructure/container.d.ts +8 -0
- package/dist/infrastructure/container.d.ts.map +1 -0
- package/dist/infrastructure/container.js +1157 -0
- package/dist/infrastructure/container.js.map +1 -0
- package/dist/infrastructure/containers/CloudflareContainerTransport.d.ts +22 -0
- package/dist/infrastructure/containers/CloudflareContainerTransport.d.ts.map +1 -0
- package/dist/infrastructure/containers/CloudflareContainerTransport.js +129 -0
- package/dist/infrastructure/containers/CloudflareContainerTransport.js.map +1 -0
- package/dist/infrastructure/containers/ContainerInstanceRegistry.d.ts +62 -0
- package/dist/infrastructure/containers/ContainerInstanceRegistry.d.ts.map +1 -0
- package/dist/infrastructure/containers/ContainerInstanceRegistry.js +74 -0
- package/dist/infrastructure/containers/ContainerInstanceRegistry.js.map +1 -0
- package/dist/infrastructure/containers/ContainerSessionService.d.ts +2 -0
- package/dist/infrastructure/containers/ContainerSessionService.d.ts.map +1 -0
- package/dist/infrastructure/containers/ContainerSessionService.js +3 -0
- package/dist/infrastructure/containers/ContainerSessionService.js.map +1 -0
- package/dist/infrastructure/containers/ExecutionContainer.d.ts +48 -0
- package/dist/infrastructure/containers/ExecutionContainer.d.ts.map +1 -0
- package/dist/infrastructure/containers/ExecutionContainer.js +88 -0
- package/dist/infrastructure/containers/ExecutionContainer.js.map +1 -0
- package/dist/infrastructure/documents/ConfluenceProvider.d.ts +29 -0
- package/dist/infrastructure/documents/ConfluenceProvider.d.ts.map +1 -0
- package/dist/infrastructure/documents/ConfluenceProvider.js +179 -0
- package/dist/infrastructure/documents/ConfluenceProvider.js.map +1 -0
- package/dist/infrastructure/documents/GitHubDocsProvider.d.ts +42 -0
- package/dist/infrastructure/documents/GitHubDocsProvider.d.ts.map +1 -0
- package/dist/infrastructure/documents/GitHubDocsProvider.js +85 -0
- package/dist/infrastructure/documents/GitHubDocsProvider.js.map +1 -0
- package/dist/infrastructure/documents/NotionProvider.d.ts +32 -0
- package/dist/infrastructure/documents/NotionProvider.d.ts.map +1 -0
- package/dist/infrastructure/documents/NotionProvider.js +220 -0
- package/dist/infrastructure/documents/NotionProvider.js.map +1 -0
- package/dist/infrastructure/durable-objects/WorkspaceEventsHub.d.ts +20 -0
- package/dist/infrastructure/durable-objects/WorkspaceEventsHub.d.ts.map +1 -0
- package/dist/infrastructure/durable-objects/WorkspaceEventsHub.js +62 -0
- package/dist/infrastructure/durable-objects/WorkspaceEventsHub.js.map +1 -0
- package/dist/infrastructure/env.d.ts +370 -0
- package/dist/infrastructure/env.d.ts.map +1 -0
- package/dist/infrastructure/env.js +2 -0
- package/dist/infrastructure/env.js.map +1 -0
- package/dist/infrastructure/environments/HttpEnvironmentProvider.d.ts +27 -0
- package/dist/infrastructure/environments/HttpEnvironmentProvider.d.ts.map +1 -0
- package/dist/infrastructure/environments/HttpEnvironmentProvider.js +314 -0
- package/dist/infrastructure/environments/HttpEnvironmentProvider.js.map +1 -0
- package/dist/infrastructure/environments/WebCryptoSecretCipher.d.ts +2 -0
- package/dist/infrastructure/environments/WebCryptoSecretCipher.d.ts.map +1 -0
- package/dist/infrastructure/environments/WebCryptoSecretCipher.js +5 -0
- package/dist/infrastructure/environments/WebCryptoSecretCipher.js.map +1 -0
- package/dist/infrastructure/environments/sweep.d.ts +5 -0
- package/dist/infrastructure/environments/sweep.d.ts.map +1 -0
- package/dist/infrastructure/environments/sweep.js +16 -0
- package/dist/infrastructure/environments/sweep.js.map +1 -0
- package/dist/infrastructure/events/DurableObjectEventPublisher.d.ts +25 -0
- package/dist/infrastructure/events/DurableObjectEventPublisher.d.ts.map +1 -0
- package/dist/infrastructure/events/DurableObjectEventPublisher.js +64 -0
- package/dist/infrastructure/events/DurableObjectEventPublisher.js.map +1 -0
- package/dist/infrastructure/events/InAppNotificationChannel.d.ts +19 -0
- package/dist/infrastructure/events/InAppNotificationChannel.d.ts.map +1 -0
- package/dist/infrastructure/events/InAppNotificationChannel.js +22 -0
- package/dist/infrastructure/events/InAppNotificationChannel.js.map +1 -0
- package/dist/infrastructure/gateways/DoRealtimeGateway.d.ts +15 -0
- package/dist/infrastructure/gateways/DoRealtimeGateway.d.ts.map +1 -0
- package/dist/infrastructure/gateways/DoRealtimeGateway.js +20 -0
- package/dist/infrastructure/gateways/DoRealtimeGateway.js.map +1 -0
- package/dist/infrastructure/gateways/GitHubGateways.d.ts +27 -0
- package/dist/infrastructure/gateways/GitHubGateways.d.ts.map +1 -0
- package/dist/infrastructure/gateways/GitHubGateways.js +48 -0
- package/dist/infrastructure/gateways/GitHubGateways.js.map +1 -0
- package/dist/infrastructure/github/FetchGitHubClient.d.ts +2 -0
- package/dist/infrastructure/github/FetchGitHubClient.d.ts.map +1 -0
- package/dist/infrastructure/github/FetchGitHubClient.js +4 -0
- package/dist/infrastructure/github/FetchGitHubClient.js.map +1 -0
- package/dist/infrastructure/github/FetchGitHubProvisioningClient.d.ts +2 -0
- package/dist/infrastructure/github/FetchGitHubProvisioningClient.d.ts.map +1 -0
- package/dist/infrastructure/github/FetchGitHubProvisioningClient.js +5 -0
- package/dist/infrastructure/github/FetchGitHubProvisioningClient.js.map +1 -0
- package/dist/infrastructure/github/GitHubAppAuth.d.ts +2 -0
- package/dist/infrastructure/github/GitHubAppAuth.d.ts.map +1 -0
- package/dist/infrastructure/github/GitHubAppAuth.js +5 -0
- package/dist/infrastructure/github/GitHubAppAuth.js.map +1 -0
- package/dist/infrastructure/github/GitHubAppRegistry.d.ts +2 -0
- package/dist/infrastructure/github/GitHubAppRegistry.d.ts.map +1 -0
- package/dist/infrastructure/github/GitHubAppRegistry.js +4 -0
- package/dist/infrastructure/github/GitHubAppRegistry.js.map +1 -0
- package/dist/infrastructure/github/GitHubCiStatusProvider.d.ts +2 -0
- package/dist/infrastructure/github/GitHubCiStatusProvider.d.ts.map +1 -0
- package/dist/infrastructure/github/GitHubCiStatusProvider.js +4 -0
- package/dist/infrastructure/github/GitHubCiStatusProvider.js.map +1 -0
- package/dist/infrastructure/github/GitHubMergeabilityProvider.d.ts +2 -0
- package/dist/infrastructure/github/GitHubMergeabilityProvider.d.ts.map +1 -0
- package/dist/infrastructure/github/GitHubMergeabilityProvider.js +4 -0
- package/dist/infrastructure/github/GitHubMergeabilityProvider.js.map +1 -0
- package/dist/infrastructure/github/GitHubPullRequestMerger.d.ts +2 -0
- package/dist/infrastructure/github/GitHubPullRequestMerger.d.ts.map +1 -0
- package/dist/infrastructure/github/GitHubPullRequestMerger.js +4 -0
- package/dist/infrastructure/github/GitHubPullRequestMerger.js.map +1 -0
- package/dist/infrastructure/github/WebCryptoWebhookVerifier.d.ts +2 -0
- package/dist/infrastructure/github/WebCryptoWebhookVerifier.d.ts.map +1 -0
- package/dist/infrastructure/github/WebCryptoWebhookVerifier.js +5 -0
- package/dist/infrastructure/github/WebCryptoWebhookVerifier.js.map +1 -0
- package/dist/infrastructure/github/encoding.d.ts +2 -0
- package/dist/infrastructure/github/encoding.d.ts.map +1 -0
- package/dist/infrastructure/github/encoding.js +3 -0
- package/dist/infrastructure/github/encoding.js.map +1 -0
- package/dist/infrastructure/github/state.d.ts +2 -0
- package/dist/infrastructure/github/state.d.ts.map +1 -0
- package/dist/infrastructure/github/state.js +3 -0
- package/dist/infrastructure/github/state.js.map +1 -0
- package/dist/infrastructure/github/sync-consumer.d.ts +16 -0
- package/dist/infrastructure/github/sync-consumer.d.ts.map +1 -0
- package/dist/infrastructure/github/sync-consumer.js +130 -0
- package/dist/infrastructure/github/sync-consumer.js.map +1 -0
- package/dist/infrastructure/http/errorHandler.d.ts +2 -0
- package/dist/infrastructure/http/errorHandler.d.ts.map +1 -0
- package/dist/infrastructure/http/errorHandler.js +3 -0
- package/dist/infrastructure/http/errorHandler.js.map +1 -0
- package/dist/infrastructure/http/params.d.ts +2 -0
- package/dist/infrastructure/http/params.d.ts.map +1 -0
- package/dist/infrastructure/http/params.js +3 -0
- package/dist/infrastructure/http/params.js.map +1 -0
- package/dist/infrastructure/http/types.d.ts +12 -0
- package/dist/infrastructure/http/types.d.ts.map +1 -0
- package/dist/infrastructure/http/types.js +2 -0
- package/dist/infrastructure/http/types.js.map +1 -0
- package/dist/infrastructure/http/validation.d.ts +2 -0
- package/dist/infrastructure/http/validation.d.ts.map +1 -0
- package/dist/infrastructure/http/validation.js +3 -0
- package/dist/infrastructure/http/validation.js.map +1 -0
- package/dist/infrastructure/observability/logger.d.ts +3 -0
- package/dist/infrastructure/observability/logger.d.ts.map +1 -0
- package/dist/infrastructure/observability/logger.js +4 -0
- package/dist/infrastructure/observability/logger.js.map +1 -0
- package/dist/infrastructure/repositories/D1AccountInvitationRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1AccountInvitationRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1AccountInvitationRepository.js +63 -0
- package/dist/infrastructure/repositories/D1AccountInvitationRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1AccountRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1AccountRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1AccountRepository.js +52 -0
- package/dist/infrastructure/repositories/D1AccountRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1AgentRunRepository.d.ts +18 -0
- package/dist/infrastructure/repositories/D1AgentRunRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1AgentRunRepository.js +34 -0
- package/dist/infrastructure/repositories/D1AgentRunRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1BlockRepository.d.ts +23 -0
- package/dist/infrastructure/repositories/D1BlockRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1BlockRepository.js +101 -0
- package/dist/infrastructure/repositories/D1BlockRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1BootstrapJobRepository.d.ts +16 -0
- package/dist/infrastructure/repositories/D1BootstrapJobRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1BootstrapJobRepository.js +209 -0
- package/dist/infrastructure/repositories/D1BootstrapJobRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1BranchProjectionRepository.d.ts +12 -0
- package/dist/infrastructure/repositories/D1BranchProjectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1BranchProjectionRepository.js +29 -0
- package/dist/infrastructure/repositories/D1BranchProjectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1CheckRunProjectionRepository.d.ts +12 -0
- package/dist/infrastructure/repositories/D1CheckRunProjectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1CheckRunProjectionRepository.js +29 -0
- package/dist/infrastructure/repositories/D1CheckRunProjectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ClarityReviewRepository.d.ts +19 -0
- package/dist/infrastructure/repositories/D1ClarityReviewRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ClarityReviewRepository.js +75 -0
- package/dist/infrastructure/repositories/D1ClarityReviewRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1CommitProjectionRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1CommitProjectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1CommitProjectionRepository.js +48 -0
- package/dist/infrastructure/repositories/D1CommitProjectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ConsensusSessionRepository.d.ts +19 -0
- package/dist/infrastructure/repositories/D1ConsensusSessionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ConsensusSessionRepository.js +88 -0
- package/dist/infrastructure/repositories/D1ConsensusSessionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1DatadogConnectionRepository.d.ts +17 -0
- package/dist/infrastructure/repositories/D1DatadogConnectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1DatadogConnectionRepository.js +47 -0
- package/dist/infrastructure/repositories/D1DatadogConnectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1DocumentConnectionRepository.d.ts +27 -0
- package/dist/infrastructure/repositories/D1DocumentConnectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1DocumentConnectionRepository.js +89 -0
- package/dist/infrastructure/repositories/D1DocumentConnectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1DocumentRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1DocumentRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1DocumentRepository.js +66 -0
- package/dist/infrastructure/repositories/D1DocumentRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1EmailConnectionRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1EmailConnectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1EmailConnectionRepository.js +46 -0
- package/dist/infrastructure/repositories/D1EmailConnectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1EnvironmentConnectionRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1EnvironmentConnectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1EnvironmentConnectionRepository.js +48 -0
- package/dist/infrastructure/repositories/D1EnvironmentConnectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1EnvironmentRegistryRepository.d.ts +17 -0
- package/dist/infrastructure/repositories/D1EnvironmentRegistryRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1EnvironmentRegistryRepository.js +95 -0
- package/dist/infrastructure/repositories/D1EnvironmentRegistryRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ExecutionRepository.d.ts +28 -0
- package/dist/infrastructure/repositories/D1ExecutionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ExecutionRepository.js +113 -0
- package/dist/infrastructure/repositories/D1ExecutionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1FragmentSourceRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1FragmentSourceRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1FragmentSourceRepository.js +66 -0
- package/dist/infrastructure/repositories/D1FragmentSourceRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1GitHubInstallationRepository.d.ts +17 -0
- package/dist/infrastructure/repositories/D1GitHubInstallationRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1GitHubInstallationRepository.js +79 -0
- package/dist/infrastructure/repositories/D1GitHubInstallationRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1IssueProjectionRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1IssueProjectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1IssueProjectionRepository.js +36 -0
- package/dist/infrastructure/repositories/D1IssueProjectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1LiveContainerRepository.d.ts +17 -0
- package/dist/infrastructure/repositories/D1LiveContainerRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1LiveContainerRepository.js +40 -0
- package/dist/infrastructure/repositories/D1LiveContainerRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1LlmCallMetricRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1LlmCallMetricRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1LlmCallMetricRepository.js +123 -0
- package/dist/infrastructure/repositories/D1LlmCallMetricRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1LocalModelEndpointRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1LocalModelEndpointRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1LocalModelEndpointRepository.js +63 -0
- package/dist/infrastructure/repositories/D1LocalModelEndpointRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1MembershipRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1MembershipRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1MembershipRepository.js +58 -0
- package/dist/infrastructure/repositories/D1MembershipRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1MergePresetRepository.d.ts +21 -0
- package/dist/infrastructure/repositories/D1MergePresetRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1MergePresetRepository.js +88 -0
- package/dist/infrastructure/repositories/D1MergePresetRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ModelDefaultsRepository.d.ts +18 -0
- package/dist/infrastructure/repositories/D1ModelDefaultsRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ModelDefaultsRepository.js +47 -0
- package/dist/infrastructure/repositories/D1ModelDefaultsRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1NotificationRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/D1NotificationRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1NotificationRepository.js +81 -0
- package/dist/infrastructure/repositories/D1NotificationRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1PersonalSubscriptionRepository.d.ts +28 -0
- package/dist/infrastructure/repositories/D1PersonalSubscriptionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1PersonalSubscriptionRepository.js +142 -0
- package/dist/infrastructure/repositories/D1PersonalSubscriptionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1PipelineRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1PipelineRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1PipelineRepository.js +46 -0
- package/dist/infrastructure/repositories/D1PipelineRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1PipelineScheduleRepository.d.ts +26 -0
- package/dist/infrastructure/repositories/D1PipelineScheduleRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1PipelineScheduleRepository.js +192 -0
- package/dist/infrastructure/repositories/D1PipelineScheduleRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1PromptFragmentRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1PromptFragmentRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1PromptFragmentRepository.js +90 -0
- package/dist/infrastructure/repositories/D1PromptFragmentRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.d.ts +21 -0
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.js +108 -0
- package/dist/infrastructure/repositories/D1ProviderApiKeyRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.d.ts +19 -0
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.js +78 -0
- package/dist/infrastructure/repositories/D1ProviderSubscriptionTokenRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1PullRequestProjectionRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1PullRequestProjectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1PullRequestProjectionRepository.js +32 -0
- package/dist/infrastructure/repositories/D1PullRequestProjectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1RateLimitRepository.d.ts +18 -0
- package/dist/infrastructure/repositories/D1RateLimitRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1RateLimitRepository.js +30 -0
- package/dist/infrastructure/repositories/D1RateLimitRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ReferenceArchitectureRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1ReferenceArchitectureRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ReferenceArchitectureRepository.js +77 -0
- package/dist/infrastructure/repositories/D1ReferenceArchitectureRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ReleaseHealthConfigRepository.d.ts +17 -0
- package/dist/infrastructure/repositories/D1ReleaseHealthConfigRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ReleaseHealthConfigRepository.js +64 -0
- package/dist/infrastructure/repositories/D1ReleaseHealthConfigRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.js +64 -0
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1RepoProjectionRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/D1RepoProjectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1RepoProjectionRepository.js +121 -0
- package/dist/infrastructure/repositories/D1RepoProjectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1RequirementReviewRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/D1RequirementReviewRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1RequirementReviewRepository.js +76 -0
- package/dist/infrastructure/repositories/D1RequirementReviewRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1RunnerPoolConnectionRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1RunnerPoolConnectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1RunnerPoolConnectionRepository.js +48 -0
- package/dist/infrastructure/repositories/D1RunnerPoolConnectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ServiceFragmentDefaultsRepository.d.ts +16 -0
- package/dist/infrastructure/repositories/D1ServiceFragmentDefaultsRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ServiceFragmentDefaultsRepository.js +27 -0
- package/dist/infrastructure/repositories/D1ServiceFragmentDefaultsRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1ServiceRepository.d.ts +19 -0
- package/dist/infrastructure/repositories/D1ServiceRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1ServiceRepository.js +114 -0
- package/dist/infrastructure/repositories/D1ServiceRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1SlackRepositories.d.ts +29 -0
- package/dist/infrastructure/repositories/D1SlackRepositories.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1SlackRepositories.js +119 -0
- package/dist/infrastructure/repositories/D1SlackRepositories.js.map +1 -0
- package/dist/infrastructure/repositories/D1TaskConnectionRepository.d.ts +27 -0
- package/dist/infrastructure/repositories/D1TaskConnectionRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1TaskConnectionRepository.js +89 -0
- package/dist/infrastructure/repositories/D1TaskConnectionRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1TaskRepository.d.ts +15 -0
- package/dist/infrastructure/repositories/D1TaskRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1TaskRepository.js +90 -0
- package/dist/infrastructure/repositories/D1TaskRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1TokenUsageRepository.d.ts +13 -0
- package/dist/infrastructure/repositories/D1TokenUsageRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1TokenUsageRepository.js +41 -0
- package/dist/infrastructure/repositories/D1TokenUsageRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.d.ts +12 -0
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.js +32 -0
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1UserRepository.d.ts +19 -0
- package/dist/infrastructure/repositories/D1UserRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1UserRepository.js +108 -0
- package/dist/infrastructure/repositories/D1UserRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1WorkspaceMountRepository.d.ts +19 -0
- package/dist/infrastructure/repositories/D1WorkspaceMountRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1WorkspaceMountRepository.js +115 -0
- package/dist/infrastructure/repositories/D1WorkspaceMountRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1WorkspaceRepository.d.ts +18 -0
- package/dist/infrastructure/repositories/D1WorkspaceRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1WorkspaceRepository.js +77 -0
- package/dist/infrastructure/repositories/D1WorkspaceRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1WorkspaceSettingsRepository.d.ts +17 -0
- package/dist/infrastructure/repositories/D1WorkspaceSettingsRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1WorkspaceSettingsRepository.js +50 -0
- package/dist/infrastructure/repositories/D1WorkspaceSettingsRepository.js.map +1 -0
- package/dist/infrastructure/repositories/chunk.d.ts +11 -0
- package/dist/infrastructure/repositories/chunk.d.ts.map +1 -0
- package/dist/infrastructure/repositories/chunk.js +17 -0
- package/dist/infrastructure/repositories/chunk.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/branch.d.ts +11 -0
- package/dist/infrastructure/repositories/github-mappers/branch.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/branch.js +22 -0
- package/dist/infrastructure/repositories/github-mappers/branch.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/check-run.d.ts +13 -0
- package/dist/infrastructure/repositories/github-mappers/check-run.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/check-run.js +24 -0
- package/dist/infrastructure/repositories/github-mappers/check-run.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/commit.d.ts +12 -0
- package/dist/infrastructure/repositories/github-mappers/commit.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/commit.js +22 -0
- package/dist/infrastructure/repositories/github-mappers/commit.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/index.d.ts +11 -0
- package/dist/infrastructure/repositories/github-mappers/index.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/index.js +14 -0
- package/dist/infrastructure/repositories/github-mappers/index.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/installation.d.ts +16 -0
- package/dist/infrastructure/repositories/github-mappers/installation.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/installation.js +29 -0
- package/dist/infrastructure/repositories/github-mappers/installation.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/issue.d.ts +15 -0
- package/dist/infrastructure/repositories/github-mappers/issue.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/issue.js +29 -0
- package/dist/infrastructure/repositories/github-mappers/issue.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/pull-request.d.ts +18 -0
- package/dist/infrastructure/repositories/github-mappers/pull-request.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/pull-request.js +36 -0
- package/dist/infrastructure/repositories/github-mappers/pull-request.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/repo.d.ts +15 -0
- package/dist/infrastructure/repositories/github-mappers/repo.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/repo.js +31 -0
- package/dist/infrastructure/repositories/github-mappers/repo.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/serialize.d.ts +3 -0
- package/dist/infrastructure/repositories/github-mappers/serialize.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/serialize.js +4 -0
- package/dist/infrastructure/repositories/github-mappers/serialize.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/sync-cursor.d.ts +8 -0
- package/dist/infrastructure/repositories/github-mappers/sync-cursor.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/sync-cursor.js +4 -0
- package/dist/infrastructure/repositories/github-mappers/sync-cursor.js.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/upsert.d.ts +11 -0
- package/dist/infrastructure/repositories/github-mappers/upsert.d.ts.map +1 -0
- package/dist/infrastructure/repositories/github-mappers/upsert.js +18 -0
- package/dist/infrastructure/repositories/github-mappers/upsert.js.map +1 -0
- package/dist/infrastructure/repositories/mappers.d.ts +2 -0
- package/dist/infrastructure/repositories/mappers.d.ts.map +1 -0
- package/dist/infrastructure/repositories/mappers.js +4 -0
- package/dist/infrastructure/repositories/mappers.js.map +1 -0
- package/dist/infrastructure/runners/HttpRunnerPoolProvider.d.ts +2 -0
- package/dist/infrastructure/runners/HttpRunnerPoolProvider.d.ts.map +1 -0
- package/dist/infrastructure/runners/HttpRunnerPoolProvider.js +5 -0
- package/dist/infrastructure/runners/HttpRunnerPoolProvider.js.map +1 -0
- package/dist/infrastructure/runners/RunnerPoolTransport.d.ts +2 -0
- package/dist/infrastructure/runners/RunnerPoolTransport.d.ts.map +1 -0
- package/dist/infrastructure/runners/RunnerPoolTransport.js +5 -0
- package/dist/infrastructure/runners/RunnerPoolTransport.js.map +1 -0
- package/dist/infrastructure/runtime.d.ts +8 -0
- package/dist/infrastructure/runtime.d.ts.map +1 -0
- package/dist/infrastructure/runtime.js +13 -0
- package/dist/infrastructure/runtime.js.map +1 -0
- package/dist/infrastructure/tasks/GitHubIssuesProvider.d.ts +50 -0
- package/dist/infrastructure/tasks/GitHubIssuesProvider.d.ts.map +1 -0
- package/dist/infrastructure/tasks/GitHubIssuesProvider.js +91 -0
- package/dist/infrastructure/tasks/GitHubIssuesProvider.js.map +1 -0
- package/dist/infrastructure/tasks/JiraProvider.d.ts +29 -0
- package/dist/infrastructure/tasks/JiraProvider.d.ts.map +1 -0
- package/dist/infrastructure/tasks/JiraProvider.js +109 -0
- package/dist/infrastructure/tasks/JiraProvider.js.map +1 -0
- package/dist/infrastructure/workflows/BootstrapWorkflow.d.ts +21 -0
- package/dist/infrastructure/workflows/BootstrapWorkflow.d.ts.map +1 -0
- package/dist/infrastructure/workflows/BootstrapWorkflow.js +72 -0
- package/dist/infrastructure/workflows/BootstrapWorkflow.js.map +1 -0
- package/dist/infrastructure/workflows/ExecutionWorkflow.d.ts +15 -0
- package/dist/infrastructure/workflows/ExecutionWorkflow.d.ts.map +1 -0
- package/dist/infrastructure/workflows/ExecutionWorkflow.js +169 -0
- package/dist/infrastructure/workflows/ExecutionWorkflow.js.map +1 -0
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.d.ts +17 -0
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.d.ts.map +1 -0
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.js +24 -0
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.js.map +1 -0
- package/dist/infrastructure/workflows/WorkflowsBootstrapRunner.d.ts +15 -0
- package/dist/infrastructure/workflows/WorkflowsBootstrapRunner.d.ts.map +1 -0
- package/dist/infrastructure/workflows/WorkflowsBootstrapRunner.js +34 -0
- package/dist/infrastructure/workflows/WorkflowsBootstrapRunner.js.map +1 -0
- package/dist/infrastructure/workflows/WorkflowsWorkRunner.d.ts +31 -0
- package/dist/infrastructure/workflows/WorkflowsWorkRunner.d.ts.map +1 -0
- package/dist/infrastructure/workflows/WorkflowsWorkRunner.js +55 -0
- package/dist/infrastructure/workflows/WorkflowsWorkRunner.js.map +1 -0
- package/dist/infrastructure/workflows/retention.d.ts +35 -0
- package/dist/infrastructure/workflows/retention.d.ts.map +1 -0
- package/dist/infrastructure/workflows/retention.js +26 -0
- package/dist/infrastructure/workflows/retention.js.map +1 -0
- package/dist/infrastructure/workflows/sweeper.d.ts +57 -0
- package/dist/infrastructure/workflows/sweeper.d.ts.map +1 -0
- package/dist/infrastructure/workflows/sweeper.js +62 -0
- package/dist/infrastructure/workflows/sweeper.js.map +1 -0
- package/migrations/0001_init.sql +677 -0
- package/migrations/0002_clarity_reviews.sql +19 -0
- package/migrations/0002_consensus.sql +38 -0
- package/migrations/0002_llm_reasoning_text.sql +6 -0
- package/migrations/0002_local_model_endpoints.sql +16 -0
- package/migrations/0003_pipeline_labels_archive.sql +13 -0
- package/migrations/0003_release_health.sql +34 -0
- package/migrations/0004_run_timing_task_types.sql +24 -0
- package/package.json +65 -0
|
@@ -0,0 +1,1157 @@
|
|
|
1
|
+
import { CompositeNotificationChannel, CompositeIncidentEnrichmentProvider, NoopWorkRunner, } from '@cat-factory/kernel';
|
|
2
|
+
import { AiAgentExecutor, inlineWebSearchOptionsFromEnv, resolveAgentConfig, } from '@cat-factory/agents';
|
|
3
|
+
import { cloudflareBindingRegistry } from '@cat-factory/provider-cloudflare';
|
|
4
|
+
import { ConfluenceProvider, GitHubDocsProvider, GitHubIssuesProvider, JiraProvider, HttpEnvironmentProvider, NotionProvider, EMAIL_CIPHER_INFO, ApiKeyService, LocalModelEndpointService, PersonalSubscriptionService, ProviderSubscriptionService, RunnerPoolConnectionService, SLACK_CIPHER_INFO, SlackNotificationChannel, TicketTrackerService, DATADOG_CIPHER_INFO, DatadogReleaseHealthProvider, PagerDutyEnrichmentProvider, IncidentIoEnrichmentProvider, } from '@cat-factory/integrations';
|
|
5
|
+
import { createCore } from '@cat-factory/orchestration';
|
|
6
|
+
import { createLangfuseSink } from '@cat-factory/observability-langfuse';
|
|
7
|
+
import { buildResolveRepoTarget as buildSharedResolveRepoTarget, ensureWorkBranchViaRest, FanOutEventPublisher, InAppNotificationChannel, WebCryptoPasswordHasher, WebCryptoPersonalSecretCipher, createWebSearchUpstreamFromEnv, logger, createScopedModelProviderResolver, resolveUrlSafetyPolicy, resolveWorkspaceCapabilities, } from '@cat-factory/server';
|
|
8
|
+
import { loadConfig } from './config';
|
|
9
|
+
import { loadLangfuseConfig } from './config/langfuse';
|
|
10
|
+
import { loadObservabilityConfig } from './config/observability';
|
|
11
|
+
import { baseUrlFor } from './ai/providerEndpoints';
|
|
12
|
+
import { resolveExtraRegistries } from './ai/registries';
|
|
13
|
+
import { DoRealtimeGateway } from './gateways/DoRealtimeGateway';
|
|
14
|
+
import { CfGitHubWebhookIngest, WorkflowsBackfillScheduler } from './gateways/GitHubGateways';
|
|
15
|
+
import { WorkersAiLlmUpstream } from './ai/WorkersAiLlmUpstream';
|
|
16
|
+
import { ContainerAgentExecutor, } from './ai/ContainerAgentExecutor';
|
|
17
|
+
import { CloudflareContainerTransport } from './containers/CloudflareContainerTransport';
|
|
18
|
+
import { ContainerInstanceRegistry } from './containers/ContainerInstanceRegistry';
|
|
19
|
+
import { D1LiveContainerRepository } from './repositories/D1LiveContainerRepository';
|
|
20
|
+
import { HttpRunnerPoolProvider } from './runners/HttpRunnerPoolProvider';
|
|
21
|
+
import { RunnerPoolTransport } from './runners/RunnerPoolTransport';
|
|
22
|
+
import { D1RunnerPoolConnectionRepository } from './repositories/D1RunnerPoolConnectionRepository';
|
|
23
|
+
import { D1ProviderSubscriptionTokenRepository } from './repositories/D1ProviderSubscriptionTokenRepository';
|
|
24
|
+
import { D1ProviderApiKeyRepository } from './repositories/D1ProviderApiKeyRepository';
|
|
25
|
+
import { D1PersonalSubscriptionRepository, D1SubscriptionActivationRepository, } from './repositories/D1PersonalSubscriptionRepository';
|
|
26
|
+
import { D1LocalModelEndpointRepository } from './repositories/D1LocalModelEndpointRepository';
|
|
27
|
+
import { ContainerRepoBootstrapper } from './ai/ContainerRepoBootstrapper';
|
|
28
|
+
import { CompositeAgentExecutor } from './ai/CompositeAgentExecutor';
|
|
29
|
+
import { ContainerSessionService } from './containers/ContainerSessionService';
|
|
30
|
+
import { DurableObjectEventPublisher } from './events/DurableObjectEventPublisher';
|
|
31
|
+
import { WorkflowsWorkRunner } from './workflows/WorkflowsWorkRunner';
|
|
32
|
+
import { WorkflowsBootstrapRunner } from './workflows/WorkflowsBootstrapRunner';
|
|
33
|
+
import { D1BlockRepository } from './repositories/D1BlockRepository';
|
|
34
|
+
import { D1ExecutionRepository } from './repositories/D1ExecutionRepository';
|
|
35
|
+
import { D1PipelineRepository } from './repositories/D1PipelineRepository';
|
|
36
|
+
import { D1ServiceRepository } from './repositories/D1ServiceRepository';
|
|
37
|
+
import { D1WorkspaceMountRepository } from './repositories/D1WorkspaceMountRepository';
|
|
38
|
+
import { D1TokenUsageRepository } from './repositories/D1TokenUsageRepository';
|
|
39
|
+
import { D1LlmCallMetricRepository } from './repositories/D1LlmCallMetricRepository';
|
|
40
|
+
import { D1WorkspaceRepository } from './repositories/D1WorkspaceRepository';
|
|
41
|
+
import { D1SlackConnectionRepository, D1SlackMemberMappingRepository, D1SlackSettingsRepository, } from './repositories/D1SlackRepositories';
|
|
42
|
+
import { D1AccountRepository } from './repositories/D1AccountRepository';
|
|
43
|
+
import { D1MembershipRepository } from './repositories/D1MembershipRepository';
|
|
44
|
+
import { D1UserRepository } from './repositories/D1UserRepository';
|
|
45
|
+
import { D1AccountInvitationRepository } from './repositories/D1AccountInvitationRepository';
|
|
46
|
+
import { D1EmailConnectionRepository } from './repositories/D1EmailConnectionRepository';
|
|
47
|
+
import { D1GitHubInstallationRepository } from './repositories/D1GitHubInstallationRepository';
|
|
48
|
+
import { D1RepoProjectionRepository } from './repositories/D1RepoProjectionRepository';
|
|
49
|
+
import { D1BranchProjectionRepository } from './repositories/D1BranchProjectionRepository';
|
|
50
|
+
import { D1PullRequestProjectionRepository } from './repositories/D1PullRequestProjectionRepository';
|
|
51
|
+
import { D1IssueProjectionRepository } from './repositories/D1IssueProjectionRepository';
|
|
52
|
+
import { D1CommitProjectionRepository } from './repositories/D1CommitProjectionRepository';
|
|
53
|
+
import { D1CheckRunProjectionRepository } from './repositories/D1CheckRunProjectionRepository';
|
|
54
|
+
import { D1RateLimitRepository } from './repositories/D1RateLimitRepository';
|
|
55
|
+
import { D1DocumentConnectionRepository } from './repositories/D1DocumentConnectionRepository';
|
|
56
|
+
import { D1DocumentRepository } from './repositories/D1DocumentRepository';
|
|
57
|
+
import { D1EnvironmentConnectionRepository } from './repositories/D1EnvironmentConnectionRepository';
|
|
58
|
+
import { D1EnvironmentRegistryRepository } from './repositories/D1EnvironmentRegistryRepository';
|
|
59
|
+
import { D1ReferenceArchitectureRepository } from './repositories/D1ReferenceArchitectureRepository';
|
|
60
|
+
import { D1BootstrapJobRepository } from './repositories/D1BootstrapJobRepository';
|
|
61
|
+
import { D1AgentRunRepository } from './repositories/D1AgentRunRepository';
|
|
62
|
+
import { D1RequirementReviewRepository } from './repositories/D1RequirementReviewRepository';
|
|
63
|
+
import { D1ConsensusSessionRepository } from './repositories/D1ConsensusSessionRepository';
|
|
64
|
+
import { ConsensusAgentExecutor, registerConsensusTraits } from '@cat-factory/consensus';
|
|
65
|
+
import { D1ClarityReviewRepository } from './repositories/D1ClarityReviewRepository';
|
|
66
|
+
import { D1NotificationRepository } from './repositories/D1NotificationRepository';
|
|
67
|
+
import { D1MergePresetRepository } from './repositories/D1MergePresetRepository';
|
|
68
|
+
import { D1WorkspaceSettingsRepository } from './repositories/D1WorkspaceSettingsRepository';
|
|
69
|
+
import { D1DatadogConnectionRepository } from './repositories/D1DatadogConnectionRepository';
|
|
70
|
+
import { D1ReleaseHealthConfigRepository } from './repositories/D1ReleaseHealthConfigRepository';
|
|
71
|
+
import { D1PipelineScheduleRepository } from './repositories/D1PipelineScheduleRepository';
|
|
72
|
+
import { D1TrackerSettingsRepository } from './repositories/D1TrackerSettingsRepository';
|
|
73
|
+
import { D1ModelDefaultsRepository } from './repositories/D1ModelDefaultsRepository';
|
|
74
|
+
import { D1ServiceFragmentDefaultsRepository } from './repositories/D1ServiceFragmentDefaultsRepository';
|
|
75
|
+
import { GitHubCiStatusProvider } from './github/GitHubCiStatusProvider';
|
|
76
|
+
import { GitHubMergeabilityProvider } from './github/GitHubMergeabilityProvider';
|
|
77
|
+
import { GitHubPullRequestMerger } from './github/GitHubPullRequestMerger';
|
|
78
|
+
import { WebCryptoSecretCipher } from './environments/WebCryptoSecretCipher';
|
|
79
|
+
import { GitHubAppAuth } from './github/GitHubAppAuth';
|
|
80
|
+
import { GitHubAppRegistry } from './github/GitHubAppRegistry';
|
|
81
|
+
import { FetchGitHubClient } from './github/FetchGitHubClient';
|
|
82
|
+
import { FetchGitHubProvisioningClient } from './github/FetchGitHubProvisioningClient';
|
|
83
|
+
import { WebCryptoWebhookVerifier } from './github/WebCryptoWebhookVerifier';
|
|
84
|
+
import { D1TaskConnectionRepository } from './repositories/D1TaskConnectionRepository';
|
|
85
|
+
import { D1TaskRepository } from './repositories/D1TaskRepository';
|
|
86
|
+
import { D1PromptFragmentRepository } from './repositories/D1PromptFragmentRepository';
|
|
87
|
+
import { D1FragmentSourceRepository } from './repositories/D1FragmentSourceRepository';
|
|
88
|
+
import { LlmFragmentSelector } from './ai/LlmFragmentSelector';
|
|
89
|
+
import { CryptoIdGenerator, SystemClock } from './runtime';
|
|
90
|
+
/**
|
|
91
|
+
* The Worker's {@link ModelProvider}: the base registry plus any extra provider
|
|
92
|
+
* registries an installation registered (see ./ai/registries). Used everywhere a
|
|
93
|
+
* model provider is needed so every path — agent executor, requirements reviewer,
|
|
94
|
+
* doc planner, fragment selector — sees the same provider set. When Langfuse is
|
|
95
|
+
* configured the provider is wrapped so those INLINE (non-proxied) calls surface on
|
|
96
|
+
* the same trace sink the LLM proxy fans container calls out to.
|
|
97
|
+
*/
|
|
98
|
+
// Memoised per `(Env, db)`: every inline consumer (agent executor, requirements
|
|
99
|
+
// reviewer, doc planner, fragment selector) shares ONE resolver — and so ONE Langfuse
|
|
100
|
+
// sink — for a container build. The resolver builds a per-scope provider from the
|
|
101
|
+
// DB-backed API-key pool plus the opt-in Cloudflare binding + Bedrock registries.
|
|
102
|
+
const modelResolverCache = new WeakMap();
|
|
103
|
+
function buildModelProviderResolver(env, db) {
|
|
104
|
+
const cached = modelResolverCache.get(env);
|
|
105
|
+
if (cached)
|
|
106
|
+
return cached;
|
|
107
|
+
// Opt-in provider registries that need no per-scope DB key: the Cloudflare Workers
|
|
108
|
+
// AI binding (when bound) and any extra registries (e.g. Bedrock). NOT assumed —
|
|
109
|
+
// `workers-ai` resolves only when the `AI` binding is present.
|
|
110
|
+
const extraRegistries = [
|
|
111
|
+
...(env.AI ? [cloudflareBindingRegistry({ binding: env.AI })] : []),
|
|
112
|
+
...resolveExtraRegistries(env),
|
|
113
|
+
];
|
|
114
|
+
const langfuse = loadLangfuseConfig(env);
|
|
115
|
+
const instrument = langfuse.enabled && langfuse.publicKey && langfuse.secretKey
|
|
116
|
+
? {
|
|
117
|
+
traceSink: createLangfuseSink({
|
|
118
|
+
publicKey: langfuse.publicKey,
|
|
119
|
+
secretKey: langfuse.secretKey,
|
|
120
|
+
baseUrl: langfuse.baseUrl,
|
|
121
|
+
logger,
|
|
122
|
+
}),
|
|
123
|
+
recordPrompts: loadObservabilityConfig(env).recordPrompts,
|
|
124
|
+
}
|
|
125
|
+
: undefined;
|
|
126
|
+
const localModelEndpoints = buildLocalModelEndpointService(env, db, { now: () => Date.now() });
|
|
127
|
+
const resolver = createScopedModelProviderResolver({
|
|
128
|
+
apiKeys: buildApiKeyService(env, db, { now: () => Date.now() }),
|
|
129
|
+
baseUrlFor: (provider) => baseUrlFor(provider, env) ?? undefined,
|
|
130
|
+
extraRegistries,
|
|
131
|
+
localEndpointsFor: localModelEndpoints
|
|
132
|
+
? (userId) => localModelEndpoints.listResolved(userId)
|
|
133
|
+
: undefined,
|
|
134
|
+
instrument,
|
|
135
|
+
});
|
|
136
|
+
modelResolverCache.set(env, resolver);
|
|
137
|
+
return resolver;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The resolver every executor consults for a workspace's per-agent-kind default
|
|
141
|
+
* model (block-pinned > workspace per-kind default > env routing > env default).
|
|
142
|
+
* Backed by the D1 model-defaults repo; shared by the inline LLM executor and the
|
|
143
|
+
* container executor so both honour the workspace defaults identically.
|
|
144
|
+
*/
|
|
145
|
+
function buildResolveWorkspaceModelDefault(db) {
|
|
146
|
+
const repo = new D1ModelDefaultsRepository({ db });
|
|
147
|
+
return (workspaceId, agentKind) => repo.getForKind(workspaceId, agentKind).then((v) => v ?? undefined);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Pick the agent that performs pipeline steps: real LLM work via the Vercel AI
|
|
151
|
+
* SDK, composed with a per-run sandbox for the repo-operating steps (`coder`,
|
|
152
|
+
* `mocker`, `playwright`, …). Container-based implementation is ALWAYS on — the
|
|
153
|
+
* sandbox is a hard requirement, so this throws at startup if it can't be built.
|
|
154
|
+
* Tests bypass this entirely by overriding `agentExecutor` with a fake.
|
|
155
|
+
*
|
|
156
|
+
* There is intentionally NO inline fallback for the sandbox kinds — a one-shot
|
|
157
|
+
* LLM call cannot clone/edit/commit/open a PR, so a degraded inline implementer is
|
|
158
|
+
* silently broken rather than usefully degraded. If the sandbox prerequisites are
|
|
159
|
+
* missing we fail the deploy loudly here rather than starting with a half-wired
|
|
160
|
+
* implementer that would only fault the moment a repo-operating step is dispatched.
|
|
161
|
+
*/
|
|
162
|
+
function selectAgentExecutor(env, config, db, clock, resolveTransport, subscriptions, personalSubscriptions) {
|
|
163
|
+
const inline = new AiAgentExecutor({
|
|
164
|
+
modelProviderResolver: buildModelProviderResolver(env, db),
|
|
165
|
+
agentRouting: config.agents.routing,
|
|
166
|
+
resolveBlockModel: config.agents.resolveBlockModel,
|
|
167
|
+
// Inline (non-sandbox) kinds honour the workspace's per-kind defaults too, so
|
|
168
|
+
// the resolution precedence is uniform across every agent kind, not just the
|
|
169
|
+
// container kinds.
|
|
170
|
+
resolveWorkspaceModelDefault: buildResolveWorkspaceModelDefault(db),
|
|
171
|
+
// Opt-in provider web search for the inline design/research kinds (no-op unless
|
|
172
|
+
// INLINE_WEB_SEARCH_ENABLED and an Anthropic/OpenAI model).
|
|
173
|
+
webSearch: inlineWebSearchOptionsFromEnv(env),
|
|
174
|
+
});
|
|
175
|
+
// The sandbox MUST build — a null here means a prerequisite (GitHub App private
|
|
176
|
+
// key, WORKER_PUBLIC_URL, AUTH_SESSION_SECRET, or a runner backend: the
|
|
177
|
+
// EXEC_CONTAINER binding or a registered runner pool) is missing. We refuse to
|
|
178
|
+
// start with a half-configured implementer rather than quietly running the
|
|
179
|
+
// repo-operating steps as useless one-shot LLM calls.
|
|
180
|
+
const container = buildContainerExecutor(env, config, db, clock, resolveTransport, subscriptions, personalSubscriptions);
|
|
181
|
+
if (!container) {
|
|
182
|
+
throw new Error('Container-based implementation is required but its prerequisites are missing. ' +
|
|
183
|
+
'Required: a configured GitHub App (GITHUB_APP_PRIVATE_KEY), WORKER_PUBLIC_URL, ' +
|
|
184
|
+
'AUTH_SESSION_SECRET, and a runner backend (the EXEC_CONTAINER binding or a ' +
|
|
185
|
+
'registered runner pool with RUNNERS_ENABLED). Refusing to start with a broken ' +
|
|
186
|
+
'executor instead of silently degrading to one-shot LLM calls.');
|
|
187
|
+
}
|
|
188
|
+
// Always the composite: non-sandbox kinds run inline; sandbox kinds run in the
|
|
189
|
+
// container.
|
|
190
|
+
return new CompositeAgentExecutor(inline, container);
|
|
191
|
+
}
|
|
192
|
+
/** Truthy env flag (`true`/`1`/`yes`). */
|
|
193
|
+
function isTruthy(value) {
|
|
194
|
+
return value === 'true' || value === '1' || value === 'yes';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Wrap the standard executor with the optional consensus mechanism when
|
|
198
|
+
* `CONSENSUS_ENABLED` is set: register the consensus capability traits (so the builder
|
|
199
|
+
* offers "Enable Consensus" on eligible steps) and route consensus-enabled steps through
|
|
200
|
+
* a multi-model process, persisting + pushing the transcript. Off ⇒ returns `standard`
|
|
201
|
+
* unchanged (no traits, no wrapping), so behaviour is identical to before.
|
|
202
|
+
*/
|
|
203
|
+
function maybeWrapConsensus(standard, env, config, db, eventPublisher) {
|
|
204
|
+
if (!isTruthy(env.CONSENSUS_ENABLED))
|
|
205
|
+
return standard;
|
|
206
|
+
registerConsensusTraits();
|
|
207
|
+
return new ConsensusAgentExecutor({
|
|
208
|
+
standard,
|
|
209
|
+
modelProviderResolver: buildModelProviderResolver(env, db),
|
|
210
|
+
agentRouting: config.agents.routing,
|
|
211
|
+
resolveBlockModel: config.agents.resolveBlockModel,
|
|
212
|
+
resolveWorkspaceModelDefault: buildResolveWorkspaceModelDefault(db),
|
|
213
|
+
sessionRepository: new D1ConsensusSessionRepository({ db }),
|
|
214
|
+
...(eventPublisher ? { eventPublisher } : {}),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Build the factory that picks a job's runner backend: a workspace's own
|
|
219
|
+
* self-hosted runner pool when one is registered (and runner pools are enabled),
|
|
220
|
+
* otherwise the per-run Cloudflare Container. Returns null when neither backend is
|
|
221
|
+
* available, so {@link buildContainerExecutor} falls back to inline work.
|
|
222
|
+
*/
|
|
223
|
+
function buildResolveTransport(env, config, db, clock) {
|
|
224
|
+
// The Cloudflare backend folds in instance-level reaping: the registry records
|
|
225
|
+
// each dispatched container in the live inventory and clears it on release, so the
|
|
226
|
+
// cron reaper (index.ts) can kill anything that outlived its lifetime — covering
|
|
227
|
+
// run/blueprint/bootstrap through this one transport with no per-flow wiring.
|
|
228
|
+
const cloudflare = env.EXEC_CONTAINER
|
|
229
|
+
? new CloudflareContainerTransport(env.EXEC_CONTAINER, new ContainerInstanceRegistry(env.EXEC_CONTAINER, new D1LiveContainerRepository({ db }), clock))
|
|
230
|
+
: null;
|
|
231
|
+
// The self-hosted pool path: one stateless manifest interpreter (its OAuth cache
|
|
232
|
+
// shared) plus a connection service to resolve each workspace's manifest+secrets.
|
|
233
|
+
let runnerService;
|
|
234
|
+
let poolProvider;
|
|
235
|
+
if (config.runners.enabled) {
|
|
236
|
+
runnerService = new RunnerPoolConnectionService({
|
|
237
|
+
runnerPoolConnectionRepository: new D1RunnerPoolConnectionRepository({ db }),
|
|
238
|
+
workspaceRepository: new D1WorkspaceRepository({ db }),
|
|
239
|
+
secretCipher: new WebCryptoSecretCipher({
|
|
240
|
+
masterKeyBase64: config.runners.encryptionKey,
|
|
241
|
+
info: 'cat-factory:runners',
|
|
242
|
+
}),
|
|
243
|
+
clock,
|
|
244
|
+
});
|
|
245
|
+
const urlPolicy = resolveUrlSafetyPolicy(config.runners);
|
|
246
|
+
poolProvider = new HttpRunnerPoolProvider(urlPolicy ? { urlPolicy } : {});
|
|
247
|
+
}
|
|
248
|
+
if (!cloudflare && !runnerService)
|
|
249
|
+
return null;
|
|
250
|
+
return async (workspaceId) => {
|
|
251
|
+
if (runnerService && poolProvider && workspaceId) {
|
|
252
|
+
const resolved = await runnerService.resolve(workspaceId);
|
|
253
|
+
if (resolved) {
|
|
254
|
+
return new RunnerPoolTransport(poolProvider, resolved.manifest, resolved.resolveSecret);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (cloudflare)
|
|
258
|
+
return cloudflare;
|
|
259
|
+
throw new Error(`No runner backend available for workspace '${workspaceId ?? '(unknown)'}': ` +
|
|
260
|
+
`register a runner pool or enable Cloudflare Containers`);
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Build the container-based implementation executor, or return null when its
|
|
265
|
+
* prerequisites are missing (a runner backend — Cloudflare Containers and/or a
|
|
266
|
+
* self-hosted pool — plus a configured GitHub App, the proxy's public URL and the
|
|
267
|
+
* signing secret) — the caller then falls back to inline work.
|
|
268
|
+
*/
|
|
269
|
+
/**
|
|
270
|
+
* Build the multi-App registry (ADR 0005): the default App always, plus the
|
|
271
|
+
* privileged App when configured. It resolves which App's key to use per
|
|
272
|
+
* installation (from the binding's recorded appId), so every token mint / app-JWT
|
|
273
|
+
* call routes correctly. Callers guard on `config.github.enabled`, which requires
|
|
274
|
+
* GITHUB_APP_PRIVATE_KEY, so the default key is present.
|
|
275
|
+
*/
|
|
276
|
+
function buildAppRegistry(env, config, db, clock) {
|
|
277
|
+
const installationRepository = new D1GitHubInstallationRepository({ db });
|
|
278
|
+
const makeAuth = (appId, privateKeyPem) => new GitHubAppAuth({
|
|
279
|
+
appId,
|
|
280
|
+
privateKeyPem,
|
|
281
|
+
installationRepository,
|
|
282
|
+
clock,
|
|
283
|
+
apiBase: config.github.apiBase,
|
|
284
|
+
});
|
|
285
|
+
const privileged = config.github.privilegedApp && env.GITHUB_PRIVILEGED_APP_PRIVATE_KEY
|
|
286
|
+
? {
|
|
287
|
+
appId: config.github.privilegedApp.appId,
|
|
288
|
+
auth: makeAuth(config.github.privilegedApp.appId, env.GITHUB_PRIVILEGED_APP_PRIVATE_KEY),
|
|
289
|
+
}
|
|
290
|
+
: undefined;
|
|
291
|
+
return new GitHubAppRegistry({
|
|
292
|
+
default: {
|
|
293
|
+
appId: config.github.appId,
|
|
294
|
+
auth: makeAuth(config.github.appId, env.GITHUB_APP_PRIVATE_KEY),
|
|
295
|
+
},
|
|
296
|
+
privileged,
|
|
297
|
+
installationRepository,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Resolve the repo linked to a running block's enclosing service, via the shared
|
|
302
|
+
* runtime-neutral `buildResolveRepoTarget` (the ancestry walk + no-fallback policy
|
|
303
|
+
* live in `@cat-factory/server` so the Worker and Node service can't drift). This
|
|
304
|
+
* wrapper just binds the D1 repositories. Shared by the container executor, the CI
|
|
305
|
+
* status provider and the PR merger.
|
|
306
|
+
*/
|
|
307
|
+
function buildResolveRepoTarget(db) {
|
|
308
|
+
return buildSharedResolveRepoTarget({
|
|
309
|
+
installationRepository: new D1GitHubInstallationRepository({ db }),
|
|
310
|
+
repoProjectionRepository: new D1RepoProjectionRepository({ db }),
|
|
311
|
+
blockRepository: new D1BlockRepository({ db }),
|
|
312
|
+
serviceRepository: new D1ServiceRepository({ db }),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Build the merge-lifecycle ports. The notification repository + merge-preset
|
|
317
|
+
* repository are wired unconditionally (the inbox + presets are always available);
|
|
318
|
+
* the in-app delivery channel is wired only when the events binding is present
|
|
319
|
+
* (else rows persist but nothing is pushed). The CI status provider + PR merger
|
|
320
|
+
* need GitHub, so they're wired only when the App is configured — without them the
|
|
321
|
+
* `ci` gate passes through and `done` is a board-only flip (graceful degradation).
|
|
322
|
+
*/
|
|
323
|
+
function selectMergeLifecycleDeps(env, config, db, clock, idGenerator) {
|
|
324
|
+
const deps = {
|
|
325
|
+
notificationRepository: new D1NotificationRepository({ db }),
|
|
326
|
+
mergePresetRepository: new D1MergePresetRepository({ db }),
|
|
327
|
+
workspaceSettingsRepository: new D1WorkspaceSettingsRepository({ db }),
|
|
328
|
+
modelDefaultsRepository: new D1ModelDefaultsRepository({ db }),
|
|
329
|
+
serviceFragmentDefaultsRepository: new D1ServiceFragmentDefaultsRepository({ db }),
|
|
330
|
+
};
|
|
331
|
+
// Compose the delivery channels: in-app push (when the events binding is present)
|
|
332
|
+
// and Slack (when the integration is enabled) implement the same NotificationChannel
|
|
333
|
+
// port and fan out via CompositeNotificationChannel — realizing the seam the kernel
|
|
334
|
+
// port documents, with no change to the engine call sites that raise notifications.
|
|
335
|
+
const channels = [];
|
|
336
|
+
const publisher = selectEventPublisher(env, db);
|
|
337
|
+
if (publisher)
|
|
338
|
+
channels.push(new InAppNotificationChannel(publisher));
|
|
339
|
+
const slackChannel = buildSlackChannel(config, db);
|
|
340
|
+
if (slackChannel)
|
|
341
|
+
channels.push(slackChannel);
|
|
342
|
+
if (channels.length === 1)
|
|
343
|
+
deps.notificationChannel = channels[0];
|
|
344
|
+
else if (channels.length > 1)
|
|
345
|
+
deps.notificationChannel = new CompositeNotificationChannel(channels);
|
|
346
|
+
if (config.github.enabled && env.GITHUB_APP_PRIVATE_KEY) {
|
|
347
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
348
|
+
const githubClient = new FetchGitHubClient({
|
|
349
|
+
registry,
|
|
350
|
+
rateLimitRepository: new D1RateLimitRepository({ db, idGenerator }),
|
|
351
|
+
idGenerator,
|
|
352
|
+
clock,
|
|
353
|
+
apiBase: config.github.apiBase,
|
|
354
|
+
});
|
|
355
|
+
const resolveRepoTarget = buildResolveRepoTarget(db);
|
|
356
|
+
const blockRepository = new D1BlockRepository({ db });
|
|
357
|
+
deps.ciStatusProvider = new GitHubCiStatusProvider({
|
|
358
|
+
githubClient,
|
|
359
|
+
resolveRepoTarget,
|
|
360
|
+
blockRepository,
|
|
361
|
+
});
|
|
362
|
+
deps.mergeabilityProvider = new GitHubMergeabilityProvider({
|
|
363
|
+
githubClient,
|
|
364
|
+
resolveRepoTarget,
|
|
365
|
+
blockRepository,
|
|
366
|
+
});
|
|
367
|
+
deps.pullRequestMerger = new GitHubPullRequestMerger({
|
|
368
|
+
githubClient,
|
|
369
|
+
resolveRepoTarget,
|
|
370
|
+
blockRepository,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
return deps;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Wire the Datadog post-release-health gate when enabled (+ ENCRYPTION_KEY): the
|
|
377
|
+
* connection + per-block config repos, the cipher that seals the keys, the release-health
|
|
378
|
+
* provider the gate probes, and (optionally) the PagerDuty / incident.io enrichment
|
|
379
|
+
* providers. Off → the gate is a pass-through and the release-health module isn't built.
|
|
380
|
+
*/
|
|
381
|
+
function selectReleaseHealthDeps(env, config, db) {
|
|
382
|
+
if (!config.datadog.enabled || !config.datadog.encryptionKey)
|
|
383
|
+
return {};
|
|
384
|
+
const datadogConnectionRepository = new D1DatadogConnectionRepository({ db });
|
|
385
|
+
const releaseHealthConfigRepository = new D1ReleaseHealthConfigRepository({ db });
|
|
386
|
+
const datadogSecretCipher = new WebCryptoSecretCipher({
|
|
387
|
+
masterKeyBase64: config.datadog.encryptionKey,
|
|
388
|
+
info: DATADOG_CIPHER_INFO,
|
|
389
|
+
});
|
|
390
|
+
const deps = {
|
|
391
|
+
datadogConnectionRepository,
|
|
392
|
+
releaseHealthConfigRepository,
|
|
393
|
+
datadogSecretCipher,
|
|
394
|
+
releaseHealthProvider: new DatadogReleaseHealthProvider({
|
|
395
|
+
datadogConnectionRepository,
|
|
396
|
+
releaseHealthConfigRepository,
|
|
397
|
+
blockRepository: new D1BlockRepository({ db }),
|
|
398
|
+
secretCipher: datadogSecretCipher,
|
|
399
|
+
}),
|
|
400
|
+
};
|
|
401
|
+
const enrichers = [];
|
|
402
|
+
if (config.incidentEnrichment.pagerDuty) {
|
|
403
|
+
enrichers.push(new PagerDutyEnrichmentProvider(config.incidentEnrichment.pagerDuty));
|
|
404
|
+
}
|
|
405
|
+
if (config.incidentEnrichment.incidentIo) {
|
|
406
|
+
enrichers.push(new IncidentIoEnrichmentProvider(config.incidentEnrichment.incidentIo));
|
|
407
|
+
}
|
|
408
|
+
if (enrichers.length > 0) {
|
|
409
|
+
deps.incidentEnrichment = new CompositeIncidentEnrichmentProvider(enrichers);
|
|
410
|
+
}
|
|
411
|
+
return deps;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Construct the Slack repositories + bot-token cipher once, when the integration is
|
|
415
|
+
* enabled — the single source of truth shared by both the delivery channel and the
|
|
416
|
+
* management module so neither duplicates the wiring. Null when Slack is off.
|
|
417
|
+
*/
|
|
418
|
+
function buildSlackInfra(config, db) {
|
|
419
|
+
if (!config.slack.enabled || !config.slack.encryptionKey)
|
|
420
|
+
return null;
|
|
421
|
+
return {
|
|
422
|
+
connectionRepository: new D1SlackConnectionRepository({ db }),
|
|
423
|
+
settingsRepository: new D1SlackSettingsRepository({ db }),
|
|
424
|
+
memberMappingRepository: new D1SlackMemberMappingRepository({ db }),
|
|
425
|
+
cipher: new WebCryptoSecretCipher({
|
|
426
|
+
masterKeyBase64: config.slack.encryptionKey,
|
|
427
|
+
info: SLACK_CIPHER_INFO,
|
|
428
|
+
}),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Build the Slack notification channel when the integration is enabled — a
|
|
433
|
+
* runtime-neutral transport (fetch + decrypt + D1 reads) composed alongside the
|
|
434
|
+
* in-app channel. Null when Slack is off (then nothing Slack-related is wired).
|
|
435
|
+
*/
|
|
436
|
+
function buildSlackChannel(config, db) {
|
|
437
|
+
const infra = buildSlackInfra(config, db);
|
|
438
|
+
if (!infra)
|
|
439
|
+
return null;
|
|
440
|
+
return new SlackNotificationChannel({
|
|
441
|
+
workspaceRepository: new D1WorkspaceRepository({ db }),
|
|
442
|
+
slackConnectionRepository: infra.connectionRepository,
|
|
443
|
+
slackSettingsRepository: infra.settingsRepository,
|
|
444
|
+
slackMemberMappingRepository: infra.memberMappingRepository,
|
|
445
|
+
blockRepository: new D1BlockRepository({ db }),
|
|
446
|
+
secretCipher: infra.cipher,
|
|
447
|
+
// Best-effort delivery still surfaces failures (revoked token, missing channel
|
|
448
|
+
// invite) through the structured logger so a broken route is diagnosable.
|
|
449
|
+
onError: (error, ctx) => logger.warn({ err: error instanceof Error ? error.message : String(error), ...ctx }, 'slack notification delivery failed'),
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Wire the Slack management module (per-account connect + per-workspace routing +
|
|
454
|
+
* member map). Wired only when the integration is enabled; the actual delivery is
|
|
455
|
+
* the channel composed in by {@link selectMergeLifecycleDeps}. OAuth credentials
|
|
456
|
+
* are optional — manual bot-token onboarding works without them.
|
|
457
|
+
*/
|
|
458
|
+
function selectSlackDeps(config, db) {
|
|
459
|
+
const infra = buildSlackInfra(config, db);
|
|
460
|
+
if (!infra)
|
|
461
|
+
return {};
|
|
462
|
+
return {
|
|
463
|
+
slackConnectionRepository: infra.connectionRepository,
|
|
464
|
+
slackSettingsRepository: infra.settingsRepository,
|
|
465
|
+
slackMemberMappingRepository: infra.memberMappingRepository,
|
|
466
|
+
slackSecretCipher: infra.cipher,
|
|
467
|
+
...(config.slack.oauth ? { slackOAuth: config.slack.oauth } : {}),
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Wire account invitations + per-account email senders. Invitations are always
|
|
472
|
+
* available (an invite link works without email); the email-connection store + its
|
|
473
|
+
* cipher are wired only when EMAIL is enabled (an encryption key is mandatory), so
|
|
474
|
+
* an account can onboard a SendGrid/Resend key in the UI and have invites emailed.
|
|
475
|
+
*/
|
|
476
|
+
function selectEmailInvitationDeps(config, db) {
|
|
477
|
+
const deps = {
|
|
478
|
+
invitationRepository: new D1AccountInvitationRepository({ db }),
|
|
479
|
+
appBaseUrl: config.email.appBaseUrl || undefined,
|
|
480
|
+
};
|
|
481
|
+
if (config.email.enabled && config.email.encryptionKey) {
|
|
482
|
+
deps.emailConnectionRepository = new D1EmailConnectionRepository({ db });
|
|
483
|
+
deps.emailSecretCipher = new WebCryptoSecretCipher({
|
|
484
|
+
masterKeyBase64: config.email.encryptionKey,
|
|
485
|
+
info: EMAIL_CIPHER_INFO,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
return deps;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Wire the opt-in Langfuse trace sink. Built only when `LANGFUSE_ENABLED=true` and both
|
|
492
|
+
* keys are set; the observability service then fans every recorded LLM call out to it.
|
|
493
|
+
* A fetch-based sink, so it runs unchanged on the Worker runtime.
|
|
494
|
+
*/
|
|
495
|
+
function buildLangfuseSink(config) {
|
|
496
|
+
if (!config.langfuse.enabled || !config.langfuse.publicKey || !config.langfuse.secretKey) {
|
|
497
|
+
return undefined;
|
|
498
|
+
}
|
|
499
|
+
return createLangfuseSink({
|
|
500
|
+
publicKey: config.langfuse.publicKey,
|
|
501
|
+
secretKey: config.langfuse.secretKey,
|
|
502
|
+
baseUrl: config.langfuse.baseUrl,
|
|
503
|
+
logger,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
function selectLangfuseSink(config) {
|
|
507
|
+
const sink = buildLangfuseSink(config);
|
|
508
|
+
return sink ? { llmTraceSink: sink } : {};
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Wire the recurring-pipeline + issue-tracker ports. The schedule + tracker-setting
|
|
512
|
+
* repositories are always available (the feature is workspace-scoped CRUD); the
|
|
513
|
+
* `ticketTrackerProvider` files the tech-debt pipeline's issue and degrades
|
|
514
|
+
* gracefully — it files GitHub issues only when the App is configured (so it can
|
|
515
|
+
* resolve the service's repo + mint a token) and Jira only when the tasks
|
|
516
|
+
* integration's encryption key is set (so it can read the workspace's stored Jira
|
|
517
|
+
* credentials). With neither, the `tracker` step passes through.
|
|
518
|
+
*/
|
|
519
|
+
function selectRecurringDeps(env, config, db, clock, idGenerator) {
|
|
520
|
+
const trackerDeps = {
|
|
521
|
+
trackerSettingsRepository: new D1TrackerSettingsRepository({ db }),
|
|
522
|
+
// workerd exposes a global fetch; the Jira create call uses it.
|
|
523
|
+
fetchImpl: fetch,
|
|
524
|
+
};
|
|
525
|
+
// GitHub issues: file through the App-authenticated client against the service's
|
|
526
|
+
// linked repo (resolved from the github_repos projection). Only when the App is configured.
|
|
527
|
+
if (config.github.enabled && env.GITHUB_APP_PRIVATE_KEY) {
|
|
528
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
529
|
+
const githubClient = new FetchGitHubClient({
|
|
530
|
+
registry,
|
|
531
|
+
rateLimitRepository: new D1RateLimitRepository({ db, idGenerator }),
|
|
532
|
+
idGenerator,
|
|
533
|
+
clock,
|
|
534
|
+
apiBase: config.github.apiBase,
|
|
535
|
+
});
|
|
536
|
+
const resolveRepoTarget = buildResolveRepoTarget(db);
|
|
537
|
+
trackerDeps.fileGitHubIssue = async (request) => {
|
|
538
|
+
const repo = await resolveRepoTarget(request.workspaceId, request.frameId);
|
|
539
|
+
if (!repo)
|
|
540
|
+
return null;
|
|
541
|
+
const issue = await githubClient.createIssue(repo.installationId, { owner: repo.owner, repo: repo.name }, { title: request.title, body: request.body });
|
|
542
|
+
return { externalId: `${repo.owner}/${repo.name}#${issue.number}`, url: issue.url };
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
// Jira: read the workspace's stored connection credentials (when the tasks
|
|
546
|
+
// integration's encryption key is configured).
|
|
547
|
+
if (config.tasks.encryptionKey) {
|
|
548
|
+
const taskConnectionRepository = new D1TaskConnectionRepository({
|
|
549
|
+
db,
|
|
550
|
+
cipher: new WebCryptoSecretCipher({
|
|
551
|
+
masterKeyBase64: config.tasks.encryptionKey,
|
|
552
|
+
info: 'cat-factory:tasks',
|
|
553
|
+
}),
|
|
554
|
+
});
|
|
555
|
+
trackerDeps.resolveJiraConnection = async (workspaceId) => {
|
|
556
|
+
const connection = await taskConnectionRepository.getByWorkspace(workspaceId, 'jira');
|
|
557
|
+
const { baseUrl, accountEmail, apiToken } = connection?.credentials ?? {};
|
|
558
|
+
if (!baseUrl || !accountEmail || !apiToken)
|
|
559
|
+
return null;
|
|
560
|
+
return { baseUrl, accountEmail, apiToken };
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
return {
|
|
564
|
+
pipelineScheduleRepository: new D1PipelineScheduleRepository({ db }),
|
|
565
|
+
trackerSettingsRepository: new D1TrackerSettingsRepository({ db }),
|
|
566
|
+
ticketTrackerProvider: new TicketTrackerService(trackerDeps),
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Build the workspace subscription-token pool service (Claude Code / Codex
|
|
571
|
+
* credentials), or undefined when the shared ENCRYPTION_KEY is absent. Tokens are
|
|
572
|
+
* sealed under a subscriptions-scoped HKDF info of the shared master key.
|
|
573
|
+
*/
|
|
574
|
+
function buildSubscriptionService(env, db, clock) {
|
|
575
|
+
const masterKeyBase64 = env.ENCRYPTION_KEY?.trim();
|
|
576
|
+
if (!masterKeyBase64)
|
|
577
|
+
return undefined;
|
|
578
|
+
return new ProviderSubscriptionService({
|
|
579
|
+
providerSubscriptionTokenRepository: new D1ProviderSubscriptionTokenRepository({ db }),
|
|
580
|
+
workspaceRepository: new D1WorkspaceRepository({ db }),
|
|
581
|
+
secretCipher: new WebCryptoSecretCipher({
|
|
582
|
+
masterKeyBase64,
|
|
583
|
+
info: 'cat-factory:provider-subscriptions',
|
|
584
|
+
}),
|
|
585
|
+
idGenerator: new CryptoIdGenerator(),
|
|
586
|
+
clock,
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Build the direct-provider API-key pool service (account/workspace/user-scoped),
|
|
591
|
+
* or undefined when no ENCRYPTION_KEY is configured. Keys are sealed under an
|
|
592
|
+
* api-keys-scoped HKDF info of the shared master key. Shared by the API-key
|
|
593
|
+
* controller, the model-provider resolver, and the LLM proxy's key lease.
|
|
594
|
+
*/
|
|
595
|
+
function buildApiKeyService(env, db, clock) {
|
|
596
|
+
const masterKeyBase64 = env.ENCRYPTION_KEY?.trim();
|
|
597
|
+
if (!masterKeyBase64)
|
|
598
|
+
return undefined;
|
|
599
|
+
return new ApiKeyService({
|
|
600
|
+
providerApiKeyRepository: new D1ProviderApiKeyRepository({ db }),
|
|
601
|
+
workspaceRepository: new D1WorkspaceRepository({ db }),
|
|
602
|
+
secretCipher: new WebCryptoSecretCipher({
|
|
603
|
+
masterKeyBase64,
|
|
604
|
+
info: 'cat-factory:provider-api-keys',
|
|
605
|
+
}),
|
|
606
|
+
idGenerator: new CryptoIdGenerator(),
|
|
607
|
+
clock,
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Build the per-USER individual-usage subscription service (Claude), or undefined when
|
|
612
|
+
* no ENCRYPTION_KEY is configured. Uses the system SecretCipher (master key, scoped
|
|
613
|
+
* info) for the outer layer and the password-derived PersonalSecretCipher for the inner
|
|
614
|
+
* layer of the double-encrypted credential. Shared by the personal-subscription
|
|
615
|
+
* controller and the container executor's personal lease.
|
|
616
|
+
*/
|
|
617
|
+
function buildPersonalSubscriptionService(env, db, clock) {
|
|
618
|
+
const masterKeyBase64 = env.ENCRYPTION_KEY?.trim();
|
|
619
|
+
if (!masterKeyBase64)
|
|
620
|
+
return undefined;
|
|
621
|
+
return new PersonalSubscriptionService({
|
|
622
|
+
personalSubscriptionRepository: new D1PersonalSubscriptionRepository({ db }),
|
|
623
|
+
subscriptionActivationRepository: new D1SubscriptionActivationRepository({ db }),
|
|
624
|
+
secretCipher: new WebCryptoSecretCipher({
|
|
625
|
+
masterKeyBase64,
|
|
626
|
+
info: 'cat-factory:personal-subscriptions',
|
|
627
|
+
}),
|
|
628
|
+
personalCipher: new WebCryptoPersonalSecretCipher(),
|
|
629
|
+
idGenerator: new CryptoIdGenerator(),
|
|
630
|
+
clock,
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* The per-USER locally-run model endpoints store (Ollama / LM Studio / …), or undefined
|
|
635
|
+
* when no ENCRYPTION_KEY is configured (the optional bearer key is sealed with the system
|
|
636
|
+
* cipher). Shared by the local-runner controller, the per-user model catalog, and the LLM
|
|
637
|
+
* proxy's base-URL/key resolution for a locally-run model.
|
|
638
|
+
*/
|
|
639
|
+
function buildLocalModelEndpointService(env, db, clock) {
|
|
640
|
+
const masterKeyBase64 = env.ENCRYPTION_KEY?.trim();
|
|
641
|
+
if (!masterKeyBase64)
|
|
642
|
+
return undefined;
|
|
643
|
+
return new LocalModelEndpointService({
|
|
644
|
+
localModelEndpointRepository: new D1LocalModelEndpointRepository({ db }),
|
|
645
|
+
secretCipher: new WebCryptoSecretCipher({
|
|
646
|
+
masterKeyBase64,
|
|
647
|
+
info: 'cat-factory:local-model-endpoints',
|
|
648
|
+
}),
|
|
649
|
+
clock,
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
function buildContainerExecutor(env, config, db, clock, resolveTransport, subscriptions, personalSubscriptions) {
|
|
653
|
+
if (!config.github.enabled ||
|
|
654
|
+
!env.GITHUB_APP_PRIVATE_KEY ||
|
|
655
|
+
!env.WORKER_PUBLIC_URL ||
|
|
656
|
+
!env.AUTH_SESSION_SECRET) {
|
|
657
|
+
return null;
|
|
658
|
+
}
|
|
659
|
+
if (!resolveTransport)
|
|
660
|
+
return null;
|
|
661
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
662
|
+
const resolveRepoTarget = buildResolveRepoTarget(db);
|
|
663
|
+
return new ContainerAgentExecutor({
|
|
664
|
+
resolveTransport,
|
|
665
|
+
agentRouting: config.agents.routing,
|
|
666
|
+
resolveBlockModel: config.agents.resolveBlockModel,
|
|
667
|
+
// The workspace's per-agent-kind default model, consulted when a block pins none
|
|
668
|
+
// (block-pinned > workspace per-kind default > env routing > env default).
|
|
669
|
+
resolveWorkspaceModelDefault: buildResolveWorkspaceModelDefault(db),
|
|
670
|
+
resolveRepoTarget,
|
|
671
|
+
// Resolve the workspace's owning account so the proxy can lease account-scoped keys.
|
|
672
|
+
resolveAccountId: (workspaceId) => new D1WorkspaceRepository({ db }).accountOf(workspaceId),
|
|
673
|
+
mintInstallationToken: (id) => registry.installationToken(id),
|
|
674
|
+
// Ensure the shared per-task work branch up front so every agent (including the
|
|
675
|
+
// read-only architect) operates on the same branch — idempotent, best-effort. Writers
|
|
676
|
+
// create it from base; read-only agents only probe (`options.create`).
|
|
677
|
+
ensureWorkBranch: async (repo, branch, options) => ensureWorkBranchViaRest({
|
|
678
|
+
...(config.github.apiBase ? { apiBase: config.github.apiBase } : {}),
|
|
679
|
+
token: await registry.installationToken(repo.installationId),
|
|
680
|
+
owner: repo.owner,
|
|
681
|
+
name: repo.name,
|
|
682
|
+
baseBranch: repo.baseBranch,
|
|
683
|
+
branch,
|
|
684
|
+
create: options.create,
|
|
685
|
+
}),
|
|
686
|
+
sessionService: new ContainerSessionService({ secret: env.AUTH_SESSION_SECRET }),
|
|
687
|
+
// The subscription harnesses (Claude Code / Codex) lease a pooled token and
|
|
688
|
+
// attribute usage back for usage-aware rotation; absent ⇒ those harnesses are
|
|
689
|
+
// unavailable and a subscription-only model fails loudly at dispatch.
|
|
690
|
+
...(subscriptions
|
|
691
|
+
? {
|
|
692
|
+
leaseSubscriptionToken: (workspaceId, vendor) => subscriptions.leaseToken(workspaceId, vendor),
|
|
693
|
+
recordSubscriptionUsage: (workspaceId, tokenId, usage) => subscriptions.recordTokenUsage(workspaceId, tokenId, usage),
|
|
694
|
+
hasSubscriptionToken: (workspaceId, vendor) => subscriptions.hasToken(workspaceId, vendor),
|
|
695
|
+
}
|
|
696
|
+
: {}),
|
|
697
|
+
// Individual-usage harnesses (Claude) lease the run-initiator's OWN activated
|
|
698
|
+
// personal credential; absent ⇒ such models fail loudly at dispatch.
|
|
699
|
+
...(personalSubscriptions
|
|
700
|
+
? {
|
|
701
|
+
leasePersonalSubscriptionToken: (executionId, userId, vendor) => personalSubscriptions.leaseForRun(executionId, userId, vendor),
|
|
702
|
+
// Route a dual-mode individual model (GLM) to the initiator's own subscription
|
|
703
|
+
// when they have one; otherwise dispatch keeps it on the Cloudflare base.
|
|
704
|
+
hasPersonalSubscription: (userId, vendor) => personalSubscriptions.has(userId, vendor),
|
|
705
|
+
}
|
|
706
|
+
: {}),
|
|
707
|
+
proxyBaseUrl: `${env.WORKER_PUBLIC_URL.replace(/\/+$/, '')}/v1`,
|
|
708
|
+
// Point container agents' web search at the backend search proxy (no provider key
|
|
709
|
+
// in the sandbox) whenever an upstream is configured for this deployment.
|
|
710
|
+
webSearchProxyEnabled: Boolean(createWebSearchUpstreamFromEnv(env)),
|
|
711
|
+
githubApiBase: config.github.apiBase,
|
|
712
|
+
// Forward container tool spans to Langfuse (when configured) as child spans under
|
|
713
|
+
// the run trace — the same sink the LLM proxy fans generations out to.
|
|
714
|
+
llmTraceSink: buildLangfuseSink(config),
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Pick how runs are driven:
|
|
719
|
+
* - a Workflows binding present → durable, server-driven execution
|
|
720
|
+
* - otherwise → no-op (e.g. tests, which override this anyway)
|
|
721
|
+
* Tests override `workRunner` with a fake and drive the engine via advanceInstance.
|
|
722
|
+
*/
|
|
723
|
+
function selectWorkRunner(env) {
|
|
724
|
+
if (env.EXECUTION_WORKFLOW) {
|
|
725
|
+
return new WorkflowsWorkRunner({
|
|
726
|
+
workflow: env.EXECUTION_WORKFLOW,
|
|
727
|
+
queue: env.EXECUTION_QUEUE,
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
return new NoopWorkRunner();
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Pick how execution/board changes are pushed to clients:
|
|
734
|
+
* - WORKSPACE_EVENTS binding present → fan out via the per-workspace hub DO
|
|
735
|
+
* - otherwise → undefined (core falls back to a no-op)
|
|
736
|
+
* Tests leave the binding unset; the engine simply pushes nothing.
|
|
737
|
+
*/
|
|
738
|
+
function selectEventPublisher(env, db) {
|
|
739
|
+
if (!env.WORKSPACE_EVENTS)
|
|
740
|
+
return undefined;
|
|
741
|
+
// Fan a shared service's live events out to EVERY workspace that mounts it, not just the
|
|
742
|
+
// one the engine addressed (in-org real-time sharing).
|
|
743
|
+
return new FanOutEventPublisher(new DurableObjectEventPublisher(env.WORKSPACE_EVENTS), {
|
|
744
|
+
workspaceMountRepository: new D1WorkspaceMountRepository({ db }),
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Build the GitHub integration's concrete ports when an App is configured,
|
|
749
|
+
* mirroring `selectWorkRunner`. Returns an empty object otherwise, so `createCore`
|
|
750
|
+
* leaves the `github` module unassembled and the feature stays opt-in.
|
|
751
|
+
*/
|
|
752
|
+
function selectGitHubDeps(env, config, db, clock, idGenerator) {
|
|
753
|
+
if (!config.github.enabled)
|
|
754
|
+
return {};
|
|
755
|
+
const githubInstallationRepository = new D1GitHubInstallationRepository({ db });
|
|
756
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
757
|
+
const githubClient = new FetchGitHubClient({
|
|
758
|
+
registry,
|
|
759
|
+
rateLimitRepository: new D1RateLimitRepository({ db, idGenerator }),
|
|
760
|
+
idGenerator,
|
|
761
|
+
clock,
|
|
762
|
+
apiBase: config.github.apiBase,
|
|
763
|
+
});
|
|
764
|
+
// Privileged App tier (ADR 0005): when configured, its client backs the
|
|
765
|
+
// create-repo endpoint; `canCreateRepos` flags a connection whose installation
|
|
766
|
+
// is owned by the privileged App. Absent → repo creation stays the manual flow.
|
|
767
|
+
const repoProvisioningClient = config.github.privilegedApp
|
|
768
|
+
? new FetchGitHubProvisioningClient({ registry, apiBase: config.github.apiBase })
|
|
769
|
+
: undefined;
|
|
770
|
+
return {
|
|
771
|
+
githubClient,
|
|
772
|
+
githubInstallationRepository,
|
|
773
|
+
repoProjectionRepository: new D1RepoProjectionRepository({ db }),
|
|
774
|
+
branchProjectionRepository: new D1BranchProjectionRepository({ db }),
|
|
775
|
+
pullRequestProjectionRepository: new D1PullRequestProjectionRepository({ db }),
|
|
776
|
+
issueProjectionRepository: new D1IssueProjectionRepository({ db }),
|
|
777
|
+
commitProjectionRepository: new D1CommitProjectionRepository({ db }),
|
|
778
|
+
checkRunProjectionRepository: new D1CheckRunProjectionRepository({ db }),
|
|
779
|
+
webhookVerifier: new WebCryptoWebhookVerifier(env.GITHUB_WEBHOOK_SECRET),
|
|
780
|
+
// Bound the initial backfill to the commit retention horizon (0 = full).
|
|
781
|
+
commitBackfillHorizonMs: config.retention.commitMs || undefined,
|
|
782
|
+
repoProvisioningClient,
|
|
783
|
+
canCreateRepos: (installation) => registry.canCreateRepos(installation),
|
|
784
|
+
// Advisory: does the install actually grant `workflows: write`? Read from the
|
|
785
|
+
// owning App's installation-token permission set (cached), so the UI can warn
|
|
786
|
+
// when agent pushes touching `.github/workflows/*` would be rejected.
|
|
787
|
+
workflowsGranted: async (installation) => {
|
|
788
|
+
const perms = await registry.installationPermissions(installation.installationId);
|
|
789
|
+
return perms.workflows === 'write';
|
|
790
|
+
},
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Build the document-source integration's concrete ports: the configured source
|
|
795
|
+
* providers (Confluence, Notion, …) plus the two D1 repositories. The integration is
|
|
796
|
+
* always on (config load fails loudly without the encryption key), so this is wired
|
|
797
|
+
* on every deployment. The model provider is wired only in 'llm' planner mode (it
|
|
798
|
+
* just needs a provider credential); the planner degrades to its deterministic parser
|
|
799
|
+
* if no model is usable.
|
|
800
|
+
*/
|
|
801
|
+
function selectDocumentsDeps(env, config, db, clock, idGenerator) {
|
|
802
|
+
const providers = [];
|
|
803
|
+
if (config.documents.sources.includes('confluence'))
|
|
804
|
+
providers.push(new ConfluenceProvider());
|
|
805
|
+
if (config.documents.sources.includes('notion'))
|
|
806
|
+
providers.push(new NotionProvider());
|
|
807
|
+
// GitHub repo docs reuse the workspace's installed GitHub App, so this provider
|
|
808
|
+
// is wired only when the GitHub integration is also configured — it has no
|
|
809
|
+
// credentials of its own and resolves the installation per file (mirrors the
|
|
810
|
+
// GitHub-issues task source).
|
|
811
|
+
if (config.documents.sources.includes('github') && config.github.enabled) {
|
|
812
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
813
|
+
providers.push(new GitHubDocsProvider({
|
|
814
|
+
githubClient: new FetchGitHubClient({
|
|
815
|
+
registry,
|
|
816
|
+
rateLimitRepository: new D1RateLimitRepository({ db, idGenerator }),
|
|
817
|
+
idGenerator,
|
|
818
|
+
clock,
|
|
819
|
+
apiBase: config.github.apiBase,
|
|
820
|
+
}),
|
|
821
|
+
installations: new D1GitHubInstallationRepository({ db }),
|
|
822
|
+
}));
|
|
823
|
+
}
|
|
824
|
+
if (providers.length === 0)
|
|
825
|
+
return {};
|
|
826
|
+
return {
|
|
827
|
+
documentSourceProviders: providers,
|
|
828
|
+
documentConnectionRepository: new D1DocumentConnectionRepository({
|
|
829
|
+
db,
|
|
830
|
+
// The config gate guarantees the key is present when enabled; source
|
|
831
|
+
// credentials are encrypted at rest under a documents-scoped HKDF info.
|
|
832
|
+
cipher: new WebCryptoSecretCipher({
|
|
833
|
+
masterKeyBase64: config.documents.encryptionKey,
|
|
834
|
+
info: 'cat-factory:documents',
|
|
835
|
+
}),
|
|
836
|
+
}),
|
|
837
|
+
documentRepository: new D1DocumentRepository({ db }),
|
|
838
|
+
...(config.documents.planner === 'llm'
|
|
839
|
+
? {
|
|
840
|
+
modelProviderResolver: buildModelProviderResolver(env, db),
|
|
841
|
+
documentPlannerModel: config.agents.routing.default.ref,
|
|
842
|
+
}
|
|
843
|
+
: {}),
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Build the task-source integration's concrete ports. Mirrors `selectDocumentsDeps`
|
|
848
|
+
* but with no planner — issues are linked for context, not expanded into board
|
|
849
|
+
* structure. Always on (config load fails loudly without the encryption key), so this
|
|
850
|
+
* is wired on every deployment.
|
|
851
|
+
*/
|
|
852
|
+
function selectTasksDeps(env, config, db, clock, idGenerator) {
|
|
853
|
+
const providers = [];
|
|
854
|
+
if (config.tasks.sources.includes('jira'))
|
|
855
|
+
providers.push(new JiraProvider());
|
|
856
|
+
// GitHub issues reuse the workspace's installed GitHub App, so this provider
|
|
857
|
+
// is wired only when the GitHub integration is also configured — it has no
|
|
858
|
+
// credentials of its own and resolves the installation per issue.
|
|
859
|
+
if (config.tasks.sources.includes('github') && config.github.enabled) {
|
|
860
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
861
|
+
providers.push(new GitHubIssuesProvider({
|
|
862
|
+
githubClient: new FetchGitHubClient({
|
|
863
|
+
registry,
|
|
864
|
+
rateLimitRepository: new D1RateLimitRepository({ db, idGenerator }),
|
|
865
|
+
idGenerator,
|
|
866
|
+
clock,
|
|
867
|
+
apiBase: config.github.apiBase,
|
|
868
|
+
}),
|
|
869
|
+
installations: new D1GitHubInstallationRepository({ db }),
|
|
870
|
+
}));
|
|
871
|
+
}
|
|
872
|
+
if (providers.length === 0)
|
|
873
|
+
return {};
|
|
874
|
+
return {
|
|
875
|
+
taskSourceProviders: providers,
|
|
876
|
+
taskConnectionRepository: new D1TaskConnectionRepository({
|
|
877
|
+
db,
|
|
878
|
+
// The config gate guarantees the key is present when enabled; source
|
|
879
|
+
// credentials are encrypted at rest under a tasks-scoped HKDF info.
|
|
880
|
+
cipher: new WebCryptoSecretCipher({
|
|
881
|
+
masterKeyBase64: config.tasks.encryptionKey,
|
|
882
|
+
info: 'cat-factory:tasks',
|
|
883
|
+
}),
|
|
884
|
+
}),
|
|
885
|
+
taskRepository: new D1TaskRepository({ db }),
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Wire the requirements-review feature. The repository is always available, and a
|
|
890
|
+
* model provider + the agents' default ref are supplied so the stateless reviewer
|
|
891
|
+
* works whenever an LLM is configured — independent of the documents integration.
|
|
892
|
+
* (Supplying the provider here is harmless when documents are off or set to the
|
|
893
|
+
* heading-based planner: that planner only engages when `documentPlannerModel` is
|
|
894
|
+
* also set, which this does not touch.)
|
|
895
|
+
*/
|
|
896
|
+
function selectRequirementsDeps(env, config, db) {
|
|
897
|
+
return {
|
|
898
|
+
requirementReviewRepository: new D1RequirementReviewRepository({ db }),
|
|
899
|
+
clarityReviewRepository: new D1ClarityReviewRepository({ db }),
|
|
900
|
+
modelProviderResolver: buildModelProviderResolver(env, db),
|
|
901
|
+
// The routing default already resolves to Cloudflare Workers AI unless a
|
|
902
|
+
// direct provider key is set, so the reviewer runs on Cloudflare by default.
|
|
903
|
+
requirementReviewModel: config.agents.routing.default.ref,
|
|
904
|
+
// Honour a block's pinned model with the same direct/Cloudflare fallback the
|
|
905
|
+
// agent executor (and the Pi container path) use.
|
|
906
|
+
requirementReviewResolveModel: config.agents.resolveBlockModel,
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Build the ephemeral environment integration's concrete ports when opted in.
|
|
911
|
+
* Requires the encryption key (the config gate already enforces this), so the
|
|
912
|
+
* generic HTTP provider, the D1 repositories and the Web Crypto cipher are wired
|
|
913
|
+
* together. Returns `{}` when disabled, so `createCore` leaves the `environments`
|
|
914
|
+
* module unassembled and the deterministic deployer / env discovery stay off.
|
|
915
|
+
*/
|
|
916
|
+
function selectEnvironmentsDeps(env, config, db) {
|
|
917
|
+
if (!config.environments.enabled)
|
|
918
|
+
return {};
|
|
919
|
+
// The default manifest-driven provider; a trusted in-house adapter (implementing the
|
|
920
|
+
// EnvironmentProvider port) is injected by replacing `environmentProvider` via the
|
|
921
|
+
// `overrides` argument to `buildContainer` (spread last), the same seam tests use.
|
|
922
|
+
const urlPolicy = resolveUrlSafetyPolicy(config.environments);
|
|
923
|
+
return {
|
|
924
|
+
environmentProvider: new HttpEnvironmentProvider(urlPolicy ? { urlPolicy } : {}),
|
|
925
|
+
environmentConnectionRepository: new D1EnvironmentConnectionRepository({ db }),
|
|
926
|
+
environmentRegistryRepository: new D1EnvironmentRegistryRepository({ db }),
|
|
927
|
+
secretCipher: new WebCryptoSecretCipher({
|
|
928
|
+
masterKeyBase64: config.environments.encryptionKey,
|
|
929
|
+
}),
|
|
930
|
+
...(urlPolicy ? { environmentUrlSafetyPolicy: urlPolicy } : {}),
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Build the self-hosted runner-pool integration's concrete ports when opted in:
|
|
935
|
+
* the D1 connection repository and a dedicated Web Crypto cipher (its own master
|
|
936
|
+
* key + HKDF domain, separate from the environment module's). This assembles
|
|
937
|
+
* `Core.runners` (the connection-management API); the per-job transport selection
|
|
938
|
+
* lives in `buildResolveTransport` above. Returns `{}` when disabled.
|
|
939
|
+
*/
|
|
940
|
+
function selectRunnersDeps(env, config, db) {
|
|
941
|
+
if (!config.runners.enabled)
|
|
942
|
+
return {};
|
|
943
|
+
const urlPolicy = resolveUrlSafetyPolicy(config.runners);
|
|
944
|
+
return {
|
|
945
|
+
runnerPoolConnectionRepository: new D1RunnerPoolConnectionRepository({ db }),
|
|
946
|
+
runnerSecretCipher: new WebCryptoSecretCipher({
|
|
947
|
+
masterKeyBase64: config.runners.encryptionKey,
|
|
948
|
+
info: 'cat-factory:runners',
|
|
949
|
+
}),
|
|
950
|
+
...(urlPolicy ? { runnerUrlSafetyPolicy: urlPolicy } : {}),
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Build the container-backed repo bootstrapper for the "bootstrap repo" task,
|
|
955
|
+
* gated on the same prerequisites as the implementation container (the binding, a
|
|
956
|
+
* configured GitHub App, the proxy's public URL and signing secret). Returns
|
|
957
|
+
* undefined otherwise, leaving reference-architecture CRUD available while the run
|
|
958
|
+
* path reports itself unavailable.
|
|
959
|
+
*/
|
|
960
|
+
function selectRepoBootstrapper(env, config, db, clock, idGenerator, resolveTransport) {
|
|
961
|
+
if (!resolveTransport ||
|
|
962
|
+
!config.github.enabled ||
|
|
963
|
+
!env.GITHUB_APP_PRIVATE_KEY ||
|
|
964
|
+
!env.WORKER_PUBLIC_URL ||
|
|
965
|
+
!env.AUTH_SESSION_SECRET) {
|
|
966
|
+
return undefined;
|
|
967
|
+
}
|
|
968
|
+
const installationRepository = new D1GitHubInstallationRepository({ db });
|
|
969
|
+
const registry = buildAppRegistry(env, config, db, clock);
|
|
970
|
+
const githubClient = new FetchGitHubClient({
|
|
971
|
+
registry,
|
|
972
|
+
rateLimitRepository: new D1RateLimitRepository({ db, idGenerator }),
|
|
973
|
+
idGenerator,
|
|
974
|
+
clock,
|
|
975
|
+
apiBase: config.github.apiBase,
|
|
976
|
+
});
|
|
977
|
+
return new ContainerRepoBootstrapper({
|
|
978
|
+
resolveTransport,
|
|
979
|
+
installationRepository,
|
|
980
|
+
bootstrapJobRepository: new D1BootstrapJobRepository({ db }),
|
|
981
|
+
repoRepository: new D1RepoProjectionRepository({ db }),
|
|
982
|
+
githubClient,
|
|
983
|
+
mintInstallationToken: (id) => registry.installationToken(id),
|
|
984
|
+
sessionService: new ContainerSessionService({ secret: env.AUTH_SESSION_SECRET }),
|
|
985
|
+
// Bootstrap is an `architect`-kind run, so it follows that kind's routing
|
|
986
|
+
// (GLM-5.2 by default) rather than the global default.
|
|
987
|
+
model: resolveAgentConfig(config.agents.routing, 'architect').ref,
|
|
988
|
+
proxyBaseUrl: `${env.WORKER_PUBLIC_URL.replace(/\/+$/, '')}/v1`,
|
|
989
|
+
githubApiBase: config.github.apiBase,
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Build the prompt-fragment library's concrete ports when opted in (ADR 0006):
|
|
994
|
+
* the two D1 repositories, the relevance selector (LLM when configured, else the
|
|
995
|
+
* core deterministic matcher via `fragmentSelector: undefined`), and the
|
|
996
|
+
* installation resolver repo-source sync uses to read guideline repos through the
|
|
997
|
+
* tier's GitHub installation. Returns `{}` when disabled, so `createCore` leaves
|
|
998
|
+
* the `fragmentLibrary` module unassembled and the engine uses manual fragmentIds.
|
|
999
|
+
*/
|
|
1000
|
+
function selectFragmentLibraryDeps(env, config, db) {
|
|
1001
|
+
if (!config.fragmentLibrary.enabled)
|
|
1002
|
+
return {};
|
|
1003
|
+
const installationRepository = new D1GitHubInstallationRepository({ db });
|
|
1004
|
+
const resolveFragmentInstallationId = async (ownerKind, ownerId) => {
|
|
1005
|
+
if (ownerKind === 'workspace') {
|
|
1006
|
+
return (await installationRepository.getByWorkspace(ownerId))?.installationId ?? null;
|
|
1007
|
+
}
|
|
1008
|
+
// Account scope: the installation bound to this account (migration 0017).
|
|
1009
|
+
const active = await installationRepository.listActive();
|
|
1010
|
+
return active.find((i) => i.accountId === ownerId)?.installationId ?? null;
|
|
1011
|
+
};
|
|
1012
|
+
return {
|
|
1013
|
+
promptFragmentRepository: new D1PromptFragmentRepository({ db }),
|
|
1014
|
+
fragmentSourceRepository: new D1FragmentSourceRepository({ db }),
|
|
1015
|
+
resolveFragmentInstallationId,
|
|
1016
|
+
...(config.fragmentLibrary.selector === 'llm'
|
|
1017
|
+
? {
|
|
1018
|
+
fragmentSelector: new LlmFragmentSelector({
|
|
1019
|
+
modelProviderResolver: buildModelProviderResolver(env, db),
|
|
1020
|
+
modelRef: config.agents.routing.default.ref,
|
|
1021
|
+
}),
|
|
1022
|
+
}
|
|
1023
|
+
: {}),
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
export function buildContainer(env, overrides = {}, opts = {}) {
|
|
1027
|
+
const config = loadConfig(env);
|
|
1028
|
+
const db = env.DB;
|
|
1029
|
+
const clock = new SystemClock();
|
|
1030
|
+
const idGenerator = new CryptoIdGenerator();
|
|
1031
|
+
// The runner-backend factory is shared by every container-backed flow (the
|
|
1032
|
+
// implementation executor and the repo bootstrapper), so both dispatch through the
|
|
1033
|
+
// same Cloudflare/self-hosted seam — and the bootstrapper rides the reaping-aware
|
|
1034
|
+
// Cloudflare transport for free. Null when no backend is configured.
|
|
1035
|
+
const resolveTransport = buildResolveTransport(env, config, db, clock);
|
|
1036
|
+
// The subscription-token pool (Claude Code / Codex credentials) — built once and
|
|
1037
|
+
// shared by the container executor (lease + usage feedback) and the
|
|
1038
|
+
// vendor-credential controller, so both read the same pool.
|
|
1039
|
+
const subscriptions = buildSubscriptionService(env, db, clock);
|
|
1040
|
+
// The per-user individual-usage subscription store (Claude) — shared by the
|
|
1041
|
+
// personal-subscription controller and the container executor's personal lease.
|
|
1042
|
+
const personalSubscriptions = buildPersonalSubscriptionService(env, db, clock);
|
|
1043
|
+
// The direct-provider API-key pool (account/workspace/user) — shared by the
|
|
1044
|
+
// API-key controller, the model-provider resolver, and the LLM proxy key lease.
|
|
1045
|
+
const apiKeys = buildApiKeyService(env, db, clock);
|
|
1046
|
+
// The per-user locally-run model endpoints store (Ollama / LM Studio / …) — shared by
|
|
1047
|
+
// the local-runner controller, the per-user model catalog, and the LLM proxy.
|
|
1048
|
+
const localModelEndpoints = buildLocalModelEndpointService(env, db, clock);
|
|
1049
|
+
// Cloudflare Workers AI is opt-in: enabled when the `AI` binding is present. A caller
|
|
1050
|
+
// (the cross-runtime conformance suite) may force it off to assert key-driven
|
|
1051
|
+
// selectability + the provider guard uniformly across runtimes.
|
|
1052
|
+
const cloudflareModelsEnabled = opts.cloudflareModelsEnabled ?? !!env.AI;
|
|
1053
|
+
// Built once so the consensus executor and the engine share the same publisher (live
|
|
1054
|
+
// consensus transcript pushes ride the same hub as run/board events).
|
|
1055
|
+
const eventPublisher = selectEventPublisher(env, db);
|
|
1056
|
+
const dependencies = {
|
|
1057
|
+
workspaceRepository: new D1WorkspaceRepository({ db }),
|
|
1058
|
+
accountRepository: new D1AccountRepository({ db }),
|
|
1059
|
+
membershipRepository: new D1MembershipRepository({ db }),
|
|
1060
|
+
userRepository: new D1UserRepository({ db }),
|
|
1061
|
+
passwordHasher: new WebCryptoPasswordHasher(),
|
|
1062
|
+
blockRepository: new D1BlockRepository({ db }),
|
|
1063
|
+
pipelineRepository: new D1PipelineRepository({ db }),
|
|
1064
|
+
executionRepository: new D1ExecutionRepository({ db, clock }),
|
|
1065
|
+
// Clear a finished run's personal-credential activation promptly (TTL sweep is the backstop).
|
|
1066
|
+
subscriptionActivationRepository: new D1SubscriptionActivationRepository({ db }),
|
|
1067
|
+
serviceRepository: new D1ServiceRepository({ db }),
|
|
1068
|
+
workspaceMountRepository: new D1WorkspaceMountRepository({ db }),
|
|
1069
|
+
tokenUsageRepository: new D1TokenUsageRepository({ db }),
|
|
1070
|
+
llmCallMetricRepository: new D1LlmCallMetricRepository({ db }),
|
|
1071
|
+
recordLlmPrompts: config.observability.recordPrompts,
|
|
1072
|
+
idGenerator,
|
|
1073
|
+
clock,
|
|
1074
|
+
// When a caller injects its own agentExecutor (tests pass a FakeAgentExecutor)
|
|
1075
|
+
// skip selection entirely — selectAgentExecutor throws when a sandbox is opted
|
|
1076
|
+
// in but its prerequisites are missing, which is the desired loud failure in
|
|
1077
|
+
// production but must not fire for tests that never reach the real executor.
|
|
1078
|
+
agentExecutor: overrides.agentExecutor ??
|
|
1079
|
+
maybeWrapConsensus(selectAgentExecutor(env, config, db, clock, resolveTransport, subscriptions, personalSubscriptions), env, config, db, eventPublisher),
|
|
1080
|
+
workRunner: selectWorkRunner(env),
|
|
1081
|
+
executionEventPublisher: eventPublisher,
|
|
1082
|
+
spendPricing: config.spend,
|
|
1083
|
+
// Repo-bootstrap repositories are wired unconditionally (reference-architecture
|
|
1084
|
+
// CRUD is always available); the run path additionally needs the bootstrapper.
|
|
1085
|
+
referenceArchitectureRepository: new D1ReferenceArchitectureRepository({ db }),
|
|
1086
|
+
bootstrapJobRepository: new D1BootstrapJobRepository({ db }),
|
|
1087
|
+
repoBootstrapper: selectRepoBootstrapper(env, config, db, clock, idGenerator, resolveTransport),
|
|
1088
|
+
// Durably drive each bootstrap run's poll loop when the Workflows binding is
|
|
1089
|
+
// present (mirrors the execution driver); without it a run still dispatches.
|
|
1090
|
+
bootstrapRunner: env.BOOTSTRAP_WORKFLOW
|
|
1091
|
+
? new WorkflowsBootstrapRunner(env.BOOTSTRAP_WORKFLOW)
|
|
1092
|
+
: undefined,
|
|
1093
|
+
...selectGitHubDeps(env, config, db, clock, idGenerator),
|
|
1094
|
+
...selectMergeLifecycleDeps(env, config, db, clock, idGenerator),
|
|
1095
|
+
...selectReleaseHealthDeps(env, config, db),
|
|
1096
|
+
...selectSlackDeps(config, db),
|
|
1097
|
+
...selectEmailInvitationDeps(config, db),
|
|
1098
|
+
...selectLangfuseSink(config),
|
|
1099
|
+
...selectRecurringDeps(env, config, db, clock, idGenerator),
|
|
1100
|
+
...selectDocumentsDeps(env, config, db, clock, idGenerator),
|
|
1101
|
+
...selectTasksDeps(env, config, db, clock, idGenerator),
|
|
1102
|
+
...selectRequirementsDeps(env, config, db),
|
|
1103
|
+
...selectEnvironmentsDeps(env, config, db),
|
|
1104
|
+
...selectRunnersDeps(env, config, db),
|
|
1105
|
+
...selectFragmentLibraryDeps(env, config, db),
|
|
1106
|
+
// The pipeline-start guard resolves what's configured for a workspace + initiator.
|
|
1107
|
+
resolveProviderCapabilities: (workspaceId, initiatedBy) => resolveWorkspaceCapabilities({
|
|
1108
|
+
apiKeys,
|
|
1109
|
+
subscriptions,
|
|
1110
|
+
personalSubscriptions,
|
|
1111
|
+
cloudflareModelsEnabled,
|
|
1112
|
+
baseUrlFor: (provider) => baseUrlFor(provider, env),
|
|
1113
|
+
localModelEndpoints,
|
|
1114
|
+
}, workspaceId, initiatedBy),
|
|
1115
|
+
...overrides,
|
|
1116
|
+
};
|
|
1117
|
+
return {
|
|
1118
|
+
...createCore(dependencies),
|
|
1119
|
+
config,
|
|
1120
|
+
agentRunRepository: new D1AgentRunRepository({ db }),
|
|
1121
|
+
// The consensus transcript store, for the read endpoint (the SPA window's initial
|
|
1122
|
+
// load / reload). Always wired; live updates ride the `consensus` workspace event.
|
|
1123
|
+
consensusSessionRepository: new D1ConsensusSessionRepository({ db }),
|
|
1124
|
+
// The vendor-credential (subscription token pool) service the shared controller
|
|
1125
|
+
// reads; present when the shared ENCRYPTION_KEY is configured.
|
|
1126
|
+
subscriptions,
|
|
1127
|
+
// The per-user individual-usage subscription store (Claude); present when the
|
|
1128
|
+
// shared ENCRYPTION_KEY is configured.
|
|
1129
|
+
personalSubscriptions,
|
|
1130
|
+
// The direct-provider API-key pool (account/workspace/user); present when the
|
|
1131
|
+
// shared ENCRYPTION_KEY is configured.
|
|
1132
|
+
apiKeys,
|
|
1133
|
+
// Whether the opt-in Cloudflare Workers AI lib is enabled (the `AI` binding).
|
|
1134
|
+
cloudflareModelsEnabled,
|
|
1135
|
+
// The direct-provider base-URL resolver the catalog uses to gate selectability on a
|
|
1136
|
+
// resolvable endpoint (e.g. LiteLLM stays unselectable until LITELLM_BASE_URL is set).
|
|
1137
|
+
baseUrlFor: (provider) => baseUrlFor(provider, env),
|
|
1138
|
+
// The per-user locally-run model endpoints store; present when ENCRYPTION_KEY is set.
|
|
1139
|
+
localModelEndpoints,
|
|
1140
|
+
gateways: {
|
|
1141
|
+
// Real-time event delivery via the per-workspace WorkspaceEventsHub DO (when
|
|
1142
|
+
// the WORKSPACE_EVENTS namespace is bound; absent → the events route 501s).
|
|
1143
|
+
realtime: new DoRealtimeGateway(env.WORKSPACE_EVENTS),
|
|
1144
|
+
// GitHub backfill via Workflows; webhook/resync ingest via the sync Queue. Both
|
|
1145
|
+
// fall back to inline handling when their binding is absent (local/dev/tests).
|
|
1146
|
+
githubBackfill: new WorkflowsBackfillScheduler(env.GITHUB_BACKFILL_WORKFLOW),
|
|
1147
|
+
githubWebhook: new CfGitHubWebhookIngest(env.GITHUB_SYNC_QUEUE),
|
|
1148
|
+
// LLM proxy upstream: OpenAI-compatible providers from env keys + the in-process
|
|
1149
|
+
// Workers AI binding path (the `workers-ai` provider).
|
|
1150
|
+
llmUpstream: new WorkersAiLlmUpstream(env),
|
|
1151
|
+
// Container web-search proxy upstream (Brave, or a self-hosted SearXNG). Absent
|
|
1152
|
+
// ⇒ the `/v1/web-search` route 503s and container web search stays off.
|
|
1153
|
+
webSearch: createWebSearchUpstreamFromEnv(env),
|
|
1154
|
+
},
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
//# sourceMappingURL=container.js.map
|