@wardby/cli 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
- package/dist/claude-coding-worker/driver.d.ts +21 -3
- package/dist/claude-coding-worker/driver.js +125 -17
- package/dist/claude-coding-worker/main.js +34 -6
- package/dist/claude-coding-worker/sdk.js +12 -1
- package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
- package/dist/claude-coding-worker/tool-socket.js +111 -0
- package/dist/claude-coding-worker/transcript.d.ts +18 -0
- package/dist/claude-coding-worker/transcript.js +77 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +1 -0
- package/dist/cli.js +24 -10
- package/dist/coding/continuation-wording.d.ts +35 -0
- package/dist/coding/continuation-wording.js +73 -0
- package/dist/coding/linked-issue-note.d.ts +23 -0
- package/dist/coding/linked-issue-note.js +47 -0
- package/dist/coding/merge-wording.d.ts +28 -0
- package/dist/coding/merge-wording.js +78 -0
- package/dist/coding/pr-description-note.d.ts +9 -0
- package/dist/coding/pr-description-note.js +32 -0
- package/dist/coding/profile.d.ts +46 -126
- package/dist/coding/profile.js +45 -4
- package/dist/coding/protected-path-wording.d.ts +8 -0
- package/dist/coding/protected-path-wording.js +1 -1
- package/dist/coding/protocol.d.ts +264 -346
- package/dist/coding/protocol.js +235 -12
- package/dist/coding/redact.d.ts +3 -0
- package/dist/coding/redact.js +12 -0
- package/dist/coding/registry/allowlist.d.ts +12 -0
- package/dist/coding/registry/allowlist.js +14 -1
- package/dist/coding/registry/audit-mode.d.ts +153 -0
- package/dist/coding/registry/audit-mode.js +304 -0
- package/dist/coding/registry/lockfile-shared.d.ts +36 -0
- package/dist/coding/registry/lockfile-shared.js +128 -0
- package/dist/coding/registry/lockfiles.js +1 -1
- package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
- package/dist/coding/registry/npm-lockfile-formats.js +41 -0
- package/dist/coding/registry/npm-lockfile.d.ts +8 -4
- package/dist/coding/registry/npm-lockfile.js +4 -6
- package/dist/coding/registry/npm.js +78 -8
- package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
- package/dist/coding/registry/pnpm-lockfile.js +189 -0
- package/dist/coding/registry/pypi-plan.d.ts +50 -0
- package/dist/coding/registry/pypi-plan.js +406 -0
- package/dist/coding/registry/pypi-requirements.d.ts +58 -0
- package/dist/coding/registry/pypi-requirements.js +155 -0
- package/dist/coding/registry/pypi.d.ts +3 -27
- package/dist/coding/registry/pypi.js +40 -154
- package/dist/coding/registry/refusal-hints.d.ts +20 -0
- package/dist/coding/registry/refusal-hints.js +61 -0
- package/dist/coding/registry/refusal-wording.d.ts +11 -0
- package/dist/coding/registry/refusal-wording.js +56 -0
- package/dist/coding/registry/report.d.ts +70 -8
- package/dist/coding/registry/report.js +112 -5
- package/dist/coding/registry/types.d.ts +58 -8
- package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
- package/dist/coding/registry/yarn-lockfile.js +367 -0
- package/dist/coding/services/catalog.d.ts +37 -351
- package/dist/coding/transcript/claude-code.d.ts +13 -0
- package/dist/coding/transcript/claude-code.js +273 -0
- package/dist/coding/transcript/download-protocol.d.ts +30 -0
- package/dist/coding/transcript/download-protocol.js +18 -0
- package/dist/coding/transcript/format.d.ts +20 -0
- package/dist/coding/transcript/format.js +32 -0
- package/dist/coding/transcript/recorder.d.ts +51 -0
- package/dist/coding/transcript/recorder.js +225 -0
- package/dist/coding/transcript/resume/checkout.d.ts +31 -0
- package/dist/coding/transcript/resume/checkout.js +203 -0
- package/dist/coding/transcript/resume/command.d.ts +17 -0
- package/dist/coding/transcript/resume/command.js +176 -0
- package/dist/coding/transcript/resume/download.d.ts +20 -0
- package/dist/coding/transcript/resume/download.js +153 -0
- package/dist/coding/transcript/resume/launch.d.ts +38 -0
- package/dist/coding/transcript/resume/launch.js +128 -0
- package/dist/coding/transcript/resume/session-file.d.ts +13 -0
- package/dist/coding/transcript/resume/session-file.js +79 -0
- package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
- package/dist/coding/transcript/resume/stand-in.js +49 -0
- package/dist/coding-worker/artifact.d.ts +8 -3
- package/dist/coding-worker/artifact.js +3 -1
- package/dist/coding-worker/debug-trace.d.ts +6 -5
- package/dist/coding-worker/debug-trace.js +13 -18
- package/dist/coding-worker/dependency-cache.d.mts +229 -0
- package/dist/coding-worker/dependency-cache.mjs +2123 -0
- package/dist/coding-worker/driver.d.ts +4 -3
- package/dist/coding-worker/driver.js +116 -38
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +32 -0
- package/dist/coding-worker/task-note.d.ts +11 -0
- package/dist/coding-worker/task-note.js +13 -0
- package/dist/coding-worker/types.d.ts +11 -0
- package/dist/config/dependency-cache.d.ts +23 -0
- package/dist/config/dependency-cache.js +32 -0
- package/dist/config/providers.d.ts +12 -3
- package/dist/config/providers.js +55 -5
- package/dist/config/test-simulators.d.ts +82 -0
- package/dist/config/test-simulators.js +305 -0
- package/dist/core/async-context.d.ts +2 -0
- package/dist/core/async-context.js +12 -0
- package/dist/core/budget-events.d.ts +108 -0
- package/dist/core/budget-events.js +346 -0
- package/dist/core/budget-groups.d.ts +50 -1
- package/dist/core/budget-groups.js +236 -27
- package/dist/core/budget-stopped-head.d.ts +46 -0
- package/dist/core/budget-stopped-head.js +81 -0
- package/dist/core/budget-topup.d.ts +51 -0
- package/dist/core/budget-topup.js +156 -0
- package/dist/core/budget-wording.d.ts +16 -2
- package/dist/core/budget-wording.js +40 -2
- package/dist/core/coding-queue.d.ts +2 -1
- package/dist/core/coding-queue.js +7 -0
- package/dist/core/cron.d.ts +19 -1
- package/dist/core/cron.js +17 -0
- package/dist/core/datastores.js +1 -1
- package/dist/core/deferred-coding.d.ts +14 -0
- package/dist/core/deferred-coding.js +62 -0
- package/dist/core/delegation-child.d.ts +25 -0
- package/dist/core/delegation-child.js +37 -0
- package/dist/core/dispatch.d.ts +42 -0
- package/dist/core/dispatch.js +131 -56
- package/dist/core/engine-native.js +1 -1
- package/dist/core/error-code.d.ts +38 -0
- package/dist/core/error-code.js +168 -0
- package/dist/core/grants.d.ts +19 -6
- package/dist/core/grants.js +55 -6
- package/dist/core/host-events.d.ts +18 -2
- package/dist/core/host-events.js +284 -24
- package/dist/core/host-status.d.ts +85 -3
- package/dist/core/host-status.js +298 -20
- package/dist/core/issue-bridge.d.ts +50 -6
- package/dist/core/issue-bridge.js +124 -33
- package/dist/core/issue-events.d.ts +1 -1
- package/dist/core/issue-events.js +4 -10
- package/dist/core/issue-status.d.ts +1 -1
- package/dist/core/issue-status.js +54 -26
- package/dist/core/logger.d.ts +5 -0
- package/dist/core/logger.js +14 -1
- package/dist/core/lost-run-children.d.ts +6 -0
- package/dist/core/lost-run-children.js +32 -0
- package/dist/core/mark-ready.d.ts +34 -0
- package/dist/core/mark-ready.js +152 -0
- package/dist/core/markdown-code.d.ts +8 -0
- package/dist/core/markdown-code.js +107 -0
- package/dist/core/memory-tools.js +7 -0
- package/dist/core/merge-order-check.d.ts +2 -1
- package/dist/core/merge-order-check.js +8 -1
- package/dist/core/notification-templates.d.ts +1 -7
- package/dist/core/notification-templates.js +36 -2
- package/dist/core/pull-request-state-sync.js +2 -2
- package/dist/core/reconciler.d.ts +4 -3
- package/dist/core/reconciler.js +8 -1
- package/dist/core/related-pull-requests.d.ts +11 -3
- package/dist/core/related-pull-requests.js +27 -14
- package/dist/core/reply-parts.d.ts +21 -0
- package/dist/core/reply-parts.js +73 -0
- package/dist/core/review-fix.d.ts +1 -1
- package/dist/core/review-fix.js +2 -1
- package/dist/core/review-host-checks.d.ts +1 -1
- package/dist/core/review-host-tools.d.ts +3 -0
- package/dist/core/review-host-tools.js +99 -13
- package/dist/core/review-reads.d.ts +55 -0
- package/dist/core/review-reads.js +233 -0
- package/dist/core/run-status.d.ts +12 -0
- package/dist/core/run-status.js +12 -0
- package/dist/core/runner.d.ts +80 -34
- package/dist/core/runner.js +439 -144
- package/dist/core/schedule-start.d.ts +12 -0
- package/dist/core/schedule-start.js +14 -0
- package/dist/core/secret-broker-config.d.ts +10 -74
- package/dist/core/secret-guard.d.ts +46 -0
- package/dist/core/secret-guard.js +104 -0
- package/dist/core/secret-guarded-stores.d.ts +12 -0
- package/dist/core/secret-guarded-stores.js +41 -0
- package/dist/core/secret-spans.d.ts +50 -0
- package/dist/core/secret-spans.js +94 -0
- package/dist/core/stop-run.d.ts +46 -0
- package/dist/core/stop-run.js +61 -0
- package/dist/core/workflow-events.d.ts +14 -2
- package/dist/core/workflow-events.js +4 -0
- package/dist/core/workflow-run-events.d.ts +5 -3
- package/dist/core/workflow-run-events.js +43 -8
- package/dist/core/zod-json-schema.d.ts +4 -0
- package/dist/core/zod-json-schema.js +39 -0
- package/dist/core/zod3-window.d.ts +35 -0
- package/dist/core/zod3-window.js +124 -0
- package/dist/generated/prisma/browser.d.ts +34 -3
- package/dist/generated/prisma/client.d.ts +34 -3
- package/dist/generated/prisma/commonInputTypes.d.ts +220 -60
- package/dist/generated/prisma/enums.d.ts +10 -0
- package/dist/generated/prisma/enums.js +8 -0
- package/dist/generated/prisma/internal/class.d.ts +44 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +428 -9
- package/dist/generated/prisma/internal/prismaNamespace.js +92 -1
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +95 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +92 -1
- package/dist/generated/prisma/models/Agent.d.ts +106 -8
- package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +229 -1
- package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
- package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
- package/dist/generated/prisma/models/CodingRun.d.ts +1637 -1
- package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
- package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
- package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
- package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
- package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
- package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
- package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +738 -2
- package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
- package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
- package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
- package/dist/generated/prisma/models/RunTranscript.js +1 -0
- package/dist/generated/prisma/models.d.ts +4 -0
- package/dist/help-index.json +1320 -69
- package/dist/import/create.js +32 -3
- package/dist/import/neutral-schema.d.ts +50 -281
- package/dist/import/neutral-schema.js +5 -4
- package/dist/knowledge/check.d.ts +1 -1
- package/dist/knowledge/cli.d.ts +11 -1
- package/dist/knowledge/cli.js +37 -4
- package/dist/knowledge/concept.d.ts +3 -19
- package/dist/knowledge/location.d.ts +31 -0
- package/dist/knowledge/location.js +78 -0
- package/dist/mcp/auth/access.d.ts +10 -2
- package/dist/mcp/auth/access.js +15 -1
- package/dist/mcp/auth/ownership.d.ts +7 -7
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
- package/dist/mcp/host-events/github-ingress.d.ts +2 -0
- package/dist/mcp/host-events/github-ingress.js +2 -1
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.js +58 -10
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +33 -14
- package/dist/mcp/tools/agents.d.ts +4 -0
- package/dist/mcp/tools/agents.js +198 -16
- package/dist/mcp/tools/datastore.js +17 -8
- package/dist/mcp/tools/grants.js +9 -3
- package/dist/mcp/tools/memory.js +11 -1
- package/dist/mcp/tools/notification-channels.js +2 -2
- package/dist/mcp/tools/packages.d.ts +2 -0
- package/dist/mcp/tools/packages.js +195 -0
- package/dist/mcp/tools/repositories.js +18 -5
- package/dist/mcp/tools/run-access.d.ts +16 -0
- package/dist/mcp/tools/run-access.js +25 -0
- package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
- package/dist/mcp/tools/run-transcript-download.js +129 -0
- package/dist/mcp/tools/run-transcript.d.ts +19 -0
- package/dist/mcp/tools/run-transcript.js +70 -0
- package/dist/mcp/tools/runs.js +34 -12
- package/dist/mcp/tools/scheduling.js +3 -1
- package/dist/mcp/tools/secret-elicitation-form.js +5 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
- package/dist/mcp/tools/secret-elicitation-server.js +10 -61
- package/dist/mcp/tools/secrets.js +2 -2
- package/dist/mcp/tools/stop-run.d.ts +2 -0
- package/dist/mcp/tools/stop-run.js +82 -0
- package/dist/mcp/tools/subagents.js +2 -2
- package/dist/mcp/tools/tools.d.ts +1 -1
- package/dist/mcp/tools/tools.js +25 -9
- package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
- package/dist/mcp/transport/stdio-link-host.js +67 -0
- package/dist/mcp/transport/streamable-http.d.ts +13 -0
- package/dist/mcp/transport/streamable-http.js +41 -1
- package/dist/native-worker/docker-launcher.d.ts +38 -2
- package/dist/native-worker/docker-launcher.js +65 -5
- package/dist/native-worker/gateway-server.d.ts +41 -3
- package/dist/native-worker/gateway-server.js +124 -27
- package/dist/native-worker/gateway.d.ts +27 -1
- package/dist/native-worker/gateway.js +70 -4
- package/dist/native-worker/http-server.d.ts +3 -1
- package/dist/native-worker/http-server.js +11 -7
- package/dist/native-worker/http-transport.js +1 -1
- package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
- package/dist/native-worker/kubernetes-launcher.js +43 -3
- package/dist/native-worker/launch.d.ts +18 -1
- package/dist/native-worker/launch.js +6 -1
- package/dist/native-worker/ledger.d.ts +18 -2
- package/dist/native-worker/ledger.js +57 -4
- package/dist/native-worker/loopback.js +3 -8
- package/dist/native-worker/main.d.ts +2 -1
- package/dist/native-worker/main.js +14 -3
- package/dist/native-worker/protocol.d.ts +129 -577
- package/dist/native-worker/protocol.js +47 -1
- package/dist/native-worker/sandbox-executor.d.ts +17 -2
- package/dist/native-worker/sandbox-executor.js +78 -4
- package/dist/native-worker/stderr-redaction.d.ts +77 -0
- package/dist/native-worker/stderr-redaction.js +237 -0
- package/dist/native-worker/stdio.d.ts +1 -1
- package/dist/native-worker/stdio.js +6 -5
- package/dist/native-worker/warm-pool.d.ts +2 -2
- package/dist/native-worker/warm-pool.js +4 -4
- package/dist/native-worker/worker.js +28 -2
- package/dist/observability/metrics.js +6 -1
- package/dist/providers/auth/self-hosted.d.ts +1 -1
- package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
- package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
- package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
- package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
- package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
- package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
- package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
- package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
- package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
- package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
- package/dist/providers/coding-proxy/hold.d.ts +32 -0
- package/dist/providers/coding-proxy/hold.js +86 -0
- package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
- package/dist/providers/coding-proxy/interrupted.js +104 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
- package/dist/providers/coding-proxy/memory-ledger.js +84 -8
- package/dist/providers/coding-proxy/metering.d.ts +16 -0
- package/dist/providers/coding-proxy/metering.js +27 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
- package/dist/providers/coding-proxy/proxy.d.ts +14 -1
- package/dist/providers/coding-proxy/proxy.js +166 -14
- package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
- package/dist/providers/coding-proxy/registry/audit.js +94 -17
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
- package/dist/providers/coding-proxy/registry/plan.js +201 -48
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
- package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
- package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
- package/dist/providers/coding-proxy/registry/service.js +579 -112
- package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
- package/dist/providers/coding-proxy/registry/store.js +54 -1
- package/dist/providers/coding-proxy/runtime.d.ts +4 -0
- package/dist/providers/coding-proxy/runtime.js +78 -16
- package/dist/providers/coding-proxy/server.d.ts +6 -1
- package/dist/providers/coding-proxy/server.js +45 -1
- package/dist/providers/coding-proxy/types.d.ts +65 -1
- package/dist/providers/datastore/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +17 -2
- package/dist/providers/engine/types.js +17 -0
- package/dist/providers/executor/composition.d.ts +10 -3
- package/dist/providers/executor/composition.js +47 -7
- package/dist/providers/executor/container.d.ts +361 -8
- package/dist/providers/executor/container.js +1136 -91
- package/dist/providers/executor/dbos-status.d.ts +31 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +50 -1
- package/dist/providers/executor/dbos.js +207 -20
- package/dist/providers/executor/deferred.d.ts +12 -24
- package/dist/providers/executor/deferred.js +10 -29
- package/dist/providers/executor/in-process.d.ts +9 -1
- package/dist/providers/executor/in-process.js +14 -4
- package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
- package/dist/providers/executor/linked-issue-reader.js +30 -0
- package/dist/providers/executor/routing.d.ts +2 -0
- package/dist/providers/executor/routing.js +4 -0
- package/dist/providers/executor/types.d.ts +13 -0
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/issue-tracker/types.d.ts +17 -0
- package/dist/providers/issue-tracker/types.js +39 -1
- package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
- package/dist/providers/jobs/claude-tool-setup.js +5 -2
- package/dist/providers/jobs/docker-isolation.d.ts +8 -0
- package/dist/providers/jobs/docker-isolation.js +17 -0
- package/dist/providers/jobs/docker.d.ts +1 -0
- package/dist/providers/jobs/docker.js +27 -2
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
- package/dist/providers/jobs/kubernetes-api.js +10 -0
- package/dist/providers/jobs/kubernetes-client.js +10 -1
- package/dist/providers/jobs/kubernetes-isolation.d.ts +2 -0
- package/dist/providers/jobs/kubernetes-isolation.js +17 -1
- package/dist/providers/jobs/kubernetes.d.ts +6 -1
- package/dist/providers/jobs/kubernetes.js +105 -16
- package/dist/providers/jobs/types.d.ts +33 -0
- package/dist/providers/jobs/types.js +13 -1
- package/dist/providers/llm/anthropic.js +5 -1
- package/dist/providers/llm/bedrock.d.ts +0 -12
- package/dist/providers/llm/bedrock.js +4 -0
- package/dist/providers/llm/claude-messages.d.ts +3 -1
- package/dist/providers/llm/claude-messages.js +4 -1
- package/dist/providers/llm/claude-provider.d.ts +2 -2
- package/dist/providers/llm/claude-provider.js +2 -2
- package/dist/providers/llm/openai.d.ts +2 -2
- package/dist/providers/llm/openai.js +6 -2
- package/dist/providers/llm/routing.d.ts +2 -2
- package/dist/providers/llm/routing.js +2 -2
- package/dist/providers/llm/types.d.ts +12 -2
- package/dist/providers/review-host/github-events.d.ts +9 -1
- package/dist/providers/review-host/github-events.js +34 -12
- package/dist/providers/review-host/github.d.ts +29 -2
- package/dist/providers/review-host/github.js +224 -29
- package/dist/providers/review-host/local.d.ts +8 -4
- package/dist/providers/review-host/local.js +49 -31
- package/dist/providers/review-host/patch-pages.d.ts +41 -0
- package/dist/providers/review-host/patch-pages.js +176 -0
- package/dist/providers/review-host/review-format.d.ts +19 -1
- package/dist/providers/review-host/review-format.js +38 -7
- package/dist/providers/review-host/types.d.ts +134 -2
- package/dist/providers/review-host/types.js +8 -0
- package/dist/providers/storage/gcs.d.ts +63 -0
- package/dist/providers/storage/gcs.js +69 -0
- package/dist/providers/storage/index.d.ts +15 -0
- package/dist/providers/storage/index.js +14 -0
- package/dist/providers/storage/local.d.ts +24 -0
- package/dist/providers/storage/local.js +92 -0
- package/dist/providers/storage/meter.d.ts +14 -0
- package/dist/providers/storage/meter.js +34 -0
- package/dist/providers/storage/s3.d.ts +41 -0
- package/dist/providers/storage/s3.js +107 -0
- package/dist/providers/storage/types.d.ts +37 -3
- package/dist/providers/storage/types.js +21 -4
- package/dist/providers/vcs/git.d.ts +33 -2
- package/dist/providers/vcs/git.js +324 -22
- package/dist/providers/vcs/github-remote.d.ts +26 -3
- package/dist/providers/vcs/github-remote.js +124 -14
- package/dist/providers/vcs/github.d.ts +214 -6
- package/dist/providers/vcs/github.js +447 -45
- package/dist/providers/vcs/index.js +8 -1
- package/dist/providers/vcs/pr-description.d.ts +127 -0
- package/dist/providers/vcs/pr-description.js +270 -0
- package/dist/providers/vcs/remote.d.ts +33 -1
- package/dist/providers/vcs/routing.d.ts +4 -2
- package/dist/providers/vcs/routing.js +6 -0
- package/dist/providers/vcs/types.d.ts +80 -3
- package/dist/quickstart/coding-seed.d.ts +14 -3
- package/dist/quickstart/coding-seed.js +213 -4
- package/dist/quickstart/reviewer-prompt.d.ts +1 -1
- package/dist/quickstart/reviewer-prompt.js +6 -6
- package/dist/quickstart-images.json +1 -1
- package/dist/sandbox/generated/zod.bundle.js +62 -1
- package/dist/sandbox/generated/zod3.bundle.js +5 -0
- package/dist/sandbox/host-functions.d.ts +1 -0
- package/dist/sandbox/host-functions.js +6 -11
- package/dist/sandbox/secret-broker.js +3 -4
- package/dist/sandbox/tool-capabilities.d.ts +10 -30
- package/dist/sandbox/zod-params.d.ts +37 -5
- package/dist/sandbox/zod-params.js +181 -26
- package/dist/serve.js +8 -1
- package/dist/viewer/api-schema.d.ts +349 -2627
- package/dist/viewer/api-schema.js +7 -0
- package/dist/viewer/build-schemas.js +6 -2
- package/dist/viewer/openapi.js +2 -4
- package/dist/wardby-bin.js +10 -0
- package/docs/agent-recipes.md +58 -20
- package/docs/code-review-agents.md +551 -41
- package/docs/coding-agent-setup.md +489 -7
- package/docs/coding-packages.md +1033 -90
- package/docs/coding-services.md +27 -12
- package/docs/coding-worker-byo-images.md +20 -0
- package/docs/coding-worker-isolation.md +105 -30
- package/docs/getting-started-gke.md +124 -137
- package/docs/getting-started-identity-provider.md +10 -1
- package/docs/getting-started.md +9 -0
- package/docs/jira-agents.md +17 -8
- package/docs/knowledge/blob-not-found-semantics.md +41 -0
- package/docs/knowledge/bounded-file-descriptor.md +52 -0
- package/docs/knowledge/delegation-admission-slots.md +52 -0
- package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
- package/docs/knowledge/import-rename-target.md +52 -0
- package/docs/knowledge/index.md +57 -0
- package/docs/knowledge/log.md +9 -0
- package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
- package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
- package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
- package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
- package/docs/knowledge/overview-cli.md +74 -0
- package/docs/knowledge/overview-coding-proxy.md +72 -0
- package/docs/knowledge/overview-coding.md +72 -0
- package/docs/knowledge/overview-config.md +60 -0
- package/docs/knowledge/overview-core.md +72 -0
- package/docs/knowledge/overview-deploy.md +83 -0
- package/docs/knowledge/overview-mcp.md +61 -0
- package/docs/knowledge/overview-prisma.md +72 -0
- package/docs/knowledge/overview-providers.md +89 -0
- package/docs/knowledge/overview-sandbox.md +83 -0
- package/docs/knowledge/overview-surfaces.md +83 -0
- package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
- package/docs/knowledge/proxy-settlement-projections.md +41 -0
- package/docs/knowledge/run-pricing-first-writer.md +43 -0
- package/docs/knowledge/schedule-claim-transaction.md +41 -0
- package/docs/knowledge/secret-entry-replica-contract.md +52 -0
- package/docs/knowledge/terminal-run-first-writer.md +41 -0
- package/docs/knowledge/transactional-agent-authorization.md +52 -0
- package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
- package/docs/knowledge/warm-input-publication.md +30 -0
- package/docs/knowledge/workspace-staging-failure.md +54 -0
- package/docs/knowledge.md +54 -14
- package/docs/native-sandbox.md +119 -23
- package/docs/observability.md +4 -0
- package/docs/security-deployment.md +33 -2
- package/docs/slack-notifications.md +35 -19
- package/docs/tool-secrets.md +42 -10
- package/docs/viewer-api.openapi.yml +1 -1
- package/help/admin-viewer.md +24 -2
- package/help/architecture-agent.md +11 -6
- package/help/build-worker-image.md +3 -1
- package/help/builder-agent.md +19 -6
- package/help/code-review-agents.md +177 -6
- package/help/coding-packages.md +156 -6
- package/help/cost-attribution.md +9 -5
- package/help/creating-agents.md +14 -1
- package/help/dependency-cache.md +143 -0
- package/help/deploy-gke.md +15 -8
- package/help/errors/budget-exhausted.md +187 -0
- package/help/errors/budget-group-exhausted.md +5 -1
- package/help/errors/coding-stream-quota-exceeded.md +33 -0
- package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
- package/help/errors/continuation-closed.md +9 -12
- package/help/errors/delegation-conflict.md +24 -0
- package/help/errors/file-list-truncated.md +45 -0
- package/help/errors/full-read-required.md +49 -0
- package/help/errors/github-account-not-allowed.md +4 -0
- package/help/errors/graph-incomplete.md +43 -0
- package/help/errors/graph-limit.md +43 -0
- package/help/errors/merge-conflict.md +49 -0
- package/help/errors/native-sandbox-gateway-error.md +20 -0
- package/help/errors/native-sandbox-launch-abandoned.md +21 -0
- package/help/errors/native-sandbox-worker-exited.md +3 -2
- package/help/errors/package-not-allowed-pending.md +52 -0
- package/help/errors/package-not-allowed.md +51 -0
- package/help/errors/package-refusals.md +43 -0
- package/help/errors/patch-cursor-malformed.md +31 -0
- package/help/errors/run-lost.md +39 -0
- package/help/errors/run-transcript-download.md +44 -0
- package/help/errors/secret-in-value.md +69 -0
- package/help/errors/target-merge.md +40 -0
- package/help/fix-merge-conflicts.md +73 -0
- package/help/github-app-setup.md +132 -0
- package/help/github.md +22 -0
- package/help/identity-and-access.md +2 -0
- package/help/jira.md +23 -6
- package/help/knowledge.md +16 -7
- package/help/local-repositories.md +1 -1
- package/help/low-power-mode.md +7 -1
- package/help/merge-order-check.md +5 -0
- package/help/native-capabilities.md +29 -1
- package/help/native-sandbox.md +15 -1
- package/help/operating-agents.md +5 -0
- package/help/package-audit-mode.md +91 -0
- package/help/related-pull-requests.md +10 -7
- package/help/resume-runs-locally.md +131 -0
- package/help/review-fix-rounds.md +33 -1
- package/help/sharing-agents.md +59 -0
- package/help/slack-notifications.md +19 -5
- package/help/status-comments.md +31 -0
- package/help/stop-run.md +58 -0
- package/help/troubleshooting/budgets.md +28 -0
- package/help/troubleshooting/coding-workers.md +78 -7
- package/package.json +17 -10
- package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
- package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
- package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
- package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
- package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
- package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
- package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
- package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
- package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
- package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
- package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
- package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
- package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
- package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
- package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
- package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
- package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
- package/prisma/schema.prisma +311 -97
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { LocalRepoError, loadLocalRepoRoots, normalizeLocalRepository, resolveLocalRepository, } from "../../coding/local-repo.js";
|
|
2
2
|
import { SHA, isSafeRefName, isSafeRepoPath, localGit as git } from "../../coding/local-git.js";
|
|
3
3
|
import { skippedInListing } from "./github.js";
|
|
4
|
+
import { pagePatches } from "./patch-pages.js";
|
|
4
5
|
import { verdictConclusion } from "./review-format.js";
|
|
5
6
|
import { ReviewHostError, } from "./types.js";
|
|
6
|
-
/**
|
|
7
|
-
const MAX_PR_FILES =
|
|
7
|
+
/** A pull request's file list is cut at this many files (as GitHub's host bounds its paging). */
|
|
8
|
+
const MAX_PR_FILES = 1000;
|
|
8
9
|
const MAX_LISTED_FILES = 1000;
|
|
9
10
|
const MAX_BODY_CHARS = 8000;
|
|
10
11
|
const MAX_LOGGED_COMMITS = 100;
|
|
@@ -117,7 +118,10 @@ export class LocalReviewHost {
|
|
|
117
118
|
return false;
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Files changed between two commits (both 40-hex), with rename detection, in git's order, at
|
|
123
|
+
* most MAX_PR_FILES of them; `complete` is false when the list was cut.
|
|
124
|
+
*/
|
|
121
125
|
async changedFiles(dir, from, to) {
|
|
122
126
|
const diff = ["diff", "--no-ext-diff", "--no-textconv", "--no-color", "-M", "-z"];
|
|
123
127
|
let nameStatus;
|
|
@@ -166,23 +170,19 @@ export class LocalReviewHost {
|
|
|
166
170
|
...(counts.get(filename) ?? { additions: 0, deletions: 0 }),
|
|
167
171
|
});
|
|
168
172
|
}
|
|
169
|
-
return files.slice(0, MAX_PR_FILES);
|
|
173
|
+
return { files: files.slice(0, MAX_PR_FILES), complete: files.length <= MAX_PR_FILES };
|
|
170
174
|
}
|
|
171
|
-
/**
|
|
172
|
-
async withPatches(dir, from, to, files,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
let patch;
|
|
182
|
-
let complete = true;
|
|
175
|
+
/** Pages patches like GitHub (patch-pages.ts); a diff is run only for files on the page. */
|
|
176
|
+
async withPatches(dir, from, to, files, opts) {
|
|
177
|
+
return pagePatches(files.map((f) => ({ ...f, changes: f.additions + f.deletions })), {
|
|
178
|
+
budget: opts.maxPatchChars,
|
|
179
|
+
cursor: opts.patchCursor,
|
|
180
|
+
headSha: opts.headSha,
|
|
181
|
+
comparedFrom: opts.comparedFrom,
|
|
182
|
+
}, async (file) => {
|
|
183
|
+
const paths = file.previousFilename ? [file.previousFilename, file.filename] : [file.filename];
|
|
183
184
|
try {
|
|
184
|
-
|
|
185
|
-
patch = hunks(await git(dir, [
|
|
185
|
+
return hunks(await git(dir, [
|
|
186
186
|
"diff",
|
|
187
187
|
"--no-ext-diff",
|
|
188
188
|
"--no-textconv",
|
|
@@ -196,15 +196,10 @@ export class LocalReviewHost {
|
|
|
196
196
|
]));
|
|
197
197
|
}
|
|
198
198
|
catch {
|
|
199
|
-
// Too large for the buffer (or unreadable): no patch
|
|
200
|
-
|
|
201
|
-
complete = changes === 0;
|
|
199
|
+
// Too large for the buffer (or unreadable): no patch (unavailable when it has changes).
|
|
200
|
+
return undefined;
|
|
202
201
|
}
|
|
203
|
-
|
|
204
|
-
budget -= kept.length;
|
|
205
|
-
out.push({ ...file, patch: kept, patchTruncated: kept.length < patch.length || !complete });
|
|
206
|
-
}
|
|
207
|
-
return out;
|
|
202
|
+
});
|
|
208
203
|
}
|
|
209
204
|
async repositoryPermission(_repository, _user) {
|
|
210
205
|
return { level: "admin", login: "local" };
|
|
@@ -225,12 +220,13 @@ export class LocalReviewHost {
|
|
|
225
220
|
fail("no common ancestor between the branch and its base");
|
|
226
221
|
let from = baseSha;
|
|
227
222
|
let files = null;
|
|
223
|
+
let fileListComplete = true;
|
|
228
224
|
let comparedFrom = null;
|
|
229
225
|
let baseMergedSince = false;
|
|
230
226
|
const since = opts.sinceSha;
|
|
231
227
|
if (since && SHA.test(since) && since !== headSha && (await this.isAncestor(dir, since, headSha))) {
|
|
232
228
|
comparedFrom = since;
|
|
233
|
-
files = await this.changedFiles(dir, since, headSha);
|
|
229
|
+
({ files, complete: fileListComplete } = await this.changedFiles(dir, since, headSha));
|
|
234
230
|
from = since;
|
|
235
231
|
let merges = "0";
|
|
236
232
|
try {
|
|
@@ -243,11 +239,14 @@ export class LocalReviewHost {
|
|
|
243
239
|
if (baseMergedSince) {
|
|
244
240
|
// As on GitHub: the PR's own diff against its base, limited to files that changed since.
|
|
245
241
|
const changedSince = new Set(files.map((f) => f.filename));
|
|
246
|
-
|
|
242
|
+
const all = await this.changedFiles(dir, baseSha, headSha);
|
|
243
|
+
files = all.files.filter((f) => changedSince.has(f.filename));
|
|
244
|
+
fileListComplete &&= all.complete;
|
|
247
245
|
from = baseSha;
|
|
248
246
|
}
|
|
249
247
|
}
|
|
250
|
-
|
|
248
|
+
if (!files)
|
|
249
|
+
({ files, complete: fileListComplete } = await this.changedFiles(dir, baseSha, headSha));
|
|
251
250
|
let log = "";
|
|
252
251
|
try {
|
|
253
252
|
log = await git(dir, [
|
|
@@ -262,11 +261,23 @@ export class LocalReviewHost {
|
|
|
262
261
|
catch {
|
|
263
262
|
// The commit list is a courtesy; the diff is the review.
|
|
264
263
|
}
|
|
264
|
+
const page = await this.withPatches(dir, from, headSha, files, {
|
|
265
|
+
maxPatchChars: opts.maxPatchChars,
|
|
266
|
+
patchCursor: opts.patchCursor,
|
|
267
|
+
headSha,
|
|
268
|
+
comparedFrom,
|
|
269
|
+
});
|
|
265
270
|
const last = await this.db.localReview.findFirst({
|
|
266
271
|
where: { pullRequestId: row.id, agentId: opts.agentMarker },
|
|
267
272
|
orderBy: { createdAt: "desc" },
|
|
268
273
|
select: { headSha: true },
|
|
269
274
|
});
|
|
275
|
+
// A review that did not read every file leaves coveredSha null, so the latest covered one counts.
|
|
276
|
+
const covered = await this.db.localReview.findFirst({
|
|
277
|
+
where: { pullRequestId: row.id, agentId: opts.agentMarker, coveredSha: { not: null } },
|
|
278
|
+
orderBy: { createdAt: "desc" },
|
|
279
|
+
select: { coveredSha: true },
|
|
280
|
+
});
|
|
270
281
|
return {
|
|
271
282
|
number: row.number,
|
|
272
283
|
title: `${row.branch} into ${row.base}`,
|
|
@@ -281,9 +292,15 @@ export class LocalReviewHost {
|
|
|
281
292
|
isFork: false,
|
|
282
293
|
htmlUrl: prUrl(row),
|
|
283
294
|
lastReviewedSha: last?.headSha ?? null,
|
|
295
|
+
lastCoveredSha: covered?.coveredSha ?? null,
|
|
284
296
|
comparedFrom,
|
|
285
297
|
baseMergedSince,
|
|
286
|
-
files:
|
|
298
|
+
files: page.files,
|
|
299
|
+
fileListComplete,
|
|
300
|
+
patchesComplete: page.patchesComplete,
|
|
301
|
+
truncatedFiles: page.truncatedFiles,
|
|
302
|
+
nextPatchCursor: page.nextPatchCursor,
|
|
303
|
+
remainingPatchFiles: page.remainingPatchFiles,
|
|
287
304
|
openThreads: [],
|
|
288
305
|
ci: { headSha, state: "none", checks: [], truncated: false, statusesUnavailable: false },
|
|
289
306
|
};
|
|
@@ -385,6 +402,7 @@ export class LocalReviewHost {
|
|
|
385
402
|
pullRequestId: row.id,
|
|
386
403
|
agentId: input.agentMarker,
|
|
387
404
|
headSha: currentHeadSha,
|
|
405
|
+
coveredSha: input.coveredSha === currentHeadSha ? currentHeadSha : null,
|
|
388
406
|
verdict: input.verdict,
|
|
389
407
|
summary: input.summary,
|
|
390
408
|
body: input.body,
|
|
@@ -426,7 +444,7 @@ export class LocalReviewHost {
|
|
|
426
444
|
return { url: `${prUrl(row)}#${review.id}`, id: review.id };
|
|
427
445
|
}
|
|
428
446
|
async editComment(_repository, _input) { }
|
|
429
|
-
async acknowledge(_repository, _target) { }
|
|
447
|
+
async acknowledge(_repository, _target, _outcome) { }
|
|
430
448
|
async startCheck(_repository, _input) {
|
|
431
449
|
return { checkId: "local" };
|
|
432
450
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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 { type PullRequestFileView } from "./types.js";
|
|
7
|
+
export interface PatchSource {
|
|
8
|
+
filename: string;
|
|
9
|
+
status: string;
|
|
10
|
+
additions: number;
|
|
11
|
+
deletions: number;
|
|
12
|
+
previousFilename?: string;
|
|
13
|
+
/** Changed lines as the host counts them; 0 means there is nothing to show. */
|
|
14
|
+
changes: number;
|
|
15
|
+
}
|
|
16
|
+
export interface PatchPage {
|
|
17
|
+
files: PullRequestFileView[];
|
|
18
|
+
patchesComplete: boolean;
|
|
19
|
+
truncatedFiles: string[];
|
|
20
|
+
nextPatchCursor: string | null;
|
|
21
|
+
remainingPatchFiles: number;
|
|
22
|
+
}
|
|
23
|
+
/** The longest patchCursor this module issues or accepts; callers use it as the tool schema's maximum. */
|
|
24
|
+
export declare const MAX_PATCH_CURSOR_CHARS = 4000;
|
|
25
|
+
/** "code" (source, tests, config, migrations) is filled first; "other" is everything a review can skim. */
|
|
26
|
+
export declare function reviewGroup(path: string): "code" | "other";
|
|
27
|
+
/** Code first; the host's order within each group (stable). */
|
|
28
|
+
export declare function reviewOrder<T extends {
|
|
29
|
+
filename: string;
|
|
30
|
+
}>(files: T[]): T[];
|
|
31
|
+
/**
|
|
32
|
+
* One page of patches: every file in review order, with patch content for the files from the
|
|
33
|
+
* cursor on until `budget` characters are used. `load` is called only for files on this page
|
|
34
|
+
* (undefined: the host has no patch, which is unavailable when the file has changes).
|
|
35
|
+
*/
|
|
36
|
+
export declare function pagePatches(sources: PatchSource[], opts: {
|
|
37
|
+
budget: number;
|
|
38
|
+
cursor?: string;
|
|
39
|
+
headSha: string;
|
|
40
|
+
comparedFrom: string | null;
|
|
41
|
+
}, load: (file: PatchSource) => Promise<string | undefined>): Promise<PatchPage>;
|
|
@@ -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,
|