@wardby/cli 0.5.3 → 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/.env.example +33 -0
- package/README.md +25 -14
- package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
- package/dist/claude-coding-worker/context.d.ts +22 -0
- package/dist/claude-coding-worker/context.js +92 -0
- package/dist/claude-coding-worker/driver.d.ts +27 -3
- package/dist/claude-coding-worker/driver.js +161 -20
- package/dist/claude-coding-worker/main.js +34 -6
- package/dist/claude-coding-worker/sdk.js +25 -5
- 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 +6 -2
- package/dist/cli-native-mode.d.ts +9 -0
- package/dist/cli-native-mode.js +20 -0
- package/dist/cli.d.ts +3 -1
- package/dist/cli.js +161 -11
- package/dist/coding/claude-context.d.ts +45 -0
- package/dist/coding/claude-context.js +434 -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/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 +50 -118
- package/dist/coding/profile.js +51 -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 +292 -270
- package/dist/coding/protocol.js +322 -15
- 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 +16 -3
- package/dist/coding-worker/artifact.js +5 -3
- 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 +118 -38
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/sdk.d.ts +6 -0
- package/dist/coding-worker/sdk.js +1 -0
- package/dist/coding-worker/skills.d.ts +23 -0
- package/dist/coding-worker/skills.js +117 -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 +13 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/github-allowed-accounts.d.ts +15 -0
- package/dist/config/github-allowed-accounts.js +36 -0
- package/dist/config/low-power.d.ts +12 -0
- package/dist/config/low-power.js +18 -0
- package/dist/config/mobile.d.ts +12 -0
- package/dist/config/mobile.js +18 -0
- package/dist/config/providers.d.ts +65 -3
- package/dist/config/providers.js +147 -11
- 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/db.d.ts +16 -6
- package/dist/core/db.js +12 -10
- 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 +53 -0
- package/dist/core/dispatch.js +167 -57
- package/dist/core/engine-native.js +10 -6
- 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 +67 -5
- package/dist/core/host-events.js +571 -37
- 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 +151 -20
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +16 -11
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +68 -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/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +130 -0
- package/dist/core/merge-order-check.js +343 -0
- package/dist/core/notification-dispatcher.d.ts +70 -0
- package/dist/core/notification-dispatcher.js +368 -0
- package/dist/core/notification-templates.d.ts +19 -0
- package/dist/core/notification-templates.js +139 -0
- package/dist/core/notifications.d.ts +10 -0
- package/dist/core/notifications.js +38 -0
- package/dist/core/pg-auth.d.ts +22 -0
- package/dist/core/pg-auth.js +152 -0
- package/dist/core/power-composition.d.ts +16 -0
- package/dist/core/power-composition.js +37 -0
- package/dist/core/power-idle.d.ts +14 -0
- package/dist/core/power-idle.js +30 -0
- package/dist/core/power.d.ts +71 -0
- package/dist/core/power.js +202 -0
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +8 -5
- package/dist/core/reconciler.js +37 -6
- package/dist/core/related-pull-requests.d.ts +59 -7
- package/dist/core/related-pull-requests.js +140 -25
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/repo-access.d.ts +15 -0
- package/dist/core/repo-access.js +66 -0
- package/dist/core/review-fix.d.ts +38 -1
- package/dist/core/review-fix.js +209 -7
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +23 -0
- package/dist/core/review-host-tools.js +156 -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 +384 -5
- package/dist/core/runner.js +1244 -372
- 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 +39 -0
- package/dist/core/secret-broker-config.js +112 -0
- 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/secrets.d.ts +39 -4
- package/dist/core/secrets.js +148 -40
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/workflow-event-recorder.d.ts +14 -0
- package/dist/core/workflow-event-recorder.js +120 -0
- package/dist/core/workflow-events.d.ts +94 -0
- package/dist/core/workflow-events.js +48 -0
- package/dist/core/workflow-run-events.d.ts +18 -0
- package/dist/core/workflow-run-events.js +75 -0
- 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 +92 -3
- package/dist/generated/prisma/client.d.ts +92 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +364 -54
- package/dist/generated/prisma/enums.d.ts +37 -0
- package/dist/generated/prisma/enums.js +31 -0
- package/dist/generated/prisma/internal/class.d.ts +132 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +1332 -142
- package/dist/generated/prisma/internal/prismaNamespace.js +227 -5
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +234 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +227 -5
- package/dist/generated/prisma/models/Agent.d.ts +464 -7
- package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +301 -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 +1841 -1
- package/dist/generated/prisma/models/DeferredReview.d.ts +78 -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 +1713 -0
- package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1551 -0
- package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
- package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
- package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
- package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
- package/dist/generated/prisma/models/NotificationChannel.js +1 -0
- package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
- package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
- package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
- package/dist/generated/prisma/models/NotificationThread.js +1 -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/Run.d.ts +1619 -58
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
- 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 +37 -1
- package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
- package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
- package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
- package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
- package/dist/generated/prisma/models.d.ts +12 -0
- package/dist/help/build.js +4 -2
- package/dist/help/catalog.d.ts +1 -1
- package/dist/help/catalog.js +31 -6
- package/dist/help-index.json +2584 -146
- package/dist/import/create.js +49 -3
- package/dist/import/neutral-schema.d.ts +50 -277
- 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 +11 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/repo-authorization.js +14 -0
- package/dist/mcp/auth/resource-server.d.ts +2 -1
- package/dist/mcp/auth/resource-server.js +7 -2
- package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
- package/dist/mcp/auth/self-hosted/browser.js +19 -6
- 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 +6 -0
- package/dist/mcp/host-events/github-ingress.d.ts +25 -1
- package/dist/mcp/host-events/github-ingress.js +70 -1
- package/dist/mcp/index.d.ts +19 -0
- package/dist/mcp/index.js +117 -20
- 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 +277 -24
- 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.d.ts +2 -0
- package/dist/mcp/tools/notification-channels.js +293 -0
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/power.d.ts +2 -0
- package/dist/mcp/tools/power.js +77 -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.d.ts +0 -6
- package/dist/mcp/tools/runs.js +41 -14
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
- package/dist/mcp/tools/secret-broker-compat.js +23 -0
- package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
- package/dist/mcp/tools/secret-elicitation-form.js +205 -10
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -54
- package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
- package/dist/mcp/tools/secret-elicitation.js +110 -12
- package/dist/mcp/tools/secrets.js +186 -9
- 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 +2 -2
- package/dist/mcp/tools/tools.js +47 -11
- 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/composition.d.ts +23 -0
- package/dist/native-worker/composition.js +77 -0
- package/dist/native-worker/docker-isolation.d.ts +65 -0
- package/dist/native-worker/docker-isolation.js +183 -0
- package/dist/native-worker/docker-launcher.d.ts +110 -0
- package/dist/native-worker/docker-launcher.js +297 -0
- package/dist/native-worker/gateway-server.d.ts +77 -0
- package/dist/native-worker/gateway-server.js +412 -0
- package/dist/native-worker/gateway.d.ts +70 -0
- package/dist/native-worker/gateway.js +263 -0
- package/dist/native-worker/http-server.d.ts +24 -0
- package/dist/native-worker/http-server.js +113 -0
- package/dist/native-worker/http-transport.d.ts +17 -0
- package/dist/native-worker/http-transport.js +88 -0
- package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
- package/dist/native-worker/kubernetes-isolation.js +218 -0
- package/dist/native-worker/kubernetes-launcher.d.ts +106 -0
- package/dist/native-worker/kubernetes-launcher.js +375 -0
- package/dist/native-worker/launch.d.ts +62 -0
- package/dist/native-worker/launch.js +49 -0
- package/dist/native-worker/ledger.d.ts +125 -0
- package/dist/native-worker/ledger.js +245 -0
- package/dist/native-worker/loopback.d.ts +12 -0
- package/dist/native-worker/loopback.js +44 -0
- package/dist/native-worker/main.d.ts +8 -0
- package/dist/native-worker/main.js +85 -0
- package/dist/native-worker/protocol.d.ts +296 -0
- package/dist/native-worker/protocol.js +246 -0
- package/dist/native-worker/sandbox-executor.d.ts +83 -0
- package/dist/native-worker/sandbox-executor.js +284 -0
- 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 +29 -0
- package/dist/native-worker/stdio.js +189 -0
- package/dist/native-worker/warm-delivery.d.ts +16 -0
- package/dist/native-worker/warm-delivery.js +33 -0
- package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
- package/dist/native-worker/warm-pool-ledger.js +73 -0
- package/dist/native-worker/warm-pool.d.ts +107 -0
- package/dist/native-worker/warm-pool.js +283 -0
- package/dist/native-worker/worker.d.ts +17 -0
- package/dist/native-worker/worker.js +141 -0
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/authorization-server.d.ts +3 -0
- package/dist/providers/auth/index.js +2 -0
- package/dist/providers/auth/self-hosted.d.ts +14 -2
- package/dist/providers/auth/self-hosted.js +54 -4
- package/dist/providers/chat/fake.d.ts +46 -0
- package/dist/providers/chat/fake.js +39 -0
- package/dist/providers/chat/index.d.ts +4 -0
- package/dist/providers/chat/index.js +8 -0
- package/dist/providers/chat/slack.d.ts +37 -0
- package/dist/providers/chat/slack.js +105 -0
- package/dist/providers/chat/types.d.ts +42 -0
- package/dist/providers/chat/types.js +19 -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/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 +36 -2
- package/dist/providers/engine/types.js +39 -0
- package/dist/providers/executor/composition.d.ts +31 -1
- package/dist/providers/executor/composition.js +81 -8
- package/dist/providers/executor/container.d.ts +385 -9
- package/dist/providers/executor/container.js +1234 -99
- 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 +91 -0
- package/dist/providers/executor/dbos.js +319 -26
- package/dist/providers/executor/deferred.d.ts +44 -0
- package/dist/providers/executor/deferred.js +100 -0
- 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 +39 -10
- package/dist/providers/executor/routing.js +77 -32
- package/dist/providers/executor/types.d.ts +25 -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 +29 -4
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +23 -2
- package/dist/providers/jobs/fake-kubernetes-api.js +45 -1
- package/dist/providers/jobs/kubernetes-api.d.ts +25 -1
- package/dist/providers/jobs/kubernetes-api.js +17 -0
- package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
- package/dist/providers/jobs/kubernetes-client.js +61 -3
- package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
- package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
- package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
- package/dist/providers/jobs/kubernetes-isolation.js +23 -1
- package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
- package/dist/providers/jobs/kubernetes-platform.js +38 -1
- package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
- package/dist/providers/jobs/kubernetes-preflight.js +4 -2
- package/dist/providers/jobs/kubernetes.d.ts +42 -2
- package/dist/providers/jobs/kubernetes.js +178 -19
- package/dist/providers/jobs/metadata-probes.d.ts +11 -0
- package/dist/providers/jobs/metadata-probes.js +13 -0
- package/dist/providers/jobs/types.d.ts +42 -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 +39 -2
- package/dist/providers/review-host/github.js +274 -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 +157 -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 +246 -12
- package/dist/providers/vcs/github.js +521 -61
- 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 +21 -3
- package/dist/quickstart/coding-seed.js +283 -3
- package/dist/quickstart/images.d.ts +2 -0
- package/dist/quickstart/images.js +7 -1
- 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/brokered-fetch.d.ts +23 -0
- package/dist/sandbox/brokered-fetch.js +37 -0
- 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 +35 -0
- package/dist/sandbox/host-functions.js +150 -91
- package/dist/sandbox/prelude.js +7 -1
- package/dist/sandbox/run-in-sandbox.d.ts +19 -0
- package/dist/sandbox/run-in-sandbox.js +28 -10
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +3 -1
- package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
- package/dist/sandbox/secret-broker-sigv4.js +49 -0
- package/dist/sandbox/secret-broker.d.ts +34 -0
- package/dist/sandbox/secret-broker.js +161 -0
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/user-tool.d.ts +14 -0
- package/dist/sandbox/user-tool.js +32 -0
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +25 -0
- package/dist/viewer/api-schema.d.ts +372 -2454
- package/dist/viewer/api-schema.js +29 -0
- package/dist/viewer/build-schemas.js +10 -3
- package/dist/viewer/event-bus.d.ts +6 -0
- package/dist/viewer/event-bus.js +16 -7
- package/dist/viewer/graph.d.ts +5 -2
- package/dist/viewer/graph.js +7 -2
- package/dist/viewer/http.d.ts +0 -1
- package/dist/viewer/http.js +2 -2
- package/dist/viewer/infra.js +25 -2
- package/dist/viewer/limits.d.ts +4 -0
- package/dist/viewer/limits.js +4 -0
- package/dist/viewer/openapi.d.ts +15 -0
- package/dist/viewer/openapi.js +170 -0
- package/dist/wardby-bin.js +10 -0
- package/docs/README.md +7 -0
- package/docs/agent-recipes.md +114 -27
- package/docs/architecture-runtime.md +16 -1
- package/docs/code-review-agents.md +689 -45
- package/docs/coding-agent-setup.md +602 -12
- package/docs/coding-packages.md +1037 -92
- package/docs/coding-services.md +30 -13
- package/docs/coding-worker-byo-images.md +218 -6
- package/docs/coding-worker-isolation.md +173 -44
- package/docs/getting-started-gke.md +332 -129
- package/docs/getting-started-identity-provider.md +31 -11
- package/docs/getting-started.md +14 -4
- package/docs/jira-agents.md +22 -9
- 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 +731 -0
- package/docs/observability.md +4 -0
- package/docs/release-verification.md +9 -0
- package/docs/security-deployment.md +146 -14
- package/docs/slack-notifications.md +268 -0
- package/docs/tool-secrets.md +284 -0
- package/docs/viewer-api.md +46 -5
- package/docs/viewer-api.openapi.yml +1404 -0
- package/help/admin-viewer.md +29 -3
- package/help/agent-recipes.md +27 -0
- package/help/architecture-agent.md +11 -6
- package/help/brokered-secrets.md +79 -0
- package/help/build-claude-code-image.md +131 -0
- package/help/build-worker-image.md +6 -7
- package/help/builder-agent.md +19 -6
- package/help/code-review-agents.md +243 -10
- 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 +23 -9
- package/help/deployment-targets.md +25 -14
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-provider-not-configured.md +2 -2
- 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 +28 -0
- 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 +29 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/low-power-disabled.md +29 -0
- package/help/errors/low-power-scale-forbidden.md +35 -0
- package/help/errors/low-power-wake-timeout.md +30 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/mobile-disabled.md +31 -0
- package/help/errors/native-sandbox-capacity.md +22 -0
- package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
- package/help/errors/native-sandbox-docker-failed.md +20 -0
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
- package/help/errors/native-sandbox-image-not-pinned.md +19 -0
- package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-network-unenforced.md +22 -0
- package/help/errors/native-sandbox-requires-catalog.md +31 -0
- package/help/errors/native-sandbox-unavailable.md +19 -0
- package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
- package/help/errors/native-sandbox-worker-exited.md +21 -0
- package/help/errors/native-sandbox-worker-lost.md +20 -0
- package/help/errors/native-sandbox-worker-unready.md +22 -0
- 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-broker-body-invalid.md +26 -0
- package/help/errors/secret-broker-changed.md +20 -0
- package/help/errors/secret-broker-config-invalid.md +30 -0
- package/help/errors/secret-broker-conflict.md +27 -0
- package/help/errors/secret-broker-destination-denied.md +28 -0
- package/help/errors/secret-broker-value-invalid.md +28 -0
- package/help/errors/secret-brokered.md +24 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/secret-not-brokered.md +25 -0
- package/help/errors/slack-auth-failed.md +48 -0
- package/help/errors/slack-channel-unreachable.md +39 -0
- package/help/errors/slack-not-configured.md +33 -0
- package/help/errors/target-merge.md +40 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/getting-started.md +4 -5
- package/help/github-app-setup.md +132 -0
- package/help/github.md +40 -1
- package/help/identity-and-access.md +7 -1
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +3 -4
- package/help/low-power-mode.md +131 -0
- package/help/merge-order-check.md +122 -0
- package/help/mobile-app.md +54 -0
- package/help/native-capabilities.md +29 -1
- package/help/native-sandbox.md +150 -0
- package/help/observability.md +8 -0
- package/help/operating-agents.md +5 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +80 -16
- package/help/repo-instructions-and-skills.md +91 -0
- package/help/resume-runs-locally.md +131 -0
- package/help/review-fix-rounds.md +43 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +76 -0
- 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 +99 -7
- package/package.json +27 -13
- package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
- package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
- package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
- package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
- package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
- package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
- package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
- package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
- package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
- package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
- package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
- package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
- package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
- package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
- 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 +631 -146
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -1,32 +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";
|
|
17
|
+
import { dedupeKeys, emitWorkflowEvent } from "./workflow-events.js";
|
|
14
18
|
const log = logger.child({ module: "issue-bridge" });
|
|
15
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
|
+
}
|
|
16
24
|
/**
|
|
17
25
|
* Makes sure the issue/PR pair has a row, without ever overwriting one: a new
|
|
18
26
|
* row is "created"; an existing open one gets its url refreshed ("open"); a
|
|
19
27
|
* merged or closed one is left alone ("settled"). A lost create race (P2002)
|
|
20
28
|
* reads back the winner's row. "unknown" when the store could not be read.
|
|
21
29
|
*/
|
|
22
|
-
async function ensurePair(db,
|
|
30
|
+
async function ensurePair(db, issue, pr) {
|
|
23
31
|
const where = {
|
|
24
32
|
codeProvider_repository_number_issueProvider_issueKey: {
|
|
25
33
|
codeProvider: pr.codeProvider,
|
|
26
34
|
repository: pr.repository,
|
|
27
35
|
number: pr.number,
|
|
28
|
-
issueProvider:
|
|
29
|
-
issueKey:
|
|
36
|
+
issueProvider: issue.provider,
|
|
37
|
+
issueKey: issue.key,
|
|
30
38
|
},
|
|
31
39
|
};
|
|
32
40
|
try {
|
|
@@ -35,13 +43,13 @@ async function ensurePair(db, input, pr) {
|
|
|
35
43
|
try {
|
|
36
44
|
await db.issuePullRequest.create({
|
|
37
45
|
data: {
|
|
38
|
-
issueProvider:
|
|
39
|
-
issueKey:
|
|
46
|
+
issueProvider: issue.provider,
|
|
47
|
+
issueKey: issue.key,
|
|
40
48
|
codeProvider: pr.codeProvider,
|
|
41
49
|
repository: pr.repository,
|
|
42
50
|
number: pr.number,
|
|
43
51
|
url: pr.url,
|
|
44
|
-
agentId:
|
|
52
|
+
agentId: pr.agentId,
|
|
45
53
|
openedByRunId: pr.openedByRunId,
|
|
46
54
|
},
|
|
47
55
|
});
|
|
@@ -61,10 +69,98 @@ async function ensurePair(db, input, pr) {
|
|
|
61
69
|
return "open";
|
|
62
70
|
}
|
|
63
71
|
catch (err) {
|
|
64
|
-
log.warn({ err, issueKey:
|
|
72
|
+
log.warn({ err, issueKey: issue.key, repository: pr.repository, number: pr.number }, "could not record the issue/PR pair");
|
|
65
73
|
return "unknown";
|
|
66
74
|
}
|
|
67
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
|
+
}
|
|
68
164
|
/**
|
|
69
165
|
* Returns sentences for the outcome comment (a refused status move); empty
|
|
70
166
|
* when there is nothing to say. Safe to repeat (a retried completion): each
|
|
@@ -77,8 +173,11 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
77
173
|
const notes = [];
|
|
78
174
|
try {
|
|
79
175
|
let newlyOpened = false;
|
|
80
|
-
|
|
81
|
-
|
|
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];
|
|
82
181
|
if (state === "created" && pr.outcome === "pull_request_opened")
|
|
83
182
|
newlyOpened = true;
|
|
84
183
|
if (state !== "created" && state !== "open")
|
|
@@ -95,15 +194,19 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
95
194
|
}
|
|
96
195
|
}
|
|
97
196
|
const target = input.onPullRequestOpened;
|
|
197
|
+
let movedTo = null;
|
|
98
198
|
if (target && newlyOpened) {
|
|
99
199
|
try {
|
|
100
|
-
await tracker.transitionTo(input.issueKey, target);
|
|
200
|
+
const moved = await tracker.transitionTo(input.issueKey, target);
|
|
201
|
+
movedTo = moved.toStatus || target;
|
|
101
202
|
}
|
|
102
203
|
catch (err) {
|
|
103
204
|
log.warn({ err, issueKey: input.issueKey, target }, "could not move the issue after a pull request opened");
|
|
104
205
|
notes.push(`Could not move ${input.issueKey} to "${target}"; it may need a manual move.`);
|
|
105
206
|
}
|
|
106
207
|
}
|
|
208
|
+
// Only pairs this call newly recorded, so a retried completion does not notify twice. Never throws.
|
|
209
|
+
await emitNewlyOpened(issue, records, states, movedTo);
|
|
107
210
|
}
|
|
108
211
|
catch (err) {
|
|
109
212
|
log.warn({ err, issueKey: input.issueKey }, "could not bridge the pull requests to the issue");
|
|
@@ -112,8 +215,9 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
112
215
|
}
|
|
113
216
|
/**
|
|
114
217
|
* A pull request wardby recorded against an issue was merged or closed: marks
|
|
115
|
-
* each still-open pair
|
|
116
|
-
*
|
|
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
|
|
117
221
|
* applies the link's onPullRequestMerged move). Only rows wardby wrote are
|
|
118
222
|
* touched, matched by the host's own identity for the PR — nothing from the
|
|
119
223
|
* PR's text. The row is claimed first (open → merged/closed), so a duplicate
|
|
@@ -122,12 +226,32 @@ export async function recordPullRequests(db, tracker, input) {
|
|
|
122
226
|
* delivery is rolled back and redelivered; never throws after that.
|
|
123
227
|
*/
|
|
124
228
|
export async function handlePullRequestClosed(db, trackers, pr) {
|
|
125
|
-
if (!trackers)
|
|
126
|
-
return;
|
|
127
229
|
const where = { codeProvider: pr.codeProvider, repository: pr.repository, number: pr.number };
|
|
128
230
|
// Not caught: nothing is claimed yet, and a throw rolls back the delivery so it is redelivered.
|
|
129
|
-
|
|
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
|
+
});
|
|
130
237
|
for (const row of rows) {
|
|
238
|
+
// Exactly once per claimed row, from the finally below, even when a later step throws: the row is no
|
|
239
|
+
// longer open, so nothing would retry it. Never throws.
|
|
240
|
+
const emitClosed = (movedTo) => emitWorkflowEvent({
|
|
241
|
+
dedupeKey: dedupeKeys.prClosed(pr.codeProvider, pr.repository, pr.number),
|
|
242
|
+
agentId: row.agentId,
|
|
243
|
+
workItem: { provider: row.issueProvider, key: row.issueKey },
|
|
244
|
+
pullRequest: { codeProvider: pr.codeProvider, repository: pr.repository, number: pr.number },
|
|
245
|
+
payload: {
|
|
246
|
+
kind: "pr_closed",
|
|
247
|
+
prLabel: `${row.repository}#${row.number}`,
|
|
248
|
+
prUrl: row.url,
|
|
249
|
+
merged: pr.merged,
|
|
250
|
+
movedTo,
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
let claimedRow = false;
|
|
254
|
+
let movedTo = null;
|
|
131
255
|
try {
|
|
132
256
|
const claimed = await db.issuePullRequest.updateMany({
|
|
133
257
|
where: { id: row.id, state: "open" },
|
|
@@ -135,7 +259,9 @@ export async function handlePullRequestClosed(db, trackers, pr) {
|
|
|
135
259
|
});
|
|
136
260
|
if (claimed.count === 0)
|
|
137
261
|
continue;
|
|
138
|
-
|
|
262
|
+
claimedRow = true;
|
|
263
|
+
// A pair with no configured tracker (a GitHub issue's, say) is only marked.
|
|
264
|
+
const tracker = trackers?.[row.issueProvider];
|
|
139
265
|
if (!tracker)
|
|
140
266
|
continue;
|
|
141
267
|
const link = await db.agentIssueProject.findUnique({
|
|
@@ -166,6 +292,7 @@ export async function handlePullRequestClosed(db, trackers, pr) {
|
|
|
166
292
|
if (target) {
|
|
167
293
|
try {
|
|
168
294
|
const moved = await tracker.transitionTo(row.issueKey, target);
|
|
295
|
+
movedTo = moved.toStatus;
|
|
169
296
|
markdown += ` Moved to ${moved.toStatus}.`;
|
|
170
297
|
}
|
|
171
298
|
catch (err) {
|
|
@@ -185,5 +312,9 @@ export async function handlePullRequestClosed(db, trackers, pr) {
|
|
|
185
312
|
catch (err) {
|
|
186
313
|
log.warn({ err, issueKey: row.issueKey, ...where }, "could not bridge the closed pull request to the issue");
|
|
187
314
|
}
|
|
315
|
+
finally {
|
|
316
|
+
if (claimedRow)
|
|
317
|
+
await emitClosed(movedTo);
|
|
318
|
+
}
|
|
188
319
|
}
|
|
189
320
|
}
|
|
@@ -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,11 +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
|
+
import { dedupeKeys, emitWorkflowEvent } from "./workflow-events.js";
|
|
7
8
|
const log = logger.child({ module: "issue-events" });
|
|
8
9
|
const MAX_TASK_BODY = 8000;
|
|
9
|
-
const RUN_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
10
10
|
/** Only admin-configured values (trigger labels, the target status) appear here: never free text from the actor. */
|
|
11
11
|
function describeKind(event, kind, link) {
|
|
12
12
|
switch (kind) {
|
|
@@ -44,14 +44,9 @@ export function issueTaskText(event, matched, issueUrl, link, openPrs = []) {
|
|
|
44
44
|
"do not also post it with jira_comment; use jira_comment only for other issues or progress notes on long work.",
|
|
45
45
|
];
|
|
46
46
|
// Control-plane data from stored rows (validated here), never issue text.
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
sections.push(
|
|
50
|
-
`(https://github.com/${pr.repository}/pull/${pr.number}). ` +
|
|
51
|
-
`To revise it, delegate with continuePriorRun set to exactly "${pr.openedByRunId}".`);
|
|
52
|
-
}
|
|
53
|
-
if (hinted.length > 0)
|
|
54
|
-
sections.push(SIBLING_GUIDANCE);
|
|
47
|
+
const hints = openPullRequestHints(openPrs);
|
|
48
|
+
if (hints)
|
|
49
|
+
sections.push(hints);
|
|
55
50
|
if (matched.includes("mention") && event.comment) {
|
|
56
51
|
sections.push(`Request comment:\n${event.comment.body.slice(0, MAX_TASK_BODY)}`);
|
|
57
52
|
}
|
|
@@ -93,7 +88,7 @@ export async function routeIssueEvent(event, deps) {
|
|
|
93
88
|
return result;
|
|
94
89
|
const links = (await deps.db.agentIssueProject.findMany({
|
|
95
90
|
where: { provider: event.provider, projectKey: event.projectKey },
|
|
96
|
-
include: { agent: { select: { ownerId: true, kind: true } } },
|
|
91
|
+
include: { agent: { select: { ownerId: true, kind: true, name: true } } },
|
|
97
92
|
}));
|
|
98
93
|
const bot = await tracker.botAccountId();
|
|
99
94
|
// One snapshot per event, taken lazily on the first dispatch so an event no link matches costs nothing.
|
|
@@ -139,6 +134,16 @@ export async function routeIssueEvent(event, deps) {
|
|
|
139
134
|
const runId = dispatched.run.id;
|
|
140
135
|
result.runIds.push(runId);
|
|
141
136
|
result.followUps.push(() => postIssueWorkingStatus(deps.db, deps.trackers, runId));
|
|
137
|
+
// describeKind shows only admin-configured values, so the trigger is safe to show in chat.
|
|
138
|
+
const trigger = matched.map((k) => describeKind(event, k, link)).join("; ");
|
|
139
|
+
const agentName = link.agent.name;
|
|
140
|
+
result.followUps.push(() => emitWorkflowEvent({
|
|
141
|
+
dedupeKey: dedupeKeys.issuePickedUp(runId),
|
|
142
|
+
runId,
|
|
143
|
+
agentId: link.agentId,
|
|
144
|
+
workItem: { provider: event.provider, key: event.issueKey },
|
|
145
|
+
payload: { kind: "issue_picked_up", agentName, trigger },
|
|
146
|
+
}));
|
|
142
147
|
log.info({ issueKey: event.issueKey, agentId: link.agentId, runId, kinds: matched }, "issue run dispatched");
|
|
143
148
|
}
|
|
144
149
|
catch (err) {
|
|
@@ -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"]);
|
|
@@ -22,12 +22,23 @@ export function toJiraMarkdown(text) {
|
|
|
22
22
|
export function issueStatusRow(event, runId, visibilityRole) {
|
|
23
23
|
return { runId, provider: "jira", issueKey: event.issueKey, visibilityRole };
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Cents from $1 up ($12.34, $1234.50); below $1, two significant digits with at
|
|
27
|
+
* least two decimals so fractions of a cent stay readable ($0.50, $0.12, $0.0035).
|
|
28
|
+
* Never exponent form.
|
|
29
|
+
*/
|
|
30
|
+
const usd = (amount) => {
|
|
31
|
+
const abs = Math.abs(amount);
|
|
32
|
+
const decimals = abs === 0 || abs >= 1 ? 2 : Math.max(2, 1 - Math.floor(Math.log10(abs)));
|
|
33
|
+
// Trailing zeros past the cents are noise ($0.010, $0.100 from rounding up).
|
|
34
|
+
return `$${amount.toFixed(Math.min(decimals, 20)).replace(/(\.\d\d\d*?)0+$/, "$1")}`;
|
|
35
|
+
};
|
|
25
36
|
export function formatSpendLine(input) {
|
|
26
|
-
const parts = [`Agent spend:
|
|
37
|
+
const parts = [`Agent spend: ${usd(input.treeUsd)} this run`];
|
|
27
38
|
if (input.issueUsd !== null)
|
|
28
|
-
parts.push(
|
|
39
|
+
parts.push(`${usd(input.issueUsd)} on this issue so far`);
|
|
29
40
|
if (input.models.length > 0)
|
|
30
|
-
parts.push(input.models.map((m) => `${m.model}
|
|
41
|
+
parts.push(input.models.map((m) => `${m.model} ${usd(m.costUsd)}`).join(", "));
|
|
31
42
|
return parts.join(" · ");
|
|
32
43
|
}
|
|
33
44
|
/** The whole run tree under `runId` (every depth), the issue's total across all its runs, and the tree's models. */
|
|
@@ -115,26 +126,6 @@ async function currentLink(db, runId, issueKey, provider) {
|
|
|
115
126
|
});
|
|
116
127
|
return link ? { agentId: run.agentId, ...link } : null;
|
|
117
128
|
}
|
|
118
|
-
/**
|
|
119
|
-
* The coding runs (of `runIds`) that continued a pull request opened for a
|
|
120
|
-
* different issue: their PR belongs to that issue, not this one. A continued
|
|
121
|
-
* PR with no issue, or this same issue, is fine.
|
|
122
|
-
*/
|
|
123
|
-
async function continuedForAnotherIssue(db, runIds, issue) {
|
|
124
|
-
if (runIds.length === 0)
|
|
125
|
-
return new Set();
|
|
126
|
-
const rows = await db.codingRun.findMany({
|
|
127
|
-
where: { runId: { in: runIds } },
|
|
128
|
-
select: { runId: true, rootCodingRun: { select: { issueProvider: true, issueKey: true } } },
|
|
129
|
-
});
|
|
130
|
-
return new Set(rows
|
|
131
|
-
.filter(({ rootCodingRun: root }) => {
|
|
132
|
-
if (!root?.issueKey)
|
|
133
|
-
return false;
|
|
134
|
-
return root.issueKey !== issue.issueKey || root.issueProvider !== issue.provider;
|
|
135
|
-
})
|
|
136
|
-
.map((row) => row.runId));
|
|
137
|
-
}
|
|
138
129
|
export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
139
130
|
if (!trackers)
|
|
140
131
|
return;
|
|
@@ -153,9 +144,10 @@ export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
|
153
144
|
const writable = link?.access === "write";
|
|
154
145
|
const project = projectOf(status.issueKey);
|
|
155
146
|
let body;
|
|
147
|
+
let fullReply = null;
|
|
156
148
|
if (writable) {
|
|
157
|
-
const { pullRequests, failedChildren, budgetSentence } = await collectRunOutcome(db, run);
|
|
158
|
-
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 });
|
|
159
151
|
for (const runId of foreign) {
|
|
160
152
|
log.info({ runId: run.id, codingRunId: runId, issueKey: status.issueKey }, "not linking a pull request continued from another issue's run");
|
|
161
153
|
}
|
|
@@ -180,9 +172,18 @@ export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
|
180
172
|
pullRequests: bridged,
|
|
181
173
|
})
|
|
182
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);
|
|
183
179
|
const outcome = outcomeBody(run, "", pullRequests, failedChildren, {
|
|
184
180
|
budgetSentence,
|
|
181
|
+
packageRefusals,
|
|
182
|
+
packageAudit,
|
|
183
|
+
noChanges,
|
|
184
|
+
fullReplyFollows: true,
|
|
185
185
|
noPullRequestText: "Done.",
|
|
186
|
+
fromIssue: true,
|
|
186
187
|
// One comment per request: this status comment carries the agent's answer.
|
|
187
188
|
replyAsAnswer: true,
|
|
188
189
|
});
|
|
@@ -210,12 +211,50 @@ export async function completeIssueStatus(db, run, trackers, opts = {}) {
|
|
|
210
211
|
}
|
|
211
212
|
// Unlinked or read-only with no status comment yet: complete the row
|
|
212
213
|
// without posting; never create content where the agent may not write.
|
|
213
|
-
|
|
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
|
+
}
|
|
214
228
|
}
|
|
215
229
|
catch (err) {
|
|
216
230
|
log.warn({ err, runId: run.id }, "could not complete the issue status comment");
|
|
217
231
|
}
|
|
218
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
|
+
}
|
|
219
258
|
export async function closeOrphanedIssueStatuses(db, trackers, now = new Date()) {
|
|
220
259
|
const providers = Object.keys(trackers ?? {});
|
|
221
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>;
|