@wardby/cli 0.2.0 → 0.3.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 +34 -4
- package/README.md +183 -71
- package/dist/claude-coding-worker/driver.d.ts +7 -1
- package/dist/claude-coding-worker/driver.js +31 -2
- package/dist/claude-coding-worker/main.js +5 -2
- 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 +13 -4
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +219 -29
- 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 +99 -3
- package/dist/coding/protocol.js +155 -4
- 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 +18 -0
- package/dist/coding-worker/artifact.js +48 -6
- 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 +14 -1
- package/dist/coding-worker/driver.js +106 -14
- package/dist/coding-worker/errors.d.ts +7 -0
- package/dist/coding-worker/errors.js +26 -0
- package/dist/coding-worker/main.js +13 -4
- 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 +41 -0
- package/dist/config/providers.js +66 -0
- package/dist/core/budget-groups.d.ts +109 -6
- package/dist/core/budget-groups.js +125 -19
- package/dist/core/budget-wording.d.ts +22 -0
- package/dist/core/budget-wording.js +55 -0
- package/dist/core/coding-queue.d.ts +1 -1
- package/dist/core/datastores.d.ts +1 -1
- package/dist/core/datastores.js +18 -2
- package/dist/core/db.d.ts +40 -2
- package/dist/core/db.js +75 -2
- package/dist/core/dispatch.d.ts +49 -7
- package/dist/core/dispatch.js +290 -45
- package/dist/core/engine-native.js +27 -10
- package/dist/core/grants.d.ts +86 -0
- package/dist/core/grants.js +126 -0
- package/dist/core/host-events.d.ts +49 -0
- package/dist/core/host-events.js +257 -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 +61 -0
- package/dist/core/host-status.js +211 -0
- package/dist/core/http-runtime.js +3 -4
- package/dist/core/in-flight-runs.d.ts +8 -0
- package/dist/core/in-flight-runs.js +56 -0
- package/dist/core/lease.d.ts +1 -1
- package/dist/core/private-directory.d.ts +20 -0
- package/dist/core/private-directory.js +36 -0
- package/dist/core/provider-wording.d.ts +12 -0
- package/dist/core/provider-wording.js +44 -0
- package/dist/core/reconciler.d.ts +39 -3
- package/dist/core/reconciler.js +86 -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 +347 -0
- package/dist/core/run-heartbeat.d.ts +27 -0
- package/dist/core/run-heartbeat.js +54 -0
- package/dist/core/runner.d.ts +31 -9
- package/dist/core/runner.js +237 -40
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/secrets.d.ts +12 -3
- package/dist/core/secrets.js +25 -6
- package/dist/core/subagent-memory-tools.d.ts +2 -2
- 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 +64 -0
- package/dist/core/untrusted-content.d.ts +32 -0
- package/dist/core/untrusted-content.js +72 -0
- package/dist/core/webhooks.d.ts +9 -2
- package/dist/core/webhooks.js +23 -2
- package/dist/generated/prisma/browser.d.ts +328 -0
- package/dist/generated/prisma/browser.js +17 -0
- package/dist/generated/prisma/client.d.ts +347 -0
- package/dist/generated/prisma/client.js +34 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +839 -0
- package/dist/generated/prisma/commonInputTypes.js +10 -0
- package/dist/generated/prisma/enums.d.ts +59 -0
- package/dist/generated/prisma/enums.js +59 -0
- package/dist/generated/prisma/internal/class.d.ts +605 -0
- package/dist/generated/prisma/internal/class.js +49 -0
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +4494 -0
- package/dist/generated/prisma/internal/prismaNamespace.js +628 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +635 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +599 -0
- package/dist/generated/prisma/models/Agent.d.ts +3560 -0
- package/dist/generated/prisma/models/Agent.js +1 -0
- package/dist/generated/prisma/models/AgentDatastore.d.ts +1210 -0
- package/dist/generated/prisma/models/AgentDatastore.js +1 -0
- package/dist/generated/prisma/models/AgentMemory.d.ts +986 -0
- package/dist/generated/prisma/models/AgentMemory.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/AgentSecret.d.ts +1212 -0
- package/dist/generated/prisma/models/AgentSecret.js +1 -0
- package/dist/generated/prisma/models/AgentSubAgent.d.ts +1217 -0
- package/dist/generated/prisma/models/AgentSubAgent.js +1 -0
- package/dist/generated/prisma/models/AgentTool.d.ts +1403 -0
- package/dist/generated/prisma/models/AgentTool.js +1 -0
- package/dist/generated/prisma/models/AuthFormChallenge.d.ts +1298 -0
- package/dist/generated/prisma/models/AuthFormChallenge.js +1 -0
- package/dist/generated/prisma/models/AuthLoginKey.d.ts +1245 -0
- package/dist/generated/prisma/models/AuthLoginKey.js +1 -0
- package/dist/generated/prisma/models/AuthRateLimit.d.ts +979 -0
- package/dist/generated/prisma/models/AuthRateLimit.js +1 -0
- package/dist/generated/prisma/models/AuthSession.d.ts +1376 -0
- package/dist/generated/prisma/models/AuthSession.js +1 -0
- package/dist/generated/prisma/models/AuthUser.d.ts +1700 -0
- package/dist/generated/prisma/models/AuthUser.js +1 -0
- package/dist/generated/prisma/models/BudgetGroup.d.ts +1548 -0
- package/dist/generated/prisma/models/BudgetGroup.js +1 -0
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +1681 -0
- package/dist/generated/prisma/models/CodingAgentProfile.js +1 -0
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +1749 -0
- package/dist/generated/prisma/models/CodingProxyRequest.js +1 -0
- package/dist/generated/prisma/models/CodingProxySession.d.ts +1626 -0
- package/dist/generated/prisma/models/CodingProxySession.js +1 -0
- package/dist/generated/prisma/models/CodingRun.d.ts +3583 -0
- package/dist/generated/prisma/models/CodingRun.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/Datastore.d.ts +1434 -0
- package/dist/generated/prisma/models/Datastore.js +1 -0
- package/dist/generated/prisma/models/DatastoreEntry.d.ts +1314 -0
- package/dist/generated/prisma/models/DatastoreEntry.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/OAuthAuthorizationCode.d.ts +1526 -0
- package/dist/generated/prisma/models/OAuthAuthorizationCode.js +1 -0
- package/dist/generated/prisma/models/OAuthAuthorizationRequest.d.ts +1350 -0
- package/dist/generated/prisma/models/OAuthAuthorizationRequest.js +1 -0
- package/dist/generated/prisma/models/OAuthClient.d.ts +1289 -0
- package/dist/generated/prisma/models/OAuthClient.js +1 -0
- package/dist/generated/prisma/models/OAuthFamily.d.ts +1540 -0
- package/dist/generated/prisma/models/OAuthFamily.js +1 -0
- package/dist/generated/prisma/models/OAuthGrant.d.ts +1280 -0
- package/dist/generated/prisma/models/OAuthGrant.js +1 -0
- package/dist/generated/prisma/models/Principal.d.ts +2245 -0
- package/dist/generated/prisma/models/Principal.js +1 -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 +2669 -0
- package/dist/generated/prisma/models/Run.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/SchedulerLease.d.ts +970 -0
- package/dist/generated/prisma/models/SchedulerLease.js +1 -0
- package/dist/generated/prisma/models/Secret.d.ts +1399 -0
- package/dist/generated/prisma/models/Secret.js +1 -0
- package/dist/generated/prisma/models/SecretElicitationOutcome.d.ts +973 -0
- package/dist/generated/prisma/models/SecretElicitationOutcome.js +1 -0
- package/dist/generated/prisma/models/Task.d.ts +1176 -0
- package/dist/generated/prisma/models/Task.js +1 -0
- package/dist/generated/prisma/models/Tool.d.ts +1490 -0
- package/dist/generated/prisma/models/Tool.js +1 -0
- package/dist/generated/prisma/models/Webhook.d.ts +1386 -0
- package/dist/generated/prisma/models/Webhook.js +1 -0
- package/dist/generated/prisma/models.d.ts +45 -0
- package/dist/generated/prisma/models.js +1 -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 +660 -0
- package/dist/import/cli-args.js +3 -2
- package/dist/import/create.d.ts +6 -1
- package/dist/import/create.js +68 -14
- package/dist/import/index.d.ts +1 -1
- package/dist/import/index.js +19 -9
- package/dist/import/neutral-schema.d.ts +11 -11
- package/dist/mcp/auth/access.d.ts +70 -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 +37 -63
- package/dist/mcp/auth/ownership.js +19 -14
- package/dist/mcp/auth/principal.d.ts +1 -1
- 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 +32 -3
- package/dist/mcp/auth/resource-server.js +84 -3
- package/dist/mcp/auth/self-hosted/browser.js +22 -8
- package/dist/mcp/auth/self-hosted/cli.d.ts +1 -1
- package/dist/mcp/auth/self-hosted/cli.js +47 -13
- package/dist/mcp/auth/self-hosted/credentials.d.ts +21 -3
- package/dist/mcp/auth/self-hosted/credentials.js +62 -4
- package/dist/mcp/auth/self-hosted/rate-limit.d.ts +1 -1
- package/dist/mcp/auth/self-hosted/session.d.ts +3 -2
- package/dist/mcp/context.d.ts +28 -2
- package/dist/mcp/errors.d.ts +25 -6
- package/dist/mcp/errors.js +98 -0
- package/dist/mcp/host-events/github-ingress.d.ts +36 -0
- package/dist/mcp/host-events/github-ingress.js +92 -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/index.d.ts +8 -1
- package/dist/mcp/index.js +106 -16
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +27 -9
- package/dist/mcp/shared/page-style.d.ts +16 -0
- package/dist/mcp/shared/page-style.js +129 -0
- package/dist/mcp/tasks/manager.d.ts +1 -1
- package/dist/mcp/tools/agents.js +447 -49
- package/dist/mcp/tools/budget-groups.js +3 -3
- package/dist/mcp/tools/datastore.js +23 -16
- 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/memory.d.ts +7 -1
- package/dist/mcp/tools/memory.js +5 -5
- package/dist/mcp/tools/repositories.d.ts +2 -0
- package/dist/mcp/tools/repositories.js +181 -0
- package/dist/mcp/tools/runs.d.ts +6 -0
- package/dist/mcp/tools/runs.js +60 -6
- package/dist/mcp/tools/scheduling.js +4 -7
- package/dist/mcp/tools/secret-elicitation-form.d.ts +1 -1
- package/dist/mcp/tools/secret-elicitation-form.js +10 -28
- package/dist/mcp/tools/secret-elicitation.d.ts +1 -1
- 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 +53 -17
- package/dist/mcp/tools/tools.d.ts +41 -0
- package/dist/mcp/tools/tools.js +202 -41
- package/dist/mcp/tools/trigger.js +36 -6
- package/dist/mcp/tools/webhooks.js +15 -4
- package/dist/mcp/transport/streamable-http.d.ts +11 -1
- package/dist/mcp/transport/streamable-http.js +32 -2
- package/dist/mcp/unattended-schedules.d.ts +1 -1
- package/dist/mcp/webhooks/ingress.d.ts +1 -1
- package/dist/providers/auth/delegating.d.ts +19 -0
- package/dist/providers/auth/delegating.js +71 -0
- package/dist/providers/auth/index.d.ts +3 -1
- package/dist/providers/auth/index.js +11 -0
- package/dist/providers/auth/self-hosted.d.ts +4 -3
- package/dist/providers/auth/self-hosted.js +16 -4
- package/dist/providers/auth/types.d.ts +6 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +3 -0
- package/dist/providers/coding-proxy/memory-ledger.js +21 -2
- package/dist/providers/coding-proxy/metering.d.ts +4 -0
- package/dist/providers/coding-proxy/metering.js +28 -2
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +18 -1
- package/dist/providers/coding-proxy/prisma-ledger.js +50 -5
- package/dist/providers/coding-proxy/proxy.d.ts +13 -0
- package/dist/providers/coding-proxy/proxy.js +479 -18
- 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 +18 -1
- 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 +15 -0
- package/dist/providers/datastore/postgres.d.ts +1 -1
- package/dist/providers/engine/types.d.ts +10 -0
- package/dist/providers/executor/build.d.ts +3 -3
- package/dist/providers/executor/composition.d.ts +4 -1
- package/dist/providers/executor/composition.js +19 -0
- package/dist/providers/executor/container.d.ts +106 -4
- package/dist/providers/executor/container.js +305 -22
- package/dist/providers/executor/dbos.d.ts +3 -4
- package/dist/providers/executor/in-process.d.ts +2 -3
- package/dist/providers/executor/routing.d.ts +7 -0
- package/dist/providers/executor/routing.js +13 -0
- package/dist/providers/executor/types.d.ts +22 -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 +60 -2
- package/dist/providers/jobs/docker.js +313 -50
- 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 +21 -2
- package/dist/providers/jobs/kubernetes.js +117 -31
- package/dist/providers/jobs/types.d.ts +20 -0
- package/dist/providers/llm/anthropic.js +6 -2
- package/dist/providers/llm/bedrock.js +2 -1
- 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 +3 -1
- package/dist/providers/llm/claude-provider.js +5 -1
- package/dist/providers/llm/index.d.ts +1 -1
- package/dist/providers/llm/index.js +1 -1
- package/dist/providers/llm/pricing-anthropic.d.ts +10 -0
- package/dist/providers/llm/pricing-anthropic.js +32 -14
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +8 -0
- package/dist/providers/llm/pricing-bedrock-claude.js +9 -0
- package/dist/providers/llm/routing.d.ts +10 -1
- package/dist/providers/llm/routing.js +18 -0
- package/dist/providers/llm/types.d.ts +12 -0
- package/dist/providers/llm/types.js +8 -1
- package/dist/providers/memory/postgres.d.ts +1 -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 +180 -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 +567 -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 +284 -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 +79 -14
- package/dist/providers/vcs/github.d.ts +74 -3
- package/dist/providers/vcs/github.js +195 -15
- package/dist/providers/vcs/types.d.ts +42 -4
- package/dist/quickstart/index.js +34 -32
- package/dist/quickstart/migrate.d.ts +23 -0
- package/dist/quickstart/migrate.js +125 -0
- 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 +1 -1
- package/dist/wardby-bin.js +6 -0
- package/docs/README.md +30 -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 +481 -0
- package/docs/coding-agent-setup.md +172 -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 +1061 -0
- package/docs/getting-started-gke.md +615 -0
- package/docs/getting-started-identity-provider.md +308 -0
- package/docs/getting-started.md +133 -0
- package/docs/observability.md +53 -0
- package/docs/release-verification.md +66 -0
- package/docs/security-deployment.md +657 -0
- package/help/code-review-agents.md +31 -0
- package/help/coding-packages.md +31 -0
- package/help/coding-services.md +71 -0
- package/help/creating-agents.md +68 -0
- package/help/deploy-gke.md +39 -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/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 +31 -0
- package/help/github.md +30 -0
- package/help/identity-and-access.md +39 -0
- package/help/mcp.md +30 -0
- package/help/native-capabilities.md +30 -0
- package/help/observability.md +41 -0
- package/help/operating-agents.md +30 -0
- package/help/security.md +27 -0
- package/help/troubleshooting/budgets.md +26 -0
- package/help/troubleshooting/coding-workers.md +47 -0
- package/help/troubleshooting/repository-access.md +27 -0
- package/package.json +30 -11
- package/prisma/migrate.config.mjs +20 -0
- 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/schema.prisma +417 -23
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in code-review tools (`repo_*`) for native agents with at least one
|
|
3
|
+
* AgentRepository link. Like the memory built-ins they are synthesized by the
|
|
4
|
+
* runner, recognized by name, and never run in the sandbox. The security
|
|
5
|
+
* boundary is here: every call names a repository, which must resolve to one
|
|
6
|
+
* of this agent's links (with write access for write tools); the host then
|
|
7
|
+
* mints its own least-permission credential. The model never sees a token,
|
|
8
|
+
* a check id, or a marker. Never throws — failures are JSON tool results.
|
|
9
|
+
* See docs/private/2026-09-25-code-review-host-design.md §7.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import { REVIEW_HOST_PROVIDERS, ReviewHostError, } from "../providers/review-host/types.js";
|
|
13
|
+
import { normalizeGitHubRepository } from "../coding/protocol.js";
|
|
14
|
+
import { logger } from "./logger.js";
|
|
15
|
+
import { describeDenial } from "./repo-access.js";
|
|
16
|
+
const log = logger.child({ module: "review-host-tools" });
|
|
17
|
+
const DEFAULT_PATCH_CHARS = 60_000;
|
|
18
|
+
const SHA = z.string().regex(/^[0-9a-f]{40}$/);
|
|
19
|
+
const Repository = z.string().min(1).max(300);
|
|
20
|
+
const PrReadArgs = z
|
|
21
|
+
.object({
|
|
22
|
+
repository: Repository,
|
|
23
|
+
prNumber: z.number().int().positive(),
|
|
24
|
+
sinceSha: SHA.optional(),
|
|
25
|
+
maxPatchChars: z.number().int().positive().max(200_000).optional(),
|
|
26
|
+
})
|
|
27
|
+
.strict();
|
|
28
|
+
const ReadFileArgs = z
|
|
29
|
+
.object({
|
|
30
|
+
repository: Repository,
|
|
31
|
+
path: z.string().min(1).max(500),
|
|
32
|
+
ref: z.string().min(1).max(200).optional(),
|
|
33
|
+
startLine: z.number().int().positive().optional(),
|
|
34
|
+
maxLines: z.number().int().positive().max(2000).optional(),
|
|
35
|
+
})
|
|
36
|
+
.strict();
|
|
37
|
+
const ListFilesArgs = z
|
|
38
|
+
.object({
|
|
39
|
+
repository: Repository,
|
|
40
|
+
ref: z.string().min(1).max(200).optional(),
|
|
41
|
+
pathPrefix: z.string().max(500).optional(),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
const InlineCommentArgs = z
|
|
45
|
+
.object({
|
|
46
|
+
path: z.string().min(1).max(500),
|
|
47
|
+
line: z.number().int().positive(),
|
|
48
|
+
side: z.enum(["LEFT", "RIGHT"]).optional(),
|
|
49
|
+
severity: z.string().min(1).max(20),
|
|
50
|
+
body: z.string().min(1).max(4000),
|
|
51
|
+
})
|
|
52
|
+
.strict();
|
|
53
|
+
const PublishArgs = z
|
|
54
|
+
.object({
|
|
55
|
+
repository: Repository,
|
|
56
|
+
prNumber: z.number().int().positive(),
|
|
57
|
+
headSha: SHA,
|
|
58
|
+
verdict: z.enum(["APPROVE", "CHANGES_REQUESTED", "COMMENT"]),
|
|
59
|
+
summary: z.string().min(1).max(140),
|
|
60
|
+
body: z.string().min(1).max(60_000),
|
|
61
|
+
comments: z.array(InlineCommentArgs).max(50).optional(),
|
|
62
|
+
resolveThreadIds: z
|
|
63
|
+
.array(z.string().regex(/^[A-Za-z0-9_=-]{1,100}$/))
|
|
64
|
+
.max(100)
|
|
65
|
+
.optional(),
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
|
+
const CommentArgs = z
|
|
69
|
+
.object({
|
|
70
|
+
repository: Repository,
|
|
71
|
+
number: z.number().int().positive(),
|
|
72
|
+
body: z.string().min(1).max(20_000),
|
|
73
|
+
replyToReviewCommentId: z
|
|
74
|
+
.string()
|
|
75
|
+
.regex(/^\d{1,20}$/)
|
|
76
|
+
.optional(),
|
|
77
|
+
})
|
|
78
|
+
.strict();
|
|
79
|
+
const REPOSITORY_PROP = {
|
|
80
|
+
type: "string",
|
|
81
|
+
description: 'The repository as "owner/name" (or "github.com/owner/name"); must be one this agent is linked to.',
|
|
82
|
+
};
|
|
83
|
+
export const REVIEW_HOST_TOOL_DEFS = [
|
|
84
|
+
{
|
|
85
|
+
name: "repo_pr_read",
|
|
86
|
+
description: "Reads a pull request: title, body, author, state, refs, headSha, isFork, each changed file's unified-diff patch (patches share a character budget; truncated ones are flagged), lastReviewedSha — the head you last reviewed on this PR, if any — and openThreads: your own unresolved inline review threads (id, path, line, outdated, body). Pass sinceSha (usually lastReviewedSha) to get only what changed since then; if baseMergedSince is true, the base branch was merged in meanwhile and each file shows the PR's full diff against the base, limited to files that changed since sinceSha.",
|
|
87
|
+
jsonSchema: {
|
|
88
|
+
type: "object",
|
|
89
|
+
properties: {
|
|
90
|
+
repository: REPOSITORY_PROP,
|
|
91
|
+
prNumber: { type: "integer", minimum: 1 },
|
|
92
|
+
sinceSha: { type: "string", pattern: "^[0-9a-f]{40}$" },
|
|
93
|
+
maxPatchChars: { type: "integer", minimum: 1, maximum: 200000 },
|
|
94
|
+
},
|
|
95
|
+
required: ["repository", "prNumber"],
|
|
96
|
+
additionalProperties: false,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "repo_read_file",
|
|
101
|
+
description: "Reads a file with line numbers (paged by startLine/maxLines, default 400 lines) or lists a directory, at a ref. Use the PR's headSha as the ref when reviewing.",
|
|
102
|
+
jsonSchema: {
|
|
103
|
+
type: "object",
|
|
104
|
+
properties: {
|
|
105
|
+
repository: REPOSITORY_PROP,
|
|
106
|
+
path: { type: "string" },
|
|
107
|
+
ref: { type: "string" },
|
|
108
|
+
startLine: { type: "integer", minimum: 1 },
|
|
109
|
+
maxLines: { type: "integer", minimum: 1, maximum: 2000 },
|
|
110
|
+
},
|
|
111
|
+
required: ["repository", "path"],
|
|
112
|
+
additionalProperties: false,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "repo_list_files",
|
|
117
|
+
description: 'Lists every file (path and size) at a ref (default: the default branch), optionally under a path prefix such as "tests/". Skips node_modules, dist, and lockfiles.',
|
|
118
|
+
jsonSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: { repository: REPOSITORY_PROP, ref: { type: "string" }, pathPrefix: { type: "string" } },
|
|
121
|
+
required: ["repository"],
|
|
122
|
+
additionalProperties: false,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "repo_publish_review",
|
|
127
|
+
description: "Publishes your review of one pull request head, in one call: inline comments on diff lines (a ```suggestion block in a comment body becomes a one-click fix; comments on lines outside the diff move to the summary automatically), one summary comment that is edited in place on later reviews, and — only on the pull request this run was started for, by an agent linked with a check name — the check conclusion (APPROVE = success, CHANGES_REQUESTED = failure, COMMENT = neutral). Pass resolveThreadIds with the ids of your openThreads that this head fixes; only your own open threads on this PR are resolved, and the result lists resolvedThreadIds and skippedThreadIds. Returns published:false with reason stale_head if the PR moved on; then stop.",
|
|
128
|
+
jsonSchema: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
repository: REPOSITORY_PROP,
|
|
132
|
+
prNumber: { type: "integer", minimum: 1 },
|
|
133
|
+
headSha: { type: "string", pattern: "^[0-9a-f]{40}$" },
|
|
134
|
+
verdict: { type: "string", enum: ["APPROVE", "CHANGES_REQUESTED", "COMMENT"] },
|
|
135
|
+
summary: { type: "string", maxLength: 140, description: "One line, shown on the check." },
|
|
136
|
+
body: { type: "string", maxLength: 60000, description: "The full review in markdown." },
|
|
137
|
+
comments: {
|
|
138
|
+
type: "array",
|
|
139
|
+
maxItems: 50,
|
|
140
|
+
items: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
path: { type: "string" },
|
|
144
|
+
line: {
|
|
145
|
+
type: "integer",
|
|
146
|
+
minimum: 1,
|
|
147
|
+
description: "Line number in the new file (side RIGHT) or the old file (side LEFT).",
|
|
148
|
+
},
|
|
149
|
+
side: { type: "string", enum: ["LEFT", "RIGHT"] },
|
|
150
|
+
severity: { type: "string", description: "e.g. CRITICAL, MAJOR, MINOR, NIT" },
|
|
151
|
+
body: { type: "string", maxLength: 4000 },
|
|
152
|
+
},
|
|
153
|
+
required: ["path", "line", "severity", "body"],
|
|
154
|
+
additionalProperties: false,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
resolveThreadIds: {
|
|
158
|
+
type: "array",
|
|
159
|
+
maxItems: 100,
|
|
160
|
+
items: { type: "string", pattern: "^[A-Za-z0-9_=-]{1,100}$" },
|
|
161
|
+
description: "Ids from repo_pr_read's openThreads whose problem this head fixes. Leave a thread out when unsure.",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
required: ["repository", "prNumber", "headSha", "verdict", "summary", "body"],
|
|
165
|
+
additionalProperties: false,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "repo_comment",
|
|
170
|
+
description: "Posts a comment on an issue or pull request conversation, or — with replyToReviewCommentId — replies inside an inline review thread.",
|
|
171
|
+
jsonSchema: {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {
|
|
174
|
+
repository: REPOSITORY_PROP,
|
|
175
|
+
number: { type: "integer", minimum: 1, description: "The issue or pull request number." },
|
|
176
|
+
body: { type: "string", maxLength: 20000 },
|
|
177
|
+
replyToReviewCommentId: { type: "string", pattern: "^\\d{1,20}$" },
|
|
178
|
+
},
|
|
179
|
+
required: ["repository", "number", "body"],
|
|
180
|
+
additionalProperties: false,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
];
|
|
184
|
+
export const REVIEW_HOST_TOOL_NAMES = new Set(REVIEW_HOST_TOOL_DEFS.map((t) => t.name));
|
|
185
|
+
const WRITE_TOOLS = new Set(["repo_publish_review", "repo_comment"]);
|
|
186
|
+
const HOST_PREFIXES = { github: "github.com/" };
|
|
187
|
+
function normalizeFor(provider, value) {
|
|
188
|
+
try {
|
|
189
|
+
if (provider === "github")
|
|
190
|
+
return normalizeGitHubRepository(value);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
export function resolveLink(links, repositoryArg) {
|
|
198
|
+
const raw = repositoryArg.trim();
|
|
199
|
+
for (const provider of REVIEW_HOST_PROVIDERS) {
|
|
200
|
+
const prefix = HOST_PREFIXES[provider];
|
|
201
|
+
if (raw.toLowerCase().startsWith(prefix)) {
|
|
202
|
+
const repository = normalizeFor(provider, raw.slice(prefix.length));
|
|
203
|
+
return links.find((l) => l.provider === provider && l.repository === repository) ?? null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const matches = links.filter((l) => l.repository === normalizeFor(l.provider, raw));
|
|
207
|
+
if (matches.length > 1)
|
|
208
|
+
return "ambiguous";
|
|
209
|
+
return matches[0] ?? null;
|
|
210
|
+
}
|
|
211
|
+
function error(code, message = code) {
|
|
212
|
+
return JSON.stringify({ error: code, message });
|
|
213
|
+
}
|
|
214
|
+
/** Bookkeeping only: a failure to record the check completed is logged and never changes the tool result. */
|
|
215
|
+
async function markCompleted(ctx) {
|
|
216
|
+
try {
|
|
217
|
+
await ctx.markRunCheckCompleted();
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
log.warn({ err, agentId: ctx.agentId }, "could not record the run's check completed");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Dispatches one built-in repo tool call. Never throws — mirrors
|
|
225
|
+
* runner.ts's `runSandboxTool` contract: a failure becomes a JSON error
|
|
226
|
+
* result fed back to the model as the tool's result, not an engine-halting
|
|
227
|
+
* exception.
|
|
228
|
+
*/
|
|
229
|
+
export async function handleReviewHostTool(name, argsJson, ctx) {
|
|
230
|
+
let parsed;
|
|
231
|
+
try {
|
|
232
|
+
parsed = JSON.parse(argsJson || "{}");
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
return error("invalid_arguments_json", err instanceof Error ? err.message : String(err));
|
|
236
|
+
}
|
|
237
|
+
const repositoryArg = parsed?.repository;
|
|
238
|
+
if (typeof repositoryArg !== "string")
|
|
239
|
+
return error("invalid_arguments", "repository is required");
|
|
240
|
+
const link = resolveLink(ctx.links, repositoryArg);
|
|
241
|
+
if (link === "ambiguous")
|
|
242
|
+
return error("repository_not_linked", "Ambiguous repository; qualify it as host/owner/name.");
|
|
243
|
+
if (!link)
|
|
244
|
+
return error("repository_not_linked", `This agent is not linked to "${repositoryArg}".`);
|
|
245
|
+
if (WRITE_TOOLS.has(name) && link.access !== "write") {
|
|
246
|
+
return error("write_access_required", `This agent's link to ${link.repository} is read-only.`);
|
|
247
|
+
}
|
|
248
|
+
const host = ctx.hosts[link.provider];
|
|
249
|
+
if (!host)
|
|
250
|
+
return error("host_not_configured", `No ${link.provider} host is configured on this deployment.`);
|
|
251
|
+
let decision;
|
|
252
|
+
try {
|
|
253
|
+
decision = await ctx.authorize(link);
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
log.warn({ err, agentId: ctx.agentId }, "repository authorization failed; denying");
|
|
257
|
+
decision = { ok: false, reason: "check_failed" };
|
|
258
|
+
}
|
|
259
|
+
if (!decision.ok) {
|
|
260
|
+
log.info({ agentId: ctx.agentId, repository: link.repository, reason: decision.reason }, "repository use denied");
|
|
261
|
+
return error(decision.reason === "check_unavailable" ? "repository_access_unavailable" : "repository_access_denied", describeDenial(decision, link.repository));
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
switch (name) {
|
|
265
|
+
case "repo_pr_read": {
|
|
266
|
+
const a = PrReadArgs.parse(parsed);
|
|
267
|
+
return JSON.stringify(await host.readPullRequest(link.repository, a.prNumber, {
|
|
268
|
+
sinceSha: a.sinceSha,
|
|
269
|
+
maxPatchChars: a.maxPatchChars ?? DEFAULT_PATCH_CHARS,
|
|
270
|
+
agentMarker: ctx.agentId,
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
case "repo_read_file": {
|
|
274
|
+
const a = ReadFileArgs.parse(parsed);
|
|
275
|
+
return JSON.stringify(await host.readFile(link.repository, a.path, a.ref, {
|
|
276
|
+
startLine: a.startLine ?? 1,
|
|
277
|
+
maxLines: a.maxLines ?? 400,
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
case "repo_list_files": {
|
|
281
|
+
const a = ListFilesArgs.parse(parsed);
|
|
282
|
+
return JSON.stringify(await host.listFiles(link.repository, a.ref, a.pathPrefix));
|
|
283
|
+
}
|
|
284
|
+
case "repo_publish_review": {
|
|
285
|
+
const a = PublishArgs.parse(parsed);
|
|
286
|
+
const runCheck = ctx.runCheck;
|
|
287
|
+
// E-08/H5-4: a verdict check is only ever published on the PR this
|
|
288
|
+
// run was dispatched for (never a fork: those are never dispatched).
|
|
289
|
+
// Any other publish is comments only, with no check at all.
|
|
290
|
+
const samePullRequest = runCheck !== null &&
|
|
291
|
+
runCheck.provider === link.provider &&
|
|
292
|
+
runCheck.repository === link.repository &&
|
|
293
|
+
runCheck.prNumber !== null &&
|
|
294
|
+
runCheck.prNumber === a.prNumber;
|
|
295
|
+
const ownsCheck = samePullRequest && a.headSha === runCheck.headSha;
|
|
296
|
+
if (samePullRequest && !ownsCheck) {
|
|
297
|
+
// The run's check sits on another head; close it rather than attach this review's verdict to it.
|
|
298
|
+
try {
|
|
299
|
+
await host.completeCheck(link.repository, {
|
|
300
|
+
checkId: runCheck.checkId,
|
|
301
|
+
conclusion: "neutral",
|
|
302
|
+
title: "Superseded by a newer push",
|
|
303
|
+
summary: "This run reviewed a newer commit; see that commit's check.",
|
|
304
|
+
});
|
|
305
|
+
await markCompleted(ctx);
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
log.warn({ err, agentId: ctx.agentId }, "could not supersede the run's check");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const result = await host.publishReview(link.repository, {
|
|
312
|
+
prNumber: a.prNumber,
|
|
313
|
+
headSha: a.headSha,
|
|
314
|
+
verdict: a.verdict,
|
|
315
|
+
summary: a.summary,
|
|
316
|
+
body: a.body,
|
|
317
|
+
comments: (a.comments ?? []).map((c) => ({ ...c, side: c.side ?? "RIGHT" })),
|
|
318
|
+
agentMarker: ctx.agentId,
|
|
319
|
+
...(samePullRequest && link.checkName ? { checkName: link.checkName } : {}),
|
|
320
|
+
...(ownsCheck ? { checkId: runCheck.checkId } : {}),
|
|
321
|
+
...(a.resolveThreadIds?.length ? { resolveThreadIds: a.resolveThreadIds } : {}),
|
|
322
|
+
});
|
|
323
|
+
if (ownsCheck)
|
|
324
|
+
await markCompleted(ctx);
|
|
325
|
+
return JSON.stringify(result);
|
|
326
|
+
}
|
|
327
|
+
case "repo_comment": {
|
|
328
|
+
const a = CommentArgs.parse(parsed);
|
|
329
|
+
return JSON.stringify(await host.comment(link.repository, {
|
|
330
|
+
number: a.number,
|
|
331
|
+
body: a.body,
|
|
332
|
+
replyToReviewCommentId: a.replyToReviewCommentId,
|
|
333
|
+
}));
|
|
334
|
+
}
|
|
335
|
+
default:
|
|
336
|
+
return error("unknown_tool", `No built-in tool named "${name}".`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
if (err instanceof z.ZodError) {
|
|
341
|
+
return error("invalid_arguments", err.issues.map((i) => `${i.path.join(".") || "input"}: ${i.message}`).join("; "));
|
|
342
|
+
}
|
|
343
|
+
if (err instanceof ReviewHostError)
|
|
344
|
+
return error(err.code, err.message);
|
|
345
|
+
return error("host_api_error", "The host request failed.");
|
|
346
|
+
}
|
|
347
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Liveness for native runs that no executor watches: an attended
|
|
3
|
+
* `wardby run` and a native sub-agent child, which runs inline inside its
|
|
4
|
+
* parent's tool call. Managed runs already beat through their executor
|
|
5
|
+
* (InProcessExecutor, DbosExecutor). A beat is what keeps a run's budget
|
|
6
|
+
* hold counted against its budget group (budget-groups.ts isHoldLive): once a
|
|
7
|
+
* process dies and the beats stop, the hold lapses on its own instead of
|
|
8
|
+
* pinning the group for the rest of the period.
|
|
9
|
+
*/
|
|
10
|
+
import type { PrismaClient } from "#prisma";
|
|
11
|
+
type RunDb = Pick<PrismaClient, "run">;
|
|
12
|
+
/** Beats `runId` once now and every `intervalMs` until `fn` settles. */
|
|
13
|
+
export declare function withRunHeartbeat<T>(db: RunDb, runId: string, fn: () => Promise<T>, intervalMs?: number): Promise<T>;
|
|
14
|
+
/** The part of `process` an interrupt handler needs (a fake in tests). */
|
|
15
|
+
export interface SignalTarget {
|
|
16
|
+
once(signal: NodeJS.Signals, listener: () => void): unknown;
|
|
17
|
+
off(signal: NodeJS.Signals, listener: () => void): unknown;
|
|
18
|
+
exit(code: number): never | void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* For an attended run: on SIGINT/SIGTERM, record the run as `cancelled`
|
|
22
|
+
* (only if it is still pending/running) and exit with the conventional
|
|
23
|
+
* 128+signal code, instead of leaving a `running` row behind. Returns a
|
|
24
|
+
* function that removes the handlers once the run has finished.
|
|
25
|
+
*/
|
|
26
|
+
export declare function cancelRunOnSignal(db: RunDb, runId: string, target?: SignalTarget): () => void;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { HEARTBEAT_INTERVAL_MS } from "./timing.js";
|
|
2
|
+
async function beat(db, runId) {
|
|
3
|
+
try {
|
|
4
|
+
await db.run.updateMany({
|
|
5
|
+
where: { id: runId, status: { in: ["pending", "running"] } },
|
|
6
|
+
data: { heartbeatAt: new Date() },
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// A missed beat only lets the hold lapse a little sooner; never fatal to the run.
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Beats `runId` once now and every `intervalMs` until `fn` settles. */
|
|
14
|
+
export async function withRunHeartbeat(db, runId, fn, intervalMs = HEARTBEAT_INTERVAL_MS) {
|
|
15
|
+
await beat(db, runId);
|
|
16
|
+
const timer = setInterval(() => void beat(db, runId), intervalMs);
|
|
17
|
+
timer.unref?.();
|
|
18
|
+
try {
|
|
19
|
+
return await fn();
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
clearInterval(timer);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const EXIT_CODES = { SIGINT: 130, SIGTERM: 143 };
|
|
26
|
+
/**
|
|
27
|
+
* For an attended run: on SIGINT/SIGTERM, record the run as `cancelled`
|
|
28
|
+
* (only if it is still pending/running) and exit with the conventional
|
|
29
|
+
* 128+signal code, instead of leaving a `running` row behind. Returns a
|
|
30
|
+
* function that removes the handlers once the run has finished.
|
|
31
|
+
*/
|
|
32
|
+
export function cancelRunOnSignal(db, runId, target = process) {
|
|
33
|
+
const handlers = new Map();
|
|
34
|
+
const remove = () => {
|
|
35
|
+
for (const [signal, handler] of handlers)
|
|
36
|
+
target.off(signal, handler);
|
|
37
|
+
handlers.clear();
|
|
38
|
+
};
|
|
39
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
40
|
+
const handler = () => {
|
|
41
|
+
remove();
|
|
42
|
+
void db.run
|
|
43
|
+
.updateMany({
|
|
44
|
+
where: { id: runId, status: { in: ["pending", "running"] } },
|
|
45
|
+
data: { status: "cancelled", error: `Interrupted by ${signal}.`, finishedAt: new Date() },
|
|
46
|
+
})
|
|
47
|
+
.catch(() => undefined)
|
|
48
|
+
.finally(() => target.exit(EXIT_CODES[signal] ?? 1));
|
|
49
|
+
};
|
|
50
|
+
handlers.set(signal, handler);
|
|
51
|
+
target.once(signal, handler);
|
|
52
|
+
}
|
|
53
|
+
return remove;
|
|
54
|
+
}
|
package/dist/core/runner.d.ts
CHANGED
|
@@ -16,17 +16,26 @@
|
|
|
16
16
|
* down) lives inside the engine now — there is exactly one place that
|
|
17
17
|
* reasons about cost, not one here plus one in the engine.
|
|
18
18
|
*/
|
|
19
|
-
import type { PrismaClient, Run, RunTrigger } from "
|
|
19
|
+
import type { PrismaClient, Run, RunTrigger } from "#prisma";
|
|
20
20
|
import type { ProviderRegistry } from "../providers/index.js";
|
|
21
21
|
import { type StepRunner } from "../providers/engine/types.js";
|
|
22
22
|
import type { Executor } from "../providers/executor/types.js";
|
|
23
|
+
import type { ReviewHostRegistry } from "../providers/review-host/types.js";
|
|
24
|
+
import { type RepoAccessGate } from "./repo-access.js";
|
|
23
25
|
/**
|
|
24
26
|
* The subset of the Prisma client the runner touches — mockable in tests.
|
|
25
27
|
* Includes `codingRun`/`task`/`webhook`/`$transaction`/`$queryRaw` so this
|
|
26
28
|
* also satisfies `dispatch.ts`'s `DispatchDb`, needed for dispatching a
|
|
27
29
|
* coding-kind sub-agent from inside a running native turn loop.
|
|
28
30
|
*/
|
|
29
|
-
export type RunnerDb = Pick<PrismaClient, "agent" | "run" | "agentTool" | "agentSecret" | "agentDatastore" | "budgetGroup" | "agentSubAgent" | "codingRun" | "task" | "webhook" | "$transaction" | "$queryRaw">;
|
|
31
|
+
export type RunnerDb = Pick<PrismaClient, "agent" | "run" | "agentTool" | "agentSecret" | "agentDatastore" | "budgetGroup" | "agentSubAgent" | "resourceGrant" | "codingRun" | "task" | "webhook" | "$transaction" | "$queryRaw" | "agentRepository" | "runHostCheck" | "runHostStatus" | "hostIdentity">;
|
|
32
|
+
/** The providers a native run needs; `executor` and `reviewHosts` are optional capabilities. */
|
|
33
|
+
export type NativeRunProviders = Pick<ProviderRegistry, "llm" | "engine" | "datastore" | "secrets" | "memory"> & {
|
|
34
|
+
executor?: ProviderRegistry["executor"];
|
|
35
|
+
reviewHosts?: ReviewHostRegistry;
|
|
36
|
+
/** Repository authorization for repo_* calls; built from reviewHosts when absent. */
|
|
37
|
+
repoAccess?: RepoAccessGate;
|
|
38
|
+
};
|
|
30
39
|
/**
|
|
31
40
|
* Raised when a run's step boundary observed a cancellation (DbosExecutor's
|
|
32
41
|
* `stop`). `executeRun`'s backstop persists these as `cancelled` with the
|
|
@@ -61,6 +70,19 @@ export interface WaitForCodingChildOptions {
|
|
|
61
70
|
now?: () => number;
|
|
62
71
|
sleep?: (ms: number) => Promise<void>;
|
|
63
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* What a coding sub-agent's run tells the parent run's model. A run refused
|
|
75
|
+
* over its services carries the host sentence (never the raw Run.error), so
|
|
76
|
+
* the parent can pass it on — for a mention, that is the requester.
|
|
77
|
+
*/
|
|
78
|
+
export declare function codingChildResult(run: {
|
|
79
|
+
status: string;
|
|
80
|
+
finalText: string | null;
|
|
81
|
+
costUsd: unknown;
|
|
82
|
+
tokensIn: number;
|
|
83
|
+
tokensOut: number;
|
|
84
|
+
error: string | null;
|
|
85
|
+
}): string;
|
|
64
86
|
/**
|
|
65
87
|
* Polls a dispatched coding child until it reaches a terminal status. Needed
|
|
66
88
|
* because a queued child (every concurrency slot taken) makes Executor.start
|
|
@@ -78,10 +100,10 @@ export declare function waitForCodingChild(options: WaitForCodingChildOptions):
|
|
|
78
100
|
/** Persists a new pending Run for the named agent. Throws if the agent is unknown. */
|
|
79
101
|
export declare function createRun(db: RunnerDb, agentName: string, trigger?: RunTrigger): Promise<Run>;
|
|
80
102
|
/** Drives an existing Run (created by `createRun` or the scheduler) to a terminal state. */
|
|
81
|
-
export declare function executeRun(runId: string, providers:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
103
|
+
export declare function executeRun(runId: string, providers: NativeRunProviders, db?: RunnerDb, onText?: (delta: string) => void, step?: StepRunner): Promise<Run>;
|
|
104
|
+
/**
|
|
105
|
+
* Convenience: create + execute a manual run in one call (what the CLI's
|
|
106
|
+
* `wardby run` uses). No executor watches it, so it beats itself; `onCreated`
|
|
107
|
+
* lets the caller hook the new run (the CLI cancels it on SIGINT/SIGTERM).
|
|
108
|
+
*/
|
|
109
|
+
export declare function runAgent(agentName: string, providers: NativeRunProviders, db?: RunnerDb, onText?: (delta: string) => void, onCreated?: (run: Run) => void): Promise<Run>;
|