@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,48 @@
|
|
|
1
|
+
import { storePersonalSubscriptionSchema, subscriptionVendorSchema } from '@cat-factory/contracts';
|
|
2
|
+
import * as v from 'valibot';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { param } from '../../http/params.js';
|
|
5
|
+
import { jsonBody } from '../../http/validation.js';
|
|
6
|
+
// Per-USER individual-usage subscription endpoints (Claude). Unlike the workspace
|
|
7
|
+
// vendor-credential pool, these are scoped to the signed-in user: a personal
|
|
8
|
+
// subscription is licensed for that individual only, stored DOUBLE-encrypted (a
|
|
9
|
+
// personal-password layer inside the system layer), and never shared. Mounted at the
|
|
10
|
+
// root (not under a workspace) and require a signed-in user — with auth disabled there
|
|
11
|
+
// is no individual to own a personal credential.
|
|
12
|
+
const signInRequired = (c) => c.json({ error: { code: 'unauthorized', message: 'Sign in to manage personal subscriptions' } }, 401);
|
|
13
|
+
const unavailable = (c) => c.json({ error: { code: 'unavailable', message: 'Personal subscription storage is not configured' } }, 503);
|
|
14
|
+
export function personalSubscriptionController() {
|
|
15
|
+
const app = new Hono();
|
|
16
|
+
app.get('/personal-subscriptions', async (c) => {
|
|
17
|
+
const personal = c.get('container').personalSubscriptions;
|
|
18
|
+
if (!personal)
|
|
19
|
+
return unavailable(c);
|
|
20
|
+
const user = c.get('user');
|
|
21
|
+
if (!user)
|
|
22
|
+
return signInRequired(c);
|
|
23
|
+
return c.json({ subscriptions: await personal.list(user.id) });
|
|
24
|
+
});
|
|
25
|
+
app.post('/personal-subscriptions', jsonBody(storePersonalSubscriptionSchema), async (c) => {
|
|
26
|
+
const personal = c.get('container').personalSubscriptions;
|
|
27
|
+
if (!personal)
|
|
28
|
+
return unavailable(c);
|
|
29
|
+
const user = c.get('user');
|
|
30
|
+
if (!user)
|
|
31
|
+
return signInRequired(c);
|
|
32
|
+
const status = await personal.store(user.id, c.req.valid('json'));
|
|
33
|
+
return c.json(status, 201);
|
|
34
|
+
});
|
|
35
|
+
app.delete('/personal-subscriptions/:vendor', async (c) => {
|
|
36
|
+
const personal = c.get('container').personalSubscriptions;
|
|
37
|
+
if (!personal)
|
|
38
|
+
return unavailable(c);
|
|
39
|
+
const user = c.get('user');
|
|
40
|
+
if (!user)
|
|
41
|
+
return signInRequired(c);
|
|
42
|
+
const vendor = v.parse(subscriptionVendorSchema, param(c, 'vendor'));
|
|
43
|
+
await personal.remove(user.id, vendor);
|
|
44
|
+
return c.body(null, 204);
|
|
45
|
+
});
|
|
46
|
+
return app;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=PersonalSubscriptionController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersonalSubscriptionController.js","sourceRoot":"","sources":["../../../src/modules/providers/PersonalSubscriptionController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VendorCredentialController.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/VendorCredentialController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAmC/C,wBAAgB,0BAA0B,IAAI,IAAI,CAAC,MAAM,CAAC,CA0BzD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { addVendorCredentialSchema } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { param } from '../../http/params.js';
|
|
4
|
+
import { jsonBody } from '../../http/validation.js';
|
|
5
|
+
// Workspace-scoped vendor-credential (subscription token pool) endpoints. A user
|
|
6
|
+
// connects one or more Claude Pro/Max OAuth tokens or ChatGPT auth.json bundles;
|
|
7
|
+
// the Claude Code / Codex harnesses lease them with usage-aware rotation. Tokens
|
|
8
|
+
// are write-only — only metadata + rolling-window usage is ever returned. Mounted
|
|
9
|
+
// under `/workspaces/:workspaceId`.
|
|
10
|
+
const unavailable = (c) => c.json({
|
|
11
|
+
error: {
|
|
12
|
+
code: 'unavailable',
|
|
13
|
+
message: 'Subscription credential storage is not configured',
|
|
14
|
+
},
|
|
15
|
+
}, 503);
|
|
16
|
+
/** Project the service summary onto the wire type (already secret-free). */
|
|
17
|
+
function toWire(summary) {
|
|
18
|
+
return {
|
|
19
|
+
id: summary.id,
|
|
20
|
+
vendor: summary.vendor,
|
|
21
|
+
label: summary.label,
|
|
22
|
+
createdAt: summary.createdAt,
|
|
23
|
+
lastUsedAt: summary.lastUsedAt,
|
|
24
|
+
inputTokens: summary.inputTokens,
|
|
25
|
+
outputTokens: summary.outputTokens,
|
|
26
|
+
requestCount: summary.requestCount,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function vendorCredentialController() {
|
|
30
|
+
const app = new Hono();
|
|
31
|
+
app.get('/vendor-credentials', async (c) => {
|
|
32
|
+
const subscriptions = c.get('container').subscriptions;
|
|
33
|
+
if (!subscriptions)
|
|
34
|
+
return unavailable(c);
|
|
35
|
+
const tokens = await subscriptions.listTokens(param(c, 'workspaceId'));
|
|
36
|
+
return c.json({ credentials: tokens.map(toWire) });
|
|
37
|
+
});
|
|
38
|
+
app.post('/vendor-credentials', jsonBody(addVendorCredentialSchema), async (c) => {
|
|
39
|
+
const subscriptions = c.get('container').subscriptions;
|
|
40
|
+
if (!subscriptions)
|
|
41
|
+
return unavailable(c);
|
|
42
|
+
const input = c.req.valid('json');
|
|
43
|
+
const summary = await subscriptions.addToken(param(c, 'workspaceId'), input);
|
|
44
|
+
return c.json(toWire(summary), 201);
|
|
45
|
+
});
|
|
46
|
+
app.delete('/vendor-credentials/:id', async (c) => {
|
|
47
|
+
const subscriptions = c.get('container').subscriptions;
|
|
48
|
+
if (!subscriptions)
|
|
49
|
+
return unavailable(c);
|
|
50
|
+
await subscriptions.removeToken(param(c, 'workspaceId'), param(c, 'id'));
|
|
51
|
+
return c.body(null, 204);
|
|
52
|
+
});
|
|
53
|
+
return app;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=VendorCredentialController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VendorCredentialController.js","sourceRoot":"","sources":["../../../src/modules/providers/VendorCredentialController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Context } from 'hono';
|
|
2
|
+
import type { AppEnv, ServerContainer } from '../../http/env.js';
|
|
3
|
+
import type { SessionPayload } from '../../auth/signing.js';
|
|
4
|
+
/**
|
|
5
|
+
* Read the ambient personal password from the request header (see
|
|
6
|
+
* `PERSONAL_PASSWORD_HEADER`). The client attaches it on the gated run calls the way it
|
|
7
|
+
* attaches the bearer token, so it never lives in a request body. Absent ⇒ undefined.
|
|
8
|
+
*/
|
|
9
|
+
export declare function readPersonalPassword(c: Context<AppEnv>): string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Best-effort, transparent re-mint of a run's individual-usage activation(s) when a user
|
|
12
|
+
* interacts with it (resolve decision / approve / request changes). Runs BEFORE the engine
|
|
13
|
+
* advances and dispatches the next step, so a freshly-minted activation is in place even if
|
|
14
|
+
* the previous one lapsed under its short TTL — keeping an actively-tended run alive without
|
|
15
|
+
* re-prompting. Driven off the cached password on the header; a wrong/absent one is ignored
|
|
16
|
+
* (the next dispatch then 428s and the client re-prompts on retry). Never throws, and skips
|
|
17
|
+
* entirely for non-individual runs (no password work on the common path).
|
|
18
|
+
*/
|
|
19
|
+
export declare function remintActivations(c: Context<AppEnv>, workspaceId: string, executionId: string): Promise<void>;
|
|
20
|
+
export interface PersonalCredentialGate {
|
|
21
|
+
/** Recorded on the run (individual-usage credential ownership). */
|
|
22
|
+
initiatedBy: string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Mints the per-run activation(s); passed to `executionService.start`/`retry` so it
|
|
25
|
+
* runs with the new run id before dispatch. Undefined when the run needs no personal
|
|
26
|
+
* credential.
|
|
27
|
+
*/
|
|
28
|
+
activate?: (executionId: string) => Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/** Gate for STARTING a run on a block with a given pipeline. */
|
|
31
|
+
export declare function personalGateForBlock(container: ServerContainer, workspaceId: string, blockId: string, pipelineId: string, user: SessionPayload | undefined, password: string | undefined): Promise<PersonalCredentialGate>;
|
|
32
|
+
/** Gate for RETRYING a failed run. */
|
|
33
|
+
export declare function personalGateForRun(container: ServerContainer, workspaceId: string, executionId: string, user: SessionPayload | undefined, password: string | undefined): Promise<PersonalCredentialGate>;
|
|
34
|
+
//# sourceMappingURL=personalCredentialGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personalCredentialGate.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/personalCredentialGate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAE3E;AAmBD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAyBf;AASD,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClD;AAiDD,gEAAgE;AAChE,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,eAAe,EAC1B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,cAAc,GAAG,SAAS,EAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAQjC;AAED,sCAAsC;AACtC,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,eAAe,EAC1B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,cAAc,GAAG,SAAS,EAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAOjC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { CredentialRequiredError } from '@cat-factory/kernel';
|
|
2
|
+
import { PERSONAL_PASSWORD_HEADER } from '@cat-factory/contracts';
|
|
3
|
+
/**
|
|
4
|
+
* Read the ambient personal password from the request header (see
|
|
5
|
+
* `PERSONAL_PASSWORD_HEADER`). The client attaches it on the gated run calls the way it
|
|
6
|
+
* attaches the bearer token, so it never lives in a request body. Absent ⇒ undefined.
|
|
7
|
+
*/
|
|
8
|
+
export function readPersonalPassword(c) {
|
|
9
|
+
return c.req.header(PERSONAL_PASSWORD_HEADER) || undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A predicate over the vendors the run's user has their OWN personal subscription for.
|
|
13
|
+
* Passed into the engine's vendor resolution so a DUAL-MODE individual model (GLM) gates
|
|
14
|
+
* only a subscriber (a non-subscriber runs it on the Cloudflare base). Empty for an
|
|
15
|
+
* unauthenticated/unconfigured caller — then only subscription-ONLY individual models
|
|
16
|
+
* (Claude / Codex) gate.
|
|
17
|
+
*/
|
|
18
|
+
async function resolvePersonalVendorPredicate(container, user) {
|
|
19
|
+
const personal = container.personalSubscriptions;
|
|
20
|
+
if (!personal || !user)
|
|
21
|
+
return () => false;
|
|
22
|
+
const owned = new Set((await personal.list(user.id)).map((s) => s.vendor));
|
|
23
|
+
return (vendor) => owned.has(vendor);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Best-effort, transparent re-mint of a run's individual-usage activation(s) when a user
|
|
27
|
+
* interacts with it (resolve decision / approve / request changes). Runs BEFORE the engine
|
|
28
|
+
* advances and dispatches the next step, so a freshly-minted activation is in place even if
|
|
29
|
+
* the previous one lapsed under its short TTL — keeping an actively-tended run alive without
|
|
30
|
+
* re-prompting. Driven off the cached password on the header; a wrong/absent one is ignored
|
|
31
|
+
* (the next dispatch then 428s and the client re-prompts on retry). Never throws, and skips
|
|
32
|
+
* entirely for non-individual runs (no password work on the common path).
|
|
33
|
+
*/
|
|
34
|
+
export async function remintActivations(c, workspaceId, executionId) {
|
|
35
|
+
const container = c.get('container');
|
|
36
|
+
const personal = container.personalSubscriptions;
|
|
37
|
+
const user = c.get('user');
|
|
38
|
+
if (!personal || !user)
|
|
39
|
+
return;
|
|
40
|
+
try {
|
|
41
|
+
const vendors = await container.executionService.individualVendorsForRun(workspaceId, executionId, await resolvePersonalVendorPredicate(container, user));
|
|
42
|
+
if (vendors.length === 0)
|
|
43
|
+
return;
|
|
44
|
+
const password = readPersonalPassword(c);
|
|
45
|
+
if (password) {
|
|
46
|
+
// Re-mint from the password — robust even when the prior activation already expired.
|
|
47
|
+
for (const vendor of vendors) {
|
|
48
|
+
await personal.activateForRun(executionId, user.id, vendor, password);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// No password on hand — just extend any still-live activation (no-op if expired).
|
|
53
|
+
await personal.refreshActivations(executionId, user.id);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Best-effort: a lapsed run surfaces 428 at the next dispatch, which the client retries.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build the gate for the set of individual-usage vendors a run will use (empty ⇒ no
|
|
62
|
+
* personal credential needed). The same password unlocks every vendor's activation: the
|
|
63
|
+
* client caches one password and rides it along, and a per-vendor failure (wrong/missing
|
|
64
|
+
* password, no subscription) surfaces as a `428 credential_required` the client re-prompts
|
|
65
|
+
* on. Vendors are activated in order, so the first one that can't be unlocked is reported.
|
|
66
|
+
*/
|
|
67
|
+
function gate(container, vendors, user, password) {
|
|
68
|
+
if (vendors.length === 0)
|
|
69
|
+
return { initiatedBy: user?.id ?? null };
|
|
70
|
+
// The vendor named in the up-front errors (before any activation is attempted).
|
|
71
|
+
const first = vendors[0];
|
|
72
|
+
if (!user) {
|
|
73
|
+
throw new CredentialRequiredError(`Sign in to run a ${first} model with your personal subscription.`, { vendor: first, reason: 'no_subscription' });
|
|
74
|
+
}
|
|
75
|
+
const personal = container.personalSubscriptions;
|
|
76
|
+
if (!personal) {
|
|
77
|
+
throw new CredentialRequiredError(`Personal ${first} subscriptions are not configured on this deployment.`, { vendor: first, reason: 'no_subscription' });
|
|
78
|
+
}
|
|
79
|
+
if (!password) {
|
|
80
|
+
// The credential exists (or not) — either way the unlock needs the password; the
|
|
81
|
+
// client re-prompts on this reason and retries with it.
|
|
82
|
+
throw new CredentialRequiredError(`Enter your personal password to run this ${first} model.`, {
|
|
83
|
+
vendor: first,
|
|
84
|
+
reason: 'password_required',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
initiatedBy: user.id,
|
|
89
|
+
activate: async (executionId) => {
|
|
90
|
+
for (const vendor of vendors) {
|
|
91
|
+
await personal.activateForRun(executionId, user.id, vendor, password);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Gate for STARTING a run on a block with a given pipeline. */
|
|
97
|
+
export async function personalGateForBlock(container, workspaceId, blockId, pipelineId, user, password) {
|
|
98
|
+
const vendors = await container.executionService.individualVendorsForBlock(workspaceId, blockId, pipelineId, await resolvePersonalVendorPredicate(container, user));
|
|
99
|
+
return gate(container, vendors, user, password);
|
|
100
|
+
}
|
|
101
|
+
/** Gate for RETRYING a failed run. */
|
|
102
|
+
export async function personalGateForRun(container, workspaceId, executionId, user, password) {
|
|
103
|
+
const vendors = await container.executionService.individualVendorsForRun(workspaceId, executionId, await resolvePersonalVendorPredicate(container, user));
|
|
104
|
+
return gate(container, vendors, user, password);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=personalCredentialGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personalCredentialGate.js","sourceRoot":"","sources":["../../../src/modules/providers/personalCredentialGate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAA2B,MAAM,qBAAqB,CAAA;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAKjE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,CAAkB;IACrD,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,wBAAwB,CAAC,IAAI,SAAS,CAAA;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,8BAA8B,CAC3C,SAA0B,EAC1B,IAAgC;IAEhC,MAAM,QAAQ,GAAG,SAAS,CAAC,qBAAqB,CAAA;IAChD,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,EAAE,CAAC,KAAK,CAAA;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC1E,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,CAAkB,EAClB,WAAmB,EACnB,WAAmB;IAEnB,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,qBAAqB,CAAA;IAChD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;QAAE,OAAM;IAC9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,uBAAuB,CACtE,WAAW,EACX,WAAW,EACX,MAAM,8BAA8B,CAAC,SAAS,EAAE,IAAI,CAAC,CACtD,CAAA;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAChC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,qFAAqF;YACrF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;YACvE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kFAAkF;YAClF,MAAM,QAAQ,CAAC,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;QACzD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yFAAyF;IAC3F,CAAC;AACH,CAAC;AAoBD;;;;;;GAMG;AACH,SAAS,IAAI,CACX,SAA0B,EAC1B,OAA6B,EAC7B,IAAgC,EAChC,QAA4B;IAE5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE,CAAA;IAClE,gFAAgF;IAChF,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IACzB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,uBAAuB,CAC/B,oBAAoB,KAAK,yCAAyC,EAClE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAC7C,CAAA;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,qBAAqB,CAAA;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,uBAAuB,CAC/B,YAAY,KAAK,uDAAuD,EACxE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAC7C,CAAA;IACH,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,iFAAiF;QACjF,wDAAwD;QACxD,MAAM,IAAI,uBAAuB,CAAC,4CAA4C,KAAK,SAAS,EAAE;YAC5F,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,mBAAmB;SAC5B,CAAC,CAAA;IACJ,CAAC;IACD,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,EAAE;QACpB,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;YAC9B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;YACvE,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,SAA0B,EAC1B,WAAmB,EACnB,OAAe,EACf,UAAkB,EAClB,IAAgC,EAChC,QAA4B;IAE5B,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,yBAAyB,CACxE,WAAW,EACX,OAAO,EACP,UAAU,EACV,MAAM,8BAA8B,CAAC,SAAS,EAAE,IAAI,CAAC,CACtD,CAAA;IACD,OAAO,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;AACjD,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAA0B,EAC1B,WAAmB,EACnB,WAAmB,EACnB,IAAgC,EAChC,QAA4B;IAE5B,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,uBAAuB,CACtE,WAAW,EACX,WAAW,EACX,MAAM,8BAA8B,CAAC,SAAS,EAAE,IAAI,CAAC,CACtD,CAAA;IACD,OAAO,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;AACjD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../../http/env.js';
|
|
3
|
+
/**
|
|
4
|
+
* CRUD + run history for a workspace's recurring pipelines (schedules that re-run a
|
|
5
|
+
* pipeline against a service on a cadence). Mounted under `/workspaces/:workspaceId`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function recurringPipelineController(): Hono<AppEnv>;
|
|
8
|
+
//# sourceMappingURL=RecurringPipelineController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecurringPipelineController.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/RecurringPipelineController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAY/C;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAAC,MAAM,CAAC,CAgD1D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createScheduleSchema, updateScheduleSchema } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { param } from '../../http/params.js';
|
|
4
|
+
import { jsonBody } from '../../http/validation.js';
|
|
5
|
+
/** Resolve the recurring-pipeline module or send a 503, returning null when unconfigured. */
|
|
6
|
+
function requireRecurring(c) {
|
|
7
|
+
return c.get('container').recurring ?? null;
|
|
8
|
+
}
|
|
9
|
+
const unavailable = (c) => c.json({ error: { code: 'unavailable', message: 'Recurring pipelines are not configured' } }, 503);
|
|
10
|
+
/**
|
|
11
|
+
* CRUD + run history for a workspace's recurring pipelines (schedules that re-run a
|
|
12
|
+
* pipeline against a service on a cadence). Mounted under `/workspaces/:workspaceId`.
|
|
13
|
+
*/
|
|
14
|
+
export function recurringPipelineController() {
|
|
15
|
+
const app = new Hono();
|
|
16
|
+
app.get('/recurring-pipelines', async (c) => {
|
|
17
|
+
const recurring = requireRecurring(c);
|
|
18
|
+
if (!recurring)
|
|
19
|
+
return unavailable(c);
|
|
20
|
+
return c.json(await recurring.service.list(param(c, 'workspaceId')));
|
|
21
|
+
});
|
|
22
|
+
app.post('/recurring-pipelines', jsonBody(createScheduleSchema), async (c) => {
|
|
23
|
+
const recurring = requireRecurring(c);
|
|
24
|
+
if (!recurring)
|
|
25
|
+
return unavailable(c);
|
|
26
|
+
const schedule = await recurring.service.create(param(c, 'workspaceId'), c.req.valid('json'));
|
|
27
|
+
return c.json(schedule, 201);
|
|
28
|
+
});
|
|
29
|
+
app.patch('/recurring-pipelines/:scheduleId', jsonBody(updateScheduleSchema), async (c) => {
|
|
30
|
+
const recurring = requireRecurring(c);
|
|
31
|
+
if (!recurring)
|
|
32
|
+
return unavailable(c);
|
|
33
|
+
const schedule = await recurring.service.update(param(c, 'workspaceId'), param(c, 'scheduleId'), c.req.valid('json'));
|
|
34
|
+
return c.json(schedule);
|
|
35
|
+
});
|
|
36
|
+
app.delete('/recurring-pipelines/:scheduleId', async (c) => {
|
|
37
|
+
const recurring = requireRecurring(c);
|
|
38
|
+
if (!recurring)
|
|
39
|
+
return unavailable(c);
|
|
40
|
+
await recurring.service.remove(param(c, 'workspaceId'), param(c, 'scheduleId'));
|
|
41
|
+
return c.body(null, 204);
|
|
42
|
+
});
|
|
43
|
+
app.get('/recurring-pipelines/:scheduleId/runs', async (c) => {
|
|
44
|
+
const recurring = requireRecurring(c);
|
|
45
|
+
if (!recurring)
|
|
46
|
+
return unavailable(c);
|
|
47
|
+
return c.json(await recurring.service.listRuns(param(c, 'workspaceId'), param(c, 'scheduleId')));
|
|
48
|
+
});
|
|
49
|
+
app.post('/recurring-pipelines/:scheduleId/run-now', async (c) => {
|
|
50
|
+
const recurring = requireRecurring(c);
|
|
51
|
+
if (!recurring)
|
|
52
|
+
return unavailable(c);
|
|
53
|
+
const schedule = await recurring.service.runNow(param(c, 'workspaceId'), param(c, 'scheduleId'));
|
|
54
|
+
return c.json(schedule);
|
|
55
|
+
});
|
|
56
|
+
return app;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=RecurringPipelineController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecurringPipelineController.js","sourceRoot":"","sources":["../../../src/modules/recurring/RecurringPipelineController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../../http/env.js';
|
|
3
|
+
/**
|
|
4
|
+
* Read/write a workspace's issue-tracker selection (GitHub Issues or Jira). Mounted
|
|
5
|
+
* under `/workspaces/:workspaceId`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function trackerSettingsController(): Hono<AppEnv>;
|
|
8
|
+
//# sourceMappingURL=TrackerSettingsController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrackerSettingsController.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAY/C;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAAC,MAAM,CAAC,CAgBxD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { putTrackerSettingsSchema } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { param } from '../../http/params.js';
|
|
4
|
+
import { jsonBody } from '../../http/validation.js';
|
|
5
|
+
/** Resolve the tracker-settings module or send a 503, returning null when unconfigured. */
|
|
6
|
+
function requireTracker(c) {
|
|
7
|
+
return c.get('container').tracker ?? null;
|
|
8
|
+
}
|
|
9
|
+
const unavailable = (c) => c.json({ error: { code: 'unavailable', message: 'Issue tracker is not configured' } }, 503);
|
|
10
|
+
/**
|
|
11
|
+
* Read/write a workspace's issue-tracker selection (GitHub Issues or Jira). Mounted
|
|
12
|
+
* under `/workspaces/:workspaceId`.
|
|
13
|
+
*/
|
|
14
|
+
export function trackerSettingsController() {
|
|
15
|
+
const app = new Hono();
|
|
16
|
+
app.get('/tracker-settings', async (c) => {
|
|
17
|
+
const tracker = requireTracker(c);
|
|
18
|
+
if (!tracker)
|
|
19
|
+
return unavailable(c);
|
|
20
|
+
return c.json(await tracker.service.get(param(c, 'workspaceId')));
|
|
21
|
+
});
|
|
22
|
+
app.put('/tracker-settings', jsonBody(putTrackerSettingsSchema), async (c) => {
|
|
23
|
+
const tracker = requireTracker(c);
|
|
24
|
+
if (!tracker)
|
|
25
|
+
return unavailable(c);
|
|
26
|
+
return c.json(await tracker.service.put(param(c, 'workspaceId'), c.req.valid('json')));
|
|
27
|
+
});
|
|
28
|
+
return app;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=TrackerSettingsController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrackerSettingsController.js","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,2FAA2F;AAC3F,SAAS,cAAc,CAAC,CAAkB;IACxC,OAAO,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,IAAI,IAAI,CAAA;AAC3C,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,CAAkB,EAAE,EAAE,CACzC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,iCAAiC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;AAE7F;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAE9B,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QACjC,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,CAAC,CAAC,CAAA;QACnC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3E,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QACjC,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,CAAC,CAAC,CAAC,CAAA;QACnC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACxF,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../../http/env.js';
|
|
3
|
+
/**
|
|
4
|
+
* Per-workspace settings for the post-release-health gate: the (single) Datadog
|
|
5
|
+
* connection (keys write-only, never read back) and the per-block monitor/SLO
|
|
6
|
+
* mappings the gate reads. Mounted under `/workspaces/:workspaceId`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function releaseHealthController(): Hono<AppEnv>;
|
|
9
|
+
//# sourceMappingURL=ReleaseHealthController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReleaseHealthController.d.ts","sourceRoot":"","sources":["../../../src/modules/releaseHealth/ReleaseHealthController.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAe/C;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAAC,MAAM,CAAC,CAmDtD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { upsertDatadogConnectionSchema, upsertReleaseHealthConfigSchema, } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { param } from '../../http/params.js';
|
|
4
|
+
import { jsonBody } from '../../http/validation.js';
|
|
5
|
+
/** Resolve the release-health module or send a 503, returning null when unconfigured. */
|
|
6
|
+
function requireReleaseHealth(c) {
|
|
7
|
+
return c.get('container').releaseHealth ?? null;
|
|
8
|
+
}
|
|
9
|
+
const unavailable = (c) => c.json({ error: { code: 'unavailable', message: 'The Datadog integration is not configured' } }, 503);
|
|
10
|
+
/**
|
|
11
|
+
* Per-workspace settings for the post-release-health gate: the (single) Datadog
|
|
12
|
+
* connection (keys write-only, never read back) and the per-block monitor/SLO
|
|
13
|
+
* mappings the gate reads. Mounted under `/workspaces/:workspaceId`.
|
|
14
|
+
*/
|
|
15
|
+
export function releaseHealthController() {
|
|
16
|
+
const app = new Hono();
|
|
17
|
+
app.get('/datadog/connection', async (c) => {
|
|
18
|
+
const rh = requireReleaseHealth(c);
|
|
19
|
+
if (!rh)
|
|
20
|
+
return unavailable(c);
|
|
21
|
+
return c.json(await rh.service.getConnection(param(c, 'workspaceId')));
|
|
22
|
+
});
|
|
23
|
+
app.put('/datadog/connection', jsonBody(upsertDatadogConnectionSchema), async (c) => {
|
|
24
|
+
const rh = requireReleaseHealth(c);
|
|
25
|
+
if (!rh)
|
|
26
|
+
return unavailable(c);
|
|
27
|
+
return c.json(await rh.service.setConnection(param(c, 'workspaceId'), c.req.valid('json')));
|
|
28
|
+
});
|
|
29
|
+
app.delete('/datadog/connection', async (c) => {
|
|
30
|
+
const rh = requireReleaseHealth(c);
|
|
31
|
+
if (!rh)
|
|
32
|
+
return unavailable(c);
|
|
33
|
+
await rh.service.deleteConnection(param(c, 'workspaceId'));
|
|
34
|
+
return c.body(null, 204);
|
|
35
|
+
});
|
|
36
|
+
app.get('/release-health-configs', async (c) => {
|
|
37
|
+
const rh = requireReleaseHealth(c);
|
|
38
|
+
if (!rh)
|
|
39
|
+
return unavailable(c);
|
|
40
|
+
return c.json(await rh.service.listConfigs(param(c, 'workspaceId')));
|
|
41
|
+
});
|
|
42
|
+
app.put('/release-health-configs/:blockId', jsonBody(upsertReleaseHealthConfigSchema), async (c) => {
|
|
43
|
+
const rh = requireReleaseHealth(c);
|
|
44
|
+
if (!rh)
|
|
45
|
+
return unavailable(c);
|
|
46
|
+
const config = await rh.service.upsertConfig(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json'));
|
|
47
|
+
return c.json(config);
|
|
48
|
+
});
|
|
49
|
+
app.delete('/release-health-configs/:blockId', async (c) => {
|
|
50
|
+
const rh = requireReleaseHealth(c);
|
|
51
|
+
if (!rh)
|
|
52
|
+
return unavailable(c);
|
|
53
|
+
await rh.service.deleteConfig(param(c, 'workspaceId'), param(c, 'blockId'));
|
|
54
|
+
return c.body(null, 204);
|
|
55
|
+
});
|
|
56
|
+
return app;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ReleaseHealthController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReleaseHealthController.js","sourceRoot":"","sources":["../../../src/modules/releaseHealth/ReleaseHealthController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../../http/env.js';
|
|
3
|
+
/**
|
|
4
|
+
* Workspace-scoped requirements-review endpoints. The initial review runs an LLM inline and
|
|
5
|
+
* returns the entity. Incorporation, by contrast, is ASYNCHRONOUS: it records the human's
|
|
6
|
+
* intent on the parked run, signals the durable driver to fold + re-review in the
|
|
7
|
+
* background, and returns at once with the `incorporating` review so the SPA can return the
|
|
8
|
+
* user to the board — they are summoned again (a notification) only if input is needed.
|
|
9
|
+
* Mounted under `/workspaces/:workspaceId`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function requirementReviewController(): Hono<AppEnv>;
|
|
12
|
+
//# sourceMappingURL=RequirementReviewController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequirementReviewController.d.ts","sourceRoot":"","sources":["../../../src/modules/requirements/RequirementReviewController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAY/C;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAAC,MAAM,CAAC,CA8H1D"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { incorporateRequirementsSchema, replyReviewItemSchema, resolveRequirementsExceededSchema, updateReviewItemStatusSchema, } from '@cat-factory/contracts';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { param } from '../../http/params.js';
|
|
4
|
+
import { jsonBody } from '../../http/validation.js';
|
|
5
|
+
/** Resolve the requirements module or send a 503, returning null when unconfigured. */
|
|
6
|
+
function requireRequirements(c) {
|
|
7
|
+
return c.get('container').requirements ?? null;
|
|
8
|
+
}
|
|
9
|
+
const unavailable = (c) => c.json({ error: { code: 'unavailable', message: 'Requirements review is not configured' } }, 503);
|
|
10
|
+
/**
|
|
11
|
+
* Workspace-scoped requirements-review endpoints. The initial review runs an LLM inline and
|
|
12
|
+
* returns the entity. Incorporation, by contrast, is ASYNCHRONOUS: it records the human's
|
|
13
|
+
* intent on the parked run, signals the durable driver to fold + re-review in the
|
|
14
|
+
* background, and returns at once with the `incorporating` review so the SPA can return the
|
|
15
|
+
* user to the board — they are summoned again (a notification) only if input is needed.
|
|
16
|
+
* Mounted under `/workspaces/:workspaceId`.
|
|
17
|
+
*/
|
|
18
|
+
export function requirementReviewController() {
|
|
19
|
+
const app = new Hono();
|
|
20
|
+
// The current review for a block (null when none has been run yet).
|
|
21
|
+
app.get('/blocks/:blockId/requirement-review', async (c) => {
|
|
22
|
+
const requirements = requireRequirements(c);
|
|
23
|
+
if (!requirements)
|
|
24
|
+
return unavailable(c);
|
|
25
|
+
const review = await requirements.service.getForBlock(param(c, 'workspaceId'), param(c, 'blockId'));
|
|
26
|
+
return c.json(review);
|
|
27
|
+
});
|
|
28
|
+
// Run a fresh review of the block's collected requirements (replaces any prior).
|
|
29
|
+
// Routed through the execution service so the off-path surface honours the task's
|
|
30
|
+
// merge-preset knobs (iteration budget + tolerated severity) exactly like the gate.
|
|
31
|
+
app.post('/blocks/:blockId/requirement-review', async (c) => {
|
|
32
|
+
const requirements = requireRequirements(c);
|
|
33
|
+
if (!requirements)
|
|
34
|
+
return unavailable(c);
|
|
35
|
+
const review = await c
|
|
36
|
+
.get('container')
|
|
37
|
+
.executionService.reviewRequirements(param(c, 'workspaceId'), param(c, 'blockId'));
|
|
38
|
+
return c.json(review, 201);
|
|
39
|
+
});
|
|
40
|
+
// Answer a single review item.
|
|
41
|
+
app.post('/requirement-reviews/:reviewId/items/:itemId/reply', jsonBody(replyReviewItemSchema), async (c) => {
|
|
42
|
+
const requirements = requireRequirements(c);
|
|
43
|
+
if (!requirements)
|
|
44
|
+
return unavailable(c);
|
|
45
|
+
const review = await requirements.service.replyToItem(param(c, 'workspaceId'), param(c, 'reviewId'), param(c, 'itemId'), c.req.valid('json').reply);
|
|
46
|
+
return c.json(review);
|
|
47
|
+
});
|
|
48
|
+
// Set a review item's status (resolve / dismiss / reopen).
|
|
49
|
+
app.patch('/requirement-reviews/:reviewId/items/:itemId', jsonBody(updateReviewItemStatusSchema), async (c) => {
|
|
50
|
+
const requirements = requireRequirements(c);
|
|
51
|
+
if (!requirements)
|
|
52
|
+
return unavailable(c);
|
|
53
|
+
const review = await requirements.service.setItemStatus(param(c, 'workspaceId'), param(c, 'reviewId'), param(c, 'itemId'), c.req.valid('json').status);
|
|
54
|
+
return c.json(review);
|
|
55
|
+
});
|
|
56
|
+
// Incorporate the answers ASYNCHRONOUSLY: the durable driver folds them into one
|
|
57
|
+
// standard-format document and re-reviews it in the background. Optional `feedback` is the
|
|
58
|
+
// "do it differently" lever when redoing a merge. Returns the `incorporating` review at
|
|
59
|
+
// once (no LLM in the request) so the SPA returns the user to the board; a notification
|
|
60
|
+
// calls them back only if the re-review needs input. Blocks scoped (the review is resolved
|
|
61
|
+
// from the block) to match the other run-driving endpoints.
|
|
62
|
+
app.post('/blocks/:blockId/requirement-review/incorporate', jsonBody(incorporateRequirementsSchema), async (c) => {
|
|
63
|
+
const requirements = requireRequirements(c);
|
|
64
|
+
if (!requirements)
|
|
65
|
+
return unavailable(c);
|
|
66
|
+
const review = await c
|
|
67
|
+
.get('container')
|
|
68
|
+
.executionService.incorporateRequirements(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json').feedback);
|
|
69
|
+
return c.json(review);
|
|
70
|
+
});
|
|
71
|
+
// Re-review the incorporated document (one more reviewer pass). On convergence the
|
|
72
|
+
// parked run advances; otherwise the response carries the next cycle's findings (or the
|
|
73
|
+
// iteration-cap state). Returns the updated review.
|
|
74
|
+
app.post('/blocks/:blockId/requirement-review/re-review', async (c) => {
|
|
75
|
+
const requirements = requireRequirements(c);
|
|
76
|
+
if (!requirements)
|
|
77
|
+
return unavailable(c);
|
|
78
|
+
const review = await c
|
|
79
|
+
.get('container')
|
|
80
|
+
.executionService.reReviewRequirements(param(c, 'workspaceId'), param(c, 'blockId'));
|
|
81
|
+
return c.json(review);
|
|
82
|
+
});
|
|
83
|
+
// Proceed: settle the requirements (last incorporated doc wins downstream) and advance
|
|
84
|
+
// the parked run. Used when every finding is dismissed.
|
|
85
|
+
app.post('/blocks/:blockId/requirement-review/proceed', async (c) => {
|
|
86
|
+
const requirements = requireRequirements(c);
|
|
87
|
+
if (!requirements)
|
|
88
|
+
return unavailable(c);
|
|
89
|
+
const review = await c
|
|
90
|
+
.get('container')
|
|
91
|
+
.executionService.proceedRequirements(param(c, 'workspaceId'), param(c, 'blockId'));
|
|
92
|
+
return c.json(review);
|
|
93
|
+
});
|
|
94
|
+
// Resolve a review that hit its iteration cap: one more round / proceed anyway / stop
|
|
95
|
+
// and reset the task to phase zero. Returns the updated review.
|
|
96
|
+
app.post('/blocks/:blockId/requirement-review/resolve-exceeded', jsonBody(resolveRequirementsExceededSchema), async (c) => {
|
|
97
|
+
const requirements = requireRequirements(c);
|
|
98
|
+
if (!requirements)
|
|
99
|
+
return unavailable(c);
|
|
100
|
+
const review = await c
|
|
101
|
+
.get('container')
|
|
102
|
+
.executionService.resolveRequirementsExceeded(param(c, 'workspaceId'), param(c, 'blockId'), c.req.valid('json').choice);
|
|
103
|
+
return c.json(review);
|
|
104
|
+
});
|
|
105
|
+
return app;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=RequirementReviewController.js.map
|