@cat-factory/server 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/agents/CompositeAgentExecutor.d.ts +39 -0
- package/dist/agents/CompositeAgentExecutor.d.ts.map +1 -0
- package/dist/agents/CompositeAgentExecutor.js +169 -0
- package/dist/agents/CompositeAgentExecutor.js.map +1 -0
- package/dist/agents/ContainerAgentExecutor.d.ts +235 -0
- package/dist/agents/ContainerAgentExecutor.d.ts.map +1 -0
- package/dist/agents/ContainerAgentExecutor.js +825 -0
- package/dist/agents/ContainerAgentExecutor.js.map +1 -0
- package/dist/agents/ContainerRepoBootstrapper.d.ts +78 -0
- package/dist/agents/ContainerRepoBootstrapper.d.ts.map +1 -0
- package/dist/agents/ContainerRepoBootstrapper.js +279 -0
- package/dist/agents/ContainerRepoBootstrapper.js.map +1 -0
- package/dist/agents/ModelRouter.d.ts +69 -0
- package/dist/agents/ModelRouter.d.ts.map +1 -0
- package/dist/agents/ModelRouter.js +84 -0
- package/dist/agents/ModelRouter.js.map +1 -0
- package/dist/agents/RunnerJobClient.d.ts +41 -0
- package/dist/agents/RunnerJobClient.d.ts.map +1 -0
- package/dist/agents/RunnerJobClient.js +43 -0
- package/dist/agents/RunnerJobClient.js.map +1 -0
- package/dist/agents/modelProviderResolver.d.ts +33 -0
- package/dist/agents/modelProviderResolver.d.ts.map +1 -0
- package/dist/agents/modelProviderResolver.js +48 -0
- package/dist/agents/modelProviderResolver.js.map +1 -0
- package/dist/agents/providerCapabilities.d.ts +22 -0
- package/dist/agents/providerCapabilities.d.ts.map +1 -0
- package/dist/agents/providerCapabilities.js +43 -0
- package/dist/agents/providerCapabilities.js.map +1 -0
- package/dist/agents/resolveRepoTarget.d.ts +33 -0
- package/dist/agents/resolveRepoTarget.d.ts.map +1 -0
- package/dist/agents/resolveRepoTarget.js +81 -0
- package/dist/agents/resolveRepoTarget.js.map +1 -0
- package/dist/app.d.ts +12 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +102 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/GitHubOAuth.d.ts +39 -0
- package/dist/auth/GitHubOAuth.d.ts.map +1 -0
- package/dist/auth/GitHubOAuth.js +90 -0
- package/dist/auth/GitHubOAuth.js.map +1 -0
- package/dist/auth/GoogleOAuth.d.ts +35 -0
- package/dist/auth/GoogleOAuth.d.ts.map +1 -0
- package/dist/auth/GoogleOAuth.js +66 -0
- package/dist/auth/GoogleOAuth.js.map +1 -0
- package/dist/auth/middleware.d.ts +15 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +63 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/signing.d.ts +50 -0
- package/dist/auth/signing.d.ts.map +1 -0
- package/dist/auth/signing.js +96 -0
- package/dist/auth/signing.js.map +1 -0
- package/dist/auth/wsTicket.d.ts +34 -0
- package/dist/auth/wsTicket.d.ts.map +1 -0
- package/dist/auth/wsTicket.js +50 -0
- package/dist/auth/wsTicket.js.map +1 -0
- package/dist/config/types.d.ts +294 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/url-safety.d.ts +8 -0
- package/dist/config/url-safety.d.ts.map +1 -0
- package/dist/config/url-safety.js +11 -0
- package/dist/config/url-safety.js.map +1 -0
- package/dist/containers/ContainerSessionService.d.ts +67 -0
- package/dist/containers/ContainerSessionService.d.ts.map +1 -0
- package/dist/containers/ContainerSessionService.js +44 -0
- package/dist/containers/ContainerSessionService.js.map +1 -0
- package/dist/crypto/WebCryptoPasswordHasher.d.ts +9 -0
- package/dist/crypto/WebCryptoPasswordHasher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoPasswordHasher.js +67 -0
- package/dist/crypto/WebCryptoPasswordHasher.js.map +1 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts +6 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.js +57 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.js.map +1 -0
- package/dist/crypto/WebCryptoSecretCipher.d.ts +23 -0
- package/dist/crypto/WebCryptoSecretCipher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoSecretCipher.js +60 -0
- package/dist/crypto/WebCryptoSecretCipher.js.map +1 -0
- package/dist/crypto/encoding.d.ts +14 -0
- package/dist/crypto/encoding.d.ts.map +1 -0
- package/dist/crypto/encoding.js +58 -0
- package/dist/crypto/encoding.js.map +1 -0
- package/dist/events/FanOutEventPublisher.d.ts +32 -0
- package/dist/events/FanOutEventPublisher.d.ts.map +1 -0
- package/dist/events/FanOutEventPublisher.js +76 -0
- package/dist/events/FanOutEventPublisher.js.map +1 -0
- package/dist/events/InAppNotificationChannel.d.ts +20 -0
- package/dist/events/InAppNotificationChannel.d.ts.map +1 -0
- package/dist/events/InAppNotificationChannel.js +23 -0
- package/dist/events/InAppNotificationChannel.js.map +1 -0
- package/dist/github/FetchGitHubClient.d.ts +72 -0
- package/dist/github/FetchGitHubClient.d.ts.map +1 -0
- package/dist/github/FetchGitHubClient.js +485 -0
- package/dist/github/FetchGitHubClient.js.map +1 -0
- package/dist/github/FetchGitHubProvisioningClient.d.ts +13 -0
- package/dist/github/FetchGitHubProvisioningClient.d.ts.map +1 -0
- package/dist/github/FetchGitHubProvisioningClient.js +59 -0
- package/dist/github/FetchGitHubProvisioningClient.js.map +1 -0
- package/dist/github/GitHubAppAuth.d.ts +30 -0
- package/dist/github/GitHubAppAuth.d.ts.map +1 -0
- package/dist/github/GitHubAppAuth.js +95 -0
- package/dist/github/GitHubAppAuth.js.map +1 -0
- package/dist/github/GitHubAppRegistry.d.ts +57 -0
- package/dist/github/GitHubAppRegistry.d.ts.map +1 -0
- package/dist/github/GitHubAppRegistry.js +51 -0
- package/dist/github/GitHubAppRegistry.js.map +1 -0
- package/dist/github/GitHubCiStatusProvider.d.ts +21 -0
- package/dist/github/GitHubCiStatusProvider.d.ts.map +1 -0
- package/dist/github/GitHubCiStatusProvider.js +39 -0
- package/dist/github/GitHubCiStatusProvider.js.map +1 -0
- package/dist/github/GitHubMergeabilityProvider.d.ts +26 -0
- package/dist/github/GitHubMergeabilityProvider.d.ts.map +1 -0
- package/dist/github/GitHubMergeabilityProvider.js +38 -0
- package/dist/github/GitHubMergeabilityProvider.js.map +1 -0
- package/dist/github/GitHubPullRequestMerger.d.ts +23 -0
- package/dist/github/GitHubPullRequestMerger.d.ts.map +1 -0
- package/dist/github/GitHubPullRequestMerger.js +38 -0
- package/dist/github/GitHubPullRequestMerger.js.map +1 -0
- package/dist/github/WebCryptoWebhookVerifier.d.ts +9 -0
- package/dist/github/WebCryptoWebhookVerifier.d.ts.map +1 -0
- package/dist/github/WebCryptoWebhookVerifier.js +40 -0
- package/dist/github/WebCryptoWebhookVerifier.js.map +1 -0
- package/dist/github/ensureWorkBranch.d.ts +26 -0
- package/dist/github/ensureWorkBranch.d.ts.map +1 -0
- package/dist/github/ensureWorkBranch.js +97 -0
- package/dist/github/ensureWorkBranch.js.map +1 -0
- package/dist/github/state.d.ts +19 -0
- package/dist/github/state.d.ts.map +1 -0
- package/dist/github/state.js +55 -0
- package/dist/github/state.js.map +1 -0
- package/dist/http/authGate.d.ts +21 -0
- package/dist/http/authGate.d.ts.map +1 -0
- package/dist/http/authGate.js +77 -0
- package/dist/http/authGate.js.map +1 -0
- package/dist/http/cors.d.ts +13 -0
- package/dist/http/cors.d.ts.map +1 -0
- package/dist/http/cors.js +30 -0
- package/dist/http/cors.js.map +1 -0
- package/dist/http/env.d.ts +68 -0
- package/dist/http/env.d.ts.map +1 -0
- package/dist/http/env.js +2 -0
- package/dist/http/env.js.map +1 -0
- package/dist/http/errorHandler.d.ts +4 -0
- package/dist/http/errorHandler.d.ts.map +1 -0
- package/dist/http/errorHandler.js +33 -0
- package/dist/http/errorHandler.js.map +1 -0
- package/dist/http/params.d.ts +8 -0
- package/dist/http/params.d.ts.map +1 -0
- package/dist/http/params.js +13 -0
- package/dist/http/params.js.map +1 -0
- package/dist/http/validation.d.ts +12 -0
- package/dist/http/validation.d.ts.map +1 -0
- package/dist/http/validation.js +21 -0
- package/dist/http/validation.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/accounts/AccountController.d.ts +10 -0
- package/dist/modules/accounts/AccountController.d.ts.map +1 -0
- package/dist/modules/accounts/AccountController.js +197 -0
- package/dist/modules/accounts/AccountController.js.map +1 -0
- package/dist/modules/agentRuns/AgentRunController.d.ts +10 -0
- package/dist/modules/agentRuns/AgentRunController.d.ts.map +1 -0
- package/dist/modules/agentRuns/AgentRunController.js +65 -0
- package/dist/modules/agentRuns/AgentRunController.js.map +1 -0
- package/dist/modules/auth/AuthController.d.ts +12 -0
- package/dist/modules/auth/AuthController.d.ts.map +1 -0
- package/dist/modules/auth/AuthController.js +457 -0
- package/dist/modules/auth/AuthController.js.map +1 -0
- package/dist/modules/board/BoardController.d.ts +8 -0
- package/dist/modules/board/BoardController.d.ts.map +1 -0
- package/dist/modules/board/BoardController.js +89 -0
- package/dist/modules/board/BoardController.js.map +1 -0
- package/dist/modules/boardScan/BoardScanController.d.ts +10 -0
- package/dist/modules/boardScan/BoardScanController.d.ts.map +1 -0
- package/dist/modules/boardScan/BoardScanController.js +53 -0
- package/dist/modules/boardScan/BoardScanController.js.map +1 -0
- package/dist/modules/bootstrap/BootstrapController.d.ts +10 -0
- package/dist/modules/bootstrap/BootstrapController.d.ts.map +1 -0
- package/dist/modules/bootstrap/BootstrapController.js +75 -0
- package/dist/modules/bootstrap/BootstrapController.js.map +1 -0
- package/dist/modules/clarity/ClarityReviewController.d.ts +11 -0
- package/dist/modules/clarity/ClarityReviewController.d.ts.map +1 -0
- package/dist/modules/clarity/ClarityReviewController.js +97 -0
- package/dist/modules/clarity/ClarityReviewController.js.map +1 -0
- package/dist/modules/consensus/ConsensusController.d.ts +12 -0
- package/dist/modules/consensus/ConsensusController.d.ts.map +1 -0
- package/dist/modules/consensus/ConsensusController.js +23 -0
- package/dist/modules/consensus/ConsensusController.js.map +1 -0
- package/dist/modules/documents/DocumentSourceController.d.ts +10 -0
- package/dist/modules/documents/DocumentSourceController.d.ts.map +1 -0
- package/dist/modules/documents/DocumentSourceController.js +116 -0
- package/dist/modules/documents/DocumentSourceController.js.map +1 -0
- package/dist/modules/environments/EnvironmentController.d.ts +10 -0
- package/dist/modules/environments/EnvironmentController.d.ts.map +1 -0
- package/dist/modules/environments/EnvironmentController.js +95 -0
- package/dist/modules/environments/EnvironmentController.js.map +1 -0
- package/dist/modules/events/EventsController.d.ts +26 -0
- package/dist/modules/events/EventsController.d.ts.map +1 -0
- package/dist/modules/events/EventsController.js +56 -0
- package/dist/modules/events/EventsController.js.map +1 -0
- package/dist/modules/execution/ExecutionController.d.ts +10 -0
- package/dist/modules/execution/ExecutionController.d.ts.map +1 -0
- package/dist/modules/execution/ExecutionController.js +156 -0
- package/dist/modules/execution/ExecutionController.js.map +1 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts +14 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts.map +1 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js +128 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js.map +1 -0
- package/dist/modules/github/GitHubController.d.ts +12 -0
- package/dist/modules/github/GitHubController.d.ts.map +1 -0
- package/dist/modules/github/GitHubController.js +234 -0
- package/dist/modules/github/GitHubController.js.map +1 -0
- package/dist/modules/github/GitHubWebhookController.d.ts +13 -0
- package/dist/modules/github/GitHubWebhookController.d.ts.map +1 -0
- package/dist/modules/github/GitHubWebhookController.js +74 -0
- package/dist/modules/github/GitHubWebhookController.js.map +1 -0
- package/dist/modules/llmProxy/LlmProxyController.d.ts +18 -0
- package/dist/modules/llmProxy/LlmProxyController.d.ts.map +1 -0
- package/dist/modules/llmProxy/LlmProxyController.js +567 -0
- package/dist/modules/llmProxy/LlmProxyController.js.map +1 -0
- package/dist/modules/localModels/LocalModelEndpointController.d.ts +4 -0
- package/dist/modules/localModels/LocalModelEndpointController.d.ts.map +1 -0
- package/dist/modules/localModels/LocalModelEndpointController.js +58 -0
- package/dist/modules/localModels/LocalModelEndpointController.js.map +1 -0
- package/dist/modules/merge/MergePresetController.d.ts +9 -0
- package/dist/modules/merge/MergePresetController.d.ts.map +1 -0
- package/dist/modules/merge/MergePresetController.js +46 -0
- package/dist/modules/merge/MergePresetController.js.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.d.ts +9 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.d.ts.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.js +32 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.js.map +1 -0
- package/dist/modules/models/ModelController.d.ts +11 -0
- package/dist/modules/models/ModelController.d.ts.map +1 -0
- package/dist/modules/models/ModelController.js +38 -0
- package/dist/modules/models/ModelController.js.map +1 -0
- package/dist/modules/notifications/NotificationController.d.ts +13 -0
- package/dist/modules/notifications/NotificationController.d.ts.map +1 -0
- package/dist/modules/notifications/NotificationController.js +67 -0
- package/dist/modules/notifications/NotificationController.js.map +1 -0
- package/dist/modules/pipelines/PipelineController.d.ts +5 -0
- package/dist/modules/pipelines/PipelineController.d.ts.map +1 -0
- package/dist/modules/pipelines/PipelineController.js +46 -0
- package/dist/modules/pipelines/PipelineController.js.map +1 -0
- package/dist/modules/promptFragments/PromptFragmentController.d.ts +11 -0
- package/dist/modules/promptFragments/PromptFragmentController.d.ts.map +1 -0
- package/dist/modules/promptFragments/PromptFragmentController.js +18 -0
- package/dist/modules/promptFragments/PromptFragmentController.js.map +1 -0
- package/dist/modules/providers/ApiKeyController.d.ts +13 -0
- package/dist/modules/providers/ApiKeyController.d.ts.map +1 -0
- package/dist/modules/providers/ApiKeyController.js +98 -0
- package/dist/modules/providers/ApiKeyController.js.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionController.d.ts +4 -0
- package/dist/modules/providers/PersonalSubscriptionController.d.ts.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionController.js +48 -0
- package/dist/modules/providers/PersonalSubscriptionController.js.map +1 -0
- package/dist/modules/providers/VendorCredentialController.d.ts +4 -0
- package/dist/modules/providers/VendorCredentialController.d.ts.map +1 -0
- package/dist/modules/providers/VendorCredentialController.js +55 -0
- package/dist/modules/providers/VendorCredentialController.js.map +1 -0
- package/dist/modules/providers/personalCredentialGate.d.ts +34 -0
- package/dist/modules/providers/personalCredentialGate.d.ts.map +1 -0
- package/dist/modules/providers/personalCredentialGate.js +106 -0
- package/dist/modules/providers/personalCredentialGate.js.map +1 -0
- package/dist/modules/recurring/RecurringPipelineController.d.ts +8 -0
- package/dist/modules/recurring/RecurringPipelineController.d.ts.map +1 -0
- package/dist/modules/recurring/RecurringPipelineController.js +58 -0
- package/dist/modules/recurring/RecurringPipelineController.js.map +1 -0
- package/dist/modules/recurring/TrackerSettingsController.d.ts +8 -0
- package/dist/modules/recurring/TrackerSettingsController.d.ts.map +1 -0
- package/dist/modules/recurring/TrackerSettingsController.js +30 -0
- package/dist/modules/recurring/TrackerSettingsController.js.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts +9 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.js +58 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.js.map +1 -0
- package/dist/modules/requirements/RequirementReviewController.d.ts +12 -0
- package/dist/modules/requirements/RequirementReviewController.d.ts.map +1 -0
- package/dist/modules/requirements/RequirementReviewController.js +107 -0
- package/dist/modules/requirements/RequirementReviewController.js.map +1 -0
- package/dist/modules/runners/RunnerPoolController.d.ts +10 -0
- package/dist/modules/runners/RunnerPoolController.d.ts.map +1 -0
- package/dist/modules/runners/RunnerPoolController.js +52 -0
- package/dist/modules/runners/RunnerPoolController.js.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts +9 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js +32 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js.map +1 -0
- package/dist/modules/services/ServiceMountController.d.ts +11 -0
- package/dist/modules/services/ServiceMountController.d.ts.map +1 -0
- package/dist/modules/services/ServiceMountController.js +64 -0
- package/dist/modules/services/ServiceMountController.js.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsController.d.ts +9 -0
- package/dist/modules/settings/WorkspaceSettingsController.d.ts.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsController.js +32 -0
- package/dist/modules/settings/WorkspaceSettingsController.js.map +1 -0
- package/dist/modules/slack/SlackController.d.ts +17 -0
- package/dist/modules/slack/SlackController.d.ts.map +1 -0
- package/dist/modules/slack/SlackController.js +135 -0
- package/dist/modules/slack/SlackController.js.map +1 -0
- package/dist/modules/tasks/TaskSourceController.d.ts +9 -0
- package/dist/modules/tasks/TaskSourceController.d.ts.map +1 -0
- package/dist/modules/tasks/TaskSourceController.js +103 -0
- package/dist/modules/tasks/TaskSourceController.js.map +1 -0
- package/dist/modules/webSearch/WebSearchProxyController.d.ts +4 -0
- package/dist/modules/webSearch/WebSearchProxyController.d.ts.map +1 -0
- package/dist/modules/webSearch/WebSearchProxyController.js +78 -0
- package/dist/modules/webSearch/WebSearchProxyController.js.map +1 -0
- package/dist/modules/webSearch/upstreams.d.ts +50 -0
- package/dist/modules/webSearch/upstreams.d.ts.map +1 -0
- package/dist/modules/webSearch/upstreams.js +107 -0
- package/dist/modules/webSearch/upstreams.js.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts +5 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.js +167 -0
- package/dist/modules/workspaces/WorkspaceController.js.map +1 -0
- package/dist/observability/logger.d.ts +9 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +39 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/persistence/mappers.d.ts +101 -0
- package/dist/persistence/mappers.d.ts.map +1 -0
- package/dist/persistence/mappers.js +260 -0
- package/dist/persistence/mappers.js.map +1 -0
- package/dist/runtime/escalateNotifications.d.ts +12 -0
- package/dist/runtime/escalateNotifications.d.ts.map +1 -0
- package/dist/runtime/escalateNotifications.js +25 -0
- package/dist/runtime/escalateNotifications.js.map +1 -0
- package/dist/runtime/gateways.d.ts +159 -0
- package/dist/runtime/gateways.d.ts.map +1 -0
- package/dist/runtime/gateways.js +2 -0
- package/dist/runtime/gateways.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { ContainerSessionService } from '../../containers/ContainerSessionService.js';
|
|
3
|
+
import { logger } from '../../observability/logger.js';
|
|
4
|
+
// The SearXNG-compatible web-search proxy that implementation containers point Pi's
|
|
5
|
+
// `web_search` tool at (rpiv-web-tools, SearXNG provider). It is the seam that keeps a
|
|
6
|
+
// search-provider key out of the container — exactly like the LLM proxy keeps model
|
|
7
|
+
// keys out: the container authenticates with its short-lived, model-locked session
|
|
8
|
+
// token (no provider key), and the facade performs the search server-side under its
|
|
9
|
+
// own key via the `webSearch` gateway.
|
|
10
|
+
//
|
|
11
|
+
// The container reaches it at `${proxyBaseUrl}/web-search`, so the SearXNG client
|
|
12
|
+
// issues `GET ${that}/search?q=...&format=json` with `Authorization: Bearer <token>`.
|
|
13
|
+
// Mounted under `/v1`, which the auth gate treats as public (token-authenticated).
|
|
14
|
+
/** Pull the bearer token from the Authorization header (Pi's SearXNG client sends it). */
|
|
15
|
+
function bearer(header) {
|
|
16
|
+
if (!header)
|
|
17
|
+
return null;
|
|
18
|
+
const match = /^Bearer\s+(.+)$/i.exec(header.trim());
|
|
19
|
+
return match ? match[1].trim() : null;
|
|
20
|
+
}
|
|
21
|
+
export function webSearchProxyController() {
|
|
22
|
+
const app = new Hono();
|
|
23
|
+
// SearXNG's search endpoint shape: `/search?q=...&format=json`. We always answer
|
|
24
|
+
// JSON regardless of the `format` param (the container only ever asks for json).
|
|
25
|
+
app.get('/v1/web-search/search', async (c) => {
|
|
26
|
+
const { config, gateways, spendService } = c.get('container');
|
|
27
|
+
// No upstream wired ⇒ container web search isn't enabled for this deployment.
|
|
28
|
+
const upstream = gateways.webSearch;
|
|
29
|
+
if (!upstream) {
|
|
30
|
+
return c.json({ error: { message: 'Web search is not configured' } }, 503);
|
|
31
|
+
}
|
|
32
|
+
const secret = config.auth.sessionSecret;
|
|
33
|
+
if (!secret) {
|
|
34
|
+
logger.error({ scope: 'webSearchProxy' }, 'web-search proxy: session secret not configured');
|
|
35
|
+
return c.json({ error: { message: 'Web search proxy is not configured' } }, 503);
|
|
36
|
+
}
|
|
37
|
+
// Same model-locked container token the LLM proxy verifies: only our own per-run
|
|
38
|
+
// containers can reach the search upstream, and only while their token is valid.
|
|
39
|
+
const sessions = new ContainerSessionService({ secret });
|
|
40
|
+
const session = await sessions.verify(bearer(c.req.header('authorization')));
|
|
41
|
+
if (!session) {
|
|
42
|
+
logger.warn({ scope: 'webSearchProxy' }, 'web-search proxy: invalid or expired session token');
|
|
43
|
+
return c.json({ error: { message: 'Invalid or expired session token' } }, 401);
|
|
44
|
+
}
|
|
45
|
+
// Budget gate: a run that has exhausted its workspace's spend budget can't keep
|
|
46
|
+
// spending on searches either (searches cost money on metered providers).
|
|
47
|
+
if (await spendService.isOverBudget()) {
|
|
48
|
+
logger.warn({ scope: 'webSearchProxy', workspaceId: session.workspaceId }, 'web-search proxy: spend budget exhausted — refusing search');
|
|
49
|
+
return c.json({ error: { message: 'Spend budget exhausted' } }, 402);
|
|
50
|
+
}
|
|
51
|
+
const query = (c.req.query('q') ?? '').trim();
|
|
52
|
+
// SearXNG returns an empty result set (not an error) for a blank query.
|
|
53
|
+
if (!query)
|
|
54
|
+
return c.json({ query: '', number_of_results: 0, results: [] });
|
|
55
|
+
const log = logger.child({
|
|
56
|
+
scope: 'webSearchProxy',
|
|
57
|
+
workspaceId: session.workspaceId,
|
|
58
|
+
executionId: session.executionId,
|
|
59
|
+
agentKind: session.agentKind,
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
const { results } = await upstream.search(query);
|
|
63
|
+
log.info({ resultCount: results.length }, 'web-search proxy: served search');
|
|
64
|
+
// Shape the response as SearXNG's `format=json` payload so the extension reads
|
|
65
|
+
// `results[].{url,title,content}` unchanged.
|
|
66
|
+
return c.json({ query, number_of_results: results.length, results });
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
70
|
+
log.error({ err: message }, 'web-search proxy: upstream search failed');
|
|
71
|
+
// SearXNG-shaped empty result on failure so the agent degrades gracefully
|
|
72
|
+
// (no results) instead of the tool hard-erroring mid-run.
|
|
73
|
+
return c.json({ query, number_of_results: 0, results: [] }, 502);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return app;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=WebSearchProxyController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSearchProxyController.js","sourceRoot":"","sources":["../../../src/modules/webSearch/WebSearchProxyController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { WebSearchResponse, WebSearchUpstream } from '../../runtime/gateways.js';
|
|
2
|
+
/** Default number of results requested per search. */
|
|
3
|
+
export declare const DEFAULT_WEB_SEARCH_COUNT = 5;
|
|
4
|
+
/**
|
|
5
|
+
* Brave Search upstream — the default, mirroring what Claude Code uses. The key
|
|
6
|
+
* (`WEB_SEARCH_BRAVE_API_KEY`) stays on the backend; the container only ever reaches
|
|
7
|
+
* this proxy with its session token. Maps Brave's `web.results[].{url,title,description}`
|
|
8
|
+
* onto the normalised `{url,title,content}` shape.
|
|
9
|
+
*/
|
|
10
|
+
export declare class BraveWebSearchUpstream implements WebSearchUpstream {
|
|
11
|
+
private readonly apiKey;
|
|
12
|
+
private readonly endpoint;
|
|
13
|
+
constructor(apiKey: string, endpoint?: string);
|
|
14
|
+
search(query: string, opts?: {
|
|
15
|
+
count?: number;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}): Promise<WebSearchResponse>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* SearXNG passthrough upstream — an authenticating reverse proxy to a SearXNG
|
|
21
|
+
* instance the deployment runs (`WEB_SEARCH_SEARXNG_URL`, with an optional bearer
|
|
22
|
+
* via `WEB_SEARCH_SEARXNG_API_KEY` when it sits behind an auth proxy). Zero vendor
|
|
23
|
+
* mapping: SearXNG already aggregates real engines and returns the canonical
|
|
24
|
+
* `results[].{url,title,content}` we pass straight through. Keeps the SearXNG URL +
|
|
25
|
+
* credential off the sandbox (the container only sees this backend proxy).
|
|
26
|
+
*/
|
|
27
|
+
export declare class SearxngWebSearchUpstream implements WebSearchUpstream {
|
|
28
|
+
private readonly apiKey?;
|
|
29
|
+
private readonly base;
|
|
30
|
+
constructor(baseUrl: string, apiKey?: string | undefined);
|
|
31
|
+
search(query: string, opts?: {
|
|
32
|
+
count?: number;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
}): Promise<WebSearchResponse>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the container web-search upstream from a deployment's environment, or
|
|
38
|
+
* undefined when none is configured (⇒ container web search stays off; the proxy
|
|
39
|
+
* route replies 503). Brave wins when its key is set (the recommended path — one
|
|
40
|
+
* backend key, nothing in the sandbox); else a self-hosted SearXNG the backend
|
|
41
|
+
* reverse-proxies. These env vars live on the BACKEND (next to the model keys), not
|
|
42
|
+
* in the container — distinct from the harness's own `BRAVE_SEARCH_API_KEY` /
|
|
43
|
+
* `SEARXNG_URL` autodetect, which only applies to self-hosted runner-pool containers.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createWebSearchUpstreamFromEnv(env: {
|
|
46
|
+
WEB_SEARCH_BRAVE_API_KEY?: string;
|
|
47
|
+
WEB_SEARCH_SEARXNG_URL?: string;
|
|
48
|
+
WEB_SEARCH_SEARXNG_API_KEY?: string;
|
|
49
|
+
}): WebSearchUpstream | undefined;
|
|
50
|
+
//# sourceMappingURL=upstreams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstreams.d.ts","sourceRoot":"","sources":["../../../src/modules/webSearch/upstreams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAQrF,sDAAsD;AACtD,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAgBzC;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,iBAAiB;IAE5D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAF3B,YACmB,MAAM,EAAE,MAAM,EACd,QAAQ,SAAmD,EAC1E;IAEE,MAAM,CACV,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAClD,OAAO,CAAC,iBAAiB,CAAC,CAkB5B;CACF;AAOD;;;;;;;GAOG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAI9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAH1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,YACE,OAAO,EAAE,MAAM,EACE,MAAM,CAAC,EAAE,MAAM,YAAA,EAGjC;IAEK,MAAM,CACV,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAClD,OAAO,CAAC,iBAAiB,CAAC,CAuB5B;CACF;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE;IAClD,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,0BAA0B,CAAC,EAAE,MAAM,CAAA;CACpC,GAAG,iBAAiB,GAAG,SAAS,CAMhC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Runtime-neutral web-search upstreams for the container search proxy. Each performs
|
|
2
|
+
// the actual search server-side (under the deployment's own provider key) and maps the
|
|
3
|
+
// provider's payload into the normalised SearXNG-style shape the proxy returns. They
|
|
4
|
+
// use only `fetch`, so the SAME implementation serves both facades — the vendor key
|
|
5
|
+
// lives on the backend, never in the sandbox (mirroring the LLM-proxy posture).
|
|
6
|
+
/** Default number of results requested per search. */
|
|
7
|
+
export const DEFAULT_WEB_SEARCH_COUNT = 5;
|
|
8
|
+
/** Hard cap on results so a hostile `count` can't ask an upstream for an unbounded page. */
|
|
9
|
+
const MAX_WEB_SEARCH_COUNT = 20;
|
|
10
|
+
/** Clamp a requested result count into a sane range, falling back to the default. */
|
|
11
|
+
function clampCount(count) {
|
|
12
|
+
if (!Number.isFinite(count) || (count ?? 0) <= 0)
|
|
13
|
+
return DEFAULT_WEB_SEARCH_COUNT;
|
|
14
|
+
return Math.min(Math.floor(count), MAX_WEB_SEARCH_COUNT);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Brave Search upstream — the default, mirroring what Claude Code uses. The key
|
|
18
|
+
* (`WEB_SEARCH_BRAVE_API_KEY`) stays on the backend; the container only ever reaches
|
|
19
|
+
* this proxy with its session token. Maps Brave's `web.results[].{url,title,description}`
|
|
20
|
+
* onto the normalised `{url,title,content}` shape.
|
|
21
|
+
*/
|
|
22
|
+
export class BraveWebSearchUpstream {
|
|
23
|
+
apiKey;
|
|
24
|
+
endpoint;
|
|
25
|
+
constructor(apiKey, endpoint = 'https://api.search.brave.com/res/v1/web/search') {
|
|
26
|
+
this.apiKey = apiKey;
|
|
27
|
+
this.endpoint = endpoint;
|
|
28
|
+
}
|
|
29
|
+
async search(query, opts = {}) {
|
|
30
|
+
const url = new URL(this.endpoint);
|
|
31
|
+
url.searchParams.set('q', query);
|
|
32
|
+
url.searchParams.set('count', String(clampCount(opts.count)));
|
|
33
|
+
const res = await fetch(url, {
|
|
34
|
+
headers: { accept: 'application/json', 'x-subscription-token': this.apiKey },
|
|
35
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
throw new Error(`Brave search failed (HTTP ${res.status})`);
|
|
39
|
+
}
|
|
40
|
+
const json = (await res.json());
|
|
41
|
+
const results = (json.web?.results ?? [])
|
|
42
|
+
.filter((r) => {
|
|
43
|
+
return typeof r.url === 'string';
|
|
44
|
+
})
|
|
45
|
+
.map((r) => ({ url: r.url, title: r.title ?? '', content: r.description ?? '' }));
|
|
46
|
+
return { query, results };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* SearXNG passthrough upstream — an authenticating reverse proxy to a SearXNG
|
|
51
|
+
* instance the deployment runs (`WEB_SEARCH_SEARXNG_URL`, with an optional bearer
|
|
52
|
+
* via `WEB_SEARCH_SEARXNG_API_KEY` when it sits behind an auth proxy). Zero vendor
|
|
53
|
+
* mapping: SearXNG already aggregates real engines and returns the canonical
|
|
54
|
+
* `results[].{url,title,content}` we pass straight through. Keeps the SearXNG URL +
|
|
55
|
+
* credential off the sandbox (the container only sees this backend proxy).
|
|
56
|
+
*/
|
|
57
|
+
export class SearxngWebSearchUpstream {
|
|
58
|
+
apiKey;
|
|
59
|
+
base;
|
|
60
|
+
constructor(baseUrl, apiKey) {
|
|
61
|
+
this.apiKey = apiKey;
|
|
62
|
+
this.base = baseUrl.replace(/\/+$/, '');
|
|
63
|
+
}
|
|
64
|
+
async search(query, opts = {}) {
|
|
65
|
+
const url = new URL(`${this.base}/search`);
|
|
66
|
+
url.searchParams.set('q', query);
|
|
67
|
+
url.searchParams.set('format', 'json');
|
|
68
|
+
const res = await fetch(url, {
|
|
69
|
+
headers: {
|
|
70
|
+
accept: 'application/json',
|
|
71
|
+
...(this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}),
|
|
72
|
+
},
|
|
73
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
74
|
+
});
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
throw new Error(`SearXNG search failed (HTTP ${res.status})`);
|
|
77
|
+
}
|
|
78
|
+
const json = (await res.json());
|
|
79
|
+
const limit = clampCount(opts.count);
|
|
80
|
+
const results = (json.results ?? [])
|
|
81
|
+
.filter((r) => {
|
|
82
|
+
return typeof r.url === 'string';
|
|
83
|
+
})
|
|
84
|
+
.slice(0, limit)
|
|
85
|
+
.map((r) => ({ url: r.url, title: r.title ?? '', content: r.content ?? '' }));
|
|
86
|
+
return { query, results };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Build the container web-search upstream from a deployment's environment, or
|
|
91
|
+
* undefined when none is configured (⇒ container web search stays off; the proxy
|
|
92
|
+
* route replies 503). Brave wins when its key is set (the recommended path — one
|
|
93
|
+
* backend key, nothing in the sandbox); else a self-hosted SearXNG the backend
|
|
94
|
+
* reverse-proxies. These env vars live on the BACKEND (next to the model keys), not
|
|
95
|
+
* in the container — distinct from the harness's own `BRAVE_SEARCH_API_KEY` /
|
|
96
|
+
* `SEARXNG_URL` autodetect, which only applies to self-hosted runner-pool containers.
|
|
97
|
+
*/
|
|
98
|
+
export function createWebSearchUpstreamFromEnv(env) {
|
|
99
|
+
const brave = env.WEB_SEARCH_BRAVE_API_KEY?.trim();
|
|
100
|
+
if (brave)
|
|
101
|
+
return new BraveWebSearchUpstream(brave);
|
|
102
|
+
const searxng = env.WEB_SEARCH_SEARXNG_URL?.trim();
|
|
103
|
+
if (searxng)
|
|
104
|
+
return new SearxngWebSearchUpstream(searxng, env.WEB_SEARCH_SEARXNG_API_KEY?.trim());
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=upstreams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstreams.js","sourceRoot":"","sources":["../../../src/modules/webSearch/upstreams.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,uFAAuF;AACvF,qFAAqF;AACrF,oFAAoF;AACpF,gFAAgF;AAEhF,sDAAsD;AACtD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAEzC,4FAA4F;AAC5F,MAAM,oBAAoB,GAAG,EAAE,CAAA;AAE/B,qFAAqF;AACrF,SAAS,UAAU,CAAC,KAAyB;IAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC;QAAE,OAAO,wBAAwB,CAAA;IACjF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAe,CAAC,EAAE,oBAAoB,CAAC,CAAA;AACpE,CAAC;AAOD;;;;;GAKG;AACH,MAAM,OAAO,sBAAsB;IAEd,MAAM;IACN,QAAQ;IAF3B,YACmB,MAAc,EACd,QAAQ,GAAG,gDAAgD;sBAD3D,MAAM;wBACN,QAAQ;IACxB,CAAC;IAEJ,KAAK,CAAC,MAAM,CACV,KAAa,EACb,IAAI,GAA6C,EAAE;QAEnD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAChC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC7D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,IAAI,CAAC,MAAM,EAAE;YAC5E,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwB,CAAA;QACtD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAA8D,EAAE;YACxE,OAAO,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAA;QAClC,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;QACnF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IAC3B,CAAC;CACF;AAOD;;;;;;;GAOG;AACH,MAAM,OAAO,wBAAwB;IAIhB,MAAM;IAHR,IAAI,CAAQ;IAC7B,YACE,OAAe,EACE,MAAe;sBAAf,MAAM;QAEvB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,KAAa,EACb,IAAI,GAA6C,EAAE;QAEnD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,SAAS,CAAC,CAAA;QAC1C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAChC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACtC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,OAAO,EAAE;gBACP,MAAM,EAAE,kBAAkB;gBAC1B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACnE;YACD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;QAC/D,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAA;QACxD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;aACjC,MAAM,CAAC,CAAC,CAAC,EAA0D,EAAE;YACpE,OAAO,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAA;QAClC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;QAC/E,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IAC3B,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAAC,GAI9C;IACC,MAAM,KAAK,GAAG,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,CAAA;IAClD,IAAI,KAAK;QAAE,OAAO,IAAI,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,OAAO,GAAG,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAA;IAClD,IAAI,OAAO;QAAE,OAAO,IAAI,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE,CAAC,CAAA;IACjG,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceController.d.ts","sourceRoot":"","sources":["../../../src/modules/workspaces/WorkspaceController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAkC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAU/C,+DAA+D;AAC/D,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,CAwIlD"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { createWorkspaceSchema, renameWorkspaceSchema } from '@cat-factory/contracts';
|
|
2
|
+
import { configContributionCatalog } from '@cat-factory/agents';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
/**
|
|
5
|
+
* The agent config-contribution catalog for a snapshot: the descriptors contributed
|
|
6
|
+
* across every agent kind used by the workspace's pipelines (deduped by id). Static
|
|
7
|
+
* metadata derived from the agent registry; the board renders the subset whose
|
|
8
|
+
* owning kind appears in a task's selected pipeline.
|
|
9
|
+
*/
|
|
10
|
+
function snapshotAgentConfigCatalog(snapshot) {
|
|
11
|
+
const kinds = new Set();
|
|
12
|
+
for (const pipeline of snapshot.pipelines)
|
|
13
|
+
for (const kind of pipeline.agentKinds)
|
|
14
|
+
kinds.add(kind);
|
|
15
|
+
return configContributionCatalog(kinds);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The deployment's env-routing defaults as `provider:model` ref strings, so the
|
|
19
|
+
* model-defaults panel can name the model behind "Deployment default" per kind.
|
|
20
|
+
* Derived from the shared agents config, so identical across facades.
|
|
21
|
+
*/
|
|
22
|
+
function deploymentModelDefaults(routing) {
|
|
23
|
+
const ref = (r) => `${r.provider}:${r.model}`;
|
|
24
|
+
return {
|
|
25
|
+
default: ref(routing.default.ref),
|
|
26
|
+
byKind: Object.fromEntries(Object.entries(routing.byKind)
|
|
27
|
+
.filter((entry) => entry[1] != null)
|
|
28
|
+
.map(([kind, cfg]) => [kind, ref(cfg.ref)])),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
import { param } from '../../http/params.js';
|
|
32
|
+
import { jsonBody } from '../../http/validation.js';
|
|
33
|
+
/** The signed-in user, narrowed to what the tenancy layer needs. */
|
|
34
|
+
function accountUser(c) {
|
|
35
|
+
const user = c.get('user');
|
|
36
|
+
return user ? { id: user.id, login: user.login, name: user.name } : null;
|
|
37
|
+
}
|
|
38
|
+
/** Board (workspace) lifecycle and full-snapshot retrieval. */
|
|
39
|
+
export function workspaceController() {
|
|
40
|
+
const app = new Hono();
|
|
41
|
+
// Boards visible to the signed-in user: those in any account they belong to,
|
|
42
|
+
// plus any legacy board they personally own. When auth is disabled (`user`
|
|
43
|
+
// unset) the scope is null → no scoping (every board, dev behaviour).
|
|
44
|
+
app.get('/workspaces', async (c) => {
|
|
45
|
+
const container = c.get('container');
|
|
46
|
+
const user = accountUser(c);
|
|
47
|
+
if (!user)
|
|
48
|
+
return c.json(await container.workspaceService.list(null));
|
|
49
|
+
await container.accountService.ensurePersonalAccount(user);
|
|
50
|
+
const accountIds = await container.accountService.accessibleAccountIds(user.id);
|
|
51
|
+
return c.json(await container.workspaceService.list({ accountIds, ownerUserId: user.id }));
|
|
52
|
+
});
|
|
53
|
+
app.post('/workspaces', jsonBody(createWorkspaceSchema), async (c) => {
|
|
54
|
+
const container = c.get('container');
|
|
55
|
+
const user = accountUser(c);
|
|
56
|
+
const body = c.req.valid('json');
|
|
57
|
+
// Resolve the owning account: an explicit one the caller belongs to, else the
|
|
58
|
+
// caller's personal account; unscoped when there's no signed-in user (dev).
|
|
59
|
+
let accountId = null;
|
|
60
|
+
if (user) {
|
|
61
|
+
if (body.accountId) {
|
|
62
|
+
// Membership is required — a non-member is told the account doesn't exist.
|
|
63
|
+
await container.accountService.requireMember(body.accountId, user.id);
|
|
64
|
+
accountId = body.accountId;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
accountId = (await container.accountService.ensurePersonalAccount(user)).id;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (body.accountId) {
|
|
71
|
+
accountId = body.accountId;
|
|
72
|
+
}
|
|
73
|
+
const snapshot = await container.workspaceService.create(body, user?.id ?? null, accountId);
|
|
74
|
+
const spend = await container.spendService.status();
|
|
75
|
+
return c.json({
|
|
76
|
+
...snapshot,
|
|
77
|
+
spend,
|
|
78
|
+
agentConfigCatalog: snapshotAgentConfigCatalog(snapshot),
|
|
79
|
+
deploymentModelDefaults: deploymentModelDefaults(container.config.agents.routing),
|
|
80
|
+
}, 201);
|
|
81
|
+
});
|
|
82
|
+
app.get('/workspaces/:workspaceId', async (c) => {
|
|
83
|
+
const container = c.get('container');
|
|
84
|
+
const workspaceId = param(c, 'workspaceId');
|
|
85
|
+
const snapshot = await container.workspaceService.snapshot(workspaceId);
|
|
86
|
+
const spend = await container.spendService.status();
|
|
87
|
+
// Carry bootstrap runs in the snapshot so the board renders a bootstrap's live
|
|
88
|
+
// progress / failure + retry the moment it loads (no separate, independently
|
|
89
|
+
// failing fetch). No-op when the bootstrap module isn't configured.
|
|
90
|
+
const bootstrapJobs = container.bootstrap
|
|
91
|
+
? await container.bootstrap.service.listJobs(workspaceId)
|
|
92
|
+
: undefined;
|
|
93
|
+
// Open notifications + merge-preset library, so the board renders the inbox,
|
|
94
|
+
// per-block badges and the task preset picker on load. No-ops when unconfigured.
|
|
95
|
+
const notifications = container.notifications
|
|
96
|
+
? await container.notifications.service.listOpen(workspaceId)
|
|
97
|
+
: undefined;
|
|
98
|
+
const mergePresets = container.mergePresets
|
|
99
|
+
? await container.mergePresets.service.list(workspaceId)
|
|
100
|
+
: undefined;
|
|
101
|
+
// The workspace's per-agent-kind default models, so the board renders the
|
|
102
|
+
// model-defaults settings on load. No-op when the module isn't configured.
|
|
103
|
+
const modelDefaults = container.modelDefaults
|
|
104
|
+
? await container.modelDefaults.service.get(workspaceId)
|
|
105
|
+
: undefined;
|
|
106
|
+
// The workspace's default service-fragment selection, so the board renders the
|
|
107
|
+
// defaults settings on load. No-op when the module isn't configured.
|
|
108
|
+
const serviceFragmentDefaults = container.serviceFragmentDefaults
|
|
109
|
+
? await container.serviceFragmentDefaults.service.get(workspaceId)
|
|
110
|
+
: undefined;
|
|
111
|
+
// The workspace's recurring pipelines + issue-tracker selection, so the board
|
|
112
|
+
// renders the recurring-task badges and the tracker config on load. No-ops when
|
|
113
|
+
// the modules aren't configured. Run history is fetched lazily, not here.
|
|
114
|
+
const recurringPipelines = container.recurring
|
|
115
|
+
? await container.recurring.service.list(workspaceId)
|
|
116
|
+
: undefined;
|
|
117
|
+
const trackerSettings = container.tracker
|
|
118
|
+
? await container.tracker.service.get(workspaceId)
|
|
119
|
+
: undefined;
|
|
120
|
+
// The workspace's runtime settings (human-wait escalation threshold + per-service
|
|
121
|
+
// task limit), so the board renders the settings panel on load. No-op when unconfigured.
|
|
122
|
+
const settings = container.settings
|
|
123
|
+
? await container.settings.service.get(workspaceId)
|
|
124
|
+
: undefined;
|
|
125
|
+
// In-org shared services: the workspace's mounts + the org catalog it can mount from
|
|
126
|
+
// (each catalog service annotated with its mount count for the "Shared" badge).
|
|
127
|
+
const mounts = container.services
|
|
128
|
+
? await container.services.service.listMounts(workspaceId)
|
|
129
|
+
: undefined;
|
|
130
|
+
const accountId = container.services
|
|
131
|
+
? await container.workspaceService.accountOf(workspaceId)
|
|
132
|
+
: undefined;
|
|
133
|
+
const serviceCatalog = container.services && accountId !== undefined
|
|
134
|
+
? await container.services.service.listForAccount(accountId)
|
|
135
|
+
: undefined;
|
|
136
|
+
return c.json({
|
|
137
|
+
...snapshot,
|
|
138
|
+
spend,
|
|
139
|
+
...(bootstrapJobs ? { bootstrapJobs } : {}),
|
|
140
|
+
...(notifications ? { notifications } : {}),
|
|
141
|
+
...(mergePresets ? { mergePresets } : {}),
|
|
142
|
+
...(modelDefaults ? { modelDefaults } : {}),
|
|
143
|
+
...(serviceFragmentDefaults ? { serviceFragmentDefaults } : {}),
|
|
144
|
+
...(recurringPipelines ? { recurringPipelines } : {}),
|
|
145
|
+
...(trackerSettings ? { trackerSettings } : {}),
|
|
146
|
+
...(settings ? { settings } : {}),
|
|
147
|
+
...(mounts ? { mounts } : {}),
|
|
148
|
+
...(serviceCatalog ? { serviceCatalog } : {}),
|
|
149
|
+
agentConfigCatalog: snapshotAgentConfigCatalog(snapshot),
|
|
150
|
+
deploymentModelDefaults: deploymentModelDefaults(container.config.agents.routing),
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
app.patch('/workspaces/:workspaceId', jsonBody(renameWorkspaceSchema), async (c) => {
|
|
154
|
+
const body = c.req.valid('json');
|
|
155
|
+
const workspace = await c.get('container').workspaceService.update(param(c, 'workspaceId'), {
|
|
156
|
+
...(body.name !== undefined ? { name: body.name } : {}),
|
|
157
|
+
...('description' in body ? { description: body.description } : {}),
|
|
158
|
+
});
|
|
159
|
+
return c.json(workspace);
|
|
160
|
+
});
|
|
161
|
+
app.delete('/workspaces/:workspaceId', async (c) => {
|
|
162
|
+
await c.get('container').workspaceService.delete(param(c, 'workspaceId'));
|
|
163
|
+
return c.body(null, 204);
|
|
164
|
+
});
|
|
165
|
+
return app;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=WorkspaceController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceController.js","sourceRoot":"","sources":["../../../src/modules/workspaces/WorkspaceController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
/**
|
|
3
|
+
* Process-wide logger. Prefer `logger.child({ … })` (or pass a `fields` object)
|
|
4
|
+
* to attach correlation context — workspaceId, executionId, jobId — so a run can
|
|
5
|
+
* be traced across the request, the workflow and the container.
|
|
6
|
+
*/
|
|
7
|
+
export declare const logger: pino.Logger<never, boolean>;
|
|
8
|
+
export type Logger = typeof logger;
|
|
9
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/observability/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAoBvB;;;;GAIG;AACH,eAAO,MAAM,MAAM,6BAajB,CAAA;AAEF,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
// Structured logging shared by every facade. The default pino transport relies on
|
|
3
|
+
// Node worker threads, which workerd doesn't provide, so we use pino's browser API
|
|
4
|
+
// with an explicit per-level `write` that emits one JSON line to the matching
|
|
5
|
+
// `console` method. Both Cloudflare (via `wrangler tail` / Logpush) and a Node
|
|
6
|
+
// process capture `console.*`, so this gives queryable, level-routed structured
|
|
7
|
+
// logs on either runtime.
|
|
8
|
+
const LEVEL = globalThis.LOG_LEVEL ?? 'info';
|
|
9
|
+
function write(level) {
|
|
10
|
+
return (o) => {
|
|
11
|
+
const line = JSON.stringify({ level, ...o });
|
|
12
|
+
if (level === 'error' || level === 'fatal')
|
|
13
|
+
console.error(line);
|
|
14
|
+
else if (level === 'warn')
|
|
15
|
+
console.warn(line);
|
|
16
|
+
else
|
|
17
|
+
console.log(line);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Process-wide logger. Prefer `logger.child({ … })` (or pass a `fields` object)
|
|
22
|
+
* to attach correlation context — workspaceId, executionId, jobId — so a run can
|
|
23
|
+
* be traced across the request, the workflow and the container.
|
|
24
|
+
*/
|
|
25
|
+
export const logger = pino({
|
|
26
|
+
level: LEVEL,
|
|
27
|
+
browser: {
|
|
28
|
+
asObject: true,
|
|
29
|
+
write: {
|
|
30
|
+
trace: write('trace'),
|
|
31
|
+
debug: write('debug'),
|
|
32
|
+
info: write('info'),
|
|
33
|
+
warn: write('warn'),
|
|
34
|
+
error: write('error'),
|
|
35
|
+
fatal: write('fatal'),
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/observability/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,kFAAkF;AAClF,mFAAmF;AACnF,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,0BAA0B;AAE1B,MAAM,KAAK,GAAI,UAAqC,CAAC,SAAS,IAAI,MAAM,CAAA;AAExE,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,CAAC,CAAS,EAAE,EAAE;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QAC5C,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;aAC1D,IAAI,KAAK,KAAK,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;;YACxC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE;QACP,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;SACtB;KACF;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { BlockPatch } from '@cat-factory/kernel';
|
|
2
|
+
import type { Block, ExecutionInstance, Pipeline, Workspace } from '@cat-factory/contracts';
|
|
3
|
+
export interface WorkspaceRow {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description?: string | null;
|
|
7
|
+
created_at: number;
|
|
8
|
+
account_id: string | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function rowToWorkspace(row: WorkspaceRow): Workspace;
|
|
11
|
+
export interface BlockRow {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
pos_x: number;
|
|
17
|
+
pos_y: number;
|
|
18
|
+
width: number | null;
|
|
19
|
+
height: number | null;
|
|
20
|
+
status: string;
|
|
21
|
+
progress: number;
|
|
22
|
+
depends_on: string;
|
|
23
|
+
execution_id: string | null;
|
|
24
|
+
level: string;
|
|
25
|
+
parent_id: string | null;
|
|
26
|
+
confidence: number | null;
|
|
27
|
+
module_name: string | null;
|
|
28
|
+
fragment_ids: string | null;
|
|
29
|
+
/** Service-level: the service's selected best-practice fragment ids, JSON array. */
|
|
30
|
+
service_fragment_ids: string | null;
|
|
31
|
+
model_id: string | null;
|
|
32
|
+
pull_request: string | null;
|
|
33
|
+
merge_preset_id: string | null;
|
|
34
|
+
pipeline_id: string | null;
|
|
35
|
+
/** Task-level agent-contributed config values, JSON id→value map. */
|
|
36
|
+
agent_config: string | null;
|
|
37
|
+
/** Service-level: docker-compose path for the Tester's local infra. */
|
|
38
|
+
test_compose_path: string | null;
|
|
39
|
+
/** Service-level: whether the service has no infra dependencies (0/1). */
|
|
40
|
+
no_infra_dependencies: number | null;
|
|
41
|
+
/** Service-level: cloud provider the service's jobs run on. */
|
|
42
|
+
cloud_provider: string | null;
|
|
43
|
+
/** Service-level: abstract instance size for the service's jobs. */
|
|
44
|
+
instance_size: string | null;
|
|
45
|
+
created_by: string | null;
|
|
46
|
+
responsible_product_user_id: string | null;
|
|
47
|
+
/** Task-level: the task-estimator's triage (complexity/risk/impact), JSON object. */
|
|
48
|
+
estimate?: string | null;
|
|
49
|
+
/** Task-level: the kind of work (feature/bug/document/spike/recurring). */
|
|
50
|
+
task_type?: string | null;
|
|
51
|
+
/** Task-level: small per-type form fields (bug severity, spike timebox…), JSON object. */
|
|
52
|
+
task_type_fields?: string | null;
|
|
53
|
+
}
|
|
54
|
+
export declare function rowToBlock(row: BlockRow): Block;
|
|
55
|
+
/** Full column tuple for inserting a block. */
|
|
56
|
+
export declare function blockInsertValues(block: Block): Record<string, unknown>;
|
|
57
|
+
/** Map a domain patch onto `{ column: value }` pairs for an UPDATE. */
|
|
58
|
+
export declare function blockPatchToColumns(patch: BlockPatch): Record<string, unknown>;
|
|
59
|
+
export interface PipelineRow {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
agent_kinds: string;
|
|
63
|
+
/** Nullable JSON array of per-step approval gates (migration 0022). */
|
|
64
|
+
gates: string | null;
|
|
65
|
+
/** Nullable JSON array of per-step companion quality thresholds (migration 0035). */
|
|
66
|
+
thresholds?: string | null;
|
|
67
|
+
/** Nullable JSON array of per-step enable flags (migration 0002). */
|
|
68
|
+
enabled?: string | null;
|
|
69
|
+
/** Truthy (1) for the curated built-in catalog templates (migration 0002). */
|
|
70
|
+
builtin?: number | boolean | null;
|
|
71
|
+
/** Nullable JSON array of per-step consensus configs (parallel to agent_kinds). */
|
|
72
|
+
consensus?: string | null;
|
|
73
|
+
/** Nullable JSON array of per-step estimate gating (migration 0003). */
|
|
74
|
+
gating?: string | null;
|
|
75
|
+
/** Nullable JSON array of organizational labels (migration 0003). */
|
|
76
|
+
labels?: string | null;
|
|
77
|
+
/** Truthy (1) when the pipeline is archived / hidden from the default view (migration 0003). */
|
|
78
|
+
archived?: number | boolean | null;
|
|
79
|
+
}
|
|
80
|
+
export declare function rowToPipeline(row: PipelineRow): Pipeline;
|
|
81
|
+
/**
|
|
82
|
+
* A `kind='execution'` row of the unified `agent_runs` table (migration 0019).
|
|
83
|
+
* The pipeline shape (pipelineId/Name, steps, currentStep) lives in the `detail`
|
|
84
|
+
* JSON column; lifecycle/failure are top-level columns shared with bootstrap.
|
|
85
|
+
*/
|
|
86
|
+
export interface ExecutionRow {
|
|
87
|
+
id: string;
|
|
88
|
+
block_id: string | null;
|
|
89
|
+
status: string;
|
|
90
|
+
/** JSON {pipelineId,pipelineName,steps,currentStep}. */
|
|
91
|
+
detail: string;
|
|
92
|
+
error: string | null;
|
|
93
|
+
/** JSON-encoded AgentFailure; null unless the run failed. */
|
|
94
|
+
failure: string | null;
|
|
95
|
+
updated_at: number;
|
|
96
|
+
workflow_instance_id: string | null;
|
|
97
|
+
}
|
|
98
|
+
export declare function rowToExecution(row: ExecutionRow): ExecutionInstance;
|
|
99
|
+
/** Build the `agent_runs.detail` JSON for an execution instance (shared by both repos). */
|
|
100
|
+
export declare function executionToDetail(instance: ExecutionInstance): string;
|
|
101
|
+
//# sourceMappingURL=mappers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../src/persistence/mappers.ts"],"names":[],"mappings":"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"}
|