@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
package/dist/mcp/tools/runs.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { McpError } from "../errors.js";
|
|
2
|
-
import {
|
|
2
|
+
import { agentAccess, requireAgentAccess } from "../auth/access.js";
|
|
3
3
|
import { publicCodingRunResult } from "../../coding/protocol.js";
|
|
4
|
+
import { countPlanRefusals, summarizeRegistryFetches } from "../../coding/registry/report.js";
|
|
5
|
+
import { storedServiceLabels } from "../../coding/services/catalog.js";
|
|
4
6
|
import { textResult } from "./text-result.js";
|
|
7
|
+
/**
|
|
8
|
+
* Run visibility (resource-sharing grants spec §3.5, A6): a run's output is
|
|
9
|
+
* the triggerer's and the agent owner's, never every reader's. The owner
|
|
10
|
+
* (and the stdio operator) sees every run; anyone else only runs with
|
|
11
|
+
* Run.triggeredById equal to themselves.
|
|
12
|
+
*/
|
|
5
13
|
export function registerRunTools(mcp) {
|
|
6
14
|
mcp.registerTool({
|
|
7
15
|
name: "list_runs",
|
|
@@ -12,9 +20,13 @@ export function registerRunTools(mcp) {
|
|
|
12
20
|
required: ["agentId"],
|
|
13
21
|
},
|
|
14
22
|
handler: async (args, ctx) => {
|
|
15
|
-
await
|
|
23
|
+
const { access } = await requireAgentAccess(ctx, args.agentId, "read");
|
|
16
24
|
const runs = await ctx.db.run.findMany({
|
|
17
|
-
where: {
|
|
25
|
+
where: {
|
|
26
|
+
agentId: args.agentId,
|
|
27
|
+
...(args.status ? { status: args.status } : {}),
|
|
28
|
+
...(access === "owner" ? {} : { triggeredById: ctx.principal.id }),
|
|
29
|
+
},
|
|
18
30
|
take: args.limit,
|
|
19
31
|
orderBy: { startedAt: "desc" },
|
|
20
32
|
});
|
|
@@ -40,21 +52,63 @@ export function registerRunTools(mcp) {
|
|
|
40
52
|
inputSchema: { type: "object", properties: { runId: { type: "string" } }, required: ["runId"] },
|
|
41
53
|
handler: async (args, ctx) => {
|
|
42
54
|
const run = await ctx.db.run.findUnique({ where: { id: args.runId } });
|
|
55
|
+
const notFound = new McpError(404, `Run "${args.runId}" not found.`);
|
|
43
56
|
if (!run)
|
|
44
|
-
throw
|
|
45
|
-
|
|
57
|
+
throw notFound;
|
|
58
|
+
// Its triggerer keeps seeing it even after losing access to the agent;
|
|
59
|
+
// otherwise only the agent's owner. read on the agent is not enough.
|
|
60
|
+
if (run.triggeredById !== ctx.principal.id) {
|
|
61
|
+
const agent = await ctx.db.agent.findUnique({ where: { id: run.agentId } });
|
|
62
|
+
if (!agent || (await agentAccess(ctx, agent)) !== "owner")
|
|
63
|
+
throw notFound;
|
|
64
|
+
}
|
|
46
65
|
const codingRun = await ctx.db.codingRun.findUnique({
|
|
47
66
|
where: { runId: run.id },
|
|
48
|
-
select: {
|
|
67
|
+
select: {
|
|
68
|
+
result: true,
|
|
69
|
+
queuedAt: true,
|
|
70
|
+
failureCategory: true,
|
|
71
|
+
diagnosticId: true,
|
|
72
|
+
debugTrace: true,
|
|
73
|
+
services: true,
|
|
74
|
+
},
|
|
49
75
|
});
|
|
50
76
|
const codingResult = publicCodingRunResult(codingRun?.result);
|
|
51
77
|
// A pending coding run with queuedAt is waiting for a concurrency slot
|
|
52
78
|
// (CODING_MAX_CONCURRENT), not stuck.
|
|
53
79
|
const codingQueuedAt = run.status === "pending" && codingRun?.queuedAt ? codingRun.queuedAt.toISOString() : undefined;
|
|
80
|
+
// Packages served/refused only exist for coding runs; a non-coding run
|
|
81
|
+
// has no RegistryFetch rows at all, so skip the query entirely.
|
|
82
|
+
const registryFetches = codingRun
|
|
83
|
+
? await ctx.db.registryFetch.findMany({ where: { runId: run.id }, orderBy: { createdAt: "asc" } })
|
|
84
|
+
: [];
|
|
85
|
+
const { packages, packageRefusals } = summarizeRegistryFetches(registryFetches);
|
|
86
|
+
// Lockfile verification (POST /registry/<ecosystem>/-/plan): exact
|
|
87
|
+
// versions approved for the run, and distinct entries it refused.
|
|
88
|
+
const packagePlan = codingRun
|
|
89
|
+
? {
|
|
90
|
+
approved: await ctx.db.registryApprovedVersion.count({ where: { runId: run.id } }),
|
|
91
|
+
refused: countPlanRefusals(registryFetches),
|
|
92
|
+
}
|
|
93
|
+
: undefined;
|
|
94
|
+
// A failed coding run's error is only an opaque id; these two say which
|
|
95
|
+
// stage failed and are the key an operator searches the control-plane
|
|
96
|
+
// log for (the real reason is logged there, never persisted). Both are
|
|
97
|
+
// designed to be safe to show the agent's owner (schema.prisma).
|
|
98
|
+
const failureCategory = codingRun?.failureCategory ?? undefined;
|
|
99
|
+
const diagnosticId = codingRun?.diagnosticId ?? undefined;
|
|
100
|
+
// Which services the run started with ("postgres 16"); never their images or environments.
|
|
101
|
+
const services = codingRun ? storedServiceLabels(codingRun.services) : [];
|
|
54
102
|
return textResult({
|
|
55
103
|
...run,
|
|
56
104
|
...(codingResult ? { codingResult } : {}),
|
|
105
|
+
...(failureCategory ? { failureCategory } : {}),
|
|
106
|
+
...(diagnosticId ? { diagnosticId } : {}),
|
|
57
107
|
...(codingQueuedAt ? { codingQueuedAt } : {}),
|
|
108
|
+
// An admin turned on the debug trace: the worker's full trace is in its pod log.
|
|
109
|
+
...(codingRun?.debugTrace ? { debugTrace: true } : {}),
|
|
110
|
+
...(services.length > 0 ? { services } : {}),
|
|
111
|
+
...(codingRun ? { packages, packageRefusals, packagePlan } : {}),
|
|
58
112
|
});
|
|
59
113
|
},
|
|
60
114
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Prisma } from "#prisma";
|
|
2
2
|
import { validateCronExpression } from "../../core/cron.js";
|
|
3
3
|
import { McpError } from "../errors.js";
|
|
4
|
-
import {
|
|
4
|
+
import { assertAgentAccess, requireAgentAccess } from "../auth/access.js";
|
|
5
5
|
import { textResult } from "./text-result.js";
|
|
6
6
|
export function registerSchedulingTools(mcp) {
|
|
7
7
|
mcp.registerTool({
|
|
@@ -20,10 +20,7 @@ export function registerSchedulingTools(mcp) {
|
|
|
20
20
|
throw new McpError(400, `Invalid schedule/timezone: ${err instanceof Error ? err.message : String(err)}`);
|
|
21
21
|
}
|
|
22
22
|
const agent = await ctx.db.$transaction(async (tx) => {
|
|
23
|
-
const existing = await tx.agent.findUnique({ where: { id: args.agentId }, include: { codingProfile: true } });
|
|
24
|
-
if (!existing)
|
|
25
|
-
throw new McpError(404, `Agent "${args.agentId}" not found.`);
|
|
26
|
-
assertCanMutate(existing.ownerId, ctx.principal.id, `Agent "${args.agentId}" is not owned by the caller.`);
|
|
23
|
+
const { agent: existing } = await assertAgentAccess(ctx, await tx.agent.findUnique({ where: { id: args.agentId }, include: { codingProfile: true } }), args.agentId, "write", tx);
|
|
27
24
|
if (existing.kind === "coding" && !existing.codingProfile?.defaultTask) {
|
|
28
25
|
throw new McpError(400, "A default task is required before enabling a coding-agent schedule.");
|
|
29
26
|
}
|
|
@@ -40,7 +37,7 @@ export function registerSchedulingTools(mcp) {
|
|
|
40
37
|
scope: "agents:write",
|
|
41
38
|
inputSchema: { type: "object", properties: { agentId: { type: "string" } }, required: ["agentId"] },
|
|
42
39
|
handler: async (args, ctx) => {
|
|
43
|
-
await
|
|
40
|
+
await requireAgentAccess(ctx, args.agentId, "write");
|
|
44
41
|
const agent = await ctx.db.agent.update({ where: { id: args.agentId }, data: { scheduleEnabled: false } });
|
|
45
42
|
return textResult(agent);
|
|
46
43
|
},
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { inputRequired, inputResponse } from "@modelcontextprotocol/server";
|
|
7
7
|
import { createSecret, listSecrets, attachSecret, detachSecret, deleteSecret } from "../../core/secrets.js";
|
|
8
8
|
import { McpError } from "../errors.js";
|
|
9
|
-
import {
|
|
9
|
+
import { requireOwnedSecret } from "../auth/ownership.js";
|
|
10
|
+
import { requireAgentAccess, requireBindingOwner } from "../auth/access.js";
|
|
10
11
|
import { getSecretElicitationOutcome } from "./secret-elicitation.js";
|
|
11
12
|
import { textResult } from "./text-result.js";
|
|
12
13
|
export function registerSecretsTools(mcp, opts) {
|
|
@@ -87,9 +88,15 @@ export function registerSecretsTools(mcp, opts) {
|
|
|
87
88
|
required: ["agentId", "name"],
|
|
88
89
|
},
|
|
89
90
|
handler: async (args, ctx) => {
|
|
90
|
-
|
|
91
|
+
// Strictly the agent owner's own secret on the owner's own agent
|
|
92
|
+
// (A2/S2-2): a binding hands the value to every tool the owner lets
|
|
93
|
+
// read it. Not even the stdio operator crosses owners.
|
|
94
|
+
const { agent } = await requireAgentAccess(ctx, args.agentId, "read");
|
|
95
|
+
requireBindingOwner(ctx, agent);
|
|
96
|
+
const ownerId = agent.ownerId;
|
|
91
97
|
try {
|
|
92
|
-
|
|
98
|
+
// Resolved among the agent owner's secrets (== the caller here).
|
|
99
|
+
await attachSecret(args.agentId, args.name, ownerId, ctx.db, args.alias ?? args.name);
|
|
93
100
|
}
|
|
94
101
|
catch (err) {
|
|
95
102
|
throw new McpError(404, err instanceof Error ? err.message : String(err));
|
|
@@ -100,15 +107,20 @@ export function registerSecretsTools(mcp, opts) {
|
|
|
100
107
|
mcp.registerTool({
|
|
101
108
|
name: "detach_secret",
|
|
102
109
|
scope: "secrets:write",
|
|
110
|
+
description: "Detaches a secret from an agent. `name` is the alias it was attached under; the secret's own name also works when no attachment has that alias.",
|
|
103
111
|
inputSchema: {
|
|
104
112
|
type: "object",
|
|
105
113
|
properties: { agentId: { type: "string" }, name: { type: "string" } },
|
|
106
114
|
required: ["agentId", "name"],
|
|
107
115
|
},
|
|
108
116
|
handler: async (args, ctx) => {
|
|
109
|
-
await
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
const { agent } = await requireAgentAccess(ctx, args.agentId, "read");
|
|
118
|
+
requireBindingOwner(ctx, agent);
|
|
119
|
+
const count = await detachSecret(args.agentId, args.name, ctx.db);
|
|
120
|
+
if (count === 0) {
|
|
121
|
+
throw new McpError(404, `No secret is attached to agent "${args.agentId}" as "${args.name}".`);
|
|
122
|
+
}
|
|
123
|
+
return textResult({ detached: true, count });
|
|
112
124
|
},
|
|
113
125
|
});
|
|
114
126
|
mcp.registerTool({
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The coding-run service catalog over MCP (docs/coding-services.md). Reading
|
|
3
|
+
* it needs only agents:read: agent owners need to see which services exist and
|
|
4
|
+
* the variables (testEnv) their tests will get before allowing one, and entries
|
|
5
|
+
* hold no secrets (serviceEnv values are throwaway per-run test credentials).
|
|
6
|
+
* Changing it needs services:manage, a privileged scope honoured only with a
|
|
7
|
+
* role granting it (service-manager or admin; resource-server.ts): an entry
|
|
8
|
+
* decides which image runs next to every coding run that names it, and with
|
|
9
|
+
* what. Each change is audit-logged (event coding.service_catalog.<action>).
|
|
10
|
+
* Built-in entries ship with wardby and change only with a release.
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { CodingServiceDefinitionSchema, catalogEntryFromRow, codingServiceNameSchema, codingServiceVersionSchema, } from "../../coding/services/catalog.js";
|
|
14
|
+
import { logger } from "../../core/logger.js";
|
|
15
|
+
import { McpError } from "../errors.js";
|
|
16
|
+
import { textResult } from "./text-result.js";
|
|
17
|
+
const servicesLog = logger.child({ module: "mcp-services" });
|
|
18
|
+
const KeySchema = z.object({ name: codingServiceNameSchema, version: codingServiceVersionSchema }).strict();
|
|
19
|
+
/** Everything but the key is optional here; the merged entry is validated in full. */
|
|
20
|
+
const UpdateSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
name: codingServiceNameSchema,
|
|
23
|
+
version: codingServiceVersionSchema,
|
|
24
|
+
image: z.unknown().optional(),
|
|
25
|
+
port: z.unknown().optional(),
|
|
26
|
+
serviceEnv: z.unknown().optional(),
|
|
27
|
+
testEnv: z.unknown().optional(),
|
|
28
|
+
readiness: z.unknown().optional(),
|
|
29
|
+
resources: z.unknown().optional(),
|
|
30
|
+
dataPath: z.unknown().optional(),
|
|
31
|
+
writablePaths: z.unknown().optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict();
|
|
34
|
+
function parse(schema, label, value) {
|
|
35
|
+
const result = schema.safeParse(value);
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
const details = result.error.issues
|
|
38
|
+
.map((issue) => `${issue.path.join(".") || "input"}: ${issue.message}`)
|
|
39
|
+
.join("; ");
|
|
40
|
+
throw new McpError(400, `Invalid ${label}: ${details}`);
|
|
41
|
+
}
|
|
42
|
+
return result.data;
|
|
43
|
+
}
|
|
44
|
+
function audit(ctx, action, entry) {
|
|
45
|
+
servicesLog.info({
|
|
46
|
+
event: `coding.service_catalog.${action}`,
|
|
47
|
+
name: entry.name,
|
|
48
|
+
version: entry.version,
|
|
49
|
+
...(entry.image ? { image: entry.image } : {}),
|
|
50
|
+
by: ctx.principal.id,
|
|
51
|
+
}, "coding service catalog changed");
|
|
52
|
+
}
|
|
53
|
+
async function findEntry(ctx, key) {
|
|
54
|
+
const row = await ctx.db.codingService.findUnique({ where: { name_version: key } });
|
|
55
|
+
if (!row)
|
|
56
|
+
throw new McpError(404, `No coding service "${key.name} ${key.version}" in the catalog.`);
|
|
57
|
+
return row;
|
|
58
|
+
}
|
|
59
|
+
function refuseBuiltin(key) {
|
|
60
|
+
return new McpError(403, `"${key.name} ${key.version}" is built in: built-in services change only with a wardby release. Create an entry under another name or version instead.`);
|
|
61
|
+
}
|
|
62
|
+
function view(row) {
|
|
63
|
+
return { ...catalogEntryFromRow(row), builtin: row.builtin, createdAt: row.createdAt, updatedAt: row.updatedAt };
|
|
64
|
+
}
|
|
65
|
+
const keyJsonSchema = {
|
|
66
|
+
name: { type: "string", description: 'Catalog name a repository declares, e.g. "postgres".' },
|
|
67
|
+
version: { type: "string", description: 'Version a repository declares, e.g. "16".' },
|
|
68
|
+
};
|
|
69
|
+
const definitionProperties = {
|
|
70
|
+
...keyJsonSchema,
|
|
71
|
+
image: { type: "string", description: "Registry digest to run: repo@sha256:<64 hex>. Tags are refused." },
|
|
72
|
+
port: {
|
|
73
|
+
type: "integer",
|
|
74
|
+
minimum: 1,
|
|
75
|
+
maximum: 65535,
|
|
76
|
+
description: "The port the service listens on (informational).",
|
|
77
|
+
},
|
|
78
|
+
serviceEnv: {
|
|
79
|
+
type: "object",
|
|
80
|
+
additionalProperties: { type: "string" },
|
|
81
|
+
description: "Environment for the service container. Throwaway per-run values only, never secrets.",
|
|
82
|
+
},
|
|
83
|
+
testEnv: {
|
|
84
|
+
type: "object",
|
|
85
|
+
additionalProperties: { type: "string" },
|
|
86
|
+
description: "Variables the agent's shells receive (e.g. DATABASE_URL). Upper-case names; wardby's own names (PATH, HOME, PIP_*, WARDBY_*, ...) are refused.",
|
|
87
|
+
},
|
|
88
|
+
readiness: {
|
|
89
|
+
type: "object",
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
required: ["command", "periodSeconds", "timeoutSeconds", "failureThreshold"],
|
|
92
|
+
properties: {
|
|
93
|
+
command: { type: "array", minItems: 1, maxItems: 16, items: { type: "string" } },
|
|
94
|
+
periodSeconds: { type: "integer", minimum: 1, maximum: 60 },
|
|
95
|
+
timeoutSeconds: { type: "integer", minimum: 1, maximum: 60 },
|
|
96
|
+
failureThreshold: { type: "integer", minimum: 1, maximum: 120 },
|
|
97
|
+
},
|
|
98
|
+
description: "Startup probe: a command in the service's image that succeeds once it accepts connections on 127.0.0.1.",
|
|
99
|
+
},
|
|
100
|
+
resources: {
|
|
101
|
+
type: "object",
|
|
102
|
+
additionalProperties: false,
|
|
103
|
+
required: ["cpuMillicores", "memoryMib", "diskMib"],
|
|
104
|
+
properties: {
|
|
105
|
+
cpuMillicores: { type: "integer", minimum: 100, maximum: 4000 },
|
|
106
|
+
memoryMib: { type: "integer", minimum: 64, maximum: 16384 },
|
|
107
|
+
diskMib: { type: "integer", minimum: 64, maximum: 8192 },
|
|
108
|
+
},
|
|
109
|
+
description: "Requests equal limits. diskMib sizes the data volume.",
|
|
110
|
+
},
|
|
111
|
+
dataPath: {
|
|
112
|
+
type: "string",
|
|
113
|
+
description: "Absolute directory the service writes its data to: an empty volume in each run.",
|
|
114
|
+
},
|
|
115
|
+
writablePaths: {
|
|
116
|
+
type: "array",
|
|
117
|
+
maxItems: 4,
|
|
118
|
+
items: { type: "string" },
|
|
119
|
+
description: "Further directories the image writes to (a socket directory, /tmp); its root filesystem is read-only.",
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
export function registerServiceTools(mcp) {
|
|
123
|
+
mcp.registerTool({
|
|
124
|
+
name: "list_services",
|
|
125
|
+
scope: "agents:read",
|
|
126
|
+
description: "The coding-run service catalog (name, version, image, built in or not): the names a coding agent's codingProfile.services can allow.",
|
|
127
|
+
inputSchema: { type: "object", additionalProperties: false, properties: {} },
|
|
128
|
+
handler: async (_args, ctx) => {
|
|
129
|
+
const rows = await ctx.db.codingService.findMany({ orderBy: [{ name: "asc" }, { version: "asc" }] });
|
|
130
|
+
return textResult(rows.map((row) => ({
|
|
131
|
+
name: row.name,
|
|
132
|
+
version: row.version,
|
|
133
|
+
kind: row.kind,
|
|
134
|
+
image: row.image,
|
|
135
|
+
port: row.port,
|
|
136
|
+
builtin: row.builtin,
|
|
137
|
+
})));
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
mcp.registerTool({
|
|
141
|
+
name: "get_service",
|
|
142
|
+
scope: "agents:read",
|
|
143
|
+
description: "One catalog entry in full, including the variables (testEnv) a run's shells receive — the contract a repository's tests rely on.",
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
additionalProperties: false,
|
|
147
|
+
required: ["name", "version"],
|
|
148
|
+
properties: keyJsonSchema,
|
|
149
|
+
},
|
|
150
|
+
handler: async (rawArgs, ctx) => {
|
|
151
|
+
const key = parse(KeySchema, "get_service arguments", rawArgs);
|
|
152
|
+
return textResult(view(await findEntry(ctx, key)));
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
mcp.registerTool({
|
|
156
|
+
name: "create_service",
|
|
157
|
+
scope: "services:manage",
|
|
158
|
+
description: "Service managers (services:manage): add a catalog entry repositories can then declare in .wardby/services.yaml. The image must be pinned by digest; kind is sidecar (a fresh instance in each run's pod).",
|
|
159
|
+
inputSchema: {
|
|
160
|
+
type: "object",
|
|
161
|
+
additionalProperties: false,
|
|
162
|
+
required: ["name", "version", "image", "port", "readiness", "resources", "dataPath"],
|
|
163
|
+
// kind is checked by the zod schema (only "sidecar" today), so a refusal names the field.
|
|
164
|
+
properties: { ...definitionProperties, kind: { type: "string", description: 'Only "sidecar" today.' } },
|
|
165
|
+
},
|
|
166
|
+
handler: async (rawArgs, ctx) => {
|
|
167
|
+
const definition = parse(CodingServiceDefinitionSchema, "create_service arguments", rawArgs);
|
|
168
|
+
const key = { name: definition.name, version: definition.version };
|
|
169
|
+
if (await ctx.db.codingService.findUnique({ where: { name_version: key } })) {
|
|
170
|
+
throw new McpError(409, `The catalog already has "${key.name} ${key.version}"; use update_service to change it.`);
|
|
171
|
+
}
|
|
172
|
+
const row = await ctx.db.codingService.create({
|
|
173
|
+
data: { ...definition, builtin: false, createdById: ctx.principal.id },
|
|
174
|
+
});
|
|
175
|
+
audit(ctx, "create", definition);
|
|
176
|
+
return textResult(view(row));
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
mcp.registerTool({
|
|
180
|
+
name: "update_service",
|
|
181
|
+
scope: "services:manage",
|
|
182
|
+
description: "Service managers (services:manage): change a non-built-in catalog entry (name and version identify it and never change). Runs already dispatched keep the entry they started with.",
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: "object",
|
|
185
|
+
additionalProperties: false,
|
|
186
|
+
required: ["name", "version"],
|
|
187
|
+
properties: definitionProperties,
|
|
188
|
+
},
|
|
189
|
+
handler: async (rawArgs, ctx) => {
|
|
190
|
+
const { name, version, ...patch } = parse(UpdateSchema, "update_service arguments", rawArgs);
|
|
191
|
+
const row = await findEntry(ctx, { name, version });
|
|
192
|
+
if (row.builtin)
|
|
193
|
+
throw refuseBuiltin({ name, version });
|
|
194
|
+
const changes = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined));
|
|
195
|
+
const next = parse(CodingServiceDefinitionSchema, "coding service", { ...catalogEntryFromRow(row), ...changes });
|
|
196
|
+
const { name: _name, version: _version, kind: _kind, ...fields } = next;
|
|
197
|
+
const updated = await ctx.db.codingService.update({ where: { name_version: { name, version } }, data: fields });
|
|
198
|
+
audit(ctx, "update", next);
|
|
199
|
+
return textResult(view(updated));
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
mcp.registerTool({
|
|
203
|
+
name: "delete_service",
|
|
204
|
+
scope: "services:manage",
|
|
205
|
+
description: "Service managers (services:manage): remove a non-built-in catalog entry. Repositories still declaring it are refused at their next run (service_unknown).",
|
|
206
|
+
inputSchema: {
|
|
207
|
+
type: "object",
|
|
208
|
+
additionalProperties: false,
|
|
209
|
+
required: ["name", "version"],
|
|
210
|
+
properties: keyJsonSchema,
|
|
211
|
+
},
|
|
212
|
+
handler: async (rawArgs, ctx) => {
|
|
213
|
+
const key = parse(KeySchema, "delete_service arguments", rawArgs);
|
|
214
|
+
const row = await findEntry(ctx, key);
|
|
215
|
+
if (row.builtin)
|
|
216
|
+
throw refuseBuiltin(key);
|
|
217
|
+
await ctx.db.codingService.delete({ where: { name_version: key } });
|
|
218
|
+
audit(ctx, "delete", key);
|
|
219
|
+
return textResult({ deleted: key });
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AgentSubAgent CRUD — agent-composition edges.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* AgentSubAgent CRUD — agent-composition edges. An edge runs the child
|
|
3
|
+
* (with its owner's bindings) whenever the parent delegates, and hands the
|
|
4
|
+
* child whatever the parent's runs pass it, so it is a binding of the
|
|
5
|
+
* parent: only the parent's owner attaches or detaches one (review I2; a
|
|
6
|
+
* write-grantee could otherwise route every run's data to their own agent).
|
|
7
|
+
* Across owners it also needs an explicit grant (resource-sharing grants
|
|
8
|
+
* spec §3.4.4, N1): the caller needs execute on the child, and the parent's
|
|
9
|
+
* owner must be the child's owner or hold execute on it (canDelegate,
|
|
10
|
+
* re-checked on every delegation at run time). The child's owner can
|
|
11
|
+
* always cut an edge. Attach also rejects any edge that would
|
|
12
|
+
* create a cycle in the parent/child graph (§7 of the design doc) — cycles
|
|
13
|
+
* are not something Postgres can enforce natively.
|
|
8
14
|
*/
|
|
9
15
|
import { Prisma } from "#prisma";
|
|
10
|
-
import {
|
|
16
|
+
import { atLeast, canDelegate } from "../../core/grants.js";
|
|
17
|
+
import { agentAccess, agentAccessResolver, agentNotFound, requireAgentAccess, requireBindingOwner, } from "../auth/access.js";
|
|
11
18
|
import { McpError } from "../errors.js";
|
|
12
19
|
import { textResult } from "./text-result.js";
|
|
13
20
|
/**
|
|
@@ -60,8 +67,16 @@ export function registerSubAgentTools(mcp) {
|
|
|
60
67
|
if (args.parentAgentId === args.childAgentId) {
|
|
61
68
|
throw new McpError(400, "An agent cannot be its own sub-agent.");
|
|
62
69
|
}
|
|
63
|
-
const parent = await
|
|
64
|
-
|
|
70
|
+
const { agent: parent } = await requireAgentAccess(ctx, args.parentAgentId, "read");
|
|
71
|
+
requireBindingOwner(ctx, parent);
|
|
72
|
+
// The caller could trigger the child anyway; the edge must not widen that.
|
|
73
|
+
const { agent: child } = await requireAgentAccess(ctx, args.childAgentId, "execute");
|
|
74
|
+
if (parent.ownerId === null) {
|
|
75
|
+
throw new McpError(403, `Agent "${parent.id}" has no owner, so it can't take sub-agents; an admin can assign one with make_owner.`);
|
|
76
|
+
}
|
|
77
|
+
if (!(await canDelegate(ctx.db, parent, child))) {
|
|
78
|
+
throw new McpError(403, `"${child.name}" belongs to another owner, who has not given the owner of "${parent.name}" execute access to it.`);
|
|
79
|
+
}
|
|
65
80
|
if (await canReach(ctx.db, args.childAgentId, args.parentAgentId)) {
|
|
66
81
|
throw new McpError(400, `Attaching "${child.name}" as a sub-agent of "${parent.name}" would create a cycle.`);
|
|
67
82
|
}
|
|
@@ -95,8 +110,20 @@ export function registerSubAgentTools(mcp) {
|
|
|
95
110
|
required: ["parentAgentId", "childAgentId"],
|
|
96
111
|
},
|
|
97
112
|
handler: async (args, ctx) => {
|
|
98
|
-
|
|
99
|
-
|
|
113
|
+
// The parent's owner (or the stdio operator), or the child's owner: a
|
|
114
|
+
// child's owner can always take its agent back out of someone else's
|
|
115
|
+
// composition.
|
|
116
|
+
const [parent, child] = await Promise.all([
|
|
117
|
+
ctx.db.agent.findUnique({ where: { id: args.parentAgentId } }),
|
|
118
|
+
ctx.db.agent.findUnique({ where: { id: args.childAgentId } }),
|
|
119
|
+
]);
|
|
120
|
+
const parentAccess = parent ? await agentAccess(ctx, parent) : "none";
|
|
121
|
+
const childAccess = child ? await agentAccess(ctx, child) : "none";
|
|
122
|
+
if (parentAccess !== "owner" && childAccess !== "owner") {
|
|
123
|
+
if (!atLeast("agent", parentAccess, "read"))
|
|
124
|
+
throw agentNotFound(args.parentAgentId);
|
|
125
|
+
throw new McpError(403, `Detaching needs ownership of "${args.parentAgentId}" or of "${args.childAgentId}".`);
|
|
126
|
+
}
|
|
100
127
|
await ctx.db.agentSubAgent.deleteMany({
|
|
101
128
|
where: { parentAgentId: args.parentAgentId, childAgentId: args.childAgentId },
|
|
102
129
|
});
|
|
@@ -113,20 +140,29 @@ export function registerSubAgentTools(mcp) {
|
|
|
113
140
|
required: ["agentId"],
|
|
114
141
|
},
|
|
115
142
|
handler: async (args, ctx) => {
|
|
116
|
-
await
|
|
143
|
+
await requireAgentAccess(ctx, args.agentId, "read");
|
|
144
|
+
const accessOf = await agentAccessResolver(ctx);
|
|
117
145
|
const [asParent, asChild] = await Promise.all([
|
|
118
146
|
ctx.db.agentSubAgent.findMany({
|
|
119
147
|
where: { parentAgentId: args.agentId },
|
|
120
|
-
include: { child: { select: { id: true, name: true } } },
|
|
148
|
+
include: { child: { select: { id: true, name: true, ownerId: true } } },
|
|
121
149
|
}),
|
|
122
150
|
ctx.db.agentSubAgent.findMany({
|
|
123
151
|
where: { childAgentId: args.agentId },
|
|
124
|
-
include: { parent: { select: { id: true, name: true } } },
|
|
152
|
+
include: { parent: { select: { id: true, name: true, ownerId: true } } },
|
|
125
153
|
}),
|
|
126
154
|
]);
|
|
155
|
+
// Only agents the caller can read are named; the rest are counted.
|
|
156
|
+
const readable = (agent) => atLeast("agent", accessOf(agent), "read");
|
|
157
|
+
const children = asParent.filter((e) => readable(e.child));
|
|
158
|
+
const parents = asChild.filter((e) => readable(e.parent));
|
|
159
|
+
const hiddenChildren = asParent.length - children.length;
|
|
160
|
+
const hiddenParents = asChild.length - parents.length;
|
|
127
161
|
return textResult({
|
|
128
|
-
children:
|
|
129
|
-
parents:
|
|
162
|
+
children: children.map((e) => ({ boundName: e.boundName, agentId: e.child.id, agentName: e.child.name })),
|
|
163
|
+
parents: parents.map((e) => ({ boundName: e.boundName, agentId: e.parent.id, agentName: e.parent.name })),
|
|
164
|
+
...(hiddenChildren > 0 ? { hiddenChildren } : {}),
|
|
165
|
+
...(hiddenParents > 0 ? { hiddenParents } : {}),
|
|
130
166
|
});
|
|
131
167
|
},
|
|
132
168
|
});
|
|
@@ -1,2 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool authoring — raw path only (Amendment A: the guided Elicitation/Tasks
|
|
3
|
+
* flow is deferred; this ships create_tool + dry_run_tool as the
|
|
4
|
+
* test-before-commit loop instead). A compile/validation failure is a
|
|
5
|
+
* NORMAL tool result carrying `{ok:false, errorKind, errorMessage}` — not
|
|
6
|
+
* an isError — since the call itself succeeded (compilation was attempted
|
|
7
|
+
* and correctly reported a problem the caller can fix and retry), matching
|
|
8
|
+
* runInSandbox's own SandboxResult convention. Ownership/scope failures
|
|
9
|
+
* (attach/detach on an agent or tool you don't own) DO throw, same
|
|
10
|
+
* convention as every other tool in this codebase.
|
|
11
|
+
*/
|
|
12
|
+
import { type Tool } from "#prisma";
|
|
1
13
|
import type { WardbyMcpServer } from "../server.js";
|
|
14
|
+
/**
|
|
15
|
+
* A tool row as a caller who doesn't own it may see it: name and
|
|
16
|
+
* description, never code or paramsZod (A7). `public` tells an owner-less
|
|
17
|
+
* tool apart from the caller's own same-named one (names are unique per
|
|
18
|
+
* owner, not globally). Shared by list_tools and get_agent.
|
|
19
|
+
*/
|
|
20
|
+
export declare function projectTool(tool: Tool, principalId: string): {
|
|
21
|
+
name: string;
|
|
22
|
+
code: string;
|
|
23
|
+
createdAt: Date;
|
|
24
|
+
updatedAt: Date;
|
|
25
|
+
id: string;
|
|
26
|
+
ownerId: string | null;
|
|
27
|
+
description: string;
|
|
28
|
+
paramsZod: string;
|
|
29
|
+
jsonSchema: import("@prisma/client/runtime/client").JsonValue;
|
|
30
|
+
} | {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
public: boolean;
|
|
35
|
+
ownerIsCaller?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
public: boolean;
|
|
41
|
+
ownerIsCaller: boolean;
|
|
42
|
+
};
|
|
2
43
|
export declare function registerToolAuthoringTools(mcp: WardbyMcpServer): void;
|