@wardby/cli 0.6.0 → 0.8.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/.env.example +5 -5
- package/README.md +6 -1
- package/deploy/local/docker-compose.quickstart-coding.yml +19 -0
- package/dist/claude-coding-worker/driver.d.ts +33 -3
- package/dist/claude-coding-worker/driver.js +151 -21
- package/dist/claude-coding-worker/main.js +38 -6
- package/dist/claude-coding-worker/sdk.js +29 -2
- package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
- package/dist/claude-coding-worker/tool-socket.js +111 -0
- package/dist/claude-coding-worker/transcript.d.ts +18 -0
- package/dist/claude-coding-worker/transcript.js +77 -0
- package/dist/claude-plugin/command.d.ts +61 -0
- package/dist/claude-plugin/command.js +376 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +3 -1
- package/dist/cli.js +71 -13
- package/dist/coding/code-host.d.ts +16 -0
- package/dist/coding/code-host.js +60 -0
- package/dist/coding/continuation-wording.d.ts +35 -0
- package/dist/coding/continuation-wording.js +73 -0
- package/dist/coding/linked-issue-note.d.ts +23 -0
- package/dist/coding/linked-issue-note.js +47 -0
- package/dist/coding/mcp-token.d.ts +12 -0
- package/dist/coding/mcp-token.js +26 -0
- package/dist/coding/merge-wording.d.ts +28 -0
- package/dist/coding/merge-wording.js +78 -0
- package/dist/coding/pr-description-note.d.ts +9 -0
- package/dist/coding/pr-description-note.js +32 -0
- package/dist/coding/profile.d.ts +46 -126
- package/dist/coding/profile.js +45 -4
- package/dist/coding/protected-path-wording.d.ts +8 -0
- package/dist/coding/protected-path-wording.js +1 -1
- package/dist/coding/protocol.d.ts +264 -346
- package/dist/coding/protocol.js +237 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +17 -0
- package/dist/coding/registry/allowlist.d.ts +12 -0
- package/dist/coding/registry/allowlist.js +14 -1
- package/dist/coding/registry/audit-mode.d.ts +153 -0
- package/dist/coding/registry/audit-mode.js +304 -0
- package/dist/coding/registry/lockfile-shared.d.ts +36 -0
- package/dist/coding/registry/lockfile-shared.js +128 -0
- package/dist/coding/registry/lockfiles.js +1 -1
- package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
- package/dist/coding/registry/npm-lockfile-formats.js +41 -0
- package/dist/coding/registry/npm-lockfile.d.ts +8 -4
- package/dist/coding/registry/npm-lockfile.js +4 -6
- package/dist/coding/registry/npm.js +78 -8
- package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
- package/dist/coding/registry/pnpm-lockfile.js +189 -0
- package/dist/coding/registry/pypi-plan.d.ts +50 -0
- package/dist/coding/registry/pypi-plan.js +406 -0
- package/dist/coding/registry/pypi-requirements.d.ts +58 -0
- package/dist/coding/registry/pypi-requirements.js +155 -0
- package/dist/coding/registry/pypi.d.ts +3 -27
- package/dist/coding/registry/pypi.js +40 -154
- package/dist/coding/registry/refusal-hints.d.ts +20 -0
- package/dist/coding/registry/refusal-hints.js +61 -0
- package/dist/coding/registry/refusal-wording.d.ts +11 -0
- package/dist/coding/registry/refusal-wording.js +56 -0
- package/dist/coding/registry/report.d.ts +70 -8
- package/dist/coding/registry/report.js +112 -5
- package/dist/coding/registry/types.d.ts +58 -8
- package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
- package/dist/coding/registry/yarn-lockfile.js +367 -0
- package/dist/coding/services/catalog.d.ts +37 -351
- package/dist/coding/transcript/claude-code.d.ts +13 -0
- package/dist/coding/transcript/claude-code.js +273 -0
- package/dist/coding/transcript/download-protocol.d.ts +30 -0
- package/dist/coding/transcript/download-protocol.js +18 -0
- package/dist/coding/transcript/format.d.ts +20 -0
- package/dist/coding/transcript/format.js +32 -0
- package/dist/coding/transcript/recorder.d.ts +52 -0
- package/dist/coding/transcript/recorder.js +225 -0
- package/dist/coding/transcript/resume/checkout.d.ts +31 -0
- package/dist/coding/transcript/resume/checkout.js +203 -0
- package/dist/coding/transcript/resume/command.d.ts +17 -0
- package/dist/coding/transcript/resume/command.js +176 -0
- package/dist/coding/transcript/resume/download.d.ts +20 -0
- package/dist/coding/transcript/resume/download.js +153 -0
- package/dist/coding/transcript/resume/launch.d.ts +38 -0
- package/dist/coding/transcript/resume/launch.js +128 -0
- package/dist/coding/transcript/resume/session-file.d.ts +13 -0
- package/dist/coding/transcript/resume/session-file.js +79 -0
- package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
- package/dist/coding/transcript/resume/stand-in.js +49 -0
- package/dist/coding-worker/artifact.d.ts +8 -3
- package/dist/coding-worker/artifact.js +3 -1
- package/dist/coding-worker/debug-trace.d.ts +9 -6
- package/dist/coding-worker/debug-trace.js +16 -19
- package/dist/coding-worker/dependency-cache.d.mts +229 -0
- package/dist/coding-worker/dependency-cache.mjs +2123 -0
- package/dist/coding-worker/driver.d.ts +4 -3
- package/dist/coding-worker/driver.js +124 -39
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/main.js +5 -1
- package/dist/coding-worker/mcp-config.d.ts +27 -0
- package/dist/coding-worker/mcp-config.js +32 -0
- package/dist/coding-worker/sdk.d.ts +36 -0
- package/dist/coding-worker/sdk.js +28 -1
- package/dist/coding-worker/task-note.d.ts +11 -0
- package/dist/coding-worker/task-note.js +13 -0
- package/dist/coding-worker/types.d.ts +15 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/mcp-call-limit.d.ts +8 -0
- package/dist/config/mcp-call-limit.js +18 -0
- package/dist/config/mcp-servers.d.ts +8 -0
- package/dist/config/mcp-servers.js +12 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +92 -0
- package/dist/config/test-simulators.js +333 -0
- package/dist/config/tool-timeout.d.ts +1 -0
- package/dist/config/tool-timeout.js +18 -0
- package/dist/core/async-context.d.ts +2 -0
- package/dist/core/async-context.js +12 -0
- package/dist/core/budget-events.d.ts +108 -0
- package/dist/core/budget-events.js +346 -0
- package/dist/core/budget-groups.d.ts +50 -1
- package/dist/core/budget-groups.js +236 -27
- package/dist/core/budget-stopped-head.d.ts +46 -0
- package/dist/core/budget-stopped-head.js +81 -0
- package/dist/core/budget-topup.d.ts +51 -0
- package/dist/core/budget-topup.js +156 -0
- package/dist/core/budget-wording.d.ts +16 -2
- package/dist/core/budget-wording.js +40 -2
- package/dist/core/coding-mcp.d.ts +36 -0
- package/dist/core/coding-mcp.js +253 -0
- package/dist/core/coding-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -0
- package/dist/core/coding-repository.d.ts +46 -0
- package/dist/core/coding-repository.js +92 -0
- package/dist/core/cron.d.ts +19 -1
- package/dist/core/cron.js +17 -0
- package/dist/core/datastores.js +1 -1
- package/dist/core/deferred-coding.d.ts +14 -0
- package/dist/core/deferred-coding.js +62 -0
- package/dist/core/delegation-child.d.ts +25 -0
- package/dist/core/delegation-child.js +37 -0
- package/dist/core/delegation-slots.d.ts +27 -0
- package/dist/core/delegation-slots.js +44 -0
- package/dist/core/dispatch.d.ts +48 -2
- package/dist/core/dispatch.js +166 -66
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +169 -0
- package/dist/core/grants.d.ts +46 -8
- package/dist/core/grants.js +99 -8
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +291 -27
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +300 -22
- package/dist/core/issue-bridge.d.ts +50 -6
- package/dist/core/issue-bridge.js +124 -33
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +4 -10
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +58 -29
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +14 -1
- package/dist/core/lost-run-children.d.ts +6 -0
- package/dist/core/lost-run-children.js +32 -0
- package/dist/core/mark-ready.d.ts +34 -0
- package/dist/core/mark-ready.js +152 -0
- package/dist/core/markdown-code.d.ts +8 -0
- package/dist/core/markdown-code.js +107 -0
- package/dist/core/mcp-client/client.d.ts +47 -0
- package/dist/core/mcp-client/client.js +141 -0
- package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
- package/dist/core/mcp-client/jsonrpc.js +54 -0
- package/dist/core/mcp-client/results.d.ts +13 -0
- package/dist/core/mcp-client/results.js +42 -0
- package/dist/core/mcp-servers.d.ts +90 -0
- package/dist/core/mcp-servers.js +230 -0
- package/dist/core/mcp-tools.d.ts +108 -0
- package/dist/core/mcp-tools.js +287 -0
- package/dist/core/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +44 -18
- package/dist/core/notification-dispatcher.js +2 -1
- package/dist/core/notification-templates.d.ts +1 -7
- package/dist/core/notification-templates.js +36 -2
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +4 -3
- package/dist/core/reconciler.js +8 -1
- package/dist/core/related-pull-requests.d.ts +11 -3
- package/dist/core/related-pull-requests.js +49 -20
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/review-fix.d.ts +1 -1
- package/dist/core/review-fix.js +4 -3
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +3 -0
- package/dist/core/review-host-tools.js +102 -14
- package/dist/core/review-reads.d.ts +55 -0
- package/dist/core/review-reads.js +233 -0
- package/dist/core/run-status.d.ts +12 -0
- package/dist/core/run-status.js +12 -0
- package/dist/core/runner.d.ts +145 -49
- package/dist/core/runner.js +719 -216
- package/dist/core/schedule-start.d.ts +12 -0
- package/dist/core/schedule-start.js +14 -0
- package/dist/core/secret-broker-config.d.ts +12 -74
- package/dist/core/secret-broker-config.js +1 -1
- package/dist/core/secret-guard.d.ts +49 -0
- package/dist/core/secret-guard.js +119 -0
- package/dist/core/secret-guarded-stores.d.ts +12 -0
- package/dist/core/secret-guarded-stores.js +41 -0
- package/dist/core/secret-spans.d.ts +50 -0
- package/dist/core/secret-spans.js +94 -0
- package/dist/core/secrets.d.ts +11 -1
- package/dist/core/secrets.js +27 -1
- package/dist/core/serializable-retry.d.ts +18 -0
- package/dist/core/serializable-retry.js +43 -0
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/tool-admin.d.ts +5 -1
- package/dist/core/tool-admin.js +7 -2
- package/dist/core/tool-names.d.ts +13 -0
- package/dist/core/tool-names.js +20 -0
- package/dist/core/webhooks.d.ts +4 -0
- package/dist/core/webhooks.js +68 -49
- package/dist/core/workflow-events.d.ts +14 -2
- package/dist/core/workflow-events.js +4 -0
- package/dist/core/workflow-run-events.d.ts +5 -3
- package/dist/core/workflow-run-events.js +45 -9
- package/dist/core/zod-json-schema.d.ts +4 -0
- package/dist/core/zod-json-schema.js +39 -0
- package/dist/core/zod3-window.d.ts +35 -0
- package/dist/core/zod3-window.js +124 -0
- package/dist/generated/prisma/browser.d.ts +65 -3
- package/dist/generated/prisma/client.d.ts +65 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +266 -106
- package/dist/generated/prisma/enums.d.ts +10 -0
- package/dist/generated/prisma/enums.js +8 -0
- package/dist/generated/prisma/internal/class.d.ts +110 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +957 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +166 -2
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +174 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +166 -2
- package/dist/generated/prisma/models/Agent.d.ts +377 -8
- package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
- package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +81 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +228 -7
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +232 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1712 -1
- package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
- package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
- package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
- package/dist/generated/prisma/models/HostProvider.js +1 -0
- package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
- package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
- package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
- package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
- package/dist/generated/prisma/models/McpServer.js +1 -0
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +77 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- package/dist/generated/prisma/models/Principal.d.ts +167 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
- package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
- package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
- package/dist/generated/prisma/models/Run.d.ts +738 -2
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
- package/dist/generated/prisma/models/RunTranscript.js +1 -0
- package/dist/generated/prisma/models/Secret.d.ts +387 -0
- package/dist/generated/prisma/models/Tool.d.ts +223 -1
- package/dist/generated/prisma/models.d.ts +10 -0
- package/dist/help/search.js +12 -3
- package/dist/help-index.json +2033 -110
- package/dist/import/create.js +48 -4
- package/dist/import/neutral-schema.d.ts +51 -281
- package/dist/import/neutral-schema.js +7 -4
- package/dist/knowledge/check.d.ts +1 -1
- package/dist/knowledge/cli.d.ts +11 -1
- package/dist/knowledge/cli.js +37 -4
- package/dist/knowledge/concept.d.ts +3 -19
- package/dist/knowledge/location.d.ts +31 -0
- package/dist/knowledge/location.js +78 -0
- package/dist/mcp/auth/access.d.ts +10 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/grants-cli.d.ts +6 -4
- package/dist/mcp/auth/grants-cli.js +42 -3
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/resource-server.d.ts +3 -1
- package/dist/mcp/auth/resource-server.js +17 -2
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
- package/dist/mcp/context.d.ts +3 -0
- package/dist/mcp/host-events/github-ingress.d.ts +2 -0
- package/dist/mcp/host-events/github-ingress.js +2 -1
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +69 -10
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +33 -14
- package/dist/mcp/tools/agents.d.ts +4 -0
- package/dist/mcp/tools/agents.js +295 -28
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +73 -29
- package/dist/mcp/tools/host-providers.d.ts +2 -0
- package/dist/mcp/tools/host-providers.js +215 -0
- package/dist/mcp/tools/mcp-servers.d.ts +26 -0
- package/dist/mcp/tools/mcp-servers.js +481 -0
- package/dist/mcp/tools/memory.js +11 -1
- package/dist/mcp/tools/notification-channels.js +2 -2
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/repositories.js +65 -12
- package/dist/mcp/tools/run-access.d.ts +16 -0
- package/dist/mcp/tools/run-access.js +25 -0
- package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
- package/dist/mcp/tools/run-transcript-download.js +129 -0
- package/dist/mcp/tools/run-transcript.d.ts +19 -0
- package/dist/mcp/tools/run-transcript.js +70 -0
- package/dist/mcp/tools/runs.js +209 -27
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-elicitation-form.js +5 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -61
- package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
- package/dist/mcp/tools/secret-elicitation.js +25 -2
- package/dist/mcp/tools/secrets.js +40 -6
- package/dist/mcp/tools/stop-run.d.ts +2 -0
- package/dist/mcp/tools/stop-run.js +82 -0
- package/dist/mcp/tools/subagents.js +2 -2
- package/dist/mcp/tools/tools.d.ts +7 -5
- package/dist/mcp/tools/tools.js +64 -16
- package/dist/mcp/tools/trigger.js +28 -6
- package/dist/mcp/transport/http-limits.d.ts +2 -0
- package/dist/mcp/transport/http-limits.js +6 -2
- package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
- package/dist/mcp/transport/stdio-link-host.js +67 -0
- package/dist/mcp/transport/streamable-http.d.ts +13 -0
- package/dist/mcp/transport/streamable-http.js +41 -1
- package/dist/mcp/webhooks/ingress.js +10 -0
- package/dist/native-worker/docker-launcher.d.ts +38 -2
- package/dist/native-worker/docker-launcher.js +65 -5
- package/dist/native-worker/gateway-server.d.ts +55 -3
- package/dist/native-worker/gateway-server.js +152 -34
- package/dist/native-worker/gateway.d.ts +29 -1
- package/dist/native-worker/gateway.js +74 -4
- package/dist/native-worker/http-server.d.ts +7 -1
- package/dist/native-worker/http-server.js +62 -7
- package/dist/native-worker/http-transport.js +1 -1
- package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
- package/dist/native-worker/kubernetes-launcher.js +43 -3
- package/dist/native-worker/launch.d.ts +18 -1
- package/dist/native-worker/launch.js +6 -1
- package/dist/native-worker/ledger.d.ts +24 -4
- package/dist/native-worker/ledger.js +62 -8
- package/dist/native-worker/loopback.js +3 -8
- package/dist/native-worker/main.d.ts +2 -1
- package/dist/native-worker/main.js +14 -3
- package/dist/native-worker/protocol.d.ts +130 -577
- package/dist/native-worker/protocol.js +51 -2
- package/dist/native-worker/sandbox-executor.d.ts +17 -2
- package/dist/native-worker/sandbox-executor.js +78 -4
- package/dist/native-worker/stderr-redaction.d.ts +77 -0
- package/dist/native-worker/stderr-redaction.js +237 -0
- package/dist/native-worker/stdio.d.ts +1 -1
- package/dist/native-worker/stdio.js +6 -5
- package/dist/native-worker/warm-pool.d.ts +2 -2
- package/dist/native-worker/warm-pool.js +4 -4
- package/dist/native-worker/worker.js +28 -2
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/self-hosted.d.ts +1 -1
- package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
- package/dist/providers/coding-proxy/capability-hash.js +5 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
- package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
- package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
- package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
- package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
- package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
- package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
- package/dist/providers/coding-proxy/hold.d.ts +32 -0
- package/dist/providers/coding-proxy/hold.js +86 -0
- package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
- package/dist/providers/coding-proxy/interrupted.js +104 -0
- package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
- package/dist/providers/coding-proxy/mcp-route.js +166 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -2
- package/dist/providers/coding-proxy/memory-ledger.js +99 -8
- package/dist/providers/coding-proxy/metering.d.ts +16 -0
- package/dist/providers/coding-proxy/metering.js +27 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +16 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +209 -69
- package/dist/providers/coding-proxy/proxy.d.ts +21 -2
- package/dist/providers/coding-proxy/proxy.js +300 -48
- package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
- package/dist/providers/coding-proxy/registry/audit.js +94 -17
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
- package/dist/providers/coding-proxy/registry/plan.js +201 -48
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
- package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
- package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
- package/dist/providers/coding-proxy/registry/service.js +579 -112
- package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
- package/dist/providers/coding-proxy/registry/store.js +54 -1
- package/dist/providers/coding-proxy/runtime.d.ts +10 -0
- package/dist/providers/coding-proxy/runtime.js +109 -16
- package/dist/providers/coding-proxy/server.d.ts +9 -1
- package/dist/providers/coding-proxy/server.js +55 -1
- package/dist/providers/coding-proxy/types.d.ts +78 -1
- package/dist/providers/datastore/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +17 -2
- package/dist/providers/engine/types.js +17 -0
- package/dist/providers/executor/composition.d.ts +10 -3
- package/dist/providers/executor/composition.js +52 -7
- package/dist/providers/executor/container.d.ts +394 -9
- package/dist/providers/executor/container.js +1210 -96
- package/dist/providers/executor/dbos-status.d.ts +31 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +50 -1
- package/dist/providers/executor/dbos.js +207 -20
- package/dist/providers/executor/deferred.d.ts +12 -24
- package/dist/providers/executor/deferred.js +10 -29
- package/dist/providers/executor/in-process.d.ts +9 -1
- package/dist/providers/executor/in-process.js +14 -4
- package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
- package/dist/providers/executor/linked-issue-reader.js +30 -0
- package/dist/providers/executor/routing.d.ts +2 -0
- package/dist/providers/executor/routing.js +4 -0
- package/dist/providers/executor/types.d.ts +13 -0
- package/dist/providers/host-tools/invoke.d.ts +37 -0
- package/dist/providers/host-tools/invoke.js +117 -0
- package/dist/providers/host-tools/operations.d.ts +65 -0
- package/dist/providers/host-tools/operations.js +149 -0
- package/dist/providers/host-tools/registry.d.ts +79 -0
- package/dist/providers/host-tools/registry.js +362 -0
- package/dist/providers/host-tools/request-guard.d.ts +17 -0
- package/dist/providers/host-tools/request-guard.js +99 -0
- package/dist/providers/host-tools/self-test.d.ts +64 -0
- package/dist/providers/host-tools/self-test.js +142 -0
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/issue-tracker/types.d.ts +17 -0
- package/dist/providers/issue-tracker/types.js +39 -1
- package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
- package/dist/providers/jobs/claude-tool-setup.js +5 -2
- package/dist/providers/jobs/docker-isolation.d.ts +10 -2
- package/dist/providers/jobs/docker-isolation.js +47 -8
- package/dist/providers/jobs/docker.d.ts +9 -0
- package/dist/providers/jobs/docker.js +60 -11
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
- package/dist/providers/jobs/kubernetes-api.js +10 -0
- package/dist/providers/jobs/kubernetes-client.js +10 -1
- package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
- package/dist/providers/jobs/kubernetes-isolation.js +32 -3
- package/dist/providers/jobs/kubernetes.d.ts +11 -1
- package/dist/providers/jobs/kubernetes.js +111 -17
- package/dist/providers/jobs/types.d.ts +39 -0
- package/dist/providers/jobs/types.js +13 -1
- package/dist/providers/llm/anthropic.js +5 -1
- package/dist/providers/llm/bedrock.d.ts +0 -12
- package/dist/providers/llm/bedrock.js +4 -0
- package/dist/providers/llm/claude-messages.d.ts +3 -1
- package/dist/providers/llm/claude-messages.js +4 -1
- package/dist/providers/llm/claude-provider.d.ts +2 -2
- package/dist/providers/llm/claude-provider.js +2 -2
- package/dist/providers/llm/openai.d.ts +2 -2
- package/dist/providers/llm/openai.js +6 -2
- package/dist/providers/llm/routing.d.ts +2 -2
- package/dist/providers/llm/routing.js +2 -2
- package/dist/providers/llm/types.d.ts +12 -2
- package/dist/providers/review-host/github-events.d.ts +9 -1
- package/dist/providers/review-host/github-events.js +34 -12
- package/dist/providers/review-host/github.d.ts +29 -2
- package/dist/providers/review-host/github.js +224 -29
- package/dist/providers/review-host/local.d.ts +8 -4
- package/dist/providers/review-host/local.js +49 -31
- package/dist/providers/review-host/patch-pages.d.ts +41 -0
- package/dist/providers/review-host/patch-pages.js +176 -0
- package/dist/providers/review-host/review-format.d.ts +19 -1
- package/dist/providers/review-host/review-format.js +38 -7
- package/dist/providers/review-host/types.d.ts +140 -6
- package/dist/providers/review-host/types.js +9 -1
- package/dist/providers/storage/gcs.d.ts +63 -0
- package/dist/providers/storage/gcs.js +69 -0
- package/dist/providers/storage/index.d.ts +15 -0
- package/dist/providers/storage/index.js +14 -0
- package/dist/providers/storage/local.d.ts +24 -0
- package/dist/providers/storage/local.js +92 -0
- package/dist/providers/storage/meter.d.ts +14 -0
- package/dist/providers/storage/meter.js +34 -0
- package/dist/providers/storage/s3.d.ts +41 -0
- package/dist/providers/storage/s3.js +107 -0
- package/dist/providers/storage/types.d.ts +37 -3
- package/dist/providers/storage/types.js +21 -4
- package/dist/providers/vcs/git.d.ts +39 -4
- package/dist/providers/vcs/git.js +339 -26
- package/dist/providers/vcs/github-remote.d.ts +26 -3
- package/dist/providers/vcs/github-remote.js +124 -14
- package/dist/providers/vcs/github.d.ts +183 -44
- package/dist/providers/vcs/github.js +455 -56
- package/dist/providers/vcs/index.d.ts +1 -1
- package/dist/providers/vcs/index.js +9 -2
- package/dist/providers/vcs/pr-description.d.ts +127 -0
- package/dist/providers/vcs/pr-description.js +270 -0
- package/dist/providers/vcs/remote.d.ts +37 -1
- package/dist/providers/vcs/remote.js +7 -1
- package/dist/providers/vcs/routing.d.ts +16 -8
- package/dist/providers/vcs/routing.js +27 -6
- package/dist/providers/vcs/types.d.ts +150 -5
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- package/dist/quickstart/index.d.ts +5 -0
- package/dist/quickstart/index.js +21 -0
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +6 -6
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/eval-core.d.ts +12 -2
- package/dist/sandbox/eval-core.js +20 -4
- package/dist/sandbox/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +5 -0
- package/dist/sandbox/host-functions.js +13 -13
- package/dist/sandbox/limits.d.ts +4 -1
- package/dist/sandbox/limits.js +4 -1
- package/dist/sandbox/run-in-sandbox.d.ts +6 -0
- package/dist/sandbox/run-in-sandbox.js +14 -2
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +1 -1
- package/dist/sandbox/secret-broker.d.ts +1 -0
- package/dist/sandbox/secret-broker.js +4 -5
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/tool-timeout.d.ts +32 -0
- package/dist/sandbox/tool-timeout.js +52 -0
- package/dist/sandbox/user-tool.d.ts +8 -1
- package/dist/sandbox/user-tool.js +9 -3
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +8 -1
- package/dist/viewer/api-schema.d.ts +349 -2627
- package/dist/viewer/api-schema.js +7 -0
- package/dist/viewer/build-schemas.js +6 -2
- package/dist/viewer/graph.js +2 -1
- package/dist/viewer/openapi.js +2 -4
- package/dist/wardby-bin.js +15 -0
- package/docs/README.md +11 -1
- package/docs/agent-recipes.md +95 -24
- package/docs/architecture-runtime.md +1 -1
- package/docs/claude-code-plugin.md +164 -0
- package/docs/code-review-agents.md +557 -41
- package/docs/coding-agent-setup.md +566 -8
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +24 -2
- package/docs/coding-worker-isolation.md +183 -37
- package/docs/debugging-agent-runs.md +242 -0
- package/docs/getting-started-gke.md +129 -141
- package/docs/getting-started-identity-provider.md +53 -38
- package/docs/getting-started.md +17 -0
- package/docs/host-providers.md +294 -0
- package/docs/jira-agents.md +17 -8
- package/docs/knowledge/blob-not-found-semantics.md +41 -0
- package/docs/knowledge/bounded-file-descriptor.md +52 -0
- package/docs/knowledge/delegation-admission-slots.md +52 -0
- package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
- package/docs/knowledge/import-rename-target.md +52 -0
- package/docs/knowledge/index.md +57 -0
- package/docs/knowledge/log.md +9 -0
- package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
- package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
- package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
- package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
- package/docs/knowledge/overview-cli.md +74 -0
- package/docs/knowledge/overview-coding-proxy.md +72 -0
- package/docs/knowledge/overview-coding.md +72 -0
- package/docs/knowledge/overview-config.md +60 -0
- package/docs/knowledge/overview-core.md +72 -0
- package/docs/knowledge/overview-deploy.md +83 -0
- package/docs/knowledge/overview-mcp.md +61 -0
- package/docs/knowledge/overview-prisma.md +72 -0
- package/docs/knowledge/overview-providers.md +89 -0
- package/docs/knowledge/overview-sandbox.md +83 -0
- package/docs/knowledge/overview-surfaces.md +83 -0
- package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
- package/docs/knowledge/proxy-settlement-projections.md +41 -0
- package/docs/knowledge/run-pricing-first-writer.md +43 -0
- package/docs/knowledge/schedule-claim-transaction.md +41 -0
- package/docs/knowledge/secret-entry-replica-contract.md +52 -0
- package/docs/knowledge/terminal-run-first-writer.md +41 -0
- package/docs/knowledge/transactional-agent-authorization.md +52 -0
- package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
- package/docs/knowledge/warm-input-publication.md +30 -0
- package/docs/knowledge/workspace-staging-failure.md +54 -0
- package/docs/knowledge.md +54 -14
- package/docs/mcp-servers.md +254 -0
- package/docs/native-sandbox.md +143 -31
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +139 -29
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +45 -10
- package/docs/viewer-api.md +6 -0
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +28 -2
- package/help/agent-recipes.md +33 -2
- package/help/architecture-agent.md +11 -6
- package/help/brokered-secrets.md +3 -0
- package/help/build-claude-code-image.md +1 -1
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- package/help/claude-code-run-pane.md +40 -0
- package/help/code-review-agents.md +177 -6
- package/help/coding-packages.md +156 -6
- package/help/cost-attribution.md +9 -5
- package/help/creating-agents.md +14 -1
- package/help/dependency-cache.md +143 -0
- package/help/deploy-gke.md +15 -8
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-mcp-pins-unavailable.md +35 -0
- package/help/errors/coding-stream-quota-exceeded.md +33 -0
- package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
- package/help/errors/continuation-closed.md +9 -12
- package/help/errors/database-auth-invalid.md +1 -1
- package/help/errors/delegation-conflict.md +24 -0
- package/help/errors/file-list-truncated.md +45 -0
- package/help/errors/full-read-required.md +49 -0
- package/help/errors/github-account-not-allowed.md +4 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/host-provider-error.md +40 -0
- package/help/errors/host-tool-failed.md +36 -0
- package/help/errors/mcp-call-limit.md +22 -0
- package/help/errors/mcp-call-timeout.md +22 -0
- package/help/errors/mcp-server-auth-failed.md +22 -0
- package/help/errors/mcp-server-credentials-unavailable.md +45 -0
- package/help/errors/mcp-server-error.md +28 -0
- package/help/errors/mcp-server-unreachable.md +22 -0
- package/help/errors/mcp-servers-off.md +21 -0
- package/help/errors/mcp-tool-not-allowed.md +26 -0
- package/help/errors/mcp-tool-removed.md +22 -0
- package/help/errors/mcp-unavailable.md +25 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-capacity.md +1 -1
- package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
- package/help/errors/native-sandbox-docker-failed.md +1 -1
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
- package/help/errors/native-sandbox-image-not-pinned.md +1 -1
- package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-network-unenforced.md +1 -1
- package/help/errors/native-sandbox-requires-catalog.md +1 -1
- package/help/errors/native-sandbox-unavailable.md +1 -1
- package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
- package/help/errors/native-sandbox-worker-exited.md +4 -3
- package/help/errors/native-sandbox-worker-lost.md +1 -1
- package/help/errors/native-sandbox-worker-unready.md +1 -1
- package/help/errors/package-not-allowed-pending.md +52 -0
- package/help/errors/package-not-allowed.md +51 -0
- package/help/errors/package-refusals.md +43 -0
- package/help/errors/patch-cursor-malformed.md +31 -0
- package/help/errors/repository-not-listed.md +36 -0
- package/help/errors/repository-required.md +36 -0
- package/help/errors/run-lost.md +39 -0
- package/help/errors/run-transcript-download.md +44 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/target-merge.md +40 -0
- package/help/errors/tool-timeout.md +38 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/host-providers.md +40 -0
- package/help/identity-and-access.md +6 -1
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +1 -1
- package/help/low-power-mode.md +7 -1
- package/help/mcp-servers.md +73 -0
- package/help/mcp.md +7 -2
- package/help/merge-order-check.md +5 -0
- package/help/native-capabilities.md +55 -1
- package/help/native-sandbox.md +16 -2
- package/help/operating-agents.md +21 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +17 -10
- package/help/repo-instructions-and-skills.md +3 -1
- package/help/resume-runs-locally.md +134 -0
- package/help/review-fix-rounds.md +33 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +19 -5
- package/help/status-comments.md +31 -0
- package/help/stop-run.md +58 -0
- package/help/troubleshooting/budgets.md +28 -0
- package/help/troubleshooting/coding-workers.md +86 -7
- package/help/troubleshooting/debugging-agent-runs.md +29 -0
- package/package.json +18 -10
- package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
- package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
- package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
- package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
- package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
- package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
- package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
- package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
- package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
- package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
- package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
- package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
- package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
- package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
- package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
- package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
- package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
- package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
- package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
- package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
- package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
- package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
- package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
- package/prisma/schema.prisma +468 -109
- package/scripts/git-askpass.sh +1 -1
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
import type { PackageAllowlist } from "../../../coding/registry/allowlist.js";
|
|
2
|
+
import type { AuditAdvisory, AuditRelation, PackageAuditMode, PackageAuditVerdict } from "../../../coding/registry/audit-mode.js";
|
|
2
3
|
import type { DeclaredDependency, FileDependency } from "../../../coding/registry/types.js";
|
|
3
4
|
export interface RegistryRunContext {
|
|
4
5
|
runId: string;
|
|
5
6
|
deadlineAt: Date;
|
|
6
7
|
allowlist: PackageAllowlist;
|
|
7
8
|
policy: unknown;
|
|
9
|
+
/** The run's repository (CodingRun.repository), a cache-key input. */
|
|
10
|
+
repository: string;
|
|
11
|
+
/** The image whose environment the install runs in: CodingRun.toolImage ?? workerImage; null when neither is recorded. */
|
|
12
|
+
cacheImage: string | null;
|
|
13
|
+
/** Whether the run's agent enabled the dependency cache, fixed at dispatch (CodingRun.dependencyCache). */
|
|
14
|
+
dependencyCache: boolean;
|
|
15
|
+
/** Package audit mode, fixed at dispatch (CodingRun.packageAuditMode); null = normal enforcement. */
|
|
16
|
+
packageAudit: PackageAuditMode | null;
|
|
17
|
+
}
|
|
18
|
+
/** A coding proxy session's dependency cache state (CodingProxySession). */
|
|
19
|
+
export interface DependencyCacheSessionState {
|
|
20
|
+
/** Lockfile hashes this session's plans approved with no refusals, while unsealed. */
|
|
21
|
+
lockHashes: string[];
|
|
22
|
+
/** When the run's dependency step ended; after it the cache refuses the session. */
|
|
23
|
+
sealedAt: Date | null;
|
|
24
|
+
/** When the session was created: the upload window starts here. */
|
|
25
|
+
createdAt: Date;
|
|
8
26
|
}
|
|
9
27
|
export interface RegistryFetchRecord {
|
|
10
28
|
runId: string;
|
|
@@ -31,6 +49,32 @@ export interface ApprovedVersion {
|
|
|
31
49
|
name: string;
|
|
32
50
|
version: string;
|
|
33
51
|
integrity: string;
|
|
52
|
+
/** Blocking advisories the run's accepted set waived for this version,
|
|
53
|
+
* when the plan kept it only by that waiver; absent or empty otherwise. */
|
|
54
|
+
acceptedAdvisories?: readonly string[];
|
|
55
|
+
/** Audit-mode plans only: why this approval is audited (outside the
|
|
56
|
+
* allowlist, or kept past advisories in full mode). Absent = a normal approval. */
|
|
57
|
+
audit?: PackageAuditVerdict;
|
|
58
|
+
}
|
|
59
|
+
/** What a download of a plan-approved version needs. */
|
|
60
|
+
export interface ApprovedDownload {
|
|
61
|
+
integrity: string;
|
|
62
|
+
downloadUrl: string;
|
|
63
|
+
/** Advisories the approval waived (empty when none). */
|
|
64
|
+
acceptedAdvisories: string[];
|
|
65
|
+
/** The approval's audit verdict; absent for a normal approval. */
|
|
66
|
+
audit?: PackageAuditVerdict;
|
|
67
|
+
}
|
|
68
|
+
/** One RegistryAuditRecord: a version a run's registry served only because of package audit mode. */
|
|
69
|
+
export interface RegistryAuditInsert {
|
|
70
|
+
runId: string;
|
|
71
|
+
ecosystem: string;
|
|
72
|
+
name: string;
|
|
73
|
+
version: string;
|
|
74
|
+
relation: AuditRelation;
|
|
75
|
+
via?: string;
|
|
76
|
+
sizeBytes?: number;
|
|
77
|
+
advisories: readonly AuditAdvisory[];
|
|
34
78
|
}
|
|
35
79
|
/** One exact version a lockfile plan definitively refused for a run. */
|
|
36
80
|
export interface PlanRefusedVersion {
|
|
@@ -52,13 +96,25 @@ export interface PlanRefusedVersion {
|
|
|
52
96
|
export declare function extraAllowanceName(name: string, extra: string): string;
|
|
53
97
|
/** The extra in an allowance row name for `name`, or null when the row is not one of its extras. */
|
|
54
98
|
export declare function extraOfAllowanceName(rowName: string, name: string): string | null;
|
|
99
|
+
/** The `auditedVia` of an audited allowance whose relation a lockfile plan
|
|
100
|
+
* could not tell (`unknown`): no package name is empty. */
|
|
101
|
+
export declare const AUDITED_VIA_UNKNOWN = "";
|
|
55
102
|
/** Run-scoped store over the registry-only token session lookup and the
|
|
56
103
|
* RegistryAllowance/RegistryFetch tables (Task 5). Backs the registry proxy:
|
|
57
104
|
* it never sees the model capability, only the derived registry token. */
|
|
58
105
|
export interface RegistryStore {
|
|
59
106
|
findRunByRegistryTokenHash(hash: string, now: Date): Promise<RegistryRunContext | null>;
|
|
60
107
|
isAllowedDependency(runId: string, ecosystem: string, name: string): Promise<boolean>;
|
|
108
|
+
/** The run's allowance of `name` (null = none): `auditedVia` is the audited package that declared it,
|
|
109
|
+
* AUDITED_VIA_UNKNOWN when no one is known to, or null. */
|
|
110
|
+
findAllowance(runId: string, ecosystem: string, name: string): Promise<{
|
|
111
|
+
auditedVia: string | null;
|
|
112
|
+
} | null>;
|
|
61
113
|
addAllowances(runId: string, ecosystem: string, names: readonly string[]): Promise<void>;
|
|
114
|
+
/** Like addAllowances, each name tagged with the audited package that declared it; existing rows are kept. */
|
|
115
|
+
addAuditedAllowances(runId: string, ecosystem: string, names: readonly string[], auditedVia: string): Promise<void>;
|
|
116
|
+
/** Insert-only; a row for the same run/ecosystem/name/version already present is kept. */
|
|
117
|
+
recordAudit(record: RegistryAuditInsert): Promise<void>;
|
|
62
118
|
/** The extras the run allows for `name` (normalized, sorted). */
|
|
63
119
|
allowedExtras(runId: string, ecosystem: string, name: string): Promise<string[]>;
|
|
64
120
|
/** Records extras the run allows for each package (an existing one is kept). */
|
|
@@ -73,6 +129,10 @@ export interface RegistryStore {
|
|
|
73
129
|
listFetches(runId: string): Promise<(RegistryFetchRecord & {
|
|
74
130
|
createdAt: Date;
|
|
75
131
|
})[]>;
|
|
132
|
+
/** The run's refused rows recorded at or after `since`, newest first, at most `limit`. */
|
|
133
|
+
listRecentRefusals(runId: string, since: Date, limit: number): Promise<(RegistryFetchRecord & {
|
|
134
|
+
createdAt: Date;
|
|
135
|
+
})[]>;
|
|
76
136
|
/** Stored facts for these versions (any not stored are absent). */
|
|
77
137
|
getVersionFacts(ecosystem: string, versions: readonly {
|
|
78
138
|
name: string;
|
|
@@ -83,11 +143,9 @@ export interface RegistryStore {
|
|
|
83
143
|
/** Approves exact versions for the run (an existing approval is kept). */
|
|
84
144
|
approveVersions(runId: string, ecosystem: string, versions: readonly ApprovedVersion[]): Promise<void>;
|
|
85
145
|
/** The run's approval of this exact version, with its download URL (from
|
|
86
|
-
* the version's fact), or
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
downloadUrl: string;
|
|
90
|
-
} | null>;
|
|
146
|
+
* the version's fact) and any advisories it was approved by waiving, or
|
|
147
|
+
* null. */
|
|
148
|
+
findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<ApprovedDownload | null>;
|
|
91
149
|
/** Stores the run's plan refusals (an existing one is kept). */
|
|
92
150
|
refusePlanVersions(runId: string, ecosystem: string, versions: readonly PlanRefusedVersion[]): Promise<void>;
|
|
93
151
|
/** The run's plan refusal of this exact version, or null. */
|
|
@@ -96,12 +154,21 @@ export interface RegistryStore {
|
|
|
96
154
|
reason: string;
|
|
97
155
|
publishedAt: Date | null;
|
|
98
156
|
} | null>;
|
|
157
|
+
/** Adds a lockfile hash to the run's session, atomically and only while
|
|
158
|
+
* the session is unsealed, does not already hold it, and holds fewer
|
|
159
|
+
* than `max`; otherwise does nothing. */
|
|
160
|
+
recordDependencyCacheLockHash(runId: string, lockHash: string, max: number): Promise<void>;
|
|
99
161
|
}
|
|
100
162
|
/** In-memory adapter for tests. `contexts` is settable directly so tests can
|
|
101
163
|
* seed a run without going through a full proxy session. */
|
|
102
164
|
export declare class MemoryRegistryStore implements RegistryStore {
|
|
103
165
|
readonly contexts: Map<string, RegistryRunContext>;
|
|
104
166
|
readonly allowances: Set<string>;
|
|
167
|
+
/** `runId\0ecosystem\0name` -> the audited package that declared the allowance (first writer). */
|
|
168
|
+
readonly auditedVia: Map<string, string>;
|
|
169
|
+
readonly audits: (RegistryAuditInsert & {
|
|
170
|
+
createdAt: Date;
|
|
171
|
+
})[];
|
|
105
172
|
readonly fetches: (RegistryFetchRecord & {
|
|
106
173
|
createdAt: Date;
|
|
107
174
|
})[];
|
|
@@ -111,9 +178,16 @@ export declare class MemoryRegistryStore implements RegistryStore {
|
|
|
111
178
|
readonly approvals: Map<string, ApprovedVersion>;
|
|
112
179
|
/** `runId\0ecosystem\0name\0version` -> plan refusal. */
|
|
113
180
|
readonly planRefusals: Map<string, PlanRefusedVersion>;
|
|
181
|
+
/** runId -> dependency cache session state (shareable with the cache's memory store). */
|
|
182
|
+
readonly cacheSessions: Map<string, DependencyCacheSessionState>;
|
|
114
183
|
findRunByRegistryTokenHash(hash: string, now: Date): Promise<RegistryRunContext | null>;
|
|
115
184
|
isAllowedDependency(runId: string, ecosystem: string, name: string): Promise<boolean>;
|
|
185
|
+
findAllowance(runId: string, ecosystem: string, name: string): Promise<{
|
|
186
|
+
auditedVia: string | null;
|
|
187
|
+
} | null>;
|
|
116
188
|
addAllowances(runId: string, ecosystem: string, names: readonly string[]): Promise<void>;
|
|
189
|
+
addAuditedAllowances(runId: string, ecosystem: string, names: readonly string[], auditedVia: string): Promise<void>;
|
|
190
|
+
recordAudit(record: RegistryAuditInsert): Promise<void>;
|
|
117
191
|
allowedExtras(runId: string, ecosystem: string, name: string): Promise<string[]>;
|
|
118
192
|
addExtraAllowances(runId: string, ecosystem: string, dependencies: readonly FileDependency[]): Promise<void>;
|
|
119
193
|
recordFetch(record: RegistryFetchRecord): Promise<void>;
|
|
@@ -125,20 +199,21 @@ export declare class MemoryRegistryStore implements RegistryStore {
|
|
|
125
199
|
listFetches(runId: string): Promise<(RegistryFetchRecord & {
|
|
126
200
|
createdAt: Date;
|
|
127
201
|
})[]>;
|
|
202
|
+
listRecentRefusals(runId: string, since: Date, limit: number): Promise<(RegistryFetchRecord & {
|
|
203
|
+
createdAt: Date;
|
|
204
|
+
})[]>;
|
|
128
205
|
getVersionFacts(ecosystem: string, versions: readonly {
|
|
129
206
|
name: string;
|
|
130
207
|
version: string;
|
|
131
208
|
}[]): Promise<StoredVersionFact[]>;
|
|
132
209
|
putVersionFacts(ecosystem: string, facts: readonly StoredVersionFact[]): Promise<void>;
|
|
133
210
|
approveVersions(runId: string, ecosystem: string, versions: readonly ApprovedVersion[]): Promise<void>;
|
|
134
|
-
findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<
|
|
135
|
-
integrity: string;
|
|
136
|
-
downloadUrl: string;
|
|
137
|
-
} | null>;
|
|
211
|
+
findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<ApprovedDownload | null>;
|
|
138
212
|
refusePlanVersions(runId: string, ecosystem: string, versions: readonly PlanRefusedVersion[]): Promise<void>;
|
|
139
213
|
findPlanRefusal(runId: string, ecosystem: string, name: string, version: string): Promise<{
|
|
140
214
|
code: string;
|
|
141
215
|
reason: string;
|
|
142
216
|
publishedAt: Date | null;
|
|
143
217
|
} | null>;
|
|
218
|
+
recordDependencyCacheLockHash(runId: string, lockHash: string, max: number): Promise<void>;
|
|
144
219
|
}
|
|
@@ -17,11 +17,17 @@ export function extraOfAllowanceName(rowName, name) {
|
|
|
17
17
|
const extra = rowName.slice(prefix.length, -1);
|
|
18
18
|
return /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(extra) ? extra : null;
|
|
19
19
|
}
|
|
20
|
+
/** The `auditedVia` of an audited allowance whose relation a lockfile plan
|
|
21
|
+
* could not tell (`unknown`): no package name is empty. */
|
|
22
|
+
export const AUDITED_VIA_UNKNOWN = "";
|
|
20
23
|
/** In-memory adapter for tests. `contexts` is settable directly so tests can
|
|
21
24
|
* seed a run without going through a full proxy session. */
|
|
22
25
|
export class MemoryRegistryStore {
|
|
23
26
|
contexts = new Map();
|
|
24
27
|
allowances = new Set();
|
|
28
|
+
/** `runId\0ecosystem\0name` -> the audited package that declared the allowance (first writer). */
|
|
29
|
+
auditedVia = new Map();
|
|
30
|
+
audits = [];
|
|
25
31
|
fetches = [];
|
|
26
32
|
/** `ecosystem\0name\0version` -> fact. */
|
|
27
33
|
facts = new Map();
|
|
@@ -29,6 +35,8 @@ export class MemoryRegistryStore {
|
|
|
29
35
|
approvals = new Map();
|
|
30
36
|
/** `runId\0ecosystem\0name\0version` -> plan refusal. */
|
|
31
37
|
planRefusals = new Map();
|
|
38
|
+
/** runId -> dependency cache session state (shareable with the cache's memory store). */
|
|
39
|
+
cacheSessions = new Map();
|
|
32
40
|
async findRunByRegistryTokenHash(hash, now) {
|
|
33
41
|
const context = this.contexts.get(hash);
|
|
34
42
|
return context && context.deadlineAt > now ? context : null;
|
|
@@ -39,10 +47,32 @@ export class MemoryRegistryStore {
|
|
|
39
47
|
return false;
|
|
40
48
|
return this.allowances.has(`${runId}\0${ecosystem}\0${name}`);
|
|
41
49
|
}
|
|
50
|
+
async findAllowance(runId, ecosystem, name) {
|
|
51
|
+
if (!(await this.isAllowedDependency(runId, ecosystem, name)))
|
|
52
|
+
return null;
|
|
53
|
+
return { auditedVia: this.auditedVia.get(`${runId}\0${ecosystem}\0${name}`) ?? null };
|
|
54
|
+
}
|
|
42
55
|
async addAllowances(runId, ecosystem, names) {
|
|
43
56
|
for (const name of names)
|
|
44
57
|
this.allowances.add(`${runId}\0${ecosystem}\0${name}`);
|
|
45
58
|
}
|
|
59
|
+
async addAuditedAllowances(runId, ecosystem, names, auditedVia) {
|
|
60
|
+
for (const name of names) {
|
|
61
|
+
const key = `${runId}\0${ecosystem}\0${name}`;
|
|
62
|
+
if (this.allowances.has(key))
|
|
63
|
+
continue;
|
|
64
|
+
this.allowances.add(key);
|
|
65
|
+
this.auditedVia.set(key, auditedVia);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async recordAudit(record) {
|
|
69
|
+
const same = (row) => row.runId === record.runId &&
|
|
70
|
+
row.ecosystem === record.ecosystem &&
|
|
71
|
+
row.name === record.name &&
|
|
72
|
+
row.version === record.version;
|
|
73
|
+
if (!this.audits.some(same))
|
|
74
|
+
this.audits.push({ ...record, createdAt: new Date() });
|
|
75
|
+
}
|
|
46
76
|
async allowedExtras(runId, ecosystem, name) {
|
|
47
77
|
const prefix = `${runId}\0${ecosystem}\0`;
|
|
48
78
|
return [...this.allowances]
|
|
@@ -67,6 +97,12 @@ export class MemoryRegistryStore {
|
|
|
67
97
|
async listFetches(runId) {
|
|
68
98
|
return this.fetches.filter((fetch) => fetch.runId === runId);
|
|
69
99
|
}
|
|
100
|
+
async listRecentRefusals(runId, since, limit) {
|
|
101
|
+
return this.fetches
|
|
102
|
+
.filter((fetch) => fetch.runId === runId && fetch.outcome === "refused" && fetch.createdAt >= since)
|
|
103
|
+
.reverse()
|
|
104
|
+
.slice(0, limit);
|
|
105
|
+
}
|
|
70
106
|
async getVersionFacts(ecosystem, versions) {
|
|
71
107
|
return versions.flatMap(({ name, version }) => this.facts.get(`${ecosystem}\0${name}\0${version}`) ?? []);
|
|
72
108
|
}
|
|
@@ -87,7 +123,14 @@ export class MemoryRegistryStore {
|
|
|
87
123
|
async findApprovedVersion(runId, ecosystem, name, version) {
|
|
88
124
|
const approval = this.approvals.get(`${runId}\0${ecosystem}\0${name}\0${version}`);
|
|
89
125
|
const fact = this.facts.get(`${ecosystem}\0${name}\0${version}`);
|
|
90
|
-
return approval && fact
|
|
126
|
+
return approval && fact
|
|
127
|
+
? {
|
|
128
|
+
integrity: approval.integrity,
|
|
129
|
+
downloadUrl: fact.downloadUrl,
|
|
130
|
+
acceptedAdvisories: [...(approval.acceptedAdvisories ?? [])],
|
|
131
|
+
...(approval.audit ? { audit: approval.audit } : {}),
|
|
132
|
+
}
|
|
133
|
+
: null;
|
|
91
134
|
}
|
|
92
135
|
async refusePlanVersions(runId, ecosystem, versions) {
|
|
93
136
|
for (const refusal of versions) {
|
|
@@ -100,4 +143,14 @@ export class MemoryRegistryStore {
|
|
|
100
143
|
const refusal = this.planRefusals.get(`${runId}\0${ecosystem}\0${name}\0${version}`);
|
|
101
144
|
return refusal ? { code: refusal.code, reason: refusal.reason, publishedAt: refusal.publishedAt ?? null } : null;
|
|
102
145
|
}
|
|
146
|
+
async recordDependencyCacheLockHash(runId, lockHash, max) {
|
|
147
|
+
let session = this.cacheSessions.get(runId);
|
|
148
|
+
if (!session) {
|
|
149
|
+
session = { lockHashes: [], sealedAt: null, createdAt: new Date() };
|
|
150
|
+
this.cacheSessions.set(runId, session);
|
|
151
|
+
}
|
|
152
|
+
if (session.sealedAt || session.lockHashes.includes(lockHash) || session.lockHashes.length >= max)
|
|
153
|
+
return;
|
|
154
|
+
session.lockHashes.push(lockHash);
|
|
155
|
+
}
|
|
103
156
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { PrismaClient } from "#prisma";
|
|
2
2
|
import type { UpstreamFetch } from "../../coding/registry/types.js";
|
|
3
|
+
import { type BlobStoreConfig } from "../storage/index.js";
|
|
4
|
+
import type { BlobStore } from "../storage/types.js";
|
|
3
5
|
import { startDenyPortListener } from "./deny-port.js";
|
|
4
6
|
import { type PinnedProxyFetchOptions } from "./secure-fetch.js";
|
|
5
7
|
import { startCodingProxyServer, type CodingProxyServerHandle } from "./server.js";
|
|
@@ -12,6 +14,12 @@ import type { ProxyAuditSink } from "./types.js";
|
|
|
12
14
|
* JSON). Exported so its header-mapping can be unit-tested directly,
|
|
13
15
|
* without needing a live upstream. */
|
|
14
16
|
export declare function createRegistryUpstream(pinned: typeof globalThis.fetch): UpstreamFetch;
|
|
17
|
+
/**
|
|
18
|
+
* WARDBY_MCP_GATEWAY_URL: the native gateway's base URL, which the /mcp route forwards to (its
|
|
19
|
+
* /coding-mcp route). Unset or empty: /mcp answers 503 mcp_unavailable. Anything but an http(s) URL
|
|
20
|
+
* without credentials, query or fragment stops start-up (the value is not echoed).
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadMcpGatewayUrl(env: NodeJS.ProcessEnv): string | undefined;
|
|
15
23
|
export interface CodingProxyRuntimeOptions {
|
|
16
24
|
db: PrismaClient;
|
|
17
25
|
/** The package registry's own client, so its traffic (many concurrent
|
|
@@ -25,6 +33,8 @@ export interface CodingProxyRuntimeOptions {
|
|
|
25
33
|
* upstream hosts are actually passed to the pinned-fetch allowlist. */
|
|
26
34
|
createPinnedFetch?: (options: PinnedProxyFetchOptions) => typeof globalThis.fetch;
|
|
27
35
|
audit?: ProxyAuditSink;
|
|
36
|
+
/** Overridable for tests: builds the dependency cache's blob store. */
|
|
37
|
+
createBlobStore?: (config: BlobStoreConfig) => BlobStore;
|
|
28
38
|
onRequest?: (event: {
|
|
29
39
|
protocol: "openai-responses" | "anthropic-messages" | "other";
|
|
30
40
|
status: number;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import { loadDependencyCacheConfig } from "../../config/dependency-cache.js";
|
|
2
|
+
import { createSimulatorModelFetch, createSimulatorRegistryFetch, startupTestSimulators, } from "../../config/test-simulators.js";
|
|
1
3
|
import { logger } from "../../core/logger.js";
|
|
2
4
|
import { REGISTRY_ADAPTERS } from "../../coding/registry/adapters.js";
|
|
3
5
|
import { CODING_PROXY_ALIAS, CODING_PROXY_DENY_PORT, CODING_PROXY_PORT } from "../jobs/docker-isolation.js";
|
|
6
|
+
import { createBlobStore } from "../storage/index.js";
|
|
7
|
+
import { startEviction } from "./dependency-cache/eviction.js";
|
|
8
|
+
import { PrismaDependencyCacheStore } from "./dependency-cache/prisma-store.js";
|
|
9
|
+
import { ModelRequestSeal } from "./dependency-cache/model-request-seal.js";
|
|
10
|
+
import { DependencyCacheService } from "./dependency-cache/service.js";
|
|
4
11
|
import { startDenyPortListener } from "./deny-port.js";
|
|
5
12
|
import { EnvironmentCredentialResolver } from "./environment-credentials.js";
|
|
13
|
+
import { createMcpRoute } from "./mcp-route.js";
|
|
6
14
|
import { createMockUpstream, mockUpstreamFromEnv } from "./mock-upstream.js";
|
|
7
15
|
import { CodingProxy } from "./proxy.js";
|
|
8
16
|
import { PrismaProxyLedger } from "./prisma-ledger.js";
|
|
@@ -10,7 +18,7 @@ import { OsvAudit } from "./registry/audit.js";
|
|
|
10
18
|
import { PrismaRegistryStore } from "./registry/prisma-store.js";
|
|
11
19
|
import { DEFAULT_PLAN_MAX_ENTRIES, DEFAULT_PLAN_TIMEOUT_MS } from "./registry/plan.js";
|
|
12
20
|
import { DEFAULT_GRAPH_TIMEOUT_MS, DEFAULT_MAX_GRAPH_PACKAGES, DEFAULT_PLAN_MAX_PER_RUN, RegistryService, } from "./registry/service.js";
|
|
13
|
-
import { createPinnedProxyFetch } from "./secure-fetch.js";
|
|
21
|
+
import { createPinnedProxyFetch, PROXY_EGRESS_ERROR } from "./secure-fetch.js";
|
|
14
22
|
import { startCodingProxyServer } from "./server.js";
|
|
15
23
|
const MIB = 1024 * 1024;
|
|
16
24
|
function positiveInt(value, fallback) {
|
|
@@ -37,9 +45,37 @@ export function createRegistryUpstream(pinned) {
|
|
|
37
45
|
},
|
|
38
46
|
});
|
|
39
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* WARDBY_MCP_GATEWAY_URL: the native gateway's base URL, which the /mcp route forwards to (its
|
|
50
|
+
* /coding-mcp route). Unset or empty: /mcp answers 503 mcp_unavailable. Anything but an http(s) URL
|
|
51
|
+
* without credentials, query or fragment stops start-up (the value is not echoed).
|
|
52
|
+
*/
|
|
53
|
+
export function loadMcpGatewayUrl(env) {
|
|
54
|
+
const value = env.WARDBY_MCP_GATEWAY_URL?.trim();
|
|
55
|
+
if (!value)
|
|
56
|
+
return undefined;
|
|
57
|
+
let url;
|
|
58
|
+
try {
|
|
59
|
+
url = new URL(value);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
url = undefined;
|
|
63
|
+
}
|
|
64
|
+
if (!url ||
|
|
65
|
+
(url.protocol !== "http:" && url.protocol !== "https:") ||
|
|
66
|
+
url.username ||
|
|
67
|
+
url.password ||
|
|
68
|
+
url.search ||
|
|
69
|
+
url.hash) {
|
|
70
|
+
throw new Error("WARDBY_MCP_GATEWAY_URL must be an http(s) URL without credentials, query or fragment");
|
|
71
|
+
}
|
|
72
|
+
return url.href.replace(/\/+$/, "");
|
|
73
|
+
}
|
|
40
74
|
/** Starts the trusted proxy with the fixed worker-only Docker endpoint, plus the deny port the enforcement witness probes. */
|
|
41
75
|
export async function startConfiguredCodingProxy(options) {
|
|
42
76
|
const env = options.env ?? process.env;
|
|
77
|
+
// Throws on an invalid setting, before anything listens.
|
|
78
|
+
const cacheConfig = loadDependencyCacheConfig(env);
|
|
43
79
|
// Throws (mock_upstream_guard) on a partial or malformed setting, before anything listens.
|
|
44
80
|
const mock = mockUpstreamFromEnv(env);
|
|
45
81
|
if (mock) {
|
|
@@ -48,21 +84,24 @@ export async function startConfiguredCodingProxy(options) {
|
|
|
48
84
|
const audit = mock
|
|
49
85
|
? (event) => options.audit?.({ ...event, mockUpstream: true })
|
|
50
86
|
: options.audit;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
...(mock ? { fetch: createMockUpstream(mock) } : {}),
|
|
56
|
-
});
|
|
87
|
+
// Throws on an invalid setting, before anything listens.
|
|
88
|
+
const mcpGatewayUrl = loadMcpGatewayUrl(env);
|
|
89
|
+
// Throws (test_simulators_refused) on any refusal, before anything listens.
|
|
90
|
+
const simulators = startupTestSimulators("coding-proxy", env);
|
|
57
91
|
const buildPinnedFetch = options.createPinnedFetch ?? createPinnedProxyFetch;
|
|
58
92
|
const upstreamHosts = [...new Set([...REGISTRY_ADAPTERS.values()].flatMap((adapter) => adapter.upstreamHosts))];
|
|
59
|
-
|
|
93
|
+
// WARDBY_TEST_SIMULATORS (test only): the registry hosts go to their simulators, and every
|
|
94
|
+
// other host is still refused.
|
|
95
|
+
const pinned = simulators
|
|
96
|
+
? createSimulatorRegistryFetch(simulators, () => new Error(PROXY_EGRESS_ERROR))
|
|
97
|
+
: buildPinnedFetch({ allowedHosts: [...upstreamHosts, "api.osv.dev"] });
|
|
60
98
|
const upstream = createRegistryUpstream(pinned);
|
|
61
99
|
const metadataTimeoutMs = positiveInt(env.REGISTRY_METADATA_TIMEOUT_MS, 30_000);
|
|
62
100
|
const maxMetadataBytes = positiveInt(env.REGISTRY_MAX_METADATA_MB, 64) * MIB;
|
|
101
|
+
const registryStore = new PrismaRegistryStore(options.registryDb ?? options.db);
|
|
63
102
|
const registry = new RegistryService({
|
|
64
103
|
adapters: REGISTRY_ADAPTERS,
|
|
65
|
-
store:
|
|
104
|
+
store: registryStore,
|
|
66
105
|
audit: new OsvAudit({
|
|
67
106
|
fetch: upstream,
|
|
68
107
|
failOpen: env.REGISTRY_AUDIT_FAIL_OPEN === "true",
|
|
@@ -85,14 +124,66 @@ export async function startConfiguredCodingProxy(options) {
|
|
|
85
124
|
idleTimeoutMs: positiveInt(env.REGISTRY_IDLE_TIMEOUT_MS, 120_000),
|
|
86
125
|
},
|
|
87
126
|
});
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
127
|
+
let dependencyCache;
|
|
128
|
+
let modelRequestSeal;
|
|
129
|
+
let eviction;
|
|
130
|
+
if (cacheConfig.enabled) {
|
|
131
|
+
const blobs = (options.createBlobStore ?? createBlobStore)(cacheConfig.blobStore);
|
|
132
|
+
const cacheStore = new PrismaDependencyCacheStore(options.registryDb ?? options.db);
|
|
133
|
+
modelRequestSeal = new ModelRequestSeal(cacheStore);
|
|
134
|
+
dependencyCache = new DependencyCacheService({
|
|
135
|
+
registry: registryStore,
|
|
136
|
+
store: cacheStore,
|
|
137
|
+
blobs,
|
|
138
|
+
maxSnapshotBytes: cacheConfig.maxSnapshotBytes,
|
|
139
|
+
uploadMs: cacheConfig.uploadMs,
|
|
140
|
+
});
|
|
141
|
+
eviction = startEviction({
|
|
142
|
+
store: cacheStore,
|
|
143
|
+
blobs,
|
|
144
|
+
limits: {
|
|
145
|
+
maxAgeMs: cacheConfig.maxAgeMs,
|
|
146
|
+
repoCapBytes: cacheConfig.repoCapBytes,
|
|
147
|
+
totalCapBytes: cacheConfig.totalCapBytes,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else if (cacheConfig.reason === "no_blob_store") {
|
|
152
|
+
logger.warn({ module: "coding-proxy-runtime", event: "proxy.dependency_cache_no_blob_store" }, "coding proxy: WARDBY_DEPENDENCY_CACHE=true but no BLOB_STORE is configured; the dependency cache is off");
|
|
153
|
+
}
|
|
154
|
+
const seal = modelRequestSeal;
|
|
155
|
+
const ledger = new PrismaProxyLedger(options.db);
|
|
156
|
+
const proxy = new CodingProxy({
|
|
157
|
+
ledger,
|
|
158
|
+
credentials: new EnvironmentCredentialResolver(env),
|
|
159
|
+
audit,
|
|
160
|
+
// WARDBY_TEST_SIMULATORS (test only; refused alongside the mock upstream): the scripted model,
|
|
161
|
+
// with every credential header dropped.
|
|
162
|
+
...(simulators
|
|
163
|
+
? { fetch: createSimulatorModelFetch(simulators, () => new Error(PROXY_EGRESS_ERROR)) }
|
|
164
|
+
: mock
|
|
165
|
+
? { fetch: createMockUpstream(mock) }
|
|
166
|
+
: {}),
|
|
167
|
+
// The run's first model request closes its dependency cache (no-op for a run with it off).
|
|
168
|
+
...(seal ? { onModelRequest: (runId) => seal.onModelRequest(runId) } : {}),
|
|
95
169
|
});
|
|
170
|
+
const startServer = options.startServer ?? startCodingProxyServer;
|
|
171
|
+
let server;
|
|
172
|
+
try {
|
|
173
|
+
server = await startServer(proxy, {
|
|
174
|
+
host: "0.0.0.0",
|
|
175
|
+
port: CODING_PROXY_PORT,
|
|
176
|
+
expectedHost: `${CODING_PROXY_ALIAS}:${CODING_PROXY_PORT}`,
|
|
177
|
+
registry,
|
|
178
|
+
...(dependencyCache ? { dependencyCache } : {}),
|
|
179
|
+
mcp: createMcpRoute({ ledger, gatewayUrl: mcpGatewayUrl }),
|
|
180
|
+
onRequest: options.onRequest,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
eviction?.stop();
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
96
187
|
let deny;
|
|
97
188
|
try {
|
|
98
189
|
deny = await (options.startDenyPort ?? startDenyPortListener)("0.0.0.0", CODING_PROXY_DENY_PORT);
|
|
@@ -100,12 +191,14 @@ export async function startConfiguredCodingProxy(options) {
|
|
|
100
191
|
catch (error) {
|
|
101
192
|
// A proxy without its witness must not stay up: the launcher's gate would never be able to
|
|
102
193
|
// prove a policy is enforced, and every launch would fail at the gate instead of at startup.
|
|
194
|
+
eviction?.stop();
|
|
103
195
|
await server.close();
|
|
104
196
|
throw error;
|
|
105
197
|
}
|
|
106
198
|
return {
|
|
107
199
|
port: server.port,
|
|
108
200
|
close: async () => {
|
|
201
|
+
eviction?.stop();
|
|
109
202
|
await deny.close();
|
|
110
203
|
await server.close();
|
|
111
204
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
1
2
|
import type { ProxyAuditEvent } from "./types.js";
|
|
2
3
|
import { type CodingProxy } from "./proxy.js";
|
|
3
4
|
import { type RegistryService } from "./registry/service.js";
|
|
5
|
+
import type { DependencyCacheService } from "./dependency-cache/service.js";
|
|
4
6
|
import type { ProxyProtocol } from "./types.js";
|
|
5
7
|
declare const proxyLog: import("pino").Logger<never, boolean>;
|
|
6
8
|
/**
|
|
@@ -13,7 +15,13 @@ export interface CodingProxyServerConfig {
|
|
|
13
15
|
host: string;
|
|
14
16
|
port: number;
|
|
15
17
|
expectedHost?: string;
|
|
16
|
-
registry?: Pick<RegistryService, "handle"> & Partial<Pick<RegistryService, "plan">>;
|
|
18
|
+
registry?: Pick<RegistryService, "handle"> & Partial<Pick<RegistryService, "plan" | "refusals">>;
|
|
19
|
+
/** The dependency cache (`/cache/...`); absent when the deployment has it off. */
|
|
20
|
+
dependencyCache?: Pick<DependencyCacheService, "handle" | "uploadMs">;
|
|
21
|
+
/** Time to receive a whole request (default HTTP_LIMITS.requestMs); a cache upload gets its upload window instead. */
|
|
22
|
+
requestMs?: number;
|
|
23
|
+
/** The worker's MCP route (`/mcp`, createMcpRoute); absent, /mcp is not found. */
|
|
24
|
+
mcp?: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
17
25
|
onRequest?: (event: {
|
|
18
26
|
protocol: ProxyProtocol | "other";
|
|
19
27
|
status: number;
|
|
@@ -6,6 +6,7 @@ import { logger } from "../../core/logger.js";
|
|
|
6
6
|
import { CodingProxyError, PROXY_MAX_BODY_BYTES } from "./proxy.js";
|
|
7
7
|
import { RegistryError } from "../../coding/registry/types.js";
|
|
8
8
|
import { MAX_PLAN_BODY_BYTES } from "./registry/service.js";
|
|
9
|
+
import { MCP_ROUTE_PATH } from "./mcp-route.js";
|
|
9
10
|
const proxyLog = logger.child({ module: "coding-proxy" });
|
|
10
11
|
/**
|
|
11
12
|
* Writes a proxy audit event to the operator log. The events carry ids,
|
|
@@ -99,6 +100,12 @@ function readPlanBody(request, signal) {
|
|
|
99
100
|
failed();
|
|
100
101
|
});
|
|
101
102
|
}
|
|
103
|
+
/** An error answer to a request whose body was not read: close the
|
|
104
|
+
* connection rather than read (or keep) what the client is still sending. */
|
|
105
|
+
function closeIfBodyUnread(request, response) {
|
|
106
|
+
if (!request.complete && !response.headersSent)
|
|
107
|
+
response.setHeader("connection", "close");
|
|
108
|
+
}
|
|
102
109
|
function routeProtocol(method, url) {
|
|
103
110
|
if (method !== "POST")
|
|
104
111
|
return undefined;
|
|
@@ -130,8 +137,25 @@ function responseSink(response) {
|
|
|
130
137
|
};
|
|
131
138
|
}
|
|
132
139
|
export async function startCodingProxyServer(proxy, config) {
|
|
140
|
+
const requestMs = config.requestMs ?? HTTP_LIMITS.requestMs;
|
|
141
|
+
// A snapshot upload (up to WARDBY_DEPENDENCY_CACHE_MAX_SNAPSHOT_MB) cannot
|
|
142
|
+
// arrive within requestMs, and Node's requestTimeout is server-wide: with
|
|
143
|
+
// the cache on it is widened to cover the upload window (which the cache
|
|
144
|
+
// enforces on the upload itself), and every request gets a requestMs timer
|
|
145
|
+
// of its own. Only the cache lifts that timer, and only for an upload it
|
|
146
|
+
// has authenticated, found eligible and given its upload slot.
|
|
147
|
+
const extendedRequests = config.dependencyCache !== undefined;
|
|
133
148
|
const server = createServer({ maxHeaderSize: 16 * 1024, requireHostHeader: true }, (request, response) => {
|
|
134
149
|
const startedAt = performance.now();
|
|
150
|
+
const bodyTimer = extendedRequests
|
|
151
|
+
? setTimeout(() => {
|
|
152
|
+
if (!request.complete)
|
|
153
|
+
request.socket.destroy();
|
|
154
|
+
}, requestMs).unref()
|
|
155
|
+
: undefined;
|
|
156
|
+
// Done with once the response is over (finished or closed early).
|
|
157
|
+
if (bodyTimer)
|
|
158
|
+
response.once("close", () => clearTimeout(bodyTimer));
|
|
135
159
|
const protocol = routeProtocol(request.method, request.url) ?? "other";
|
|
136
160
|
response.once("finish", () => {
|
|
137
161
|
try {
|
|
@@ -143,9 +167,19 @@ export async function startCodingProxyServer(proxy, config) {
|
|
|
143
167
|
});
|
|
144
168
|
void (async () => {
|
|
145
169
|
if (config.expectedHost && request.headers.host !== config.expectedHost) {
|
|
170
|
+
closeIfBodyUnread(request, response);
|
|
146
171
|
sendError(response, 403, "invalid_host");
|
|
147
172
|
return;
|
|
148
173
|
}
|
|
174
|
+
if (request.url?.startsWith("/cache/")) {
|
|
175
|
+
if (!config.dependencyCache) {
|
|
176
|
+
closeIfBodyUnread(request, response);
|
|
177
|
+
sendError(response, 404, "not_found");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
await config.dependencyCache.handle(request, response, registryToken(request.headers.authorization), () => clearTimeout(bodyTimer));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
149
183
|
if (request.url?.startsWith("/registry/")) {
|
|
150
184
|
if (!config.registry) {
|
|
151
185
|
sendError(response, 404, "not_found");
|
|
@@ -187,6 +221,16 @@ export async function startCodingProxyServer(proxy, config) {
|
|
|
187
221
|
sendError(response, 405, "method_not_allowed");
|
|
188
222
|
return;
|
|
189
223
|
}
|
|
224
|
+
// The run's recent refusals, for clients that don't print the 403 body (pip, uv).
|
|
225
|
+
const refusals = request.url.match(/^\/registry\/-\/refusals(?:\?(.*))?$/);
|
|
226
|
+
if (refusals && config.registry.refusals) {
|
|
227
|
+
const since = new URLSearchParams(refusals[1] ?? "").get("since");
|
|
228
|
+
sendRegistry(response, await config.registry.refusals({
|
|
229
|
+
token: registryToken(request.headers.authorization),
|
|
230
|
+
...(since ? { since: new Date(since) } : {}),
|
|
231
|
+
}));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
190
234
|
const match = request.url.match(/^\/registry\/([a-z0-9-]+)\/(.*)$/);
|
|
191
235
|
if (!match) {
|
|
192
236
|
sendError(response, 404, "not_found");
|
|
@@ -223,6 +267,15 @@ export async function startCodingProxyServer(proxy, config) {
|
|
|
223
267
|
});
|
|
224
268
|
return;
|
|
225
269
|
}
|
|
270
|
+
if (request.url === MCP_ROUTE_PATH || request.url?.startsWith(`${MCP_ROUTE_PATH}?`)) {
|
|
271
|
+
if (!config.mcp) {
|
|
272
|
+
closeIfBodyUnread(request, response);
|
|
273
|
+
sendError(response, 404, "not_found");
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
await config.mcp(request, response);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
226
279
|
if (request.method === "HEAD" && request.url === "/api/hello") {
|
|
227
280
|
response.writeHead(200, { "cache-control": "no-store" }).end();
|
|
228
281
|
return;
|
|
@@ -269,6 +322,7 @@ export async function startCodingProxyServer(proxy, config) {
|
|
|
269
322
|
response.destroy();
|
|
270
323
|
return;
|
|
271
324
|
}
|
|
325
|
+
closeIfBodyUnread(request, response);
|
|
272
326
|
if (error instanceof CodingProxyError || error instanceof HttpBoundaryError) {
|
|
273
327
|
proxyLog.info({ event: "request.rejected", code: error instanceof CodingProxyError ? error.code : error.message }, "coding proxy request rejected");
|
|
274
328
|
sendError(response, error.status, error instanceof CodingProxyError ? error.code : error.message);
|
|
@@ -283,7 +337,7 @@ export async function startCodingProxyServer(proxy, config) {
|
|
|
283
337
|
sendError(response, 500, "internal_error");
|
|
284
338
|
});
|
|
285
339
|
});
|
|
286
|
-
server.requestTimeout =
|
|
340
|
+
server.requestTimeout = extendedRequests ? requestMs + config.dependencyCache.uploadMs : requestMs;
|
|
287
341
|
server.headersTimeout = HTTP_LIMITS.headersMs;
|
|
288
342
|
server.keepAliveTimeout = 5_000;
|
|
289
343
|
server.maxRequestsPerSocket = 100;
|