@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
|
@@ -4,24 +4,38 @@
|
|
|
4
4
|
* lockfile claims is trusted:
|
|
5
5
|
*
|
|
6
6
|
* - every entry's integrity must equal the registry's own for that exact
|
|
7
|
-
* version (a per-version fact read from the registry, stored forever)
|
|
7
|
+
* version (a per-version fact read from the registry, stored forever),
|
|
8
|
+
* unless the format records no npm integrity at all (yarn Berry): then
|
|
9
|
+
* the approval is the exact name@version, and the download is checked
|
|
10
|
+
* against the registry's integrity alone;
|
|
8
11
|
* - edges come from the registry too: a parent version's declared
|
|
9
12
|
* dependencies, resolved to lockfile entries by the client's own rule
|
|
10
13
|
* (npm: nearest ancestor node_modules), and kept only when the entry is
|
|
11
14
|
* the declared package at a version inside the declared range;
|
|
12
|
-
* - reachability starts at
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* - reachability starts at every lockfile entry that is an allowlist root
|
|
16
|
+
* (at a version inside the root's range), wherever it sits and whether or
|
|
17
|
+
* not a project declares it, and follows only verified
|
|
18
|
+
* edges, through versions old enough and without a HIGH/CRITICAL advisory
|
|
19
|
+
* (one the run's accepted set waives does not count; malware always does).
|
|
20
|
+
*
|
|
21
|
+
* PyPI dependency lines may be gated on extras: an entry is expanded with the
|
|
22
|
+
* extras it is installed with (a start's allowlist entry's, then those its
|
|
23
|
+
* parents' lines ask of it), and a plain install follows none.
|
|
15
24
|
*
|
|
16
25
|
* A refused entry refuses itself and whatever is reachable only through it;
|
|
17
|
-
* everything else is approved, as exact name@version pairs
|
|
26
|
+
* everything else is approved, as exact name@version pairs (an ecosystem
|
|
27
|
+
* that `approves: "names"` turns them into name allowances). In package
|
|
28
|
+
* audit mode every registry entry is a start as well: one the allowlist does
|
|
29
|
+
* not reach is approved when it passes every other check, marked with its
|
|
30
|
+
* audit verdict (and, in `full`, a version kept only past non-malware
|
|
31
|
+
* blocking advisories is approved and marked too). The work is
|
|
18
32
|
* bounded: facts are fetched only for entries reached (so a lockfile of
|
|
19
33
|
* unrelated packages costs nothing upstream), with bounded concurrency and a
|
|
20
34
|
* deadline.
|
|
21
35
|
*/
|
|
22
36
|
import { matchRoot } from "../../../coding/registry/allowlist.js";
|
|
23
37
|
import { RegistryError, } from "../../../coding/registry/types.js";
|
|
24
|
-
import { versionKey } from "./audit.js";
|
|
38
|
+
import { auditAdvisoryOf, splitWaived, versionKey } from "./audit.js";
|
|
25
39
|
export const DEFAULT_PLAN_MAX_ENTRIES = 5000;
|
|
26
40
|
export const DEFAULT_PLAN_TIMEOUT_MS = 120_000;
|
|
27
41
|
/** Per-version documents fetched at once (each is a few KB). */
|
|
@@ -61,21 +75,29 @@ export async function verifyLockfilePlan(input) {
|
|
|
61
75
|
reason: entry.unsupportedReason ?? "cannot be verified against the registry",
|
|
62
76
|
});
|
|
63
77
|
}
|
|
64
|
-
// Starting points:
|
|
65
|
-
//
|
|
78
|
+
// Starting points: every registry entry that is an allowlist root at a
|
|
79
|
+
// version inside the root's range, wherever it sits in the lockfile and
|
|
80
|
+
// whether or not a project declares it. An allowlisted name may be
|
|
81
|
+
// installed by name anyway (the download path allows the same name@version:
|
|
82
|
+
// `authorize` matches the name with `matchRoot`, and `keptVersions`
|
|
83
|
+
// applies the root's range, release age and advisories), so an `overrides`-forced version of it, which no parent's
|
|
84
|
+
// declared range reaches, is a start in its own right. Every start still
|
|
85
|
+
// passes the fact checks below (integrity, release age, advisories), and
|
|
86
|
+
// edges are still followed only inside declared ranges.
|
|
66
87
|
const starts = new Set();
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
// The extras each reached entry is installed with (PyPI): a start's are its
|
|
89
|
+
// allowlist entry's, a child's those its parents' lines ask of it.
|
|
90
|
+
const extrasOf = new Map();
|
|
91
|
+
for (const entry of lockfile.entries) {
|
|
92
|
+
if (entry.kind !== "registry")
|
|
93
|
+
continue;
|
|
94
|
+
const root = matchRoot(input.roots, adapter.normalizeName(entry.name));
|
|
95
|
+
if (!root)
|
|
96
|
+
continue;
|
|
97
|
+
if (root.range && !safeSatisfies(adapter, entry.version, root.range))
|
|
98
|
+
continue;
|
|
99
|
+
starts.add(entry);
|
|
100
|
+
extrasOf.set(entry, new Set(root.extras ?? []));
|
|
79
101
|
}
|
|
80
102
|
// Breadth first over verified edges, fetching facts one layer at a time
|
|
81
103
|
// (only for entries actually reached).
|
|
@@ -83,11 +105,28 @@ export async function verifyLockfilePlan(input) {
|
|
|
83
105
|
const edges = new Map();
|
|
84
106
|
const candidates = new Set();
|
|
85
107
|
const visited = new Set(starts);
|
|
108
|
+
// Package audit mode: every other registry entry starts too, except an
|
|
109
|
+
// allowlisted name outside its entry's own range (an owner's explicit
|
|
110
|
+
// restriction, never widened by audit mode). Visited after the roots'
|
|
111
|
+
// graph, so facts load in the same bounded layers.
|
|
112
|
+
const auditStarts = input.auditMode
|
|
113
|
+
? lockfile.entries.filter((entry) => entry.kind === "registry" &&
|
|
114
|
+
!starts.has(entry) &&
|
|
115
|
+
!outsideRootRange(input, adapter.normalizeName(entry.name), entry.version))
|
|
116
|
+
: [];
|
|
86
117
|
let layer = [...starts];
|
|
87
|
-
|
|
118
|
+
let auditSeeded = false;
|
|
119
|
+
while (layer.length > 0 || (!auditSeeded && auditStarts.length > 0)) {
|
|
120
|
+
if (layer.length === 0) {
|
|
121
|
+
auditSeeded = true;
|
|
122
|
+
layer = auditStarts.filter((entry) => !visited.has(entry));
|
|
123
|
+
for (const entry of layer)
|
|
124
|
+
visited.add(entry);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
88
127
|
signal.throwIfAborted();
|
|
89
128
|
await loadFacts(input, layer, outcomes);
|
|
90
|
-
const next =
|
|
129
|
+
const next = new Set();
|
|
91
130
|
for (const entry of layer) {
|
|
92
131
|
const outcome = outcomes.get(versionKey(entry.name, entry.version));
|
|
93
132
|
if ("refusal" in outcome) {
|
|
@@ -95,7 +134,8 @@ export async function verifyLockfilePlan(input) {
|
|
|
95
134
|
continue;
|
|
96
135
|
}
|
|
97
136
|
const { fact } = outcome;
|
|
98
|
-
if (
|
|
137
|
+
if (lockfile.integrity !== "registry" &&
|
|
138
|
+
(entry.integrity === null || entry.integrity.trim() !== fact.integrity)) {
|
|
99
139
|
refusals.set(entry, {
|
|
100
140
|
code: "wardby_lockfile_integrity_mismatch",
|
|
101
141
|
reason: `the lockfile's integrity is not the registry's for ${entry.name}@${entry.version}`,
|
|
@@ -113,34 +153,63 @@ export async function verifyLockfilePlan(input) {
|
|
|
113
153
|
}
|
|
114
154
|
candidates.add(entry);
|
|
115
155
|
const children = [];
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
156
|
+
const dependencies = support.dependenciesOf
|
|
157
|
+
? support.dependenciesOf(fact, [...(extrasOf.get(entry) ?? [])].sort())
|
|
158
|
+
: fact.dependencies;
|
|
159
|
+
for (const dependency of dependencies) {
|
|
160
|
+
const resolved = lockfile.resolveAll
|
|
161
|
+
? lockfile.resolveAll(entry.path, dependency.key)
|
|
162
|
+
: [lockfile.resolve(entry.path, dependency.key)];
|
|
163
|
+
for (const child of resolved) {
|
|
164
|
+
if (!child || child.kind !== "registry" || child.name !== dependency.name)
|
|
165
|
+
continue;
|
|
166
|
+
if (!support.edgeSatisfies(child.version, dependency.range))
|
|
167
|
+
continue;
|
|
168
|
+
children.push(child);
|
|
169
|
+
const asked = dependency.extras ?? [];
|
|
170
|
+
if (!visited.has(child)) {
|
|
171
|
+
visited.add(child);
|
|
172
|
+
extrasOf.set(child, new Set(asked));
|
|
173
|
+
next.add(child);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Reached again with extras it lacked: expanded again, now with them
|
|
177
|
+
// (extras only grow, so this ends).
|
|
178
|
+
const known = extrasOf.get(child) ?? new Set();
|
|
179
|
+
if (asked.some((extra) => !known.has(extra))) {
|
|
180
|
+
for (const extra of asked)
|
|
181
|
+
known.add(extra);
|
|
182
|
+
extrasOf.set(child, known);
|
|
183
|
+
next.add(child);
|
|
184
|
+
}
|
|
126
185
|
}
|
|
127
186
|
}
|
|
128
187
|
edges.set(entry, children);
|
|
129
188
|
}
|
|
130
|
-
layer = next;
|
|
189
|
+
layer = [...next];
|
|
131
190
|
}
|
|
132
191
|
// One advisory lookup for every candidate version.
|
|
133
192
|
const withheld = await input.audit([...new Map([...candidates].map((entry) => [versionKey(entry.name, entry.version), entry])).values()].map(({ name, version }) => ({ name, version })), signal);
|
|
193
|
+
// Advisories the run's accepted set waived, per approved name@version,
|
|
194
|
+
// and (full mode) the blocking ones served past.
|
|
195
|
+
const waivers = new Map();
|
|
196
|
+
const auditAdvisories = new Map();
|
|
134
197
|
for (const entry of candidates) {
|
|
135
|
-
const
|
|
136
|
-
|
|
198
|
+
const key = versionKey(entry.name, entry.version);
|
|
199
|
+
const split = splitWaived(withheld.get(key) ?? [], input.accepted, { auditAll: input.auditMode === "full" });
|
|
200
|
+
if (split.audited.length > 0)
|
|
201
|
+
auditAdvisories.set(key, split.audited.map(auditAdvisoryOf));
|
|
202
|
+
if (split.withheld.length > 0) {
|
|
137
203
|
candidates.delete(entry);
|
|
138
204
|
refusals.set(entry, {
|
|
139
205
|
code: "wardby_version_filtered",
|
|
140
|
-
reason: `withheld by advisory ${
|
|
206
|
+
reason: `withheld by advisory ${split.withheld.map(({ id }) => id).join(", ")} (high severity or malware)`,
|
|
141
207
|
intrinsic: true,
|
|
142
208
|
});
|
|
143
209
|
}
|
|
210
|
+
else if (split.waived.length > 0) {
|
|
211
|
+
waivers.set(key, split.waived.map(({ id }) => id));
|
|
212
|
+
}
|
|
144
213
|
}
|
|
145
214
|
// Reachability again, now only through entries that passed every check:
|
|
146
215
|
// a refused entry refuses whatever is reachable only through it.
|
|
@@ -157,16 +226,38 @@ export async function verifyLockfilePlan(input) {
|
|
|
157
226
|
queue.push(child);
|
|
158
227
|
}
|
|
159
228
|
}
|
|
229
|
+
// Package audit mode: every other entry that passed every check is
|
|
230
|
+
// approved too, marked with how it reached the lockfile.
|
|
231
|
+
const relations = input.auditMode
|
|
232
|
+
? auditRelations(input, approvedEntries, candidates, edges)
|
|
233
|
+
: new Map();
|
|
160
234
|
const approved = new Map();
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
235
|
+
const approve = (entry, relation) => {
|
|
236
|
+
const key = versionKey(entry.name, entry.version);
|
|
237
|
+
const outcome = outcomes.get(key);
|
|
238
|
+
if (!outcome || !("fact" in outcome) || approved.has(key))
|
|
239
|
+
return;
|
|
240
|
+
const acceptedAdvisories = waivers.get(key);
|
|
241
|
+
const advisories = auditAdvisories.get(key);
|
|
242
|
+
const audit = relation
|
|
243
|
+
? { ...relation, ...(advisories ? { advisories } : {}) }
|
|
244
|
+
: advisories
|
|
245
|
+
? { relation: "allowed", advisories }
|
|
246
|
+
: undefined;
|
|
247
|
+
approved.set(key, {
|
|
248
|
+
name: entry.name,
|
|
249
|
+
version: entry.version,
|
|
250
|
+
integrity: outcome.fact.integrity,
|
|
251
|
+
...(acceptedAdvisories ? { acceptedAdvisories } : {}),
|
|
252
|
+
...(audit ? { audit } : {}),
|
|
253
|
+
});
|
|
254
|
+
};
|
|
255
|
+
// Approvals through the allowlist first: an exact version approved both
|
|
256
|
+
// ways is not audited.
|
|
257
|
+
for (const entry of approvedEntries)
|
|
258
|
+
approve(entry, undefined);
|
|
259
|
+
for (const [entry, relation] of relations)
|
|
260
|
+
approve(entry, relation);
|
|
170
261
|
const refused = new Map();
|
|
171
262
|
for (const entry of lockfile.entries) {
|
|
172
263
|
if (entry.kind === "bundled")
|
|
@@ -182,7 +273,59 @@ export async function verifyLockfilePlan(input) {
|
|
|
182
273
|
}
|
|
183
274
|
// An entry refused at one place in the tree but approved at another (the
|
|
184
275
|
// same name@version) is approved: approvals are per exact version.
|
|
185
|
-
|
|
276
|
+
const approvals = [...approved.values()];
|
|
277
|
+
return {
|
|
278
|
+
approved: approvals,
|
|
279
|
+
refused: [...refused.values()],
|
|
280
|
+
audited: approvals.filter((approval) => approval.audit).length,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/** Whether `name@version` is an allowlisted name at a version its entry's range excludes. */
|
|
284
|
+
function outsideRootRange(input, name, version) {
|
|
285
|
+
const root = matchRoot(input.roots, name);
|
|
286
|
+
return !!root?.range && !safeSatisfies(input.adapter, version, root.range);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* How each candidate the allowlist does not reach came into the lockfile
|
|
290
|
+
* (package audit mode): `top-level` when a lockfile project declares it,
|
|
291
|
+
* `transitive` when an audited top-level entry reaches it over verified
|
|
292
|
+
* edges (`via` its nearest such ancestor, breadth first), otherwise
|
|
293
|
+
* `unknown`. Best effort: it decides only what a reviewer is shown.
|
|
294
|
+
*/
|
|
295
|
+
function auditRelations(input, approvedEntries, candidates, edges) {
|
|
296
|
+
const { lockfile } = input;
|
|
297
|
+
// An allowlisted name outside its entry's range is never audited in,
|
|
298
|
+
// even when an audited package declares it.
|
|
299
|
+
const audited = new Set([...candidates].filter((entry) => !approvedEntries.has(entry) && !outsideRootRange(input, input.adapter.normalizeName(entry.name), entry.version)));
|
|
300
|
+
const relations = new Map();
|
|
301
|
+
const declared = new Set();
|
|
302
|
+
for (const project of lockfile.projects)
|
|
303
|
+
for (const dependency of project.dependencies) {
|
|
304
|
+
const entry = lockfile.resolve(project.path, dependency.key);
|
|
305
|
+
if (entry)
|
|
306
|
+
declared.add(entry);
|
|
307
|
+
}
|
|
308
|
+
const queue = [];
|
|
309
|
+
for (const entry of audited)
|
|
310
|
+
if (declared.has(entry)) {
|
|
311
|
+
relations.set(entry, { relation: "top-level" });
|
|
312
|
+
queue.push(entry);
|
|
313
|
+
}
|
|
314
|
+
const via = new Map(queue.map((entry) => [entry, entry.name]));
|
|
315
|
+
while (queue.length > 0) {
|
|
316
|
+
const entry = queue.shift();
|
|
317
|
+
for (const child of edges.get(entry) ?? []) {
|
|
318
|
+
if (via.has(child) || !audited.has(child))
|
|
319
|
+
continue;
|
|
320
|
+
via.set(child, via.get(entry));
|
|
321
|
+
relations.set(child, { relation: "transitive", via: via.get(entry) });
|
|
322
|
+
queue.push(child);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
for (const entry of audited)
|
|
326
|
+
if (!relations.has(entry))
|
|
327
|
+
relations.set(entry, { relation: "unknown" });
|
|
328
|
+
return relations;
|
|
186
329
|
}
|
|
187
330
|
function safeSatisfies(adapter, version, range) {
|
|
188
331
|
try {
|
|
@@ -213,6 +356,7 @@ async function loadFacts(input, layer, outcomes) {
|
|
|
213
356
|
if (missing.length === 0)
|
|
214
357
|
return;
|
|
215
358
|
const fresh = new Map();
|
|
359
|
+
const complete = [];
|
|
216
360
|
await eachLimited(missing, input.factConcurrency ?? DEFAULT_PLAN_FACT_CONCURRENCY, async ({ name, version }) => {
|
|
217
361
|
const key = versionKey(name, version);
|
|
218
362
|
try {
|
|
@@ -227,6 +371,13 @@ async function loadFacts(input, layer, outcomes) {
|
|
|
227
371
|
});
|
|
228
372
|
return;
|
|
229
373
|
}
|
|
374
|
+
// A registry that gives the publish time with the version (PyPI) needs no second read.
|
|
375
|
+
if (fact.publishedAt) {
|
|
376
|
+
const stored = { ...fact, publishedAt: fact.publishedAt };
|
|
377
|
+
complete.push(stored);
|
|
378
|
+
outcomes.set(key, checkedFact(input, stored));
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
230
381
|
fresh.set(key, fact);
|
|
231
382
|
}
|
|
232
383
|
catch (error) {
|
|
@@ -239,7 +390,6 @@ async function loadFacts(input, layer, outcomes) {
|
|
|
239
390
|
const byName = new Map();
|
|
240
391
|
for (const fact of fresh.values())
|
|
241
392
|
byName.set(fact.name, [...(byName.get(fact.name) ?? []), fact.version]);
|
|
242
|
-
const complete = [];
|
|
243
393
|
await eachLimited([...byName.entries()], input.timeConcurrency ?? DEFAULT_PLAN_TIME_CONCURRENCY, async ([name, versions]) => {
|
|
244
394
|
let times;
|
|
245
395
|
try {
|
|
@@ -300,5 +450,8 @@ function upstreamRefusal(error) {
|
|
|
300
450
|
return { code: "wardby_metadata_too_large", reason: error.message };
|
|
301
451
|
if (error instanceof RegistryError && error.code === "wardby_package_not_found")
|
|
302
452
|
return { code: "wardby_package_not_found", reason: error.message };
|
|
453
|
+
// A release with nothing the registry may serve (PyPI: no wheel) stays so.
|
|
454
|
+
if (error instanceof RegistryError && error.code === "wardby_file_not_allowed")
|
|
455
|
+
return { code: "wardby_file_not_allowed", reason: error.message, intrinsic: true };
|
|
303
456
|
return { code: "wardby_upstream_error", reason: "the registry could not be read for it; try again" };
|
|
304
457
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import type { PrismaClient } from "#prisma";
|
|
2
2
|
import type { FileDependency } from "../../../coding/registry/types.js";
|
|
3
|
-
import type { ApprovedVersion, PlanRefusedVersion, RegistryFetchRecord, RegistryRunContext, RegistryStore, StoredVersionFact } from "./store.js";
|
|
3
|
+
import type { ApprovedDownload, ApprovedVersion, PlanRefusedVersion, RegistryAuditInsert, RegistryFetchRecord, RegistryRunContext, RegistryStore, StoredVersionFact } from "./store.js";
|
|
4
4
|
export declare class PrismaRegistryStore implements RegistryStore {
|
|
5
5
|
private readonly db;
|
|
6
6
|
constructor(db: PrismaClient);
|
|
7
7
|
findRunByRegistryTokenHash(hash: string, now: Date): Promise<RegistryRunContext | null>;
|
|
8
8
|
isAllowedDependency(runId: string, ecosystem: string, name: string): Promise<boolean>;
|
|
9
|
+
findAllowance(runId: string, ecosystem: string, name: string): Promise<{
|
|
10
|
+
auditedVia: string | null;
|
|
11
|
+
} | null>;
|
|
9
12
|
addAllowances(runId: string, ecosystem: string, names: readonly string[]): Promise<void>;
|
|
13
|
+
addAuditedAllowances(runId: string, ecosystem: string, names: readonly string[], auditedVia: string): Promise<void>;
|
|
14
|
+
recordAudit(record: RegistryAuditInsert): Promise<void>;
|
|
10
15
|
allowedExtras(runId: string, ecosystem: string, name: string): Promise<string[]>;
|
|
11
16
|
addExtraAllowances(runId: string, ecosystem: string, dependencies: readonly FileDependency[]): Promise<void>;
|
|
12
17
|
recordFetch(record: RegistryFetchRecord): Promise<void>;
|
|
@@ -18,20 +23,21 @@ export declare class PrismaRegistryStore implements RegistryStore {
|
|
|
18
23
|
listFetches(runId: string): Promise<(RegistryFetchRecord & {
|
|
19
24
|
createdAt: Date;
|
|
20
25
|
})[]>;
|
|
26
|
+
listRecentRefusals(runId: string, since: Date, limit: number): Promise<(RegistryFetchRecord & {
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
})[]>;
|
|
21
29
|
getVersionFacts(ecosystem: string, versions: readonly {
|
|
22
30
|
name: string;
|
|
23
31
|
version: string;
|
|
24
32
|
}[]): Promise<StoredVersionFact[]>;
|
|
25
33
|
putVersionFacts(ecosystem: string, facts: readonly StoredVersionFact[]): Promise<void>;
|
|
26
34
|
approveVersions(runId: string, ecosystem: string, versions: readonly ApprovedVersion[]): Promise<void>;
|
|
27
|
-
findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<
|
|
28
|
-
integrity: string;
|
|
29
|
-
downloadUrl: string;
|
|
30
|
-
} | null>;
|
|
35
|
+
findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<ApprovedDownload | null>;
|
|
31
36
|
refusePlanVersions(runId: string, ecosystem: string, versions: readonly PlanRefusedVersion[]): Promise<void>;
|
|
32
37
|
findPlanRefusal(runId: string, ecosystem: string, name: string, version: string): Promise<{
|
|
33
38
|
code: string;
|
|
34
39
|
reason: string;
|
|
35
40
|
publishedAt: Date | null;
|
|
36
41
|
} | null>;
|
|
42
|
+
recordDependencyCacheLockHash(runId: string, lockHash: string, max: number): Promise<void>;
|
|
37
43
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isPackageAuditMode, parsePackageAuditVerdict } from "../../../coding/registry/audit-mode.js";
|
|
1
2
|
import { extraAllowanceName, extraOfAllowanceName } from "./store.js";
|
|
2
3
|
/** Versions looked up per query, so a 5000-entry lockfile is a handful of
|
|
3
4
|
* bounded queries rather than one enormous OR. */
|
|
@@ -14,7 +15,17 @@ export class PrismaRegistryStore {
|
|
|
14
15
|
runId: true,
|
|
15
16
|
status: true,
|
|
16
17
|
deadlineAt: true,
|
|
17
|
-
run: {
|
|
18
|
+
run: {
|
|
19
|
+
select: {
|
|
20
|
+
packageAllowlist: true,
|
|
21
|
+
packagePolicy: true,
|
|
22
|
+
repository: true,
|
|
23
|
+
workerImage: true,
|
|
24
|
+
toolImage: true,
|
|
25
|
+
dependencyCache: true,
|
|
26
|
+
packageAuditMode: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
18
29
|
},
|
|
19
30
|
});
|
|
20
31
|
if (!session || session.status !== "active" || session.deadlineAt <= now)
|
|
@@ -24,6 +35,10 @@ export class PrismaRegistryStore {
|
|
|
24
35
|
deadlineAt: session.deadlineAt,
|
|
25
36
|
allowlist: (session.run.packageAllowlist ?? {}),
|
|
26
37
|
policy: session.run.packagePolicy,
|
|
38
|
+
repository: session.run.repository,
|
|
39
|
+
cacheImage: session.run.toolImage ?? session.run.workerImage,
|
|
40
|
+
dependencyCache: session.run.dependencyCache,
|
|
41
|
+
packageAudit: isPackageAuditMode(session.run.packageAuditMode) ? session.run.packageAuditMode : null,
|
|
27
42
|
};
|
|
28
43
|
}
|
|
29
44
|
async isAllowedDependency(runId, ecosystem, name) {
|
|
@@ -36,6 +51,15 @@ export class PrismaRegistryStore {
|
|
|
36
51
|
});
|
|
37
52
|
return row !== null;
|
|
38
53
|
}
|
|
54
|
+
async findAllowance(runId, ecosystem, name) {
|
|
55
|
+
// An extra's row (`name[extra]`) is never a package allowance.
|
|
56
|
+
if (name.includes("["))
|
|
57
|
+
return null;
|
|
58
|
+
return this.db.registryAllowance.findUnique({
|
|
59
|
+
where: { runId_ecosystem_name: { runId, ecosystem, name } },
|
|
60
|
+
select: { auditedVia: true },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
39
63
|
async addAllowances(runId, ecosystem, names) {
|
|
40
64
|
if (names.length === 0)
|
|
41
65
|
return;
|
|
@@ -44,6 +68,32 @@ export class PrismaRegistryStore {
|
|
|
44
68
|
skipDuplicates: true,
|
|
45
69
|
});
|
|
46
70
|
}
|
|
71
|
+
async addAuditedAllowances(runId, ecosystem, names, auditedVia) {
|
|
72
|
+
if (names.length === 0)
|
|
73
|
+
return;
|
|
74
|
+
// Insert-only (the proxy has no UPDATE): an existing row keeps its first writer.
|
|
75
|
+
await this.db.registryAllowance.createMany({
|
|
76
|
+
data: [...new Set(names)].map((name) => ({ runId, ecosystem, name, auditedVia })),
|
|
77
|
+
skipDuplicates: true,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async recordAudit(record) {
|
|
81
|
+
await this.db.registryAuditRecord.createMany({
|
|
82
|
+
data: [
|
|
83
|
+
{
|
|
84
|
+
runId: record.runId,
|
|
85
|
+
ecosystem: record.ecosystem,
|
|
86
|
+
name: record.name,
|
|
87
|
+
version: record.version,
|
|
88
|
+
relation: record.relation,
|
|
89
|
+
via: record.via ?? null,
|
|
90
|
+
sizeBytes: record.sizeBytes ?? null,
|
|
91
|
+
advisories: record.advisories.map(({ id, severity, summary }) => ({ id, severity, summary })),
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
skipDuplicates: true,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
47
97
|
async allowedExtras(runId, ecosystem, name) {
|
|
48
98
|
const rows = await this.db.registryAllowance.findMany({
|
|
49
99
|
where: { runId, ecosystem, name: { startsWith: `${name}[` } },
|
|
@@ -73,18 +123,15 @@ export class PrismaRegistryStore {
|
|
|
73
123
|
}
|
|
74
124
|
async listFetches(runId) {
|
|
75
125
|
const rows = await this.db.registryFetch.findMany({ where: { runId }, orderBy: { createdAt: "asc" } });
|
|
76
|
-
return rows.map(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
reason: row.reason ?? undefined,
|
|
86
|
-
createdAt: row.createdAt,
|
|
87
|
-
}));
|
|
126
|
+
return rows.map(fetchRecordOf);
|
|
127
|
+
}
|
|
128
|
+
async listRecentRefusals(runId, since, limit) {
|
|
129
|
+
const rows = await this.db.registryFetch.findMany({
|
|
130
|
+
where: { runId, outcome: "refused", createdAt: { gte: since } },
|
|
131
|
+
orderBy: { createdAt: "desc" },
|
|
132
|
+
take: limit,
|
|
133
|
+
});
|
|
134
|
+
return rows.map(fetchRecordOf);
|
|
88
135
|
}
|
|
89
136
|
async getVersionFacts(ecosystem, versions) {
|
|
90
137
|
const facts = [];
|
|
@@ -117,7 +164,13 @@ export class PrismaRegistryStore {
|
|
|
117
164
|
publishedAt: fact.publishedAt,
|
|
118
165
|
integrity: fact.integrity,
|
|
119
166
|
downloadUrl: fact.downloadUrl,
|
|
120
|
-
dependencies: fact.dependencies.map(({ key, name, range }) => ({
|
|
167
|
+
dependencies: fact.dependencies.map(({ key, name, range, extras, when }) => ({
|
|
168
|
+
key,
|
|
169
|
+
name,
|
|
170
|
+
range,
|
|
171
|
+
...(extras ? { extras: [...extras] } : {}),
|
|
172
|
+
...(when ? { when: [...when] } : {}),
|
|
173
|
+
})),
|
|
121
174
|
})),
|
|
122
175
|
skipDuplicates: true,
|
|
123
176
|
});
|
|
@@ -126,14 +179,32 @@ export class PrismaRegistryStore {
|
|
|
126
179
|
if (versions.length === 0)
|
|
127
180
|
return;
|
|
128
181
|
await this.db.registryApprovedVersion.createMany({
|
|
129
|
-
data: versions.map(({ name, version, integrity }) => ({
|
|
182
|
+
data: versions.map(({ name, version, integrity, acceptedAdvisories, audit }) => ({
|
|
183
|
+
runId,
|
|
184
|
+
ecosystem,
|
|
185
|
+
name,
|
|
186
|
+
version,
|
|
187
|
+
integrity,
|
|
188
|
+
acceptedAdvisories: [...(acceptedAdvisories ?? [])],
|
|
189
|
+
...(audit
|
|
190
|
+
? {
|
|
191
|
+
audit: {
|
|
192
|
+
relation: audit.relation,
|
|
193
|
+
...(audit.via ? { via: audit.via } : {}),
|
|
194
|
+
...(audit.advisories?.length
|
|
195
|
+
? { advisories: audit.advisories.map(({ id, severity, summary }) => ({ id, severity, summary })) }
|
|
196
|
+
: {}),
|
|
197
|
+
},
|
|
198
|
+
}
|
|
199
|
+
: {}),
|
|
200
|
+
})),
|
|
130
201
|
skipDuplicates: true,
|
|
131
202
|
});
|
|
132
203
|
}
|
|
133
204
|
async findApprovedVersion(runId, ecosystem, name, version) {
|
|
134
205
|
const approval = await this.db.registryApprovedVersion.findUnique({
|
|
135
206
|
where: { runId_ecosystem_name_version: { runId, ecosystem, name, version } },
|
|
136
|
-
select: { integrity: true },
|
|
207
|
+
select: { integrity: true, acceptedAdvisories: true, audit: true },
|
|
137
208
|
});
|
|
138
209
|
if (!approval)
|
|
139
210
|
return null;
|
|
@@ -141,7 +212,15 @@ export class PrismaRegistryStore {
|
|
|
141
212
|
where: { ecosystem_name_version: { ecosystem, name, version } },
|
|
142
213
|
select: { downloadUrl: true },
|
|
143
214
|
});
|
|
144
|
-
|
|
215
|
+
const audit = parsePackageAuditVerdict(approval.audit);
|
|
216
|
+
return fact
|
|
217
|
+
? {
|
|
218
|
+
integrity: approval.integrity,
|
|
219
|
+
downloadUrl: fact.downloadUrl,
|
|
220
|
+
acceptedAdvisories: approval.acceptedAdvisories,
|
|
221
|
+
...(audit ? { audit } : {}),
|
|
222
|
+
}
|
|
223
|
+
: null;
|
|
145
224
|
}
|
|
146
225
|
async refusePlanVersions(runId, ecosystem, versions) {
|
|
147
226
|
if (versions.length === 0)
|
|
@@ -165,4 +244,28 @@ export class PrismaRegistryStore {
|
|
|
165
244
|
select: { code: true, reason: true, publishedAt: true },
|
|
166
245
|
});
|
|
167
246
|
}
|
|
247
|
+
async recordDependencyCacheLockHash(runId, lockHash, max) {
|
|
248
|
+
// One statement, so a concurrent seal or plan can never slip past a check.
|
|
249
|
+
await this.db.$executeRaw `
|
|
250
|
+
UPDATE "CodingProxySession"
|
|
251
|
+
SET "dependencyCacheLockHashes" = array_append("dependencyCacheLockHashes", ${lockHash})
|
|
252
|
+
WHERE "runId" = ${runId}
|
|
253
|
+
AND "dependencyCacheSealedAt" IS NULL
|
|
254
|
+
AND NOT (${lockHash} = ANY("dependencyCacheLockHashes"))
|
|
255
|
+
AND cardinality("dependencyCacheLockHashes") < ${max}`;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function fetchRecordOf(row) {
|
|
259
|
+
return {
|
|
260
|
+
runId: row.runId,
|
|
261
|
+
ecosystem: row.ecosystem,
|
|
262
|
+
name: row.name,
|
|
263
|
+
version: row.version ?? undefined,
|
|
264
|
+
filename: row.filename ?? undefined,
|
|
265
|
+
integrity: row.integrity ?? undefined,
|
|
266
|
+
sizeBytes: row.sizeBytes ?? undefined,
|
|
267
|
+
outcome: row.outcome,
|
|
268
|
+
reason: row.reason ?? undefined,
|
|
269
|
+
createdAt: row.createdAt,
|
|
270
|
+
};
|
|
168
271
|
}
|