@wardby/cli 0.2.1 → 0.4.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 +53 -4
- package/README.md +52 -13
- package/dist/claude-coding-worker/driver.d.ts +6 -1
- package/dist/claude-coding-worker/driver.js +27 -1
- package/dist/claude-coding-worker/main.js +2 -0
- package/dist/claude-coding-worker/tool-socket.d.ts +9 -0
- package/dist/claude-coding-worker/tool-socket.js +26 -0
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +14 -4
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +284 -36
- package/dist/coding/base-commit.d.ts +6 -0
- package/dist/coding/base-commit.js +12 -0
- package/dist/coding/collect-exclude.d.ts +25 -0
- package/dist/coding/collect-exclude.js +76 -0
- package/dist/coding/profile.d.ts +67 -22
- package/dist/coding/profile.js +58 -25
- package/dist/coding/protected-path-wording.d.ts +24 -0
- package/dist/coding/protected-path-wording.js +55 -0
- package/dist/coding/protected-paths.d.ts +31 -0
- package/dist/coding/protected-paths.js +48 -0
- package/dist/coding/protocol.d.ts +91 -4
- package/dist/coding/protocol.js +123 -12
- package/dist/coding/provider.d.ts +6 -1
- package/dist/coding/provider.js +16 -9
- package/dist/coding/registry/adapters.d.ts +2 -0
- package/dist/coding/registry/adapters.js +9 -0
- package/dist/coding/registry/allowlist.d.ts +9 -0
- package/dist/coding/registry/allowlist.js +28 -0
- package/dist/coding/registry/json-scan.d.ts +55 -0
- package/dist/coding/registry/json-scan.js +191 -0
- package/dist/coding/registry/lockfiles.d.ts +6 -0
- package/dist/coding/registry/lockfiles.js +89 -0
- package/dist/coding/registry/npm-lockfile.d.ts +9 -0
- package/dist/coding/registry/npm-lockfile.js +73 -0
- package/dist/coding/registry/npm-plan.d.ts +29 -0
- package/dist/coding/registry/npm-plan.js +289 -0
- package/dist/coding/registry/npm.d.ts +7 -0
- package/dist/coding/registry/npm.js +252 -0
- package/dist/coding/registry/pypi.d.ts +4 -0
- package/dist/coding/registry/pypi.js +210 -0
- package/dist/coding/registry/report.d.ts +37 -0
- package/dist/coding/registry/report.js +31 -0
- package/dist/coding/registry/token.d.ts +4 -0
- package/dist/coding/registry/token.js +7 -0
- package/dist/coding/registry/types.d.ts +286 -0
- package/dist/coding/registry/types.js +19 -0
- package/dist/coding/registry/worker-config.d.ts +14 -0
- package/dist/coding/registry/worker-config.js +31 -0
- package/dist/coding/services/builtins.d.ts +22 -0
- package/dist/coding/services/builtins.js +85 -0
- package/dist/coding/services/catalog.d.ts +443 -0
- package/dist/coding/services/catalog.js +159 -0
- package/dist/coding/services/declaration.d.ts +11 -0
- package/dist/coding/services/declaration.js +114 -0
- package/dist/coding/services/note.d.ts +8 -0
- package/dist/coding/services/note.js +15 -0
- package/dist/coding/services/resolve.d.ts +25 -0
- package/dist/coding/services/resolve.js +50 -0
- package/dist/coding/services/wording.d.ts +25 -0
- package/dist/coding/services/wording.js +70 -0
- package/dist/coding-proxy/main.js +24 -4
- package/dist/coding-worker/artifact.d.ts +6 -0
- package/dist/coding-worker/debug-trace.d.ts +37 -0
- package/dist/coding-worker/debug-trace.js +117 -0
- package/dist/coding-worker/driver.d.ts +13 -1
- package/dist/coding-worker/driver.js +102 -13
- package/dist/coding-worker/errors.js +8 -0
- package/dist/coding-worker/main.js +10 -2
- package/dist/coding-worker/sdk.d.ts +2 -2
- package/dist/coding-worker/sdk.js +7 -2
- package/dist/coding-worker/types.d.ts +3 -0
- package/dist/config/providers.d.ts +66 -0
- package/dist/config/providers.js +137 -0
- package/dist/core/attribution.d.ts +101 -0
- package/dist/core/attribution.js +208 -0
- package/dist/core/budget-groups.d.ts +120 -10
- package/dist/core/budget-groups.js +133 -24
- package/dist/core/budget-wording.d.ts +22 -0
- package/dist/core/budget-wording.js +55 -0
- package/dist/core/coding-queue.d.ts +3 -0
- package/dist/core/coding-queue.js +6 -2
- package/dist/core/coding-service-status.d.ts +11 -0
- package/dist/core/coding-service-status.js +17 -0
- package/dist/core/cost-report.d.ts +88 -0
- package/dist/core/cost-report.js +248 -0
- package/dist/core/datastores.js +18 -2
- package/dist/core/db.d.ts +5 -1
- package/dist/core/db.js +8 -2
- package/dist/core/dispatch.d.ts +74 -7
- package/dist/core/dispatch.js +382 -47
- package/dist/core/engine-native.js +44 -14
- package/dist/core/glob.d.ts +10 -0
- package/dist/core/glob.js +33 -0
- package/dist/core/grants.d.ts +86 -0
- package/dist/core/grants.js +126 -0
- package/dist/core/host-events.d.ts +72 -0
- package/dist/core/host-events.js +597 -0
- package/dist/core/host-identity-links.d.ts +54 -0
- package/dist/core/host-identity-links.js +189 -0
- package/dist/core/host-status.d.ts +78 -0
- package/dist/core/host-status.js +228 -0
- package/dist/core/in-flight-runs.d.ts +8 -0
- package/dist/core/in-flight-runs.js +56 -0
- package/dist/core/issue-bridge.d.ts +60 -0
- package/dist/core/issue-bridge.js +189 -0
- package/dist/core/issue-dedupe.d.ts +70 -0
- package/dist/core/issue-dedupe.js +255 -0
- package/dist/core/issue-events.d.ts +42 -0
- package/dist/core/issue-events.js +155 -0
- package/dist/core/issue-status.d.ts +29 -0
- package/dist/core/issue-status.js +241 -0
- package/dist/core/issue-tracker-tools.d.ts +64 -0
- package/dist/core/issue-tracker-tools.js +850 -0
- package/dist/core/model-usage.d.ts +10 -0
- package/dist/core/model-usage.js +24 -0
- package/dist/core/provider-wording.d.ts +12 -0
- package/dist/core/provider-wording.js +44 -0
- package/dist/core/reconciler.d.ts +42 -2
- package/dist/core/reconciler.js +97 -2
- package/dist/core/repo-access.d.ts +99 -0
- package/dist/core/repo-access.js +136 -0
- package/dist/core/review-host-checks.d.ts +11 -0
- package/dist/core/review-host-checks.js +41 -0
- package/dist/core/review-host-tools.d.ts +47 -0
- package/dist/core/review-host-tools.js +354 -0
- package/dist/core/run-heartbeat.d.ts +27 -0
- package/dist/core/run-heartbeat.js +54 -0
- package/dist/core/run-pricing.d.ts +61 -0
- package/dist/core/run-pricing.js +56 -0
- package/dist/core/runner.d.ts +33 -8
- package/dist/core/runner.js +410 -62
- package/dist/core/scheduler.d.ts +4 -1
- package/dist/core/scheduler.js +3 -2
- package/dist/core/secrets.d.ts +11 -2
- package/dist/core/secrets.js +25 -6
- package/dist/core/self-defects.d.ts +80 -0
- package/dist/core/self-defects.js +180 -0
- package/dist/core/subagent-memory-tools.d.ts +1 -1
- package/dist/core/subagent-memory-tools.js +16 -3
- package/dist/core/tool-admin.d.ts +81 -0
- package/dist/core/tool-admin.js +129 -0
- package/dist/core/tool-names.d.ts +42 -0
- package/dist/core/tool-names.js +67 -0
- package/dist/core/untrusted-content.d.ts +32 -0
- package/dist/core/untrusted-content.js +72 -0
- package/dist/core/webhooks.d.ts +17 -2
- package/dist/core/webhooks.js +42 -3
- package/dist/generated/prisma/browser.d.ts +166 -0
- package/dist/generated/prisma/client.d.ts +166 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +152 -52
- package/dist/generated/prisma/enums.d.ts +13 -0
- package/dist/generated/prisma/enums.js +12 -1
- package/dist/generated/prisma/internal/class.d.ts +242 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +2571 -577
- package/dist/generated/prisma/internal/prismaNamespace.js +312 -6
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +328 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +312 -6
- package/dist/generated/prisma/models/Agent.d.ts +682 -1
- package/dist/generated/prisma/models/AgentIssueProject.d.ts +1838 -0
- package/dist/generated/prisma/models/AgentIssueProject.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +1425 -0
- package/dist/generated/prisma/models/AgentRepository.js +1 -0
- package/dist/generated/prisma/models/AgentTool.d.ts +95 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +56 -1
- package/dist/generated/prisma/models/CodingAgentProfile.d.ts +258 -7
- package/dist/generated/prisma/models/CodingProxySession.d.ts +195 -2
- package/dist/generated/prisma/models/CodingRun.d.ts +1405 -95
- package/dist/generated/prisma/models/CodingRunServiceStatus.d.ts +1404 -0
- package/dist/generated/prisma/models/CodingRunServiceStatus.js +1 -0
- package/dist/generated/prisma/models/CodingService.d.ts +1348 -0
- package/dist/generated/prisma/models/CodingService.js +1 -0
- package/dist/generated/prisma/models/HostEventDelivery.d.ts +946 -0
- package/dist/generated/prisma/models/HostEventDelivery.js +1 -0
- package/dist/generated/prisma/models/HostIdentity.d.ts +1232 -0
- package/dist/generated/prisma/models/HostIdentity.js +1 -0
- package/dist/generated/prisma/models/HostIdentityLinkRequest.d.ts +1473 -0
- package/dist/generated/prisma/models/HostIdentityLinkRequest.js +1 -0
- package/dist/generated/prisma/models/IssueFingerprint.d.ts +1183 -0
- package/dist/generated/prisma/models/IssueFingerprint.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +1255 -0
- package/dist/generated/prisma/models/IssuePullRequest.js +1 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.d.ts +1322 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.js +1 -0
- package/dist/generated/prisma/models/Principal.d.ts +455 -0
- package/dist/generated/prisma/models/RegistryAllowance.d.ts +1148 -0
- package/dist/generated/prisma/models/RegistryAllowance.js +1 -0
- package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +1219 -0
- package/dist/generated/prisma/models/RegistryApprovedVersion.js +1 -0
- package/dist/generated/prisma/models/RegistryFetch.d.ts +1428 -0
- package/dist/generated/prisma/models/RegistryFetch.js +1 -0
- package/dist/generated/prisma/models/RegistryPlanRefusal.d.ts +1294 -0
- package/dist/generated/prisma/models/RegistryPlanRefusal.js +1 -0
- package/dist/generated/prisma/models/RegistryVersionFact.d.ts +1085 -0
- package/dist/generated/prisma/models/RegistryVersionFact.js +1 -0
- package/dist/generated/prisma/models/ResourceGrant.d.ts +1437 -0
- package/dist/generated/prisma/models/ResourceGrant.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +1402 -82
- package/dist/generated/prisma/models/RunAttribution.d.ts +1259 -0
- package/dist/generated/prisma/models/RunAttribution.js +1 -0
- package/dist/generated/prisma/models/RunHostCheck.d.ts +1239 -0
- package/dist/generated/prisma/models/RunHostCheck.js +1 -0
- package/dist/generated/prisma/models/RunHostStatus.d.ts +1315 -0
- package/dist/generated/prisma/models/RunHostStatus.js +1 -0
- package/dist/generated/prisma/models/RunIssueStatus.d.ts +1199 -0
- package/dist/generated/prisma/models/RunIssueStatus.js +1 -0
- package/dist/generated/prisma/models/RunModelUsage.d.ts +1316 -0
- package/dist/generated/prisma/models/RunModelUsage.js +1 -0
- package/dist/generated/prisma/models/Tool.d.ts +15 -3
- package/dist/generated/prisma/models/WorkItem.d.ts +1408 -0
- package/dist/generated/prisma/models/WorkItem.js +1 -0
- package/dist/generated/prisma/models.d.ts +22 -0
- package/dist/help/build.d.ts +1 -0
- package/dist/help/build.js +9 -0
- package/dist/help/catalog.d.ts +24 -0
- package/dist/help/catalog.js +160 -0
- package/dist/help/cli.d.ts +2 -0
- package/dist/help/cli.js +65 -0
- package/dist/help/runtime.d.ts +3 -0
- package/dist/help/runtime.js +44 -0
- package/dist/help/search.d.ts +9 -0
- package/dist/help/search.js +104 -0
- package/dist/help-index.json +999 -0
- package/dist/import/cli-args.js +3 -2
- package/dist/import/create.d.ts +5 -0
- package/dist/import/create.js +67 -13
- package/dist/import/index.js +19 -9
- package/dist/import/neutral-schema.d.ts +18 -18
- package/dist/knowledge/check.d.ts +13 -0
- package/dist/knowledge/check.js +69 -0
- package/dist/knowledge/cli.d.ts +14 -0
- package/dist/knowledge/cli.js +67 -0
- package/dist/knowledge/concept.d.ts +54 -0
- package/dist/knowledge/concept.js +78 -0
- package/dist/knowledge/note.d.ts +11 -0
- package/dist/knowledge/note.js +39 -0
- package/dist/knowledge/relevance.d.ts +11 -0
- package/dist/knowledge/relevance.js +14 -0
- package/dist/knowledge/span-hash.d.ts +3 -0
- package/dist/knowledge/span-hash.js +16 -0
- package/dist/mcp/auth/access.d.ts +72 -0
- package/dist/mcp/auth/access.js +58 -0
- package/dist/mcp/auth/grants-cli.d.ts +149 -0
- package/dist/mcp/auth/grants-cli.js +518 -0
- package/dist/mcp/auth/host-account-cli.d.ts +2 -0
- package/dist/mcp/auth/host-account-cli.js +47 -0
- package/dist/mcp/auth/ownership.d.ts +25 -51
- package/dist/mcp/auth/ownership.js +19 -14
- package/dist/mcp/auth/repo-authorization.d.ts +22 -0
- package/dist/mcp/auth/repo-authorization.js +51 -0
- package/dist/mcp/auth/resource-server.d.ts +33 -2
- package/dist/mcp/auth/resource-server.js +99 -3
- package/dist/mcp/auth/self-hosted/browser.js +2 -2
- package/dist/mcp/auth/self-hosted/cli.js +47 -13
- package/dist/mcp/auth/self-hosted/credentials.d.ts +23 -5
- package/dist/mcp/auth/self-hosted/credentials.js +62 -4
- package/dist/mcp/auth/self-hosted/session.d.ts +7 -6
- package/dist/mcp/context.d.ts +30 -1
- package/dist/mcp/errors.d.ts +25 -6
- package/dist/mcp/errors.js +98 -0
- package/dist/mcp/host-events/deliveries.d.ts +9 -0
- package/dist/mcp/host-events/deliveries.js +17 -0
- package/dist/mcp/host-events/github-ingress.d.ts +38 -0
- package/dist/mcp/host-events/github-ingress.js +83 -0
- package/dist/mcp/host-events/github-user-callback.d.ts +18 -0
- package/dist/mcp/host-events/github-user-callback.js +50 -0
- package/dist/mcp/host-events/jira-ingress.d.ts +29 -0
- package/dist/mcp/host-events/jira-ingress.js +92 -0
- package/dist/mcp/index.d.ts +10 -1
- package/dist/mcp/index.js +187 -19
- package/dist/mcp/server.js +32 -11
- package/dist/mcp/tools/agents.js +519 -50
- package/dist/mcp/tools/budget-groups.js +3 -3
- package/dist/mcp/tools/cost-report.d.ts +8 -0
- package/dist/mcp/tools/cost-report.js +60 -0
- package/dist/mcp/tools/datastore.js +22 -15
- package/dist/mcp/tools/grants.d.ts +2 -0
- package/dist/mcp/tools/grants.js +239 -0
- package/dist/mcp/tools/help.d.ts +5 -0
- package/dist/mcp/tools/help.js +67 -0
- package/dist/mcp/tools/host-accounts.d.ts +2 -0
- package/dist/mcp/tools/host-accounts.js +114 -0
- package/dist/mcp/tools/issue-projects.d.ts +2 -0
- package/dist/mcp/tools/issue-projects.js +238 -0
- package/dist/mcp/tools/memory.d.ts +7 -1
- package/dist/mcp/tools/memory.js +5 -5
- package/dist/mcp/tools/model-catalog.d.ts +22 -0
- package/dist/mcp/tools/model-catalog.js +423 -0
- package/dist/mcp/tools/repositories.d.ts +2 -0
- package/dist/mcp/tools/repositories.js +182 -0
- package/dist/mcp/tools/runs.d.ts +6 -0
- package/dist/mcp/tools/runs.js +60 -6
- package/dist/mcp/tools/scheduling.js +3 -6
- package/dist/mcp/tools/secrets.js +18 -6
- package/dist/mcp/tools/services.d.ts +2 -0
- package/dist/mcp/tools/services.js +222 -0
- package/dist/mcp/tools/subagents.js +52 -16
- package/dist/mcp/tools/tools.d.ts +41 -0
- package/dist/mcp/tools/tools.js +201 -40
- package/dist/mcp/tools/trigger.js +65 -7
- package/dist/mcp/tools/webhooks.js +15 -4
- package/dist/mcp/transport/streamable-http.d.ts +15 -0
- package/dist/mcp/transport/streamable-http.js +55 -3
- package/dist/mcp/webhooks/ingress.d.ts +2 -1
- package/dist/mcp/webhooks/ingress.js +9 -2
- package/dist/providers/auth/delegating.d.ts +19 -0
- package/dist/providers/auth/delegating.js +71 -0
- package/dist/providers/auth/index.d.ts +2 -0
- package/dist/providers/auth/index.js +11 -0
- package/dist/providers/auth/self-hosted.d.ts +10 -2
- package/dist/providers/auth/self-hosted.js +55 -6
- package/dist/providers/auth/types.d.ts +6 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +4 -1
- package/dist/providers/coding-proxy/memory-ledger.js +31 -3
- package/dist/providers/coding-proxy/metering.d.ts +6 -1
- package/dist/providers/coding-proxy/metering.js +41 -4
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +17 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +106 -8
- package/dist/providers/coding-proxy/proxy.d.ts +25 -2
- package/dist/providers/coding-proxy/proxy.js +561 -38
- package/dist/providers/coding-proxy/registry/audit.d.ts +131 -0
- package/dist/providers/coding-proxy/registry/audit.js +380 -0
- package/dist/providers/coding-proxy/registry/bounded-fetch.d.ts +16 -0
- package/dist/providers/coding-proxy/registry/bounded-fetch.js +77 -0
- package/dist/providers/coding-proxy/registry/plan.d.ts +58 -0
- package/dist/providers/coding-proxy/registry/plan.js +304 -0
- package/dist/providers/coding-proxy/registry/prisma-store.d.ts +34 -0
- package/dist/providers/coding-proxy/registry/prisma-store.js +151 -0
- package/dist/providers/coding-proxy/registry/service.d.ts +213 -0
- package/dist/providers/coding-proxy/registry/service.js +1137 -0
- package/dist/providers/coding-proxy/registry/store.d.ts +127 -0
- package/dist/providers/coding-proxy/registry/store.js +70 -0
- package/dist/providers/coding-proxy/runtime.d.ts +17 -0
- package/dist/providers/coding-proxy/runtime.js +63 -0
- package/dist/providers/coding-proxy/secure-fetch.js +0 -1
- package/dist/providers/coding-proxy/server.d.ts +11 -0
- package/dist/providers/coding-proxy/server.js +163 -0
- package/dist/providers/coding-proxy/types.d.ts +33 -1
- package/dist/providers/coding-proxy/types.js +12 -1
- package/dist/providers/engine/types.d.ts +29 -0
- package/dist/providers/executor/build.d.ts +2 -2
- package/dist/providers/executor/composition.d.ts +3 -0
- package/dist/providers/executor/composition.js +28 -1
- package/dist/providers/executor/container.d.ts +134 -4
- package/dist/providers/executor/container.js +394 -37
- package/dist/providers/executor/dbos.d.ts +4 -3
- package/dist/providers/executor/dbos.js +7 -5
- package/dist/providers/executor/in-process.d.ts +2 -3
- package/dist/providers/executor/routing.d.ts +13 -0
- package/dist/providers/executor/routing.js +18 -0
- package/dist/providers/executor/types.d.ts +34 -0
- package/dist/providers/issue-tracker/adf.d.ts +31 -0
- package/dist/providers/issue-tracker/adf.js +181 -0
- package/dist/providers/issue-tracker/index.d.ts +5 -0
- package/dist/providers/issue-tracker/index.js +12 -0
- package/dist/providers/issue-tracker/jira-client.d.ts +41 -0
- package/dist/providers/issue-tracker/jira-client.js +151 -0
- package/dist/providers/issue-tracker/jira-events.d.ts +3 -0
- package/dist/providers/issue-tracker/jira-events.js +98 -0
- package/dist/providers/issue-tracker/jira.d.ts +116 -0
- package/dist/providers/issue-tracker/jira.js +502 -0
- package/dist/providers/issue-tracker/types.d.ts +269 -0
- package/dist/providers/issue-tracker/types.js +16 -0
- package/dist/providers/jobs/claude-tool-setup.d.ts +23 -0
- package/dist/providers/jobs/claude-tool-setup.js +50 -0
- package/dist/providers/jobs/collect-prune.d.ts +7 -0
- package/dist/providers/jobs/collect-prune.js +27 -0
- package/dist/providers/jobs/docker-isolation.d.ts +48 -3
- package/dist/providers/jobs/docker-isolation.js +213 -22
- package/dist/providers/jobs/docker-services.d.ts +35 -0
- package/dist/providers/jobs/docker-services.js +191 -0
- package/dist/providers/jobs/docker.d.ts +53 -2
- package/dist/providers/jobs/docker.js +307 -32
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +1 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +12 -3
- package/dist/providers/jobs/kubernetes-isolation.d.ts +17 -2
- package/dist/providers/jobs/kubernetes-isolation.js +238 -57
- package/dist/providers/jobs/kubernetes-platform.d.ts +10 -4
- package/dist/providers/jobs/kubernetes-platform.js +11 -5
- package/dist/providers/jobs/kubernetes-preflight.js +3 -0
- package/dist/providers/jobs/kubernetes.d.ts +24 -2
- package/dist/providers/jobs/kubernetes.js +153 -22
- package/dist/providers/jobs/service-state.d.ts +22 -0
- package/dist/providers/jobs/service-state.js +17 -0
- package/dist/providers/jobs/types.d.ts +18 -0
- package/dist/providers/llm/anthropic.d.ts +3 -3
- package/dist/providers/llm/anthropic.js +3 -5
- package/dist/providers/llm/bedrock.d.ts +3 -3
- package/dist/providers/llm/bedrock.js +3 -8
- package/dist/providers/llm/catalog-lookup.d.ts +10 -0
- package/dist/providers/llm/catalog-lookup.js +15 -0
- package/dist/providers/llm/catalog-shipped.d.ts +18 -0
- package/dist/providers/llm/catalog-shipped.js +197 -0
- package/dist/providers/llm/catalog-store.d.ts +58 -0
- package/dist/providers/llm/catalog-store.js +138 -0
- package/dist/providers/llm/catalog-types.d.ts +66 -0
- package/dist/providers/llm/catalog-types.js +64 -0
- package/dist/providers/llm/catalog.d.ts +61 -0
- package/dist/providers/llm/catalog.js +147 -0
- package/dist/providers/llm/claude-messages.d.ts +5 -1
- package/dist/providers/llm/claude-messages.js +1 -0
- package/dist/providers/llm/claude-provider.d.ts +10 -12
- package/dist/providers/llm/claude-provider.js +15 -6
- package/dist/providers/llm/index.d.ts +9 -6
- package/dist/providers/llm/index.js +8 -5
- package/dist/providers/llm/openai.d.ts +14 -5
- package/dist/providers/llm/openai.js +24 -14
- package/dist/providers/llm/pricing-core.d.ts +5 -3
- package/dist/providers/llm/registration.js +8 -12
- package/dist/providers/llm/routing.d.ts +21 -11
- package/dist/providers/llm/routing.js +47 -13
- package/dist/providers/llm/types.d.ts +12 -0
- package/dist/providers/llm/types.js +8 -1
- package/dist/providers/review-host/diff-lines.d.ts +16 -0
- package/dist/providers/review-host/diff-lines.js +59 -0
- package/dist/providers/review-host/github-events.d.ts +6 -0
- package/dist/providers/review-host/github-events.js +226 -0
- package/dist/providers/review-host/github-user-auth.d.ts +38 -0
- package/dist/providers/review-host/github-user-auth.js +128 -0
- package/dist/providers/review-host/github.d.ts +57 -0
- package/dist/providers/review-host/github.js +568 -0
- package/dist/providers/review-host/index.d.ts +12 -0
- package/dist/providers/review-host/index.js +30 -0
- package/dist/providers/review-host/review-format.d.ts +19 -0
- package/dist/providers/review-host/review-format.js +59 -0
- package/dist/providers/review-host/types.d.ts +309 -0
- package/dist/providers/review-host/types.js +24 -0
- package/dist/providers/vcs/git.d.ts +16 -6
- package/dist/providers/vcs/git.js +78 -34
- package/dist/providers/vcs/github.d.ts +94 -3
- package/dist/providers/vcs/github.js +223 -17
- package/dist/providers/vcs/types.d.ts +48 -4
- package/dist/quickstart/index.d.ts +2 -0
- package/dist/quickstart/index.js +36 -8
- package/dist/sandbox/fetch-policy.d.ts +20 -2
- package/dist/sandbox/fetch-policy.js +64 -3
- package/dist/sandbox/host-functions.d.ts +9 -1
- package/dist/sandbox/host-functions.js +12 -5
- package/dist/serve.js +8 -2
- package/dist/viewer/api-schema.d.ts +2757 -0
- package/dist/viewer/api-schema.js +165 -0
- package/dist/viewer/build-schemas.d.ts +2 -0
- package/dist/viewer/build-schemas.js +18 -0
- package/dist/viewer/event-bus.d.ts +38 -0
- package/dist/viewer/event-bus.js +232 -0
- package/dist/viewer/graph.d.ts +40 -0
- package/dist/viewer/graph.js +243 -0
- package/dist/viewer/http.d.ts +30 -0
- package/dist/viewer/http.js +133 -0
- package/dist/viewer/run-detail.d.ts +4 -0
- package/dist/viewer/run-detail.js +61 -0
- package/dist/wardby-bin.js +11 -0
- package/docs/README.md +40 -0
- package/docs/agent-recipes.md +383 -0
- package/docs/architecture-runtime.md +90 -0
- package/docs/assets/brand/wardby-icon-512.png +0 -0
- package/docs/assets/brand/wardby-icon.svg +16 -0
- package/docs/assets/brand/wardby-mascot-profile-512.png +0 -0
- package/docs/assets/brand/wardby-mascot.png +0 -0
- package/docs/assets/brand/wardby-mascot.svg +5 -0
- package/docs/assets/wardby-workflow.svg +106 -0
- package/docs/code-review-agents.md +508 -0
- package/docs/coding-agent-setup.md +175 -0
- package/docs/coding-packages.md +455 -0
- package/docs/coding-services.md +300 -0
- package/docs/coding-worker-byo-images.md +98 -0
- package/docs/coding-worker-isolation.md +1068 -0
- package/docs/getting-started-gke.md +632 -0
- package/docs/getting-started-identity-provider.md +319 -0
- package/docs/getting-started.md +147 -0
- package/docs/jira-agents.md +649 -0
- package/docs/knowledge.md +387 -0
- package/docs/models.md +221 -0
- package/docs/observability.md +53 -0
- package/docs/release-verification.md +66 -0
- package/docs/security-deployment.md +667 -0
- package/docs/viewer-api.md +142 -0
- package/help/admin-viewer.md +39 -0
- package/help/agent-recipes.md +173 -0
- package/help/architecture-agent.md +189 -0
- package/help/builder-agent.md +80 -0
- package/help/code-review-agents.md +37 -0
- package/help/coding-packages.md +31 -0
- package/help/coding-services.md +71 -0
- package/help/cost-attribution.md +67 -0
- package/help/creating-agents.md +90 -0
- package/help/deploy-gke.md +45 -0
- package/help/deployment-targets.md +39 -0
- package/help/errors/budget-group-exhausted.md +25 -0
- package/help/errors/docker-isolation-unsupported.md +26 -0
- package/help/errors/model-unavailable.md +63 -0
- package/help/errors/protected-path.md +45 -0
- package/help/errors/repo-access.md +27 -0
- package/help/errors/service-declaration-invalid.md +27 -0
- package/help/errors/service-declaration-unavailable.md +25 -0
- package/help/errors/service-launcher-unsupported.md +30 -0
- package/help/errors/service-not-allowed.md +27 -0
- package/help/errors/service-unknown.md +23 -0
- package/help/errors/service-unready.md +49 -0
- package/help/getting-started.md +32 -0
- package/help/github.md +48 -0
- package/help/identity-and-access.md +44 -0
- package/help/jira.md +135 -0
- package/help/knowledge.md +47 -0
- package/help/mcp.md +30 -0
- package/help/models.md +90 -0
- package/help/native-capabilities.md +30 -0
- package/help/observability.md +41 -0
- package/help/operating-agents.md +36 -0
- package/help/security.md +27 -0
- package/help/troubleshooting/budgets.md +32 -0
- package/help/troubleshooting/coding-workers.md +47 -0
- package/help/troubleshooting/repository-access.md +27 -0
- package/package.json +14 -3
- package/prisma/migrations/20260925010000_coding_collect_exclude/migration.sql +8 -0
- package/prisma/migrations/20260925015000_allowed_egress_default/migration.sql +8 -0
- package/prisma/migrations/20260925020000_coding_package_registry/migration.sql +55 -0
- package/prisma/migrations/20260925030000_tool_name_per_owner/migration.sql +11 -0
- package/prisma/migrations/20260926010000_run_trigger_host_event/migration.sql +7 -0
- package/prisma/migrations/20260926020000_code_review_hosts/migration.sql +53 -0
- package/prisma/migrations/20260926030000_auth_user_roles/migration.sql +9 -0
- package/prisma/migrations/20260926040000_agent_effort/migration.sql +6 -0
- package/prisma/migrations/20260926050000_registry_lockfile_plan/migration.sql +32 -0
- package/prisma/migrations/20260926050000_repo_access_authorization/migration.sql +82 -0
- package/prisma/migrations/20260926060000_registry_plan_refusal/migration.sql +19 -0
- package/prisma/migrations/20260926100000_registry_plan_refusal_published_at/migration.sql +5 -0
- package/prisma/migrations/20260926190000_run_host_status/migration.sql +18 -0
- package/prisma/migrations/20260926210000_run_host_status_at_dispatch/migration.sql +5 -0
- package/prisma/migrations/20260927010000_resource_grants/migration.sql +72 -0
- package/prisma/migrations/20260927020000_proxy_session_budget_exhausted/migration.sql +3 -0
- package/prisma/migrations/20260927030000_coding_debug_trace/migration.sql +4 -0
- package/prisma/migrations/20260927040000_proxy_session_upstream_failure/migration.sql +3 -0
- package/prisma/migrations/20260927050000_coding_run_services/migration.sql +74 -0
- package/prisma/migrations/20260928000000_coding_run_tool_image/migration.sql +5 -0
- package/prisma/migrations/20260930000000_jira_issue_projects/migration.sql +34 -0
- package/prisma/migrations/20261001000000_jira_phase2_allowlists/migration.sql +3 -0
- package/prisma/migrations/20261001010000_jira_link_types_allowlist/migration.sql +2 -0
- package/prisma/migrations/20261002000000_jira_coding_bridge/migration.sql +28 -0
- package/prisma/migrations/20261002010000_jira_issue_creation/migration.sql +25 -0
- package/prisma/migrations/20261003000000_issue_cost_attribution/migration.sql +56 -0
- package/prisma/migrations/20261003010000_coding_run_service_status/migration.sql +23 -0
- package/prisma/migrations/20261003020000_viewer_notify/migration.sql +54 -0
- package/prisma/migrations/20261003030000_viewer_notify_fixes/migration.sql +47 -0
- package/prisma/migrations/20261003040000_viewer_indexes/migration.sql +12 -0
- package/prisma/migrations/20261004000000_model_catalog/migration.sql +26 -0
- package/prisma/schema.prisma +663 -21
- package/dist/mcp/tools/models.d.ts +0 -8
- package/dist/mcp/tools/models.js +0 -15
- package/dist/providers/llm/pricing-anthropic.d.ts +0 -4
- package/dist/providers/llm/pricing-anthropic.js +0 -30
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +0 -12
- package/dist/providers/llm/pricing-bedrock-claude.js +0 -37
- package/dist/providers/llm/pricing.d.ts +0 -30
- package/dist/providers/llm/pricing.js +0 -74
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Agent ids are cuids; anything else could break out of the HTML comment. */
|
|
2
|
+
export const SAFE_AGENT_MARKER = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
3
|
+
const SAFE_SHA = /^[0-9a-f]{40}$/;
|
|
4
|
+
const MARKER_PREFIX = "<!-- wardby:review:";
|
|
5
|
+
function assertMarker(agentMarker) {
|
|
6
|
+
if (!SAFE_AGENT_MARKER.test(agentMarker))
|
|
7
|
+
throw new Error("review_marker_invalid");
|
|
8
|
+
}
|
|
9
|
+
export function reviewMarker(agentMarker, headSha) {
|
|
10
|
+
assertMarker(agentMarker);
|
|
11
|
+
if (!SAFE_SHA.test(headSha))
|
|
12
|
+
throw new Error("review_marker_invalid");
|
|
13
|
+
return `${MARKER_PREFIX}${agentMarker} sha=${headSha} -->`;
|
|
14
|
+
}
|
|
15
|
+
export function hasReviewMarker(body, agentMarker) {
|
|
16
|
+
assertMarker(agentMarker);
|
|
17
|
+
return body.includes(`${MARKER_PREFIX}${agentMarker} sha=`);
|
|
18
|
+
}
|
|
19
|
+
export function parseReviewMarker(body, agentMarker) {
|
|
20
|
+
assertMarker(agentMarker);
|
|
21
|
+
const match = new RegExp(`${MARKER_PREFIX}${agentMarker} sha=([0-9a-f]{40}) -->`).exec(body);
|
|
22
|
+
return match ? match[1] : null;
|
|
23
|
+
}
|
|
24
|
+
export function verdictConclusion(verdict) {
|
|
25
|
+
if (verdict === "APPROVE")
|
|
26
|
+
return "success";
|
|
27
|
+
if (verdict === "CHANGES_REQUESTED")
|
|
28
|
+
return "failure";
|
|
29
|
+
return "neutral";
|
|
30
|
+
}
|
|
31
|
+
const BADGES = {
|
|
32
|
+
APPROVE: "✅ **Approved**",
|
|
33
|
+
CHANGES_REQUESTED: "❌ **Changes requested**",
|
|
34
|
+
COMMENT: "💬 **Comments**",
|
|
35
|
+
};
|
|
36
|
+
const FINDING_PREFIX = "<!-- wardby:finding:";
|
|
37
|
+
/** Tags an inline comment with the agent that wrote it, so only that agent resolves its thread. */
|
|
38
|
+
export function findingMarker(agentMarker) {
|
|
39
|
+
assertMarker(agentMarker);
|
|
40
|
+
return `${FINDING_PREFIX}${agentMarker} -->`;
|
|
41
|
+
}
|
|
42
|
+
export function hasFindingMarker(body, agentMarker) {
|
|
43
|
+
return body.includes(findingMarker(agentMarker));
|
|
44
|
+
}
|
|
45
|
+
export function renderInlineComment(comment, agentMarker) {
|
|
46
|
+
return `**[${comment.severity}]** ${comment.body}\n\n${findingMarker(agentMarker)}`;
|
|
47
|
+
}
|
|
48
|
+
export function renderSummaryComment(input) {
|
|
49
|
+
const sections = [
|
|
50
|
+
reviewMarker(input.agentMarker, input.headSha),
|
|
51
|
+
`${BADGES[input.verdict]} — reviewed \`${input.headSha.slice(0, 7)}\``,
|
|
52
|
+
input.summary,
|
|
53
|
+
input.body,
|
|
54
|
+
];
|
|
55
|
+
if (input.outside.length > 0) {
|
|
56
|
+
sections.push(["## Outside the diff", ...input.outside.map((c) => `- **[${c.severity}] ${c.path}:${c.line}** ${c.body}`)].join("\n"));
|
|
57
|
+
}
|
|
58
|
+
return sections.join("\n\n");
|
|
59
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-neutral code-review surface for native agents. GitHub is the first
|
|
3
|
+
* implementation (./github.ts); Bitbucket Cloud is anticipated. Every method
|
|
4
|
+
* takes the repository and mints its own least-permission credential — no
|
|
5
|
+
* method accepts a token or a permission. See
|
|
6
|
+
* docs/private/2026-09-25-code-review-host-design.md §5.
|
|
7
|
+
*/
|
|
8
|
+
export type ReviewHostProvider = "github";
|
|
9
|
+
export declare const REVIEW_HOST_PROVIDERS: readonly ReviewHostProvider[];
|
|
10
|
+
export type ReviewVerdict = "APPROVE" | "CHANGES_REQUESTED" | "COMMENT";
|
|
11
|
+
export type CheckConclusion = "success" | "failure" | "neutral";
|
|
12
|
+
export type CommentSide = "LEFT" | "RIGHT";
|
|
13
|
+
export interface PullRequestFileView {
|
|
14
|
+
filename: string;
|
|
15
|
+
status: string;
|
|
16
|
+
additions: number;
|
|
17
|
+
deletions: number;
|
|
18
|
+
previousFilename?: string;
|
|
19
|
+
patch: string;
|
|
20
|
+
patchTruncated: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** One of this agent's own review threads that is still unresolved. */
|
|
23
|
+
export interface ReviewThreadView {
|
|
24
|
+
/** Opaque host id; pass it back in PublishReviewInput.resolveThreadIds. */
|
|
25
|
+
id: string;
|
|
26
|
+
path: string;
|
|
27
|
+
/** The line in the current head, or null when the thread is outdated (its line no longer exists). */
|
|
28
|
+
line: number | null;
|
|
29
|
+
outdated: boolean;
|
|
30
|
+
/** The finding as posted, without its marker, capped at 1,000 characters. */
|
|
31
|
+
body: string;
|
|
32
|
+
}
|
|
33
|
+
export interface PullRequestView {
|
|
34
|
+
number: number;
|
|
35
|
+
title: string;
|
|
36
|
+
body: string;
|
|
37
|
+
author: string | null;
|
|
38
|
+
state: string;
|
|
39
|
+
merged: boolean;
|
|
40
|
+
draft: boolean;
|
|
41
|
+
baseRef: string;
|
|
42
|
+
headRef: string;
|
|
43
|
+
headSha: string;
|
|
44
|
+
isFork: boolean;
|
|
45
|
+
htmlUrl: string;
|
|
46
|
+
/** Head sha recorded in this agent's summary comment, if it reviewed before. */
|
|
47
|
+
lastReviewedSha: string | null;
|
|
48
|
+
/** Set when `files` is the compare of `comparedFrom...headSha` rather than the whole PR. */
|
|
49
|
+
comparedFrom: string | null;
|
|
50
|
+
/**
|
|
51
|
+
* The base branch was merged into the PR since `comparedFrom`: `files` is
|
|
52
|
+
* then the PR's own diff (against its base), limited to files that changed
|
|
53
|
+
* since `comparedFrom`, so base-branch changes are left out.
|
|
54
|
+
*/
|
|
55
|
+
baseMergedSince: boolean;
|
|
56
|
+
files: PullRequestFileView[];
|
|
57
|
+
/** This agent's own unresolved review threads on the PR (the first 100 threads are searched). */
|
|
58
|
+
openThreads: ReviewThreadView[];
|
|
59
|
+
}
|
|
60
|
+
export interface PullRequestHead {
|
|
61
|
+
headSha: string;
|
|
62
|
+
isFork: boolean;
|
|
63
|
+
state: string;
|
|
64
|
+
}
|
|
65
|
+
export type FileReadResult = {
|
|
66
|
+
kind: "file";
|
|
67
|
+
path: string;
|
|
68
|
+
ref: string;
|
|
69
|
+
totalLines: number;
|
|
70
|
+
startLine: number;
|
|
71
|
+
endLine: number;
|
|
72
|
+
truncated: boolean;
|
|
73
|
+
/** The window with `N: ` line-number prefixes: the display form shown to agents. */
|
|
74
|
+
content: string;
|
|
75
|
+
/** The same window without line-number prefixes, lines joined by "\n": for machine parsing. */
|
|
76
|
+
text: string;
|
|
77
|
+
} | {
|
|
78
|
+
kind: "directory";
|
|
79
|
+
path: string;
|
|
80
|
+
entries: string[];
|
|
81
|
+
} | {
|
|
82
|
+
kind: "not_found";
|
|
83
|
+
path: string;
|
|
84
|
+
};
|
|
85
|
+
export interface FileListView {
|
|
86
|
+
ref: string;
|
|
87
|
+
count: number;
|
|
88
|
+
truncated: boolean;
|
|
89
|
+
/** Display strings (path plus size) shown to agents. */
|
|
90
|
+
files: string[];
|
|
91
|
+
/** Bare repository paths, same order and length as `files`. */
|
|
92
|
+
paths: string[];
|
|
93
|
+
}
|
|
94
|
+
export interface InlineComment {
|
|
95
|
+
path: string;
|
|
96
|
+
line: number;
|
|
97
|
+
side: CommentSide;
|
|
98
|
+
severity: string;
|
|
99
|
+
body: string;
|
|
100
|
+
}
|
|
101
|
+
export interface PublishReviewInput {
|
|
102
|
+
prNumber: number;
|
|
103
|
+
headSha: string;
|
|
104
|
+
verdict: ReviewVerdict;
|
|
105
|
+
summary: string;
|
|
106
|
+
body: string;
|
|
107
|
+
comments: InlineComment[];
|
|
108
|
+
/** Identifies this agent's summary comment; the agent id. */
|
|
109
|
+
agentMarker: string;
|
|
110
|
+
/**
|
|
111
|
+
* Names a completed check to create when no checkId is supplied (a run not
|
|
112
|
+
* started by a host event). With neither, no check is created.
|
|
113
|
+
*/
|
|
114
|
+
checkName?: string;
|
|
115
|
+
/** The run's own in-progress check, when the control plane started one. */
|
|
116
|
+
checkId?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Threads to resolve because this head fixes them. Only this agent's own
|
|
119
|
+
* unresolved threads on this PR are resolved; any other id is skipped.
|
|
120
|
+
*/
|
|
121
|
+
resolveThreadIds?: string[];
|
|
122
|
+
}
|
|
123
|
+
export type PublishReviewResult = {
|
|
124
|
+
published: true;
|
|
125
|
+
reviewUrl: string | null;
|
|
126
|
+
summaryCommentUrl: string;
|
|
127
|
+
/** Null when no check was completed or created (neither checkId nor checkName). */
|
|
128
|
+
checkId: string | null;
|
|
129
|
+
/** The verdict's check mapping — informational when checkId is null. */
|
|
130
|
+
checkConclusion: CheckConclusion;
|
|
131
|
+
inlineCount: number;
|
|
132
|
+
outsideDiffCount: number;
|
|
133
|
+
resolvedThreadIds: string[];
|
|
134
|
+
/** Requested ids that were not resolved: not this agent's open thread on this PR, or the host refused. */
|
|
135
|
+
skippedThreadIds: string[];
|
|
136
|
+
} | {
|
|
137
|
+
published: false;
|
|
138
|
+
reason: "stale_head";
|
|
139
|
+
currentHeadSha: string;
|
|
140
|
+
};
|
|
141
|
+
export interface CommentInput {
|
|
142
|
+
number: number;
|
|
143
|
+
body: string;
|
|
144
|
+
replyToReviewCommentId?: string;
|
|
145
|
+
}
|
|
146
|
+
/** A comment the App wrote, to edit later: a conversation comment or a reply in a review thread. */
|
|
147
|
+
export interface EditCommentInput {
|
|
148
|
+
kind: "conversation" | "inline";
|
|
149
|
+
id: string;
|
|
150
|
+
body: string;
|
|
151
|
+
}
|
|
152
|
+
export interface CommentRef {
|
|
153
|
+
/**
|
|
154
|
+
* "conversation" = a top-level comment on an issue/PR conversation; "inline" = a comment on a diff line (review
|
|
155
|
+
* thread); "subject" = the issue or PR itself (its title/description), with `id` its number.
|
|
156
|
+
*/
|
|
157
|
+
kind: "conversation" | "inline" | "subject";
|
|
158
|
+
id: string;
|
|
159
|
+
}
|
|
160
|
+
export interface StartCheckInput {
|
|
161
|
+
headSha: string;
|
|
162
|
+
name: string;
|
|
163
|
+
}
|
|
164
|
+
export interface CompleteCheckInput {
|
|
165
|
+
checkId: string;
|
|
166
|
+
conclusion: CheckConclusion;
|
|
167
|
+
title: string;
|
|
168
|
+
summary: string;
|
|
169
|
+
text?: string;
|
|
170
|
+
detailsUrl?: string;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* A user's effective permission on one repository, host-neutral and ranked
|
|
174
|
+
* none < read < triage < write < maintain < admin. GitHub maps its
|
|
175
|
+
* collaborator permission onto these directly; GitLab would map reporter ->
|
|
176
|
+
* read, developer -> write, maintainer -> maintain, owner -> admin.
|
|
177
|
+
*/
|
|
178
|
+
export type HostPermission = "none" | "read" | "triage" | "write" | "maintain" | "admin";
|
|
179
|
+
export declare const HOST_PERMISSION_RANK: Readonly<Record<HostPermission, number>>;
|
|
180
|
+
/** A host user, by its immutable numeric id (as text) and its current login. */
|
|
181
|
+
export interface HostUser {
|
|
182
|
+
id: string;
|
|
183
|
+
login: string;
|
|
184
|
+
}
|
|
185
|
+
export interface CodeReviewHost {
|
|
186
|
+
readonly provider: ReviewHostProvider;
|
|
187
|
+
/**
|
|
188
|
+
* The user's effective permission on `repository`, asked with the App's own
|
|
189
|
+
* installation credential (never a user token). Answers only for the user
|
|
190
|
+
* with this id: a login that now names someone else is re-resolved by id,
|
|
191
|
+
* and `login` in the result is the user's current login.
|
|
192
|
+
*/
|
|
193
|
+
repositoryPermission(repository: string, user: HostUser): Promise<{
|
|
194
|
+
level: HostPermission;
|
|
195
|
+
login: string;
|
|
196
|
+
}>;
|
|
197
|
+
readPullRequest(repository: string, prNumber: number, opts: {
|
|
198
|
+
sinceSha?: string;
|
|
199
|
+
maxPatchChars: number;
|
|
200
|
+
agentMarker: string;
|
|
201
|
+
}): Promise<PullRequestView>;
|
|
202
|
+
pullRequestHead(repository: string, prNumber: number): Promise<PullRequestHead>;
|
|
203
|
+
readFile(repository: string, path: string, ref: string | undefined, window: {
|
|
204
|
+
startLine: number;
|
|
205
|
+
maxLines: number;
|
|
206
|
+
}): Promise<FileReadResult>;
|
|
207
|
+
listFiles(repository: string, ref: string | undefined, pathPrefix?: string): Promise<FileListView>;
|
|
208
|
+
publishReview(repository: string, input: PublishReviewInput): Promise<PublishReviewResult>;
|
|
209
|
+
/** `id` identifies the new comment for editComment; a reply is an "inline" comment, anything else "conversation". */
|
|
210
|
+
comment(repository: string, input: CommentInput): Promise<{
|
|
211
|
+
url: string;
|
|
212
|
+
id: string;
|
|
213
|
+
}>;
|
|
214
|
+
/** Replaces the body of a comment the App wrote. */
|
|
215
|
+
editComment(repository: string, input: EditCommentInput): Promise<void>;
|
|
216
|
+
/** Marks a comment as picked up (GitHub: a 👀 reaction); a host without reactions may do nothing. */
|
|
217
|
+
acknowledge(repository: string, target: CommentRef): Promise<void>;
|
|
218
|
+
startCheck(repository: string, input: StartCheckInput): Promise<{
|
|
219
|
+
checkId: string;
|
|
220
|
+
}>;
|
|
221
|
+
completeCheck(repository: string, input: CompleteCheckInput): Promise<void>;
|
|
222
|
+
}
|
|
223
|
+
export type ReviewHostErrorCode = "host_not_installed" | "host_permission_missing" | "host_api_error" | "host_invalid_response";
|
|
224
|
+
export declare class ReviewHostError extends Error {
|
|
225
|
+
readonly code: ReviewHostErrorCode;
|
|
226
|
+
constructor(code: ReviewHostErrorCode, message?: string);
|
|
227
|
+
}
|
|
228
|
+
export type ReviewHostRegistry = Partial<Record<ReviewHostProvider, CodeReviewHost>>;
|
|
229
|
+
/**
|
|
230
|
+
* A host's user-authorization (OAuth web) flow, used only to learn who a
|
|
231
|
+
* wardby principal is on the host. Implementations never store or return the
|
|
232
|
+
* user token: `complete` reads the user and revokes the token at once.
|
|
233
|
+
*/
|
|
234
|
+
export interface HostUserAuthorizer {
|
|
235
|
+
readonly provider: ReviewHostProvider;
|
|
236
|
+
authorizeUrl(input: {
|
|
237
|
+
state: string;
|
|
238
|
+
codeChallenge: string;
|
|
239
|
+
redirectUri: string;
|
|
240
|
+
}): string;
|
|
241
|
+
complete(input: {
|
|
242
|
+
code: string;
|
|
243
|
+
codeVerifier: string;
|
|
244
|
+
redirectUri: string;
|
|
245
|
+
}): Promise<{
|
|
246
|
+
hostUserId: string;
|
|
247
|
+
login: string;
|
|
248
|
+
}>;
|
|
249
|
+
}
|
|
250
|
+
export type HostUserAuthorizerRegistry = Partial<Record<ReviewHostProvider, HostUserAuthorizer>>;
|
|
251
|
+
/**
|
|
252
|
+
* Host-neutral shape a webhook adapter (github-events.ts) normalises its
|
|
253
|
+
* provider payload into, for src/core/host-events.ts to route.
|
|
254
|
+
*/
|
|
255
|
+
export type HostEvent = {
|
|
256
|
+
kind: "push";
|
|
257
|
+
provider: ReviewHostProvider;
|
|
258
|
+
repository: string;
|
|
259
|
+
/** The branch pushed (without refs/heads/), always the repository's default branch. */
|
|
260
|
+
branch: string;
|
|
261
|
+
before: string;
|
|
262
|
+
after: string;
|
|
263
|
+
/** Union of added/modified/removed paths over the payload's commits, deduplicated, at most 1000. */
|
|
264
|
+
changedPaths: string[];
|
|
265
|
+
/** False when GitHub truncated the commit list (> 20 commits) or paths were capped: treat every concept as in scope. */
|
|
266
|
+
changedPathsComplete: boolean;
|
|
267
|
+
} | {
|
|
268
|
+
kind: "pr_updated";
|
|
269
|
+
provider: ReviewHostProvider;
|
|
270
|
+
repository: string;
|
|
271
|
+
prNumber: number;
|
|
272
|
+
headSha: string;
|
|
273
|
+
isFork: boolean;
|
|
274
|
+
} | {
|
|
275
|
+
/** The PR was merged or closed; only drives bookkeeping on issue/PR pairs wardby recorded. */
|
|
276
|
+
kind: "pr_closed";
|
|
277
|
+
provider: ReviewHostProvider;
|
|
278
|
+
repository: string;
|
|
279
|
+
prNumber: number;
|
|
280
|
+
merged: boolean;
|
|
281
|
+
} | {
|
|
282
|
+
kind: "check_rerun";
|
|
283
|
+
provider: ReviewHostProvider;
|
|
284
|
+
repository: string;
|
|
285
|
+
prNumber: number;
|
|
286
|
+
headSha: string;
|
|
287
|
+
checkName: string;
|
|
288
|
+
} | {
|
|
289
|
+
kind: "mention";
|
|
290
|
+
provider: ReviewHostProvider;
|
|
291
|
+
repository: string;
|
|
292
|
+
number: number;
|
|
293
|
+
isPullRequest: boolean;
|
|
294
|
+
comment: CommentRef;
|
|
295
|
+
/** Set when the mention is inside an inline review thread. */
|
|
296
|
+
replyToReviewCommentId?: string;
|
|
297
|
+
/** The comment text; for a "subject" mention, the issue/PR description. */
|
|
298
|
+
body: string;
|
|
299
|
+
author: string;
|
|
300
|
+
/** The author's immutable numeric host user id, as text; their permission is checked by it. */
|
|
301
|
+
authorId: string;
|
|
302
|
+
/** The issue or PR the mention is on, when the payload carries it. */
|
|
303
|
+
subject?: {
|
|
304
|
+
title: string;
|
|
305
|
+
body: string;
|
|
306
|
+
};
|
|
307
|
+
/** The run that opened this PR, when its description carries a valid run marker. */
|
|
308
|
+
priorRunId?: string;
|
|
309
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-neutral code-review surface for native agents. GitHub is the first
|
|
3
|
+
* implementation (./github.ts); Bitbucket Cloud is anticipated. Every method
|
|
4
|
+
* takes the repository and mints its own least-permission credential — no
|
|
5
|
+
* method accepts a token or a permission. See
|
|
6
|
+
* docs/private/2026-09-25-code-review-host-design.md §5.
|
|
7
|
+
*/
|
|
8
|
+
export const REVIEW_HOST_PROVIDERS = ["github"];
|
|
9
|
+
export const HOST_PERMISSION_RANK = {
|
|
10
|
+
none: 0,
|
|
11
|
+
read: 1,
|
|
12
|
+
triage: 2,
|
|
13
|
+
write: 3,
|
|
14
|
+
maintain: 4,
|
|
15
|
+
admin: 5,
|
|
16
|
+
};
|
|
17
|
+
export class ReviewHostError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
constructor(code, message = code) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.name = "ReviewHostError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type GitHubRepositoryAccess } from "./github.js";
|
|
2
|
-
import type { FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
|
|
1
|
+
import { type GitHubRepositoryAccess, type RepositoryFileInput } from "./github.js";
|
|
2
|
+
import type { ContinuationFinishedDetails, ContinuationOutcome, FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
|
|
3
3
|
export declare const DEFAULT_MAX_CHANGED_FILES = 1000;
|
|
4
4
|
export declare const DEFAULT_MAX_DIFF_BYTES: number;
|
|
5
5
|
export interface GitCommandOptions {
|
|
@@ -43,6 +43,18 @@ export interface GitVcsProviderOptions {
|
|
|
43
43
|
/** Test-only transport override; production composition always uses github.com. */
|
|
44
44
|
cloneUrlForRepository?: (repository: string) => string;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Whether a changed path is protected, in this order: the WARDBY_PROTECTED_PATHS
|
|
48
|
+
* baseline's exception (.wardby/services.yaml, which a builder may propose; it
|
|
49
|
+
* takes effect only after merge, docs/coding-services.md) is never protected;
|
|
50
|
+
* anything else under the baseline (.wardby/**) always is, whatever the agent's
|
|
51
|
+
* exceptions say; any other path is protected when it matches one of the
|
|
52
|
+
* agent's `patterns` and is not one of its exceptions (entries with a leading
|
|
53
|
+
* "!", each a literal path, so order does not matter). The baseline is applied
|
|
54
|
+
* here, at enforcement, rather than stored, so every existing agent and
|
|
55
|
+
* in-flight run gets it.
|
|
56
|
+
*/
|
|
57
|
+
export declare function protectedPathMatcher(patterns: readonly string[]): (path: string) => boolean;
|
|
46
58
|
export declare class GitVcsProvider implements VcsProvider {
|
|
47
59
|
private readonly options;
|
|
48
60
|
private readonly rootDir;
|
|
@@ -74,10 +86,8 @@ export declare class GitVcsProvider implements VcsProvider {
|
|
|
74
86
|
* github.ts). Safe to call more than once for the same run. Same
|
|
75
87
|
* never-throw contract as notifyContinuationStarted.
|
|
76
88
|
*/
|
|
77
|
-
notifyContinuationFinished(workspace: PreparedWorkspace, outcome:
|
|
78
|
-
|
|
79
|
-
agentName?: string;
|
|
80
|
-
}): Promise<void>;
|
|
89
|
+
notifyContinuationFinished(workspace: PreparedWorkspace, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
|
|
90
|
+
readRepositoryFile(input: RepositoryFileInput): Promise<string | null>;
|
|
81
91
|
private validateInput;
|
|
82
92
|
private expectedPaths;
|
|
83
93
|
private validatePrepared;
|
|
@@ -2,7 +2,10 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { lstat, mkdir, opendir, readFile, readlink, realpath, rm } from "node:fs/promises";
|
|
3
3
|
import { isAbsolute, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { gitExcludePathspecs, normalizeCollectExclusions } from "../../coding/collect-exclude.js";
|
|
6
|
+
import { WARDBY_PROTECTED_PATHS, isProtectedPathException, isWellFormedProtectedPath, protectedPathBody, protectsSomePath, } from "../../coding/protected-paths.js";
|
|
5
7
|
import { ensurePrivateDirectory } from "../../core/private-directory.js";
|
|
8
|
+
import { globRegex } from "../../core/glob.js";
|
|
6
9
|
import { MAX_REDACTED_SPAN, redactTokenShapedValues, normalizeGitHubRepository, normalizeGitRef, } from "../../coding/protocol.js";
|
|
7
10
|
import { isSafeGitHubInstallationToken } from "./github.js";
|
|
8
11
|
export const DEFAULT_MAX_CHANGED_FILES = 1_000;
|
|
@@ -139,39 +142,40 @@ export class NodeGitCommandRunner {
|
|
|
139
142
|
});
|
|
140
143
|
}
|
|
141
144
|
}
|
|
145
|
+
/** Validates one protectedPaths entry; a leading "!" makes it an exception (see protectedPathMatcher). */
|
|
142
146
|
function validateProtectedPath(value) {
|
|
143
147
|
const path = value.trim();
|
|
144
|
-
if (!path
|
|
145
|
-
Buffer.byteLength(path, "utf8") > 512 ||
|
|
146
|
-
path.startsWith("/") ||
|
|
147
|
-
path.startsWith("./") ||
|
|
148
|
-
path.includes("\\") ||
|
|
149
|
-
path.split("/").some((part) => !part || part === "." || part === "..")) {
|
|
148
|
+
if (Buffer.byteLength(path, "utf8") > 512 || !isWellFormedProtectedPath(path)) {
|
|
150
149
|
throw new Error("vcs_protected_path_invalid");
|
|
151
150
|
}
|
|
152
151
|
return path;
|
|
153
152
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
153
|
+
/** The fixed baseline, split once: its literal exceptions and its protected globs. */
|
|
154
|
+
const WARDBY_UNPROTECTED = new Set(WARDBY_PROTECTED_PATHS.filter(isProtectedPathException).map(protectedPathBody));
|
|
155
|
+
const WARDBY_PROTECTED = WARDBY_PROTECTED_PATHS.filter((pattern) => !isProtectedPathException(pattern)).map((pattern) => globRegex(pattern));
|
|
156
|
+
/**
|
|
157
|
+
* Whether a changed path is protected, in this order: the WARDBY_PROTECTED_PATHS
|
|
158
|
+
* baseline's exception (.wardby/services.yaml, which a builder may propose; it
|
|
159
|
+
* takes effect only after merge, docs/coding-services.md) is never protected;
|
|
160
|
+
* anything else under the baseline (.wardby/**) always is, whatever the agent's
|
|
161
|
+
* exceptions say; any other path is protected when it matches one of the
|
|
162
|
+
* agent's `patterns` and is not one of its exceptions (entries with a leading
|
|
163
|
+
* "!", each a literal path, so order does not matter). The baseline is applied
|
|
164
|
+
* here, at enforcement, rather than stored, so every existing agent and
|
|
165
|
+
* in-flight run gets it.
|
|
166
|
+
*/
|
|
167
|
+
export function protectedPathMatcher(patterns) {
|
|
168
|
+
const exceptions = new Set(patterns.filter(isProtectedPathException).map(protectedPathBody));
|
|
169
|
+
const protectedPatterns = patterns
|
|
170
|
+
.filter((pattern) => !isProtectedPathException(pattern))
|
|
171
|
+
.map((pattern) => globRegex(pattern));
|
|
172
|
+
return (path) => {
|
|
173
|
+
if (WARDBY_UNPROTECTED.has(path))
|
|
174
|
+
return false;
|
|
175
|
+
if (WARDBY_PROTECTED.some((matcher) => matcher.test(path)))
|
|
176
|
+
return true;
|
|
177
|
+
return protectedPatterns.some((matcher) => matcher.test(path)) && !exceptions.has(path);
|
|
178
|
+
};
|
|
175
179
|
}
|
|
176
180
|
function validateChangedPath(path) {
|
|
177
181
|
if (!path ||
|
|
@@ -352,7 +356,15 @@ export class GitVcsProvider {
|
|
|
352
356
|
await this.inspectWorkspace(prepared.workspacePath);
|
|
353
357
|
await this.assertRemote(prepared);
|
|
354
358
|
await this.assertSafeLocalConfig(prepared.gitMetadataPath);
|
|
355
|
-
|
|
359
|
+
// Excluded paths (src/coding/collect-exclude.ts) are never collected from the worker, so
|
|
360
|
+
// they are also neither added nor deleted here: tracked files under them stay untouched.
|
|
361
|
+
await this.gitFor(prepared, [
|
|
362
|
+
"add",
|
|
363
|
+
"--all",
|
|
364
|
+
"--",
|
|
365
|
+
":/",
|
|
366
|
+
...gitExcludePathspecs(normalizeCollectExclusions(prepared.collectExclude)),
|
|
367
|
+
]);
|
|
356
368
|
const changed = nullSeparated((await this.gitFor(prepared, [
|
|
357
369
|
"diff",
|
|
358
370
|
"--cached",
|
|
@@ -364,8 +376,7 @@ export class GitVcsProvider {
|
|
|
364
376
|
])).stdout);
|
|
365
377
|
if (changed.length > this.maxChangedFiles)
|
|
366
378
|
throw new Error("vcs_changed_file_limit");
|
|
367
|
-
const
|
|
368
|
-
const protectedChange = changed.find((path) => protectedMatchers.some(({ matcher }) => matcher.test(path)));
|
|
379
|
+
const protectedChange = changed.find(protectedPathMatcher(prepared.protectedPaths));
|
|
369
380
|
if (protectedChange)
|
|
370
381
|
throw new Error(`vcs_protected_path:${protectedChange}`);
|
|
371
382
|
let diff;
|
|
@@ -412,15 +423,21 @@ export class GitVcsProvider {
|
|
|
412
423
|
// run's id), not this run's own -- this finds the existing open PR and
|
|
413
424
|
// returns it rather than creating a new one, since headRef/baseRef
|
|
414
425
|
// already match it exactly. No other change needed here: pushing a new
|
|
415
|
-
// commit onto that branch already updates the PR natively
|
|
426
|
+
// commit onto that branch already updates the PR natively -- which is
|
|
427
|
+
// also why a PR a person has since marked ready for review is accepted
|
|
428
|
+
// (acceptReadyForReview) rather than failing an already-pushed run.
|
|
416
429
|
const pullRequest = await this.options.github.createOrFindDraftPullRequest({
|
|
417
430
|
runId: prepared.continuation?.rootRunId ?? prepared.runId,
|
|
431
|
+
...(prepared.continuation ? { acceptReadyForReview: true } : {}),
|
|
418
432
|
repository: prepared.repository,
|
|
419
433
|
baseRef: prepared.baseRef,
|
|
420
434
|
headRef: prepared.headRef,
|
|
421
435
|
summary: details?.summary,
|
|
422
436
|
tests: details?.tests,
|
|
423
437
|
tag: details?.tag,
|
|
438
|
+
packages: details?.packages,
|
|
439
|
+
packageRefusals: details?.packageRefusals,
|
|
440
|
+
...(details?.issue ? { issue: details.issue } : {}),
|
|
424
441
|
});
|
|
425
442
|
return {
|
|
426
443
|
outcome: prepared.continuation ? "pull_request_updated" : "pull_request_opened",
|
|
@@ -498,14 +515,25 @@ export class GitVcsProvider {
|
|
|
498
515
|
};
|
|
499
516
|
const label = runLabel(details?.agentName, workspace.runId);
|
|
500
517
|
const summarySuffix = details?.summary ? `\n\n${details.summary}` : "";
|
|
501
|
-
const
|
|
518
|
+
const budgetSuffix = details?.budgetSentence ? ` ${details.budgetSentence}` : "";
|
|
519
|
+
const body = outcome === "succeeded"
|
|
520
|
+
? `✅ ${label} finished.${summarySuffix}`
|
|
521
|
+
: outcome === "budget_exhausted"
|
|
522
|
+
? `❌ ${label} ran out of budget.${budgetSuffix}${summarySuffix}`
|
|
523
|
+
: details?.serviceSentence
|
|
524
|
+
? `❌ ${label} could not start: ${details.serviceSentence}${summarySuffix}`
|
|
525
|
+
: details?.providerSentence
|
|
526
|
+
? `❌ ${label} could not run: ${details.providerSentence}${summarySuffix}`
|
|
527
|
+
: details?.protectedPathSentence
|
|
528
|
+
? `❌ ${label} could not open its changes: ${details.protectedPathSentence}${summarySuffix}`
|
|
529
|
+
: `❌ ${label} failed.${summarySuffix}`;
|
|
502
530
|
await Promise.allSettled([
|
|
503
531
|
this.options.github.updateContinuationStatusComment({ ...identity, body }),
|
|
504
532
|
this.options.github.completeContinuationCheckRun({
|
|
505
533
|
repository: workspace.repository,
|
|
506
534
|
headSha: workspace.baseCommit,
|
|
507
535
|
runId: workspace.runId,
|
|
508
|
-
outcome,
|
|
536
|
+
outcome: outcome === "succeeded" ? "succeeded" : "failed",
|
|
509
537
|
}),
|
|
510
538
|
]);
|
|
511
539
|
}
|
|
@@ -513,6 +541,17 @@ export class GitVcsProvider {
|
|
|
513
541
|
// Best-effort observability only -- must never affect the real run.
|
|
514
542
|
}
|
|
515
543
|
}
|
|
544
|
+
async readRepositoryFile(input) {
|
|
545
|
+
const github = this.options.github;
|
|
546
|
+
if (!github.readFileAtRef)
|
|
547
|
+
throw new Error("vcs_read_file_unsupported");
|
|
548
|
+
return github.readFileAtRef({
|
|
549
|
+
repository: normalizeGitHubRepository(input.repository),
|
|
550
|
+
ref: normalizeGitRef(input.ref),
|
|
551
|
+
path: validateChangedPath(input.path),
|
|
552
|
+
maxBytes: input.maxBytes,
|
|
553
|
+
});
|
|
554
|
+
}
|
|
516
555
|
validateInput(input) {
|
|
517
556
|
if (!SAFE_RUN_ID.test(input.runId))
|
|
518
557
|
throw new Error("vcs_run_id_invalid");
|
|
@@ -540,7 +579,10 @@ export class GitVcsProvider {
|
|
|
540
579
|
const protectedPaths = [...new Set(input.protectedPaths.map(validateProtectedPath))];
|
|
541
580
|
if (protectedPaths.length === 0 || protectedPaths.length > 128)
|
|
542
581
|
throw new Error("vcs_protected_paths_invalid");
|
|
543
|
-
|
|
582
|
+
if (!protectsSomePath(protectedPaths))
|
|
583
|
+
throw new Error("vcs_protected_paths_invalid");
|
|
584
|
+
const collectExclude = [...normalizeCollectExclusions(input.collectExclude ?? []).paths];
|
|
585
|
+
return { runId: input.runId, repository, baseRef, headRef, protectedPaths, collectExclude, continuation };
|
|
544
586
|
}
|
|
545
587
|
expectedPaths(runId) {
|
|
546
588
|
if (!SAFE_RUN_ID.test(runId))
|
|
@@ -566,6 +608,8 @@ export class GitVcsProvider {
|
|
|
566
608
|
workspace.gitMetadataPath !== expected.gitMetadataPath ||
|
|
567
609
|
workspace.protectedPaths.length !== normalized.protectedPaths.length ||
|
|
568
610
|
workspace.protectedPaths.some((path, index) => path !== normalized.protectedPaths[index]) ||
|
|
611
|
+
workspace.collectExclude.length !== normalized.collectExclude.length ||
|
|
612
|
+
workspace.collectExclude.some((path, index) => path !== normalized.collectExclude[index]) ||
|
|
569
613
|
workspace.continuation?.rootRunId !== normalized.continuation?.rootRunId) {
|
|
570
614
|
throw new Error("vcs_workspace_handle_invalid");
|
|
571
615
|
}
|