@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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stop_run: stops a run that is still pending (including a coding run queued for a slot) or
|
|
3
|
+
* running, and the delegated child runs it has in flight (src/core/stop-run.ts). A run that already
|
|
4
|
+
* finished is returned unchanged, so calling it again is harmless.
|
|
5
|
+
*
|
|
6
|
+
* Access mirrors trigger_agent: stopping a run needs execute on its agent. Runs are visible only to
|
|
7
|
+
* the agent's owner and to the run's triggerer (get_run's rule), so anyone else gets the same 404 as
|
|
8
|
+
* for a missing run; a triggerer whose access to the agent has dropped below execute gets a 403.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { atLeast } from "../../core/grants.js";
|
|
12
|
+
import { stopRun } from "../../core/stop-run.js";
|
|
13
|
+
import { agentAccess, insufficientAgentAccess } from "../auth/access.js";
|
|
14
|
+
import { McpError } from "../errors.js";
|
|
15
|
+
import { textResult } from "./text-result.js";
|
|
16
|
+
const StopRunSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
runId: z.string().trim().min(1).max(128),
|
|
19
|
+
reason: z.string().trim().max(500).optional(),
|
|
20
|
+
})
|
|
21
|
+
.strict();
|
|
22
|
+
export function registerStopRunTool(mcp) {
|
|
23
|
+
mcp.registerTool({
|
|
24
|
+
name: "stop_run",
|
|
25
|
+
scope: "runs:trigger",
|
|
26
|
+
description: "Stop a run that is pending, queued, or running, and the sub-agent runs it delegated that are still in " +
|
|
27
|
+
"flight. The run ends as `cancelled`; a coding run's worker is stopped and opens or updates no pull " +
|
|
28
|
+
"request. A run that already finished is returned unchanged. Needs execute access to the run's agent.",
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: "object",
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
properties: {
|
|
33
|
+
runId: { type: "string" },
|
|
34
|
+
reason: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Why the run is being stopped; recorded on the run (up to 500 characters).",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["runId"],
|
|
40
|
+
},
|
|
41
|
+
handler: async (raw, ctx) => {
|
|
42
|
+
const parsed = StopRunSchema.safeParse(raw);
|
|
43
|
+
if (!parsed.success) {
|
|
44
|
+
const details = parsed.error.issues.map((i) => `${i.path.join(".") || "input"}: ${i.message}`).join("; ");
|
|
45
|
+
throw new McpError(400, `Invalid stop_run arguments: ${details}`);
|
|
46
|
+
}
|
|
47
|
+
const { runId, reason } = parsed.data;
|
|
48
|
+
const notFound = new McpError(404, `Run "${runId}" not found.`);
|
|
49
|
+
const run = await ctx.db.run.findUnique({
|
|
50
|
+
where: { id: runId },
|
|
51
|
+
select: { id: true, agentId: true, triggeredById: true },
|
|
52
|
+
});
|
|
53
|
+
if (!run)
|
|
54
|
+
throw notFound;
|
|
55
|
+
const agent = await ctx.db.agent.findUnique({ where: { id: run.agentId }, select: { id: true, ownerId: true } });
|
|
56
|
+
if (!agent)
|
|
57
|
+
throw notFound;
|
|
58
|
+
const access = await agentAccess(ctx, agent);
|
|
59
|
+
const isTriggerer = run.triggeredById !== null && run.triggeredById === ctx.principal.id;
|
|
60
|
+
// Visible to the agent's owner and the run's triggerer only, exactly as get_run.
|
|
61
|
+
if (access !== "owner" && !isTriggerer)
|
|
62
|
+
throw notFound;
|
|
63
|
+
if (!atLeast("agent", access, "execute"))
|
|
64
|
+
throw insufficientAgentAccess(agent.id, "execute", access);
|
|
65
|
+
const result = await stopRun({
|
|
66
|
+
db: ctx.db,
|
|
67
|
+
executor: ctx.providers.executor,
|
|
68
|
+
runId,
|
|
69
|
+
stoppedBy: ctx.principal.id,
|
|
70
|
+
reason,
|
|
71
|
+
});
|
|
72
|
+
const message = !result.stopRequested
|
|
73
|
+
? `Run already finished as ${result.status}; nothing was changed.`
|
|
74
|
+
: result.status === "cancelled"
|
|
75
|
+
? "Run stopped."
|
|
76
|
+
: result.status === "pending" || result.status === "running"
|
|
77
|
+
? `Stop requested; the run is still ${result.status}. Check it again with get_run.`
|
|
78
|
+
: `The run finished as ${result.status} before the stop took effect.`;
|
|
79
|
+
return textResult({ ...result, message });
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { Prisma } from "#prisma";
|
|
16
16
|
import { atLeast, canDelegate } from "../../core/grants.js";
|
|
17
|
-
import { agentAccess, agentAccessResolver, agentNotFound, requireAgentAccess,
|
|
17
|
+
import { agentAccess, agentAccessResolver, agentNotFound, requireAgentAccess, requireBindable, } from "../auth/access.js";
|
|
18
18
|
import { McpError } from "../errors.js";
|
|
19
19
|
import { textResult } from "./text-result.js";
|
|
20
20
|
/**
|
|
@@ -68,7 +68,7 @@ export function registerSubAgentTools(mcp) {
|
|
|
68
68
|
throw new McpError(400, "An agent cannot be its own sub-agent.");
|
|
69
69
|
}
|
|
70
70
|
const { agent: parent } = await requireAgentAccess(ctx, args.parentAgentId, "read");
|
|
71
|
-
|
|
71
|
+
await requireBindable(ctx, parent);
|
|
72
72
|
// The caller could trigger the child anyway; the edge must not widen that.
|
|
73
73
|
const { agent: child } = await requireAgentAccess(ctx, args.childAgentId, "execute");
|
|
74
74
|
if (parent.ownerId === null) {
|
|
@@ -19,25 +19,27 @@ import type { WardbyMcpServer } from "../server.js";
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function projectTool(tool: Tool, principalId: string): {
|
|
21
21
|
name: string;
|
|
22
|
+
updatedAt: Date;
|
|
22
23
|
code: string;
|
|
24
|
+
timeoutMs: number | null;
|
|
23
25
|
createdAt: Date;
|
|
24
|
-
updatedAt: Date;
|
|
25
26
|
id: string;
|
|
26
27
|
ownerId: string | null;
|
|
27
28
|
description: string;
|
|
28
29
|
jsonSchema: import("@prisma/client/runtime/client").JsonValue;
|
|
29
30
|
paramsZod: string;
|
|
30
31
|
} | {
|
|
32
|
+
public: boolean;
|
|
31
33
|
id: string;
|
|
32
34
|
name: string;
|
|
33
35
|
description: string;
|
|
34
|
-
|
|
35
|
-
ownerIsCaller?: undefined;
|
|
36
|
+
timeoutMs: number | null;
|
|
36
37
|
} | {
|
|
38
|
+
public: boolean;
|
|
39
|
+
ownerIsCaller: boolean;
|
|
37
40
|
id: string;
|
|
38
41
|
name: string;
|
|
39
42
|
description: string;
|
|
40
|
-
|
|
41
|
-
ownerIsCaller: boolean;
|
|
43
|
+
timeoutMs: number | null;
|
|
42
44
|
};
|
|
43
45
|
export declare function registerToolAuthoringTools(mcp: WardbyMcpServer): void;
|
package/dist/mcp/tools/tools.js
CHANGED
|
@@ -11,15 +11,18 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { Prisma } from "#prisma";
|
|
13
13
|
import { deriveJsonSchema, validateParams } from "../../sandbox/zod-params.js";
|
|
14
|
+
import { cachedZod4Compatibility, toolSubject, withZod3ToolWarnings, zod3SampleArgsWarning, zod3ToolWarnings, zod3WindowWarning, } from "../../core/zod3-window.js";
|
|
14
15
|
import { runInSandbox } from "../../sandbox/run-in-sandbox.js";
|
|
16
|
+
import { effectiveToolTimeoutMs, toolTimeoutProblem } from "../../sandbox/tool-timeout.js";
|
|
17
|
+
import { loadToolMaxTimeoutMs } from "../../config/tool-timeout.js";
|
|
15
18
|
import { ToolCapabilitiesPatchSchema } from "../../sandbox/tool-capabilities.js";
|
|
16
19
|
import { buildSharedDatastoreAccessor } from "../../core/datastores.js";
|
|
17
|
-
import { findSameNamedAttachedTool, reservedToolNameReason } from "../../core/tool-names.js";
|
|
20
|
+
import { findSameNamedAttachedTool, findSameNamedMcpTool, reservedToolNameReason, sameNamedMcpToolMessage, } from "../../core/tool-names.js";
|
|
18
21
|
import { ToolAttachedError, deleteToolGuarded, hasToolChanges, prepareToolUpdate, updateToolGuarded, } from "../../core/tool-admin.js";
|
|
19
22
|
import { McpError } from "../errors.js";
|
|
20
23
|
import { requireOwnedTool, requireStrictlyOwnedTool, assertStrictlyOwnedTool, visibleToPrincipal, canRead, } from "../auth/ownership.js";
|
|
21
24
|
import { agentAccessResolver, assertAgentAccess, requireAgentAccess } from "../auth/access.js";
|
|
22
|
-
import { atLeast } from "../../core/grants.js";
|
|
25
|
+
import { atLeast, isPublicWritable } from "../../core/grants.js";
|
|
23
26
|
import { textResult } from "./text-result.js";
|
|
24
27
|
import { brokerCompatibilityWarnings } from "./secret-broker-compat.js";
|
|
25
28
|
/**
|
|
@@ -45,9 +48,16 @@ async function describeAgents(agents, ctx) {
|
|
|
45
48
|
export function projectTool(tool, principalId) {
|
|
46
49
|
if (tool.ownerId !== null && tool.ownerId === principalId)
|
|
47
50
|
return tool;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
// timeoutMs is not code: anyone who sees the tool sees how long its calls may take.
|
|
52
|
+
const shown = { id: tool.id, name: tool.name, description: tool.description, timeoutMs: tool.timeoutMs };
|
|
53
|
+
return tool.ownerId === null ? { ...shown, public: true } : { ...shown, public: false, ownerIsCaller: false };
|
|
54
|
+
}
|
|
55
|
+
const TIMEOUT_MS_DESCRIPTION = "The tool's time limit per call, in milliseconds (at least 1000). Omitted: the default of 10000. Capped by the server's WARDBY_TOOL_MAX_TIMEOUT_MS (default 300000); a larger value is refused. Each fetch times out just before it, and sleep() is capped at it.";
|
|
56
|
+
/** Refuses (400) a timeoutMs this server can't store, naming its ceiling. */
|
|
57
|
+
function assertToolTimeout(timeoutMs) {
|
|
58
|
+
const problem = toolTimeoutProblem(timeoutMs, loadToolMaxTimeoutMs());
|
|
59
|
+
if (problem)
|
|
60
|
+
throw new McpError(400, problem);
|
|
51
61
|
}
|
|
52
62
|
/**
|
|
53
63
|
* Non-blocking: which of the secrets just granted to this attachment are
|
|
@@ -82,11 +92,14 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
82
92
|
description: { type: "string" },
|
|
83
93
|
paramsZod: { type: "string" },
|
|
84
94
|
code: { type: "string" },
|
|
95
|
+
timeoutMs: { type: "integer", description: TIMEOUT_MS_DESCRIPTION },
|
|
85
96
|
},
|
|
86
97
|
required: ["name", "description", "paramsZod", "code"],
|
|
87
98
|
},
|
|
88
99
|
handler: async (args, ctx) => {
|
|
89
100
|
assertToolNameAllowed(args.name);
|
|
101
|
+
if (args.timeoutMs !== undefined)
|
|
102
|
+
assertToolTimeout(args.timeoutMs);
|
|
90
103
|
const schemaResult = await deriveJsonSchema(args.paramsZod);
|
|
91
104
|
if (!schemaResult.ok) {
|
|
92
105
|
return textResult({ ok: false, errorKind: schemaResult.errorKind, errorMessage: schemaResult.errorMessage });
|
|
@@ -100,9 +113,11 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
100
113
|
code: args.code,
|
|
101
114
|
jsonSchema: schemaResult.value,
|
|
102
115
|
ownerId: ctx.principal.id,
|
|
116
|
+
...(args.timeoutMs !== undefined ? { timeoutMs: args.timeoutMs } : {}),
|
|
103
117
|
},
|
|
104
118
|
});
|
|
105
|
-
|
|
119
|
+
const warnings = await zod3ToolWarnings(toolSubject(tool.name), args.paramsZod);
|
|
120
|
+
return textResult(warnings.length ? { ...tool, warnings } : tool);
|
|
106
121
|
}
|
|
107
122
|
catch (err) {
|
|
108
123
|
if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2002") {
|
|
@@ -115,7 +130,7 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
115
130
|
mcp.registerTool({
|
|
116
131
|
name: "update_tool",
|
|
117
132
|
scope: "tools:write",
|
|
118
|
-
description: "Replaces a tool's description, paramsZod and/or
|
|
133
|
+
description: "Replaces a tool's description, paramsZod, code and/or timeoutMs (null: back to the default limit) in place (its name can't change: agents' prompts call it by name). Owner-only: public tools can't be changed over MCP. Refused while the tool is attached to any agent you don't own, including owner-less ones and agents shared with you, since the change would reach another owner's agent; detach it there first or create a new tool. Runs already started keep the version they loaded for their whole lifetime; the next run picks up the new one.",
|
|
119
134
|
inputSchema: {
|
|
120
135
|
type: "object",
|
|
121
136
|
additionalProperties: false,
|
|
@@ -124,14 +139,25 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
124
139
|
description: { type: "string" },
|
|
125
140
|
paramsZod: { type: "string" },
|
|
126
141
|
code: { type: "string" },
|
|
142
|
+
timeoutMs: {
|
|
143
|
+
type: ["integer", "null"],
|
|
144
|
+
description: `${TIMEOUT_MS_DESCRIPTION} Pass null to go back to the default.`,
|
|
145
|
+
},
|
|
127
146
|
},
|
|
128
147
|
required: ["toolId"],
|
|
129
148
|
},
|
|
130
149
|
handler: async (args, ctx) => {
|
|
131
|
-
const changes = {
|
|
150
|
+
const changes = {
|
|
151
|
+
description: args.description,
|
|
152
|
+
paramsZod: args.paramsZod,
|
|
153
|
+
code: args.code,
|
|
154
|
+
timeoutMs: args.timeoutMs,
|
|
155
|
+
};
|
|
132
156
|
if (!hasToolChanges(changes)) {
|
|
133
|
-
throw new McpError(400, "update_tool needs at least one of description, paramsZod or
|
|
157
|
+
throw new McpError(400, "update_tool needs at least one of description, paramsZod, code or timeoutMs.");
|
|
134
158
|
}
|
|
159
|
+
if (args.timeoutMs !== undefined && args.timeoutMs !== null)
|
|
160
|
+
assertToolTimeout(args.timeoutMs);
|
|
135
161
|
// Checked once up front so a non-owner never gets as far as a sandbox
|
|
136
162
|
// compile, and again (with the attachments) inside the transaction.
|
|
137
163
|
await requireStrictlyOwnedTool(ctx.db, args.toolId, ctx.principal.id);
|
|
@@ -145,7 +171,8 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
145
171
|
// landing between the check and the write.
|
|
146
172
|
try {
|
|
147
173
|
const tool = await updateToolGuarded(ctx.db, args.toolId, prepared.data, (row) => assertStrictlyOwnedTool(row, args.toolId, ctx.principal.id));
|
|
148
|
-
|
|
174
|
+
const warnings = args.paramsZod === undefined ? [] : await zod3ToolWarnings(toolSubject(tool.name), args.paramsZod);
|
|
175
|
+
return textResult(warnings.length ? { ...tool, warnings } : tool);
|
|
149
176
|
}
|
|
150
177
|
catch (err) {
|
|
151
178
|
if (err instanceof ToolAttachedError) {
|
|
@@ -193,7 +220,7 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
193
220
|
mcp.registerTool({
|
|
194
221
|
name: "dry_run_tool",
|
|
195
222
|
scope: "tools:write",
|
|
196
|
-
description: "Test-runs tool code against sample args without persisting it. Fetch is denied by default, same as a freshly attached tool — pass allowedHosts to test code that calls fetch().",
|
|
223
|
+
description: "Test-runs tool code against sample args without persisting it, with the same time limit a run would give it (timeoutMs, as on create_tool). Fetch is denied by default, same as a freshly attached tool — pass allowedHosts to test code that calls fetch(). For this release a paramsZod is still compiled with Zod 3; a `warnings` list in the result means the next release, which compiles it with Zod 4 only, will reject it or treat the sample args differently.",
|
|
197
224
|
inputSchema: {
|
|
198
225
|
type: "object",
|
|
199
226
|
properties: {
|
|
@@ -201,10 +228,13 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
201
228
|
code: { type: "string" },
|
|
202
229
|
sampleArgs: { type: "object" },
|
|
203
230
|
allowedHosts: { type: "array", items: { type: "string" } },
|
|
231
|
+
timeoutMs: { type: "integer", description: TIMEOUT_MS_DESCRIPTION },
|
|
204
232
|
},
|
|
205
233
|
required: ["paramsZod", "code", "sampleArgs"],
|
|
206
234
|
},
|
|
207
235
|
handler: async (args, ctx) => {
|
|
236
|
+
if (args.timeoutMs !== undefined)
|
|
237
|
+
assertToolTimeout(args.timeoutMs);
|
|
208
238
|
const hosts = ToolCapabilitiesPatchSchema.pick({ allowedHosts: true }).safeParse({
|
|
209
239
|
allowedHosts: args.allowedHosts,
|
|
210
240
|
});
|
|
@@ -217,10 +247,19 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
217
247
|
}
|
|
218
248
|
const jsonSchema = schemaResult.value;
|
|
219
249
|
const validated = await validateParams(args.paramsZod, args.sampleArgs);
|
|
250
|
+
// Zod 3 compatibility window: would the next release (Zod 4 only) compile
|
|
251
|
+
// this schema, and treat the sample arguments the same way?
|
|
252
|
+
const subject = "This paramsZod";
|
|
253
|
+
const compatibility = await cachedZod4Compatibility(args.paramsZod);
|
|
254
|
+
const compatWarning = compatibility.compatible === true
|
|
255
|
+
? zod3SampleArgsWarning(subject, validated, await validateParams(args.paramsZod, args.sampleArgs, ["v4"]))
|
|
256
|
+
: zod3WindowWarning(subject, compatibility);
|
|
257
|
+
const warnings = compatWarning ? { warnings: [compatWarning] } : {};
|
|
220
258
|
if (!validated.ok) {
|
|
221
259
|
return textResult({
|
|
222
260
|
jsonSchema,
|
|
223
261
|
result: { ok: false, errorKind: validated.errorKind, errorMessage: validated.errorMessage },
|
|
262
|
+
...warnings,
|
|
224
263
|
});
|
|
225
264
|
}
|
|
226
265
|
// No real agent exists for a dry run — the caller's own principal
|
|
@@ -242,8 +281,9 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
242
281
|
sharedDatastore: buildSharedDatastoreAccessor(ctx.principal.id, ctx.providers.datastore, ctx.db),
|
|
243
282
|
toolName: "dry_run_tool",
|
|
244
283
|
allowedFetchHosts: hosts.data.allowedHosts ?? [],
|
|
284
|
+
timeoutMs: effectiveToolTimeoutMs(args.timeoutMs, loadToolMaxTimeoutMs()),
|
|
245
285
|
});
|
|
246
|
-
return textResult({ jsonSchema, result: sandboxResult });
|
|
286
|
+
return textResult({ jsonSchema, result: sandboxResult, ...warnings });
|
|
247
287
|
},
|
|
248
288
|
});
|
|
249
289
|
mcp.registerTool({
|
|
@@ -294,6 +334,9 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
294
334
|
if (capabilitiesPassed && !isOwner) {
|
|
295
335
|
throw new McpError(403, "Only the agent's owner can grant capabilities to an attachment; ask them to re-run attach_tool with the capabilities.");
|
|
296
336
|
}
|
|
337
|
+
if (capabilitiesPassed && (await isPublicWritable(tx, agent.id))) {
|
|
338
|
+
throw new McpError(409, `Agent "${agent.id}" is writable by everyone, so tool capabilities cannot be granted on it; revoke or lower the everyone grant first.`);
|
|
339
|
+
}
|
|
297
340
|
const existing = await tx.agentTool.findUnique({
|
|
298
341
|
where: { agentId_toolId: { agentId: args.agentId, toolId: args.toolId } },
|
|
299
342
|
});
|
|
@@ -319,6 +362,10 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
319
362
|
: " (a tool owned by another principal)";
|
|
320
363
|
throw new McpError(409, `Agent "${args.agentId}" already has a different tool named "${tool.name}" attached${which}; detach it first.`);
|
|
321
364
|
}
|
|
365
|
+
// Nor a name one of the agent's MCP servers already gives the model.
|
|
366
|
+
const mcpClash = await findSameNamedMcpTool(tx, args.agentId, tool.name);
|
|
367
|
+
if (mcpClash)
|
|
368
|
+
throw new McpError(409, sameNamedMcpToolMessage(args.agentId, tool.name, mcpClash.serverName));
|
|
322
369
|
// Re-granting an attachment this owner never vouched for: what is
|
|
323
370
|
// not restated is reset, never silently adopted.
|
|
324
371
|
const keepUnstated = existing?.capabilitiesGrantedById === agent.ownerId;
|
|
@@ -374,19 +421,20 @@ export function registerToolAuthoringTools(mcp) {
|
|
|
374
421
|
scope: "tools:write",
|
|
375
422
|
inputSchema: { type: "object", properties: { agentId: { type: "string" } } },
|
|
376
423
|
handler: async (args, ctx) => {
|
|
377
|
-
|
|
424
|
+
// Zod 3 window: the caller's own tools carry their warnings (cached per paramsZod text).
|
|
425
|
+
const project = (tool) => withZod3ToolWarnings(projectTool(tool, ctx.principal.id));
|
|
378
426
|
if (args.agentId) {
|
|
379
427
|
const { access } = await requireAgentAccess(ctx, args.agentId, "read");
|
|
380
428
|
const rows = await ctx.db.agentTool.findMany({ where: { agentId: args.agentId }, include: { tool: true } });
|
|
381
429
|
// The agent's owner sees every tool on it (projected: code only for
|
|
382
430
|
// the tool's own owner); anyone else only tools they could see anyway.
|
|
383
|
-
return textResult(rows
|
|
431
|
+
return textResult(await Promise.all(rows
|
|
384
432
|
.map((r) => r.tool)
|
|
385
433
|
.filter((tool) => access === "owner" || canRead(tool.ownerId, ctx.principal.id))
|
|
386
|
-
.map(project));
|
|
434
|
+
.map(project)));
|
|
387
435
|
}
|
|
388
436
|
const tools = await ctx.db.tool.findMany({ where: visibleToPrincipal(ctx.principal.id) });
|
|
389
|
-
return textResult(tools.filter((tool) => canRead(tool.ownerId, ctx.principal.id)).map(project));
|
|
437
|
+
return textResult(await Promise.all(tools.filter((tool) => canRead(tool.ownerId, ctx.principal.id)).map(project)));
|
|
390
438
|
},
|
|
391
439
|
});
|
|
392
440
|
}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* gets 404, not another principal's final text/cost.
|
|
30
30
|
*/
|
|
31
31
|
import { dispatchRun } from "../../core/dispatch.js";
|
|
32
|
+
import { RepositoryChoiceRefusedError, resolveCodingRepository } from "../../core/coding-repository.js";
|
|
32
33
|
import { AttributionError, explicitAttribution, RESPONSE_PATH_SNAPSHOT_BUDGET, } from "../../core/attribution.js";
|
|
33
34
|
import { CodingBaseRefSchema, CodingTaskOverrideSchema, isLocalRepository } from "../../coding/protocol.js";
|
|
34
35
|
import { loadLocalRepoRoots, resolveLocalRepository, LocalRepoError } from "../../coding/local-repo.js";
|
|
@@ -46,6 +47,7 @@ const TriggerAgentSchema = z
|
|
|
46
47
|
agentId: z.string().trim().min(1).max(128),
|
|
47
48
|
task: CodingTaskOverrideSchema.optional(),
|
|
48
49
|
baseRef: CodingBaseRefSchema.optional(),
|
|
50
|
+
repository: z.string().min(1).max(300).optional(),
|
|
49
51
|
issue: z.unknown().optional(),
|
|
50
52
|
review: z
|
|
51
53
|
.object({
|
|
@@ -127,10 +129,10 @@ function assertOverrideAllowed(principalId, agent, args) {
|
|
|
127
129
|
// Strictly the owner: the stdio operator's owner-level access doesn't make
|
|
128
130
|
// it the owner whose repository authority the task steers (review M8).
|
|
129
131
|
const isOwner = agent.ownerId !== null && agent.ownerId === principalId;
|
|
130
|
-
if (isOwner || (args.task === undefined && args.baseRef === undefined))
|
|
132
|
+
if (isOwner || (args.task === undefined && args.baseRef === undefined && args.repository === undefined))
|
|
131
133
|
return;
|
|
132
134
|
if (!agent.codingProfile?.allowWebhookTaskOverride) {
|
|
133
|
-
throw new McpError(403, `Agent "${agent.id}": only its owner can pass a task or
|
|
135
|
+
throw new McpError(403, `Agent "${agent.id}": only its owner can pass a task, baseRef or repository, unless the owner allows it (codingProfile.allowWebhookTaskOverride).`);
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
138
|
/** execute on the agent, plus the override rule; `db` is the transaction when re-checking. */
|
|
@@ -150,6 +152,10 @@ export function registerTriggerTool(mcp) {
|
|
|
150
152
|
agentId: { type: "string" },
|
|
151
153
|
task: { type: "string" },
|
|
152
154
|
baseRef: { type: "string" },
|
|
155
|
+
repository: {
|
|
156
|
+
type: "string",
|
|
157
|
+
description: "Coding agents only: a repository on the agent's list (see get_agent). Omit to use codingProfile.repository.",
|
|
158
|
+
},
|
|
153
159
|
review: {
|
|
154
160
|
type: "object",
|
|
155
161
|
additionalProperties: false,
|
|
@@ -189,13 +195,28 @@ export function registerTriggerTool(mcp) {
|
|
|
189
195
|
}
|
|
190
196
|
review = await resolveLocalReview(ctx, agent.id, args.review);
|
|
191
197
|
}
|
|
192
|
-
if (agent.kind !== "coding" &&
|
|
193
|
-
|
|
198
|
+
if (agent.kind !== "coding" &&
|
|
199
|
+
(args.task !== undefined || args.baseRef !== undefined || args.repository !== undefined)) {
|
|
200
|
+
throw new McpError(400, "Task, baseRef and repository overrides are only valid for coding agents.");
|
|
194
201
|
}
|
|
195
202
|
// A local repository is re-checked against the roots as they are now
|
|
196
203
|
// (they can narrow after the agent was saved), before any run exists.
|
|
197
204
|
let warnings = [];
|
|
198
|
-
|
|
205
|
+
// The resolver's refusal lists the agent's repositories, so it runs only
|
|
206
|
+
// after requireTriggerable (execute on the agent) and never echoes the
|
|
207
|
+
// requested value.
|
|
208
|
+
const refused = (err) => {
|
|
209
|
+
if (err instanceof RepositoryChoiceRefusedError)
|
|
210
|
+
throw new McpError(400, `${err.code}: ${err.message}`);
|
|
211
|
+
throw err;
|
|
212
|
+
};
|
|
213
|
+
const repository = agent.kind === "coding" && agent.codingProfile
|
|
214
|
+
? (await resolveCodingRepository(ctx.db, {
|
|
215
|
+
agentId: agent.id,
|
|
216
|
+
profile: agent.codingProfile,
|
|
217
|
+
requested: args.repository,
|
|
218
|
+
}).catch(refused)).repository
|
|
219
|
+
: undefined;
|
|
199
220
|
if (repository !== undefined && isLocalRepository(repository)) {
|
|
200
221
|
try {
|
|
201
222
|
const resolved = await resolveLocalRepository(repository, loadLocalRepoRoots(process.env).roots);
|
|
@@ -238,6 +259,7 @@ export function registerTriggerTool(mcp) {
|
|
|
238
259
|
trigger: "manual",
|
|
239
260
|
codingTask: args.task,
|
|
240
261
|
codingBaseRef: args.baseRef,
|
|
262
|
+
codingRepository: args.repository,
|
|
241
263
|
attribution,
|
|
242
264
|
task: ctx.clientSupportsTasks ? { principalId: ctx.principal.id, ttlMs: DEFAULT_TASK_TTL_MS } : undefined,
|
|
243
265
|
triggeredById: ctx.principal.id,
|
|
@@ -262,7 +284,7 @@ export function registerTriggerTool(mcp) {
|
|
|
262
284
|
catch (err) {
|
|
263
285
|
if (pullRequest)
|
|
264
286
|
await ctx.db.localPullRequest.deleteMany({ where: { id: pullRequest.id } }).catch(() => { });
|
|
265
|
-
|
|
287
|
+
return refused(err);
|
|
266
288
|
}
|
|
267
289
|
if (ctx.clientSupportsTasks) {
|
|
268
290
|
if (!dispatched.task)
|
|
@@ -14,4 +14,6 @@ export declare class PayloadTooLargeError extends HttpBoundaryError {
|
|
|
14
14
|
}
|
|
15
15
|
export declare function canonicalUrl(value: string): URL;
|
|
16
16
|
export declare function readBody(req: IncomingMessage, maxBytes: number, signal: AbortSignal): Promise<string>;
|
|
17
|
+
/** readBody's bytes, undecoded (for a route that forwards the body unchanged). */
|
|
18
|
+
export declare function readBodyBytes(req: IncomingMessage, maxBytes: number, signal: AbortSignal): Promise<Buffer>;
|
|
17
19
|
export declare function parseBody(raw: string, contentType: string | undefined): unknown;
|
|
@@ -23,7 +23,11 @@ export function canonicalUrl(value) {
|
|
|
23
23
|
}
|
|
24
24
|
return url;
|
|
25
25
|
}
|
|
26
|
-
export function readBody(req, maxBytes, signal) {
|
|
26
|
+
export async function readBody(req, maxBytes, signal) {
|
|
27
|
+
return (await readBodyBytes(req, maxBytes, signal)).toString("utf8");
|
|
28
|
+
}
|
|
29
|
+
/** readBody's bytes, undecoded (for a route that forwards the body unchanged). */
|
|
30
|
+
export function readBodyBytes(req, maxBytes, signal) {
|
|
27
31
|
const length = req.headers["content-length"];
|
|
28
32
|
if (length && (!/^\d+$/.test(length) || Number(length) > maxBytes))
|
|
29
33
|
return Promise.reject(new PayloadTooLargeError());
|
|
@@ -55,7 +59,7 @@ export function readBody(req, maxBytes, signal) {
|
|
|
55
59
|
};
|
|
56
60
|
const end = () => {
|
|
57
61
|
clean();
|
|
58
|
-
resolve(Buffer.concat(chunks, size)
|
|
62
|
+
resolve(Buffer.concat(chunks, size));
|
|
59
63
|
};
|
|
60
64
|
req.on("data", data);
|
|
61
65
|
req.once("end", end);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stdio-only host for the signed links some tools hand out (the secret-entry
|
|
3
|
+
* form, a run transcript download): an ephemeral, loopback-only HTTP server,
|
|
4
|
+
* started lazily on the first link and closed after a period of inactivity.
|
|
5
|
+
* stdio's MCP process has no other listener (see stdio.ts); this one exists
|
|
6
|
+
* only while a link may be in use, consistent with stdio's "no token; the
|
|
7
|
+
* operator is trusted" model: reachable only from this same machine, and
|
|
8
|
+
* only a holder of a signed link can do anything with it.
|
|
9
|
+
*
|
|
10
|
+
* Request logging: none. A link's token travels in its `t` query parameter
|
|
11
|
+
* and must never be logged.
|
|
12
|
+
*/
|
|
13
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
14
|
+
/** Handles one request for a path; receives the `t` query parameter. Must not log the token. */
|
|
15
|
+
export type StdioLinkHandler = (req: IncomingMessage, res: ServerResponse, token: string | null) => Promise<void>;
|
|
16
|
+
export interface StdioLinkHost {
|
|
17
|
+
/** The loopback URL for `path` carrying `token`; starts the server if it is not running. */
|
|
18
|
+
urlFor(path: string, token: string): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
export declare function createStdioLinkHost(routes: Record<string, StdioLinkHandler>): StdioLinkHost;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stdio-only host for the signed links some tools hand out (the secret-entry
|
|
3
|
+
* form, a run transcript download): an ephemeral, loopback-only HTTP server,
|
|
4
|
+
* started lazily on the first link and closed after a period of inactivity.
|
|
5
|
+
* stdio's MCP process has no other listener (see stdio.ts); this one exists
|
|
6
|
+
* only while a link may be in use, consistent with stdio's "no token; the
|
|
7
|
+
* operator is trusted" model: reachable only from this same machine, and
|
|
8
|
+
* only a holder of a signed link can do anything with it.
|
|
9
|
+
*
|
|
10
|
+
* Request logging: none. A link's token travels in its `t` query parameter
|
|
11
|
+
* and must never be logged.
|
|
12
|
+
*/
|
|
13
|
+
import { createServer } from "node:http";
|
|
14
|
+
/** Matches the requestState codec's own TTL (server.ts): no point outliving the tokens it serves. */
|
|
15
|
+
const IDLE_SHUTDOWN_MS = 10 * 60_000;
|
|
16
|
+
export function createStdioLinkHost(routes) {
|
|
17
|
+
let server;
|
|
18
|
+
let port = 0;
|
|
19
|
+
let idleTimer;
|
|
20
|
+
function scheduleIdleShutdown() {
|
|
21
|
+
if (idleTimer)
|
|
22
|
+
clearTimeout(idleTimer);
|
|
23
|
+
idleTimer = setTimeout(() => {
|
|
24
|
+
server?.close();
|
|
25
|
+
server = undefined;
|
|
26
|
+
}, IDLE_SHUTDOWN_MS);
|
|
27
|
+
idleTimer.unref();
|
|
28
|
+
}
|
|
29
|
+
async function ensureServer() {
|
|
30
|
+
if (server) {
|
|
31
|
+
scheduleIdleShutdown();
|
|
32
|
+
return port;
|
|
33
|
+
}
|
|
34
|
+
const s = createServer((req, res) => {
|
|
35
|
+
scheduleIdleShutdown();
|
|
36
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
37
|
+
const handler = Object.hasOwn(routes, url.pathname) ? routes[url.pathname] : undefined;
|
|
38
|
+
if (!handler) {
|
|
39
|
+
res.writeHead(404).end();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// A failure here must never become an unhandled rejection: that would take
|
|
43
|
+
// down the whole stdio MCP process, not just this request.
|
|
44
|
+
handler(req, res, url.searchParams.get("t")).catch(() => {
|
|
45
|
+
if (!res.headersSent)
|
|
46
|
+
res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
|
|
47
|
+
if (!res.writableEnded)
|
|
48
|
+
res.end("Internal error");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
server = s;
|
|
52
|
+
await new Promise((resolve, reject) => {
|
|
53
|
+
s.once("error", reject);
|
|
54
|
+
s.listen(0, "127.0.0.1", resolve);
|
|
55
|
+
});
|
|
56
|
+
const address = s.address();
|
|
57
|
+
port = typeof address === "object" && address ? address.port : 0;
|
|
58
|
+
scheduleIdleShutdown();
|
|
59
|
+
return port;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
async urlFor(path, token) {
|
|
63
|
+
const p = await ensureServer();
|
|
64
|
+
return `http://127.0.0.1:${p}${path}?t=${encodeURIComponent(token)}`;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -8,7 +8,16 @@ import type { McpProviders } from "../context.js";
|
|
|
8
8
|
import { type GitHubIngressDeps } from "../host-events/github-ingress.js";
|
|
9
9
|
import { type JiraIngressDeps } from "../host-events/jira-ingress.js";
|
|
10
10
|
import { type HostUserCallbackDeps } from "../host-events/github-user-callback.js";
|
|
11
|
+
import type { BlobStore } from "../../providers/storage/types.js";
|
|
11
12
|
import { type ViewerApi } from "../../viewer/http.js";
|
|
13
|
+
/**
|
|
14
|
+
* close() waits this long for open requests to finish, then cuts them. A
|
|
15
|
+
* connected MCP client's event stream never ends on its own, so without a
|
|
16
|
+
* limit close() would hold shutdown until the pod is killed. On Kubernetes
|
|
17
|
+
* the load balancer has already moved traffic away by then (preStop), and
|
|
18
|
+
* clients reconnect to another instance.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CLOSE_GRACE_MS = 10000;
|
|
12
21
|
export interface HttpServerConfig {
|
|
13
22
|
canonicalUri: string;
|
|
14
23
|
httpBind: {
|
|
@@ -40,6 +49,10 @@ export interface StartHttpServerOptions {
|
|
|
40
49
|
};
|
|
41
50
|
/** The admin viewer API (/admin/api/*); absent = those paths answer 404. */
|
|
42
51
|
viewer?: ViewerApi;
|
|
52
|
+
/** The blob store run transcripts are served from (get_run_transcript links); absent = they answer 503. */
|
|
53
|
+
blobs?: BlobStore;
|
|
54
|
+
/** How long close() lets open requests finish before cutting them (default CLOSE_GRACE_MS). */
|
|
55
|
+
closeGraceMs?: number;
|
|
43
56
|
}
|
|
44
57
|
export interface HttpServerHandle {
|
|
45
58
|
port: number;
|