@wardby/cli 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -5
- package/README.md +6 -1
- package/deploy/local/docker-compose.quickstart-coding.yml +19 -0
- package/dist/claude-coding-worker/driver.d.ts +33 -3
- package/dist/claude-coding-worker/driver.js +151 -21
- package/dist/claude-coding-worker/main.js +38 -6
- package/dist/claude-coding-worker/sdk.js +29 -2
- package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
- package/dist/claude-coding-worker/tool-socket.js +111 -0
- package/dist/claude-coding-worker/transcript.d.ts +18 -0
- package/dist/claude-coding-worker/transcript.js +77 -0
- package/dist/claude-plugin/command.d.ts +61 -0
- package/dist/claude-plugin/command.js +376 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +3 -1
- package/dist/cli.js +71 -13
- package/dist/coding/code-host.d.ts +16 -0
- package/dist/coding/code-host.js +60 -0
- package/dist/coding/continuation-wording.d.ts +35 -0
- package/dist/coding/continuation-wording.js +73 -0
- package/dist/coding/linked-issue-note.d.ts +23 -0
- package/dist/coding/linked-issue-note.js +47 -0
- package/dist/coding/mcp-token.d.ts +12 -0
- package/dist/coding/mcp-token.js +26 -0
- package/dist/coding/merge-wording.d.ts +28 -0
- package/dist/coding/merge-wording.js +78 -0
- package/dist/coding/pr-description-note.d.ts +9 -0
- package/dist/coding/pr-description-note.js +32 -0
- package/dist/coding/profile.d.ts +46 -126
- package/dist/coding/profile.js +45 -4
- package/dist/coding/protected-path-wording.d.ts +8 -0
- package/dist/coding/protected-path-wording.js +1 -1
- package/dist/coding/protocol.d.ts +264 -346
- package/dist/coding/protocol.js +237 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +17 -0
- package/dist/coding/registry/allowlist.d.ts +12 -0
- package/dist/coding/registry/allowlist.js +14 -1
- package/dist/coding/registry/audit-mode.d.ts +153 -0
- package/dist/coding/registry/audit-mode.js +304 -0
- package/dist/coding/registry/lockfile-shared.d.ts +36 -0
- package/dist/coding/registry/lockfile-shared.js +128 -0
- package/dist/coding/registry/lockfiles.js +1 -1
- package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
- package/dist/coding/registry/npm-lockfile-formats.js +41 -0
- package/dist/coding/registry/npm-lockfile.d.ts +8 -4
- package/dist/coding/registry/npm-lockfile.js +4 -6
- package/dist/coding/registry/npm.js +78 -8
- package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
- package/dist/coding/registry/pnpm-lockfile.js +189 -0
- package/dist/coding/registry/pypi-plan.d.ts +50 -0
- package/dist/coding/registry/pypi-plan.js +406 -0
- package/dist/coding/registry/pypi-requirements.d.ts +58 -0
- package/dist/coding/registry/pypi-requirements.js +155 -0
- package/dist/coding/registry/pypi.d.ts +3 -27
- package/dist/coding/registry/pypi.js +40 -154
- package/dist/coding/registry/refusal-hints.d.ts +20 -0
- package/dist/coding/registry/refusal-hints.js +61 -0
- package/dist/coding/registry/refusal-wording.d.ts +11 -0
- package/dist/coding/registry/refusal-wording.js +56 -0
- package/dist/coding/registry/report.d.ts +70 -8
- package/dist/coding/registry/report.js +112 -5
- package/dist/coding/registry/types.d.ts +58 -8
- package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
- package/dist/coding/registry/yarn-lockfile.js +367 -0
- package/dist/coding/services/catalog.d.ts +37 -351
- package/dist/coding/transcript/claude-code.d.ts +13 -0
- package/dist/coding/transcript/claude-code.js +273 -0
- package/dist/coding/transcript/download-protocol.d.ts +30 -0
- package/dist/coding/transcript/download-protocol.js +18 -0
- package/dist/coding/transcript/format.d.ts +20 -0
- package/dist/coding/transcript/format.js +32 -0
- package/dist/coding/transcript/recorder.d.ts +52 -0
- package/dist/coding/transcript/recorder.js +225 -0
- package/dist/coding/transcript/resume/checkout.d.ts +31 -0
- package/dist/coding/transcript/resume/checkout.js +203 -0
- package/dist/coding/transcript/resume/command.d.ts +17 -0
- package/dist/coding/transcript/resume/command.js +176 -0
- package/dist/coding/transcript/resume/download.d.ts +20 -0
- package/dist/coding/transcript/resume/download.js +153 -0
- package/dist/coding/transcript/resume/launch.d.ts +38 -0
- package/dist/coding/transcript/resume/launch.js +128 -0
- package/dist/coding/transcript/resume/session-file.d.ts +13 -0
- package/dist/coding/transcript/resume/session-file.js +79 -0
- package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
- package/dist/coding/transcript/resume/stand-in.js +49 -0
- package/dist/coding-worker/artifact.d.ts +8 -3
- package/dist/coding-worker/artifact.js +3 -1
- package/dist/coding-worker/debug-trace.d.ts +9 -6
- package/dist/coding-worker/debug-trace.js +16 -19
- package/dist/coding-worker/dependency-cache.d.mts +229 -0
- package/dist/coding-worker/dependency-cache.mjs +2123 -0
- package/dist/coding-worker/driver.d.ts +4 -3
- package/dist/coding-worker/driver.js +124 -39
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/main.js +5 -1
- package/dist/coding-worker/mcp-config.d.ts +27 -0
- package/dist/coding-worker/mcp-config.js +32 -0
- package/dist/coding-worker/sdk.d.ts +36 -0
- package/dist/coding-worker/sdk.js +28 -1
- package/dist/coding-worker/task-note.d.ts +11 -0
- package/dist/coding-worker/task-note.js +13 -0
- package/dist/coding-worker/types.d.ts +15 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/mcp-call-limit.d.ts +8 -0
- package/dist/config/mcp-call-limit.js +18 -0
- package/dist/config/mcp-servers.d.ts +8 -0
- package/dist/config/mcp-servers.js +12 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +92 -0
- package/dist/config/test-simulators.js +333 -0
- package/dist/config/tool-timeout.d.ts +1 -0
- package/dist/config/tool-timeout.js +18 -0
- package/dist/core/async-context.d.ts +2 -0
- package/dist/core/async-context.js +12 -0
- package/dist/core/budget-events.d.ts +108 -0
- package/dist/core/budget-events.js +346 -0
- package/dist/core/budget-groups.d.ts +50 -1
- package/dist/core/budget-groups.js +236 -27
- package/dist/core/budget-stopped-head.d.ts +46 -0
- package/dist/core/budget-stopped-head.js +81 -0
- package/dist/core/budget-topup.d.ts +51 -0
- package/dist/core/budget-topup.js +156 -0
- package/dist/core/budget-wording.d.ts +16 -2
- package/dist/core/budget-wording.js +40 -2
- package/dist/core/coding-mcp.d.ts +36 -0
- package/dist/core/coding-mcp.js +253 -0
- package/dist/core/coding-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -0
- package/dist/core/coding-repository.d.ts +46 -0
- package/dist/core/coding-repository.js +92 -0
- package/dist/core/cron.d.ts +19 -1
- package/dist/core/cron.js +17 -0
- package/dist/core/datastores.js +1 -1
- package/dist/core/deferred-coding.d.ts +14 -0
- package/dist/core/deferred-coding.js +62 -0
- package/dist/core/delegation-child.d.ts +25 -0
- package/dist/core/delegation-child.js +37 -0
- package/dist/core/delegation-slots.d.ts +27 -0
- package/dist/core/delegation-slots.js +44 -0
- package/dist/core/dispatch.d.ts +48 -2
- package/dist/core/dispatch.js +166 -66
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +169 -0
- package/dist/core/grants.d.ts +46 -8
- package/dist/core/grants.js +99 -8
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +291 -27
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +300 -22
- package/dist/core/issue-bridge.d.ts +50 -6
- package/dist/core/issue-bridge.js +124 -33
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +4 -10
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +58 -29
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +14 -1
- package/dist/core/lost-run-children.d.ts +6 -0
- package/dist/core/lost-run-children.js +32 -0
- package/dist/core/mark-ready.d.ts +34 -0
- package/dist/core/mark-ready.js +152 -0
- package/dist/core/markdown-code.d.ts +8 -0
- package/dist/core/markdown-code.js +107 -0
- package/dist/core/mcp-client/client.d.ts +47 -0
- package/dist/core/mcp-client/client.js +141 -0
- package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
- package/dist/core/mcp-client/jsonrpc.js +54 -0
- package/dist/core/mcp-client/results.d.ts +13 -0
- package/dist/core/mcp-client/results.js +42 -0
- package/dist/core/mcp-servers.d.ts +90 -0
- package/dist/core/mcp-servers.js +230 -0
- package/dist/core/mcp-tools.d.ts +108 -0
- package/dist/core/mcp-tools.js +287 -0
- package/dist/core/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +44 -18
- package/dist/core/notification-dispatcher.js +2 -1
- package/dist/core/notification-templates.d.ts +1 -7
- package/dist/core/notification-templates.js +36 -2
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +4 -3
- package/dist/core/reconciler.js +8 -1
- package/dist/core/related-pull-requests.d.ts +11 -3
- package/dist/core/related-pull-requests.js +49 -20
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/review-fix.d.ts +1 -1
- package/dist/core/review-fix.js +4 -3
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +3 -0
- package/dist/core/review-host-tools.js +102 -14
- package/dist/core/review-reads.d.ts +55 -0
- package/dist/core/review-reads.js +233 -0
- package/dist/core/run-status.d.ts +12 -0
- package/dist/core/run-status.js +12 -0
- package/dist/core/runner.d.ts +145 -49
- package/dist/core/runner.js +719 -216
- package/dist/core/schedule-start.d.ts +12 -0
- package/dist/core/schedule-start.js +14 -0
- package/dist/core/secret-broker-config.d.ts +12 -74
- package/dist/core/secret-broker-config.js +1 -1
- package/dist/core/secret-guard.d.ts +49 -0
- package/dist/core/secret-guard.js +119 -0
- package/dist/core/secret-guarded-stores.d.ts +12 -0
- package/dist/core/secret-guarded-stores.js +41 -0
- package/dist/core/secret-spans.d.ts +50 -0
- package/dist/core/secret-spans.js +94 -0
- package/dist/core/secrets.d.ts +11 -1
- package/dist/core/secrets.js +27 -1
- package/dist/core/serializable-retry.d.ts +18 -0
- package/dist/core/serializable-retry.js +43 -0
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/tool-admin.d.ts +5 -1
- package/dist/core/tool-admin.js +7 -2
- package/dist/core/tool-names.d.ts +13 -0
- package/dist/core/tool-names.js +20 -0
- package/dist/core/webhooks.d.ts +4 -0
- package/dist/core/webhooks.js +68 -49
- package/dist/core/workflow-events.d.ts +14 -2
- package/dist/core/workflow-events.js +4 -0
- package/dist/core/workflow-run-events.d.ts +5 -3
- package/dist/core/workflow-run-events.js +45 -9
- package/dist/core/zod-json-schema.d.ts +4 -0
- package/dist/core/zod-json-schema.js +39 -0
- package/dist/core/zod3-window.d.ts +35 -0
- package/dist/core/zod3-window.js +124 -0
- package/dist/generated/prisma/browser.d.ts +65 -3
- package/dist/generated/prisma/client.d.ts +65 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +266 -106
- package/dist/generated/prisma/enums.d.ts +10 -0
- package/dist/generated/prisma/enums.js +8 -0
- package/dist/generated/prisma/internal/class.d.ts +110 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +957 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +166 -2
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +174 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +166 -2
- package/dist/generated/prisma/models/Agent.d.ts +377 -8
- package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
- package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +81 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +228 -7
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +232 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1712 -1
- package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
- package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
- package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
- package/dist/generated/prisma/models/HostProvider.js +1 -0
- package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
- package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
- package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
- package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
- package/dist/generated/prisma/models/McpServer.js +1 -0
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +77 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- package/dist/generated/prisma/models/Principal.d.ts +167 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
- package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
- package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
- package/dist/generated/prisma/models/Run.d.ts +738 -2
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
- package/dist/generated/prisma/models/RunTranscript.js +1 -0
- package/dist/generated/prisma/models/Secret.d.ts +387 -0
- package/dist/generated/prisma/models/Tool.d.ts +223 -1
- package/dist/generated/prisma/models.d.ts +10 -0
- package/dist/help/search.js +12 -3
- package/dist/help-index.json +2033 -110
- package/dist/import/create.js +48 -4
- package/dist/import/neutral-schema.d.ts +51 -281
- package/dist/import/neutral-schema.js +7 -4
- package/dist/knowledge/check.d.ts +1 -1
- package/dist/knowledge/cli.d.ts +11 -1
- package/dist/knowledge/cli.js +37 -4
- package/dist/knowledge/concept.d.ts +3 -19
- package/dist/knowledge/location.d.ts +31 -0
- package/dist/knowledge/location.js +78 -0
- package/dist/mcp/auth/access.d.ts +10 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/grants-cli.d.ts +6 -4
- package/dist/mcp/auth/grants-cli.js +42 -3
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/resource-server.d.ts +3 -1
- package/dist/mcp/auth/resource-server.js +17 -2
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
- package/dist/mcp/context.d.ts +3 -0
- package/dist/mcp/host-events/github-ingress.d.ts +2 -0
- package/dist/mcp/host-events/github-ingress.js +2 -1
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +69 -10
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +33 -14
- package/dist/mcp/tools/agents.d.ts +4 -0
- package/dist/mcp/tools/agents.js +295 -28
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +73 -29
- package/dist/mcp/tools/host-providers.d.ts +2 -0
- package/dist/mcp/tools/host-providers.js +215 -0
- package/dist/mcp/tools/mcp-servers.d.ts +26 -0
- package/dist/mcp/tools/mcp-servers.js +481 -0
- package/dist/mcp/tools/memory.js +11 -1
- package/dist/mcp/tools/notification-channels.js +2 -2
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/repositories.js +65 -12
- package/dist/mcp/tools/run-access.d.ts +16 -0
- package/dist/mcp/tools/run-access.js +25 -0
- package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
- package/dist/mcp/tools/run-transcript-download.js +129 -0
- package/dist/mcp/tools/run-transcript.d.ts +19 -0
- package/dist/mcp/tools/run-transcript.js +70 -0
- package/dist/mcp/tools/runs.js +209 -27
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-elicitation-form.js +5 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -61
- package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
- package/dist/mcp/tools/secret-elicitation.js +25 -2
- package/dist/mcp/tools/secrets.js +40 -6
- package/dist/mcp/tools/stop-run.d.ts +2 -0
- package/dist/mcp/tools/stop-run.js +82 -0
- package/dist/mcp/tools/subagents.js +2 -2
- package/dist/mcp/tools/tools.d.ts +7 -5
- package/dist/mcp/tools/tools.js +64 -16
- package/dist/mcp/tools/trigger.js +28 -6
- package/dist/mcp/transport/http-limits.d.ts +2 -0
- package/dist/mcp/transport/http-limits.js +6 -2
- package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
- package/dist/mcp/transport/stdio-link-host.js +67 -0
- package/dist/mcp/transport/streamable-http.d.ts +13 -0
- package/dist/mcp/transport/streamable-http.js +41 -1
- package/dist/mcp/webhooks/ingress.js +10 -0
- package/dist/native-worker/docker-launcher.d.ts +38 -2
- package/dist/native-worker/docker-launcher.js +65 -5
- package/dist/native-worker/gateway-server.d.ts +55 -3
- package/dist/native-worker/gateway-server.js +152 -34
- package/dist/native-worker/gateway.d.ts +29 -1
- package/dist/native-worker/gateway.js +74 -4
- package/dist/native-worker/http-server.d.ts +7 -1
- package/dist/native-worker/http-server.js +62 -7
- package/dist/native-worker/http-transport.js +1 -1
- package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
- package/dist/native-worker/kubernetes-launcher.js +43 -3
- package/dist/native-worker/launch.d.ts +18 -1
- package/dist/native-worker/launch.js +6 -1
- package/dist/native-worker/ledger.d.ts +24 -4
- package/dist/native-worker/ledger.js +62 -8
- package/dist/native-worker/loopback.js +3 -8
- package/dist/native-worker/main.d.ts +2 -1
- package/dist/native-worker/main.js +14 -3
- package/dist/native-worker/protocol.d.ts +130 -577
- package/dist/native-worker/protocol.js +51 -2
- package/dist/native-worker/sandbox-executor.d.ts +17 -2
- package/dist/native-worker/sandbox-executor.js +78 -4
- package/dist/native-worker/stderr-redaction.d.ts +77 -0
- package/dist/native-worker/stderr-redaction.js +237 -0
- package/dist/native-worker/stdio.d.ts +1 -1
- package/dist/native-worker/stdio.js +6 -5
- package/dist/native-worker/warm-pool.d.ts +2 -2
- package/dist/native-worker/warm-pool.js +4 -4
- package/dist/native-worker/worker.js +28 -2
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/self-hosted.d.ts +1 -1
- package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
- package/dist/providers/coding-proxy/capability-hash.js +5 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
- package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
- package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
- package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
- package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
- package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
- package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
- package/dist/providers/coding-proxy/hold.d.ts +32 -0
- package/dist/providers/coding-proxy/hold.js +86 -0
- package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
- package/dist/providers/coding-proxy/interrupted.js +104 -0
- package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
- package/dist/providers/coding-proxy/mcp-route.js +166 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -2
- package/dist/providers/coding-proxy/memory-ledger.js +99 -8
- package/dist/providers/coding-proxy/metering.d.ts +16 -0
- package/dist/providers/coding-proxy/metering.js +27 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +16 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +209 -69
- package/dist/providers/coding-proxy/proxy.d.ts +21 -2
- package/dist/providers/coding-proxy/proxy.js +300 -48
- package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
- package/dist/providers/coding-proxy/registry/audit.js +94 -17
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
- package/dist/providers/coding-proxy/registry/plan.js +201 -48
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
- package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
- package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
- package/dist/providers/coding-proxy/registry/service.js +579 -112
- package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
- package/dist/providers/coding-proxy/registry/store.js +54 -1
- package/dist/providers/coding-proxy/runtime.d.ts +10 -0
- package/dist/providers/coding-proxy/runtime.js +109 -16
- package/dist/providers/coding-proxy/server.d.ts +9 -1
- package/dist/providers/coding-proxy/server.js +55 -1
- package/dist/providers/coding-proxy/types.d.ts +78 -1
- package/dist/providers/datastore/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +17 -2
- package/dist/providers/engine/types.js +17 -0
- package/dist/providers/executor/composition.d.ts +10 -3
- package/dist/providers/executor/composition.js +52 -7
- package/dist/providers/executor/container.d.ts +394 -9
- package/dist/providers/executor/container.js +1210 -96
- package/dist/providers/executor/dbos-status.d.ts +31 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +50 -1
- package/dist/providers/executor/dbos.js +207 -20
- package/dist/providers/executor/deferred.d.ts +12 -24
- package/dist/providers/executor/deferred.js +10 -29
- package/dist/providers/executor/in-process.d.ts +9 -1
- package/dist/providers/executor/in-process.js +14 -4
- package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
- package/dist/providers/executor/linked-issue-reader.js +30 -0
- package/dist/providers/executor/routing.d.ts +2 -0
- package/dist/providers/executor/routing.js +4 -0
- package/dist/providers/executor/types.d.ts +13 -0
- package/dist/providers/host-tools/invoke.d.ts +37 -0
- package/dist/providers/host-tools/invoke.js +117 -0
- package/dist/providers/host-tools/operations.d.ts +65 -0
- package/dist/providers/host-tools/operations.js +149 -0
- package/dist/providers/host-tools/registry.d.ts +79 -0
- package/dist/providers/host-tools/registry.js +362 -0
- package/dist/providers/host-tools/request-guard.d.ts +17 -0
- package/dist/providers/host-tools/request-guard.js +99 -0
- package/dist/providers/host-tools/self-test.d.ts +64 -0
- package/dist/providers/host-tools/self-test.js +142 -0
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/issue-tracker/types.d.ts +17 -0
- package/dist/providers/issue-tracker/types.js +39 -1
- package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
- package/dist/providers/jobs/claude-tool-setup.js +5 -2
- package/dist/providers/jobs/docker-isolation.d.ts +10 -2
- package/dist/providers/jobs/docker-isolation.js +47 -8
- package/dist/providers/jobs/docker.d.ts +9 -0
- package/dist/providers/jobs/docker.js +60 -11
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
- package/dist/providers/jobs/kubernetes-api.js +10 -0
- package/dist/providers/jobs/kubernetes-client.js +10 -1
- package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
- package/dist/providers/jobs/kubernetes-isolation.js +32 -3
- package/dist/providers/jobs/kubernetes.d.ts +11 -1
- package/dist/providers/jobs/kubernetes.js +111 -17
- package/dist/providers/jobs/types.d.ts +39 -0
- package/dist/providers/jobs/types.js +13 -1
- package/dist/providers/llm/anthropic.js +5 -1
- package/dist/providers/llm/bedrock.d.ts +0 -12
- package/dist/providers/llm/bedrock.js +4 -0
- package/dist/providers/llm/claude-messages.d.ts +3 -1
- package/dist/providers/llm/claude-messages.js +4 -1
- package/dist/providers/llm/claude-provider.d.ts +2 -2
- package/dist/providers/llm/claude-provider.js +2 -2
- package/dist/providers/llm/openai.d.ts +2 -2
- package/dist/providers/llm/openai.js +6 -2
- package/dist/providers/llm/routing.d.ts +2 -2
- package/dist/providers/llm/routing.js +2 -2
- package/dist/providers/llm/types.d.ts +12 -2
- package/dist/providers/review-host/github-events.d.ts +9 -1
- package/dist/providers/review-host/github-events.js +34 -12
- package/dist/providers/review-host/github.d.ts +29 -2
- package/dist/providers/review-host/github.js +224 -29
- package/dist/providers/review-host/local.d.ts +8 -4
- package/dist/providers/review-host/local.js +49 -31
- package/dist/providers/review-host/patch-pages.d.ts +41 -0
- package/dist/providers/review-host/patch-pages.js +176 -0
- package/dist/providers/review-host/review-format.d.ts +19 -1
- package/dist/providers/review-host/review-format.js +38 -7
- package/dist/providers/review-host/types.d.ts +140 -6
- package/dist/providers/review-host/types.js +9 -1
- package/dist/providers/storage/gcs.d.ts +63 -0
- package/dist/providers/storage/gcs.js +69 -0
- package/dist/providers/storage/index.d.ts +15 -0
- package/dist/providers/storage/index.js +14 -0
- package/dist/providers/storage/local.d.ts +24 -0
- package/dist/providers/storage/local.js +92 -0
- package/dist/providers/storage/meter.d.ts +14 -0
- package/dist/providers/storage/meter.js +34 -0
- package/dist/providers/storage/s3.d.ts +41 -0
- package/dist/providers/storage/s3.js +107 -0
- package/dist/providers/storage/types.d.ts +37 -3
- package/dist/providers/storage/types.js +21 -4
- package/dist/providers/vcs/git.d.ts +39 -4
- package/dist/providers/vcs/git.js +339 -26
- package/dist/providers/vcs/github-remote.d.ts +26 -3
- package/dist/providers/vcs/github-remote.js +124 -14
- package/dist/providers/vcs/github.d.ts +183 -44
- package/dist/providers/vcs/github.js +455 -56
- package/dist/providers/vcs/index.d.ts +1 -1
- package/dist/providers/vcs/index.js +9 -2
- package/dist/providers/vcs/pr-description.d.ts +127 -0
- package/dist/providers/vcs/pr-description.js +270 -0
- package/dist/providers/vcs/remote.d.ts +37 -1
- package/dist/providers/vcs/remote.js +7 -1
- package/dist/providers/vcs/routing.d.ts +16 -8
- package/dist/providers/vcs/routing.js +27 -6
- package/dist/providers/vcs/types.d.ts +150 -5
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- package/dist/quickstart/index.d.ts +5 -0
- package/dist/quickstart/index.js +21 -0
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +6 -6
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/eval-core.d.ts +12 -2
- package/dist/sandbox/eval-core.js +20 -4
- package/dist/sandbox/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +5 -0
- package/dist/sandbox/host-functions.js +13 -13
- package/dist/sandbox/limits.d.ts +4 -1
- package/dist/sandbox/limits.js +4 -1
- package/dist/sandbox/run-in-sandbox.d.ts +6 -0
- package/dist/sandbox/run-in-sandbox.js +14 -2
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +1 -1
- package/dist/sandbox/secret-broker.d.ts +1 -0
- package/dist/sandbox/secret-broker.js +4 -5
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/tool-timeout.d.ts +32 -0
- package/dist/sandbox/tool-timeout.js +52 -0
- package/dist/sandbox/user-tool.d.ts +8 -1
- package/dist/sandbox/user-tool.js +9 -3
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +8 -1
- package/dist/viewer/api-schema.d.ts +349 -2627
- package/dist/viewer/api-schema.js +7 -0
- package/dist/viewer/build-schemas.js +6 -2
- package/dist/viewer/graph.js +2 -1
- package/dist/viewer/openapi.js +2 -4
- package/dist/wardby-bin.js +15 -0
- package/docs/README.md +11 -1
- package/docs/agent-recipes.md +95 -24
- package/docs/architecture-runtime.md +1 -1
- package/docs/claude-code-plugin.md +164 -0
- package/docs/code-review-agents.md +557 -41
- package/docs/coding-agent-setup.md +566 -8
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +24 -2
- package/docs/coding-worker-isolation.md +183 -37
- package/docs/debugging-agent-runs.md +242 -0
- package/docs/getting-started-gke.md +129 -141
- package/docs/getting-started-identity-provider.md +53 -38
- package/docs/getting-started.md +17 -0
- package/docs/host-providers.md +294 -0
- package/docs/jira-agents.md +17 -8
- package/docs/knowledge/blob-not-found-semantics.md +41 -0
- package/docs/knowledge/bounded-file-descriptor.md +52 -0
- package/docs/knowledge/delegation-admission-slots.md +52 -0
- package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
- package/docs/knowledge/import-rename-target.md +52 -0
- package/docs/knowledge/index.md +57 -0
- package/docs/knowledge/log.md +9 -0
- package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
- package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
- package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
- package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
- package/docs/knowledge/overview-cli.md +74 -0
- package/docs/knowledge/overview-coding-proxy.md +72 -0
- package/docs/knowledge/overview-coding.md +72 -0
- package/docs/knowledge/overview-config.md +60 -0
- package/docs/knowledge/overview-core.md +72 -0
- package/docs/knowledge/overview-deploy.md +83 -0
- package/docs/knowledge/overview-mcp.md +61 -0
- package/docs/knowledge/overview-prisma.md +72 -0
- package/docs/knowledge/overview-providers.md +89 -0
- package/docs/knowledge/overview-sandbox.md +83 -0
- package/docs/knowledge/overview-surfaces.md +83 -0
- package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
- package/docs/knowledge/proxy-settlement-projections.md +41 -0
- package/docs/knowledge/run-pricing-first-writer.md +43 -0
- package/docs/knowledge/schedule-claim-transaction.md +41 -0
- package/docs/knowledge/secret-entry-replica-contract.md +52 -0
- package/docs/knowledge/terminal-run-first-writer.md +41 -0
- package/docs/knowledge/transactional-agent-authorization.md +52 -0
- package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
- package/docs/knowledge/warm-input-publication.md +30 -0
- package/docs/knowledge/workspace-staging-failure.md +54 -0
- package/docs/knowledge.md +54 -14
- package/docs/mcp-servers.md +254 -0
- package/docs/native-sandbox.md +143 -31
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +139 -29
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +45 -10
- package/docs/viewer-api.md +6 -0
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +28 -2
- package/help/agent-recipes.md +33 -2
- package/help/architecture-agent.md +11 -6
- package/help/brokered-secrets.md +3 -0
- package/help/build-claude-code-image.md +1 -1
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- package/help/claude-code-run-pane.md +40 -0
- package/help/code-review-agents.md +177 -6
- package/help/coding-packages.md +156 -6
- package/help/cost-attribution.md +9 -5
- package/help/creating-agents.md +14 -1
- package/help/dependency-cache.md +143 -0
- package/help/deploy-gke.md +15 -8
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-mcp-pins-unavailable.md +35 -0
- package/help/errors/coding-stream-quota-exceeded.md +33 -0
- package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
- package/help/errors/continuation-closed.md +9 -12
- package/help/errors/database-auth-invalid.md +1 -1
- package/help/errors/delegation-conflict.md +24 -0
- package/help/errors/file-list-truncated.md +45 -0
- package/help/errors/full-read-required.md +49 -0
- package/help/errors/github-account-not-allowed.md +4 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/host-provider-error.md +40 -0
- package/help/errors/host-tool-failed.md +36 -0
- package/help/errors/mcp-call-limit.md +22 -0
- package/help/errors/mcp-call-timeout.md +22 -0
- package/help/errors/mcp-server-auth-failed.md +22 -0
- package/help/errors/mcp-server-credentials-unavailable.md +45 -0
- package/help/errors/mcp-server-error.md +28 -0
- package/help/errors/mcp-server-unreachable.md +22 -0
- package/help/errors/mcp-servers-off.md +21 -0
- package/help/errors/mcp-tool-not-allowed.md +26 -0
- package/help/errors/mcp-tool-removed.md +22 -0
- package/help/errors/mcp-unavailable.md +25 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-capacity.md +1 -1
- package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
- package/help/errors/native-sandbox-docker-failed.md +1 -1
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
- package/help/errors/native-sandbox-image-not-pinned.md +1 -1
- package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-network-unenforced.md +1 -1
- package/help/errors/native-sandbox-requires-catalog.md +1 -1
- package/help/errors/native-sandbox-unavailable.md +1 -1
- package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
- package/help/errors/native-sandbox-worker-exited.md +4 -3
- package/help/errors/native-sandbox-worker-lost.md +1 -1
- package/help/errors/native-sandbox-worker-unready.md +1 -1
- package/help/errors/package-not-allowed-pending.md +52 -0
- package/help/errors/package-not-allowed.md +51 -0
- package/help/errors/package-refusals.md +43 -0
- package/help/errors/patch-cursor-malformed.md +31 -0
- package/help/errors/repository-not-listed.md +36 -0
- package/help/errors/repository-required.md +36 -0
- package/help/errors/run-lost.md +39 -0
- package/help/errors/run-transcript-download.md +44 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/target-merge.md +40 -0
- package/help/errors/tool-timeout.md +38 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/host-providers.md +40 -0
- package/help/identity-and-access.md +6 -1
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +1 -1
- package/help/low-power-mode.md +7 -1
- package/help/mcp-servers.md +73 -0
- package/help/mcp.md +7 -2
- package/help/merge-order-check.md +5 -0
- package/help/native-capabilities.md +55 -1
- package/help/native-sandbox.md +16 -2
- package/help/operating-agents.md +21 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +17 -10
- package/help/repo-instructions-and-skills.md +3 -1
- package/help/resume-runs-locally.md +134 -0
- package/help/review-fix-rounds.md +33 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +19 -5
- package/help/status-comments.md +31 -0
- package/help/stop-run.md +58 -0
- package/help/troubleshooting/budgets.md +28 -0
- package/help/troubleshooting/coding-workers.md +86 -7
- package/help/troubleshooting/debugging-agent-runs.md +29 -0
- package/package.json +18 -10
- package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
- package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
- package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
- package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
- package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
- package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
- package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
- package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
- package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
- package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
- package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
- package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
- package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
- package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
- package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
- package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
- package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
- package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
- package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
- package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
- package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
- package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
- package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
- package/prisma/schema.prisma +468 -109
- package/scripts/git-askpass.sh +1 -1
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -11,6 +11,16 @@ export class KubernetesForbiddenError extends Error {
|
|
|
11
11
|
this.name = "KubernetesForbiddenError";
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
/** A create the namespace ResourceQuota refused (HTTP 403 "exceeded quota"). */
|
|
15
|
+
export class KubernetesQuotaExceededError extends Error {
|
|
16
|
+
/** The refusing quota's name as the API server worded it; unvalidated, and nothing else of the refusal is kept. */
|
|
17
|
+
quotaName;
|
|
18
|
+
constructor(message, options) {
|
|
19
|
+
super(message, options);
|
|
20
|
+
this.name = "KubernetesQuotaExceededError";
|
|
21
|
+
this.quotaName = options?.quotaName;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
14
24
|
/** Stale resourceVersion on replace. */
|
|
15
25
|
export class KubernetesConflictError extends Error {
|
|
16
26
|
constructor(message) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ApiException, AppsV1Api, AuthorizationV1Api, CoreV1Api, Exec, KubeConfig, NetworkingV1Api, PatchStrategy, setHeaderOptions, VersionApi, } from "@kubernetes/client-node";
|
|
7
7
|
import { Writable } from "node:stream";
|
|
8
|
-
import { KubernetesAlreadyExistsError, KubernetesConflictError, KubernetesForbiddenError, KubernetesNotFoundError, } from "./kubernetes-api.js";
|
|
8
|
+
import { KubernetesAlreadyExistsError, KubernetesConflictError, KubernetesForbiddenError, KubernetesNotFoundError, KubernetesQuotaExceededError, } from "./kubernetes-api.js";
|
|
9
9
|
function statusCode(error) {
|
|
10
10
|
return error instanceof ApiException ? error.code : undefined;
|
|
11
11
|
}
|
|
@@ -44,6 +44,11 @@ async function deleteIgnoringMissing(remove) {
|
|
|
44
44
|
throw error;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
/** The error's message plus its body as text, for matching only; never copied into a thrown message. */
|
|
48
|
+
function bodyText(error) {
|
|
49
|
+
const { body, message } = error;
|
|
50
|
+
return `${message}\n${typeof body === "string" ? body : JSON.stringify(body ?? "")}`;
|
|
51
|
+
}
|
|
47
52
|
async function create(what, write) {
|
|
48
53
|
try {
|
|
49
54
|
return await write();
|
|
@@ -54,6 +59,10 @@ async function create(what, write) {
|
|
|
54
59
|
throw new KubernetesAlreadyExistsError(what);
|
|
55
60
|
if (code === 404)
|
|
56
61
|
throw new KubernetesNotFoundError(what);
|
|
62
|
+
if (code === 403 && /exceeded quota/i.test(bodyText(error))) {
|
|
63
|
+
const quotaName = /exceeded quota: ([^\s,"\\]+)/i.exec(bodyText(error))?.[1];
|
|
64
|
+
throw new KubernetesQuotaExceededError(`exceeded quota: ${what}`, { cause: error, quotaName });
|
|
65
|
+
}
|
|
57
66
|
throw error;
|
|
58
67
|
}
|
|
59
68
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { V1Container, V1NetworkPolicy, V1Pod, V1Secret } from "@kubernetes/client-node";
|
|
2
2
|
import { type ResolvedCodingService } from "../../coding/services/catalog.js";
|
|
3
3
|
import type { JobSpec } from "./types.js";
|
|
4
|
+
import { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB } from "./docker-isolation.js";
|
|
4
5
|
import { type KubernetesPlatform } from "./kubernetes-platform.js";
|
|
5
6
|
export declare const KUBERNETES_ISOLATION_ERROR = "kubernetes_isolation_unsupported";
|
|
6
7
|
/** Extra seconds past timeoutSec before Kubernetes kills the pod (keeper included). */
|
|
@@ -12,6 +13,8 @@ export declare const WORKER_CONTAINER = "worker";
|
|
|
12
13
|
export declare const TOOL_RUNNER_CONTAINER = "tool-runner";
|
|
13
14
|
/** The run Secret's key holding the tool runner's setup (claude-tool-setup.ts). */
|
|
14
15
|
export declare const TOOL_SETUP_SECRET_KEY = "tool-setup";
|
|
16
|
+
/** The run Secret's key for the MCP token (a run with MCP tools only); the agent container alone reads it. */
|
|
17
|
+
export declare const MCP_TOKEN_SECRET_KEY = "mcp-token";
|
|
15
18
|
/** Where the tool runner listens and the agent's relay connects (claude-tool-runner/main.mjs). */
|
|
16
19
|
export declare const TOOL_SOCKET_PATH = "/run/wardby/tool/runner.sock";
|
|
17
20
|
/** Every service sidecar's container name starts with this (service-postgres, service-redis, ...). */
|
|
@@ -51,6 +54,7 @@ export declare const ENFORCEMENT_PROBE_PROXY_UNREACHABLE = 4;
|
|
|
51
54
|
* blocking the path — the port is reachable-but-unserved and witnesses nothing.
|
|
52
55
|
*/
|
|
53
56
|
export declare const ENFORCEMENT_PROBE_DENY_REFUSED = 5;
|
|
57
|
+
export { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB };
|
|
54
58
|
export interface KubernetesRunNames {
|
|
55
59
|
token: string;
|
|
56
60
|
runSha: string;
|
|
@@ -80,7 +84,7 @@ export interface RunPodOptions {
|
|
|
80
84
|
}
|
|
81
85
|
export declare function buildRunPod(spec: JobSpec, options: RunPodOptions): V1Pod;
|
|
82
86
|
export declare function buildRunNetworkPolicy(spec: JobSpec, namespace: string): V1NetworkPolicy;
|
|
83
|
-
export declare function buildCapabilitySecret(spec: JobSpec, namespace: string, capability: string, toolSetup?: string): V1Secret;
|
|
87
|
+
export declare function buildCapabilitySecret(spec: JobSpec, namespace: string, capability: string, toolSetup?: string, mcpToken?: string): V1Secret;
|
|
84
88
|
/** A copy of a container's resources with every quantity in one rendering ("1" and "1000m" alike); see normalizeResources. */
|
|
85
89
|
export declare function canonicalResources(r?: V1Container["resources"]): V1Container["resources"];
|
|
86
90
|
/**
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { isIP } from "node:net";
|
|
9
9
|
import { StoredCodingServicesSchema } from "../../coding/services/catalog.js";
|
|
10
|
-
import {
|
|
10
|
+
import { MCP_TOKEN_ENV } from "../../coding/mcp-token.js";
|
|
11
|
+
import { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB, CLAUDE_TOOL_SETUP_ENV, CODING_PROXY_ALIAS, CODING_PROXY_DENY_PORT, CODING_PROXY_PORT, CODING_WORKER_GID, CODING_WORKER_UID, WORKER_STOP_GRACE_SECONDS, claudeToolLimits, isRepositoryDigest, } from "./docker-isolation.js";
|
|
11
12
|
import { GVISOR_RUNTIME_CLASS, KubernetesPlatformError, STORAGE_INIT_EPHEMERAL_MIB, TOOL_RUNNER_EPHEMERAL_MIB, WORKER_EPHEMERAL_MIB, conformResources, describeMib, normalizePlatformMetadata, platformProfile, podEphemeralStorageMib, } from "./kubernetes-platform.js";
|
|
12
13
|
export const KUBERNETES_ISOLATION_ERROR = "kubernetes_isolation_unsupported";
|
|
13
14
|
/** Extra seconds past timeoutSec before Kubernetes kills the pod (keeper included). */
|
|
@@ -19,6 +20,8 @@ export const WORKER_CONTAINER = "worker";
|
|
|
19
20
|
export const TOOL_RUNNER_CONTAINER = "tool-runner";
|
|
20
21
|
/** The run Secret's key holding the tool runner's setup (claude-tool-setup.ts). */
|
|
21
22
|
export const TOOL_SETUP_SECRET_KEY = "tool-setup";
|
|
23
|
+
/** The run Secret's key for the MCP token (a run with MCP tools only); the agent container alone reads it. */
|
|
24
|
+
export const MCP_TOKEN_SECRET_KEY = "mcp-token";
|
|
22
25
|
/** Where the tool runner listens and the agent's relay connects (claude-tool-runner/main.mjs). */
|
|
23
26
|
export const TOOL_SOCKET_PATH = "/run/wardby/tool/runner.sock";
|
|
24
27
|
const CODEX_ENTRYPOINT = "/opt/wardby/coding-worker/main.js";
|
|
@@ -97,6 +100,9 @@ const STORAGE_DIRECTORIES = ["workspace", "input", "output"];
|
|
|
97
100
|
* sandbox (GKE Autopilot annotates it `share: pod`), so the agent's relay can connect.
|
|
98
101
|
*/
|
|
99
102
|
const TOOL_SOCKET_VOLUME = "tool-socket";
|
|
103
|
+
/** Session resume only: the Claude worker's SDK config dir (docker-isolation.ts CLAUDE_CONFIG_SCRATCH_MIB). */
|
|
104
|
+
const CLAUDE_CONFIG_VOLUME = "claude-config";
|
|
105
|
+
export { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB };
|
|
100
106
|
const TOOL_SOCKET_VOLUME_MIB = 1;
|
|
101
107
|
/**
|
|
102
108
|
* `reason` is a short, fixed code naming which check failed (never a value from the spec itself,
|
|
@@ -166,6 +172,11 @@ export function validateKubernetesSpec(spec) {
|
|
|
166
172
|
else if (spec.toolImage !== undefined) {
|
|
167
173
|
throw isolationError("tool-image-set");
|
|
168
174
|
}
|
|
175
|
+
if (spec.sessionResume !== undefined && (spec.sessionResume !== true || spec.provider !== "claude-code")) {
|
|
176
|
+
throw isolationError("session-resume-not-claude");
|
|
177
|
+
}
|
|
178
|
+
if (spec.mcpTools !== undefined && spec.mcpTools !== true)
|
|
179
|
+
throw isolationError("mcp-tools-invalid");
|
|
169
180
|
if (!isRegistryDigest(spec.image))
|
|
170
181
|
throw isolationError("image-not-registry-digest");
|
|
171
182
|
if (spec.services !== undefined) {
|
|
@@ -307,6 +318,10 @@ export function buildRunPod(spec, options) {
|
|
|
307
318
|
env: [
|
|
308
319
|
{ name: "WARDBY_PROXY_URL", value: `http://${CODING_PROXY_ALIAS}:${CODING_PROXY_PORT}` },
|
|
309
320
|
{ name: "WARDBY_RUN_CAPABILITY", valueFrom: { secretKeyRef: { name: names.secret, key: "capability" } } },
|
|
321
|
+
// A run with MCP tools only: the agent's bearer for the proxy's /mcp route. Never the tool runner's.
|
|
322
|
+
...(spec.mcpTools
|
|
323
|
+
? [{ name: MCP_TOKEN_ENV, valueFrom: { secretKeyRef: { name: names.secret, key: MCP_TOKEN_SECRET_KEY } } }]
|
|
324
|
+
: []),
|
|
310
325
|
],
|
|
311
326
|
securityContext: containerSecurity(),
|
|
312
327
|
resources: conformResources(profile, {
|
|
@@ -322,6 +337,8 @@ export function buildRunPod(spec, options) {
|
|
|
322
337
|
{ name: TOOL_SOCKET_VOLUME, mountPath: "/run/wardby/tool" },
|
|
323
338
|
{ name: "tmp", mountPath: "/tmp" },
|
|
324
339
|
{ name: "home", mountPath: "/home/wardby" },
|
|
340
|
+
// Session resume: the SDK's config dir, where the session file grows, off /tmp's budget.
|
|
341
|
+
...(spec.sessionResume ? [{ name: CLAUDE_CONFIG_VOLUME, mountPath: CLAUDE_CONFIG_PATH }] : []),
|
|
325
342
|
]
|
|
326
343
|
: [
|
|
327
344
|
{ name: "storage", mountPath: "/workspace", subPath: "workspace" },
|
|
@@ -414,6 +431,14 @@ export function buildRunPod(spec, options) {
|
|
|
414
431
|
{ name: TOOL_SOCKET_VOLUME, emptyDir: { medium: "Memory", sizeLimit: `${TOOL_SOCKET_VOLUME_MIB}Mi` } },
|
|
415
432
|
{ name: "tool-tmp", emptyDir: { medium: "Memory", sizeLimit: `${toolScratchMb}Mi` } },
|
|
416
433
|
{ name: "tool-home", emptyDir: { medium: "Memory", sizeLimit: `${toolScratchMb}Mi` } },
|
|
434
|
+
...(spec.sessionResume
|
|
435
|
+
? [
|
|
436
|
+
{
|
|
437
|
+
name: CLAUDE_CONFIG_VOLUME,
|
|
438
|
+
emptyDir: { medium: "Memory", sizeLimit: `${CLAUDE_CONFIG_SCRATCH_MIB}Mi` },
|
|
439
|
+
},
|
|
440
|
+
]
|
|
441
|
+
: []),
|
|
417
442
|
]
|
|
418
443
|
: []),
|
|
419
444
|
...serviceVolumes(services),
|
|
@@ -448,14 +473,18 @@ export function buildRunNetworkPolicy(spec, namespace) {
|
|
|
448
473
|
},
|
|
449
474
|
};
|
|
450
475
|
}
|
|
451
|
-
export function buildCapabilitySecret(spec, namespace, capability, toolSetup) {
|
|
476
|
+
export function buildCapabilitySecret(spec, namespace, capability, toolSetup, mcpToken) {
|
|
452
477
|
const names = kubernetesRunNames(spec.runId);
|
|
453
478
|
return {
|
|
454
479
|
apiVersion: "v1",
|
|
455
480
|
kind: "Secret",
|
|
456
481
|
type: "Opaque",
|
|
457
482
|
metadata: { name: names.secret, namespace, labels: runLabels(spec.runId) },
|
|
458
|
-
stringData: {
|
|
483
|
+
stringData: {
|
|
484
|
+
capability,
|
|
485
|
+
...(toolSetup !== undefined ? { [TOOL_SETUP_SECRET_KEY]: toolSetup } : {}),
|
|
486
|
+
...(mcpToken !== undefined ? { [MCP_TOKEN_SECRET_KEY]: mcpToken } : {}),
|
|
487
|
+
},
|
|
459
488
|
};
|
|
460
489
|
}
|
|
461
490
|
/**
|
|
@@ -4,7 +4,7 @@ import { type Power } from "../../core/power.js";
|
|
|
4
4
|
import { type KubernetesApi } from "./kubernetes-api.js";
|
|
5
5
|
import { type ServiceStateReporter } from "./service-state.js";
|
|
6
6
|
import type { CodingProvider } from "../../coding/provider.js";
|
|
7
|
-
import type
|
|
7
|
+
import { type JobHandle, type JobResult, type JobSpec, type JobStatus, type WorkspaceJobLauncher } from "./types.js";
|
|
8
8
|
export interface KubernetesClusterInfo {
|
|
9
9
|
/** The proxy Service's ClusterIP: the enforcement witness's address (8787 reachable, 8788 not). */
|
|
10
10
|
proxyIp: string;
|
|
@@ -14,6 +14,11 @@ export interface KubernetesJobLauncherOptions {
|
|
|
14
14
|
config: KubernetesJobConfig;
|
|
15
15
|
workspaceRoot: string;
|
|
16
16
|
resolveCapability: (runId: string) => Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* The run's MCP token (the capability vault), asked for only when the spec has mcpTools; it goes into
|
|
19
|
+
* the run's Secret next to the capability. Absent = a run with MCP tools can't be launched.
|
|
20
|
+
*/
|
|
21
|
+
resolveMcpToken?: (runId: string) => Promise<string | undefined>;
|
|
17
22
|
/**
|
|
18
23
|
* Cluster preflight run once before the first launch; failure fails every launch. It may return the
|
|
19
24
|
* proxy ClusterIP it validated; otherwise the launcher reads the proxy witness once itself. Either way
|
|
@@ -165,6 +170,10 @@ export declare class KubernetesJobLauncher implements WorkspaceJobLauncher {
|
|
|
165
170
|
* must not open the gate at the initial proof either.
|
|
166
171
|
*/
|
|
167
172
|
private waitForPolicyEnforcement;
|
|
173
|
+
/** True when `found` is a requeued record for this spec, which launch() replaces with a fresh one. */
|
|
174
|
+
private isRequeued;
|
|
175
|
+
/** Tells the operator once that a quota refused a pod while no quota is configured for the pre-launch check. */
|
|
176
|
+
private hintQuotaUnconfigured;
|
|
168
177
|
private existingLaunch;
|
|
169
178
|
private provision;
|
|
170
179
|
private createIfMissing;
|
|
@@ -178,6 +187,7 @@ export declare class KubernetesJobLauncher implements WorkspaceJobLauncher {
|
|
|
178
187
|
private refresh;
|
|
179
188
|
/** Reads only a fixed diagnostic code from a failed worker's bounded log tail; never keeps anything else. */
|
|
180
189
|
private readWorkerDiagnostic;
|
|
190
|
+
readTranscript(handle: JobHandle, maxBytes: number): Promise<string | undefined>;
|
|
181
191
|
private readResultArtifact;
|
|
182
192
|
/**
|
|
183
193
|
* Streams the keeper's workspace through the strict extractor into `staging`.
|
|
@@ -30,17 +30,19 @@ import { createHash } from "node:crypto";
|
|
|
30
30
|
import { isIP } from "node:net";
|
|
31
31
|
import { logger } from "../../core/logger.js";
|
|
32
32
|
import { DISABLED_POWER, wakeTimeoutMs } from "../../core/power.js";
|
|
33
|
-
import { MAX_CODING_ARTIFACT_BYTES, MAX_CODING_INPUT_BYTES, MAX_DEBUG_TRACE_LINE_BYTES,
|
|
33
|
+
import { MAX_CODING_ARTIFACT_BYTES, MAX_CODING_INPUT_BYTES, MAX_DEBUG_TRACE_LINE_BYTES, parseCodingWorkerOutputJson, } from "../../coding/protocol.js";
|
|
34
34
|
import { CODING_PROXY_DENY_PORT, CODING_PROXY_PORT } from "./docker-isolation.js";
|
|
35
35
|
import { parseWorkerDiagnosticLine } from "./docker.js";
|
|
36
|
-
import { KubernetesAlreadyExistsError, KubernetesConflictError } from "./kubernetes-api.js";
|
|
36
|
+
import { KubernetesAlreadyExistsError, KubernetesConflictError, KubernetesQuotaExceededError, } from "./kubernetes-api.js";
|
|
37
37
|
import { ENFORCEMENT_PROBE_DENY_REACHABLE, ENFORCEMENT_PROBE_PROVEN, ENFORCEMENT_PROBE_DENY_REFUSED, ENFORCEMENT_PROBE_PROXY_UNREACHABLE, KEEPER_CONTAINER, KEEPER_SEEDED_MARKER, KUBERNETES_ISOLATION_ERROR, STORAGE_ROOT, TOOL_RUNNER_CONTAINER, WORKER_CONTAINER, assertRunNetworkPolicyMatches, assertRunPodMatches, buildCapabilitySecret, buildRunNetworkPolicy, buildRunPod, enforcementStreakScript, kubernetesRunNames, kubernetesRunNamesForToken, runLabels, serviceContainerName, validateKubernetesSpec, } from "./kubernetes-isolation.js";
|
|
38
38
|
import { claudeToolSetup } from "./claude-tool-setup.js";
|
|
39
|
+
import { isMcpToken } from "../../coding/mcp-token.js";
|
|
39
40
|
import { podQuotaUsage, quotaShortfall } from "./kubernetes-quota.js";
|
|
40
41
|
import { readProxyWitness } from "./kubernetes-witness.js";
|
|
41
42
|
import { safeExtract } from "./safe-extract.js";
|
|
42
43
|
import { reportServiceState, } from "./service-state.js";
|
|
43
44
|
import { serviceUnreadyError } from "../../coding/services/wording.js";
|
|
45
|
+
import { JobCapacityError, } from "./types.js";
|
|
44
46
|
import { replaceDirectoryFromStaging } from "./workspace-swap.js";
|
|
45
47
|
import { collectExclusions, normalizeCollectExclusions, tarExcludeArgs, } from "../../coding/collect-exclude.js";
|
|
46
48
|
const BACKEND = "kubernetes";
|
|
@@ -184,10 +186,22 @@ const TOKEN = /^[a-f0-9]{20}$/;
|
|
|
184
186
|
const WORKSPACE_STORAGE = `${STORAGE_ROOT}/workspace`;
|
|
185
187
|
const INPUT_STORAGE = `${STORAGE_ROOT}/input`;
|
|
186
188
|
const RESULT_PATH = `${STORAGE_ROOT}/output/result.json`;
|
|
189
|
+
const TRANSCRIPT_PATH = `${STORAGE_ROOT}/output/session.jsonl`;
|
|
187
190
|
/** Stands in for the proxy ClusterIP when building a pod only to count its resources. */
|
|
188
191
|
const QUOTA_PROBE_PROXY_IP = "10.0.0.1";
|
|
192
|
+
/** A Kubernetes object name (RFC 1123 subdomain). */
|
|
193
|
+
const DNS_1123_NAME = /^[a-z0-9]([-a-z0-9.]{0,251}[a-z0-9])?$/;
|
|
189
194
|
const kubernetesLog = logger.child({ module: "kubernetes-jobs" });
|
|
190
|
-
const PHASES = new Set([
|
|
195
|
+
const PHASES = new Set([
|
|
196
|
+
"provisioning",
|
|
197
|
+
"requeued",
|
|
198
|
+
"active",
|
|
199
|
+
"succeeded",
|
|
200
|
+
"failed",
|
|
201
|
+
"stopped",
|
|
202
|
+
"lost",
|
|
203
|
+
"removed",
|
|
204
|
+
]);
|
|
191
205
|
const TERMINAL_PHASES = new Set(["succeeded", "failed", "stopped", "lost", "removed"]);
|
|
192
206
|
// ---------------------------------------------------------------------------
|
|
193
207
|
// Pure helpers: the lifecycle rules.
|
|
@@ -206,6 +220,8 @@ function statusFor(record) {
|
|
|
206
220
|
switch (record.phase) {
|
|
207
221
|
case "provisioning":
|
|
208
222
|
return { state: "pending" };
|
|
223
|
+
case "requeued":
|
|
224
|
+
return { state: "pending", capacityRefused: true };
|
|
209
225
|
case "active":
|
|
210
226
|
return { state: "running" };
|
|
211
227
|
case "succeeded":
|
|
@@ -508,8 +524,9 @@ export class KubernetesJobLauncher {
|
|
|
508
524
|
const handle = { backend: BACKEND, id: `${this.namespace}/${names.token}` };
|
|
509
525
|
const specHash = stableSpecHash(spec);
|
|
510
526
|
const existing = await this.readRecord(names);
|
|
511
|
-
if (existing)
|
|
527
|
+
if (existing && !this.isRequeued(existing, specHash)) {
|
|
512
528
|
return this.existingLaunch(existing.record, specHash, handle);
|
|
529
|
+
}
|
|
513
530
|
const createdAt = this.now();
|
|
514
531
|
const record = {
|
|
515
532
|
schemaVersion: RECORD_SCHEMA_VERSION,
|
|
@@ -521,22 +538,54 @@ export class KubernetesJobLauncher {
|
|
|
521
538
|
phase: "provisioning",
|
|
522
539
|
collectExclude: spec.collectExclude ?? collectExclusions([]),
|
|
523
540
|
};
|
|
524
|
-
|
|
525
|
-
//
|
|
526
|
-
|
|
541
|
+
if (existing) {
|
|
542
|
+
// Replaces the requeued record; a conflict means another replica got there first.
|
|
543
|
+
try {
|
|
544
|
+
await this.api.replaceConfigMap(this.namespace, names.record, this.recordConfigMap(names, record, existing.resourceVersion));
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
if (!(error instanceof KubernetesConflictError))
|
|
548
|
+
throw error;
|
|
549
|
+
const raced = await this.readRecord(names);
|
|
550
|
+
if (!raced)
|
|
551
|
+
throw error;
|
|
552
|
+
if (!this.isRequeued(raced, specHash))
|
|
553
|
+
return this.existingLaunch(raced.record, specHash, handle);
|
|
554
|
+
// Requeued again by the other replica (its attempt was refused too): start over from that record.
|
|
555
|
+
return this.launch(spec);
|
|
556
|
+
}
|
|
527
557
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
558
|
+
else {
|
|
559
|
+
try {
|
|
560
|
+
// The record is the idempotency fence before any other cluster side effect. A quota refusing
|
|
561
|
+
// this create itself (a count/configmaps quota) is not a capacity refusal: it fails the run.
|
|
562
|
+
await this.api.createConfigMap(this.namespace, this.recordConfigMap(names, record));
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
if (!(error instanceof KubernetesAlreadyExistsError))
|
|
566
|
+
throw error;
|
|
567
|
+
const raced = await this.readRecord(names);
|
|
568
|
+
if (!raced)
|
|
569
|
+
throw error;
|
|
570
|
+
if (!this.isRequeued(raced, specHash))
|
|
571
|
+
return this.existingLaunch(raced.record, specHash, handle);
|
|
572
|
+
// Another replica requeued it between our read and create: start over from the requeued record.
|
|
573
|
+
return this.launch(spec);
|
|
574
|
+
}
|
|
535
575
|
}
|
|
536
576
|
try {
|
|
537
577
|
await this.provision(spec, names, record);
|
|
538
578
|
}
|
|
539
579
|
catch (error) {
|
|
580
|
+
if (error instanceof KubernetesQuotaExceededError) {
|
|
581
|
+
// Capacity, not failure: leave a record a later launch() provisions afresh.
|
|
582
|
+
await this.updateRecord(names, () => ({ phase: "requeued" })).catch(() => undefined);
|
|
583
|
+
await this.cleanupRun(names, 0);
|
|
584
|
+
this.hintQuotaUnconfigured(error.quotaName);
|
|
585
|
+
throw new JobCapacityError("kubernetes_quota_exceeded: the namespace ResourceQuota has no room for this run", {
|
|
586
|
+
cause: error,
|
|
587
|
+
});
|
|
588
|
+
}
|
|
540
589
|
// Record the failure before deleting the pod, so a replica that observes "no pod" in between
|
|
541
590
|
// can't record `lost` first and have this more specific outcome dropped.
|
|
542
591
|
await this.updateRecord(names, () => ({
|
|
@@ -758,6 +807,22 @@ export class KubernetesJobLauncher {
|
|
|
758
807
|
await this.sleep(ENFORCEMENT_POLL_MS);
|
|
759
808
|
}
|
|
760
809
|
}
|
|
810
|
+
/** True when `found` is a requeued record for this spec, which launch() replaces with a fresh one. */
|
|
811
|
+
isRequeued(found, specHash) {
|
|
812
|
+
if (found.record.phase !== "requeued")
|
|
813
|
+
return false;
|
|
814
|
+
if (found.record.specHash !== specHash)
|
|
815
|
+
throw new Error("job_spec_conflict");
|
|
816
|
+
return true;
|
|
817
|
+
}
|
|
818
|
+
/** Tells the operator once that a quota refused a pod while no quota is configured for the pre-launch check. */
|
|
819
|
+
hintQuotaUnconfigured(refusedQuota) {
|
|
820
|
+
if (this.options.config.resourceQuota)
|
|
821
|
+
return;
|
|
822
|
+
const name = refusedQuota !== undefined && DNS_1123_NAME.test(refusedQuota) ? refusedQuota : undefined;
|
|
823
|
+
this.warnOnce(`kubernetes_resource_quota_unconfigured: a pod was refused by ${name ? `ResourceQuota ${name}` : "a ResourceQuota"}; ` +
|
|
824
|
+
`set KUBERNETES_RESOURCE_QUOTA=${name ?? "<name>"} and grant the launcher get on that ResourceQuota so runs wait before they start`);
|
|
825
|
+
}
|
|
761
826
|
existingLaunch(record, specHash, handle) {
|
|
762
827
|
if (record.specHash !== specHash)
|
|
763
828
|
throw new Error("job_spec_conflict");
|
|
@@ -774,6 +839,10 @@ export class KubernetesJobLauncher {
|
|
|
774
839
|
const capability = await this.options.resolveCapability(spec.runId);
|
|
775
840
|
if (!CAPABILITY.test(capability))
|
|
776
841
|
throw new Error("kubernetes_capability_invalid");
|
|
842
|
+
const mcpToken = spec.mcpTools ? await this.options.resolveMcpToken?.(spec.runId) : undefined;
|
|
843
|
+
if (spec.mcpTools && !isMcpToken(mcpToken)) {
|
|
844
|
+
throw new Error("kubernetes_mcp_token_invalid");
|
|
845
|
+
}
|
|
777
846
|
// Re-read (not just the ClusterIP): the gate below reads "deny port unreachable" as evidence,
|
|
778
847
|
// which is only meaningful against a Service that actually exposes it with a ready backend.
|
|
779
848
|
const witness = await readProxyWitness(this.api, this.namespace, proxyService);
|
|
@@ -787,7 +856,7 @@ export class KubernetesJobLauncher {
|
|
|
787
856
|
});
|
|
788
857
|
const policy = buildRunNetworkPolicy(spec, this.namespace);
|
|
789
858
|
const toolSetup = spec.provider === "claude-code" ? claudeToolSetup(spec, capability) : undefined;
|
|
790
|
-
await this.createIfMissing(() => this.api.createSecret(this.namespace, buildCapabilitySecret(spec, this.namespace, capability, toolSetup)));
|
|
859
|
+
await this.createIfMissing(() => this.api.createSecret(this.namespace, buildCapabilitySecret(spec, this.namespace, capability, toolSetup, mcpToken)));
|
|
791
860
|
await this.createIfMissing(() => this.api.createNetworkPolicy(this.namespace, policy));
|
|
792
861
|
await this.createIfMissing(() => this.api.createPod(this.namespace, pod));
|
|
793
862
|
await this.waitForKeeper(names, spec.runId, (spec.services ?? []).map((service) => service.name), spec.provider === "claude-code");
|
|
@@ -957,7 +1026,8 @@ export class KubernetesJobLauncher {
|
|
|
957
1026
|
// Observation and collection
|
|
958
1027
|
/** Observes a non-terminal run against its pod and persists any transition; returns the stored record. */
|
|
959
1028
|
async refresh(names, record) {
|
|
960
|
-
|
|
1029
|
+
// A requeued run has no pod by design; observing it would record it lost.
|
|
1030
|
+
if (isTerminal(record.phase) || record.phase === "requeued")
|
|
961
1031
|
return record;
|
|
962
1032
|
const pod = await this.api.readPod(this.namespace, names.pod);
|
|
963
1033
|
const observed = observePod(pod, record, this.now(), this.readyTimeoutMs);
|
|
@@ -985,6 +1055,30 @@ export class KubernetesJobLauncher {
|
|
|
985
1055
|
}
|
|
986
1056
|
return undefined;
|
|
987
1057
|
}
|
|
1058
|
+
async readTranscript(handle, maxBytes) {
|
|
1059
|
+
const names = this.namesFor(handle);
|
|
1060
|
+
const found = names && (await this.readRecord(names));
|
|
1061
|
+
if (!names || !found)
|
|
1062
|
+
return undefined;
|
|
1063
|
+
const collector = new BoundedCollector(maxBytes);
|
|
1064
|
+
let exitCode;
|
|
1065
|
+
try {
|
|
1066
|
+
exitCode = await this.api.exec(this.namespace, names.pod, KEEPER_CONTAINER, ["head", "-c", String(maxBytes + 1), TRANSCRIPT_PATH], { stdout: collector, timeoutMs: SHORT_EXEC_TIMEOUT_MS });
|
|
1067
|
+
if (!collector.writableEnded)
|
|
1068
|
+
collector.end();
|
|
1069
|
+
await finished(collector);
|
|
1070
|
+
}
|
|
1071
|
+
catch {
|
|
1072
|
+
// The pod is gone (a stopped run) or unreachable: there is nothing to collect.
|
|
1073
|
+
collector.destroy();
|
|
1074
|
+
return undefined;
|
|
1075
|
+
}
|
|
1076
|
+
if (exitCode !== 0)
|
|
1077
|
+
return undefined;
|
|
1078
|
+
if (collector.exceeded)
|
|
1079
|
+
throw new Error("transcript_too_large");
|
|
1080
|
+
return collector.text();
|
|
1081
|
+
}
|
|
988
1082
|
async readResultArtifact(names, runId) {
|
|
989
1083
|
const collector = new BoundedCollector(MAX_CODING_ARTIFACT_BYTES);
|
|
990
1084
|
let raw;
|
|
@@ -1005,7 +1099,7 @@ export class KubernetesJobLauncher {
|
|
|
1005
1099
|
}
|
|
1006
1100
|
let output;
|
|
1007
1101
|
try {
|
|
1008
|
-
output =
|
|
1102
|
+
output = parseCodingWorkerOutputJson(raw);
|
|
1009
1103
|
}
|
|
1010
1104
|
catch (error) {
|
|
1011
1105
|
throw errorWithCode("kubernetes_result_artifact_invalid", error);
|
|
@@ -21,6 +21,20 @@ export interface JobSpec {
|
|
|
21
21
|
/** Required only for Claude's credential-free repository tool container. */
|
|
22
22
|
toolImage?: string;
|
|
23
23
|
inputArtifact: string;
|
|
24
|
+
/** Set only when the run's dependency cache is on (CodingRun.dependencyCache); absent otherwise, never false. */
|
|
25
|
+
dependencyCache?: true;
|
|
26
|
+
/**
|
|
27
|
+
* Claude Code only, set only when the run keeps its session (CodingRun.sessionResume); absent otherwise,
|
|
28
|
+
* never false. The worker's SDK config dir, where the session file grows, gets its own size-limited
|
|
29
|
+
* scratch so a long session never fills the worker's shared /tmp.
|
|
30
|
+
*/
|
|
31
|
+
sessionResume?: true;
|
|
32
|
+
/**
|
|
33
|
+
* Set only when the run has pinned MCP tools (remote MCP servers); absent otherwise, never false.
|
|
34
|
+
* The launcher then delivers the run's MCP token, from the capability vault, as WARDBY_MCP_TOKEN to
|
|
35
|
+
* the agent container only (never Claude's tool runner). The token itself is never in the spec.
|
|
36
|
+
*/
|
|
37
|
+
mcpTools?: true;
|
|
24
38
|
timeoutSec: number;
|
|
25
39
|
limits: JobResourceLimits;
|
|
26
40
|
labels: Record<string, string>;
|
|
@@ -42,6 +56,12 @@ export interface JobHandle {
|
|
|
42
56
|
}
|
|
43
57
|
export type JobStatus = {
|
|
44
58
|
state: "pending" | "running";
|
|
59
|
+
/**
|
|
60
|
+
* Only ever on `pending`: the backend refused this job's launch for capacity (JobCapacityError)
|
|
61
|
+
* and nothing of it is running, nor will it start on its own. A caller that finds its job so
|
|
62
|
+
* may return the run to its queue and later `launch` the same spec again.
|
|
63
|
+
*/
|
|
64
|
+
capacityRefused?: true;
|
|
45
65
|
} | {
|
|
46
66
|
state: "succeeded";
|
|
47
67
|
} | {
|
|
@@ -61,11 +81,24 @@ export interface JobResult {
|
|
|
61
81
|
/** Output-schema failure locations (`path:code`) that passed SAFE_CODING_OUTPUT_ISSUE; never values. */
|
|
62
82
|
diagnosticIssues?: string[];
|
|
63
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* The backend has no room for this job right now (Kubernetes: the namespace ResourceQuota). No
|
|
86
|
+
* workload of the job is left running; the backend may keep a record of the refusal (Kubernetes
|
|
87
|
+
* does: its run record, which `status` then reports as `pending` with `capacityRefused`). The
|
|
88
|
+
* caller may launch the same spec again later.
|
|
89
|
+
*/
|
|
90
|
+
export declare class JobCapacityError extends Error {
|
|
91
|
+
readonly code = "coding_capacity_exceeded";
|
|
92
|
+
constructor(message: string, options?: ErrorOptions);
|
|
93
|
+
}
|
|
64
94
|
/**
|
|
65
95
|
* Lifecycle invariants implemented by every launcher:
|
|
66
96
|
*
|
|
67
97
|
* - `launch` is idempotent by runId for an identical spec and rejects a
|
|
68
98
|
* different spec for the same runId.
|
|
99
|
+
* - `launch` may reject with JobCapacityError when the backend has no room for
|
|
100
|
+
* the job; nothing of it is then left running, and a later `launch` of the
|
|
101
|
+
* same spec provisions it afresh.
|
|
69
102
|
* - pending may become running or terminal; running may become terminal;
|
|
70
103
|
* terminal states never change.
|
|
71
104
|
* - `collect` is repeatable for a terminal job until `remove` succeeds.
|
|
@@ -100,6 +133,12 @@ export interface JobLauncher {
|
|
|
100
133
|
launch: (spec: JobSpec) => Promise<JobHandle>;
|
|
101
134
|
status: (handle: JobHandle) => Promise<JobStatus>;
|
|
102
135
|
collect: (handle: JobHandle) => Promise<JobResult>;
|
|
136
|
+
/**
|
|
137
|
+
* The run's session transcript file (the worker's session.jsonl), at most `maxBytes`; undefined
|
|
138
|
+
* when there is none or the job's storage is gone (a stopped job). Throws `transcript_too_large`
|
|
139
|
+
* when larger. Never cached in the job record: it is not redacted yet. Call before `remove`.
|
|
140
|
+
*/
|
|
141
|
+
readTranscript?: (handle: JobHandle, maxBytes: number) => Promise<string | undefined>;
|
|
103
142
|
stop: (handle: JobHandle, reason?: string) => Promise<void>;
|
|
104
143
|
remove: (handle: JobHandle) => Promise<void>;
|
|
105
144
|
}
|
|
@@ -3,4 +3,16 @@
|
|
|
3
3
|
* values are carried in a versioned input artifact, never expanded into an
|
|
4
4
|
* arbitrary environment map or shell command.
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The backend has no room for this job right now (Kubernetes: the namespace ResourceQuota). No
|
|
8
|
+
* workload of the job is left running; the backend may keep a record of the refusal (Kubernetes
|
|
9
|
+
* does: its run record, which `status` then reports as `pending` with `capacityRefused`). The
|
|
10
|
+
* caller may launch the same spec again later.
|
|
11
|
+
*/
|
|
12
|
+
export class JobCapacityError extends Error {
|
|
13
|
+
code = "coding_capacity_exceeded";
|
|
14
|
+
constructor(message, options) {
|
|
15
|
+
super(message, options);
|
|
16
|
+
this.name = "JobCapacityError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import Anthropic from "@anthropic-ai/sdk";
|
|
8
8
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
9
|
+
import { simulatorModelClientOptions } from "../../config/test-simulators.js";
|
|
9
10
|
export function anthropicCredentialsPresent(env = process.env) {
|
|
10
11
|
return Boolean(env.ANTHROPIC_API_KEY);
|
|
11
12
|
}
|
|
@@ -14,6 +15,9 @@ export class AnthropicLlmProvider extends ClaudeLlmProvider {
|
|
|
14
15
|
if (!client && !apiKey) {
|
|
15
16
|
throw new Error("ANTHROPIC_API_KEY is not set — required by the Anthropic LlmProvider adapter.");
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
+
// WARDBY_TEST_SIMULATORS (test only): the scripted model, with a placeholder key the
|
|
19
|
+
// credential-free fetch drops; the real key never goes there.
|
|
20
|
+
const simulator = client ? null : simulatorModelClientOptions("anthropic");
|
|
21
|
+
super(client ?? new Anthropic(simulator ?? { apiKey }), lookup);
|
|
18
22
|
}
|
|
19
23
|
}
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bedrock-Claude adapter for the LlmProvider seam. `@anthropic-ai/bedrock-sdk`
|
|
3
|
-
* is imported only here; all protocol/pricing-dispatch logic lives in the
|
|
4
|
-
* shared ClaudeLlmProvider base class (claude-provider.ts) — AnthropicBedrock
|
|
5
|
-
* exposes the identical .messages.stream() surface as @anthropic-ai/sdk, so
|
|
6
|
-
* this file's only job is constructing the right client.
|
|
7
|
-
*
|
|
8
|
-
* Named BedrockClaudeLlmProvider, not BedrockLlmProvider: Bedrock hosts
|
|
9
|
-
* multiple model vendors, and this adapter only ever speaks the
|
|
10
|
-
* Anthropic-native protocol for Claude models. A future non-Claude Bedrock
|
|
11
|
-
* adapter gets its own name, not a rename of this one.
|
|
12
|
-
*/
|
|
13
1
|
import { AnthropicBedrock } from "@anthropic-ai/bedrock-sdk";
|
|
14
2
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
15
3
|
import type { CatalogLookup } from "./catalog-lookup.js";
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* Anthropic-native protocol for Claude models. A future non-Claude Bedrock
|
|
11
11
|
* adapter gets its own name, not a rename of this one.
|
|
12
12
|
*/
|
|
13
|
+
import { refuseBedrockUnderTestSimulators } from "../../config/test-simulators.js";
|
|
13
14
|
import { AnthropicBedrock } from "@anthropic-ai/bedrock-sdk";
|
|
14
15
|
import { ClaudeLlmProvider } from "./claude-provider.js";
|
|
15
16
|
export function bedrockCredentialsPresent(env = process.env) {
|
|
@@ -23,6 +24,9 @@ export class BedrockClaudeLlmProvider extends ClaudeLlmProvider {
|
|
|
23
24
|
if (!client && !region) {
|
|
24
25
|
throw new Error("BEDROCK_REGION (or AWS_REGION) is required by the Bedrock Claude LlmProvider adapter.");
|
|
25
26
|
}
|
|
27
|
+
// WARDBY_TEST_SIMULATORS (test only) refuses Bedrock: AWS-signed calls cannot go to the simulator.
|
|
28
|
+
if (!client)
|
|
29
|
+
refuseBedrockUnderTestSimulators();
|
|
26
30
|
super(client ?? new AnthropicBedrock({ awsRegion: region }), lookup);
|
|
27
31
|
}
|
|
28
32
|
}
|
|
@@ -106,5 +106,7 @@ export type ClaudeStreamEvent = {
|
|
|
106
106
|
} | {
|
|
107
107
|
type: "message_stop";
|
|
108
108
|
};
|
|
109
|
-
export declare function mapClaudeStream(events: AsyncIterable<ClaudeStreamEvent>, priceUsd: (usage: LlmUsage) => number
|
|
109
|
+
export declare function mapClaudeStream(events: AsyncIterable<ClaudeStreamEvent>, priceUsd: (usage: LlmUsage) => number,
|
|
110
|
+
/** Called at message_start: the response has started, and output may be billed from here on. */
|
|
111
|
+
onResponseStarted?: () => void): AsyncIterable<LlmStreamEvent>;
|
|
110
112
|
export {};
|
|
@@ -98,7 +98,9 @@ export function withCacheBreakpoints(req) {
|
|
|
98
98
|
});
|
|
99
99
|
return { ...req, ...(system ? { system } : {}), messages };
|
|
100
100
|
}
|
|
101
|
-
export async function* mapClaudeStream(events, priceUsd
|
|
101
|
+
export async function* mapClaudeStream(events, priceUsd,
|
|
102
|
+
/** Called at message_start: the response has started, and output may be billed from here on. */
|
|
103
|
+
onResponseStarted) {
|
|
102
104
|
const toolBuffers = new Map();
|
|
103
105
|
let start = {};
|
|
104
106
|
let outputTokens = 0;
|
|
@@ -106,6 +108,7 @@ export async function* mapClaudeStream(events, priceUsd) {
|
|
|
106
108
|
for await (const ev of events) {
|
|
107
109
|
switch (ev.type) {
|
|
108
110
|
case "message_start":
|
|
111
|
+
onResponseStarted?.();
|
|
109
112
|
start = ev.message.usage ?? {};
|
|
110
113
|
outputTokens = ev.message.usage?.output_tokens ?? 0;
|
|
111
114
|
break;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* stays exactly what each concrete adapter (anthropic.ts, bedrock.ts) has in
|
|
6
6
|
* common, and nothing more.
|
|
7
7
|
*/
|
|
8
|
-
import type { LlmMessage, LlmRequest, LlmStreamEvent, LlmToolDef } from "./types.js";
|
|
8
|
+
import type { LlmMessage, LlmRequest, LlmStreamEvent, LlmStreamHooks, LlmToolDef } from "./types.js";
|
|
9
9
|
import { type CatalogLookup } from "./catalog-lookup.js";
|
|
10
10
|
import type { CatalogEntry } from "./catalog-types.js";
|
|
11
11
|
import type { CatalogLlmAdapter } from "./routing.js";
|
|
@@ -27,7 +27,7 @@ export declare class ClaudeLlmProvider implements CatalogLlmAdapter {
|
|
|
27
27
|
private readonly lookup;
|
|
28
28
|
constructor(client: ClaudeMessagesClient, lookup?: CatalogLookup);
|
|
29
29
|
withEntry(entry: CatalogEntry): ClaudeLlmProvider;
|
|
30
|
-
stream(req: LlmRequest, signal?: AbortSignal): AsyncIterable<LlmStreamEvent>;
|
|
30
|
+
stream(req: LlmRequest, signal?: AbortSignal, hooks?: LlmStreamHooks): AsyncIterable<LlmStreamEvent>;
|
|
31
31
|
countTokens(model: string, messages: LlmMessage[], tools?: LlmToolDef[]): Promise<number>;
|
|
32
32
|
priceUsd(model: string, usage: {
|
|
33
33
|
inputTokens: number;
|