@wardby/cli 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -5
- package/README.md +6 -1
- package/deploy/local/docker-compose.quickstart-coding.yml +19 -0
- package/dist/claude-coding-worker/driver.d.ts +33 -3
- package/dist/claude-coding-worker/driver.js +151 -21
- package/dist/claude-coding-worker/main.js +38 -6
- package/dist/claude-coding-worker/sdk.js +29 -2
- package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
- package/dist/claude-coding-worker/tool-socket.js +111 -0
- package/dist/claude-coding-worker/transcript.d.ts +18 -0
- package/dist/claude-coding-worker/transcript.js +77 -0
- package/dist/claude-plugin/command.d.ts +61 -0
- package/dist/claude-plugin/command.js +376 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +3 -1
- package/dist/cli.js +71 -13
- package/dist/coding/code-host.d.ts +16 -0
- package/dist/coding/code-host.js +60 -0
- package/dist/coding/continuation-wording.d.ts +35 -0
- package/dist/coding/continuation-wording.js +73 -0
- package/dist/coding/linked-issue-note.d.ts +23 -0
- package/dist/coding/linked-issue-note.js +47 -0
- package/dist/coding/mcp-token.d.ts +12 -0
- package/dist/coding/mcp-token.js +26 -0
- package/dist/coding/merge-wording.d.ts +28 -0
- package/dist/coding/merge-wording.js +78 -0
- package/dist/coding/pr-description-note.d.ts +9 -0
- package/dist/coding/pr-description-note.js +32 -0
- package/dist/coding/profile.d.ts +46 -126
- package/dist/coding/profile.js +45 -4
- package/dist/coding/protected-path-wording.d.ts +8 -0
- package/dist/coding/protected-path-wording.js +1 -1
- package/dist/coding/protocol.d.ts +264 -346
- package/dist/coding/protocol.js +237 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +17 -0
- package/dist/coding/registry/allowlist.d.ts +12 -0
- package/dist/coding/registry/allowlist.js +14 -1
- package/dist/coding/registry/audit-mode.d.ts +153 -0
- package/dist/coding/registry/audit-mode.js +304 -0
- package/dist/coding/registry/lockfile-shared.d.ts +36 -0
- package/dist/coding/registry/lockfile-shared.js +128 -0
- package/dist/coding/registry/lockfiles.js +1 -1
- package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
- package/dist/coding/registry/npm-lockfile-formats.js +41 -0
- package/dist/coding/registry/npm-lockfile.d.ts +8 -4
- package/dist/coding/registry/npm-lockfile.js +4 -6
- package/dist/coding/registry/npm.js +78 -8
- package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
- package/dist/coding/registry/pnpm-lockfile.js +189 -0
- package/dist/coding/registry/pypi-plan.d.ts +50 -0
- package/dist/coding/registry/pypi-plan.js +406 -0
- package/dist/coding/registry/pypi-requirements.d.ts +58 -0
- package/dist/coding/registry/pypi-requirements.js +155 -0
- package/dist/coding/registry/pypi.d.ts +3 -27
- package/dist/coding/registry/pypi.js +40 -154
- package/dist/coding/registry/refusal-hints.d.ts +20 -0
- package/dist/coding/registry/refusal-hints.js +61 -0
- package/dist/coding/registry/refusal-wording.d.ts +11 -0
- package/dist/coding/registry/refusal-wording.js +56 -0
- package/dist/coding/registry/report.d.ts +70 -8
- package/dist/coding/registry/report.js +112 -5
- package/dist/coding/registry/types.d.ts +58 -8
- package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
- package/dist/coding/registry/yarn-lockfile.js +367 -0
- package/dist/coding/services/catalog.d.ts +37 -351
- package/dist/coding/transcript/claude-code.d.ts +13 -0
- package/dist/coding/transcript/claude-code.js +273 -0
- package/dist/coding/transcript/download-protocol.d.ts +30 -0
- package/dist/coding/transcript/download-protocol.js +18 -0
- package/dist/coding/transcript/format.d.ts +20 -0
- package/dist/coding/transcript/format.js +32 -0
- package/dist/coding/transcript/recorder.d.ts +52 -0
- package/dist/coding/transcript/recorder.js +225 -0
- package/dist/coding/transcript/resume/checkout.d.ts +31 -0
- package/dist/coding/transcript/resume/checkout.js +203 -0
- package/dist/coding/transcript/resume/command.d.ts +17 -0
- package/dist/coding/transcript/resume/command.js +176 -0
- package/dist/coding/transcript/resume/download.d.ts +20 -0
- package/dist/coding/transcript/resume/download.js +153 -0
- package/dist/coding/transcript/resume/launch.d.ts +38 -0
- package/dist/coding/transcript/resume/launch.js +128 -0
- package/dist/coding/transcript/resume/session-file.d.ts +13 -0
- package/dist/coding/transcript/resume/session-file.js +79 -0
- package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
- package/dist/coding/transcript/resume/stand-in.js +49 -0
- package/dist/coding-worker/artifact.d.ts +8 -3
- package/dist/coding-worker/artifact.js +3 -1
- package/dist/coding-worker/debug-trace.d.ts +9 -6
- package/dist/coding-worker/debug-trace.js +16 -19
- package/dist/coding-worker/dependency-cache.d.mts +229 -0
- package/dist/coding-worker/dependency-cache.mjs +2123 -0
- package/dist/coding-worker/driver.d.ts +4 -3
- package/dist/coding-worker/driver.js +124 -39
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/main.js +5 -1
- package/dist/coding-worker/mcp-config.d.ts +27 -0
- package/dist/coding-worker/mcp-config.js +32 -0
- package/dist/coding-worker/sdk.d.ts +36 -0
- package/dist/coding-worker/sdk.js +28 -1
- package/dist/coding-worker/task-note.d.ts +11 -0
- package/dist/coding-worker/task-note.js +13 -0
- package/dist/coding-worker/types.d.ts +15 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/mcp-call-limit.d.ts +8 -0
- package/dist/config/mcp-call-limit.js +18 -0
- package/dist/config/mcp-servers.d.ts +8 -0
- package/dist/config/mcp-servers.js +12 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +92 -0
- package/dist/config/test-simulators.js +333 -0
- package/dist/config/tool-timeout.d.ts +1 -0
- package/dist/config/tool-timeout.js +18 -0
- package/dist/core/async-context.d.ts +2 -0
- package/dist/core/async-context.js +12 -0
- package/dist/core/budget-events.d.ts +108 -0
- package/dist/core/budget-events.js +346 -0
- package/dist/core/budget-groups.d.ts +50 -1
- package/dist/core/budget-groups.js +236 -27
- package/dist/core/budget-stopped-head.d.ts +46 -0
- package/dist/core/budget-stopped-head.js +81 -0
- package/dist/core/budget-topup.d.ts +51 -0
- package/dist/core/budget-topup.js +156 -0
- package/dist/core/budget-wording.d.ts +16 -2
- package/dist/core/budget-wording.js +40 -2
- package/dist/core/coding-mcp.d.ts +36 -0
- package/dist/core/coding-mcp.js +253 -0
- package/dist/core/coding-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -0
- package/dist/core/coding-repository.d.ts +46 -0
- package/dist/core/coding-repository.js +92 -0
- package/dist/core/cron.d.ts +19 -1
- package/dist/core/cron.js +17 -0
- package/dist/core/datastores.js +1 -1
- package/dist/core/deferred-coding.d.ts +14 -0
- package/dist/core/deferred-coding.js +62 -0
- package/dist/core/delegation-child.d.ts +25 -0
- package/dist/core/delegation-child.js +37 -0
- package/dist/core/delegation-slots.d.ts +27 -0
- package/dist/core/delegation-slots.js +44 -0
- package/dist/core/dispatch.d.ts +48 -2
- package/dist/core/dispatch.js +166 -66
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +169 -0
- package/dist/core/grants.d.ts +46 -8
- package/dist/core/grants.js +99 -8
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +291 -27
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +300 -22
- package/dist/core/issue-bridge.d.ts +50 -6
- package/dist/core/issue-bridge.js +124 -33
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +4 -10
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +58 -29
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +14 -1
- package/dist/core/lost-run-children.d.ts +6 -0
- package/dist/core/lost-run-children.js +32 -0
- package/dist/core/mark-ready.d.ts +34 -0
- package/dist/core/mark-ready.js +152 -0
- package/dist/core/markdown-code.d.ts +8 -0
- package/dist/core/markdown-code.js +107 -0
- package/dist/core/mcp-client/client.d.ts +47 -0
- package/dist/core/mcp-client/client.js +141 -0
- package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
- package/dist/core/mcp-client/jsonrpc.js +54 -0
- package/dist/core/mcp-client/results.d.ts +13 -0
- package/dist/core/mcp-client/results.js +42 -0
- package/dist/core/mcp-servers.d.ts +90 -0
- package/dist/core/mcp-servers.js +230 -0
- package/dist/core/mcp-tools.d.ts +108 -0
- package/dist/core/mcp-tools.js +287 -0
- package/dist/core/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +44 -18
- package/dist/core/notification-dispatcher.js +2 -1
- package/dist/core/notification-templates.d.ts +1 -7
- package/dist/core/notification-templates.js +36 -2
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +4 -3
- package/dist/core/reconciler.js +8 -1
- package/dist/core/related-pull-requests.d.ts +11 -3
- package/dist/core/related-pull-requests.js +49 -20
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/review-fix.d.ts +1 -1
- package/dist/core/review-fix.js +4 -3
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +3 -0
- package/dist/core/review-host-tools.js +102 -14
- package/dist/core/review-reads.d.ts +55 -0
- package/dist/core/review-reads.js +233 -0
- package/dist/core/run-status.d.ts +12 -0
- package/dist/core/run-status.js +12 -0
- package/dist/core/runner.d.ts +145 -49
- package/dist/core/runner.js +719 -216
- package/dist/core/schedule-start.d.ts +12 -0
- package/dist/core/schedule-start.js +14 -0
- package/dist/core/secret-broker-config.d.ts +12 -74
- package/dist/core/secret-broker-config.js +1 -1
- package/dist/core/secret-guard.d.ts +49 -0
- package/dist/core/secret-guard.js +119 -0
- package/dist/core/secret-guarded-stores.d.ts +12 -0
- package/dist/core/secret-guarded-stores.js +41 -0
- package/dist/core/secret-spans.d.ts +50 -0
- package/dist/core/secret-spans.js +94 -0
- package/dist/core/secrets.d.ts +11 -1
- package/dist/core/secrets.js +27 -1
- package/dist/core/serializable-retry.d.ts +18 -0
- package/dist/core/serializable-retry.js +43 -0
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/tool-admin.d.ts +5 -1
- package/dist/core/tool-admin.js +7 -2
- package/dist/core/tool-names.d.ts +13 -0
- package/dist/core/tool-names.js +20 -0
- package/dist/core/webhooks.d.ts +4 -0
- package/dist/core/webhooks.js +68 -49
- package/dist/core/workflow-events.d.ts +14 -2
- package/dist/core/workflow-events.js +4 -0
- package/dist/core/workflow-run-events.d.ts +5 -3
- package/dist/core/workflow-run-events.js +45 -9
- package/dist/core/zod-json-schema.d.ts +4 -0
- package/dist/core/zod-json-schema.js +39 -0
- package/dist/core/zod3-window.d.ts +35 -0
- package/dist/core/zod3-window.js +124 -0
- package/dist/generated/prisma/browser.d.ts +65 -3
- package/dist/generated/prisma/client.d.ts +65 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +266 -106
- package/dist/generated/prisma/enums.d.ts +10 -0
- package/dist/generated/prisma/enums.js +8 -0
- package/dist/generated/prisma/internal/class.d.ts +110 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +957 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +166 -2
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +174 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +166 -2
- package/dist/generated/prisma/models/Agent.d.ts +377 -8
- package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
- package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +81 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +228 -7
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +232 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1712 -1
- package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
- package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
- package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
- package/dist/generated/prisma/models/HostProvider.js +1 -0
- package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
- package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
- package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
- package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
- package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
- package/dist/generated/prisma/models/McpServer.js +1 -0
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +77 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- package/dist/generated/prisma/models/Principal.d.ts +167 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
- package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
- package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
- package/dist/generated/prisma/models/Run.d.ts +738 -2
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
- package/dist/generated/prisma/models/RunTranscript.js +1 -0
- package/dist/generated/prisma/models/Secret.d.ts +387 -0
- package/dist/generated/prisma/models/Tool.d.ts +223 -1
- package/dist/generated/prisma/models.d.ts +10 -0
- package/dist/help/search.js +12 -3
- package/dist/help-index.json +2033 -110
- package/dist/import/create.js +48 -4
- package/dist/import/neutral-schema.d.ts +51 -281
- package/dist/import/neutral-schema.js +7 -4
- package/dist/knowledge/check.d.ts +1 -1
- package/dist/knowledge/cli.d.ts +11 -1
- package/dist/knowledge/cli.js +37 -4
- package/dist/knowledge/concept.d.ts +3 -19
- package/dist/knowledge/location.d.ts +31 -0
- package/dist/knowledge/location.js +78 -0
- package/dist/mcp/auth/access.d.ts +10 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/grants-cli.d.ts +6 -4
- package/dist/mcp/auth/grants-cli.js +42 -3
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/resource-server.d.ts +3 -1
- package/dist/mcp/auth/resource-server.js +17 -2
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
- package/dist/mcp/context.d.ts +3 -0
- package/dist/mcp/host-events/github-ingress.d.ts +2 -0
- package/dist/mcp/host-events/github-ingress.js +2 -1
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +69 -10
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +33 -14
- package/dist/mcp/tools/agents.d.ts +4 -0
- package/dist/mcp/tools/agents.js +295 -28
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +73 -29
- package/dist/mcp/tools/host-providers.d.ts +2 -0
- package/dist/mcp/tools/host-providers.js +215 -0
- package/dist/mcp/tools/mcp-servers.d.ts +26 -0
- package/dist/mcp/tools/mcp-servers.js +481 -0
- package/dist/mcp/tools/memory.js +11 -1
- package/dist/mcp/tools/notification-channels.js +2 -2
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/repositories.js +65 -12
- package/dist/mcp/tools/run-access.d.ts +16 -0
- package/dist/mcp/tools/run-access.js +25 -0
- package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
- package/dist/mcp/tools/run-transcript-download.js +129 -0
- package/dist/mcp/tools/run-transcript.d.ts +19 -0
- package/dist/mcp/tools/run-transcript.js +70 -0
- package/dist/mcp/tools/runs.js +209 -27
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-elicitation-form.js +5 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -61
- package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
- package/dist/mcp/tools/secret-elicitation.js +25 -2
- package/dist/mcp/tools/secrets.js +40 -6
- package/dist/mcp/tools/stop-run.d.ts +2 -0
- package/dist/mcp/tools/stop-run.js +82 -0
- package/dist/mcp/tools/subagents.js +2 -2
- package/dist/mcp/tools/tools.d.ts +7 -5
- package/dist/mcp/tools/tools.js +64 -16
- package/dist/mcp/tools/trigger.js +28 -6
- package/dist/mcp/transport/http-limits.d.ts +2 -0
- package/dist/mcp/transport/http-limits.js +6 -2
- package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
- package/dist/mcp/transport/stdio-link-host.js +67 -0
- package/dist/mcp/transport/streamable-http.d.ts +13 -0
- package/dist/mcp/transport/streamable-http.js +41 -1
- package/dist/mcp/webhooks/ingress.js +10 -0
- package/dist/native-worker/docker-launcher.d.ts +38 -2
- package/dist/native-worker/docker-launcher.js +65 -5
- package/dist/native-worker/gateway-server.d.ts +55 -3
- package/dist/native-worker/gateway-server.js +152 -34
- package/dist/native-worker/gateway.d.ts +29 -1
- package/dist/native-worker/gateway.js +74 -4
- package/dist/native-worker/http-server.d.ts +7 -1
- package/dist/native-worker/http-server.js +62 -7
- package/dist/native-worker/http-transport.js +1 -1
- package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
- package/dist/native-worker/kubernetes-launcher.js +43 -3
- package/dist/native-worker/launch.d.ts +18 -1
- package/dist/native-worker/launch.js +6 -1
- package/dist/native-worker/ledger.d.ts +24 -4
- package/dist/native-worker/ledger.js +62 -8
- package/dist/native-worker/loopback.js +3 -8
- package/dist/native-worker/main.d.ts +2 -1
- package/dist/native-worker/main.js +14 -3
- package/dist/native-worker/protocol.d.ts +130 -577
- package/dist/native-worker/protocol.js +51 -2
- package/dist/native-worker/sandbox-executor.d.ts +17 -2
- package/dist/native-worker/sandbox-executor.js +78 -4
- package/dist/native-worker/stderr-redaction.d.ts +77 -0
- package/dist/native-worker/stderr-redaction.js +237 -0
- package/dist/native-worker/stdio.d.ts +1 -1
- package/dist/native-worker/stdio.js +6 -5
- package/dist/native-worker/warm-pool.d.ts +2 -2
- package/dist/native-worker/warm-pool.js +4 -4
- package/dist/native-worker/worker.js +28 -2
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/self-hosted.d.ts +1 -1
- package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
- package/dist/providers/coding-proxy/capability-hash.js +5 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
- package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
- package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
- package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
- package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
- package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
- package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
- package/dist/providers/coding-proxy/hold.d.ts +32 -0
- package/dist/providers/coding-proxy/hold.js +86 -0
- package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
- package/dist/providers/coding-proxy/interrupted.js +104 -0
- package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
- package/dist/providers/coding-proxy/mcp-route.js +166 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -2
- package/dist/providers/coding-proxy/memory-ledger.js +99 -8
- package/dist/providers/coding-proxy/metering.d.ts +16 -0
- package/dist/providers/coding-proxy/metering.js +27 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +16 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +209 -69
- package/dist/providers/coding-proxy/proxy.d.ts +21 -2
- package/dist/providers/coding-proxy/proxy.js +300 -48
- package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
- package/dist/providers/coding-proxy/registry/audit.js +94 -17
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
- package/dist/providers/coding-proxy/registry/plan.js +201 -48
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
- package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
- package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
- package/dist/providers/coding-proxy/registry/service.js +579 -112
- package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
- package/dist/providers/coding-proxy/registry/store.js +54 -1
- package/dist/providers/coding-proxy/runtime.d.ts +10 -0
- package/dist/providers/coding-proxy/runtime.js +109 -16
- package/dist/providers/coding-proxy/server.d.ts +9 -1
- package/dist/providers/coding-proxy/server.js +55 -1
- package/dist/providers/coding-proxy/types.d.ts +78 -1
- package/dist/providers/datastore/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +17 -2
- package/dist/providers/engine/types.js +17 -0
- package/dist/providers/executor/composition.d.ts +10 -3
- package/dist/providers/executor/composition.js +52 -7
- package/dist/providers/executor/container.d.ts +394 -9
- package/dist/providers/executor/container.js +1210 -96
- package/dist/providers/executor/dbos-status.d.ts +31 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +50 -1
- package/dist/providers/executor/dbos.js +207 -20
- package/dist/providers/executor/deferred.d.ts +12 -24
- package/dist/providers/executor/deferred.js +10 -29
- package/dist/providers/executor/in-process.d.ts +9 -1
- package/dist/providers/executor/in-process.js +14 -4
- package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
- package/dist/providers/executor/linked-issue-reader.js +30 -0
- package/dist/providers/executor/routing.d.ts +2 -0
- package/dist/providers/executor/routing.js +4 -0
- package/dist/providers/executor/types.d.ts +13 -0
- package/dist/providers/host-tools/invoke.d.ts +37 -0
- package/dist/providers/host-tools/invoke.js +117 -0
- package/dist/providers/host-tools/operations.d.ts +65 -0
- package/dist/providers/host-tools/operations.js +149 -0
- package/dist/providers/host-tools/registry.d.ts +79 -0
- package/dist/providers/host-tools/registry.js +362 -0
- package/dist/providers/host-tools/request-guard.d.ts +17 -0
- package/dist/providers/host-tools/request-guard.js +99 -0
- package/dist/providers/host-tools/self-test.d.ts +64 -0
- package/dist/providers/host-tools/self-test.js +142 -0
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/issue-tracker/types.d.ts +17 -0
- package/dist/providers/issue-tracker/types.js +39 -1
- package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
- package/dist/providers/jobs/claude-tool-setup.js +5 -2
- package/dist/providers/jobs/docker-isolation.d.ts +10 -2
- package/dist/providers/jobs/docker-isolation.js +47 -8
- package/dist/providers/jobs/docker.d.ts +9 -0
- package/dist/providers/jobs/docker.js +60 -11
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
- package/dist/providers/jobs/kubernetes-api.js +10 -0
- package/dist/providers/jobs/kubernetes-client.js +10 -1
- package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
- package/dist/providers/jobs/kubernetes-isolation.js +32 -3
- package/dist/providers/jobs/kubernetes.d.ts +11 -1
- package/dist/providers/jobs/kubernetes.js +111 -17
- package/dist/providers/jobs/types.d.ts +39 -0
- package/dist/providers/jobs/types.js +13 -1
- package/dist/providers/llm/anthropic.js +5 -1
- package/dist/providers/llm/bedrock.d.ts +0 -12
- package/dist/providers/llm/bedrock.js +4 -0
- package/dist/providers/llm/claude-messages.d.ts +3 -1
- package/dist/providers/llm/claude-messages.js +4 -1
- package/dist/providers/llm/claude-provider.d.ts +2 -2
- package/dist/providers/llm/claude-provider.js +2 -2
- package/dist/providers/llm/openai.d.ts +2 -2
- package/dist/providers/llm/openai.js +6 -2
- package/dist/providers/llm/routing.d.ts +2 -2
- package/dist/providers/llm/routing.js +2 -2
- package/dist/providers/llm/types.d.ts +12 -2
- package/dist/providers/review-host/github-events.d.ts +9 -1
- package/dist/providers/review-host/github-events.js +34 -12
- package/dist/providers/review-host/github.d.ts +29 -2
- package/dist/providers/review-host/github.js +224 -29
- package/dist/providers/review-host/local.d.ts +8 -4
- package/dist/providers/review-host/local.js +49 -31
- package/dist/providers/review-host/patch-pages.d.ts +41 -0
- package/dist/providers/review-host/patch-pages.js +176 -0
- package/dist/providers/review-host/review-format.d.ts +19 -1
- package/dist/providers/review-host/review-format.js +38 -7
- package/dist/providers/review-host/types.d.ts +140 -6
- package/dist/providers/review-host/types.js +9 -1
- package/dist/providers/storage/gcs.d.ts +63 -0
- package/dist/providers/storage/gcs.js +69 -0
- package/dist/providers/storage/index.d.ts +15 -0
- package/dist/providers/storage/index.js +14 -0
- package/dist/providers/storage/local.d.ts +24 -0
- package/dist/providers/storage/local.js +92 -0
- package/dist/providers/storage/meter.d.ts +14 -0
- package/dist/providers/storage/meter.js +34 -0
- package/dist/providers/storage/s3.d.ts +41 -0
- package/dist/providers/storage/s3.js +107 -0
- package/dist/providers/storage/types.d.ts +37 -3
- package/dist/providers/storage/types.js +21 -4
- package/dist/providers/vcs/git.d.ts +39 -4
- package/dist/providers/vcs/git.js +339 -26
- package/dist/providers/vcs/github-remote.d.ts +26 -3
- package/dist/providers/vcs/github-remote.js +124 -14
- package/dist/providers/vcs/github.d.ts +183 -44
- package/dist/providers/vcs/github.js +455 -56
- package/dist/providers/vcs/index.d.ts +1 -1
- package/dist/providers/vcs/index.js +9 -2
- package/dist/providers/vcs/pr-description.d.ts +127 -0
- package/dist/providers/vcs/pr-description.js +270 -0
- package/dist/providers/vcs/remote.d.ts +37 -1
- package/dist/providers/vcs/remote.js +7 -1
- package/dist/providers/vcs/routing.d.ts +16 -8
- package/dist/providers/vcs/routing.js +27 -6
- package/dist/providers/vcs/types.d.ts +150 -5
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- package/dist/quickstart/index.d.ts +5 -0
- package/dist/quickstart/index.js +21 -0
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +6 -6
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/eval-core.d.ts +12 -2
- package/dist/sandbox/eval-core.js +20 -4
- package/dist/sandbox/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +5 -0
- package/dist/sandbox/host-functions.js +13 -13
- package/dist/sandbox/limits.d.ts +4 -1
- package/dist/sandbox/limits.js +4 -1
- package/dist/sandbox/run-in-sandbox.d.ts +6 -0
- package/dist/sandbox/run-in-sandbox.js +14 -2
- package/dist/sandbox/safe-fetch.d.ts +2 -0
- package/dist/sandbox/safe-fetch.js +1 -1
- package/dist/sandbox/secret-broker.d.ts +1 -0
- package/dist/sandbox/secret-broker.js +4 -5
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/tool-timeout.d.ts +32 -0
- package/dist/sandbox/tool-timeout.js +52 -0
- package/dist/sandbox/user-tool.d.ts +8 -1
- package/dist/sandbox/user-tool.js +9 -3
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +8 -1
- package/dist/viewer/api-schema.d.ts +349 -2627
- package/dist/viewer/api-schema.js +7 -0
- package/dist/viewer/build-schemas.js +6 -2
- package/dist/viewer/graph.js +2 -1
- package/dist/viewer/openapi.js +2 -4
- package/dist/wardby-bin.js +15 -0
- package/docs/README.md +11 -1
- package/docs/agent-recipes.md +95 -24
- package/docs/architecture-runtime.md +1 -1
- package/docs/claude-code-plugin.md +164 -0
- package/docs/code-review-agents.md +557 -41
- package/docs/coding-agent-setup.md +566 -8
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +24 -2
- package/docs/coding-worker-isolation.md +183 -37
- package/docs/debugging-agent-runs.md +242 -0
- package/docs/getting-started-gke.md +129 -141
- package/docs/getting-started-identity-provider.md +53 -38
- package/docs/getting-started.md +17 -0
- package/docs/host-providers.md +294 -0
- package/docs/jira-agents.md +17 -8
- package/docs/knowledge/blob-not-found-semantics.md +41 -0
- package/docs/knowledge/bounded-file-descriptor.md +52 -0
- package/docs/knowledge/delegation-admission-slots.md +52 -0
- package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
- package/docs/knowledge/import-rename-target.md +52 -0
- package/docs/knowledge/index.md +57 -0
- package/docs/knowledge/log.md +9 -0
- package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
- package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
- package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
- package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
- package/docs/knowledge/overview-cli.md +74 -0
- package/docs/knowledge/overview-coding-proxy.md +72 -0
- package/docs/knowledge/overview-coding.md +72 -0
- package/docs/knowledge/overview-config.md +60 -0
- package/docs/knowledge/overview-core.md +72 -0
- package/docs/knowledge/overview-deploy.md +83 -0
- package/docs/knowledge/overview-mcp.md +61 -0
- package/docs/knowledge/overview-prisma.md +72 -0
- package/docs/knowledge/overview-providers.md +89 -0
- package/docs/knowledge/overview-sandbox.md +83 -0
- package/docs/knowledge/overview-surfaces.md +83 -0
- package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
- package/docs/knowledge/proxy-settlement-projections.md +41 -0
- package/docs/knowledge/run-pricing-first-writer.md +43 -0
- package/docs/knowledge/schedule-claim-transaction.md +41 -0
- package/docs/knowledge/secret-entry-replica-contract.md +52 -0
- package/docs/knowledge/terminal-run-first-writer.md +41 -0
- package/docs/knowledge/transactional-agent-authorization.md +52 -0
- package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
- package/docs/knowledge/warm-input-publication.md +30 -0
- package/docs/knowledge/workspace-staging-failure.md +54 -0
- package/docs/knowledge.md +54 -14
- package/docs/mcp-servers.md +254 -0
- package/docs/native-sandbox.md +143 -31
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +139 -29
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +45 -10
- package/docs/viewer-api.md +6 -0
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +28 -2
- package/help/agent-recipes.md +33 -2
- package/help/architecture-agent.md +11 -6
- package/help/brokered-secrets.md +3 -0
- package/help/build-claude-code-image.md +1 -1
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- package/help/claude-code-run-pane.md +40 -0
- package/help/code-review-agents.md +177 -6
- package/help/coding-packages.md +156 -6
- package/help/cost-attribution.md +9 -5
- package/help/creating-agents.md +14 -1
- package/help/dependency-cache.md +143 -0
- package/help/deploy-gke.md +15 -8
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-mcp-pins-unavailable.md +35 -0
- package/help/errors/coding-stream-quota-exceeded.md +33 -0
- package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
- package/help/errors/continuation-closed.md +9 -12
- package/help/errors/database-auth-invalid.md +1 -1
- package/help/errors/delegation-conflict.md +24 -0
- package/help/errors/file-list-truncated.md +45 -0
- package/help/errors/full-read-required.md +49 -0
- package/help/errors/github-account-not-allowed.md +4 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/host-provider-error.md +40 -0
- package/help/errors/host-tool-failed.md +36 -0
- package/help/errors/mcp-call-limit.md +22 -0
- package/help/errors/mcp-call-timeout.md +22 -0
- package/help/errors/mcp-server-auth-failed.md +22 -0
- package/help/errors/mcp-server-credentials-unavailable.md +45 -0
- package/help/errors/mcp-server-error.md +28 -0
- package/help/errors/mcp-server-unreachable.md +22 -0
- package/help/errors/mcp-servers-off.md +21 -0
- package/help/errors/mcp-tool-not-allowed.md +26 -0
- package/help/errors/mcp-tool-removed.md +22 -0
- package/help/errors/mcp-unavailable.md +25 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-capacity.md +1 -1
- package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
- package/help/errors/native-sandbox-docker-failed.md +1 -1
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
- package/help/errors/native-sandbox-image-not-pinned.md +1 -1
- package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-network-unenforced.md +1 -1
- package/help/errors/native-sandbox-requires-catalog.md +1 -1
- package/help/errors/native-sandbox-unavailable.md +1 -1
- package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
- package/help/errors/native-sandbox-worker-exited.md +4 -3
- package/help/errors/native-sandbox-worker-lost.md +1 -1
- package/help/errors/native-sandbox-worker-unready.md +1 -1
- package/help/errors/package-not-allowed-pending.md +52 -0
- package/help/errors/package-not-allowed.md +51 -0
- package/help/errors/package-refusals.md +43 -0
- package/help/errors/patch-cursor-malformed.md +31 -0
- package/help/errors/repository-not-listed.md +36 -0
- package/help/errors/repository-required.md +36 -0
- package/help/errors/run-lost.md +39 -0
- package/help/errors/run-transcript-download.md +44 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/target-merge.md +40 -0
- package/help/errors/tool-timeout.md +38 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/host-providers.md +40 -0
- package/help/identity-and-access.md +6 -1
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +1 -1
- package/help/low-power-mode.md +7 -1
- package/help/mcp-servers.md +73 -0
- package/help/mcp.md +7 -2
- package/help/merge-order-check.md +5 -0
- package/help/native-capabilities.md +55 -1
- package/help/native-sandbox.md +16 -2
- package/help/operating-agents.md +21 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +17 -10
- package/help/repo-instructions-and-skills.md +3 -1
- package/help/resume-runs-locally.md +134 -0
- package/help/review-fix-rounds.md +33 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +19 -5
- package/help/status-comments.md +31 -0
- package/help/stop-run.md +58 -0
- package/help/troubleshooting/budgets.md +28 -0
- package/help/troubleshooting/coding-workers.md +86 -7
- package/help/troubleshooting/debugging-agent-runs.md +29 -0
- package/package.json +18 -10
- package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
- package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
- package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
- package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
- package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
- package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
- package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
- package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
- package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
- package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
- package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
- package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
- package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
- package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
- package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
- package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
- package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
- package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
- package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
- package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
- package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
- package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
- package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
- package/prisma/schema.prisma +468 -109
- package/scripts/git-askpass.sh +1 -1
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* repo_pr_read's diff pages: which files get the patch budget first (code before docs, help,
|
|
3
|
+
* lockfiles, generated files and fixtures), how a page is filled from a cursor, and the cursor
|
|
4
|
+
* itself. Shared by every review host so paging behaves the same on GitHub and local repositories.
|
|
5
|
+
*/
|
|
6
|
+
import { PatchCursorError } from "./types.js";
|
|
7
|
+
const LOCKFILES = new Set([
|
|
8
|
+
"package-lock.json",
|
|
9
|
+
"npm-shrinkwrap.json",
|
|
10
|
+
"yarn.lock",
|
|
11
|
+
"pnpm-lock.yaml",
|
|
12
|
+
"bun.lockb",
|
|
13
|
+
"poetry.lock",
|
|
14
|
+
"uv.lock",
|
|
15
|
+
"Pipfile.lock",
|
|
16
|
+
"Cargo.lock",
|
|
17
|
+
"go.sum",
|
|
18
|
+
"Gemfile.lock",
|
|
19
|
+
"composer.lock",
|
|
20
|
+
"mix.lock",
|
|
21
|
+
"pubspec.lock",
|
|
22
|
+
]);
|
|
23
|
+
const OTHER_EXTENSIONS = /\.(md|mdx|rst|adoc|txt|snap|svg|png|jpe?g|gif|webp|ico|pdf|lock)$/i;
|
|
24
|
+
// docs/ and help/ are the repository's own documentation folders (root only); the rest can be anywhere.
|
|
25
|
+
const OTHER_DIRECTORY = /^(docs?|help)\/|(^|\/)(generated|__generated__|dist|vendor|fixtures|__fixtures__|__snapshots__|testdata)\//i;
|
|
26
|
+
const MINIFIED = /\.min\.(js|css)$/i;
|
|
27
|
+
/** The longest patchCursor this module issues or accepts; callers use it as the tool schema's maximum. */
|
|
28
|
+
export const MAX_PATCH_CURSOR_CHARS = 4000;
|
|
29
|
+
/** "code" (source, tests, config, migrations) is filled first; "other" is everything a review can skim. */
|
|
30
|
+
export function reviewGroup(path) {
|
|
31
|
+
const base = path.slice(path.lastIndexOf("/") + 1);
|
|
32
|
+
if (/^requirements.*\.txt$/i.test(base) || base === "CMakeLists.txt")
|
|
33
|
+
return "code";
|
|
34
|
+
if (LOCKFILES.has(base) || OTHER_EXTENSIONS.test(base) || MINIFIED.test(base) || OTHER_DIRECTORY.test(path))
|
|
35
|
+
return "other";
|
|
36
|
+
return "code";
|
|
37
|
+
}
|
|
38
|
+
/** Code first; the host's order within each group (stable). */
|
|
39
|
+
export function reviewOrder(files) {
|
|
40
|
+
return [
|
|
41
|
+
...files.filter((f) => reviewGroup(f.filename) === "code"),
|
|
42
|
+
...files.filter((f) => reviewGroup(f.filename) === "other"),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
const CURSOR = /^v1\.([0-9a-f]{40})\.([0-9a-f]{40}|-)\.(\d{1,6})\.(\d{1,9})\.(-|\d{1,6}(?:,\d{1,6})*)$/;
|
|
46
|
+
function encodeCursor(headSha, comparedFrom, pos) {
|
|
47
|
+
const u = pos.unavailable.length ? pos.unavailable.join(",") : "-";
|
|
48
|
+
return `v1.${headSha}.${comparedFrom ?? "-"}.${pos.fileIndex}.${pos.offset}.${u}`;
|
|
49
|
+
}
|
|
50
|
+
function parseCursor(cursor, headSha, comparedFrom, fileCount) {
|
|
51
|
+
const m = cursor.length <= MAX_PATCH_CURSOR_CHARS ? CURSOR.exec(cursor) : null;
|
|
52
|
+
if (!m)
|
|
53
|
+
throw new PatchCursorError("malformed");
|
|
54
|
+
if (m[1] !== headSha || m[2] !== (comparedFrom ?? "-"))
|
|
55
|
+
throw new PatchCursorError("stale");
|
|
56
|
+
const pos = {
|
|
57
|
+
fileIndex: Number(m[3]),
|
|
58
|
+
offset: Number(m[4]),
|
|
59
|
+
unavailable: m[5] === "-" ? [] : m[5].split(",").map(Number),
|
|
60
|
+
};
|
|
61
|
+
if (pos.fileIndex > fileCount)
|
|
62
|
+
throw new PatchCursorError("malformed");
|
|
63
|
+
let previous = -1;
|
|
64
|
+
for (const index of pos.unavailable) {
|
|
65
|
+
if (index <= previous || index >= pos.fileIndex)
|
|
66
|
+
throw new PatchCursorError("malformed");
|
|
67
|
+
previous = index;
|
|
68
|
+
}
|
|
69
|
+
return pos;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The longest prefix of `text` within `max` characters that ends at a line break. With no break
|
|
73
|
+
* in range, a single longer line is cut at `max` when `hardCut`, else nothing is returned.
|
|
74
|
+
*/
|
|
75
|
+
function cutAtLine(text, max, hardCut) {
|
|
76
|
+
if (text.length <= max)
|
|
77
|
+
return text;
|
|
78
|
+
const cut = text.lastIndexOf("\n", max - 1);
|
|
79
|
+
if (cut >= 0)
|
|
80
|
+
return text.slice(0, cut + 1);
|
|
81
|
+
return hardCut ? text.slice(0, max) : "";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* One page of patches: every file in review order, with patch content for the files from the
|
|
85
|
+
* cursor on until `budget` characters are used. `load` is called only for files on this page
|
|
86
|
+
* (undefined: the host has no patch, which is unavailable when the file has changes).
|
|
87
|
+
*/
|
|
88
|
+
export async function pagePatches(sources, opts, load) {
|
|
89
|
+
const ordered = reviewOrder(sources);
|
|
90
|
+
const start = opts.cursor
|
|
91
|
+
? parseCursor(opts.cursor, opts.headSha, opts.comparedFrom, ordered.length)
|
|
92
|
+
: { fileIndex: 0, offset: 0, unavailable: [] };
|
|
93
|
+
const earlierUnavailable = new Set(start.unavailable);
|
|
94
|
+
const unavailable = [...start.unavailable];
|
|
95
|
+
let budget = opts.budget;
|
|
96
|
+
let next = null;
|
|
97
|
+
const files = [];
|
|
98
|
+
let pageHasCode = false;
|
|
99
|
+
for (const [index, source] of ordered.entries()) {
|
|
100
|
+
const { changes, ...view } = source;
|
|
101
|
+
const out = (patchStatus, patch = "", part) => ({
|
|
102
|
+
...view,
|
|
103
|
+
patch,
|
|
104
|
+
patchStatus,
|
|
105
|
+
patchTruncated: patchStatus === "later_page" || patchStatus === "unavailable" || (part?.continues ?? false),
|
|
106
|
+
...(part ? { patchOffset: part.offset, patchContinues: part.continues } : {}),
|
|
107
|
+
});
|
|
108
|
+
if (index < start.fileIndex) {
|
|
109
|
+
files.push(out(changes === 0 ? "empty" : earlierUnavailable.has(index) ? "unavailable" : "earlier_page"));
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (next) {
|
|
113
|
+
files.push(out(changes === 0 ? "empty" : "later_page"));
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
// A page that carries code ends where the docs, lockfiles and generated files begin, so a
|
|
117
|
+
// reviewer can stop paging there without that text sitting in its context.
|
|
118
|
+
if (pageHasCode && changes > 0 && reviewGroup(source.filename) === "other") {
|
|
119
|
+
files.push(out("later_page"));
|
|
120
|
+
next = { fileIndex: index, offset: 0 };
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const patch = await load(source);
|
|
124
|
+
const offset = index === start.fileIndex ? start.offset : 0;
|
|
125
|
+
if (patch === undefined || patch === "") {
|
|
126
|
+
if (offset > 0)
|
|
127
|
+
throw new PatchCursorError("malformed");
|
|
128
|
+
if (changes === 0) {
|
|
129
|
+
files.push(out("empty"));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
files.push(out("unavailable"));
|
|
133
|
+
unavailable.push(index);
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// A cursor never points at the end: the part that reaches it does not continue.
|
|
138
|
+
if (offset >= patch.length && offset > 0)
|
|
139
|
+
throw new PatchCursorError("malformed");
|
|
140
|
+
const rest = patch.slice(offset);
|
|
141
|
+
if (reviewGroup(source.filename) === "code")
|
|
142
|
+
pageHasCode = true;
|
|
143
|
+
if (rest.length <= budget) {
|
|
144
|
+
files.push(offset === 0 ? out("complete", rest) : out("partial", rest, { offset, continues: false }));
|
|
145
|
+
budget -= rest.length;
|
|
146
|
+
if (budget <= 0 && index + 1 < ordered.length)
|
|
147
|
+
next = { fileIndex: index + 1, offset: 0 };
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// A single line longer than the whole budget is cut only when nothing else is on the page;
|
|
151
|
+
// otherwise the file waits for the next page.
|
|
152
|
+
const firstContent = !files.some((f) => f.patchStatus === "complete" || f.patchStatus === "partial");
|
|
153
|
+
const part = budget > 0 ? cutAtLine(rest, budget, firstContent) : "";
|
|
154
|
+
if (part.length === 0) {
|
|
155
|
+
files.push(out("later_page"));
|
|
156
|
+
next = { fileIndex: index, offset };
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
files.push(out("partial", part, { offset, continues: true }));
|
|
160
|
+
next = { fileIndex: index, offset: offset + part.length };
|
|
161
|
+
}
|
|
162
|
+
const truncatedFiles = files.filter((f) => f.patchTruncated).map((f) => f.filename);
|
|
163
|
+
const remainingPatchFiles = files.filter((f) => f.patchStatus === "later_page" || (f.patchStatus === "partial" && f.patchContinues)).length;
|
|
164
|
+
return {
|
|
165
|
+
files,
|
|
166
|
+
truncatedFiles,
|
|
167
|
+
remainingPatchFiles,
|
|
168
|
+
nextPatchCursor: next
|
|
169
|
+
? encodeCursor(opts.headSha, opts.comparedFrom, {
|
|
170
|
+
...next,
|
|
171
|
+
unavailable: unavailable.filter((i) => i < next.fileIndex),
|
|
172
|
+
})
|
|
173
|
+
: null,
|
|
174
|
+
patchesComplete: next === null && unavailable.length === 0,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import type { CheckConclusion, InlineComment, ReviewVerdict } from "./types.js";
|
|
2
2
|
/** Agent ids are cuids; anything else could break out of the HTML comment. */
|
|
3
3
|
export declare const SAFE_AGENT_MARKER: RegExp;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* `coveredSha`: the latest head this agent reviewed after reading every file. A marker without
|
|
6
|
+
* it (an older one included) means none.
|
|
7
|
+
*/
|
|
8
|
+
export declare function reviewMarker(agentMarker: string, headSha: string, coveredSha?: string | null): string;
|
|
9
|
+
/**
|
|
10
|
+
* The review marker counts only at the very start of a body, where renderSummaryComment writes it:
|
|
11
|
+
* anywhere else it is text someone else wrote (model text the App posted, for one).
|
|
12
|
+
*/
|
|
5
13
|
export declare function hasReviewMarker(body: string, agentMarker: string): boolean;
|
|
6
14
|
export declare function parseReviewMarker(body: string, agentMarker: string): string | null;
|
|
15
|
+
/** The marker's covered head; null for a marker without one. */
|
|
16
|
+
export declare function parseCoveredMarker(body: string, agentMarker: string): string | null;
|
|
17
|
+
/**
|
|
18
|
+
* Model-written text the App posts, with each opener of a wardby marker escaped (`<!--`, shown
|
|
19
|
+
* as text), so no wardby marker can come from it. Any other `<!--` (in a code block or a
|
|
20
|
+
* ```suggestion, say) is left as written. One pass is enough: the replacement adds no `<` and no
|
|
21
|
+
* marker name, so it can never complete a new opener. wardby adds its own markers after this.
|
|
22
|
+
*/
|
|
23
|
+
export declare function escapeHtmlComments(text: string): string;
|
|
7
24
|
export declare function verdictConclusion(verdict: ReviewVerdict): CheckConclusion;
|
|
8
25
|
/** Tags an inline comment with the agent that wrote it, so only that agent resolves its thread. */
|
|
9
26
|
export declare function findingMarker(agentMarker: string): string;
|
|
@@ -12,6 +29,7 @@ export declare function renderInlineComment(comment: InlineComment, agentMarker:
|
|
|
12
29
|
export declare function renderSummaryComment(input: {
|
|
13
30
|
agentMarker: string;
|
|
14
31
|
headSha: string;
|
|
32
|
+
coveredSha?: string | null;
|
|
15
33
|
verdict: ReviewVerdict;
|
|
16
34
|
summary: string;
|
|
17
35
|
body: string;
|
|
@@ -6,20 +6,51 @@ function assertMarker(agentMarker) {
|
|
|
6
6
|
if (!SAFE_AGENT_MARKER.test(agentMarker))
|
|
7
7
|
throw new Error("review_marker_invalid");
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* `coveredSha`: the latest head this agent reviewed after reading every file. A marker without
|
|
11
|
+
* it (an older one included) means none.
|
|
12
|
+
*/
|
|
13
|
+
export function reviewMarker(agentMarker, headSha, coveredSha) {
|
|
10
14
|
assertMarker(agentMarker);
|
|
11
15
|
if (!SAFE_SHA.test(headSha))
|
|
12
16
|
throw new Error("review_marker_invalid");
|
|
13
|
-
|
|
17
|
+
if (coveredSha && !SAFE_SHA.test(coveredSha))
|
|
18
|
+
throw new Error("review_marker_invalid");
|
|
19
|
+
return `${MARKER_PREFIX}${agentMarker} sha=${headSha}${coveredSha ? ` covered=${coveredSha}` : ""} -->`;
|
|
14
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The review marker counts only at the very start of a body, where renderSummaryComment writes it:
|
|
23
|
+
* anywhere else it is text someone else wrote (model text the App posted, for one).
|
|
24
|
+
*/
|
|
15
25
|
export function hasReviewMarker(body, agentMarker) {
|
|
16
26
|
assertMarker(agentMarker);
|
|
17
|
-
return body.
|
|
27
|
+
return body.startsWith(`${MARKER_PREFIX}${agentMarker} sha=`);
|
|
18
28
|
}
|
|
19
|
-
|
|
29
|
+
function matchReviewMarker(body, agentMarker) {
|
|
20
30
|
assertMarker(agentMarker);
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
return new RegExp(`^${MARKER_PREFIX}${agentMarker} sha=([0-9a-f]{40})(?: covered=([0-9a-f]{40}))? -->`).exec(body);
|
|
32
|
+
}
|
|
33
|
+
export function parseReviewMarker(body, agentMarker) {
|
|
34
|
+
return matchReviewMarker(body, agentMarker)?.[1] ?? null;
|
|
35
|
+
}
|
|
36
|
+
/** The marker's covered head; null for a marker without one. */
|
|
37
|
+
export function parseCoveredMarker(body, agentMarker) {
|
|
38
|
+
return matchReviewMarker(body, agentMarker)?.[2] ?? null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* An HTML comment opener that starts a wardby marker: every marker wardby writes or ever wrote
|
|
42
|
+
* names `wardby…` (wardby:review/finding, wardby-status/description/latest/related) or the legacy
|
|
43
|
+
* `reevo-run…`. Case-insensitive, wider than any parse of them.
|
|
44
|
+
*/
|
|
45
|
+
const MARKER_OPENER = /<!--(?=\s*(?:wardby|reevo-run))/gi;
|
|
46
|
+
/**
|
|
47
|
+
* Model-written text the App posts, with each opener of a wardby marker escaped (`<!--`, shown
|
|
48
|
+
* as text), so no wardby marker can come from it. Any other `<!--` (in a code block or a
|
|
49
|
+
* ```suggestion, say) is left as written. One pass is enough: the replacement adds no `<` and no
|
|
50
|
+
* marker name, so it can never complete a new opener. wardby adds its own markers after this.
|
|
51
|
+
*/
|
|
52
|
+
export function escapeHtmlComments(text) {
|
|
53
|
+
return text.replace(MARKER_OPENER, "<!--");
|
|
23
54
|
}
|
|
24
55
|
export function verdictConclusion(verdict) {
|
|
25
56
|
if (verdict === "APPROVE")
|
|
@@ -47,7 +78,7 @@ export function renderInlineComment(comment, agentMarker) {
|
|
|
47
78
|
}
|
|
48
79
|
export function renderSummaryComment(input) {
|
|
49
80
|
const sections = [
|
|
50
|
-
reviewMarker(input.agentMarker, input.headSha),
|
|
81
|
+
reviewMarker(input.agentMarker, input.headSha, input.coveredSha),
|
|
51
82
|
`${BADGES[input.verdict]} — reviewed \`${input.headSha.slice(0, 7)}\``,
|
|
52
83
|
input.summary,
|
|
53
84
|
input.body,
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Host-neutral code-review surface for native agents. GitHub (./github.ts) and
|
|
3
|
-
* local git repositories (./local.ts) implement it
|
|
3
|
+
* local git repositories (./local.ts) implement it, and registered host providers add their own. Every method
|
|
4
4
|
* takes the repository and mints its own least-permission credential — no
|
|
5
5
|
* method accepts a token or a permission. See
|
|
6
6
|
* docs/private/2026-09-25-code-review-host-design.md §5.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
export
|
|
8
|
+
/** Compiled-in hosts. Registered host providers add their own names at runtime. */
|
|
9
|
+
export type BuiltInHostProvider = "github" | "local";
|
|
10
|
+
export type ReviewHostProvider = BuiltInHostProvider | (string & {});
|
|
11
|
+
export declare const REVIEW_HOST_PROVIDERS: readonly BuiltInHostProvider[];
|
|
10
12
|
/** Providers with host user accounts to link (link_host_account); a local repository has none. */
|
|
11
|
-
export declare const HOST_ACCOUNT_PROVIDERS: readonly
|
|
13
|
+
export declare const HOST_ACCOUNT_PROVIDERS: readonly BuiltInHostProvider[];
|
|
12
14
|
export type ReviewVerdict = "APPROVE" | "CHANGES_REQUESTED" | "COMMENT";
|
|
13
15
|
export type CheckConclusion = "success" | "failure" | "neutral";
|
|
14
16
|
export type CommentSide = "LEFT" | "RIGHT";
|
|
17
|
+
/**
|
|
18
|
+
* Where a file's patch is in a repo_pr_read result:
|
|
19
|
+
* - complete: the whole patch is in this result;
|
|
20
|
+
* - partial: one part, starting at patchOffset; the rest comes with nextPatchCursor;
|
|
21
|
+
* - later_page: not in this result; call again with nextPatchCursor;
|
|
22
|
+
* - earlier_page: delivered by an earlier call of the same cursor chain;
|
|
23
|
+
* - unavailable: the host has no patch for it (too large, binary): read it with repo_read_file;
|
|
24
|
+
* - empty: nothing to show (no line changes, a pure rename).
|
|
25
|
+
*/
|
|
26
|
+
export type PatchStatus = "complete" | "partial" | "later_page" | "earlier_page" | "unavailable" | "empty";
|
|
15
27
|
export interface PullRequestFileView {
|
|
16
28
|
filename: string;
|
|
17
29
|
status: string;
|
|
@@ -19,7 +31,18 @@ export interface PullRequestFileView {
|
|
|
19
31
|
deletions: number;
|
|
20
32
|
previousFilename?: string;
|
|
21
33
|
patch: string;
|
|
34
|
+
/** True for later_page, unavailable, and a partial part that the next page continues. */
|
|
22
35
|
patchTruncated: boolean;
|
|
36
|
+
patchStatus: PatchStatus;
|
|
37
|
+
/** Where this part starts in the file's patch; only on partial. */
|
|
38
|
+
patchOffset?: number;
|
|
39
|
+
/** Only on partial: true when the next page continues this file, false when this part is its last. */
|
|
40
|
+
patchContinues?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** A patchCursor that is not one this deployment issued, or one for a head or compare that has moved on. */
|
|
43
|
+
export declare class PatchCursorError extends Error {
|
|
44
|
+
readonly reason: "malformed" | "stale";
|
|
45
|
+
constructor(reason: "malformed" | "stale");
|
|
23
46
|
}
|
|
24
47
|
/** One of this agent's own review threads that is still unresolved. */
|
|
25
48
|
export interface ReviewThreadView {
|
|
@@ -71,6 +94,12 @@ export interface PullRequestView {
|
|
|
71
94
|
htmlUrl: string;
|
|
72
95
|
/** Head sha recorded in this agent's summary comment, if it reviewed before. */
|
|
73
96
|
lastReviewedSha: string | null;
|
|
97
|
+
/**
|
|
98
|
+
* The latest head this agent reviewed after reading every file (a whole, uncut list of the
|
|
99
|
+
* pull request or a delta from an earlier covered head, every source/test/config file read),
|
|
100
|
+
* whatever the verdict. The only safe sinceSha for a re-review that may APPROVE.
|
|
101
|
+
*/
|
|
102
|
+
lastCoveredSha: string | null;
|
|
74
103
|
/** Set when `files` is the compare of `comparedFrom...headSha` rather than the whole PR. */
|
|
75
104
|
comparedFrom: string | null;
|
|
76
105
|
/**
|
|
@@ -80,10 +109,26 @@ export interface PullRequestView {
|
|
|
80
109
|
*/
|
|
81
110
|
baseMergedSince: boolean;
|
|
82
111
|
files: PullRequestFileView[];
|
|
112
|
+
/**
|
|
113
|
+
* False when `files` is cut: the host's listing stopped at its upper bound before every
|
|
114
|
+
* changed file (on GitHub, also a compare at its 300-file limit). repo_publish_review then
|
|
115
|
+
* refuses an APPROVE of this head with file_list_truncated.
|
|
116
|
+
*/
|
|
117
|
+
fileListComplete: boolean;
|
|
118
|
+
/** No patch is left to page through and none is unavailable: with earlier pages, every patch was delivered. */
|
|
119
|
+
patchesComplete: boolean;
|
|
120
|
+
/** Files whose patch is not (fully) delivered yet: later_page, unavailable, or a partial part the next page continues; in review order. */
|
|
121
|
+
truncatedFiles: string[];
|
|
122
|
+
/** Pass as repo_pr_read's patchCursor for the next page; null when nothing is left to page. */
|
|
123
|
+
nextPatchCursor: string | null;
|
|
124
|
+
/** Estimate of files with patch content still to come after this page (a partial file counts once); a later_page file may turn out empty or unavailable once loaded. */
|
|
125
|
+
remainingPatchFiles: number;
|
|
83
126
|
/** This agent's own unresolved review threads on the PR (the first 100 threads are searched). */
|
|
84
127
|
openThreads: ReviewThreadView[];
|
|
85
128
|
/** CI on headSha (check runs and commit statuses, minus wardby's own); absent on hosts that can't read CI. */
|
|
86
129
|
ci?: CiView;
|
|
130
|
+
/** Only on a wardby pull request with a pending proposal in its description comment. */
|
|
131
|
+
descriptionProposal?: DescriptionProposalView;
|
|
87
132
|
}
|
|
88
133
|
export interface PullRequestHead {
|
|
89
134
|
headSha: string;
|
|
@@ -120,6 +165,59 @@ export type FileReadResult = {
|
|
|
120
165
|
kind: "not_found";
|
|
121
166
|
path: string;
|
|
122
167
|
};
|
|
168
|
+
/** One issue comment; author-written text, untrusted. */
|
|
169
|
+
export interface IssueCommentView {
|
|
170
|
+
author: string | null;
|
|
171
|
+
body: string;
|
|
172
|
+
createdAt: string;
|
|
173
|
+
/** The body was cut at the per-comment cap. */
|
|
174
|
+
truncated: boolean;
|
|
175
|
+
}
|
|
176
|
+
/** An issue as repo_issue_read shows it. Title, body, labels, and comments are untrusted text. */
|
|
177
|
+
export interface IssueView {
|
|
178
|
+
number: number;
|
|
179
|
+
title: string;
|
|
180
|
+
state: "open" | "closed";
|
|
181
|
+
body: string;
|
|
182
|
+
bodyTruncated: boolean;
|
|
183
|
+
labels: string[];
|
|
184
|
+
author: string | null;
|
|
185
|
+
url: string;
|
|
186
|
+
createdAt: string;
|
|
187
|
+
updatedAt: string;
|
|
188
|
+
/** The most recent comments, oldest first. */
|
|
189
|
+
comments: IssueCommentView[];
|
|
190
|
+
/** All comments on the issue, including any left out. */
|
|
191
|
+
totalComments: number;
|
|
192
|
+
/** Anything was cut: the body, a comment, or older comments left out. */
|
|
193
|
+
truncated: boolean;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* wardby's proposed description on a pull request whose description wardby
|
|
197
|
+
* couldn't confirm as its own (from its description comment). `current`: the
|
|
198
|
+
* proposal is for the head being read; `not_for_this_head`: it isn't yet;
|
|
199
|
+
* `unavailable`: the comments couldn't be read.
|
|
200
|
+
*/
|
|
201
|
+
export type DescriptionProposalView = {
|
|
202
|
+
state: "current";
|
|
203
|
+
forHead: string;
|
|
204
|
+
runId?: string;
|
|
205
|
+
text: string;
|
|
206
|
+
truncated: boolean;
|
|
207
|
+
note: string;
|
|
208
|
+
} | {
|
|
209
|
+
state: "not_for_this_head" | "unavailable";
|
|
210
|
+
note: string;
|
|
211
|
+
};
|
|
212
|
+
export type IssueReadResult = ({
|
|
213
|
+
kind: "issue";
|
|
214
|
+
} & IssueView) | {
|
|
215
|
+
kind: "pull_request";
|
|
216
|
+
number: number;
|
|
217
|
+
} | {
|
|
218
|
+
kind: "not_found";
|
|
219
|
+
number: number;
|
|
220
|
+
};
|
|
123
221
|
export interface FileListView {
|
|
124
222
|
ref: string;
|
|
125
223
|
count: number;
|
|
@@ -157,6 +255,11 @@ export interface PublishReviewInput {
|
|
|
157
255
|
* unresolved threads on this PR are resolved; any other id is skipped.
|
|
158
256
|
*/
|
|
159
257
|
resolveThreadIds?: string[];
|
|
258
|
+
/**
|
|
259
|
+
* headSha when this review read every file of it (see PullRequestView.lastCoveredSha); null or
|
|
260
|
+
* absent otherwise, and the host keeps the earlier covered head.
|
|
261
|
+
*/
|
|
262
|
+
coveredSha?: string | null;
|
|
160
263
|
}
|
|
161
264
|
export type PublishReviewResult = {
|
|
162
265
|
published: true;
|
|
@@ -225,6 +328,7 @@ export type UpsertNamedCheckInput = {
|
|
|
225
328
|
* collaborator permission onto these directly; GitLab would map reporter ->
|
|
226
329
|
* read, developer -> write, maintainer -> maintain, owner -> admin.
|
|
227
330
|
*/
|
|
331
|
+
export type AcknowledgeOutcome = "picked_up" | "refused";
|
|
228
332
|
export type HostPermission = "none" | "read" | "triage" | "write" | "maintain" | "admin";
|
|
229
333
|
export declare const HOST_PERMISSION_RANK: Readonly<Record<HostPermission, number>>;
|
|
230
334
|
/** A host user, by its immutable numeric id (as text) and its current login. */
|
|
@@ -250,6 +354,7 @@ export interface CodeReviewHost {
|
|
|
250
354
|
sinceSha?: string;
|
|
251
355
|
maxPatchChars: number;
|
|
252
356
|
agentMarker: string;
|
|
357
|
+
patchCursor?: string;
|
|
253
358
|
}): Promise<PullRequestView>;
|
|
254
359
|
pullRequestHead(repository: string, prNumber: number): Promise<PullRequestHead>;
|
|
255
360
|
/** CI on one commit, excluding wardby's own checks. Never throws. Hosts that can't say leave it out. */
|
|
@@ -274,6 +379,11 @@ export interface CodeReviewHost {
|
|
|
274
379
|
maxLines: number;
|
|
275
380
|
}): Promise<FileReadResult>;
|
|
276
381
|
listFiles(repository: string, ref: string | undefined, pathPrefix?: string): Promise<FileListView>;
|
|
382
|
+
/** An issue and its most recent comments, read-only. Hosts without issues (a local repository) leave it out. */
|
|
383
|
+
/** `comments: false` reads the issue alone (title, body, labels), without its comments. */
|
|
384
|
+
readIssue?(repository: string, number: number, opts?: {
|
|
385
|
+
comments?: boolean;
|
|
386
|
+
}): Promise<IssueReadResult>;
|
|
277
387
|
publishReview(repository: string, input: PublishReviewInput): Promise<PublishReviewResult>;
|
|
278
388
|
/** `id` identifies the new comment for editComment; a reply is an "inline" comment, anything else "conversation". */
|
|
279
389
|
comment(repository: string, input: CommentInput): Promise<{
|
|
@@ -282,8 +392,12 @@ export interface CodeReviewHost {
|
|
|
282
392
|
}>;
|
|
283
393
|
/** Replaces the body of a comment the App wrote. */
|
|
284
394
|
editComment(repository: string, input: EditCommentInput): Promise<void>;
|
|
285
|
-
/**
|
|
286
|
-
|
|
395
|
+
/**
|
|
396
|
+
* Marks a comment as picked up (GitHub: a 👀 reaction), or as refused (😕)
|
|
397
|
+
* when its author can see the repository but lacks the access to start a
|
|
398
|
+
* run. A host without reactions may do nothing.
|
|
399
|
+
*/
|
|
400
|
+
acknowledge(repository: string, target: CommentRef, outcome?: AcknowledgeOutcome): Promise<void>;
|
|
287
401
|
startCheck(repository: string, input: StartCheckInput): Promise<{
|
|
288
402
|
checkId: string;
|
|
289
403
|
}>;
|
|
@@ -297,6 +411,22 @@ export interface CodeReviewHost {
|
|
|
297
411
|
* post checks (e.g. a local repository) leave this out.
|
|
298
412
|
*/
|
|
299
413
|
upsertNamedCheck?(repository: string, input: UpsertNamedCheckInput): Promise<void>;
|
|
414
|
+
/**
|
|
415
|
+
* This App's newest check run per name on one commit (names not found are absent).
|
|
416
|
+
* At most 10 names. Hosts that can't say leave it out.
|
|
417
|
+
*/
|
|
418
|
+
readOwnChecks?(repository: string, headSha: string, names: string[]): Promise<Map<string, OwnCheckView>>;
|
|
419
|
+
/**
|
|
420
|
+
* Marks a draft pull request this App authored ready for review, only while it is
|
|
421
|
+
* open, a draft, at `expectedHeadSha`, and carrying `expectedMarkerRunId` in its
|
|
422
|
+
* description's run marker (mirrors replaceRelatedSection's expectedMarkerRunId).
|
|
423
|
+
* "skipped" covers every refusal.
|
|
424
|
+
*/
|
|
425
|
+
markReadyForReview?(repository: string, prNumber: number, expectedHeadSha: string, expectedMarkerRunId: string): Promise<"marked" | "skipped">;
|
|
426
|
+
}
|
|
427
|
+
export interface OwnCheckView {
|
|
428
|
+
status: string;
|
|
429
|
+
conclusion: string | null;
|
|
300
430
|
}
|
|
301
431
|
export type ReviewHostErrorCode = "host_not_installed" | "host_permission_missing" | "host_api_error" | "host_invalid_response";
|
|
302
432
|
export declare class ReviewHostError extends Error {
|
|
@@ -384,6 +514,10 @@ export type HostEvent = {
|
|
|
384
514
|
author: string;
|
|
385
515
|
/** The author's immutable numeric host user id, as text; their permission is checked by it. */
|
|
386
516
|
authorId: string;
|
|
517
|
+
/** GitHub's `author_association` for the author; a hint only, never a permission. */
|
|
518
|
+
authorAssociation?: string;
|
|
519
|
+
/** Whether the repository is private, when the payload says. */
|
|
520
|
+
repositoryPrivate?: boolean;
|
|
387
521
|
/** The issue or PR the mention is on, when the payload carries it. */
|
|
388
522
|
subject?: {
|
|
389
523
|
title: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Host-neutral code-review surface for native agents. GitHub (./github.ts) and
|
|
3
|
-
* local git repositories (./local.ts) implement it
|
|
3
|
+
* local git repositories (./local.ts) implement it, and registered host providers add their own. Every method
|
|
4
4
|
* takes the repository and mints its own least-permission credential — no
|
|
5
5
|
* method accepts a token or a permission. See
|
|
6
6
|
* docs/private/2026-09-25-code-review-host-design.md §5.
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
export const REVIEW_HOST_PROVIDERS = ["github", "local"];
|
|
9
9
|
/** Providers with host user accounts to link (link_host_account); a local repository has none. */
|
|
10
10
|
export const HOST_ACCOUNT_PROVIDERS = ["github"];
|
|
11
|
+
/** A patchCursor that is not one this deployment issued, or one for a head or compare that has moved on. */
|
|
12
|
+
export class PatchCursorError extends Error {
|
|
13
|
+
reason;
|
|
14
|
+
constructor(reason) {
|
|
15
|
+
super(reason === "stale" ? "patch_cursor_stale" : "patch_cursor_malformed");
|
|
16
|
+
this.reason = reason;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
11
19
|
export const HOST_PERMISSION_RANK = {
|
|
12
20
|
none: 0,
|
|
13
21
|
read: 1,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
import { type BlobInfo, type BlobStore } from "./types.js";
|
|
3
|
+
/** The slice of a GCS File the adapter uses (the real `File` satisfies it; tests supply an in-memory fake). */
|
|
4
|
+
export interface GcsFileLike {
|
|
5
|
+
createWriteStream(options?: {
|
|
6
|
+
resumable?: boolean;
|
|
7
|
+
contentType?: string;
|
|
8
|
+
}): Writable;
|
|
9
|
+
createReadStream(): Readable;
|
|
10
|
+
getMetadata(): Promise<[
|
|
11
|
+
{
|
|
12
|
+
size?: string | number;
|
|
13
|
+
updated?: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
},
|
|
16
|
+
...unknown[]
|
|
17
|
+
]>;
|
|
18
|
+
save(data: Buffer, options?: {
|
|
19
|
+
resumable?: boolean;
|
|
20
|
+
contentType?: string;
|
|
21
|
+
}): Promise<unknown>;
|
|
22
|
+
delete(options?: {
|
|
23
|
+
ignoreNotFound?: boolean;
|
|
24
|
+
}): Promise<unknown>;
|
|
25
|
+
getSignedUrl(config: {
|
|
26
|
+
version: "v4";
|
|
27
|
+
action: "read" | "write";
|
|
28
|
+
expires: number;
|
|
29
|
+
}): Promise<[string]>;
|
|
30
|
+
}
|
|
31
|
+
export interface GcsBucketLike {
|
|
32
|
+
file(name: string): GcsFileLike;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Google Cloud Storage blob store. Credentials come from Application Default Credentials (Workload Identity on
|
|
36
|
+
* GKE); no key files. Uploads are single-request (non-resumable), so an upload that is destroyed before it
|
|
37
|
+
* finishes never creates or replaces an object.
|
|
38
|
+
*/
|
|
39
|
+
export declare class GcsBlobStore implements BlobStore {
|
|
40
|
+
private readonly bucket;
|
|
41
|
+
constructor(bucket: GcsBucketLike);
|
|
42
|
+
/** Build a store over `bucketName` using Application Default Credentials. */
|
|
43
|
+
static forBucket(bucketName: string): GcsBlobStore;
|
|
44
|
+
private file;
|
|
45
|
+
put(key: string, body: Buffer, opts?: {
|
|
46
|
+
contentType?: string;
|
|
47
|
+
}): Promise<void>;
|
|
48
|
+
get(key: string): Promise<Buffer>;
|
|
49
|
+
delete(key: string): Promise<void>;
|
|
50
|
+
signedUrl(key: string, opts: {
|
|
51
|
+
expiresSec: number;
|
|
52
|
+
method: "GET" | "PUT";
|
|
53
|
+
}): Promise<string>;
|
|
54
|
+
putStream(key: string, body: NodeJS.ReadableStream, opts?: {
|
|
55
|
+
contentType?: string;
|
|
56
|
+
maxBytes?: number;
|
|
57
|
+
}): Promise<{
|
|
58
|
+
sizeBytes: number;
|
|
59
|
+
sha256: string;
|
|
60
|
+
}>;
|
|
61
|
+
getStream(key: string): Promise<NodeJS.ReadableStream>;
|
|
62
|
+
head(key: string): Promise<BlobInfo | null>;
|
|
63
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { pipeline } from "node:stream/promises";
|
|
2
|
+
import { Storage } from "@google-cloud/storage";
|
|
3
|
+
import { collectStream, createByteMeter } from "./meter.js";
|
|
4
|
+
import { assertValidBlobKey, BlobStoreError } from "./types.js";
|
|
5
|
+
function isNotFound(error) {
|
|
6
|
+
return error?.code === 404;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Google Cloud Storage blob store. Credentials come from Application Default Credentials (Workload Identity on
|
|
10
|
+
* GKE); no key files. Uploads are single-request (non-resumable), so an upload that is destroyed before it
|
|
11
|
+
* finishes never creates or replaces an object.
|
|
12
|
+
*/
|
|
13
|
+
export class GcsBlobStore {
|
|
14
|
+
bucket;
|
|
15
|
+
constructor(bucket) {
|
|
16
|
+
this.bucket = bucket;
|
|
17
|
+
}
|
|
18
|
+
/** Build a store over `bucketName` using Application Default Credentials. */
|
|
19
|
+
static forBucket(bucketName) {
|
|
20
|
+
return new GcsBlobStore(new Storage().bucket(bucketName));
|
|
21
|
+
}
|
|
22
|
+
file(key) {
|
|
23
|
+
assertValidBlobKey(key);
|
|
24
|
+
return this.bucket.file(key);
|
|
25
|
+
}
|
|
26
|
+
async put(key, body, opts) {
|
|
27
|
+
await this.file(key).save(body, { resumable: false, contentType: opts?.contentType });
|
|
28
|
+
}
|
|
29
|
+
async get(key) {
|
|
30
|
+
return collectStream(await this.getStream(key));
|
|
31
|
+
}
|
|
32
|
+
async delete(key) {
|
|
33
|
+
await this.file(key).delete({ ignoreNotFound: true });
|
|
34
|
+
}
|
|
35
|
+
async signedUrl(key, opts) {
|
|
36
|
+
const [url] = await this.file(key).getSignedUrl({
|
|
37
|
+
version: "v4",
|
|
38
|
+
action: opts.method === "GET" ? "read" : "write",
|
|
39
|
+
expires: Date.now() + opts.expiresSec * 1000,
|
|
40
|
+
});
|
|
41
|
+
return url;
|
|
42
|
+
}
|
|
43
|
+
async putStream(key, body, opts) {
|
|
44
|
+
const file = this.file(key);
|
|
45
|
+
const meter = createByteMeter(opts?.maxBytes);
|
|
46
|
+
// pipeline destroys every stream (including the GCS write stream) on failure, which aborts the HTTP request
|
|
47
|
+
// before the object is finalized.
|
|
48
|
+
await pipeline(body, meter.stream, file.createWriteStream({ resumable: false, contentType: opts?.contentType }));
|
|
49
|
+
return { sizeBytes: meter.size(), sha256: meter.digest() };
|
|
50
|
+
}
|
|
51
|
+
async getStream(key) {
|
|
52
|
+
const file = this.file(key);
|
|
53
|
+
// createReadStream reports a missing object asynchronously; look first so callers get a typed not_found.
|
|
54
|
+
if ((await this.head(key)) === null)
|
|
55
|
+
throw new BlobStoreError("not_found");
|
|
56
|
+
return file.createReadStream();
|
|
57
|
+
}
|
|
58
|
+
async head(key) {
|
|
59
|
+
try {
|
|
60
|
+
const [metadata] = await this.file(key).getMetadata();
|
|
61
|
+
return { sizeBytes: Number(metadata.size ?? 0), updatedAt: new Date(metadata.updated ?? 0) };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (isNotFound(error))
|
|
65
|
+
return null;
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|