@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
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* - a version or event the comparator cannot parse counts as affected
|
|
17
17
|
* (fail closed).
|
|
18
18
|
*/
|
|
19
|
+
import { type AuditAdvisory } from "../../../coding/registry/audit-mode.js";
|
|
19
20
|
import { type RegistryAdapter, type UpstreamFetch } from "../../../coding/registry/types.js";
|
|
20
21
|
export declare const DEFAULT_VULN_CACHE_ENTRIES = 10000;
|
|
21
22
|
/** Exact versions whose querybatch results are cached. */
|
|
@@ -39,6 +40,7 @@ interface OsvAffected {
|
|
|
39
40
|
}
|
|
40
41
|
interface OsvVuln {
|
|
41
42
|
id: string;
|
|
43
|
+
summary?: unknown;
|
|
42
44
|
aliases?: string[];
|
|
43
45
|
affected?: (OsvAffected & {
|
|
44
46
|
database_specific?: Record<string, unknown>;
|
|
@@ -58,11 +60,50 @@ export declare function isMalware(vuln: OsvVuln): boolean;
|
|
|
58
60
|
* names compare, and how versions order. */
|
|
59
61
|
export type AuditAdapter = Pick<RegistryAdapter, "osvEcosystem" | "normalizeName" | "compareVersions">;
|
|
60
62
|
export interface AdvisoryIndex {
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
+
/** Ids of the blocking advisories (HIGH, CRITICAL or malware) that affect
|
|
64
|
+
* `version`, minus those waived by `accepted` (see `isWaived`). Without
|
|
65
|
+
* `accepted`, or with an empty set, every blocking advisory. With
|
|
66
|
+
* `auditAll` (package audit mode `full`), only those that can never be
|
|
67
|
+
* served past: malware. */
|
|
68
|
+
withheld(version: string, accepted?: ReadonlySet<string>, auditAll?: boolean): readonly string[];
|
|
69
|
+
/** Ids of the blocking advisories affecting `version` that `accepted`
|
|
70
|
+
* waives: exactly those `withheld` subtracts. For reporting. */
|
|
71
|
+
waived(version: string, accepted: ReadonlySet<string>): readonly string[];
|
|
63
72
|
/** Advisory ids of any other severity that affect `version`. */
|
|
64
73
|
reported(version: string): readonly string[];
|
|
74
|
+
/** Blocking, non-malware, non-accepted advisories that `auditAll` lets
|
|
75
|
+
* through, with detail: what a full-mode run records when it serves `version`. */
|
|
76
|
+
audited?(version: string, accepted: ReadonlySet<string>): readonly AuditAdvisory[];
|
|
65
77
|
}
|
|
78
|
+
/** A blocking advisory, with what deciding a waiver needs. */
|
|
79
|
+
export interface WithheldAdvisory {
|
|
80
|
+
id: string;
|
|
81
|
+
/** Reports malicious code (`isMalware`): never waived. */
|
|
82
|
+
malware: boolean;
|
|
83
|
+
/** The advisory's OSV aliases (CVE ids, other GHSA ids, …). */
|
|
84
|
+
aliases: readonly string[];
|
|
85
|
+
/** OSV severity, upper-cased (HIGH, CRITICAL, …); absent when OSV gives none (malware). */
|
|
86
|
+
severity?: string;
|
|
87
|
+
/** OSV summary as plain bounded text; absent when OSV gives none. */
|
|
88
|
+
summary?: string;
|
|
89
|
+
}
|
|
90
|
+
/** Whether `accepted` waives a blocking advisory: it is not malware, and
|
|
91
|
+
* its id or one of its aliases is accepted. Malware is never waived,
|
|
92
|
+
* whatever the accepted set lists. */
|
|
93
|
+
export declare function isWaived(advisory: WithheldAdvisory, accepted?: ReadonlySet<string>): boolean;
|
|
94
|
+
/** Splits the blocking advisories affecting one version into those still
|
|
95
|
+
* withholding it, those `accepted` waives, and (package audit mode `full`,
|
|
96
|
+
* `auditAll`) those served past and recorded. Malware is always withheld.
|
|
97
|
+
* The version is withheld while `withheld` is non-empty. */
|
|
98
|
+
export declare function splitWaived<T extends WithheldAdvisory>(advisories: readonly T[], accepted?: ReadonlySet<string>, options?: {
|
|
99
|
+
auditAll?: boolean;
|
|
100
|
+
}): {
|
|
101
|
+
withheld: T[];
|
|
102
|
+
waived: T[];
|
|
103
|
+
audited: T[];
|
|
104
|
+
};
|
|
105
|
+
/** A blocking advisory as package audit mode records it. */
|
|
106
|
+
export declare function auditAdvisoryOf(advisory: WithheldAdvisory): AuditAdvisory;
|
|
66
107
|
type Compare = (a: string, b: string) => number;
|
|
67
108
|
/** OSV range evaluation: sort events by version, then sweep. A version or
|
|
68
109
|
* event the comparator cannot parse makes the version count as affected. */
|
|
@@ -73,9 +114,10 @@ export interface AuditedVersion {
|
|
|
73
114
|
name: string;
|
|
74
115
|
version: string;
|
|
75
116
|
}
|
|
76
|
-
/** `name@version` -> the HIGH/CRITICAL
|
|
77
|
-
* version with none is absent.
|
|
78
|
-
|
|
117
|
+
/** `name@version` -> the blocking (HIGH/CRITICAL or malware) advisories
|
|
118
|
+
* affecting it; a version with none is absent. Independent of any
|
|
119
|
+
* accepted set: callers subtract waivers with `splitWaived`. */
|
|
120
|
+
export type WithheldVersions = Map<string, WithheldAdvisory[]>;
|
|
79
121
|
export declare const versionKey: (name: string, version: string) => string;
|
|
80
122
|
export declare class OsvAudit {
|
|
81
123
|
private readonly options;
|
|
@@ -85,8 +127,8 @@ export declare class OsvAudit {
|
|
|
85
127
|
private readonly cache;
|
|
86
128
|
/** Single-flight: concurrent audits of one package share one OSV query. */
|
|
87
129
|
private readonly loads;
|
|
88
|
-
/** Advisory severities by id, with the
|
|
89
|
-
* read at, least recently used first. */
|
|
130
|
+
/** Advisory severities (and malware flag and aliases) by id, with the
|
|
131
|
+
* OSV `modified` time they were read at, least recently used first. */
|
|
90
132
|
private readonly vulns;
|
|
91
133
|
/** Advisory ids (and their `modified` time) per exact version from
|
|
92
134
|
* querybatch, for the audit TTL, least recently used first, so repeated
|
|
@@ -121,9 +163,10 @@ export declare class OsvAudit {
|
|
|
121
163
|
auditVersions(adapter: AuditAdapter, versions: readonly AuditedVersion[], signal?: AbortSignal): Promise<WithheldVersions>;
|
|
122
164
|
private loadVersions;
|
|
123
165
|
private rememberBatch;
|
|
124
|
-
/** Whether an advisory
|
|
125
|
-
* `modified` time for
|
|
126
|
-
|
|
166
|
+
/** Whether an advisory blocks (HIGH, CRITICAL or malware), whether it is
|
|
167
|
+
* malware, and its aliases, cached by id while OSV's `modified` time for
|
|
168
|
+
* it is unchanged. */
|
|
169
|
+
private detail;
|
|
127
170
|
private remember;
|
|
128
171
|
private load;
|
|
129
172
|
private query;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* - a version or event the comparator cannot parse counts as affected
|
|
17
17
|
* (fail closed).
|
|
18
18
|
*/
|
|
19
|
+
import { sanitizeAuditSummary } from "../../../coding/registry/audit-mode.js";
|
|
19
20
|
import { RegistryError } from "../../../coding/registry/types.js";
|
|
20
21
|
import { boundedMetadataFetch, DEFAULT_MAX_METADATA_BYTES, DEFAULT_METADATA_TIMEOUT_MS } from "./bounded-fetch.js";
|
|
21
22
|
const OSV_QUERY = "https://api.osv.dev/v1/query";
|
|
@@ -52,10 +53,59 @@ export function isMalware(vuln) {
|
|
|
52
53
|
(typeof detail.source === "string" && detail.source.includes("/malicious-packages/")));
|
|
53
54
|
});
|
|
54
55
|
}
|
|
56
|
+
/** An advisory's OSV severity (database_specific.severity), upper-cased; "" when it has none. */
|
|
57
|
+
function severityOf(vuln) {
|
|
58
|
+
const severity = vuln.database_specific?.severity;
|
|
59
|
+
return typeof severity === "string" ? severity.toUpperCase() : "";
|
|
60
|
+
}
|
|
55
61
|
/** Whether an advisory withholds the versions it affects. */
|
|
56
62
|
function blocks(vuln) {
|
|
57
|
-
return BLOCKING.has(vuln
|
|
63
|
+
return BLOCKING.has(severityOf(vuln)) || isMalware(vuln);
|
|
64
|
+
}
|
|
65
|
+
/** What package audit mode records of an advisory: its severity, and its summary bounded at the source. */
|
|
66
|
+
function auditDetail(vuln) {
|
|
67
|
+
const severity = severityOf(vuln);
|
|
68
|
+
const summary = sanitizeAuditSummary(vuln.summary);
|
|
69
|
+
return { ...(severity ? { severity } : {}), ...(summary ? { summary } : {}) };
|
|
70
|
+
}
|
|
71
|
+
/** Whether `accepted` waives a blocking advisory: it is not malware, and
|
|
72
|
+
* its id or one of its aliases is accepted. Malware is never waived,
|
|
73
|
+
* whatever the accepted set lists. */
|
|
74
|
+
export function isWaived(advisory, accepted) {
|
|
75
|
+
if (advisory.malware || !accepted || accepted.size === 0)
|
|
76
|
+
return false;
|
|
77
|
+
// Belt and braces for entries not built from an OSV record here.
|
|
78
|
+
if ([advisory.id, ...advisory.aliases].some((id) => id.startsWith("MAL-")))
|
|
79
|
+
return false;
|
|
80
|
+
return accepted.has(advisory.id) || advisory.aliases.some((alias) => accepted.has(alias));
|
|
81
|
+
}
|
|
82
|
+
/** Whether a blocking advisory reports, or may report, malicious code: never served in any mode. */
|
|
83
|
+
function isMalwareAdvisory(advisory) {
|
|
84
|
+
return advisory.malware || [advisory.id, ...advisory.aliases].some((id) => id.startsWith("MAL-"));
|
|
58
85
|
}
|
|
86
|
+
/** Splits the blocking advisories affecting one version into those still
|
|
87
|
+
* withholding it, those `accepted` waives, and (package audit mode `full`,
|
|
88
|
+
* `auditAll`) those served past and recorded. Malware is always withheld.
|
|
89
|
+
* The version is withheld while `withheld` is non-empty. */
|
|
90
|
+
export function splitWaived(advisories, accepted, options = {}) {
|
|
91
|
+
const withheld = [];
|
|
92
|
+
const waived = [];
|
|
93
|
+
const audited = [];
|
|
94
|
+
for (const advisory of advisories) {
|
|
95
|
+
if (isWaived(advisory, accepted))
|
|
96
|
+
waived.push(advisory);
|
|
97
|
+
else if (options.auditAll && !isMalwareAdvisory(advisory))
|
|
98
|
+
audited.push(advisory);
|
|
99
|
+
else
|
|
100
|
+
withheld.push(advisory);
|
|
101
|
+
}
|
|
102
|
+
return { withheld, waived, audited };
|
|
103
|
+
}
|
|
104
|
+
/** A blocking advisory as package audit mode records it. */
|
|
105
|
+
export function auditAdvisoryOf(advisory) {
|
|
106
|
+
return { id: advisory.id, severity: advisory.severity ?? "UNKNOWN", summary: advisory.summary ?? "" };
|
|
107
|
+
}
|
|
108
|
+
const aliasesOf = (vuln) => Array.isArray(vuln.aliases) ? vuln.aliases.filter((alias) => typeof alias === "string") : [];
|
|
59
109
|
function eventVersion(event) {
|
|
60
110
|
return event.introduced ?? event.fixed ?? event.last_affected ?? event.limit;
|
|
61
111
|
}
|
|
@@ -122,11 +172,16 @@ function indexOf(advisories, adapter) {
|
|
|
122
172
|
const compare = (a, b) => adapter.compareVersions(a, b);
|
|
123
173
|
const matching = (version, blocking) => advisories
|
|
124
174
|
.filter((advisory) => advisory.blocking === blocking)
|
|
125
|
-
.filter((advisory) => advisory.affected.some((affected) => affects(version, affected, compare)))
|
|
126
|
-
|
|
127
|
-
return {
|
|
175
|
+
.filter((advisory) => advisory.affected.some((affected) => affects(version, affected, compare)));
|
|
176
|
+
const ids = (list) => list.map((advisory) => advisory.id);
|
|
177
|
+
return {
|
|
178
|
+
withheld: (version, accepted, auditAll) => ids(splitWaived(matching(version, true), accepted, { auditAll }).withheld),
|
|
179
|
+
waived: (version, accepted) => ids(splitWaived(matching(version, true), accepted).waived),
|
|
180
|
+
reported: (version) => ids(matching(version, false)),
|
|
181
|
+
audited: (version, accepted) => splitWaived(matching(version, true), accepted, { auditAll: true }).audited.map(auditAdvisoryOf),
|
|
182
|
+
};
|
|
128
183
|
}
|
|
129
|
-
const EMPTY_INDEX = { withheld: () => [], reported: () => [] };
|
|
184
|
+
const EMPTY_INDEX = { withheld: () => [], waived: () => [], reported: () => [], audited: () => [] };
|
|
130
185
|
export const DEFAULT_AUDIT_CACHE_ENTRIES = 5000;
|
|
131
186
|
export const versionKey = (name, version) => `${name}@${version}`;
|
|
132
187
|
export class OsvAudit {
|
|
@@ -137,8 +192,8 @@ export class OsvAudit {
|
|
|
137
192
|
cache = new Map();
|
|
138
193
|
/** Single-flight: concurrent audits of one package share one OSV query. */
|
|
139
194
|
loads = new Map();
|
|
140
|
-
/** Advisory severities by id, with the
|
|
141
|
-
* read at, least recently used first. */
|
|
195
|
+
/** Advisory severities (and malware flag and aliases) by id, with the
|
|
196
|
+
* OSV `modified` time they were read at, least recently used first. */
|
|
142
197
|
vulns = new Map();
|
|
143
198
|
/** Advisory ids (and their `modified` time) per exact version from
|
|
144
199
|
* querybatch, for the audit TTL, least recently used first, so repeated
|
|
@@ -286,10 +341,18 @@ export class OsvAudit {
|
|
|
286
341
|
while (cursor < ids.length) {
|
|
287
342
|
const id = ids[cursor++];
|
|
288
343
|
const advisory = found.get(id);
|
|
289
|
-
|
|
344
|
+
const detail = await this.detail(id, advisory.modified, signal);
|
|
345
|
+
if (!detail.blocking)
|
|
290
346
|
continue;
|
|
347
|
+
const entry = {
|
|
348
|
+
id,
|
|
349
|
+
malware: detail.malware,
|
|
350
|
+
aliases: detail.aliases,
|
|
351
|
+
...(detail.severity ? { severity: detail.severity } : {}),
|
|
352
|
+
...(detail.summary ? { summary: detail.summary } : {}),
|
|
353
|
+
};
|
|
291
354
|
for (const key of advisory.versions)
|
|
292
|
-
withheld.set(key, [...(withheld.get(key) ?? []),
|
|
355
|
+
withheld.set(key, [...(withheld.get(key) ?? []), entry]);
|
|
293
356
|
}
|
|
294
357
|
};
|
|
295
358
|
await Promise.all(Array.from({ length: Math.min(OSV_VULN_CONCURRENCY, ids.length) }, worker));
|
|
@@ -307,14 +370,15 @@ export class OsvAudit {
|
|
|
307
370
|
}
|
|
308
371
|
this.batchCache.set(key, { expires: now + this.ttlMs, vulns });
|
|
309
372
|
}
|
|
310
|
-
/** Whether an advisory
|
|
311
|
-
* `modified` time for
|
|
312
|
-
|
|
373
|
+
/** Whether an advisory blocks (HIGH, CRITICAL or malware), whether it is
|
|
374
|
+
* malware, and its aliases, cached by id while OSV's `modified` time for
|
|
375
|
+
* it is unchanged. */
|
|
376
|
+
async detail(id, modified, signal) {
|
|
313
377
|
const cached = this.vulns.get(id);
|
|
314
378
|
if (cached && modified !== "" && cached.modified === modified) {
|
|
315
379
|
this.vulns.delete(id);
|
|
316
380
|
this.vulns.set(id, cached); // most recently used
|
|
317
|
-
return cached
|
|
381
|
+
return cached;
|
|
318
382
|
}
|
|
319
383
|
const response = await this.fetch(`${OSV_VULN}${encodeURIComponent(id)}`, { accept: "application/json", signal });
|
|
320
384
|
if (!response.ok)
|
|
@@ -322,7 +386,13 @@ export class OsvAudit {
|
|
|
322
386
|
const vuln = (await response.json());
|
|
323
387
|
if (typeof vuln.id !== "string")
|
|
324
388
|
throw new Error("osv_vuln_invalid");
|
|
325
|
-
const
|
|
389
|
+
const detail = {
|
|
390
|
+
modified: typeof vuln.modified === "string" ? vuln.modified : modified,
|
|
391
|
+
blocking: blocks(vuln),
|
|
392
|
+
malware: isMalware(vuln),
|
|
393
|
+
aliases: aliasesOf(vuln),
|
|
394
|
+
...auditDetail(vuln),
|
|
395
|
+
};
|
|
326
396
|
this.vulns.delete(id);
|
|
327
397
|
while (this.vulns.size >= (this.options.maxVulnEntries ?? DEFAULT_VULN_CACHE_ENTRIES)) {
|
|
328
398
|
const oldest = this.vulns.keys().next();
|
|
@@ -330,8 +400,8 @@ export class OsvAudit {
|
|
|
330
400
|
break;
|
|
331
401
|
this.vulns.delete(oldest.value);
|
|
332
402
|
}
|
|
333
|
-
this.vulns.set(id,
|
|
334
|
-
return
|
|
403
|
+
this.vulns.set(id, detail);
|
|
404
|
+
return detail;
|
|
335
405
|
}
|
|
336
406
|
remember(key, advisories) {
|
|
337
407
|
const now = this.now();
|
|
@@ -356,7 +426,14 @@ export class OsvAudit {
|
|
|
356
426
|
adapter.normalizeName(entry.package.name) === wanted);
|
|
357
427
|
if (affected.length === 0)
|
|
358
428
|
continue;
|
|
359
|
-
advisories.push({
|
|
429
|
+
advisories.push({
|
|
430
|
+
id: vuln.id,
|
|
431
|
+
blocking: blocks(vuln),
|
|
432
|
+
malware: isMalware(vuln),
|
|
433
|
+
aliases: aliasesOf(vuln),
|
|
434
|
+
...auditDetail(vuln),
|
|
435
|
+
affected,
|
|
436
|
+
});
|
|
360
437
|
}
|
|
361
438
|
return advisories;
|
|
362
439
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ParsedLockfile } from "../../../coding/registry/types.js";
|
|
2
|
+
export interface ParseRequest {
|
|
3
|
+
ecosystem: string;
|
|
4
|
+
body: string;
|
|
5
|
+
maxEntries: number;
|
|
6
|
+
proxyRegistryUrl: string;
|
|
7
|
+
}
|
|
8
|
+
/** A ParsedLockfile without its functions: `edges[i]` lists, for
|
|
9
|
+
* `entries[i]`, each dependency key the lockfile records that resolves to
|
|
10
|
+
* an entry, with that entry's index; `projectEdges[i]` the same for
|
|
11
|
+
* `projects[i]`. */
|
|
12
|
+
export interface ShippedLockfile {
|
|
13
|
+
entries: ParsedLockfile["entries"];
|
|
14
|
+
projects: ParsedLockfile["projects"];
|
|
15
|
+
integrity?: ParsedLockfile["integrity"];
|
|
16
|
+
edges: [key: string, target: number][][];
|
|
17
|
+
projectEdges: [key: string, target: number][][];
|
|
18
|
+
}
|
|
19
|
+
export type ParseResponse = {
|
|
20
|
+
ok: true;
|
|
21
|
+
lockfile: ShippedLockfile;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
status: number;
|
|
25
|
+
code: string;
|
|
26
|
+
message: string;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
unexpected: true;
|
|
30
|
+
message: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function parseAndShip(request: ParseRequest): ShippedLockfile;
|
|
33
|
+
/** The answer for one parse: the lockfile, the parser's refusal, or (a bug,
|
|
34
|
+
* not a verdict about the lockfile) the unexpected error's message, which
|
|
35
|
+
* the main thread logs. */
|
|
36
|
+
export declare function responseFor(parse: () => ShippedLockfile): ParseResponse;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs inside a worker thread spawned by lockfile-parse.ts: parses one
|
|
3
|
+
* lockfile with the ecosystem's own parser, off the proxy's event loop, and
|
|
4
|
+
* posts back a plain, structured-cloneable form of the result (entries,
|
|
5
|
+
* projects, and the edge table `resolve` answers from). `parentPort` is
|
|
6
|
+
* null when this file is merely imported, so nothing runs then.
|
|
7
|
+
*/
|
|
8
|
+
import { parentPort } from "node:worker_threads";
|
|
9
|
+
import { REGISTRY_ADAPTERS } from "../../../coding/registry/adapters.js";
|
|
10
|
+
import { RegistryError } from "../../../coding/registry/types.js";
|
|
11
|
+
/** At most this many edges per entry are shipped (far above any real
|
|
12
|
+
* package's dependency count), so a crafted entry with a huge dependency
|
|
13
|
+
* map can't make the main thread deserialize millions of them. */
|
|
14
|
+
const MAX_EDGES_PER_ENTRY = 2000;
|
|
15
|
+
export function parseAndShip(request) {
|
|
16
|
+
const support = REGISTRY_ADAPTERS.get(request.ecosystem)?.lockfilePlan;
|
|
17
|
+
if (!support)
|
|
18
|
+
throw new RegistryError(404, "wardby_plan_unsupported", `no lockfile plans for ${request.ecosystem}`);
|
|
19
|
+
const parsed = support.parse(request.body, {
|
|
20
|
+
maxEntries: request.maxEntries,
|
|
21
|
+
proxyRegistryUrl: request.proxyRegistryUrl,
|
|
22
|
+
});
|
|
23
|
+
if (!parsed.dependencyKeys)
|
|
24
|
+
throw new Error("this lockfile format cannot be parsed off the event loop");
|
|
25
|
+
const index = new Map(parsed.entries.map((entry, at) => [entry, at]));
|
|
26
|
+
const edgesOf = (path, what) => {
|
|
27
|
+
let keys = parsed.dependencyKeys(path);
|
|
28
|
+
// A project's edges only label audited packages top-level (best effort):
|
|
29
|
+
// past the bound they are cut, never a reason to refuse the plan.
|
|
30
|
+
if (what === "project")
|
|
31
|
+
keys = keys.slice(0, MAX_EDGES_PER_ENTRY);
|
|
32
|
+
if (keys.length > MAX_EDGES_PER_ENTRY)
|
|
33
|
+
throw new RegistryError(413, "wardby_lockfile_too_large", `lockfile ${what} "${path}" lists ${keys.length} dependencies; at most ${MAX_EDGES_PER_ENTRY} are read`);
|
|
34
|
+
const out = [];
|
|
35
|
+
for (const key of keys) {
|
|
36
|
+
const target = parsed.resolve(path, key);
|
|
37
|
+
const at = target && index.get(target);
|
|
38
|
+
if (at !== undefined && at !== null)
|
|
39
|
+
out.push([key, at]);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
entries: parsed.entries,
|
|
45
|
+
projects: parsed.projects,
|
|
46
|
+
...(parsed.integrity ? { integrity: parsed.integrity } : {}),
|
|
47
|
+
edges: parsed.entries.map((entry) => edgesOf(entry.path, "entry")),
|
|
48
|
+
projectEdges: parsed.projects.map((project) => edgesOf(project.path, "project")),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** The answer for one parse: the lockfile, the parser's refusal, or (a bug,
|
|
52
|
+
* not a verdict about the lockfile) the unexpected error's message, which
|
|
53
|
+
* the main thread logs. */
|
|
54
|
+
export function responseFor(parse) {
|
|
55
|
+
try {
|
|
56
|
+
return { ok: true, lockfile: parse() };
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (error instanceof RegistryError)
|
|
60
|
+
return { ok: false, status: error.status, code: error.code, message: error.message };
|
|
61
|
+
return { ok: false, unexpected: true, message: error instanceof Error ? String(error) : "unknown error" };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (parentPort) {
|
|
65
|
+
const port = parentPort;
|
|
66
|
+
port.on("message", (request) => port.postMessage(responseFor(() => parseAndShip(request))));
|
|
67
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ParsedLockfile } from "../../../coding/registry/types.js";
|
|
2
|
+
/** Time one off-thread lockfile parse may take. Real lockfiles at the
|
|
3
|
+
* entry bound parse in well under a second. */
|
|
4
|
+
export declare const DEFAULT_LOCKFILE_PARSE_TIMEOUT_MS = 15000;
|
|
5
|
+
export declare function parseWorkerHeapMb(maxEntries: number): number;
|
|
6
|
+
export declare function parseLockfileOffThread(ecosystem: string, body: string, options: {
|
|
7
|
+
maxEntries: number;
|
|
8
|
+
proxyRegistryUrl: string;
|
|
9
|
+
}, limits?: {
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
/** Heap bound for the worker (default parseWorkerHeapMb(maxEntries)). */
|
|
13
|
+
maxOldGenerationSizeMb?: number;
|
|
14
|
+
/** Tests only: the worker script to run. */
|
|
15
|
+
workerUrl?: URL;
|
|
16
|
+
}): Promise<ParsedLockfile>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a lockfile in a disposable worker thread with a hard time bound,
|
|
3
|
+
* for the formats that are costly to read (pnpm's and yarn's: YAML, or
|
|
4
|
+
* yarn classic's own format). A lockfile is attacker-controlled up to the
|
|
5
|
+
* 20 MiB plan cap, and a synchronous parse can't be interrupted, so on the
|
|
6
|
+
* event loop a crafted one could stall every request the proxy serves (model
|
|
7
|
+
* traffic included) for seconds. A worker's terminate() can stop it; the
|
|
8
|
+
* event loop only deserializes the bounded result (entries and their edges).
|
|
9
|
+
*
|
|
10
|
+
* One worker per parse, never reused (the same choice as the sandbox's
|
|
11
|
+
* parser pool): plans already run at most `planConcurrency` at once.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { Worker } from "node:worker_threads";
|
|
16
|
+
import { RegistryError } from "../../../coding/registry/types.js";
|
|
17
|
+
/** Time one off-thread lockfile parse may take. Real lockfiles at the
|
|
18
|
+
* entry bound parse in well under a second. */
|
|
19
|
+
export const DEFAULT_LOCKFILE_PARSE_TIMEOUT_MS = 15_000;
|
|
20
|
+
/** Heap one parse worker may use before it is stopped, per 5000 entries
|
|
21
|
+
* the plan may have (REGISTRY_PLAN_MAX_ENTRIES, at least the default's
|
|
22
|
+
* share). A realistic 5000-entry pnpm-lock.yaml (3.4 MiB: peers, engines,
|
|
23
|
+
* six dependencies a snapshot) needs 129 to 160 MiB of it, so 384 MiB is
|
|
24
|
+
* about 2.5 times that; a crafted lockfile that expands further is
|
|
25
|
+
* stopped there and refused as too large. */
|
|
26
|
+
const PARSE_WORKER_HEAP_MB_PER_5000_ENTRIES = 384;
|
|
27
|
+
export function parseWorkerHeapMb(maxEntries) {
|
|
28
|
+
return Math.ceil((PARSE_WORKER_HEAP_MB_PER_5000_ENTRIES * Math.max(maxEntries, 5000)) / 5000);
|
|
29
|
+
}
|
|
30
|
+
const compiledWorker = new URL("./lockfile-parse-worker.js", import.meta.url);
|
|
31
|
+
// Under tsx/vitest only the .ts source exists, and a worker gets no TS
|
|
32
|
+
// loader by inheritance (see src/sandbox/parser-worker/pool.ts).
|
|
33
|
+
const WORKER_URL = existsSync(fileURLToPath(compiledWorker))
|
|
34
|
+
? compiledWorker
|
|
35
|
+
: new URL("./lockfile-parse-worker.ts", import.meta.url);
|
|
36
|
+
function incomplete(message) {
|
|
37
|
+
return new RegistryError(503, "wardby_plan_incomplete", message);
|
|
38
|
+
}
|
|
39
|
+
/** The ParsedLockfile a worker shipped back, with `resolve` answering from
|
|
40
|
+
* its edge table. */
|
|
41
|
+
function rebuild(shipped) {
|
|
42
|
+
const byPath = new Map();
|
|
43
|
+
shipped.entries.forEach((entry, at) => {
|
|
44
|
+
byPath.set(entry.path, new Map(shipped.edges[at].map(([key, target]) => [key, shipped.entries[target]])));
|
|
45
|
+
});
|
|
46
|
+
// A project's own dependencies (what package audit mode labels top-level);
|
|
47
|
+
// a path an entry also uses keeps the entry's, as the parser's resolve does.
|
|
48
|
+
shipped.projects.forEach((project, at) => {
|
|
49
|
+
if (byPath.has(project.path))
|
|
50
|
+
return;
|
|
51
|
+
byPath.set(project.path, new Map(shipped.projectEdges[at].map(([key, target]) => [key, shipped.entries[target]])));
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
entries: shipped.entries,
|
|
55
|
+
projects: shipped.projects,
|
|
56
|
+
...(shipped.integrity ? { integrity: shipped.integrity } : {}),
|
|
57
|
+
resolve: (fromPath, key) => byPath.get(fromPath)?.get(key),
|
|
58
|
+
dependencyKeys: (path) => [...(byPath.get(path)?.keys() ?? [])],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export async function parseLockfileOffThread(ecosystem, body, options, limits = {}) {
|
|
62
|
+
const timeoutMs = limits.timeoutMs ?? DEFAULT_LOCKFILE_PARSE_TIMEOUT_MS;
|
|
63
|
+
if (limits.signal?.aborted)
|
|
64
|
+
throw incomplete("the client went away before the lockfile was read");
|
|
65
|
+
const workerUrl = limits.workerUrl ?? WORKER_URL;
|
|
66
|
+
const worker = new Worker(workerUrl, {
|
|
67
|
+
resourceLimits: { maxOldGenerationSizeMb: limits.maxOldGenerationSizeMb ?? parseWorkerHeapMb(options.maxEntries) },
|
|
68
|
+
execArgv: workerUrl.pathname.endsWith(".ts") ? ["--import", "tsx/esm"] : [],
|
|
69
|
+
});
|
|
70
|
+
try {
|
|
71
|
+
const response = await new Promise((resolve, reject) => {
|
|
72
|
+
const timer = setTimeout(() => reject(incomplete(`the lockfile was not read within ${Math.round(timeoutMs / 1000)} s`)), timeoutMs);
|
|
73
|
+
const onAbort = () => reject(incomplete("the client went away before the lockfile was read"));
|
|
74
|
+
limits.signal?.addEventListener("abort", onAbort, { once: true });
|
|
75
|
+
const settle = () => {
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
limits.signal?.removeEventListener("abort", onAbort);
|
|
78
|
+
};
|
|
79
|
+
worker.once("message", (message) => {
|
|
80
|
+
settle();
|
|
81
|
+
resolve(message);
|
|
82
|
+
});
|
|
83
|
+
worker.once("error", (error) => {
|
|
84
|
+
settle();
|
|
85
|
+
// Out of heap: the lockfile expanded too far, a verdict about it.
|
|
86
|
+
// Anything else (the worker failed to load, crashed) is the proxy's
|
|
87
|
+
// own failure: a plain error, which the plan route logs and answers
|
|
88
|
+
// as a failure to verify, never as a refusal of the lockfile.
|
|
89
|
+
reject(error.code === "ERR_WORKER_OUT_OF_MEMORY"
|
|
90
|
+
? new RegistryError(413, "wardby_lockfile_too_large", "the lockfile needs too much memory to read")
|
|
91
|
+
: new Error(`the lockfile reader failed: ${error.message}`, { cause: error }));
|
|
92
|
+
});
|
|
93
|
+
worker.once("exit", (code) => {
|
|
94
|
+
settle();
|
|
95
|
+
reject(new Error(`the lockfile reader stopped (exit code ${code})`));
|
|
96
|
+
});
|
|
97
|
+
const request = { ecosystem, body, ...options };
|
|
98
|
+
worker.postMessage(request);
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
if ("unexpected" in response)
|
|
102
|
+
throw new Error(`the lockfile reader failed: ${response.message}`);
|
|
103
|
+
throw new RegistryError(response.status, response.code, response.message);
|
|
104
|
+
}
|
|
105
|
+
return rebuild(response.lockfile);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
await worker.terminate().catch(() => undefined);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PackageAuditMode } from "../../../coding/registry/audit-mode.js";
|
|
1
2
|
import { type AllowlistEntry, type LockfilePlanSupport, type ParsedLockfile, type RegistryAdapter, type UpstreamFetch } from "../../../coding/registry/types.js";
|
|
2
3
|
import { type AuditedVersion, type WithheldVersions } from "./audit.js";
|
|
3
4
|
import type { ApprovedVersion, StoredVersionFact } from "./store.js";
|
|
@@ -28,6 +29,8 @@ export interface PlanRefusal {
|
|
|
28
29
|
export interface PlanResult {
|
|
29
30
|
approved: ApprovedVersion[];
|
|
30
31
|
refused: PlanRefusal[];
|
|
32
|
+
/** Approvals carrying an audit verdict (package audit mode only; 0 otherwise). */
|
|
33
|
+
audited: number;
|
|
31
34
|
}
|
|
32
35
|
export interface PlanFacts {
|
|
33
36
|
getVersionFacts(versions: readonly {
|
|
@@ -49,6 +52,12 @@ export interface PlanInput {
|
|
|
49
52
|
/** Unbuffered fetch for streamed package documents. */
|
|
50
53
|
streamUpstream: UpstreamFetch;
|
|
51
54
|
audit(versions: readonly AuditedVersion[], signal: AbortSignal): Promise<WithheldVersions>;
|
|
55
|
+
/** The run's accepted advisory ids (packagePolicy.acceptedAdvisories):
|
|
56
|
+
* blocking advisories they waive do not refuse a version (see
|
|
57
|
+
* `isWaived`; malware is never waived). Absent or empty waives nothing. */
|
|
58
|
+
accepted?: ReadonlySet<string>;
|
|
59
|
+
/** The run's package audit mode (CodingRun.packageAuditMode); absent or null = normal enforcement. */
|
|
60
|
+
auditMode?: PackageAuditMode | null;
|
|
52
61
|
hostAllowed(url: string): boolean;
|
|
53
62
|
signal: AbortSignal;
|
|
54
63
|
factConcurrency?: number;
|