@wardby/cli 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -5
- package/README.md +6 -1
- package/deploy/local/docker-compose.quickstart-coding.yml +19 -0
- package/dist/claude-coding-worker/driver.d.ts +33 -3
- package/dist/claude-coding-worker/driver.js +151 -21
- package/dist/claude-coding-worker/main.js +38 -6
- package/dist/claude-coding-worker/sdk.js +29 -2
- package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
- package/dist/claude-coding-worker/tool-socket.js +111 -0
- package/dist/claude-coding-worker/transcript.d.ts +18 -0
- package/dist/claude-coding-worker/transcript.js +77 -0
- package/dist/claude-plugin/command.d.ts +61 -0
- package/dist/claude-plugin/command.js +376 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +3 -1
- package/dist/cli.js +71 -13
- package/dist/coding/code-host.d.ts +16 -0
- package/dist/coding/code-host.js +60 -0
- package/dist/coding/continuation-wording.d.ts +35 -0
- package/dist/coding/continuation-wording.js +73 -0
- package/dist/coding/linked-issue-note.d.ts +23 -0
- package/dist/coding/linked-issue-note.js +47 -0
- package/dist/coding/mcp-token.d.ts +12 -0
- package/dist/coding/mcp-token.js +26 -0
- package/dist/coding/merge-wording.d.ts +28 -0
- package/dist/coding/merge-wording.js +78 -0
- package/dist/coding/pr-description-note.d.ts +9 -0
- package/dist/coding/pr-description-note.js +32 -0
- package/dist/coding/profile.d.ts +46 -126
- package/dist/coding/profile.js +45 -4
- package/dist/coding/protected-path-wording.d.ts +8 -0
- package/dist/coding/protected-path-wording.js +1 -1
- package/dist/coding/protocol.d.ts +264 -346
- package/dist/coding/protocol.js +237 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +17 -0
- package/dist/coding/registry/allowlist.d.ts +12 -0
- package/dist/coding/registry/allowlist.js +14 -1
- package/dist/coding/registry/audit-mode.d.ts +153 -0
- package/dist/coding/registry/audit-mode.js +304 -0
- package/dist/coding/registry/lockfile-shared.d.ts +36 -0
- package/dist/coding/registry/lockfile-shared.js +128 -0
- package/dist/coding/registry/lockfiles.js +1 -1
- package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
- package/dist/coding/registry/npm-lockfile-formats.js +41 -0
- package/dist/coding/registry/npm-lockfile.d.ts +8 -4
- package/dist/coding/registry/npm-lockfile.js +4 -6
- package/dist/coding/registry/npm.js +78 -8
- package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
- package/dist/coding/registry/pnpm-lockfile.js +189 -0
- package/dist/coding/registry/pypi-plan.d.ts +50 -0
- package/dist/coding/registry/pypi-plan.js +406 -0
- package/dist/coding/registry/pypi-requirements.d.ts +58 -0
- package/dist/coding/registry/pypi-requirements.js +155 -0
- package/dist/coding/registry/pypi.d.ts +3 -27
- package/dist/coding/registry/pypi.js +40 -154
- package/dist/coding/registry/refusal-hints.d.ts +20 -0
- package/dist/coding/registry/refusal-hints.js +61 -0
- package/dist/coding/registry/refusal-wording.d.ts +11 -0
- package/dist/coding/registry/refusal-wording.js +56 -0
- package/dist/coding/registry/report.d.ts +70 -8
- package/dist/coding/registry/report.js +112 -5
- package/dist/coding/registry/types.d.ts +58 -8
- package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
- package/dist/coding/registry/yarn-lockfile.js +367 -0
- package/dist/coding/services/catalog.d.ts +37 -351
- package/dist/coding/transcript/claude-code.d.ts +13 -0
- package/dist/coding/transcript/claude-code.js +273 -0
- package/dist/coding/transcript/download-protocol.d.ts +30 -0
- package/dist/coding/transcript/download-protocol.js +18 -0
- package/dist/coding/transcript/format.d.ts +20 -0
- package/dist/coding/transcript/format.js +32 -0
- package/dist/coding/transcript/recorder.d.ts +52 -0
- package/dist/coding/transcript/recorder.js +225 -0
- package/dist/coding/transcript/resume/checkout.d.ts +31 -0
- package/dist/coding/transcript/resume/checkout.js +203 -0
- package/dist/coding/transcript/resume/command.d.ts +17 -0
- package/dist/coding/transcript/resume/command.js +176 -0
- package/dist/coding/transcript/resume/download.d.ts +20 -0
- package/dist/coding/transcript/resume/download.js +153 -0
- package/dist/coding/transcript/resume/launch.d.ts +38 -0
- package/dist/coding/transcript/resume/launch.js +128 -0
- package/dist/coding/transcript/resume/session-file.d.ts +13 -0
- package/dist/coding/transcript/resume/session-file.js +79 -0
- package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
- package/dist/coding/transcript/resume/stand-in.js +49 -0
- package/dist/coding-worker/artifact.d.ts +8 -3
- package/dist/coding-worker/artifact.js +3 -1
- package/dist/coding-worker/debug-trace.d.ts +9 -6
- package/dist/coding-worker/debug-trace.js +16 -19
- package/dist/coding-worker/dependency-cache.d.mts +229 -0
- package/dist/coding-worker/dependency-cache.mjs +2123 -0
- package/dist/coding-worker/driver.d.ts +4 -3
- package/dist/coding-worker/driver.js +124 -39
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/main.js +5 -1
- package/dist/coding-worker/mcp-config.d.ts +27 -0
- package/dist/coding-worker/mcp-config.js +32 -0
- package/dist/coding-worker/sdk.d.ts +36 -0
- package/dist/coding-worker/sdk.js +28 -1
- package/dist/coding-worker/task-note.d.ts +11 -0
- package/dist/coding-worker/task-note.js +13 -0
- package/dist/coding-worker/types.d.ts +15 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/mcp-call-limit.d.ts +8 -0
- package/dist/config/mcp-call-limit.js +18 -0
- package/dist/config/mcp-servers.d.ts +8 -0
- package/dist/config/mcp-servers.js +12 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +92 -0
- package/dist/config/test-simulators.js +333 -0
- package/dist/config/tool-timeout.d.ts +1 -0
- package/dist/config/tool-timeout.js +18 -0
- package/dist/core/async-context.d.ts +2 -0
- package/dist/core/async-context.js +12 -0
- package/dist/core/budget-events.d.ts +108 -0
- package/dist/core/budget-events.js +346 -0
- package/dist/core/budget-groups.d.ts +50 -1
- package/dist/core/budget-groups.js +236 -27
- package/dist/core/budget-stopped-head.d.ts +46 -0
- package/dist/core/budget-stopped-head.js +81 -0
- package/dist/core/budget-topup.d.ts +51 -0
- package/dist/core/budget-topup.js +156 -0
- package/dist/core/budget-wording.d.ts +16 -2
- package/dist/core/budget-wording.js +40 -2
- package/dist/core/coding-mcp.d.ts +36 -0
- package/dist/core/coding-mcp.js +253 -0
- package/dist/core/coding-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -0
- package/dist/core/coding-repository.d.ts +46 -0
- package/dist/core/coding-repository.js +92 -0
- package/dist/core/cron.d.ts +19 -1
- package/dist/core/cron.js +17 -0
- package/dist/core/datastores.js +1 -1
- package/dist/core/deferred-coding.d.ts +14 -0
- package/dist/core/deferred-coding.js +62 -0
- package/dist/core/delegation-child.d.ts +25 -0
- package/dist/core/delegation-child.js +37 -0
- package/dist/core/delegation-slots.d.ts +27 -0
- package/dist/core/delegation-slots.js +44 -0
- package/dist/core/dispatch.d.ts +48 -2
- package/dist/core/dispatch.js +166 -66
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +169 -0
- package/dist/core/grants.d.ts +46 -8
- package/dist/core/grants.js +99 -8
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +291 -27
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +300 -22
- package/dist/core/issue-bridge.d.ts +50 -6
- package/dist/core/issue-bridge.js +124 -33
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +4 -10
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +58 -29
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +14 -1
- package/dist/core/lost-run-children.d.ts +6 -0
- package/dist/core/lost-run-children.js +32 -0
- package/dist/core/mark-ready.d.ts +34 -0
- package/dist/core/mark-ready.js +152 -0
- package/dist/core/markdown-code.d.ts +8 -0
- package/dist/core/markdown-code.js +107 -0
- package/dist/core/mcp-client/client.d.ts +47 -0
- package/dist/core/mcp-client/client.js +141 -0
- package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
- package/dist/core/mcp-client/jsonrpc.js +54 -0
- package/dist/core/mcp-client/results.d.ts +13 -0
- package/dist/core/mcp-client/results.js +42 -0
- package/dist/core/mcp-servers.d.ts +90 -0
- package/dist/core/mcp-servers.js +230 -0
- package/dist/core/mcp-tools.d.ts +108 -0
- package/dist/core/mcp-tools.js +287 -0
- package/dist/core/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +44 -18
- package/dist/core/notification-dispatcher.js +2 -1
- package/dist/core/notification-templates.d.ts +1 -7
- package/dist/core/notification-templates.js +36 -2
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +4 -3
- package/dist/core/reconciler.js +8 -1
- package/dist/core/related-pull-requests.d.ts +11 -3
- package/dist/core/related-pull-requests.js +49 -20
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/review-fix.d.ts +1 -1
- package/dist/core/review-fix.js +4 -3
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +3 -0
- package/dist/core/review-host-tools.js +102 -14
- package/dist/core/review-reads.d.ts +55 -0
- package/dist/core/review-reads.js +233 -0
- package/dist/core/run-status.d.ts +12 -0
- package/dist/core/run-status.js +12 -0
- package/dist/core/runner.d.ts +145 -49
- package/dist/core/runner.js +719 -216
- package/dist/core/schedule-start.d.ts +12 -0
- package/dist/core/schedule-start.js +14 -0
- package/dist/core/secret-broker-config.d.ts +12 -74
- package/dist/core/secret-broker-config.js +1 -1
- package/dist/core/secret-guard.d.ts +49 -0
- package/dist/core/secret-guard.js +119 -0
- package/dist/core/secret-guarded-stores.d.ts +12 -0
- package/dist/core/secret-guarded-stores.js +41 -0
- package/dist/core/secret-spans.d.ts +50 -0
- package/dist/core/secret-spans.js +94 -0
- package/dist/core/secrets.d.ts +11 -1
- package/dist/core/secrets.js +27 -1
- package/dist/core/serializable-retry.d.ts +18 -0
- package/dist/core/serializable-retry.js +43 -0
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/tool-admin.d.ts +5 -1
- package/dist/core/tool-admin.js +7 -2
- package/dist/core/tool-names.d.ts +13 -0
- package/dist/core/tool-names.js +20 -0
- package/dist/core/webhooks.d.ts +4 -0
- package/dist/core/webhooks.js +68 -49
- package/dist/core/workflow-events.d.ts +14 -2
- package/dist/core/workflow-events.js +4 -0
- package/dist/core/workflow-run-events.d.ts +5 -3
- package/dist/core/workflow-run-events.js +45 -9
- package/dist/core/zod-json-schema.d.ts +4 -0
- package/dist/core/zod-json-schema.js +39 -0
- package/dist/core/zod3-window.d.ts +35 -0
- package/dist/core/zod3-window.js +124 -0
- package/dist/generated/prisma/browser.d.ts +65 -3
- package/dist/generated/prisma/client.d.ts +65 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +266 -106
- package/dist/generated/prisma/enums.d.ts +10 -0
- package/dist/generated/prisma/enums.js +8 -0
- package/dist/generated/prisma/internal/class.d.ts +110 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +957 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +166 -2
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +174 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +166 -2
- package/dist/generated/prisma/models/Agent.d.ts +377 -8
- package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
- package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +81 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +228 -7
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +232 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1712 -1
- package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
- package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
- package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
- package/dist/generated/prisma/models/HostProvider.js +1 -0
- package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
- package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
- package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
- package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
- package/dist/generated/prisma/models/McpServer.js +1 -0
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +77 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- package/dist/generated/prisma/models/Principal.d.ts +167 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
- package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
- package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
- package/dist/generated/prisma/models/Run.d.ts +738 -2
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
- package/dist/generated/prisma/models/RunTranscript.js +1 -0
- package/dist/generated/prisma/models/Secret.d.ts +387 -0
- package/dist/generated/prisma/models/Tool.d.ts +223 -1
- package/dist/generated/prisma/models.d.ts +10 -0
- package/dist/help/search.js +12 -3
- package/dist/help-index.json +2033 -110
- package/dist/import/create.js +48 -4
- package/dist/import/neutral-schema.d.ts +51 -281
- package/dist/import/neutral-schema.js +7 -4
- package/dist/knowledge/check.d.ts +1 -1
- package/dist/knowledge/cli.d.ts +11 -1
- package/dist/knowledge/cli.js +37 -4
- package/dist/knowledge/concept.d.ts +3 -19
- package/dist/knowledge/location.d.ts +31 -0
- package/dist/knowledge/location.js +78 -0
- package/dist/mcp/auth/access.d.ts +10 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/grants-cli.d.ts +6 -4
- package/dist/mcp/auth/grants-cli.js +42 -3
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/resource-server.d.ts +3 -1
- package/dist/mcp/auth/resource-server.js +17 -2
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
- package/dist/mcp/context.d.ts +3 -0
- package/dist/mcp/host-events/github-ingress.d.ts +2 -0
- package/dist/mcp/host-events/github-ingress.js +2 -1
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +69 -10
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +33 -14
- package/dist/mcp/tools/agents.d.ts +4 -0
- package/dist/mcp/tools/agents.js +295 -28
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +73 -29
- package/dist/mcp/tools/host-providers.d.ts +2 -0
- package/dist/mcp/tools/host-providers.js +215 -0
- package/dist/mcp/tools/mcp-servers.d.ts +26 -0
- package/dist/mcp/tools/mcp-servers.js +481 -0
- package/dist/mcp/tools/memory.js +11 -1
- package/dist/mcp/tools/notification-channels.js +2 -2
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/repositories.js +65 -12
- package/dist/mcp/tools/run-access.d.ts +16 -0
- package/dist/mcp/tools/run-access.js +25 -0
- package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
- package/dist/mcp/tools/run-transcript-download.js +129 -0
- package/dist/mcp/tools/run-transcript.d.ts +19 -0
- package/dist/mcp/tools/run-transcript.js +70 -0
- package/dist/mcp/tools/runs.js +209 -27
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-elicitation-form.js +5 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -61
- package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
- package/dist/mcp/tools/secret-elicitation.js +25 -2
- package/dist/mcp/tools/secrets.js +40 -6
- package/dist/mcp/tools/stop-run.d.ts +2 -0
- package/dist/mcp/tools/stop-run.js +82 -0
- package/dist/mcp/tools/subagents.js +2 -2
- package/dist/mcp/tools/tools.d.ts +7 -5
- package/dist/mcp/tools/tools.js +64 -16
- package/dist/mcp/tools/trigger.js +28 -6
- package/dist/mcp/transport/http-limits.d.ts +2 -0
- package/dist/mcp/transport/http-limits.js +6 -2
- package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
- package/dist/mcp/transport/stdio-link-host.js +67 -0
- package/dist/mcp/transport/streamable-http.d.ts +13 -0
- package/dist/mcp/transport/streamable-http.js +41 -1
- package/dist/mcp/webhooks/ingress.js +10 -0
- package/dist/native-worker/docker-launcher.d.ts +38 -2
- package/dist/native-worker/docker-launcher.js +65 -5
- package/dist/native-worker/gateway-server.d.ts +55 -3
- package/dist/native-worker/gateway-server.js +152 -34
- package/dist/native-worker/gateway.d.ts +29 -1
- package/dist/native-worker/gateway.js +74 -4
- package/dist/native-worker/http-server.d.ts +7 -1
- package/dist/native-worker/http-server.js +62 -7
- package/dist/native-worker/http-transport.js +1 -1
- package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
- package/dist/native-worker/kubernetes-launcher.js +43 -3
- package/dist/native-worker/launch.d.ts +18 -1
- package/dist/native-worker/launch.js +6 -1
- package/dist/native-worker/ledger.d.ts +24 -4
- package/dist/native-worker/ledger.js +62 -8
- package/dist/native-worker/loopback.js +3 -8
- package/dist/native-worker/main.d.ts +2 -1
- package/dist/native-worker/main.js +14 -3
- package/dist/native-worker/protocol.d.ts +130 -577
- package/dist/native-worker/protocol.js +51 -2
- package/dist/native-worker/sandbox-executor.d.ts +17 -2
- package/dist/native-worker/sandbox-executor.js +78 -4
- package/dist/native-worker/stderr-redaction.d.ts +77 -0
- package/dist/native-worker/stderr-redaction.js +237 -0
- package/dist/native-worker/stdio.d.ts +1 -1
- package/dist/native-worker/stdio.js +6 -5
- package/dist/native-worker/warm-pool.d.ts +2 -2
- package/dist/native-worker/warm-pool.js +4 -4
- package/dist/native-worker/worker.js +28 -2
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/self-hosted.d.ts +1 -1
- package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
- package/dist/providers/coding-proxy/capability-hash.js +5 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
- package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
- package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
- package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
- package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
- package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
- package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
- package/dist/providers/coding-proxy/hold.d.ts +32 -0
- package/dist/providers/coding-proxy/hold.js +86 -0
- package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
- package/dist/providers/coding-proxy/interrupted.js +104 -0
- package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
- package/dist/providers/coding-proxy/mcp-route.js +166 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -2
- package/dist/providers/coding-proxy/memory-ledger.js +99 -8
- package/dist/providers/coding-proxy/metering.d.ts +16 -0
- package/dist/providers/coding-proxy/metering.js +27 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +16 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +209 -69
- package/dist/providers/coding-proxy/proxy.d.ts +21 -2
- package/dist/providers/coding-proxy/proxy.js +300 -48
- package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
- package/dist/providers/coding-proxy/registry/audit.js +94 -17
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
- package/dist/providers/coding-proxy/registry/plan.js +201 -48
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
- package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
- package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
- package/dist/providers/coding-proxy/registry/service.js +579 -112
- package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
- package/dist/providers/coding-proxy/registry/store.js +54 -1
- package/dist/providers/coding-proxy/runtime.d.ts +10 -0
- package/dist/providers/coding-proxy/runtime.js +109 -16
- package/dist/providers/coding-proxy/server.d.ts +9 -1
- package/dist/providers/coding-proxy/server.js +55 -1
- package/dist/providers/coding-proxy/types.d.ts +78 -1
- package/dist/providers/datastore/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +17 -2
- package/dist/providers/engine/types.js +17 -0
- package/dist/providers/executor/composition.d.ts +10 -3
- package/dist/providers/executor/composition.js +52 -7
- package/dist/providers/executor/container.d.ts +394 -9
- package/dist/providers/executor/container.js +1210 -96
- package/dist/providers/executor/dbos-status.d.ts +31 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +50 -1
- package/dist/providers/executor/dbos.js +207 -20
- package/dist/providers/executor/deferred.d.ts +12 -24
- package/dist/providers/executor/deferred.js +10 -29
- package/dist/providers/executor/in-process.d.ts +9 -1
- package/dist/providers/executor/in-process.js +14 -4
- package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
- package/dist/providers/executor/linked-issue-reader.js +30 -0
- package/dist/providers/executor/routing.d.ts +2 -0
- package/dist/providers/executor/routing.js +4 -0
- package/dist/providers/executor/types.d.ts +13 -0
- package/dist/providers/host-tools/invoke.d.ts +37 -0
- package/dist/providers/host-tools/invoke.js +117 -0
- package/dist/providers/host-tools/operations.d.ts +65 -0
- package/dist/providers/host-tools/operations.js +149 -0
- package/dist/providers/host-tools/registry.d.ts +79 -0
- package/dist/providers/host-tools/registry.js +362 -0
- package/dist/providers/host-tools/request-guard.d.ts +17 -0
- package/dist/providers/host-tools/request-guard.js +99 -0
- package/dist/providers/host-tools/self-test.d.ts +64 -0
- package/dist/providers/host-tools/self-test.js +142 -0
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/issue-tracker/types.d.ts +17 -0
- package/dist/providers/issue-tracker/types.js +39 -1
- package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
- package/dist/providers/jobs/claude-tool-setup.js +5 -2
- package/dist/providers/jobs/docker-isolation.d.ts +10 -2
- package/dist/providers/jobs/docker-isolation.js +47 -8
- package/dist/providers/jobs/docker.d.ts +9 -0
- package/dist/providers/jobs/docker.js +60 -11
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
- package/dist/providers/jobs/kubernetes-api.js +10 -0
- package/dist/providers/jobs/kubernetes-client.js +10 -1
- package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
- package/dist/providers/jobs/kubernetes-isolation.js +32 -3
- package/dist/providers/jobs/kubernetes.d.ts +11 -1
- package/dist/providers/jobs/kubernetes.js +111 -17
- package/dist/providers/jobs/types.d.ts +39 -0
- package/dist/providers/jobs/types.js +13 -1
- package/dist/providers/llm/anthropic.js +5 -1
- package/dist/providers/llm/bedrock.d.ts +0 -12
- package/dist/providers/llm/bedrock.js +4 -0
- package/dist/providers/llm/claude-messages.d.ts +3 -1
- package/dist/providers/llm/claude-messages.js +4 -1
- package/dist/providers/llm/claude-provider.d.ts +2 -2
- package/dist/providers/llm/claude-provider.js +2 -2
- package/dist/providers/llm/openai.d.ts +2 -2
- package/dist/providers/llm/openai.js +6 -2
- package/dist/providers/llm/routing.d.ts +2 -2
- package/dist/providers/llm/routing.js +2 -2
- package/dist/providers/llm/types.d.ts +12 -2
- package/dist/providers/review-host/github-events.d.ts +9 -1
- package/dist/providers/review-host/github-events.js +34 -12
- package/dist/providers/review-host/github.d.ts +29 -2
- package/dist/providers/review-host/github.js +224 -29
- package/dist/providers/review-host/local.d.ts +8 -4
- package/dist/providers/review-host/local.js +49 -31
- package/dist/providers/review-host/patch-pages.d.ts +41 -0
- package/dist/providers/review-host/patch-pages.js +176 -0
- package/dist/providers/review-host/review-format.d.ts +19 -1
- package/dist/providers/review-host/review-format.js +38 -7
- package/dist/providers/review-host/types.d.ts +140 -6
- package/dist/providers/review-host/types.js +9 -1
- package/dist/providers/storage/gcs.d.ts +63 -0
- package/dist/providers/storage/gcs.js +69 -0
- package/dist/providers/storage/index.d.ts +15 -0
- package/dist/providers/storage/index.js +14 -0
- package/dist/providers/storage/local.d.ts +24 -0
- package/dist/providers/storage/local.js +92 -0
- package/dist/providers/storage/meter.d.ts +14 -0
- package/dist/providers/storage/meter.js +34 -0
- package/dist/providers/storage/s3.d.ts +41 -0
- package/dist/providers/storage/s3.js +107 -0
- package/dist/providers/storage/types.d.ts +37 -3
- package/dist/providers/storage/types.js +21 -4
- package/dist/providers/vcs/git.d.ts +39 -4
- package/dist/providers/vcs/git.js +339 -26
- package/dist/providers/vcs/github-remote.d.ts +26 -3
- package/dist/providers/vcs/github-remote.js +124 -14
- package/dist/providers/vcs/github.d.ts +183 -44
- package/dist/providers/vcs/github.js +455 -56
- package/dist/providers/vcs/index.d.ts +1 -1
- package/dist/providers/vcs/index.js +9 -2
- package/dist/providers/vcs/pr-description.d.ts +127 -0
- package/dist/providers/vcs/pr-description.js +270 -0
- package/dist/providers/vcs/remote.d.ts +37 -1
- package/dist/providers/vcs/remote.js +7 -1
- package/dist/providers/vcs/routing.d.ts +16 -8
- package/dist/providers/vcs/routing.js +27 -6
- package/dist/providers/vcs/types.d.ts +150 -5
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- package/dist/quickstart/index.d.ts +5 -0
- package/dist/quickstart/index.js +21 -0
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +6 -6
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/eval-core.d.ts +12 -2
- package/dist/sandbox/eval-core.js +20 -4
- package/dist/sandbox/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +5 -0
- package/dist/sandbox/host-functions.js +13 -13
- package/dist/sandbox/limits.d.ts +4 -1
- package/dist/sandbox/limits.js +4 -1
- package/dist/sandbox/run-in-sandbox.d.ts +6 -0
- package/dist/sandbox/run-in-sandbox.js +14 -2
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +1 -1
- package/dist/sandbox/secret-broker.d.ts +1 -0
- package/dist/sandbox/secret-broker.js +4 -5
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/tool-timeout.d.ts +32 -0
- package/dist/sandbox/tool-timeout.js +52 -0
- package/dist/sandbox/user-tool.d.ts +8 -1
- package/dist/sandbox/user-tool.js +9 -3
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +8 -1
- package/dist/viewer/api-schema.d.ts +349 -2627
- package/dist/viewer/api-schema.js +7 -0
- package/dist/viewer/build-schemas.js +6 -2
- package/dist/viewer/graph.js +2 -1
- package/dist/viewer/openapi.js +2 -4
- package/dist/wardby-bin.js +15 -0
- package/docs/README.md +11 -1
- package/docs/agent-recipes.md +95 -24
- package/docs/architecture-runtime.md +1 -1
- package/docs/claude-code-plugin.md +164 -0
- package/docs/code-review-agents.md +557 -41
- package/docs/coding-agent-setup.md +566 -8
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +24 -2
- package/docs/coding-worker-isolation.md +183 -37
- package/docs/debugging-agent-runs.md +242 -0
- package/docs/getting-started-gke.md +129 -141
- package/docs/getting-started-identity-provider.md +53 -38
- package/docs/getting-started.md +17 -0
- package/docs/host-providers.md +294 -0
- package/docs/jira-agents.md +17 -8
- package/docs/knowledge/blob-not-found-semantics.md +41 -0
- package/docs/knowledge/bounded-file-descriptor.md +52 -0
- package/docs/knowledge/delegation-admission-slots.md +52 -0
- package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
- package/docs/knowledge/import-rename-target.md +52 -0
- package/docs/knowledge/index.md +57 -0
- package/docs/knowledge/log.md +9 -0
- package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
- package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
- package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
- package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
- package/docs/knowledge/overview-cli.md +74 -0
- package/docs/knowledge/overview-coding-proxy.md +72 -0
- package/docs/knowledge/overview-coding.md +72 -0
- package/docs/knowledge/overview-config.md +60 -0
- package/docs/knowledge/overview-core.md +72 -0
- package/docs/knowledge/overview-deploy.md +83 -0
- package/docs/knowledge/overview-mcp.md +61 -0
- package/docs/knowledge/overview-prisma.md +72 -0
- package/docs/knowledge/overview-providers.md +89 -0
- package/docs/knowledge/overview-sandbox.md +83 -0
- package/docs/knowledge/overview-surfaces.md +83 -0
- package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
- package/docs/knowledge/proxy-settlement-projections.md +41 -0
- package/docs/knowledge/run-pricing-first-writer.md +43 -0
- package/docs/knowledge/schedule-claim-transaction.md +41 -0
- package/docs/knowledge/secret-entry-replica-contract.md +52 -0
- package/docs/knowledge/terminal-run-first-writer.md +41 -0
- package/docs/knowledge/transactional-agent-authorization.md +52 -0
- package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
- package/docs/knowledge/warm-input-publication.md +30 -0
- package/docs/knowledge/workspace-staging-failure.md +54 -0
- package/docs/knowledge.md +54 -14
- package/docs/mcp-servers.md +254 -0
- package/docs/native-sandbox.md +143 -31
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +139 -29
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +45 -10
- package/docs/viewer-api.md +6 -0
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +28 -2
- package/help/agent-recipes.md +33 -2
- package/help/architecture-agent.md +11 -6
- package/help/brokered-secrets.md +3 -0
- package/help/build-claude-code-image.md +1 -1
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- package/help/claude-code-run-pane.md +40 -0
- package/help/code-review-agents.md +177 -6
- package/help/coding-packages.md +156 -6
- package/help/cost-attribution.md +9 -5
- package/help/creating-agents.md +14 -1
- package/help/dependency-cache.md +143 -0
- package/help/deploy-gke.md +15 -8
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-mcp-pins-unavailable.md +35 -0
- package/help/errors/coding-stream-quota-exceeded.md +33 -0
- package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
- package/help/errors/continuation-closed.md +9 -12
- package/help/errors/database-auth-invalid.md +1 -1
- package/help/errors/delegation-conflict.md +24 -0
- package/help/errors/file-list-truncated.md +45 -0
- package/help/errors/full-read-required.md +49 -0
- package/help/errors/github-account-not-allowed.md +4 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/host-provider-error.md +40 -0
- package/help/errors/host-tool-failed.md +36 -0
- package/help/errors/mcp-call-limit.md +22 -0
- package/help/errors/mcp-call-timeout.md +22 -0
- package/help/errors/mcp-server-auth-failed.md +22 -0
- package/help/errors/mcp-server-credentials-unavailable.md +45 -0
- package/help/errors/mcp-server-error.md +28 -0
- package/help/errors/mcp-server-unreachable.md +22 -0
- package/help/errors/mcp-servers-off.md +21 -0
- package/help/errors/mcp-tool-not-allowed.md +26 -0
- package/help/errors/mcp-tool-removed.md +22 -0
- package/help/errors/mcp-unavailable.md +25 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-capacity.md +1 -1
- package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
- package/help/errors/native-sandbox-docker-failed.md +1 -1
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
- package/help/errors/native-sandbox-image-not-pinned.md +1 -1
- package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-network-unenforced.md +1 -1
- package/help/errors/native-sandbox-requires-catalog.md +1 -1
- package/help/errors/native-sandbox-unavailable.md +1 -1
- package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
- package/help/errors/native-sandbox-worker-exited.md +4 -3
- package/help/errors/native-sandbox-worker-lost.md +1 -1
- package/help/errors/native-sandbox-worker-unready.md +1 -1
- package/help/errors/package-not-allowed-pending.md +52 -0
- package/help/errors/package-not-allowed.md +51 -0
- package/help/errors/package-refusals.md +43 -0
- package/help/errors/patch-cursor-malformed.md +31 -0
- package/help/errors/repository-not-listed.md +36 -0
- package/help/errors/repository-required.md +36 -0
- package/help/errors/run-lost.md +39 -0
- package/help/errors/run-transcript-download.md +44 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/target-merge.md +40 -0
- package/help/errors/tool-timeout.md +38 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/host-providers.md +40 -0
- package/help/identity-and-access.md +6 -1
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +1 -1
- package/help/low-power-mode.md +7 -1
- package/help/mcp-servers.md +73 -0
- package/help/mcp.md +7 -2
- package/help/merge-order-check.md +5 -0
- package/help/native-capabilities.md +55 -1
- package/help/native-sandbox.md +16 -2
- package/help/operating-agents.md +21 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +17 -10
- package/help/repo-instructions-and-skills.md +3 -1
- package/help/resume-runs-locally.md +134 -0
- package/help/review-fix-rounds.md +33 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +19 -5
- package/help/status-comments.md +31 -0
- package/help/stop-run.md +58 -0
- package/help/troubleshooting/budgets.md +28 -0
- package/help/troubleshooting/coding-workers.md +86 -7
- package/help/troubleshooting/debugging-agent-runs.md +29 -0
- package/package.json +18 -10
- package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
- package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
- package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
- package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
- package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
- package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
- package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
- package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
- package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
- package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
- package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
- package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
- package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
- package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
- package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
- package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
- package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
- package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
- package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
- package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
- package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
- package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
- package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
- package/prisma/schema.prisma +468 -109
- package/scripts/git-askpass.sh +1 -1
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -5,7 +5,7 @@ export { GitHubAppClient } from "./github.js";
|
|
|
5
5
|
export { GitVcsProvider, NodeGitCommandRunner } from "./git.js";
|
|
6
6
|
export { GitHubRemote } from "./github-remote.js";
|
|
7
7
|
export { LocalRemote } from "./local-remote.js";
|
|
8
|
-
export { RoutingVcsProvider, VCS_GITHUB_NOT_CONFIGURED_ERROR } from "./routing.js";
|
|
8
|
+
export { RoutingVcsProvider, VCS_GITHUB_NOT_CONFIGURED_ERROR, VCS_HOST_PROVIDER_NOT_CONFIGURED_ERROR, } from "./routing.js";
|
|
9
9
|
export type { GitRemote, PublishInput, PublishResult } from "./remote.js";
|
|
10
10
|
export interface BuildVcsProviderOptions {
|
|
11
11
|
/** Startup warnings; the module logger by default. */
|
|
@@ -7,13 +7,14 @@ import { GitHubRemote } from "./github-remote.js";
|
|
|
7
7
|
import { LocalRemote } from "./local-remote.js";
|
|
8
8
|
import { RoutingVcsProvider } from "./routing.js";
|
|
9
9
|
import { logger } from "../../core/logger.js";
|
|
10
|
+
import { testSimulatorBase } from "../../config/test-simulators.js";
|
|
10
11
|
const vcsLog = logger.child({ module: "vcs" });
|
|
11
12
|
export * from "./types.js";
|
|
12
13
|
export { GitHubAppClient } from "./github.js";
|
|
13
14
|
export { GitVcsProvider, NodeGitCommandRunner } from "./git.js";
|
|
14
15
|
export { GitHubRemote } from "./github-remote.js";
|
|
15
16
|
export { LocalRemote } from "./local-remote.js";
|
|
16
|
-
export { RoutingVcsProvider, VCS_GITHUB_NOT_CONFIGURED_ERROR } from "./routing.js";
|
|
17
|
+
export { RoutingVcsProvider, VCS_GITHUB_NOT_CONFIGURED_ERROR, VCS_HOST_PROVIDER_NOT_CONFIGURED_ERROR, } from "./routing.js";
|
|
17
18
|
/**
|
|
18
19
|
* GitHub is built only with App credentials, local repositories only with
|
|
19
20
|
* LOCAL_REPO_ROOTS; neither being set is allowed (the server still starts) and
|
|
@@ -33,7 +34,13 @@ export function buildVcsProvider(providerConfig, config, env = process.env, opti
|
|
|
33
34
|
privateKey: config.privateKey,
|
|
34
35
|
apiVersion: config.apiVersion,
|
|
35
36
|
});
|
|
36
|
-
|
|
37
|
+
// WARDBY_TEST_SIMULATORS (test only): clone from and push to the simulator's git server.
|
|
38
|
+
const simulatorGit = testSimulatorBase("github-git", env);
|
|
39
|
+
const remote = new GitHubRemote({
|
|
40
|
+
github: client,
|
|
41
|
+
...(simulatorGit ? { cloneUrlForRepository: (repository) => `${simulatorGit}/${repository}.git` } : {}),
|
|
42
|
+
});
|
|
43
|
+
github = new GitVcsProvider({ rootDir, remote, ...limits });
|
|
37
44
|
}
|
|
38
45
|
let local = null;
|
|
39
46
|
if (loadLocalRepoRoots(env).roots.length > 0) {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pull request description wardby writes, as pure functions: the hash it
|
|
3
|
+
* records, whether a fix round's final message is good enough to replace it,
|
|
4
|
+
* whether a person has edited it since, and the comment that carries a
|
|
5
|
+
* proposed description when wardby must not overwrite one.
|
|
6
|
+
*
|
|
7
|
+
* Depends on nothing else in providers/vcs, so github.ts can import it.
|
|
8
|
+
*/
|
|
9
|
+
/** Marks the Related pull requests section; replaced in place by later runs. */
|
|
10
|
+
export declare const RELATED_SECTION_START = "<!-- wardby-related:start -->";
|
|
11
|
+
export declare const RELATED_SECTION_END = "<!-- wardby-related:end -->";
|
|
12
|
+
/** The last line of a description a fix round rewrote: `<!-- wardby-latest:<runId> -->`. */
|
|
13
|
+
export declare const LATEST_RUN_MARKER_PREFIX = "<!-- wardby-latest:";
|
|
14
|
+
/**
|
|
15
|
+
* The first line of the one description comment per pull request (edited in
|
|
16
|
+
* place on later runs). Pull-request level, never per run. A proposal is
|
|
17
|
+
* stamped with the head commit it describes: `<!-- wardby-description head=<sha> -->`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DESCRIPTION_COMMENT_MARKER = "<!-- wardby-description -->";
|
|
20
|
+
/** The second line of the description comment once a later run applied its description directly. */
|
|
21
|
+
export declare const DESCRIPTION_COMMENT_APPLIED_MARKER = "<!-- wardby-description-applied -->";
|
|
22
|
+
/** The first line of a duplicate description comment, rewritten to point at the one in use. */
|
|
23
|
+
export declare const DESCRIPTION_COMMENT_SUPERSEDED_MARKER = "<!-- wardby-description-superseded -->";
|
|
24
|
+
/** The description comment is searched for on at most this many pages of 100 comments. */
|
|
25
|
+
export declare const MAX_DESCRIPTION_COMMENT_PAGES = 10;
|
|
26
|
+
/** A final message with fewer non-whitespace characters can't replace the description. */
|
|
27
|
+
export declare const MIN_PR_BODY_CHARS = 80;
|
|
28
|
+
/** The fallback comment stays under this many characters (GitHub's limit is 65,536). */
|
|
29
|
+
export declare const MAX_DESCRIPTION_COMMENT_CHARS = 60000;
|
|
30
|
+
/** The marked Related block, START through END inclusive; undefined when absent or malformed (missing, reversed, repeated). */
|
|
31
|
+
export declare function extractRelatedBlock(body: string): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The body as hashed: LF line endings, the Related block removed (it is
|
|
34
|
+
* rewritten as other runs finish, which is not an edit), trailing whitespace
|
|
35
|
+
* trimmed per line and at the end, and runs of blank lines collapsed to one.
|
|
36
|
+
*/
|
|
37
|
+
export declare function normalizeDescriptionForHash(body: string): string;
|
|
38
|
+
/** SHA-256 of the normalized body, lowercase hex. */
|
|
39
|
+
export declare function descriptionSha256(body: string): string;
|
|
40
|
+
/** Whether the text contains a GitHub closing keyword and issue reference (`Fixes #3`, `resolves owner/repo#3`). */
|
|
41
|
+
export declare function hasClosingKeyword(text: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The issue number of the first closing keyword in `text` that points at an
|
|
44
|
+
* issue in `repository` (`Resolves #12`, `fixes owner/repo#12` naming this
|
|
45
|
+
* repository, case-insensitively); undefined when there is none.
|
|
46
|
+
*/
|
|
47
|
+
export declare function closingIssueNumber(text: string | undefined, repository: string): number | undefined;
|
|
48
|
+
export type FinalMessageVerdict = {
|
|
49
|
+
ok: true;
|
|
50
|
+
} | {
|
|
51
|
+
ok: false;
|
|
52
|
+
reason: "empty" | "too_short" | "missing_closing_keyword";
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Whether `next` (a fix round's final message) can replace the description
|
|
56
|
+
* whose agent-written text was `previous`: not empty, at least
|
|
57
|
+
* MIN_PR_BODY_CHARS non-whitespace characters, and keeping a closing keyword
|
|
58
|
+
* when the previous text had one.
|
|
59
|
+
*/
|
|
60
|
+
export declare function assessFinalMessage(next: string | undefined, previous: string | undefined): FinalMessageVerdict;
|
|
61
|
+
/**
|
|
62
|
+
* Whether the PR description is still what wardby last wrote. It must start
|
|
63
|
+
* with the root run's marker, and its normalized hash must match the recorded
|
|
64
|
+
* one. Without a recorded hash (a description written before hashes were
|
|
65
|
+
* recorded), it must match `legacySha256`, the hash of the body wardby would
|
|
66
|
+
* have written for the root run, rebuilt from stored records; without that
|
|
67
|
+
* either it counts as edited, so a person's text is never overwritten.
|
|
68
|
+
* `previousAgentText` does not decide edit status; it is carried for callers.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isUneditedDescription(input: {
|
|
71
|
+
currentBody: string;
|
|
72
|
+
rootRunId: string;
|
|
73
|
+
recordedSha256: string | null;
|
|
74
|
+
legacySha256?: string;
|
|
75
|
+
previousAgentText?: string | undefined;
|
|
76
|
+
}): boolean;
|
|
77
|
+
export interface ParsedDescriptionComment {
|
|
78
|
+
/** The head commit the proposal describes; absent on an unstamped or applied comment. */
|
|
79
|
+
headSha?: string;
|
|
80
|
+
/** A later run applied its description directly: no proposal is pending. */
|
|
81
|
+
applied: boolean;
|
|
82
|
+
/** The run that proposed it, when named. */
|
|
83
|
+
runId?: string;
|
|
84
|
+
/** The proposed description; absent when the comment holds none. */
|
|
85
|
+
proposed?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* wardby's description comment, parsed; undefined for any other comment.
|
|
89
|
+
* Only the first line (the marker) and second line (the applied marker) are
|
|
90
|
+
* structural, so text inside a proposal can't change its state.
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseDescriptionComment(body: string): ParsedDescriptionComment | undefined;
|
|
93
|
+
export interface DescriptionCommentRecord {
|
|
94
|
+
id: number;
|
|
95
|
+
body: string;
|
|
96
|
+
url?: string;
|
|
97
|
+
parsed: ParsedDescriptionComment;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* wardby's description comments on a pull request, read the same way by the
|
|
101
|
+
* writer and the reviewer: up to MAX_DESCRIPTION_COMMENT_PAGES pages of 100
|
|
102
|
+
* (oldest first), only comments `isOurs` accepts that start with the
|
|
103
|
+
* pull-request-level marker. `newest` is the one in use; `older` are
|
|
104
|
+
* duplicates (oldest first).
|
|
105
|
+
*/
|
|
106
|
+
export declare function findDescriptionComments(fetchPage: (page: number) => Promise<unknown[]>, isOurs: (comment: Record<string, unknown>) => boolean): Promise<{
|
|
107
|
+
newest: DescriptionCommentRecord | null;
|
|
108
|
+
older: DescriptionCommentRecord[];
|
|
109
|
+
}>;
|
|
110
|
+
/** What a duplicate description comment becomes: a pointer to the one in use. */
|
|
111
|
+
export declare function supersededDescriptionComment(url: string | undefined): string;
|
|
112
|
+
/**
|
|
113
|
+
* The pull request's description comment, carrying the description wardby's
|
|
114
|
+
* latest run proposed when it could not apply it (it couldn't confirm the
|
|
115
|
+
* description is still its own text). There is one per pull request,
|
|
116
|
+
* edited in place by later runs, its marker stamped with `headSha`, the head
|
|
117
|
+
* commit the proposal describes. Holds the body in a collapsed fenced block,
|
|
118
|
+
* and stays under MAX_DESCRIPTION_COMMENT_CHARS (a long body is truncated).
|
|
119
|
+
* Throws on a run id or head that isn't safe to quote.
|
|
120
|
+
*/
|
|
121
|
+
export declare function descriptionFallbackComment(runId: string, proposedBody: string, headSha?: string): string;
|
|
122
|
+
/**
|
|
123
|
+
* What the description comment becomes once a later run applied its
|
|
124
|
+
* description directly: no proposal is pending, so nobody (a person or a
|
|
125
|
+
* reviewer) acts on a stale one.
|
|
126
|
+
*/
|
|
127
|
+
export declare function descriptionAppliedComment(runId: string): string;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* The pull request description wardby writes, as pure functions: the hash it
|
|
4
|
+
* records, whether a fix round's final message is good enough to replace it,
|
|
5
|
+
* whether a person has edited it since, and the comment that carries a
|
|
6
|
+
* proposed description when wardby must not overwrite one.
|
|
7
|
+
*
|
|
8
|
+
* Depends on nothing else in providers/vcs, so github.ts can import it.
|
|
9
|
+
*/
|
|
10
|
+
/** Marks the Related pull requests section; replaced in place by later runs. */
|
|
11
|
+
export const RELATED_SECTION_START = "<!-- wardby-related:start -->";
|
|
12
|
+
export const RELATED_SECTION_END = "<!-- wardby-related:end -->";
|
|
13
|
+
/** The last line of a description a fix round rewrote: `<!-- wardby-latest:<runId> -->`. */
|
|
14
|
+
export const LATEST_RUN_MARKER_PREFIX = "<!-- wardby-latest:";
|
|
15
|
+
/**
|
|
16
|
+
* The first line of the one description comment per pull request (edited in
|
|
17
|
+
* place on later runs). Pull-request level, never per run. A proposal is
|
|
18
|
+
* stamped with the head commit it describes: `<!-- wardby-description head=<sha> -->`.
|
|
19
|
+
*/
|
|
20
|
+
export const DESCRIPTION_COMMENT_MARKER = "<!-- wardby-description -->";
|
|
21
|
+
/** The marker line, plain or stamped with a head; anchored to the whole first line. */
|
|
22
|
+
const DESCRIPTION_COMMENT_MARKER_LINE = /^<!-- wardby-description(?: head=([0-9a-f]{40}))? -->$/;
|
|
23
|
+
/** The second line of the description comment once a later run applied its description directly. */
|
|
24
|
+
export const DESCRIPTION_COMMENT_APPLIED_MARKER = "<!-- wardby-description-applied -->";
|
|
25
|
+
/** The first line of a duplicate description comment, rewritten to point at the one in use. */
|
|
26
|
+
export const DESCRIPTION_COMMENT_SUPERSEDED_MARKER = "<!-- wardby-description-superseded -->";
|
|
27
|
+
/** The description comment is searched for on at most this many pages of 100 comments. */
|
|
28
|
+
export const MAX_DESCRIPTION_COMMENT_PAGES = 10;
|
|
29
|
+
const HEAD_SHA = /^[0-9a-f]{40}$/;
|
|
30
|
+
const PROPOSAL_SUMMARY = "<details><summary>Proposed description</summary>";
|
|
31
|
+
/** A final message with fewer non-whitespace characters can't replace the description. */
|
|
32
|
+
export const MIN_PR_BODY_CHARS = 80;
|
|
33
|
+
/** The fallback comment stays under this many characters (GitHub's limit is 65,536). */
|
|
34
|
+
export const MAX_DESCRIPTION_COMMENT_CHARS = 60_000;
|
|
35
|
+
const RUN_MARKER_PREFIX = "<!-- wardby:";
|
|
36
|
+
/** Mirrors the runId shape validated in github.ts and coding/protocol.ts. */
|
|
37
|
+
const SAFE_RUN_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
38
|
+
/** GitHub's closing keywords, then `#N` or `owner/repo#N`. */
|
|
39
|
+
const CLOSING_KEYWORD = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\b:?\s+(?:[\w.-]+\/[\w.-]+)?#\d+\b/i;
|
|
40
|
+
/** The marked Related block, START through END inclusive; undefined when absent or malformed (missing, reversed, repeated). */
|
|
41
|
+
export function extractRelatedBlock(body) {
|
|
42
|
+
const start = body.indexOf(RELATED_SECTION_START);
|
|
43
|
+
const end = body.indexOf(RELATED_SECTION_END);
|
|
44
|
+
if (start === -1 || end === -1 || end < start)
|
|
45
|
+
return undefined;
|
|
46
|
+
if (body.indexOf(RELATED_SECTION_START, start + 1) !== -1 || body.indexOf(RELATED_SECTION_END, end + 1) !== -1) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return body.slice(start, end + RELATED_SECTION_END.length);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The body as hashed: LF line endings, the Related block removed (it is
|
|
53
|
+
* rewritten as other runs finish, which is not an edit), trailing whitespace
|
|
54
|
+
* trimmed per line and at the end, and runs of blank lines collapsed to one.
|
|
55
|
+
*/
|
|
56
|
+
export function normalizeDescriptionForHash(body) {
|
|
57
|
+
let text = body.replace(/\r\n/g, "\n");
|
|
58
|
+
const related = extractRelatedBlock(text);
|
|
59
|
+
if (related)
|
|
60
|
+
text = text.replace(related, "");
|
|
61
|
+
return text
|
|
62
|
+
.split("\n")
|
|
63
|
+
.map((line) => line.trimEnd())
|
|
64
|
+
.join("\n")
|
|
65
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
66
|
+
.trimEnd();
|
|
67
|
+
}
|
|
68
|
+
/** SHA-256 of the normalized body, lowercase hex. */
|
|
69
|
+
export function descriptionSha256(body) {
|
|
70
|
+
return createHash("sha256").update(normalizeDescriptionForHash(body), "utf8").digest("hex");
|
|
71
|
+
}
|
|
72
|
+
/** Whether the text contains a GitHub closing keyword and issue reference (`Fixes #3`, `resolves owner/repo#3`). */
|
|
73
|
+
export function hasClosingKeyword(text) {
|
|
74
|
+
return CLOSING_KEYWORD.test(text);
|
|
75
|
+
}
|
|
76
|
+
const CLOSING_REFERENCES = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\b:?\s+(?:([\w.-]+\/[\w.-]+))?#(\d+)\b/gi;
|
|
77
|
+
/**
|
|
78
|
+
* The issue number of the first closing keyword in `text` that points at an
|
|
79
|
+
* issue in `repository` (`Resolves #12`, `fixes owner/repo#12` naming this
|
|
80
|
+
* repository, case-insensitively); undefined when there is none.
|
|
81
|
+
*/
|
|
82
|
+
export function closingIssueNumber(text, repository) {
|
|
83
|
+
if (!text)
|
|
84
|
+
return undefined;
|
|
85
|
+
for (const match of text.matchAll(CLOSING_REFERENCES)) {
|
|
86
|
+
if (match[1] && match[1].toLowerCase() !== repository.toLowerCase())
|
|
87
|
+
continue;
|
|
88
|
+
const number = Number(match[2]);
|
|
89
|
+
if (Number.isSafeInteger(number) && number > 0)
|
|
90
|
+
return number;
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether `next` (a fix round's final message) can replace the description
|
|
96
|
+
* whose agent-written text was `previous`: not empty, at least
|
|
97
|
+
* MIN_PR_BODY_CHARS non-whitespace characters, and keeping a closing keyword
|
|
98
|
+
* when the previous text had one.
|
|
99
|
+
*/
|
|
100
|
+
export function assessFinalMessage(next, previous) {
|
|
101
|
+
const text = next?.trim() ?? "";
|
|
102
|
+
if (!text)
|
|
103
|
+
return { ok: false, reason: "empty" };
|
|
104
|
+
if (text.replace(/\s/g, "").length < MIN_PR_BODY_CHARS)
|
|
105
|
+
return { ok: false, reason: "too_short" };
|
|
106
|
+
if (previous && hasClosingKeyword(previous) && !hasClosingKeyword(text)) {
|
|
107
|
+
return { ok: false, reason: "missing_closing_keyword" };
|
|
108
|
+
}
|
|
109
|
+
return { ok: true };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Whether the PR description is still what wardby last wrote. It must start
|
|
113
|
+
* with the root run's marker, and its normalized hash must match the recorded
|
|
114
|
+
* one. Without a recorded hash (a description written before hashes were
|
|
115
|
+
* recorded), it must match `legacySha256`, the hash of the body wardby would
|
|
116
|
+
* have written for the root run, rebuilt from stored records; without that
|
|
117
|
+
* either it counts as edited, so a person's text is never overwritten.
|
|
118
|
+
* `previousAgentText` does not decide edit status; it is carried for callers.
|
|
119
|
+
*/
|
|
120
|
+
export function isUneditedDescription(input) {
|
|
121
|
+
const body = input.currentBody.replace(/\r\n/g, "\n");
|
|
122
|
+
if (!body.startsWith(`${RUN_MARKER_PREFIX}${input.rootRunId} -->`))
|
|
123
|
+
return false;
|
|
124
|
+
const expected = input.recordedSha256 ?? input.legacySha256;
|
|
125
|
+
if (!expected)
|
|
126
|
+
return false;
|
|
127
|
+
return descriptionSha256(body) === expected;
|
|
128
|
+
}
|
|
129
|
+
/** A backtick fence one longer than the longest backtick run in `text` (at least three). */
|
|
130
|
+
function fenceFor(text) {
|
|
131
|
+
const longest = Math.max(0, ...Array.from(text.matchAll(/`+/g), (m) => m[0].length));
|
|
132
|
+
return "`".repeat(Math.max(3, longest + 1));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* wardby's description comment, parsed; undefined for any other comment.
|
|
136
|
+
* Only the first line (the marker) and second line (the applied marker) are
|
|
137
|
+
* structural, so text inside a proposal can't change its state.
|
|
138
|
+
*/
|
|
139
|
+
export function parseDescriptionComment(body) {
|
|
140
|
+
const text = body.replace(/\r\n/g, "\n");
|
|
141
|
+
const lines = text.split("\n");
|
|
142
|
+
const marker = DESCRIPTION_COMMENT_MARKER_LINE.exec(lines[0] ?? "");
|
|
143
|
+
if (!marker)
|
|
144
|
+
return undefined;
|
|
145
|
+
if (lines[1] === DESCRIPTION_COMMENT_APPLIED_MARKER)
|
|
146
|
+
return { applied: true };
|
|
147
|
+
const proposed = proposalOf(text);
|
|
148
|
+
const runId = proposed === undefined ? undefined : proposingRunId(text);
|
|
149
|
+
return {
|
|
150
|
+
...(marker[1] ? { headSha: marker[1] } : {}),
|
|
151
|
+
applied: false,
|
|
152
|
+
...(runId ? { runId } : {}),
|
|
153
|
+
...(proposed !== undefined ? { proposed } : {}),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/** The fenced block under "Proposed description"; undefined when absent. */
|
|
157
|
+
function proposalOf(text) {
|
|
158
|
+
const at = text.indexOf(PROPOSAL_SUMMARY);
|
|
159
|
+
if (at === -1)
|
|
160
|
+
return undefined;
|
|
161
|
+
const open = /\n(`{3,})markdown\n/.exec(text.slice(at));
|
|
162
|
+
if (!open)
|
|
163
|
+
return undefined;
|
|
164
|
+
const start = at + open.index + open[0].length;
|
|
165
|
+
const close = text.indexOf(`\n${open[1]}\n`, start - 1);
|
|
166
|
+
const end = close === -1 ? text.indexOf(`\n${open[1]}`, start - 1) : close;
|
|
167
|
+
if (end < start - 1)
|
|
168
|
+
return undefined;
|
|
169
|
+
const proposal = text.slice(start, Math.max(start, end)).trimEnd();
|
|
170
|
+
return proposal || undefined;
|
|
171
|
+
}
|
|
172
|
+
/** The run a fallback comment names as its proposer (in its header, before the proposal). */
|
|
173
|
+
function proposingRunId(text) {
|
|
174
|
+
const header = text.slice(0, Math.max(0, text.indexOf(PROPOSAL_SUMMARY)));
|
|
175
|
+
const named = /latest run \(`([^`\n]+)`\)/.exec(header)?.[1];
|
|
176
|
+
return named && SAFE_RUN_ID.test(named) ? named : undefined;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* wardby's description comments on a pull request, read the same way by the
|
|
180
|
+
* writer and the reviewer: up to MAX_DESCRIPTION_COMMENT_PAGES pages of 100
|
|
181
|
+
* (oldest first), only comments `isOurs` accepts that start with the
|
|
182
|
+
* pull-request-level marker. `newest` is the one in use; `older` are
|
|
183
|
+
* duplicates (oldest first).
|
|
184
|
+
*/
|
|
185
|
+
export async function findDescriptionComments(fetchPage, isOurs) {
|
|
186
|
+
const found = [];
|
|
187
|
+
for (let page = 1; page <= MAX_DESCRIPTION_COMMENT_PAGES; page++) {
|
|
188
|
+
const comments = await fetchPage(page);
|
|
189
|
+
for (const item of comments) {
|
|
190
|
+
if (!item || typeof item !== "object")
|
|
191
|
+
continue;
|
|
192
|
+
const comment = item;
|
|
193
|
+
if (typeof comment.body !== "string" || typeof comment.id !== "number")
|
|
194
|
+
continue;
|
|
195
|
+
const parsed = parseDescriptionComment(comment.body);
|
|
196
|
+
if (!parsed || !isOurs(comment))
|
|
197
|
+
continue;
|
|
198
|
+
found.push({
|
|
199
|
+
id: comment.id,
|
|
200
|
+
body: comment.body,
|
|
201
|
+
...(typeof comment.html_url === "string" ? { url: comment.html_url } : {}),
|
|
202
|
+
parsed,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
if (comments.length < 100)
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
return { newest: found.at(-1) ?? null, older: found.slice(0, -1) };
|
|
209
|
+
}
|
|
210
|
+
/** What a duplicate description comment becomes: a pointer to the one in use. */
|
|
211
|
+
export function supersededDescriptionComment(url) {
|
|
212
|
+
const link = url && /^https:\/\/[^\s)]+$/.test(url) ? `[the current one](${url})` : "a newer comment";
|
|
213
|
+
return `${DESCRIPTION_COMMENT_SUPERSEDED_MARKER}\n\nSuperseded by ${link}.`;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* The pull request's description comment, carrying the description wardby's
|
|
217
|
+
* latest run proposed when it could not apply it (it couldn't confirm the
|
|
218
|
+
* description is still its own text). There is one per pull request,
|
|
219
|
+
* edited in place by later runs, its marker stamped with `headSha`, the head
|
|
220
|
+
* commit the proposal describes. Holds the body in a collapsed fenced block,
|
|
221
|
+
* and stays under MAX_DESCRIPTION_COMMENT_CHARS (a long body is truncated).
|
|
222
|
+
* Throws on a run id or head that isn't safe to quote.
|
|
223
|
+
*/
|
|
224
|
+
export function descriptionFallbackComment(runId, proposedBody, headSha) {
|
|
225
|
+
if (!SAFE_RUN_ID.test(runId))
|
|
226
|
+
throw new Error("description_comment_run_id_invalid");
|
|
227
|
+
if (headSha !== undefined && !HEAD_SHA.test(headSha))
|
|
228
|
+
throw new Error("description_comment_head_invalid");
|
|
229
|
+
const head = [
|
|
230
|
+
headSha ? `<!-- wardby-description head=${headSha} -->` : DESCRIPTION_COMMENT_MARKER,
|
|
231
|
+
"",
|
|
232
|
+
`This is the current description proposed by wardby's latest run (\`${runId}\`)${headSha ? ` for commit ${headSha.slice(0, 12)}` : ""}. ` +
|
|
233
|
+
"It was not applied because wardby couldn't confirm the description is unchanged since it wrote it (for example, a person edited it), and wardby never overwrites a person's edits. " +
|
|
234
|
+
"The pull request author can copy it into the description; wardby then keeps it up to date again. Later runs update this comment.",
|
|
235
|
+
"",
|
|
236
|
+
PROPOSAL_SUMMARY,
|
|
237
|
+
"",
|
|
238
|
+
].join("\n");
|
|
239
|
+
const truncatedNote = "\n\n_The proposed description was truncated to fit in a comment._";
|
|
240
|
+
let body = proposedBody.replace(/\r\n/g, "\n").trimEnd();
|
|
241
|
+
let note = "";
|
|
242
|
+
const render = () => {
|
|
243
|
+
const fence = fenceFor(body);
|
|
244
|
+
return `${head}${fence}markdown\n${body}\n${fence}${note}\n\n</details>`;
|
|
245
|
+
};
|
|
246
|
+
let comment = render();
|
|
247
|
+
if (comment.length >= MAX_DESCRIPTION_COMMENT_CHARS) {
|
|
248
|
+
note = truncatedNote;
|
|
249
|
+
// Headroom for the fence growing if the cut leaves a longer backtick run (it can't), plus the note.
|
|
250
|
+
const overhead = comment.length - body.length + note.length + 64;
|
|
251
|
+
body = body.slice(0, Math.max(0, MAX_DESCRIPTION_COMMENT_CHARS - overhead)).trimEnd();
|
|
252
|
+
comment = render();
|
|
253
|
+
}
|
|
254
|
+
return comment;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* What the description comment becomes once a later run applied its
|
|
258
|
+
* description directly: no proposal is pending, so nobody (a person or a
|
|
259
|
+
* reviewer) acts on a stale one.
|
|
260
|
+
*/
|
|
261
|
+
export function descriptionAppliedComment(runId) {
|
|
262
|
+
if (!SAFE_RUN_ID.test(runId))
|
|
263
|
+
throw new Error("description_comment_run_id_invalid");
|
|
264
|
+
return [
|
|
265
|
+
DESCRIPTION_COMMENT_MARKER,
|
|
266
|
+
DESCRIPTION_COMMENT_APPLIED_MARKER,
|
|
267
|
+
"",
|
|
268
|
+
`wardby's latest run (\`${runId}\`) updated the pull request description directly, so it is current. No proposed description is pending here.`,
|
|
269
|
+
].join("\n");
|
|
270
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { FinalizeChangesDetails, PreparedWorkspace, VcsProvider } from "./types.js";
|
|
1
|
+
import type { DescriptionWriteOutcome, FinalizeChangesDetails, PreparedWorkspace, VcsProvider } from "./types.js";
|
|
2
|
+
/** Accepts bounded opaque git auth tokens without allowing control characters. */
|
|
3
|
+
export declare function isSafeGitAuthToken(value: unknown): value is string;
|
|
2
4
|
/** What a remote needs to publish a pushed commit (GitHub: open or find the draft PR). */
|
|
3
5
|
export interface PublishInput {
|
|
4
6
|
/** The validated workspace whose headRef was just pushed. */
|
|
@@ -6,11 +8,14 @@ export interface PublishInput {
|
|
|
6
8
|
details?: FinalizeChangesDetails;
|
|
7
9
|
/** Every path the commit changes relative to baseCommit (already validated). */
|
|
8
10
|
changedPaths: readonly string[];
|
|
11
|
+
/** The commit just pushed (the pull request's new head). */
|
|
12
|
+
commitSha?: string;
|
|
9
13
|
}
|
|
10
14
|
export type PublishResult = {
|
|
11
15
|
kind: "pull_request";
|
|
12
16
|
number: number;
|
|
13
17
|
url: string;
|
|
18
|
+
description?: DescriptionWriteOutcome;
|
|
14
19
|
} | {
|
|
15
20
|
kind: "branch";
|
|
16
21
|
branch: string;
|
|
@@ -22,6 +27,8 @@ export type PublishResult = {
|
|
|
22
27
|
* fetch-compare-push) stays in GitVcsProvider and applies to every remote.
|
|
23
28
|
*/
|
|
24
29
|
export interface GitRemote {
|
|
30
|
+
/** The username git sends with the token (GitHub: unset, git-askpass.sh's default). */
|
|
31
|
+
readonly gitUsername?: string;
|
|
25
32
|
/** Extra `-c` pairs appended after HARDENED_GIT_CONFIG for clone/push/ls-remote (GitHub: none). */
|
|
26
33
|
readonly gitConfig: readonly string[];
|
|
27
34
|
/** Syntactic normalization of a repository id for this remote (GitHub: owner/name; local: local:/abs/path). */
|
|
@@ -52,7 +59,36 @@ export interface GitRemote {
|
|
|
52
59
|
assertPushRef?(headRef: string): void;
|
|
53
60
|
/** When set, called inside withAccess right before the push; throws to refuse it (GitHub: unset). */
|
|
54
61
|
beforePush?(repository: string, headRef: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Optional: the branch a continuation's pull request currently targets, which
|
|
64
|
+
* prepareWorkspace merges into the workspace before the agent starts (GitHub:
|
|
65
|
+
* the open PR's base; local: unset, so no merge). Null when there is nothing to
|
|
66
|
+
* merge from: not a continuation, the PR is a fork's, or the lookup failed.
|
|
67
|
+
* Never throws.
|
|
68
|
+
*/
|
|
69
|
+
pullRequestBase?(input: {
|
|
70
|
+
runId: string;
|
|
71
|
+
repository: string;
|
|
72
|
+
baseRef: string;
|
|
73
|
+
headRef: string;
|
|
74
|
+
continuation?: {
|
|
75
|
+
rootRunId: string;
|
|
76
|
+
};
|
|
77
|
+
}): Promise<{
|
|
78
|
+
ref: string;
|
|
79
|
+
} | null>;
|
|
55
80
|
notifyContinuationStarted?: VcsProvider["notifyContinuationStarted"];
|
|
81
|
+
continuationPullRequestDraft?: VcsProvider["continuationPullRequestDraft"];
|
|
56
82
|
notifyContinuationFinished?: VcsProvider["notifyContinuationFinished"];
|
|
57
83
|
readRepositoryFile?: VcsProvider["readRepositoryFile"];
|
|
84
|
+
/**
|
|
85
|
+
* Optional: called after the commit and before the push, with the commit
|
|
86
|
+
* about to become the head. GitHub writes a continuation's description
|
|
87
|
+
* comment here, so it exists before the push starts a review. Never throws.
|
|
88
|
+
*/
|
|
89
|
+
proposeDescriptionBeforePush?(input: PublishInput & {
|
|
90
|
+
commitSha: string;
|
|
91
|
+
}): Promise<void>;
|
|
92
|
+
/** Optional: re-derive a continuation's PR description without a push (GitHub only). Never throws. */
|
|
93
|
+
refreshDescription?: VcsProvider["refreshPullRequestDescription"];
|
|
58
94
|
}
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/** Accepts bounded opaque git auth tokens without allowing control characters. */
|
|
2
|
+
export function isSafeGitAuthToken(value) {
|
|
3
|
+
return (typeof value === "string" &&
|
|
4
|
+
value.length >= 20 &&
|
|
5
|
+
Buffer.byteLength(value, "utf8") <= 512 &&
|
|
6
|
+
/^[A-Za-z0-9._-]+$/.test(value));
|
|
7
|
+
}
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
import type { RepositoryFileInput } from "./
|
|
2
|
-
import type { ContinuationFinishedDetails, ContinuationOutcome, FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
|
|
1
|
+
import type { RepositoryFileInput } from "./types.js";
|
|
2
|
+
import type { ContinuationFinishedDetails, ContinuationOutcome, ContinuationTarget, DescriptionWriteOutcome, FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
|
|
3
3
|
/** Keeps the `vcs_github_not_configured` code prefix that error matching and categorization key on. */
|
|
4
4
|
export declare const VCS_GITHUB_NOT_CONFIGURED_ERROR = "vcs_github_not_configured: set GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY to run coding agents on GitHub repositories";
|
|
5
|
+
/** Keeps a stable code prefix for error matching. The provider name comes from a validated repository id. */
|
|
6
|
+
export declare const VCS_HOST_PROVIDER_NOT_CONFIGURED_ERROR = "vcs_host_provider_not_configured";
|
|
5
7
|
export interface RoutingVcsOptions {
|
|
6
8
|
/** Null when no GitHub App is configured. */
|
|
7
9
|
github: VcsProvider | null;
|
|
8
10
|
/** Null when no local repository roots are configured. */
|
|
9
11
|
local: VcsProvider | null;
|
|
12
|
+
/** Registered host providers, by name. */
|
|
13
|
+
hosted?: ReadonlyMap<string, VcsProvider>;
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
|
-
* One VcsProvider over
|
|
13
|
-
* local provider,
|
|
14
|
-
*
|
|
15
|
-
* only
|
|
16
|
-
*
|
|
16
|
+
* One VcsProvider over every repository kind: `local:/abs/path` goes to the
|
|
17
|
+
* local provider, `<provider>:<workspace>/<repo>` to the registered host
|
|
18
|
+
* provider of that name, and everything else to GitHub. A kind that is not
|
|
19
|
+
* configured fails only when a repository of that kind is actually used, so a
|
|
20
|
+
* server with only some of them still starts. A hosted repository never falls
|
|
21
|
+
* back to GitHub. The repository name is not re-resolved here: the local
|
|
22
|
+
* provider verifies it against the trusted roots.
|
|
17
23
|
*/
|
|
18
24
|
export declare class RoutingVcsProvider implements VcsProvider {
|
|
19
25
|
private readonly options;
|
|
@@ -28,6 +34,8 @@ export declare class RoutingVcsProvider implements VcsProvider {
|
|
|
28
34
|
notifyContinuationStarted(workspace: PreparedWorkspace, details?: {
|
|
29
35
|
agentName?: string;
|
|
30
36
|
}): Promise<void>;
|
|
31
|
-
notifyContinuationFinished(workspace:
|
|
37
|
+
notifyContinuationFinished(workspace: ContinuationTarget, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
|
|
38
|
+
refreshPullRequestDescription(workspace: ContinuationTarget, details: FinalizeChangesDetails): Promise<DescriptionWriteOutcome | undefined>;
|
|
39
|
+
continuationPullRequestDraft(workspace: PreparedWorkspace): Promise<boolean | undefined>;
|
|
32
40
|
readRepositoryFile(input: RepositoryFileInput): Promise<string | null>;
|
|
33
41
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import { codeProviderOf } from "../../coding/code-host.js";
|
|
1
2
|
import { LocalRepoError, isLocalRepository } from "../../coding/local-repo.js";
|
|
2
3
|
/** Keeps the `vcs_github_not_configured` code prefix that error matching and categorization key on. */
|
|
3
4
|
export const VCS_GITHUB_NOT_CONFIGURED_ERROR = "vcs_github_not_configured: set GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY to run coding agents on GitHub repositories";
|
|
5
|
+
/** Keeps a stable code prefix for error matching. The provider name comes from a validated repository id. */
|
|
6
|
+
export const VCS_HOST_PROVIDER_NOT_CONFIGURED_ERROR = "vcs_host_provider_not_configured";
|
|
4
7
|
/**
|
|
5
|
-
* One VcsProvider over
|
|
6
|
-
* local provider,
|
|
7
|
-
*
|
|
8
|
-
* only
|
|
9
|
-
*
|
|
8
|
+
* One VcsProvider over every repository kind: `local:/abs/path` goes to the
|
|
9
|
+
* local provider, `<provider>:<workspace>/<repo>` to the registered host
|
|
10
|
+
* provider of that name, and everything else to GitHub. A kind that is not
|
|
11
|
+
* configured fails only when a repository of that kind is actually used, so a
|
|
12
|
+
* server with only some of them still starts. A hosted repository never falls
|
|
13
|
+
* back to GitHub. The repository name is not re-resolved here: the local
|
|
14
|
+
* provider verifies it against the trusted roots.
|
|
10
15
|
*/
|
|
11
16
|
export class RoutingVcsProvider {
|
|
12
17
|
options;
|
|
@@ -20,13 +25,23 @@ export class RoutingVcsProvider {
|
|
|
20
25
|
}
|
|
21
26
|
return this.options.local;
|
|
22
27
|
}
|
|
28
|
+
const provider = codeProviderOf(repository);
|
|
29
|
+
if (provider !== "github") {
|
|
30
|
+
const hosted = this.options.hosted?.get(provider);
|
|
31
|
+
if (!hosted)
|
|
32
|
+
throw new Error(`${VCS_HOST_PROVIDER_NOT_CONFIGURED_ERROR}: no host provider named ${provider}`);
|
|
33
|
+
return hosted;
|
|
34
|
+
}
|
|
23
35
|
if (!this.options.github)
|
|
24
36
|
throw new Error(VCS_GITHUB_NOT_CONFIGURED_ERROR);
|
|
25
37
|
return this.options.github;
|
|
26
38
|
}
|
|
27
39
|
/** The target when configured, else null (best-effort calls that must never throw). */
|
|
28
40
|
optionalTarget(repository) {
|
|
29
|
-
|
|
41
|
+
if (isLocalRepository(repository))
|
|
42
|
+
return this.options.local ?? null;
|
|
43
|
+
const provider = codeProviderOf(repository);
|
|
44
|
+
return (provider === "github" ? this.options.github : this.options.hosted?.get(provider)) ?? null;
|
|
30
45
|
}
|
|
31
46
|
async prepareWorkspace(input) {
|
|
32
47
|
return this.target(input.repository).prepareWorkspace(input);
|
|
@@ -46,6 +61,12 @@ export class RoutingVcsProvider {
|
|
|
46
61
|
async notifyContinuationFinished(workspace, outcome, details) {
|
|
47
62
|
await this.optionalTarget(workspace.repository)?.notifyContinuationFinished?.(workspace, outcome, details);
|
|
48
63
|
}
|
|
64
|
+
async refreshPullRequestDescription(workspace, details) {
|
|
65
|
+
return this.optionalTarget(workspace.repository)?.refreshPullRequestDescription?.(workspace, details);
|
|
66
|
+
}
|
|
67
|
+
async continuationPullRequestDraft(workspace) {
|
|
68
|
+
return this.optionalTarget(workspace.repository)?.continuationPullRequestDraft?.(workspace);
|
|
69
|
+
}
|
|
49
70
|
async readRepositoryFile(input) {
|
|
50
71
|
return (await this.optionalTarget(input.repository)?.readRepositoryFile?.(input)) ?? null;
|
|
51
72
|
}
|