@wardby/cli 0.2.1 → 0.4.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 +53 -4
- package/README.md +52 -13
- package/dist/claude-coding-worker/driver.d.ts +6 -1
- package/dist/claude-coding-worker/driver.js +27 -1
- package/dist/claude-coding-worker/main.js +2 -0
- package/dist/claude-coding-worker/tool-socket.d.ts +9 -0
- package/dist/claude-coding-worker/tool-socket.js +26 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +14 -4
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +284 -36
- package/dist/coding/base-commit.d.ts +6 -0
- package/dist/coding/base-commit.js +12 -0
- package/dist/coding/collect-exclude.d.ts +25 -0
- package/dist/coding/collect-exclude.js +76 -0
- package/dist/coding/profile.d.ts +67 -22
- package/dist/coding/profile.js +58 -25
- package/dist/coding/protected-path-wording.d.ts +24 -0
- package/dist/coding/protected-path-wording.js +55 -0
- package/dist/coding/protected-paths.d.ts +31 -0
- package/dist/coding/protected-paths.js +48 -0
- package/dist/coding/protocol.d.ts +91 -4
- package/dist/coding/protocol.js +123 -12
- package/dist/coding/provider.d.ts +6 -1
- package/dist/coding/provider.js +16 -9
- package/dist/coding/registry/adapters.d.ts +2 -0
- package/dist/coding/registry/adapters.js +9 -0
- package/dist/coding/registry/allowlist.d.ts +9 -0
- package/dist/coding/registry/allowlist.js +28 -0
- package/dist/coding/registry/json-scan.d.ts +55 -0
- package/dist/coding/registry/json-scan.js +191 -0
- package/dist/coding/registry/lockfiles.d.ts +6 -0
- package/dist/coding/registry/lockfiles.js +89 -0
- package/dist/coding/registry/npm-lockfile.d.ts +9 -0
- package/dist/coding/registry/npm-lockfile.js +73 -0
- package/dist/coding/registry/npm-plan.d.ts +29 -0
- package/dist/coding/registry/npm-plan.js +289 -0
- package/dist/coding/registry/npm.d.ts +7 -0
- package/dist/coding/registry/npm.js +252 -0
- package/dist/coding/registry/pypi.d.ts +4 -0
- package/dist/coding/registry/pypi.js +210 -0
- package/dist/coding/registry/report.d.ts +37 -0
- package/dist/coding/registry/report.js +31 -0
- package/dist/coding/registry/token.d.ts +4 -0
- package/dist/coding/registry/token.js +7 -0
- package/dist/coding/registry/types.d.ts +286 -0
- package/dist/coding/registry/types.js +19 -0
- package/dist/coding/registry/worker-config.d.ts +14 -0
- package/dist/coding/registry/worker-config.js +31 -0
- package/dist/coding/services/builtins.d.ts +22 -0
- package/dist/coding/services/builtins.js +85 -0
- package/dist/coding/services/catalog.d.ts +443 -0
- package/dist/coding/services/catalog.js +159 -0
- package/dist/coding/services/declaration.d.ts +11 -0
- package/dist/coding/services/declaration.js +114 -0
- package/dist/coding/services/note.d.ts +8 -0
- package/dist/coding/services/note.js +15 -0
- package/dist/coding/services/resolve.d.ts +25 -0
- package/dist/coding/services/resolve.js +50 -0
- package/dist/coding/services/wording.d.ts +25 -0
- package/dist/coding/services/wording.js +70 -0
- package/dist/coding-proxy/main.js +24 -4
- package/dist/coding-worker/artifact.d.ts +6 -0
- package/dist/coding-worker/debug-trace.d.ts +37 -0
- package/dist/coding-worker/debug-trace.js +117 -0
- package/dist/coding-worker/driver.d.ts +13 -1
- package/dist/coding-worker/driver.js +102 -13
- package/dist/coding-worker/errors.js +8 -0
- package/dist/coding-worker/main.js +10 -2
- package/dist/coding-worker/sdk.d.ts +2 -2
- package/dist/coding-worker/sdk.js +7 -2
- package/dist/coding-worker/types.d.ts +3 -0
- package/dist/config/providers.d.ts +66 -0
- package/dist/config/providers.js +137 -0
- package/dist/core/attribution.d.ts +101 -0
- package/dist/core/attribution.js +208 -0
- package/dist/core/budget-groups.d.ts +120 -10
- package/dist/core/budget-groups.js +133 -24
- package/dist/core/budget-wording.d.ts +22 -0
- package/dist/core/budget-wording.js +55 -0
- package/dist/core/coding-queue.d.ts +3 -0
- package/dist/core/coding-queue.js +6 -2
- package/dist/core/coding-service-status.d.ts +11 -0
- package/dist/core/coding-service-status.js +17 -0
- package/dist/core/cost-report.d.ts +88 -0
- package/dist/core/cost-report.js +248 -0
- package/dist/core/datastores.js +18 -2
- package/dist/core/db.d.ts +5 -1
- package/dist/core/db.js +8 -2
- package/dist/core/dispatch.d.ts +74 -7
- package/dist/core/dispatch.js +382 -47
- package/dist/core/engine-native.js +44 -14
- package/dist/core/glob.d.ts +10 -0
- package/dist/core/glob.js +33 -0
- package/dist/core/grants.d.ts +86 -0
- package/dist/core/grants.js +126 -0
- package/dist/core/host-events.d.ts +72 -0
- package/dist/core/host-events.js +597 -0
- package/dist/core/host-identity-links.d.ts +54 -0
- package/dist/core/host-identity-links.js +189 -0
- package/dist/core/host-status.d.ts +78 -0
- package/dist/core/host-status.js +228 -0
- package/dist/core/in-flight-runs.d.ts +8 -0
- package/dist/core/in-flight-runs.js +56 -0
- package/dist/core/issue-bridge.d.ts +60 -0
- package/dist/core/issue-bridge.js +189 -0
- package/dist/core/issue-dedupe.d.ts +70 -0
- package/dist/core/issue-dedupe.js +255 -0
- package/dist/core/issue-events.d.ts +42 -0
- package/dist/core/issue-events.js +155 -0
- package/dist/core/issue-status.d.ts +29 -0
- package/dist/core/issue-status.js +241 -0
- package/dist/core/issue-tracker-tools.d.ts +64 -0
- package/dist/core/issue-tracker-tools.js +850 -0
- package/dist/core/model-usage.d.ts +10 -0
- package/dist/core/model-usage.js +24 -0
- package/dist/core/provider-wording.d.ts +12 -0
- package/dist/core/provider-wording.js +44 -0
- package/dist/core/reconciler.d.ts +42 -2
- package/dist/core/reconciler.js +97 -2
- package/dist/core/repo-access.d.ts +99 -0
- package/dist/core/repo-access.js +136 -0
- package/dist/core/review-host-checks.d.ts +11 -0
- package/dist/core/review-host-checks.js +41 -0
- package/dist/core/review-host-tools.d.ts +47 -0
- package/dist/core/review-host-tools.js +354 -0
- package/dist/core/run-heartbeat.d.ts +27 -0
- package/dist/core/run-heartbeat.js +54 -0
- package/dist/core/run-pricing.d.ts +61 -0
- package/dist/core/run-pricing.js +56 -0
- package/dist/core/runner.d.ts +33 -8
- package/dist/core/runner.js +410 -62
- package/dist/core/scheduler.d.ts +4 -1
- package/dist/core/scheduler.js +3 -2
- package/dist/core/secrets.d.ts +11 -2
- package/dist/core/secrets.js +25 -6
- package/dist/core/self-defects.d.ts +80 -0
- package/dist/core/self-defects.js +180 -0
- package/dist/core/subagent-memory-tools.d.ts +1 -1
- package/dist/core/subagent-memory-tools.js +16 -3
- package/dist/core/tool-admin.d.ts +81 -0
- package/dist/core/tool-admin.js +129 -0
- package/dist/core/tool-names.d.ts +42 -0
- package/dist/core/tool-names.js +67 -0
- package/dist/core/untrusted-content.d.ts +32 -0
- package/dist/core/untrusted-content.js +72 -0
- package/dist/core/webhooks.d.ts +17 -2
- package/dist/core/webhooks.js +42 -3
- package/dist/generated/prisma/browser.d.ts +166 -0
- package/dist/generated/prisma/client.d.ts +166 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +152 -52
- package/dist/generated/prisma/enums.d.ts +13 -0
- package/dist/generated/prisma/enums.js +12 -1
- package/dist/generated/prisma/internal/class.d.ts +242 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +2571 -577
- package/dist/generated/prisma/internal/prismaNamespace.js +312 -6
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +328 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +312 -6
- package/dist/generated/prisma/models/Agent.d.ts +682 -1
- package/dist/generated/prisma/models/AgentIssueProject.d.ts +1838 -0
- package/dist/generated/prisma/models/AgentIssueProject.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +1425 -0
- package/dist/generated/prisma/models/AgentRepository.js +1 -0
- package/dist/generated/prisma/models/AgentTool.d.ts +95 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +56 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +258 -7
- package/dist/generated/prisma/models/CodingProxySession.d.ts +195 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1405 -95
- package/dist/generated/prisma/models/CodingRunServiceStatus.d.ts +1404 -0
- package/dist/generated/prisma/models/CodingRunServiceStatus.js +1 -0
- package/dist/generated/prisma/models/CodingService.d.ts +1348 -0
- package/dist/generated/prisma/models/CodingService.js +1 -0
- package/dist/generated/prisma/models/HostEventDelivery.d.ts +946 -0
- package/dist/generated/prisma/models/HostEventDelivery.js +1 -0
- package/dist/generated/prisma/models/HostIdentity.d.ts +1232 -0
- package/dist/generated/prisma/models/HostIdentity.js +1 -0
- package/dist/generated/prisma/models/HostIdentityLinkRequest.d.ts +1473 -0
- package/dist/generated/prisma/models/HostIdentityLinkRequest.js +1 -0
- package/dist/generated/prisma/models/IssueFingerprint.d.ts +1183 -0
- package/dist/generated/prisma/models/IssueFingerprint.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +1255 -0
- package/dist/generated/prisma/models/IssuePullRequest.js +1 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.d.ts +1322 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.js +1 -0
- package/dist/generated/prisma/models/Principal.d.ts +455 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +1148 -0
- package/dist/generated/prisma/models/RegistryAllowance.js +1 -0
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +1219 -0
- package/dist/generated/prisma/models/RegistryApprovedVersion.js +1 -0
- package/dist/generated/prisma/models/RegistryFetch.d.ts +1428 -0
- package/dist/generated/prisma/models/RegistryFetch.js +1 -0
- package/dist/generated/prisma/models/RegistryPlanRefusal.d.ts +1294 -0
- package/dist/generated/prisma/models/RegistryPlanRefusal.js +1 -0
- package/dist/generated/prisma/models/RegistryVersionFact.d.ts +1085 -0
- package/dist/generated/prisma/models/RegistryVersionFact.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1437 -0
- package/dist/generated/prisma/models/ResourceGrant.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +1402 -82
- package/dist/generated/prisma/models/RunAttribution.d.ts +1259 -0
- package/dist/generated/prisma/models/RunAttribution.js +1 -0
- package/dist/generated/prisma/models/RunHostCheck.d.ts +1239 -0
- package/dist/generated/prisma/models/RunHostCheck.js +1 -0
- package/dist/generated/prisma/models/RunHostStatus.d.ts +1315 -0
- package/dist/generated/prisma/models/RunHostStatus.js +1 -0
- package/dist/generated/prisma/models/RunIssueStatus.d.ts +1199 -0
- package/dist/generated/prisma/models/RunIssueStatus.js +1 -0
- package/dist/generated/prisma/models/RunModelUsage.d.ts +1316 -0
- package/dist/generated/prisma/models/RunModelUsage.js +1 -0
- package/dist/generated/prisma/models/Tool.d.ts +15 -3
- package/dist/generated/prisma/models/WorkItem.d.ts +1408 -0
- package/dist/generated/prisma/models/WorkItem.js +1 -0
- package/dist/generated/prisma/models.d.ts +22 -0
- package/dist/help/build.d.ts +1 -0
- package/dist/help/build.js +9 -0
- package/dist/help/catalog.d.ts +24 -0
- package/dist/help/catalog.js +160 -0
- package/dist/help/cli.d.ts +2 -0
- package/dist/help/cli.js +65 -0
- package/dist/help/runtime.d.ts +3 -0
- package/dist/help/runtime.js +44 -0
- package/dist/help/search.d.ts +9 -0
- package/dist/help/search.js +104 -0
- package/dist/help-index.json +999 -0
- package/dist/import/cli-args.js +3 -2
- package/dist/import/create.d.ts +5 -0
- package/dist/import/create.js +67 -13
- package/dist/import/index.js +19 -9
- package/dist/import/neutral-schema.d.ts +18 -18
- package/dist/knowledge/check.d.ts +13 -0
- package/dist/knowledge/check.js +69 -0
- package/dist/knowledge/cli.d.ts +14 -0
- package/dist/knowledge/cli.js +67 -0
- package/dist/knowledge/concept.d.ts +54 -0
- package/dist/knowledge/concept.js +78 -0
- package/dist/knowledge/note.d.ts +11 -0
- package/dist/knowledge/note.js +39 -0
- package/dist/knowledge/relevance.d.ts +11 -0
- package/dist/knowledge/relevance.js +14 -0
- package/dist/knowledge/span-hash.d.ts +3 -0
- package/dist/knowledge/span-hash.js +16 -0
- package/dist/mcp/auth/access.d.ts +72 -0
- package/dist/mcp/auth/access.js +58 -0
- package/dist/mcp/auth/grants-cli.d.ts +149 -0
- package/dist/mcp/auth/grants-cli.js +518 -0
- package/dist/mcp/auth/host-account-cli.d.ts +2 -0
- package/dist/mcp/auth/host-account-cli.js +47 -0
- package/dist/mcp/auth/ownership.d.ts +25 -51
- package/dist/mcp/auth/ownership.js +19 -14
- package/dist/mcp/auth/repo-authorization.d.ts +22 -0
- package/dist/mcp/auth/repo-authorization.js +51 -0
- package/dist/mcp/auth/resource-server.d.ts +33 -2
- package/dist/mcp/auth/resource-server.js +99 -3
- package/dist/mcp/auth/self-hosted/browser.js +2 -2
- package/dist/mcp/auth/self-hosted/cli.js +47 -13
- package/dist/mcp/auth/self-hosted/credentials.d.ts +23 -5
- package/dist/mcp/auth/self-hosted/credentials.js +62 -4
- package/dist/mcp/auth/self-hosted/session.d.ts +7 -6
- package/dist/mcp/context.d.ts +30 -1
- package/dist/mcp/errors.d.ts +25 -6
- package/dist/mcp/errors.js +98 -0
- package/dist/mcp/host-events/deliveries.d.ts +9 -0
- package/dist/mcp/host-events/deliveries.js +17 -0
- package/dist/mcp/host-events/github-ingress.d.ts +38 -0
- package/dist/mcp/host-events/github-ingress.js +83 -0
- package/dist/mcp/host-events/github-user-callback.d.ts +18 -0
- package/dist/mcp/host-events/github-user-callback.js +50 -0
- package/dist/mcp/host-events/jira-ingress.d.ts +29 -0
- package/dist/mcp/host-events/jira-ingress.js +92 -0
- package/dist/mcp/index.d.ts +10 -1
- package/dist/mcp/index.js +187 -19
- package/dist/mcp/server.js +32 -11
- package/dist/mcp/tools/agents.js +519 -50
- package/dist/mcp/tools/budget-groups.js +3 -3
- package/dist/mcp/tools/cost-report.d.ts +8 -0
- package/dist/mcp/tools/cost-report.js +60 -0
- package/dist/mcp/tools/datastore.js +22 -15
- package/dist/mcp/tools/grants.d.ts +2 -0
- package/dist/mcp/tools/grants.js +239 -0
- package/dist/mcp/tools/help.d.ts +5 -0
- package/dist/mcp/tools/help.js +67 -0
- package/dist/mcp/tools/host-accounts.d.ts +2 -0
- package/dist/mcp/tools/host-accounts.js +114 -0
- package/dist/mcp/tools/issue-projects.d.ts +2 -0
- package/dist/mcp/tools/issue-projects.js +238 -0
- package/dist/mcp/tools/memory.d.ts +7 -1
- package/dist/mcp/tools/memory.js +5 -5
- package/dist/mcp/tools/model-catalog.d.ts +22 -0
- package/dist/mcp/tools/model-catalog.js +423 -0
- package/dist/mcp/tools/repositories.d.ts +2 -0
- package/dist/mcp/tools/repositories.js +182 -0
- package/dist/mcp/tools/runs.d.ts +6 -0
- package/dist/mcp/tools/runs.js +60 -6
- package/dist/mcp/tools/scheduling.js +3 -6
- package/dist/mcp/tools/secrets.js +18 -6
- package/dist/mcp/tools/services.d.ts +2 -0
- package/dist/mcp/tools/services.js +222 -0
- package/dist/mcp/tools/subagents.js +52 -16
- package/dist/mcp/tools/tools.d.ts +41 -0
- package/dist/mcp/tools/tools.js +201 -40
- package/dist/mcp/tools/trigger.js +65 -7
- package/dist/mcp/tools/webhooks.js +15 -4
- package/dist/mcp/transport/streamable-http.d.ts +15 -0
- package/dist/mcp/transport/streamable-http.js +55 -3
- package/dist/mcp/webhooks/ingress.d.ts +2 -1
- package/dist/mcp/webhooks/ingress.js +9 -2
- package/dist/providers/auth/delegating.d.ts +19 -0
- package/dist/providers/auth/delegating.js +71 -0
- package/dist/providers/auth/index.d.ts +2 -0
- package/dist/providers/auth/index.js +11 -0
- package/dist/providers/auth/self-hosted.d.ts +10 -2
- package/dist/providers/auth/self-hosted.js +55 -6
- package/dist/providers/auth/types.d.ts +6 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +4 -1
- package/dist/providers/coding-proxy/memory-ledger.js +31 -3
- package/dist/providers/coding-proxy/metering.d.ts +6 -1
- package/dist/providers/coding-proxy/metering.js +41 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +17 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +106 -8
- package/dist/providers/coding-proxy/proxy.d.ts +25 -2
- package/dist/providers/coding-proxy/proxy.js +561 -38
- package/dist/providers/coding-proxy/registry/audit.d.ts +131 -0
- package/dist/providers/coding-proxy/registry/audit.js +380 -0
- package/dist/providers/coding-proxy/registry/bounded-fetch.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/bounded-fetch.js +77 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +58 -0
- package/dist/providers/coding-proxy/registry/plan.js +304 -0
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +34 -0
- package/dist/providers/coding-proxy/registry/prisma-store.js +151 -0
- package/dist/providers/coding-proxy/registry/service.d.ts +213 -0
- package/dist/providers/coding-proxy/registry/service.js +1137 -0
- package/dist/providers/coding-proxy/registry/store.d.ts +127 -0
- package/dist/providers/coding-proxy/registry/store.js +70 -0
- package/dist/providers/coding-proxy/runtime.d.ts +17 -0
- package/dist/providers/coding-proxy/runtime.js +63 -0
- package/dist/providers/coding-proxy/secure-fetch.js +0 -1
- package/dist/providers/coding-proxy/server.d.ts +11 -0
- package/dist/providers/coding-proxy/server.js +163 -0
- package/dist/providers/coding-proxy/types.d.ts +33 -1
- package/dist/providers/coding-proxy/types.js +12 -1
- package/dist/providers/engine/types.d.ts +29 -0
- package/dist/providers/executor/build.d.ts +2 -2
- package/dist/providers/executor/composition.d.ts +3 -0
- package/dist/providers/executor/composition.js +28 -1
- package/dist/providers/executor/container.d.ts +134 -4
- package/dist/providers/executor/container.js +394 -37
- package/dist/providers/executor/dbos.d.ts +4 -3
- package/dist/providers/executor/dbos.js +7 -5
- package/dist/providers/executor/in-process.d.ts +2 -3
- package/dist/providers/executor/routing.d.ts +13 -0
- package/dist/providers/executor/routing.js +18 -0
- package/dist/providers/executor/types.d.ts +34 -0
- package/dist/providers/issue-tracker/adf.d.ts +31 -0
- package/dist/providers/issue-tracker/adf.js +181 -0
- package/dist/providers/issue-tracker/index.d.ts +5 -0
- package/dist/providers/issue-tracker/index.js +12 -0
- package/dist/providers/issue-tracker/jira-client.d.ts +41 -0
- package/dist/providers/issue-tracker/jira-client.js +151 -0
- package/dist/providers/issue-tracker/jira-events.d.ts +3 -0
- package/dist/providers/issue-tracker/jira-events.js +98 -0
- package/dist/providers/issue-tracker/jira.d.ts +116 -0
- package/dist/providers/issue-tracker/jira.js +502 -0
- package/dist/providers/issue-tracker/types.d.ts +269 -0
- package/dist/providers/issue-tracker/types.js +16 -0
- package/dist/providers/jobs/claude-tool-setup.d.ts +23 -0
- package/dist/providers/jobs/claude-tool-setup.js +50 -0
- package/dist/providers/jobs/collect-prune.d.ts +7 -0
- package/dist/providers/jobs/collect-prune.js +27 -0
- package/dist/providers/jobs/docker-isolation.d.ts +48 -3
- package/dist/providers/jobs/docker-isolation.js +213 -22
- package/dist/providers/jobs/docker-services.d.ts +35 -0
- package/dist/providers/jobs/docker-services.js +191 -0
- package/dist/providers/jobs/docker.d.ts +53 -2
- package/dist/providers/jobs/docker.js +307 -32
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +1 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +12 -3
- package/dist/providers/jobs/kubernetes-isolation.d.ts +17 -2
- package/dist/providers/jobs/kubernetes-isolation.js +238 -57
- package/dist/providers/jobs/kubernetes-platform.d.ts +10 -4
- package/dist/providers/jobs/kubernetes-platform.js +11 -5
- package/dist/providers/jobs/kubernetes-preflight.js +3 -0
- package/dist/providers/jobs/kubernetes.d.ts +24 -2
- package/dist/providers/jobs/kubernetes.js +153 -22
- package/dist/providers/jobs/service-state.d.ts +22 -0
- package/dist/providers/jobs/service-state.js +17 -0
- package/dist/providers/jobs/types.d.ts +18 -0
- package/dist/providers/llm/anthropic.d.ts +3 -3
- package/dist/providers/llm/anthropic.js +3 -5
- package/dist/providers/llm/bedrock.d.ts +3 -3
- package/dist/providers/llm/bedrock.js +3 -8
- package/dist/providers/llm/catalog-lookup.d.ts +10 -0
- package/dist/providers/llm/catalog-lookup.js +15 -0
- package/dist/providers/llm/catalog-shipped.d.ts +18 -0
- package/dist/providers/llm/catalog-shipped.js +197 -0
- package/dist/providers/llm/catalog-store.d.ts +58 -0
- package/dist/providers/llm/catalog-store.js +138 -0
- package/dist/providers/llm/catalog-types.d.ts +66 -0
- package/dist/providers/llm/catalog-types.js +64 -0
- package/dist/providers/llm/catalog.d.ts +61 -0
- package/dist/providers/llm/catalog.js +147 -0
- package/dist/providers/llm/claude-messages.d.ts +5 -1
- package/dist/providers/llm/claude-messages.js +1 -0
- package/dist/providers/llm/claude-provider.d.ts +10 -12
- package/dist/providers/llm/claude-provider.js +15 -6
- package/dist/providers/llm/index.d.ts +9 -6
- package/dist/providers/llm/index.js +8 -5
- package/dist/providers/llm/openai.d.ts +14 -5
- package/dist/providers/llm/openai.js +24 -14
- package/dist/providers/llm/pricing-core.d.ts +5 -3
- package/dist/providers/llm/registration.js +8 -12
- package/dist/providers/llm/routing.d.ts +21 -11
- package/dist/providers/llm/routing.js +47 -13
- package/dist/providers/llm/types.d.ts +12 -0
- package/dist/providers/llm/types.js +8 -1
- package/dist/providers/review-host/diff-lines.d.ts +16 -0
- package/dist/providers/review-host/diff-lines.js +59 -0
- package/dist/providers/review-host/github-events.d.ts +6 -0
- package/dist/providers/review-host/github-events.js +226 -0
- package/dist/providers/review-host/github-user-auth.d.ts +38 -0
- package/dist/providers/review-host/github-user-auth.js +128 -0
- package/dist/providers/review-host/github.d.ts +57 -0
- package/dist/providers/review-host/github.js +568 -0
- package/dist/providers/review-host/index.d.ts +12 -0
- package/dist/providers/review-host/index.js +30 -0
- package/dist/providers/review-host/review-format.d.ts +19 -0
- package/dist/providers/review-host/review-format.js +59 -0
- package/dist/providers/review-host/types.d.ts +309 -0
- package/dist/providers/review-host/types.js +24 -0
- package/dist/providers/vcs/git.d.ts +16 -6
- package/dist/providers/vcs/git.js +78 -34
- package/dist/providers/vcs/github.d.ts +94 -3
- package/dist/providers/vcs/github.js +223 -17
- package/dist/providers/vcs/types.d.ts +48 -4
- package/dist/quickstart/index.d.ts +2 -0
- package/dist/quickstart/index.js +36 -8
- package/dist/sandbox/fetch-policy.d.ts +20 -2
- package/dist/sandbox/fetch-policy.js +64 -3
- package/dist/sandbox/host-functions.d.ts +9 -1
- package/dist/sandbox/host-functions.js +12 -5
- package/dist/serve.js +8 -2
- package/dist/viewer/api-schema.d.ts +2757 -0
- package/dist/viewer/api-schema.js +165 -0
- package/dist/viewer/build-schemas.d.ts +2 -0
- package/dist/viewer/build-schemas.js +18 -0
- package/dist/viewer/event-bus.d.ts +38 -0
- package/dist/viewer/event-bus.js +232 -0
- package/dist/viewer/graph.d.ts +40 -0
- package/dist/viewer/graph.js +243 -0
- package/dist/viewer/http.d.ts +30 -0
- package/dist/viewer/http.js +133 -0
- package/dist/viewer/run-detail.d.ts +4 -0
- package/dist/viewer/run-detail.js +61 -0
- package/dist/wardby-bin.js +11 -0
- package/docs/README.md +40 -0
- package/docs/agent-recipes.md +383 -0
- package/docs/architecture-runtime.md +90 -0
- package/docs/assets/brand/wardby-icon-512.png +0 -0
- package/docs/assets/brand/wardby-icon.svg +16 -0
- package/docs/assets/brand/wardby-mascot-profile-512.png +0 -0
- package/docs/assets/brand/wardby-mascot.png +0 -0
- package/docs/assets/brand/wardby-mascot.svg +5 -0
- package/docs/assets/wardby-workflow.svg +106 -0
- package/docs/code-review-agents.md +508 -0
- package/docs/coding-agent-setup.md +175 -0
- package/docs/coding-packages.md +455 -0
- package/docs/coding-services.md +300 -0
- package/docs/coding-worker-byo-images.md +98 -0
- package/docs/coding-worker-isolation.md +1068 -0
- package/docs/getting-started-gke.md +632 -0
- package/docs/getting-started-identity-provider.md +319 -0
- package/docs/getting-started.md +147 -0
- package/docs/jira-agents.md +649 -0
- package/docs/knowledge.md +387 -0
- package/docs/models.md +221 -0
- package/docs/observability.md +53 -0
- package/docs/release-verification.md +66 -0
- package/docs/security-deployment.md +667 -0
- package/docs/viewer-api.md +142 -0
- package/help/admin-viewer.md +39 -0
- package/help/agent-recipes.md +173 -0
- package/help/architecture-agent.md +189 -0
- package/help/builder-agent.md +80 -0
- package/help/code-review-agents.md +37 -0
- package/help/coding-packages.md +31 -0
- package/help/coding-services.md +71 -0
- package/help/cost-attribution.md +67 -0
- package/help/creating-agents.md +90 -0
- package/help/deploy-gke.md +45 -0
- package/help/deployment-targets.md +39 -0
- package/help/errors/budget-group-exhausted.md +25 -0
- package/help/errors/docker-isolation-unsupported.md +26 -0
- package/help/errors/model-unavailable.md +63 -0
- package/help/errors/protected-path.md +45 -0
- package/help/errors/repo-access.md +27 -0
- package/help/errors/service-declaration-invalid.md +27 -0
- package/help/errors/service-declaration-unavailable.md +25 -0
- package/help/errors/service-launcher-unsupported.md +30 -0
- package/help/errors/service-not-allowed.md +27 -0
- package/help/errors/service-unknown.md +23 -0
- package/help/errors/service-unready.md +49 -0
- package/help/getting-started.md +32 -0
- package/help/github.md +48 -0
- package/help/identity-and-access.md +44 -0
- package/help/jira.md +135 -0
- package/help/knowledge.md +47 -0
- package/help/mcp.md +30 -0
- package/help/models.md +90 -0
- package/help/native-capabilities.md +30 -0
- package/help/observability.md +41 -0
- package/help/operating-agents.md +36 -0
- package/help/security.md +27 -0
- package/help/troubleshooting/budgets.md +32 -0
- package/help/troubleshooting/coding-workers.md +47 -0
- package/help/troubleshooting/repository-access.md +27 -0
- package/package.json +14 -3
- package/prisma/migrations/20260925010000_coding_collect_exclude/migration.sql +8 -0
- package/prisma/migrations/20260925015000_allowed_egress_default/migration.sql +8 -0
- package/prisma/migrations/20260925020000_coding_package_registry/migration.sql +55 -0
- package/prisma/migrations/20260925030000_tool_name_per_owner/migration.sql +11 -0
- package/prisma/migrations/20260926010000_run_trigger_host_event/migration.sql +7 -0
- package/prisma/migrations/20260926020000_code_review_hosts/migration.sql +53 -0
- package/prisma/migrations/20260926030000_auth_user_roles/migration.sql +9 -0
- package/prisma/migrations/20260926040000_agent_effort/migration.sql +6 -0
- package/prisma/migrations/20260926050000_registry_lockfile_plan/migration.sql +32 -0
- package/prisma/migrations/20260926050000_repo_access_authorization/migration.sql +82 -0
- package/prisma/migrations/20260926060000_registry_plan_refusal/migration.sql +19 -0
- package/prisma/migrations/20260926100000_registry_plan_refusal_published_at/migration.sql +5 -0
- package/prisma/migrations/20260926190000_run_host_status/migration.sql +18 -0
- package/prisma/migrations/20260926210000_run_host_status_at_dispatch/migration.sql +5 -0
- package/prisma/migrations/20260927010000_resource_grants/migration.sql +72 -0
- package/prisma/migrations/20260927020000_proxy_session_budget_exhausted/migration.sql +3 -0
- package/prisma/migrations/20260927030000_coding_debug_trace/migration.sql +4 -0
- package/prisma/migrations/20260927040000_proxy_session_upstream_failure/migration.sql +3 -0
- package/prisma/migrations/20260927050000_coding_run_services/migration.sql +74 -0
- package/prisma/migrations/20260928000000_coding_run_tool_image/migration.sql +5 -0
- package/prisma/migrations/20260930000000_jira_issue_projects/migration.sql +34 -0
- package/prisma/migrations/20261001000000_jira_phase2_allowlists/migration.sql +3 -0
- package/prisma/migrations/20261001010000_jira_link_types_allowlist/migration.sql +2 -0
- package/prisma/migrations/20261002000000_jira_coding_bridge/migration.sql +28 -0
- package/prisma/migrations/20261002010000_jira_issue_creation/migration.sql +25 -0
- package/prisma/migrations/20261003000000_issue_cost_attribution/migration.sql +56 -0
- package/prisma/migrations/20261003010000_coding_run_service_status/migration.sql +23 -0
- package/prisma/migrations/20261003020000_viewer_notify/migration.sql +54 -0
- package/prisma/migrations/20261003030000_viewer_notify_fixes/migration.sql +47 -0
- package/prisma/migrations/20261003040000_viewer_indexes/migration.sql +12 -0
- package/prisma/migrations/20261004000000_model_catalog/migration.sql +26 -0
- package/prisma/schema.prisma +663 -21
- package/dist/mcp/tools/models.d.ts +0 -8
- package/dist/mcp/tools/models.js +0 -15
- package/dist/providers/llm/pricing-anthropic.d.ts +0 -4
- package/dist/providers/llm/pricing-anthropic.js +0 -30
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +0 -12
- package/dist/providers/llm/pricing-bedrock-claude.js +0 -37
- package/dist/providers/llm/pricing.d.ts +0 -30
- package/dist/providers/llm/pricing.js +0 -74
package/dist/coding/protocol.js
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const CODING_PROTOCOL_VERSION = 1;
|
|
3
|
+
/** The code host every coding run's repository and pull request live on (see pullRequestUrlSchema); the one place to change when another is added. */
|
|
4
|
+
export const CODING_CODE_PROVIDER = "github";
|
|
3
5
|
export const MAX_CODING_ARTIFACT_BYTES = 64 * 1024;
|
|
4
6
|
export const MAX_CODING_TASK_BYTES = 16 * 1024;
|
|
7
|
+
/** Room reserved at the end of a composed task for lines the executor appends (e.g. the base commit). */
|
|
8
|
+
export const CODING_TASK_TRAILER_RESERVE_BYTES = 256;
|
|
5
9
|
export const MAX_CODING_SUMMARY_BYTES = 8 * 1024;
|
|
6
10
|
export const MAX_CODING_TESTS = 64;
|
|
7
11
|
export const MAX_CODING_TEST_COMMAND_BYTES = 2 * 1024;
|
|
8
12
|
export const MAX_TAG_BYTES = 32;
|
|
13
|
+
/**
|
|
14
|
+
* Coding-run services (docs/coding-services.md): the catalog name and version
|
|
15
|
+
* grammar, shared by the repository's .wardby/services.yaml, the catalog, and
|
|
16
|
+
* the worker input.
|
|
17
|
+
*/
|
|
18
|
+
export const CODING_SERVICE_NAME = /^[a-z][a-z0-9-]{0,39}$/;
|
|
19
|
+
export const CODING_SERVICE_VERSION = /^[0-9A-Za-z][0-9A-Za-z._-]{0,19}$/;
|
|
20
|
+
export const MAX_CODING_SERVICES = 5;
|
|
21
|
+
/** A variable a service hands the agent's shells (DATABASE_URL, PGHOST, REDIS_URL, ...). */
|
|
22
|
+
export const CODING_SERVICE_ENV_NAME = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
23
|
+
export const MAX_CODING_SERVICE_ENV = 16;
|
|
24
|
+
export const MAX_CODING_SERVICE_ENV_VALUE_BYTES = 1024;
|
|
9
25
|
/**
|
|
10
26
|
* A worker's output-schema failure, reduced to where and how it failed, never
|
|
11
27
|
* what the model wrote: `<path>:<zod issue code>`, where the path is dot-joined
|
|
@@ -21,8 +37,8 @@ const MAX_RUN_ID_BYTES = 128;
|
|
|
21
37
|
const MAX_COST_USD = 1_000_000;
|
|
22
38
|
const MAX_JSON_NESTING_DEPTH = 64;
|
|
23
39
|
const INVALID_MULTILINE_CONTROL = /[\u0000\u000B\u000C\u000E-\u001F\u007F]/;
|
|
24
|
-
const INVALID_SINGLE_LINE_CONTROL = /[\u0000-\u001F\u007F]/;
|
|
25
|
-
function byteLength(value) {
|
|
40
|
+
export const INVALID_SINGLE_LINE_CONTROL = /[\u0000-\u001F\u007F]/;
|
|
41
|
+
export function byteLength(value) {
|
|
26
42
|
return Buffer.byteLength(value, "utf8");
|
|
27
43
|
}
|
|
28
44
|
function boundedText(maxBytes, singleLine = false) {
|
|
@@ -33,6 +49,72 @@ function boundedText(maxBytes, singleLine = false) {
|
|
|
33
49
|
.refine((value) => !invalidControl.test(value), "must not contain control characters")
|
|
34
50
|
.refine((value) => value.trim().length > 0, "must not be blank");
|
|
35
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Names the worker owns: its shell basics, anything that would redirect a
|
|
54
|
+
* process's loader or network proxy, and the registry proxy's and Wardby's own
|
|
55
|
+
* settings. No service may set one, whatever its catalog entry says.
|
|
56
|
+
*/
|
|
57
|
+
const RESERVED_SERVICE_ENV_NAMES = new Set([
|
|
58
|
+
"HOME",
|
|
59
|
+
"LANG",
|
|
60
|
+
"LC_ALL",
|
|
61
|
+
"PATH",
|
|
62
|
+
"SHELL",
|
|
63
|
+
"TMPDIR",
|
|
64
|
+
"USER",
|
|
65
|
+
"LD_PRELOAD",
|
|
66
|
+
"LD_LIBRARY_PATH",
|
|
67
|
+
"NODE_OPTIONS",
|
|
68
|
+
"NODE_PATH",
|
|
69
|
+
"PYTHONPATH",
|
|
70
|
+
"PYTHONHOME",
|
|
71
|
+
"HTTP_PROXY",
|
|
72
|
+
"HTTPS_PROXY",
|
|
73
|
+
"NO_PROXY",
|
|
74
|
+
"ALL_PROXY",
|
|
75
|
+
"SSL_CERT_FILE",
|
|
76
|
+
"SSL_CERT_DIR",
|
|
77
|
+
]);
|
|
78
|
+
const RESERVED_SERVICE_ENV_PREFIXES = [
|
|
79
|
+
"WARDBY_",
|
|
80
|
+
"CODEX_",
|
|
81
|
+
"OPENAI_",
|
|
82
|
+
"ANTHROPIC_",
|
|
83
|
+
"PIP_",
|
|
84
|
+
"NPM_CONFIG_",
|
|
85
|
+
"UV_",
|
|
86
|
+
"GIT_",
|
|
87
|
+
];
|
|
88
|
+
export function isReservedServiceEnvName(name) {
|
|
89
|
+
return (RESERVED_SERVICE_ENV_NAMES.has(name) || RESERVED_SERVICE_ENV_PREFIXES.some((prefix) => name.startsWith(prefix)));
|
|
90
|
+
}
|
|
91
|
+
const serviceEnvValueSchema = z
|
|
92
|
+
.string()
|
|
93
|
+
.refine((value) => byteLength(value) <= MAX_CODING_SERVICE_ENV_VALUE_BYTES, `must be at most ${MAX_CODING_SERVICE_ENV_VALUE_BYTES} UTF-8 bytes`)
|
|
94
|
+
.refine((value) => !INVALID_SINGLE_LINE_CONTROL.test(value), "must not contain control characters");
|
|
95
|
+
/** The variables one service hands the agent's shells: upper-case names wardby does not reserve. */
|
|
96
|
+
export const CodingServiceTestEnvSchema = z.record(z.string(), serviceEnvValueSchema).superRefine((env, ctx) => {
|
|
97
|
+
const names = Object.keys(env);
|
|
98
|
+
if (names.length > MAX_CODING_SERVICE_ENV) {
|
|
99
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, message: `must have at most ${MAX_CODING_SERVICE_ENV} variables` });
|
|
100
|
+
}
|
|
101
|
+
for (const name of names) {
|
|
102
|
+
if (!CODING_SERVICE_ENV_NAME.test(name) || isReservedServiceEnvName(name)) {
|
|
103
|
+
ctx.addIssue({
|
|
104
|
+
code: z.ZodIssueCode.custom,
|
|
105
|
+
path: [name],
|
|
106
|
+
message: "must be an upper-case variable name wardby does not reserve",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const workerServiceSchema = z
|
|
112
|
+
.object({
|
|
113
|
+
name: z.string().regex(CODING_SERVICE_NAME),
|
|
114
|
+
version: z.string().regex(CODING_SERVICE_VERSION),
|
|
115
|
+
testEnv: CodingServiceTestEnvSchema,
|
|
116
|
+
})
|
|
117
|
+
.strict();
|
|
36
118
|
function repositoryParts(value) {
|
|
37
119
|
if (byteLength(value) > MAX_REPOSITORY_INPUT_BYTES || INVALID_SINGLE_LINE_CONTROL.test(value)) {
|
|
38
120
|
throw new Error("invalid GitHub repository");
|
|
@@ -119,20 +201,28 @@ export const CodingTaskOverrideSchema = boundedText(MAX_CODING_TASK_BYTES);
|
|
|
119
201
|
/**
|
|
120
202
|
* A coding worker receives only its task text, so a coding agent's own
|
|
121
203
|
* instructions (its systemPrompt) travel inside that text, ahead of the
|
|
122
|
-
* request
|
|
123
|
-
*
|
|
124
|
-
*
|
|
204
|
+
* request, followed by any note wardby generates for the run (the services it
|
|
205
|
+
* started: src/coding/services/note.ts). Blank instructions and no note leave
|
|
206
|
+
* the task unchanged. The combination must still fit MAX_CODING_TASK_BYTES;
|
|
207
|
+
* exceeding it is an error naming both parts rather than a silent truncation.
|
|
208
|
+
* A knowledge note, when given, goes between the standing instructions and the
|
|
209
|
+
* request and is fitted into whatever room is left: it is cut, or dropped,
|
|
210
|
+
* never the cause of an error.
|
|
125
211
|
*/
|
|
126
|
-
export function composeCodingTask(instructions, task) {
|
|
127
|
-
const standing = instructions?.trim();
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const composed = `Standing instructions for this coding agent:\n${standing}\n\nRequest:\n${task}`;
|
|
131
|
-
if (byteLength(composed) > MAX_CODING_TASK_BYTES) {
|
|
212
|
+
export function composeCodingTask(instructions, task, note, knowledge) {
|
|
213
|
+
const standing = [instructions?.trim(), note?.trim()].filter((part) => Boolean(part)).join("\n\n");
|
|
214
|
+
const base = standing ? `Standing instructions for this coding agent:\n${standing}\n\nRequest:\n${task}` : task;
|
|
215
|
+
if (byteLength(base) > MAX_CODING_TASK_BYTES) {
|
|
132
216
|
throw new Error(`The coding agent's instructions (${byteLength(standing)} bytes) plus this task (${byteLength(task)} bytes) ` +
|
|
133
217
|
`exceed the ${MAX_CODING_TASK_BYTES}-byte coding task limit; shorten one of them.`);
|
|
134
218
|
}
|
|
135
|
-
|
|
219
|
+
if (!knowledge)
|
|
220
|
+
return base;
|
|
221
|
+
const prefix = standing ? `Standing instructions for this coding agent:\n${standing}\n\n` : "";
|
|
222
|
+
const suffix = `\n\nRequest:\n${task}`;
|
|
223
|
+
const room = MAX_CODING_TASK_BYTES - byteLength(prefix) - byteLength(suffix) - CODING_TASK_TRAILER_RESERVE_BYTES;
|
|
224
|
+
const rendered = room > 0 ? knowledge.render(room) : undefined;
|
|
225
|
+
return rendered ? `${prefix}${rendered}${suffix}` : base;
|
|
136
226
|
}
|
|
137
227
|
const runIdSchema = boundedText(MAX_RUN_ID_BYTES, true).refine((value) => /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(value), "must be an opaque identifier");
|
|
138
228
|
const modelSchema = boundedText(MAX_MODEL_BYTES, true).refine((value) => /^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(value), "must be a model identifier");
|
|
@@ -186,6 +276,8 @@ const testResultSchema = z
|
|
|
186
276
|
outcome: z.enum(["passed", "failed", "skipped"]),
|
|
187
277
|
})
|
|
188
278
|
.strict();
|
|
279
|
+
/** Longest line a debug-traced worker writes to its log (src/coding-worker/debug-trace.ts). */
|
|
280
|
+
export const MAX_DEBUG_TRACE_LINE_BYTES = 16 * 1024;
|
|
189
281
|
export const CodingTaskInputSchema = z
|
|
190
282
|
.object({
|
|
191
283
|
schemaVersion: z.literal(CODING_PROTOCOL_VERSION),
|
|
@@ -206,6 +298,21 @@ export const CodingTaskInputSchema = z
|
|
|
206
298
|
* only enforces that headRef is internally consistent with it.
|
|
207
299
|
*/
|
|
208
300
|
continuationOf: z.object({ runId: runIdSchema }).strict().optional(),
|
|
301
|
+
/**
|
|
302
|
+
* Admin-requested debug trace (CodingAgentProfile.debugTraceUntil): the
|
|
303
|
+
* worker writes its full stream trace to its own log. Absent means off;
|
|
304
|
+
* the control plane writes the key only when true, so an input for an
|
|
305
|
+
* untraced run is unchanged for workers that predate it.
|
|
306
|
+
*/
|
|
307
|
+
debugTrace: z.boolean().optional(),
|
|
308
|
+
/**
|
|
309
|
+
* Coding-run services started next to this run (docs/coding-services.md):
|
|
310
|
+
* each one's catalog name and version, and the variables the agent's shells
|
|
311
|
+
* receive. Absent means none; the control plane writes the key only when a
|
|
312
|
+
* run has services, so every other input is unchanged for workers that
|
|
313
|
+
* predate it.
|
|
314
|
+
*/
|
|
315
|
+
services: z.array(workerServiceSchema).min(1).max(MAX_CODING_SERVICES).optional(),
|
|
209
316
|
})
|
|
210
317
|
.strict()
|
|
211
318
|
.superRefine((value, ctx) => {
|
|
@@ -217,6 +324,10 @@ export const CodingTaskInputSchema = z
|
|
|
217
324
|
message: "must match wardby/run-<runId> (or wardby/run-<continuationOf.runId>)",
|
|
218
325
|
});
|
|
219
326
|
}
|
|
327
|
+
const names = (value.services ?? []).map((service) => service.name);
|
|
328
|
+
if (new Set(names).size !== names.length) {
|
|
329
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["services"], message: "must name each service once" });
|
|
330
|
+
}
|
|
220
331
|
});
|
|
221
332
|
export const CodingAgentOutputSchema = z
|
|
222
333
|
.object({
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import type { ModelCatalog } from "../providers/llm/catalog.js";
|
|
2
|
+
import type { ModelProvider } from "../providers/llm/catalog-types.js";
|
|
1
3
|
export declare const CODING_PROVIDERS: readonly ["codex", "claude-code"];
|
|
2
4
|
export type CodingProvider = (typeof CODING_PROVIDERS)[number];
|
|
3
|
-
|
|
5
|
+
/** Which coding provider runs a model provider's models; Bedrock models are never coding models. */
|
|
6
|
+
export declare function codingProviderForModelProvider(provider: ModelProvider): CodingProvider | undefined;
|
|
7
|
+
export declare function codingProviderSupportsModel(provider: CodingProvider, model: string, catalog?: ModelCatalog): boolean;
|
|
8
|
+
export declare function assertCodingProvider(provider: string): asserts provider is CodingProvider;
|
|
4
9
|
export declare function assertCodingProviderModel(provider: string, model: string): asserts provider is CodingProvider;
|
package/dist/coding/provider.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { supportedModels as openaiSupportedModels } from "../providers/llm/pricing.js";
|
|
1
|
+
import { currentModelCatalog } from "../providers/llm/catalog-store.js";
|
|
3
2
|
export const CODING_PROVIDERS = ["codex", "claude-code"];
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
/** Which coding provider runs a model provider's models; Bedrock models are never coding models. */
|
|
4
|
+
export function codingProviderForModelProvider(provider) {
|
|
5
|
+
if (provider === "openai")
|
|
6
|
+
return "codex";
|
|
7
|
+
if (provider === "anthropic")
|
|
8
|
+
return "claude-code";
|
|
9
|
+
return undefined;
|
|
10
10
|
}
|
|
11
|
-
export function
|
|
11
|
+
export function codingProviderSupportsModel(provider, model, catalog = currentModelCatalog()) {
|
|
12
|
+
const entry = catalog.get(model);
|
|
13
|
+
return entry !== undefined && codingProviderForModelProvider(entry.provider) === provider;
|
|
14
|
+
}
|
|
15
|
+
export function assertCodingProvider(provider) {
|
|
12
16
|
if (!CODING_PROVIDERS.includes(provider)) {
|
|
13
17
|
throw new Error(`Unsupported coding provider "${provider}".`);
|
|
14
18
|
}
|
|
19
|
+
}
|
|
20
|
+
export function assertCodingProviderModel(provider, model) {
|
|
21
|
+
assertCodingProvider(provider);
|
|
15
22
|
if (!codingProviderSupportsModel(provider, model)) {
|
|
16
23
|
throw new Error(`Model "${model}" is not supported by coding provider "${provider}".`);
|
|
17
24
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The registry adapter map: every ecosystem the coding package registry
|
|
3
|
+
* proxies, keyed by its EcosystemId. Adding a new ecosystem means adding it
|
|
4
|
+
* here (and to the allowlist/profile validation that reads this map) --
|
|
5
|
+
* nothing else in the registry core hardcodes "npm" or "pypi".
|
|
6
|
+
*/
|
|
7
|
+
import { npmAdapter } from "./npm.js";
|
|
8
|
+
import { pypiAdapter } from "./pypi.js";
|
|
9
|
+
export const REGISTRY_ADAPTERS = new Map([npmAdapter, pypiAdapter].map((adapter) => [adapter.id, adapter]));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AllowlistEntry, RegistryAdapter } from "./types.js";
|
|
2
|
+
export type PackageAllowlist = Readonly<Record<string, readonly string[]>>;
|
|
3
|
+
export interface PackagePolicy {
|
|
4
|
+
minReleaseAgeDays: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const DEFAULT_MIN_RELEASE_AGE_DAYS = 3;
|
|
7
|
+
export declare function resolvePolicy(value: unknown): PackagePolicy;
|
|
8
|
+
export declare function parseAllowlist(allowlist: PackageAllowlist, adapters: ReadonlyMap<string, RegistryAdapter>): Map<string, AllowlistEntry[]>;
|
|
9
|
+
export declare function matchRoot(entries: readonly AllowlistEntry[], normalizedName: string): AllowlistEntry | undefined;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-agent package allowlist and policy model: parsing raw allowlist
|
|
3
|
+
* strings (via each ecosystem's adapter) into `AllowlistEntry` values, and
|
|
4
|
+
* matching a normalized package name against them.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
export const DEFAULT_MIN_RELEASE_AGE_DAYS = 3;
|
|
8
|
+
const PolicySchema = z
|
|
9
|
+
.object({ minReleaseAgeDays: z.number().int().min(0).max(30).default(DEFAULT_MIN_RELEASE_AGE_DAYS) })
|
|
10
|
+
.strict();
|
|
11
|
+
export function resolvePolicy(value) {
|
|
12
|
+
return PolicySchema.parse(value ?? {});
|
|
13
|
+
}
|
|
14
|
+
export function parseAllowlist(allowlist, adapters) {
|
|
15
|
+
const parsed = new Map();
|
|
16
|
+
for (const [ecosystem, entries] of Object.entries(allowlist)) {
|
|
17
|
+
const adapter = adapters.get(ecosystem);
|
|
18
|
+
if (!adapter)
|
|
19
|
+
throw new Error(`unknown package ecosystem "${ecosystem}"`);
|
|
20
|
+
parsed.set(ecosystem, entries.map((entry) => adapter.parseAllowlistEntry(entry)));
|
|
21
|
+
}
|
|
22
|
+
return parsed;
|
|
23
|
+
}
|
|
24
|
+
export function matchRoot(entries, normalizedName) {
|
|
25
|
+
return entries.find((entry) => entry.wildcard
|
|
26
|
+
? normalizedName.startsWith(entry.name) && normalizedName.length > entry.name.length
|
|
27
|
+
: entry.name === normalizedName);
|
|
28
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A streaming scan for one top-level member of a JSON object document,
|
|
3
|
+
* without ever holding the document: only the wanted member's value text is
|
|
4
|
+
* kept (bounded), and every other value, however large, is skipped as it
|
|
5
|
+
* streams past. Used to read an npm packument's `time` (per-version publish
|
|
6
|
+
* times), which comes after `versions` and can follow tens of MB of it.
|
|
7
|
+
*
|
|
8
|
+
* It is a tokenizer, not a validator: it tracks strings, escapes and
|
|
9
|
+
* nesting depth, which is all that locating a top-level member needs. The
|
|
10
|
+
* captured value is then parsed with JSON.parse, so a malformed value
|
|
11
|
+
* throws there. A document that is not an object, or that ends before the
|
|
12
|
+
* member closes, yields null.
|
|
13
|
+
*/
|
|
14
|
+
export declare class JsonMemberTooLarge extends Error {
|
|
15
|
+
}
|
|
16
|
+
export declare class TopLevelMemberScanner {
|
|
17
|
+
private readonly wanted;
|
|
18
|
+
private readonly maxValueLength;
|
|
19
|
+
private depth;
|
|
20
|
+
private inString;
|
|
21
|
+
private escape;
|
|
22
|
+
/** At depth 1, the next string is a key. */
|
|
23
|
+
private expectKey;
|
|
24
|
+
private collectingKey;
|
|
25
|
+
private key;
|
|
26
|
+
private lastKey;
|
|
27
|
+
/** After `"<wanted>":`, waiting for the value's first character. */
|
|
28
|
+
private pending;
|
|
29
|
+
private capturing;
|
|
30
|
+
private captured;
|
|
31
|
+
private capturedLength;
|
|
32
|
+
private finished;
|
|
33
|
+
private result;
|
|
34
|
+
private started;
|
|
35
|
+
constructor(wanted: string, maxValueLength: number);
|
|
36
|
+
/** True once the member was captured (or proven absent or not an
|
|
37
|
+
* object), so the caller may stop reading. */
|
|
38
|
+
get done(): boolean;
|
|
39
|
+
/** The member's value, parsed; undefined while scanning or when absent. */
|
|
40
|
+
get value(): unknown;
|
|
41
|
+
/** Feeds the next decoded text. Throws JsonMemberTooLarge when the
|
|
42
|
+
* member's value exceeds its bound. */
|
|
43
|
+
push(text: string): void;
|
|
44
|
+
private appendKey;
|
|
45
|
+
private capture;
|
|
46
|
+
private finish;
|
|
47
|
+
}
|
|
48
|
+
/** Reads `stream` (UTF-8 JSON) until the top-level member `wanted` has
|
|
49
|
+
* been captured, then cancels the rest. Returns its parsed value, or
|
|
50
|
+
* undefined when the document has no such object-valued member. At most
|
|
51
|
+
* `maxBytes` of the stream are read; more throws JsonMemberTooLarge. */
|
|
52
|
+
export declare function scanTopLevelMember(stream: ReadableStream<Uint8Array>, wanted: string, limits: {
|
|
53
|
+
maxBytes: number;
|
|
54
|
+
maxValueLength: number;
|
|
55
|
+
}): Promise<unknown>;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A streaming scan for one top-level member of a JSON object document,
|
|
3
|
+
* without ever holding the document: only the wanted member's value text is
|
|
4
|
+
* kept (bounded), and every other value, however large, is skipped as it
|
|
5
|
+
* streams past. Used to read an npm packument's `time` (per-version publish
|
|
6
|
+
* times), which comes after `versions` and can follow tens of MB of it.
|
|
7
|
+
*
|
|
8
|
+
* It is a tokenizer, not a validator: it tracks strings, escapes and
|
|
9
|
+
* nesting depth, which is all that locating a top-level member needs. The
|
|
10
|
+
* captured value is then parsed with JSON.parse, so a malformed value
|
|
11
|
+
* throws there. A document that is not an object, or that ends before the
|
|
12
|
+
* member closes, yields null.
|
|
13
|
+
*/
|
|
14
|
+
/** Longest top-level key compared; a longer one cannot be the wanted key. */
|
|
15
|
+
const MAX_KEY_LENGTH = 256;
|
|
16
|
+
export class JsonMemberTooLarge extends Error {
|
|
17
|
+
}
|
|
18
|
+
export class TopLevelMemberScanner {
|
|
19
|
+
wanted;
|
|
20
|
+
maxValueLength;
|
|
21
|
+
depth = 0;
|
|
22
|
+
inString = false;
|
|
23
|
+
escape = false;
|
|
24
|
+
/** At depth 1, the next string is a key. */
|
|
25
|
+
expectKey = false;
|
|
26
|
+
collectingKey = false;
|
|
27
|
+
key = "";
|
|
28
|
+
lastKey;
|
|
29
|
+
/** After `"<wanted>":`, waiting for the value's first character. */
|
|
30
|
+
pending = false;
|
|
31
|
+
capturing = false;
|
|
32
|
+
captured = [];
|
|
33
|
+
capturedLength = 0;
|
|
34
|
+
finished = false;
|
|
35
|
+
result = undefined;
|
|
36
|
+
started = false;
|
|
37
|
+
constructor(wanted, maxValueLength) {
|
|
38
|
+
this.wanted = wanted;
|
|
39
|
+
this.maxValueLength = maxValueLength;
|
|
40
|
+
}
|
|
41
|
+
/** True once the member was captured (or proven absent or not an
|
|
42
|
+
* object), so the caller may stop reading. */
|
|
43
|
+
get done() {
|
|
44
|
+
return this.finished;
|
|
45
|
+
}
|
|
46
|
+
/** The member's value, parsed; undefined while scanning or when absent. */
|
|
47
|
+
get value() {
|
|
48
|
+
return this.result;
|
|
49
|
+
}
|
|
50
|
+
/** Feeds the next decoded text. Throws JsonMemberTooLarge when the
|
|
51
|
+
* member's value exceeds its bound. */
|
|
52
|
+
push(text) {
|
|
53
|
+
if (this.finished)
|
|
54
|
+
return;
|
|
55
|
+
let segmentStart = this.capturing ? 0 : -1;
|
|
56
|
+
const length = text.length;
|
|
57
|
+
let i = 0;
|
|
58
|
+
while (i < length) {
|
|
59
|
+
if (this.inString) {
|
|
60
|
+
if (this.escape) {
|
|
61
|
+
this.escape = false;
|
|
62
|
+
if (this.collectingKey)
|
|
63
|
+
this.appendKey(text[i]);
|
|
64
|
+
i += 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
// Skip ahead to the next quote or backslash: the bulk of a
|
|
68
|
+
// packument is string content, never looked at char by char.
|
|
69
|
+
const quote = text.indexOf('"', i);
|
|
70
|
+
const backslash = text.indexOf("\\", i);
|
|
71
|
+
const stop = quote < 0 ? backslash : backslash < 0 ? quote : Math.min(quote, backslash);
|
|
72
|
+
if (stop < 0) {
|
|
73
|
+
if (this.collectingKey)
|
|
74
|
+
this.appendKey(text.slice(i));
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
if (this.collectingKey)
|
|
78
|
+
this.appendKey(text.slice(i, stop));
|
|
79
|
+
if (stop === backslash) {
|
|
80
|
+
this.escape = true;
|
|
81
|
+
if (this.collectingKey)
|
|
82
|
+
this.appendKey("\\");
|
|
83
|
+
i = stop + 1;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
this.inString = false;
|
|
87
|
+
if (this.collectingKey) {
|
|
88
|
+
this.collectingKey = false;
|
|
89
|
+
this.lastKey = this.key;
|
|
90
|
+
}
|
|
91
|
+
i = stop + 1;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const c = text[i];
|
|
95
|
+
if (c === " " || c === "\n" || c === "\r" || c === "\t") {
|
|
96
|
+
i += 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (!this.started) {
|
|
100
|
+
this.started = true;
|
|
101
|
+
if (c !== "{")
|
|
102
|
+
return this.finish(undefined);
|
|
103
|
+
}
|
|
104
|
+
if (this.pending) {
|
|
105
|
+
this.pending = false;
|
|
106
|
+
if (c !== "{")
|
|
107
|
+
return this.finish(undefined);
|
|
108
|
+
this.capturing = true;
|
|
109
|
+
segmentStart = i;
|
|
110
|
+
}
|
|
111
|
+
if (c === '"') {
|
|
112
|
+
this.inString = true;
|
|
113
|
+
if (this.depth === 1 && this.expectKey) {
|
|
114
|
+
this.collectingKey = true;
|
|
115
|
+
this.key = "";
|
|
116
|
+
this.expectKey = false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (c === "{" || c === "[") {
|
|
120
|
+
this.depth += 1;
|
|
121
|
+
if (this.depth === 1)
|
|
122
|
+
this.expectKey = true;
|
|
123
|
+
}
|
|
124
|
+
else if (c === "}" || c === "]") {
|
|
125
|
+
this.depth -= 1;
|
|
126
|
+
if (this.capturing && this.depth === 1) {
|
|
127
|
+
this.capture(text.slice(segmentStart, i + 1));
|
|
128
|
+
return this.finish(JSON.parse(this.captured.join("")));
|
|
129
|
+
}
|
|
130
|
+
if (this.depth === 0)
|
|
131
|
+
return this.finish(undefined);
|
|
132
|
+
}
|
|
133
|
+
else if (c === ":") {
|
|
134
|
+
if (this.depth === 1 && this.lastKey === this.wanted)
|
|
135
|
+
this.pending = true;
|
|
136
|
+
}
|
|
137
|
+
else if (c === ",") {
|
|
138
|
+
if (this.depth === 1) {
|
|
139
|
+
this.expectKey = true;
|
|
140
|
+
this.lastKey = undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
i += 1;
|
|
144
|
+
}
|
|
145
|
+
if (this.capturing && segmentStart >= 0)
|
|
146
|
+
this.capture(text.slice(segmentStart));
|
|
147
|
+
}
|
|
148
|
+
appendKey(part) {
|
|
149
|
+
if (this.key.length <= MAX_KEY_LENGTH)
|
|
150
|
+
this.key += part.slice(0, MAX_KEY_LENGTH + 1 - this.key.length);
|
|
151
|
+
}
|
|
152
|
+
capture(part) {
|
|
153
|
+
this.capturedLength += part.length;
|
|
154
|
+
if (this.capturedLength > this.maxValueLength)
|
|
155
|
+
throw new JsonMemberTooLarge(`"${this.wanted}" is too large`);
|
|
156
|
+
this.captured.push(part);
|
|
157
|
+
}
|
|
158
|
+
finish(value) {
|
|
159
|
+
this.finished = true;
|
|
160
|
+
this.result = value;
|
|
161
|
+
this.captured = [];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Reads `stream` (UTF-8 JSON) until the top-level member `wanted` has
|
|
165
|
+
* been captured, then cancels the rest. Returns its parsed value, or
|
|
166
|
+
* undefined when the document has no such object-valued member. At most
|
|
167
|
+
* `maxBytes` of the stream are read; more throws JsonMemberTooLarge. */
|
|
168
|
+
export async function scanTopLevelMember(stream, wanted, limits) {
|
|
169
|
+
const scanner = new TopLevelMemberScanner(wanted, limits.maxValueLength);
|
|
170
|
+
const decoder = new TextDecoder("utf-8");
|
|
171
|
+
const reader = stream.getReader();
|
|
172
|
+
let bytes = 0;
|
|
173
|
+
try {
|
|
174
|
+
for (;;) {
|
|
175
|
+
const { done, value } = await reader.read();
|
|
176
|
+
if (done) {
|
|
177
|
+
scanner.push(decoder.decode());
|
|
178
|
+
return scanner.value;
|
|
179
|
+
}
|
|
180
|
+
bytes += value.byteLength;
|
|
181
|
+
if (bytes > limits.maxBytes)
|
|
182
|
+
throw new JsonMemberTooLarge(`the document is larger than ${limits.maxBytes} bytes`);
|
|
183
|
+
scanner.push(decoder.decode(value, { stream: true }));
|
|
184
|
+
if (scanner.done)
|
|
185
|
+
return scanner.value;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
await reader.cancel().catch(() => undefined);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrites the proxy download URLs a package manager records in lockfiles
|
|
3
|
+
* back to public ones, for every adapter with a `lockfiles` hook. The driver
|
|
4
|
+
* runs this on the workspace before it is collected, so a committed lockfile
|
|
5
|
+
* never points at the sandbox-only proxy host.
|
|
6
|
+
*
|
|
7
|
+
* Best effort by design: a file that cannot be read or written safely is
|
|
8
|
+
* skipped, never a reason to fail the run. The walk never follows symlinks
|
|
9
|
+
* and skips the folders collection excludes by name (dependency and cache
|
|
10
|
+
* folders), which are never sent back anyway.
|
|
11
|
+
*/
|
|
12
|
+
import { constants } from "node:fs";
|
|
13
|
+
import { open, readdir } from "node:fs/promises";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { BUILTIN_COLLECT_EXCLUDE_NAMES } from "../collect-exclude.js";
|
|
16
|
+
import { REGISTRY_ADAPTERS } from "./adapters.js";
|
|
17
|
+
import { registryUrlFor } from "./worker-config.js";
|
|
18
|
+
const MAX_LOCKFILE_BYTES = 64 * 1024 * 1024;
|
|
19
|
+
const MAX_DEPTH = 32;
|
|
20
|
+
const SKIPPED_DIRECTORIES = new Set([...BUILTIN_COLLECT_EXCLUDE_NAMES, ".git"]);
|
|
21
|
+
/** Rewrites one file in place through a single descriptor (no symlinks, no
|
|
22
|
+
* path re-resolution between the checks and the write). Returns whether it
|
|
23
|
+
* changed; any failure leaves the file as it was found or skips it. */
|
|
24
|
+
async function normalizeFile(path, normalize) {
|
|
25
|
+
let file;
|
|
26
|
+
try {
|
|
27
|
+
file = await open(path, constants.O_RDWR | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const metadata = await file.stat();
|
|
34
|
+
if (!metadata.isFile() || metadata.size > MAX_LOCKFILE_BYTES)
|
|
35
|
+
return false;
|
|
36
|
+
const before = (await file.readFile()).toString("utf8");
|
|
37
|
+
const after = normalize(before);
|
|
38
|
+
if (after === before)
|
|
39
|
+
return false;
|
|
40
|
+
await file.truncate(0);
|
|
41
|
+
await file.write(after, 0, "utf8");
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await file.close();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Normalises every recognised lockfile under `workspace`; returns the
|
|
52
|
+
* workspace-relative paths it rewrote, sorted. */
|
|
53
|
+
export async function normalizeRegistryLockfiles(input) {
|
|
54
|
+
const byName = new Map();
|
|
55
|
+
for (const adapter of REGISTRY_ADAPTERS.values()) {
|
|
56
|
+
const lockfiles = adapter.lockfiles;
|
|
57
|
+
if (!lockfiles)
|
|
58
|
+
continue;
|
|
59
|
+
const registryUrl = registryUrlFor(input.proxyBaseUrl, adapter.id);
|
|
60
|
+
for (const name of lockfiles.names)
|
|
61
|
+
byName.set(name, (content) => lockfiles.normalize(content, registryUrl));
|
|
62
|
+
}
|
|
63
|
+
const rewritten = [];
|
|
64
|
+
const walk = async (relative, depth) => {
|
|
65
|
+
let entries;
|
|
66
|
+
try {
|
|
67
|
+
entries = await readdir(join(input.workspace, relative), { withFileTypes: true });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
const path = relative ? `${relative}/${entry.name}` : entry.name;
|
|
74
|
+
// Dirent types come from lstat semantics: a symlink is neither a directory nor a file here.
|
|
75
|
+
if (entry.isDirectory()) {
|
|
76
|
+
if (depth < MAX_DEPTH && !SKIPPED_DIRECTORIES.has(entry.name))
|
|
77
|
+
await walk(path, depth + 1);
|
|
78
|
+
}
|
|
79
|
+
else if (entry.isFile()) {
|
|
80
|
+
const normalize = byName.get(entry.name);
|
|
81
|
+
if (normalize && (await normalizeFile(join(input.workspace, path), normalize)))
|
|
82
|
+
rewritten.push(path);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (byName.size > 0)
|
|
87
|
+
await walk("", 0);
|
|
88
|
+
return rewritten.sort();
|
|
89
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Same shape as the adapter's allowlist name check (scoped names are lower case). */
|
|
2
|
+
export declare const PACKAGE_NAME: RegExp;
|
|
3
|
+
/** `https://registry.npmjs.org/@scope/pkg/-/pkg-1.0.0.tgz` */
|
|
4
|
+
export declare function publicNpmTarballUrl(name: string, version: string): string;
|
|
5
|
+
export declare function normalizeNpmLockfile(content: string, registryUrl: string): string;
|
|
6
|
+
export declare const npmLockfiles: {
|
|
7
|
+
readonly names: readonly ["package-lock.json", "npm-shrinkwrap.json"];
|
|
8
|
+
readonly normalize: typeof normalizeNpmLockfile;
|
|
9
|
+
};
|