@wardby/cli 0.6.0 → 0.7.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/deploy/local/docker-compose.quickstart-coding.yml +13 -0
- package/dist/claude-coding-worker/driver.d.ts +21 -3
- package/dist/claude-coding-worker/driver.js +125 -17
- package/dist/claude-coding-worker/main.js +34 -6
- package/dist/claude-coding-worker/sdk.js +12 -1
- 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/cli-help.d.ts +1 -1
- package/dist/cli-help.js +1 -0
- package/dist/cli.js +24 -10
- 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/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 +235 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +12 -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 +51 -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 +6 -5
- package/dist/coding-worker/debug-trace.js +13 -18
- 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 +116 -38
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- 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 +11 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +82 -0
- package/dist/config/test-simulators.js +305 -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-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -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/dispatch.d.ts +42 -0
- package/dist/core/dispatch.js +131 -56
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +168 -0
- package/dist/core/grants.d.ts +19 -6
- package/dist/core/grants.js +55 -6
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +284 -24
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +298 -20
- 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 +54 -26
- 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/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +8 -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 +27 -14
- 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 +2 -1
- 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 +99 -13
- 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 +80 -34
- package/dist/core/runner.js +439 -144
- 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 +10 -74
- package/dist/core/secret-guard.d.ts +46 -0
- package/dist/core/secret-guard.js +104 -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/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- 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 +43 -8
- 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 +34 -3
- package/dist/generated/prisma/client.d.ts +34 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +220 -60
- 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 +44 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +428 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +92 -1
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +95 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +92 -1
- package/dist/generated/prisma/models/Agent.d.ts +106 -8
- package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +229 -1
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
- package/dist/generated/prisma/models/CodingRun.d.ts +1637 -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/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- 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/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.d.ts +4 -0
- package/dist/help-index.json +1320 -69
- package/dist/import/create.js +32 -3
- package/dist/import/neutral-schema.d.ts +50 -281
- package/dist/import/neutral-schema.js +5 -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/ownership.d.ts +7 -7
- 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/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 +58 -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 +198 -16
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +9 -3
- 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 +18 -5
- 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 +34 -12
- 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/secrets.js +2 -2
- 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 +1 -1
- package/dist/mcp/tools/tools.js +25 -9
- 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/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 +41 -3
- package/dist/native-worker/gateway-server.js +124 -27
- package/dist/native-worker/gateway.d.ts +27 -1
- package/dist/native-worker/gateway.js +70 -4
- package/dist/native-worker/http-server.d.ts +3 -1
- package/dist/native-worker/http-server.js +11 -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 +18 -2
- package/dist/native-worker/ledger.js +57 -4
- 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 +129 -577
- package/dist/native-worker/protocol.js +47 -1
- 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/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/memory-ledger.d.ts +15 -2
- package/dist/providers/coding-proxy/memory-ledger.js +84 -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 +15 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
- package/dist/providers/coding-proxy/proxy.d.ts +14 -1
- package/dist/providers/coding-proxy/proxy.js +166 -14
- 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 +4 -0
- package/dist/providers/coding-proxy/runtime.js +78 -16
- package/dist/providers/coding-proxy/server.d.ts +6 -1
- package/dist/providers/coding-proxy/server.js +45 -1
- package/dist/providers/coding-proxy/types.d.ts +65 -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 +47 -7
- package/dist/providers/executor/container.d.ts +361 -8
- package/dist/providers/executor/container.js +1136 -91
- 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/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 +8 -0
- package/dist/providers/jobs/docker-isolation.js +17 -0
- package/dist/providers/jobs/docker.d.ts +1 -0
- package/dist/providers/jobs/docker.js +27 -2
- 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 +2 -0
- package/dist/providers/jobs/kubernetes-isolation.js +17 -1
- package/dist/providers/jobs/kubernetes.d.ts +6 -1
- package/dist/providers/jobs/kubernetes.js +105 -16
- package/dist/providers/jobs/types.d.ts +33 -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 +134 -2
- package/dist/providers/review-host/types.js +8 -0
- 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 +33 -2
- package/dist/providers/vcs/git.js +324 -22
- 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 +214 -6
- package/dist/providers/vcs/github.js +447 -45
- package/dist/providers/vcs/index.js +8 -1
- 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 +33 -1
- package/dist/providers/vcs/routing.d.ts +4 -2
- package/dist/providers/vcs/routing.js +6 -0
- package/dist/providers/vcs/types.d.ts +80 -3
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- 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/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +1 -0
- package/dist/sandbox/host-functions.js +6 -11
- package/dist/sandbox/secret-broker.js +3 -4
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- 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/openapi.js +2 -4
- package/dist/wardby-bin.js +10 -0
- package/docs/agent-recipes.md +58 -20
- package/docs/code-review-agents.md +551 -41
- package/docs/coding-agent-setup.md +489 -7
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +20 -0
- package/docs/coding-worker-isolation.md +105 -30
- package/docs/getting-started-gke.md +124 -137
- package/docs/getting-started-identity-provider.md +10 -1
- package/docs/getting-started.md +9 -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/native-sandbox.md +119 -23
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +33 -2
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +42 -10
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +24 -2
- package/help/architecture-agent.md +11 -6
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- 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-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/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/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-worker-exited.md +3 -2
- 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/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/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/identity-and-access.md +2 -0
- 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/merge-order-check.md +5 -0
- package/help/native-capabilities.md +29 -1
- package/help/native-sandbox.md +15 -1
- package/help/operating-agents.md +5 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +10 -7
- package/help/resume-runs-locally.md +131 -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 +78 -7
- package/package.json +17 -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/schema.prisma +311 -97
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -1,33 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Links a run's pull requests to the issue that started it: records each
|
|
3
|
-
* issue/PR pair,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* issue/PR pair (recordIssuePullRequests, the same for a Jira issue and a
|
|
4
|
+
* GitHub issue), and for a tracker issue puts a web link on the issue and
|
|
5
|
+
* applies the link's configured status move. Provider-neutral: a code host is
|
|
6
|
+
* only ever { provider, repository, number }. The issue key comes from the run
|
|
7
|
+
* tree (RunIssueStatus, or a GitHub mention's RunHostStatus), never from model
|
|
8
|
+
* output. The status move is a control-plane
|
|
7
9
|
* action (not gated by allowedTransitions). Nothing here throws, except
|
|
8
10
|
* handlePullRequestClosed's lookup before it has claimed anything (so the
|
|
9
11
|
* webhook delivery is rolled back and redelivered).
|
|
10
12
|
*/
|
|
11
13
|
import { Prisma } from "#prisma";
|
|
12
14
|
import { projectOf, } from "../providers/issue-tracker/types.js";
|
|
15
|
+
import { normalizeGitHubRepository } from "../coding/protocol.js";
|
|
13
16
|
import { logger } from "./logger.js";
|
|
14
17
|
import { dedupeKeys, emitWorkflowEvent } from "./workflow-events.js";
|
|
15
18
|
const log = logger.child({ module: "issue-bridge" });
|
|
16
19
|
export const pullRequestGlobalId = (pr) => `wardby:pr:${pr.codeProvider}:${pr.repository}#${pr.number}`;
|
|
20
|
+
/** A GitHub issue's IssuePullRequest key: "<owner>/<repo>#<number>", the repository normalised. */
|
|
21
|
+
export function githubIssueKey(repository, number) {
|
|
22
|
+
return `${normalizeGitHubRepository(repository)}#${number}`;
|
|
23
|
+
}
|
|
17
24
|
/**
|
|
18
25
|
* Makes sure the issue/PR pair has a row, without ever overwriting one: a new
|
|
19
26
|
* row is "created"; an existing open one gets its url refreshed ("open"); a
|
|
20
27
|
* merged or closed one is left alone ("settled"). A lost create race (P2002)
|
|
21
28
|
* reads back the winner's row. "unknown" when the store could not be read.
|
|
22
29
|
*/
|
|
23
|
-
async function ensurePair(db,
|
|
30
|
+
async function ensurePair(db, issue, pr) {
|
|
24
31
|
const where = {
|
|
25
32
|
codeProvider_repository_number_issueProvider_issueKey: {
|
|
26
33
|
codeProvider: pr.codeProvider,
|
|
27
34
|
repository: pr.repository,
|
|
28
35
|
number: pr.number,
|
|
29
|
-
issueProvider:
|
|
30
|
-
issueKey:
|
|
36
|
+
issueProvider: issue.provider,
|
|
37
|
+
issueKey: issue.key,
|
|
31
38
|
},
|
|
32
39
|
};
|
|
33
40
|
try {
|
|
@@ -36,13 +43,13 @@ async function ensurePair(db, input, pr) {
|
|
|
36
43
|
try {
|
|
37
44
|
await db.issuePullRequest.create({
|
|
38
45
|
data: {
|
|
39
|
-
issueProvider:
|
|
40
|
-
issueKey:
|
|
46
|
+
issueProvider: issue.provider,
|
|
47
|
+
issueKey: issue.key,
|
|
41
48
|
codeProvider: pr.codeProvider,
|
|
42
49
|
repository: pr.repository,
|
|
43
50
|
number: pr.number,
|
|
44
51
|
url: pr.url,
|
|
45
|
-
agentId:
|
|
52
|
+
agentId: pr.agentId,
|
|
46
53
|
openedByRunId: pr.openedByRunId,
|
|
47
54
|
},
|
|
48
55
|
});
|
|
@@ -62,10 +69,98 @@ async function ensurePair(db, input, pr) {
|
|
|
62
69
|
return "open";
|
|
63
70
|
}
|
|
64
71
|
catch (err) {
|
|
65
|
-
log.warn({ err, issueKey:
|
|
72
|
+
log.warn({ err, issueKey: issue.key, repository: pr.repository, number: pr.number }, "could not record the issue/PR pair");
|
|
66
73
|
return "unknown";
|
|
67
74
|
}
|
|
68
75
|
}
|
|
76
|
+
/** Records each pair (ensurePair), in order; each state lines up with its pull request. Never throws. */
|
|
77
|
+
async function recordPairs(db, issue, prs) {
|
|
78
|
+
const states = [];
|
|
79
|
+
for (const pr of prs)
|
|
80
|
+
states.push(await ensurePair(db, issue, pr));
|
|
81
|
+
return states;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Notifies pr_opened for each pull request this call newly recorded as opened
|
|
85
|
+
* (`states` lines up with `prs`), so a retried completion does not notify
|
|
86
|
+
* twice. One message and dedupe key for every issue provider. Never throws.
|
|
87
|
+
*/
|
|
88
|
+
async function emitNewlyOpened(issue, prs, states, movedTo) {
|
|
89
|
+
for (const [i, pr] of prs.entries()) {
|
|
90
|
+
if (states[i] !== "created" || pr.outcome !== "pull_request_opened")
|
|
91
|
+
continue;
|
|
92
|
+
await emitWorkflowEvent({
|
|
93
|
+
dedupeKey: dedupeKeys.prOpened(pr.codeProvider, pr.repository, pr.number),
|
|
94
|
+
runId: pr.openedByRunId,
|
|
95
|
+
agentId: pr.agentId,
|
|
96
|
+
workItem: { provider: issue.provider, key: issue.key },
|
|
97
|
+
pullRequest: { codeProvider: pr.codeProvider, repository: pr.repository, number: pr.number },
|
|
98
|
+
payload: { kind: "pr_opened", prLabel: `${pr.repository}#${pr.number}`, prUrl: pr.url, movedTo },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Records the pull requests a run opened or continued for an issue, the same
|
|
104
|
+
* for every issue provider (a Jira issue, a GitHub issue): one IssuePullRequest
|
|
105
|
+
* row per issue/PR pair, state "open", never duplicated or overwritten (a
|
|
106
|
+
* merged or closed pair stays so; an open one gets its url refreshed), and a
|
|
107
|
+
* pr_opened notification for each newly recorded opened pull request.
|
|
108
|
+
* handlePullRequestClosed settles the rows. A GitHub issue's key is always
|
|
109
|
+
* githubIssueKey's, so any lookup of its rows must build the key the same way.
|
|
110
|
+
* Safe to repeat; never throws.
|
|
111
|
+
*/
|
|
112
|
+
export async function recordIssuePullRequests(db, issue, prs) {
|
|
113
|
+
try {
|
|
114
|
+
await emitNewlyOpened(issue, prs, await recordPairs(db, issue, prs), null);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
log.warn({ err, issueKey: issue.key }, "could not record the issue's pull requests");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The coding runs (of `runIds`) that continued a pull request opened for a
|
|
122
|
+
* different issue: their PR belongs to that issue, not this one. A
|
|
123
|
+
* continuation is foreign when its root coding run was dispatched for another
|
|
124
|
+
* tracked issue (CodingRun.issueKey), or when that root opened a pull request
|
|
125
|
+
* recorded for a different issue of any provider (IssuePullRequest, which a
|
|
126
|
+
* GitHub issue's runs also write). A continued PR with no issue, or this same
|
|
127
|
+
* issue, is fine.
|
|
128
|
+
*/
|
|
129
|
+
export async function continuedForAnotherIssue(db, runIds, issue) {
|
|
130
|
+
if (runIds.length === 0)
|
|
131
|
+
return new Set();
|
|
132
|
+
const rows = await db.codingRun.findMany({
|
|
133
|
+
where: { runId: { in: runIds } },
|
|
134
|
+
select: {
|
|
135
|
+
runId: true,
|
|
136
|
+
rootCodingRunId: true,
|
|
137
|
+
rootCodingRun: { select: { issueProvider: true, issueKey: true } },
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
const foreign = new Set();
|
|
141
|
+
const byRoot = new Map();
|
|
142
|
+
for (const { runId, rootCodingRunId, rootCodingRun: root } of rows) {
|
|
143
|
+
if (root?.issueKey && (root.issueKey !== issue.key || root.issueProvider !== issue.provider)) {
|
|
144
|
+
foreign.add(runId);
|
|
145
|
+
}
|
|
146
|
+
else if (rootCodingRunId) {
|
|
147
|
+
byRoot.set(rootCodingRunId, [...(byRoot.get(rootCodingRunId) ?? []), runId]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (byRoot.size > 0) {
|
|
151
|
+
const recorded = await db.issuePullRequest.findMany({
|
|
152
|
+
where: { openedByRunId: { in: [...byRoot.keys()] } },
|
|
153
|
+
select: { openedByRunId: true, issueProvider: true, issueKey: true },
|
|
154
|
+
});
|
|
155
|
+
for (const r of recorded) {
|
|
156
|
+
if (r.issueProvider === issue.provider && r.issueKey === issue.key)
|
|
157
|
+
continue;
|
|
158
|
+
for (const runId of byRoot.get(r.openedByRunId) ?? [])
|
|
159
|
+
foreign.add(runId);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return foreign;
|
|
163
|
+
}
|
|
69
164
|
/**
|
|
70
165
|
* Returns sentences for the outcome comment (a refused status move); empty
|
|
71
166
|
* when there is nothing to say. Safe to repeat (a retried completion): each
|
|
@@ -78,13 +173,13 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
78
173
|
const notes = [];
|
|
79
174
|
try {
|
|
80
175
|
let newlyOpened = false;
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
176
|
+
const issue = { provider: input.issueProvider, key: input.issueKey };
|
|
177
|
+
const records = input.pullRequests.map((pr) => ({ ...pr, agentId: input.agentId }));
|
|
178
|
+
const states = await recordPairs(db, issue, records);
|
|
179
|
+
for (const [i, pr] of input.pullRequests.entries()) {
|
|
180
|
+
const state = states[i];
|
|
181
|
+
if (state === "created" && pr.outcome === "pull_request_opened")
|
|
85
182
|
newlyOpened = true;
|
|
86
|
-
opened.push(pr);
|
|
87
|
-
}
|
|
88
183
|
if (state !== "created" && state !== "open")
|
|
89
184
|
continue;
|
|
90
185
|
try {
|
|
@@ -111,16 +206,7 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
111
206
|
}
|
|
112
207
|
}
|
|
113
208
|
// Only pairs this call newly recorded, so a retried completion does not notify twice. Never throws.
|
|
114
|
-
|
|
115
|
-
await emitWorkflowEvent({
|
|
116
|
-
dedupeKey: dedupeKeys.prOpened(pr.codeProvider, pr.repository, pr.number),
|
|
117
|
-
runId: pr.openedByRunId,
|
|
118
|
-
agentId: input.agentId,
|
|
119
|
-
workItem: { provider: input.issueProvider, key: input.issueKey },
|
|
120
|
-
pullRequest: { codeProvider: pr.codeProvider, repository: pr.repository, number: pr.number },
|
|
121
|
-
payload: { kind: "pr_opened", prLabel: `${pr.repository}#${pr.number}`, prUrl: pr.url, movedTo },
|
|
122
|
-
});
|
|
123
|
-
}
|
|
209
|
+
await emitNewlyOpened(issue, records, states, movedTo);
|
|
124
210
|
}
|
|
125
211
|
catch (err) {
|
|
126
212
|
log.warn({ err, issueKey: input.issueKey }, "could not bridge the pull requests to the issue");
|
|
@@ -129,8 +215,9 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
129
215
|
}
|
|
130
216
|
/**
|
|
131
217
|
* A pull request wardby recorded against an issue was merged or closed: marks
|
|
132
|
-
* each still-open pair
|
|
133
|
-
*
|
|
218
|
+
* each still-open pair (every issue provider, configured tracker or not),
|
|
219
|
+
* and, for an issue in a configured tracker where the agent's link to the
|
|
220
|
+
* issue's project is still write, comments on the issue (and on merge resolves the web link and
|
|
134
221
|
* applies the link's onPullRequestMerged move). Only rows wardby wrote are
|
|
135
222
|
* touched, matched by the host's own identity for the PR — nothing from the
|
|
136
223
|
* PR's text. The row is claimed first (open → merged/closed), so a duplicate
|
|
@@ -139,11 +226,14 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
139
226
|
* delivery is rolled back and redelivered; never throws after that.
|
|
140
227
|
*/
|
|
141
228
|
export async function handlePullRequestClosed(db, trackers, pr) {
|
|
142
|
-
if (!trackers)
|
|
143
|
-
return;
|
|
144
229
|
const where = { codeProvider: pr.codeProvider, repository: pr.repository, number: pr.number };
|
|
145
230
|
// Not caught: nothing is claimed yet, and a throw rolls back the delivery so it is redelivered.
|
|
146
|
-
|
|
231
|
+
// Oldest pair first: pr_closed's dedupe key is per pull request, so the first-recorded issue's event is
|
|
232
|
+
// the one kept, every delivery alike.
|
|
233
|
+
const rows = await db.issuePullRequest.findMany({
|
|
234
|
+
where: { ...where, state: "open" },
|
|
235
|
+
orderBy: { createdAt: "asc" },
|
|
236
|
+
});
|
|
147
237
|
for (const row of rows) {
|
|
148
238
|
// Exactly once per claimed row, from the finally below, even when a later step throws: the row is no
|
|
149
239
|
// longer open, so nothing would retry it. Never throws.
|
|
@@ -170,7 +260,8 @@ export async function handlePullRequestClosed(db, trackers, pr) {
|
|
|
170
260
|
if (claimed.count === 0)
|
|
171
261
|
continue;
|
|
172
262
|
claimedRow = true;
|
|
173
|
-
|
|
263
|
+
// A pair with no configured tracker (a GitHub issue's, say) is only marked.
|
|
264
|
+
const tracker = trackers?.[row.issueProvider];
|
|
174
265
|
if (!tracker)
|
|
175
266
|
continue;
|
|
176
267
|
const link = await db.agentIssueProject.findUnique({
|
|
@@ -12,7 +12,7 @@ import type { Executor } from "../providers/executor/types.js";
|
|
|
12
12
|
import type { IssueEvent, IssueEventKind, IssueTrackerRegistry } from "../providers/issue-tracker/types.js";
|
|
13
13
|
import { type DispatchDb } from "./dispatch.js";
|
|
14
14
|
import { type OpenSibling } from "./related-pull-requests.js";
|
|
15
|
-
export type IssueEventDb = DispatchDb & Pick<PrismaClient, "agentIssueProject" | "runIssueStatus" | "issuePullRequest" | "workItem">;
|
|
15
|
+
export type IssueEventDb = DispatchDb & Pick<PrismaClient, "registryFetch" | "registryAuditRecord" | "runBudgetEvent" | "agentIssueProject" | "runIssueStatus" | "issuePullRequest" | "workItem">;
|
|
16
16
|
export interface RouteIssueEventDeps {
|
|
17
17
|
db: IssueEventDb;
|
|
18
18
|
executor: Executor;
|
|
@@ -2,12 +2,11 @@ import { RESPONSE_PATH_SNAPSHOT_BUDGET, resolveWorkItem } from "./attribution.js
|
|
|
2
2
|
import { dispatchRun } from "./dispatch.js";
|
|
3
3
|
import { issueStatusRow, postIssueWorkingStatus } from "./issue-status.js";
|
|
4
4
|
import { logger } from "./logger.js";
|
|
5
|
-
import {
|
|
5
|
+
import { openPullRequestHints, openSiblingsForIssue } from "./related-pull-requests.js";
|
|
6
6
|
import { composeTaskOverride } from "./untrusted-content.js";
|
|
7
7
|
import { dedupeKeys, emitWorkflowEvent } from "./workflow-events.js";
|
|
8
8
|
const log = logger.child({ module: "issue-events" });
|
|
9
9
|
const MAX_TASK_BODY = 8000;
|
|
10
|
-
const RUN_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
11
10
|
/** Only admin-configured values (trigger labels, the target status) appear here: never free text from the actor. */
|
|
12
11
|
function describeKind(event, kind, link) {
|
|
13
12
|
switch (kind) {
|
|
@@ -45,14 +44,9 @@ export function issueTaskText(event, matched, issueUrl, link, openPrs = []) {
|
|
|
45
44
|
"do not also post it with jira_comment; use jira_comment only for other issues or progress notes on long work.",
|
|
46
45
|
];
|
|
47
46
|
// Control-plane data from stored rows (validated here), never issue text.
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
sections.push(
|
|
51
|
-
`(https://github.com/${pr.repository}/pull/${pr.number}). ` +
|
|
52
|
-
`To revise it, delegate with continuePriorRun set to exactly "${pr.openedByRunId}".`);
|
|
53
|
-
}
|
|
54
|
-
if (hinted.length > 0)
|
|
55
|
-
sections.push(SIBLING_GUIDANCE);
|
|
47
|
+
const hints = openPullRequestHints(openPrs);
|
|
48
|
+
if (hints)
|
|
49
|
+
sections.push(hints);
|
|
56
50
|
if (matched.includes("mention") && event.comment) {
|
|
57
51
|
sections.push(`Request comment:\n${event.comment.body.slice(0, MAX_TASK_BODY)}`);
|
|
58
52
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { Prisma, type PrismaClient } from "#prisma";
|
|
8
8
|
import { type IssueTrackerRegistry } from "../providers/issue-tracker/types.js";
|
|
9
9
|
import { type FinishedRun } from "./host-status.js";
|
|
10
|
-
export type IssueStatusDb = Pick<PrismaClient, "runIssueStatus" | "run" | "agentIssueProject" | "issuePullRequest" | "codingRun" | "$queryRaw">;
|
|
10
|
+
export type IssueStatusDb = Pick<PrismaClient, "registryFetch" | "registryAuditRecord" | "runIssueStatus" | "run" | "runBudgetEvent" | "agentIssueProject" | "issuePullRequest" | "codingRun" | "$queryRaw">;
|
|
11
11
|
export declare function toJiraMarkdown(text: string): string;
|
|
12
12
|
export declare function issueStatusRow(event: {
|
|
13
13
|
issueKey: string;
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* text. Best effort throughout: nothing here throws.
|
|
6
6
|
*/
|
|
7
7
|
import { Prisma } from "#prisma";
|
|
8
|
-
import { projectOf } from "../providers/issue-tracker/types.js";
|
|
9
|
-
import { collectRunOutcome, outcomeBody, runLine, workingBody } from "./host-status.js";
|
|
10
|
-
import { recordPullRequests } from "./issue-bridge.js";
|
|
8
|
+
import { projectOf, } from "../providers/issue-tracker/types.js";
|
|
9
|
+
import { collectRunOutcome, fullReplyComments, fullReplyOf, isBlockedByRefusals, JIRA_REPLY_MAX_CHARS, outcomeBody, REPLY_MAX_PARTS, runLine, workingBody, } from "./host-status.js";
|
|
10
|
+
import { continuedForAnotherIssue, recordPullRequests } from "./issue-bridge.js";
|
|
11
11
|
import { logger } from "./logger.js";
|
|
12
12
|
const log = logger.child({ module: "issue-status" });
|
|
13
13
|
const TERMINAL = new Set(["succeeded", "failed", "refused", "lost", "budget_exhausted", "cancelled"]);
|
|
@@ -126,26 +126,6 @@ async function currentLink(db, runId, issueKey, provider) {
|
|
|
126
126
|
});
|
|
127
127
|
return link ? { agentId: run.agentId, ...link } : null;
|
|
128
128
|
}
|
|
129
|
-
/**
|
|
130
|
-
* The coding runs (of `runIds`) that continued a pull request opened for a
|
|
131
|
-
* different issue: their PR belongs to that issue, not this one. A continued
|
|
132
|
-
* PR with no issue, or this same issue, is fine.
|
|
133
|
-
*/
|
|
134
|
-
async function continuedForAnotherIssue(db, runIds, issue) {
|
|
135
|
-
if (runIds.length === 0)
|
|
136
|
-
return new Set();
|
|
137
|
-
const rows = await db.codingRun.findMany({
|
|
138
|
-
where: { runId: { in: runIds } },
|
|
139
|
-
select: { runId: true, rootCodingRun: { select: { issueProvider: true, issueKey: true } } },
|
|
140
|
-
});
|
|
141
|
-
return new Set(rows
|
|
142
|
-
.filter(({ rootCodingRun: root }) => {
|
|
143
|
-
if (!root?.issueKey)
|
|
144
|
-
return false;
|
|
145
|
-
return root.issueKey !== issue.issueKey || root.issueProvider !== issue.provider;
|
|
146
|
-
})
|
|
147
|
-
.map((row) => row.runId));
|
|
148
|
-
}
|
|
149
129
|
export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
150
130
|
if (!trackers)
|
|
151
131
|
return;
|
|
@@ -164,9 +144,10 @@ export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
|
164
144
|
const writable = link?.access === "write";
|
|
165
145
|
const project = projectOf(status.issueKey);
|
|
166
146
|
let body;
|
|
147
|
+
let fullReply = null;
|
|
167
148
|
if (writable) {
|
|
168
|
-
const { pullRequests, failedChildren, budgetSentence } = await collectRunOutcome(db, run);
|
|
169
|
-
const foreign = await continuedForAnotherIssue(db, pullRequests.flatMap((pr) => (pr.pullRequestUrl && pr.runId ? [pr.runId] : [])), status);
|
|
149
|
+
const { pullRequests, failedChildren, budgetSentence, packageRefusals, noChanges, packageAudit } = await collectRunOutcome(db, run);
|
|
150
|
+
const foreign = await continuedForAnotherIssue(db, pullRequests.flatMap((pr) => (pr.pullRequestUrl && pr.runId ? [pr.runId] : [])), { provider: status.provider, key: status.issueKey });
|
|
170
151
|
for (const runId of foreign) {
|
|
171
152
|
log.info({ runId: run.id, codingRunId: runId, issueKey: status.issueKey }, "not linking a pull request continued from another issue's run");
|
|
172
153
|
}
|
|
@@ -191,9 +172,18 @@ export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
|
191
172
|
pullRequests: bridged,
|
|
192
173
|
})
|
|
193
174
|
: { notes: [] };
|
|
175
|
+
// A blocked status is built from the refusals alone, so the agent's reply is not posted after it.
|
|
176
|
+
fullReply = isBlockedByRefusals(run, { pullRequests, failedChildren, packageRefusals, noChanges })
|
|
177
|
+
? null
|
|
178
|
+
: fullReplyOf(run, pullRequests, failedChildren);
|
|
194
179
|
const outcome = outcomeBody(run, "", pullRequests, failedChildren, {
|
|
195
180
|
budgetSentence,
|
|
181
|
+
packageRefusals,
|
|
182
|
+
packageAudit,
|
|
183
|
+
noChanges,
|
|
184
|
+
fullReplyFollows: true,
|
|
196
185
|
noPullRequestText: "Done.",
|
|
186
|
+
fromIssue: true,
|
|
197
187
|
// One comment per request: this status comment carries the agent's answer.
|
|
198
188
|
replyAsAnswer: true,
|
|
199
189
|
});
|
|
@@ -221,12 +211,50 @@ export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
|
221
211
|
}
|
|
222
212
|
// Unlinked or read-only with no status comment yet: complete the row
|
|
223
213
|
// without posting; never create content where the agent may not write.
|
|
224
|
-
|
|
214
|
+
// Claims the row in one step, saving a posted comment's id at once so a retry edits it instead of
|
|
215
|
+
// posting a second one. Only the completion that claims it posts the full reply, so two racing
|
|
216
|
+
// completions (the run's own and the reconciler's) never post it twice.
|
|
217
|
+
const claimed = await db.runIssueStatus.updateMany({
|
|
218
|
+
where: { runId: run.id, completedAt: null },
|
|
219
|
+
data: { commentId, completedAt: new Date() },
|
|
220
|
+
});
|
|
221
|
+
if (claimed.count !== 1) {
|
|
222
|
+
log.warn({ runId: run.id }, "the issue status comment was completed meanwhile; leaving any full reply to that completion");
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (writable && fullReply !== null) {
|
|
226
|
+
await postFullReply(tracker, status.issueKey, run.id, fullReply, issueKeyProjects, link.commentVisibilityRole);
|
|
227
|
+
}
|
|
225
228
|
}
|
|
226
229
|
catch (err) {
|
|
227
230
|
log.warn({ err, runId: run.id }, "could not complete the issue status comment");
|
|
228
231
|
}
|
|
229
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Posts the full reply's parts in order, each at most once: the status comment already points to them,
|
|
235
|
+
* so a failed part is logged and the rest skipped (a gap would misnumber the reply), and the row is still
|
|
236
|
+
* completed. The full text stays on the run. Never throws.
|
|
237
|
+
*/
|
|
238
|
+
async function postFullReply(tracker, issueKey, runId, reply, issueKeyProjects, visibilityRole) {
|
|
239
|
+
// Converted first, then split: the conversion lengthens `owner/repo#N` references, and the parts must fit after it.
|
|
240
|
+
const bodies = fullReplyComments(toJiraMarkdown(reply), {
|
|
241
|
+
maxChars: JIRA_REPLY_MAX_CHARS,
|
|
242
|
+
maxParts: REPLY_MAX_PARTS,
|
|
243
|
+
});
|
|
244
|
+
for (const [i, body] of bodies.entries()) {
|
|
245
|
+
try {
|
|
246
|
+
await tracker.comment(issueKey, {
|
|
247
|
+
markdown: body,
|
|
248
|
+
issueKeyProjects,
|
|
249
|
+
...(visibilityRole ? { visibilityRole } : {}),
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
log.warn({ err, runId, part: i + 1, parts: bodies.length }, "could not post a part of the run's full reply; the rest is skipped, the full text stays on the run");
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
230
258
|
export async function closeOrphanedIssueStatuses(db, trackers, now = new Date()) {
|
|
231
259
|
const providers = Object.keys(trackers ?? {});
|
|
232
260
|
if (!trackers || providers.length === 0)
|
package/dist/core/logger.d.ts
CHANGED
|
@@ -9,5 +9,10 @@
|
|
|
9
9
|
* for the CLI's own output — see cli.ts's stdout/stderr split).
|
|
10
10
|
*/
|
|
11
11
|
import pino from "pino";
|
|
12
|
+
/**
|
|
13
|
+
* Sets the filter every log line passes through on its way to stderr. The native sandbox worker
|
|
14
|
+
* uses it to redact the secret values it received (native-worker/stderr-redaction.ts).
|
|
15
|
+
*/
|
|
16
|
+
export declare function setLogLineFilter(filter: (line: string) => string): void;
|
|
12
17
|
export declare const logger: pino.Logger<never, boolean>;
|
|
13
18
|
export type Logger = typeof logger;
|
package/dist/core/logger.js
CHANGED
|
@@ -42,4 +42,17 @@ function redactErr(error) {
|
|
|
42
42
|
// last two); an AggregateError adds `aggregateErrors`, hence the walk.
|
|
43
43
|
return redactDeep(pino.stdSerializers.err(error));
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
/** Applied to every serialized line before it is written. Identity unless a process sets one. */
|
|
46
|
+
let lineFilter = (line) => line;
|
|
47
|
+
/**
|
|
48
|
+
* Sets the filter every log line passes through on its way to stderr. The native sandbox worker
|
|
49
|
+
* uses it to redact the secret values it received (native-worker/stderr-redaction.ts).
|
|
50
|
+
*/
|
|
51
|
+
export function setLogLineFilter(filter) {
|
|
52
|
+
lineFilter = filter;
|
|
53
|
+
}
|
|
54
|
+
export const logger = pino({
|
|
55
|
+
level: process.env.LOG_LEVEL ?? "info",
|
|
56
|
+
serializers: { err: redactErr },
|
|
57
|
+
hooks: { streamWrite: (line) => lineFilter(line) },
|
|
58
|
+
}, pino.destination({ fd: 2, sync: false }));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PrismaClient } from "#prisma";
|
|
2
|
+
import type { Executor } from "../providers/executor/types.js";
|
|
3
|
+
/** The stop reason recorded on every child stopped because its parent run ended lost. */
|
|
4
|
+
export declare const PARENT_LOST_REASON = "parent run lost";
|
|
5
|
+
/** Stops the still-drivable children of a run that ended lost, so none keeps spending for nobody. */
|
|
6
|
+
export declare function stopChildrenOfLostRun(db: Pick<PrismaClient, "run">, executor: Pick<Executor, "stop"> | undefined, runId: string): Promise<number>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DRIVABLE } from "./run-status.js";
|
|
2
|
+
import { logger } from "./logger.js";
|
|
3
|
+
const log = logger.child({ module: "lost-run-children" });
|
|
4
|
+
/** The stop reason recorded on every child stopped because its parent run ended lost. */
|
|
5
|
+
export const PARENT_LOST_REASON = "parent run lost";
|
|
6
|
+
/** Stops the still-drivable children of a run that ended lost, so none keeps spending for nobody. */
|
|
7
|
+
export async function stopChildrenOfLostRun(db, executor, runId) {
|
|
8
|
+
if (!executor)
|
|
9
|
+
return 0;
|
|
10
|
+
let children;
|
|
11
|
+
try {
|
|
12
|
+
children = await db.run.findMany({
|
|
13
|
+
where: { parentRunId: runId, status: { in: [...DRIVABLE] } },
|
|
14
|
+
select: { id: true },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
log.error({ err, runId }, "could not list the children of a lost run");
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
let stopped = 0;
|
|
22
|
+
for (const child of children) {
|
|
23
|
+
try {
|
|
24
|
+
await executor.stop(child.id, PARENT_LOST_REASON);
|
|
25
|
+
stopped++;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
log.error({ err, runId, childRunId: child.id }, "could not stop a child of a lost run");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return stopped;
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks a draft pull request Wardby's own App opened ready for review once it passes (#287):
|
|
3
|
+
* every Wardby review check on the head succeeded, CI is green, and the `wardby merge order`
|
|
4
|
+
* check is success or absent. Opt-in per write link (AgentRepository.markReadyWhenPassing) of
|
|
5
|
+
* the agent the repository event triggers: the builder that opened the pull request, or a lead
|
|
6
|
+
* that delegated to it (coding agents cannot link repositories, so a lead's link carries it).
|
|
7
|
+
* At most once per pull request (CodingRun.markedReadyAt on the opener's root coding run), so
|
|
8
|
+
* a person moving it back to draft is final. Cheap DB checks first; no host reads unless some
|
|
9
|
+
* link on the repository opted in.
|
|
10
|
+
*
|
|
11
|
+
* The host only confirms the pull request was authored by this App. The trust boundary is
|
|
12
|
+
* here: the pull request's marker must resolve (through rootCodingRunId) to a root coding run
|
|
13
|
+
* in this repository, recorded as this pull request, whose agent, or an ancestor agent in its
|
|
14
|
+
* run tree (Run.parentRunId, at most MAX_ANCESTOR_HOPS up), has an authorized, opted-in write
|
|
15
|
+
* link on this repository. An opted-in agent outside that run tree never counts. Only
|
|
16
|
+
* authorized links (authorizedVia set) count, for opting in and for review checks.
|
|
17
|
+
*
|
|
18
|
+
* Work a run stopped at its budget pushed (a draft to continue) is never marked ready.
|
|
19
|
+
*
|
|
20
|
+
* Never approves, merges, or converts back to draft. Never throws.
|
|
21
|
+
*/
|
|
22
|
+
import type { PrismaClient } from "#prisma";
|
|
23
|
+
import type { ReviewHostRegistry } from "../providers/review-host/types.js";
|
|
24
|
+
import type { Logger } from "./logger.js";
|
|
25
|
+
export type MarkReadyOutcome = "marked" | "off" | "not_ready" | "skipped" | "failed";
|
|
26
|
+
export type MarkReadyDb = Pick<PrismaClient, "agentRepository" | "codingRun" | "run" | "runHostCheck">;
|
|
27
|
+
export interface MarkReadyDeps {
|
|
28
|
+
db: MarkReadyDb;
|
|
29
|
+
hosts: ReviewHostRegistry | undefined;
|
|
30
|
+
log?: Logger;
|
|
31
|
+
}
|
|
32
|
+
export declare function maybeMarkReady(deps: MarkReadyDeps, repository: string, prNumber: number, provider?: string): Promise<MarkReadyOutcome>;
|
|
33
|
+
/** After a reviewer run ends: evaluate the pull request it reviewed. Null when it reviewed none. */
|
|
34
|
+
export declare function markReadyAfterRun(deps: MarkReadyDeps, runId: string): Promise<MarkReadyOutcome | null>;
|