@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,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jira Cloud webhook ingress — framework-agnostic, mounted unauthenticated
|
|
3
|
+
* (by OAuth) in streamable-http.ts at /hosts/jira/events. Authenticated by the
|
|
4
|
+
* webhook secret (X-Hub-Signature, WebSub style) over the raw body. The
|
|
5
|
+
* delivery id (X-Atlassian-Webhook-Identifier) is stable across Jira's
|
|
6
|
+
* retries, so it is the dedupe key. Nothing from the body is logged.
|
|
7
|
+
*/
|
|
8
|
+
import { Prisma } from "#prisma";
|
|
9
|
+
import { maybePruneHostEventDeliveries } from "./deliveries.js";
|
|
10
|
+
import { routeIssueEvent } from "../../core/issue-events.js";
|
|
11
|
+
import { logger } from "../../core/logger.js";
|
|
12
|
+
import { normalizeJiraEvent, verifyJiraSignature } from "../../providers/issue-tracker/jira-events.js";
|
|
13
|
+
const log = logger.child({ module: "jira-ingress" });
|
|
14
|
+
const SAFE_DELIVERY = /^[A-Za-z0-9._:-]{1,200}$/;
|
|
15
|
+
/** Jira retries a delivery up to 5 times, 5-15 min apart, so 2 h comfortably covers a legitimate replay. */
|
|
16
|
+
const MAX_AGE_MS = 2 * 60 * 60 * 1000;
|
|
17
|
+
const MAX_FUTURE_MS = 5 * 60 * 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the payload's top-level `timestamp` is inside the replay window.
|
|
20
|
+
* Assumed to be epoch milliseconds; a value below 1e12 (before 2001 in ms)
|
|
21
|
+
* is read as seconds. The unit is unverified against a live delivery.
|
|
22
|
+
* A missing or non-numeric timestamp is not fresh.
|
|
23
|
+
*/
|
|
24
|
+
function isFresh(payload, nowMs) {
|
|
25
|
+
const raw = payload?.timestamp;
|
|
26
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0)
|
|
27
|
+
return false;
|
|
28
|
+
const ts = raw < 1e12 ? raw * 1000 : raw;
|
|
29
|
+
return ts >= nowMs - MAX_AGE_MS && ts <= nowMs + MAX_FUTURE_MS;
|
|
30
|
+
}
|
|
31
|
+
export async function handleJiraEventIngress(req, deps) {
|
|
32
|
+
const tracker = deps.trackers.jira;
|
|
33
|
+
if (!tracker)
|
|
34
|
+
return { status: 404, body: { error: "not_found" } };
|
|
35
|
+
if (!verifyJiraSignature(req.rawBody, req.headers["x-hub-signature"], deps.webhookSecret)) {
|
|
36
|
+
return { status: 401, body: { error: "invalid_signature" } };
|
|
37
|
+
}
|
|
38
|
+
// wardby must not act as a person. A lookup failure throws (5xx), so Jira retries the delivery.
|
|
39
|
+
const identity = await tracker.identity();
|
|
40
|
+
if (identity.accountType === "atlassian") {
|
|
41
|
+
log.error("Jira token belongs to a person; refusing deliveries (use a service account)");
|
|
42
|
+
return { status: 503, body: { error: "jira_personal_account" } };
|
|
43
|
+
}
|
|
44
|
+
const deliveryId = req.headers["x-atlassian-webhook-identifier"];
|
|
45
|
+
if (!deliveryId || !SAFE_DELIVERY.test(deliveryId)) {
|
|
46
|
+
return { status: 400, body: { error: "missing_delivery_headers" } };
|
|
47
|
+
}
|
|
48
|
+
let payload;
|
|
49
|
+
try {
|
|
50
|
+
payload = JSON.parse(req.rawBody);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return { status: 400, body: { error: "invalid_json" } };
|
|
54
|
+
}
|
|
55
|
+
// Replay protection: the signature covers the body, so an old captured delivery would otherwise verify forever.
|
|
56
|
+
if (!isFresh(payload, (deps.now ?? Date.now)()))
|
|
57
|
+
return { status: 202, body: { ignored: "stale" } };
|
|
58
|
+
const event = normalizeJiraEvent(payload, identity.accountId);
|
|
59
|
+
// An event we don't act on must never claim the delivery id (see the GitHub ingress).
|
|
60
|
+
if (!event)
|
|
61
|
+
return { status: 202, body: { ignored: true } };
|
|
62
|
+
try {
|
|
63
|
+
await deps.db.hostEventDelivery.create({ data: { provider: "jira", deliveryId } });
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2002") {
|
|
67
|
+
return { status: 202, body: { duplicate: true } };
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
await maybePruneHostEventDeliveries(deps.db, new Date());
|
|
72
|
+
// A routing failure must not leave the delivery permanently marked done:
|
|
73
|
+
// un-record it and rethrow so Jira's retry is routed for real.
|
|
74
|
+
try {
|
|
75
|
+
const routed = await routeIssueEvent(event, { db: deps.db, executor: deps.executor, trackers: deps.trackers });
|
|
76
|
+
log.info({ kinds: event.kinds, deliveryId, runIds: routed.runIds }, "jira event routed");
|
|
77
|
+
return {
|
|
78
|
+
status: 202,
|
|
79
|
+
body: { runIds: routed.runIds },
|
|
80
|
+
afterResponse: async () => {
|
|
81
|
+
for (const followUp of routed.followUps)
|
|
82
|
+
await followUp();
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
await deps.db.hostEventDelivery
|
|
88
|
+
.deleteMany({ where: { provider: "jira", deliveryId } })
|
|
89
|
+
.catch((delErr) => log.warn({ err: delErr }, "could not roll back the delivery record after a routing failure"));
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { type WardbyMcpServer } from "./server.js";
|
|
2
|
-
import type { McpProviders } from "./context.js";
|
|
2
|
+
import type { McpProviders, McpRequestContext } from "./context.js";
|
|
3
|
+
import type { Principal, PrismaClient } from "#prisma";
|
|
3
4
|
import { type SecretElicitationUrlBuilder } from "./tools/secrets.js";
|
|
5
|
+
/**
|
|
6
|
+
* stdio's one fixed identity: the local operator (LOCAL_PRINCIPAL), trusted
|
|
7
|
+
* with every supported scope and every role — whoever can start the
|
|
8
|
+
* process already holds the database and its keys.
|
|
9
|
+
*/
|
|
10
|
+
export declare function localOperatorContext(principal: Principal, providers: McpProviders, db: PrismaClient): McpRequestContext;
|
|
4
11
|
/** Registers the full Phase 4 tool surface — every module, in one place. */
|
|
5
12
|
export declare function registerAllTools(mcp: WardbyMcpServer, opts: {
|
|
6
13
|
secretElicitationUrl: SecretElicitationUrlBuilder;
|
|
7
14
|
secretElicitationProtocol: boolean;
|
|
15
|
+
/** Rebuilds the process's installed model CatalogStore after set_model/disable_model/reset_model. */
|
|
16
|
+
refreshModelCatalog?: () => Promise<void>;
|
|
8
17
|
}): void;
|
|
9
18
|
export interface McpProviderComposition {
|
|
10
19
|
providers: McpProviders;
|
package/dist/mcp/index.js
CHANGED
|
@@ -1,28 +1,59 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MCP composition root: assembles the real providers, builds one
|
|
3
|
+
* WardbyMcpServer, registers every tool module, and starts whichever
|
|
4
|
+
* transport MCP_TRANSPORT selects. No business logic lives here — this
|
|
5
|
+
* file only wires together pieces every earlier task already built and
|
|
6
|
+
* tested on their own.
|
|
7
|
+
*
|
|
8
|
+
* stdio vs. HTTP diverge on two things a live smoke test surfaced (see the
|
|
9
|
+
* ledger): stdio needs no `MCP_CANONICAL_URI` (there's no HTTP endpoint or
|
|
10
|
+
* OAuth challenge to identify) and constructs no real `AuthProvider` at all
|
|
11
|
+
* (per the design: "stdio local mode: no token; the operator is trusted") —
|
|
12
|
+
* building one unconditionally would make `wardby mcp` over stdio fail on
|
|
13
|
+
* missing `AUTH_JWKS_URI`/`AUTH_SIGNING_KEY` a deployment running stdio-only
|
|
14
|
+
* never needed to set.
|
|
15
|
+
*/
|
|
16
|
+
import { loadProviderConfig, loadMcpConfig, loadShutdownDrainSeconds, loadAuthConfig, loadGitHubEventConfig, loadJiraConfig, loadGitHubVcsConfig, } from "../config/providers.js";
|
|
2
17
|
import { prisma } from "../core/db.js";
|
|
18
|
+
import { waitForInFlightRuns } from "../core/in-flight-runs.js";
|
|
3
19
|
import { NativeEngine } from "../core/engine-native.js";
|
|
4
20
|
import { resolveLlmRegistrations, RoutingLlmProvider } from "../providers/llm/index.js";
|
|
21
|
+
import { startModelCatalog } from "../providers/llm/catalog-store.js";
|
|
5
22
|
import { PostgresDatastore } from "../providers/datastore/index.js";
|
|
6
23
|
import { PostgresAgentMemory } from "../providers/memory/index.js";
|
|
7
24
|
import { buildConfiguredExecutor, buildExecutor } from "../providers/executor/index.js";
|
|
8
25
|
import { buildSecretCipher } from "../providers/secrets/index.js";
|
|
26
|
+
import { buildIssueTrackers } from "../providers/issue-tracker/index.js";
|
|
27
|
+
import { buildHostUserAuthorizers, buildReviewHosts } from "../providers/review-host/index.js";
|
|
28
|
+
import { createRepoAccessGate } from "../core/repo-access.js";
|
|
29
|
+
import { userCallbackPath } from "../core/host-identity-links.js";
|
|
9
30
|
import { buildAuthProvider } from "../providers/auth/index.js";
|
|
31
|
+
import { GitHubAppClient } from "../providers/vcs/github.js";
|
|
10
32
|
import { buildMcpServer } from "./server.js";
|
|
11
33
|
import { countUnattendedSchedules, unattendedSchedulesWarning } from "./unattended-schedules.js";
|
|
12
34
|
import { runStdioServer } from "./transport/stdio.js";
|
|
13
35
|
import { startHttpServer } from "./transport/streamable-http.js";
|
|
14
36
|
import { resolvePrincipal } from "./auth/principal.js";
|
|
15
|
-
import { SCOPES_SUPPORTED } from "./auth/resource-server.js";
|
|
37
|
+
import { ROLE_NAMES, SCOPES_SUPPORTED, authenticate } from "./auth/resource-server.js";
|
|
16
38
|
import { canonicalUrl } from "./transport/http-limits.js";
|
|
39
|
+
import { createViewerApi } from "../viewer/http.js";
|
|
40
|
+
import { createViewerEventBus } from "../viewer/event-bus.js";
|
|
17
41
|
import { registerAgentTools } from "./tools/agents.js";
|
|
42
|
+
import { registerServiceTools } from "./tools/services.js";
|
|
18
43
|
import { registerBudgetGroupTools } from "./tools/budget-groups.js";
|
|
19
|
-
import {
|
|
44
|
+
import { registerModelCatalogTools } from "./tools/model-catalog.js";
|
|
45
|
+
import { registerHelpTools } from "./tools/help.js";
|
|
20
46
|
import { registerTriggerTool } from "./tools/trigger.js";
|
|
21
47
|
import { registerToolAuthoringTools } from "./tools/tools.js";
|
|
22
48
|
import { registerSchedulingTools } from "./tools/scheduling.js";
|
|
23
49
|
import { registerRunTools } from "./tools/runs.js";
|
|
50
|
+
import { registerCostReportTools } from "./tools/cost-report.js";
|
|
24
51
|
import { registerDatastoreTools } from "./tools/datastore.js";
|
|
25
52
|
import { registerSubAgentTools } from "./tools/subagents.js";
|
|
53
|
+
import { registerGrantTools } from "./tools/grants.js";
|
|
54
|
+
import { registerRepositoryTools } from "./tools/repositories.js";
|
|
55
|
+
import { registerIssueProjectTools } from "./tools/issue-projects.js";
|
|
56
|
+
import { registerHostAccountTools } from "./tools/host-accounts.js";
|
|
26
57
|
import { registerMemoryTools } from "./tools/memory.js";
|
|
27
58
|
import { registerSecretsTools } from "./tools/secrets.js";
|
|
28
59
|
import { registerWebhookTools } from "./tools/webhooks.js";
|
|
@@ -45,17 +76,46 @@ async function warnIfNothingWillFireSchedules() {
|
|
|
45
76
|
}
|
|
46
77
|
/** Placeholder identifier for stdio, which has no HTTP endpoint to name. Never surfaced: stdio's fixed context always holds every scope, so no scope challenge is ever built against it. */
|
|
47
78
|
const STDIO_PLACEHOLDER_URI = "urn:wardby:local-stdio";
|
|
79
|
+
/**
|
|
80
|
+
* stdio's one fixed identity: the local operator (LOCAL_PRINCIPAL), trusted
|
|
81
|
+
* with every supported scope and every role — whoever can start the
|
|
82
|
+
* process already holds the database and its keys.
|
|
83
|
+
*/
|
|
84
|
+
export function localOperatorContext(principal, providers, db) {
|
|
85
|
+
return {
|
|
86
|
+
principal,
|
|
87
|
+
scopes: new Set(SCOPES_SUPPORTED),
|
|
88
|
+
roles: [...ROLE_NAMES],
|
|
89
|
+
// Full access to every resource (resource-sharing grants spec §3.9),
|
|
90
|
+
// but never past the binding rules.
|
|
91
|
+
operator: true,
|
|
92
|
+
canonicalUri: STDIO_PLACEHOLDER_URI,
|
|
93
|
+
providers,
|
|
94
|
+
db,
|
|
95
|
+
clientSupportsTasks: false,
|
|
96
|
+
// Placeholder — server.ts's resolveCtx overwrites this with the
|
|
97
|
+
// current call's real mcpReq on every dispatch.
|
|
98
|
+
mcpReq: { requestState: () => undefined },
|
|
99
|
+
};
|
|
100
|
+
}
|
|
48
101
|
/** Registers the full Phase 4 tool surface — every module, in one place. */
|
|
49
102
|
export function registerAllTools(mcp, opts) {
|
|
50
103
|
registerAgentTools(mcp);
|
|
104
|
+
registerServiceTools(mcp);
|
|
51
105
|
registerBudgetGroupTools(mcp);
|
|
52
|
-
|
|
106
|
+
registerModelCatalogTools(mcp, { refresh: opts.refreshModelCatalog });
|
|
107
|
+
registerHelpTools(mcp);
|
|
53
108
|
registerTriggerTool(mcp);
|
|
54
109
|
registerToolAuthoringTools(mcp);
|
|
55
110
|
registerSchedulingTools(mcp);
|
|
56
111
|
registerRunTools(mcp);
|
|
112
|
+
registerCostReportTools(mcp);
|
|
57
113
|
registerDatastoreTools(mcp);
|
|
58
114
|
registerSubAgentTools(mcp);
|
|
115
|
+
registerGrantTools(mcp);
|
|
116
|
+
registerRepositoryTools(mcp);
|
|
117
|
+
registerIssueProjectTools(mcp);
|
|
118
|
+
registerHostAccountTools(mcp);
|
|
59
119
|
registerMemoryTools(mcp);
|
|
60
120
|
registerSecretsTools(mcp, {
|
|
61
121
|
buildElicitationUrl: opts.secretElicitationUrl,
|
|
@@ -75,6 +135,12 @@ export function buildMcpProviders() {
|
|
|
75
135
|
const secrets = buildSecretCipher(providerConfig);
|
|
76
136
|
const datastore = new PostgresDatastore(prisma, secrets);
|
|
77
137
|
const memory = new PostgresAgentMemory(prisma);
|
|
138
|
+
const reviewHosts = buildReviewHosts();
|
|
139
|
+
const issueTrackers = buildIssueTrackers();
|
|
140
|
+
const hostUserAuthorizers = buildHostUserAuthorizers();
|
|
141
|
+
// One gate (and one cache) for the whole process: set-time checks in the
|
|
142
|
+
// MCP tools, repo_* calls in native runs, coding runs, and host events.
|
|
143
|
+
const repoAccess = createRepoAccessGate({ db: prisma, hosts: reviewHosts });
|
|
78
144
|
// `nativeProviders` is passed by reference into buildExecutor, and native
|
|
79
145
|
// runs it drives read `this.providers.executor` at call time (not at
|
|
80
146
|
// construction time) — so patching `.executor` on afterward, once the
|
|
@@ -83,11 +149,33 @@ export function buildMcpProviders() {
|
|
|
83
149
|
// through the same composed executor everything else uses. There's no
|
|
84
150
|
// way to hand the native executor a reference to its own wrapping
|
|
85
151
|
// RoutingExecutor before that wrapper is constructed.
|
|
86
|
-
const nativeProviders = {
|
|
152
|
+
const nativeProviders = {
|
|
153
|
+
llm,
|
|
154
|
+
engine,
|
|
155
|
+
datastore,
|
|
156
|
+
secrets,
|
|
157
|
+
memory,
|
|
158
|
+
reviewHosts,
|
|
159
|
+
issueTrackers,
|
|
160
|
+
repoAccess,
|
|
161
|
+
};
|
|
87
162
|
const nativeExecutor = buildExecutor(providerConfig, nativeProviders, prisma);
|
|
88
|
-
const executor = buildConfiguredExecutor({ native: nativeExecutor, db: prisma, providerConfig });
|
|
163
|
+
const executor = buildConfiguredExecutor({ native: nativeExecutor, db: prisma, providerConfig, repoAccess });
|
|
89
164
|
nativeProviders.executor = executor;
|
|
90
|
-
return {
|
|
165
|
+
return {
|
|
166
|
+
providers: {
|
|
167
|
+
llm,
|
|
168
|
+
engine,
|
|
169
|
+
datastore,
|
|
170
|
+
secrets,
|
|
171
|
+
executor,
|
|
172
|
+
memory,
|
|
173
|
+
reviewHosts,
|
|
174
|
+
issueTrackers,
|
|
175
|
+
hostUserAuthorizers,
|
|
176
|
+
repoAccess,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
91
179
|
}
|
|
92
180
|
/** Awaits `promise` (if any), logging and swallowing a rejection instead of propagating it. */
|
|
93
181
|
async function closeQuietly(promise, what) {
|
|
@@ -101,6 +189,16 @@ async function closeQuietly(promise, what) {
|
|
|
101
189
|
/** The real CLI entry point: `wardby mcp`. Reads config from the environment, starts stdio or HTTP per MCP_TRANSPORT. */
|
|
102
190
|
export async function startMcp(options = {}) {
|
|
103
191
|
const mcpConfig = loadMcpConfig();
|
|
192
|
+
// Parsed up front so a malformed value fails at startup, not at shutdown.
|
|
193
|
+
const drainSeconds = loadShutdownDrainSeconds();
|
|
194
|
+
// Loads the model catalog before anything else: running on the shipped
|
|
195
|
+
// catalog alone (the fallback currentModelCatalog() uses before a store
|
|
196
|
+
// is installed) would quietly re-enable models an admin turned off.
|
|
197
|
+
// `modelCatalog` is handed to registerAllTools as `refreshModelCatalog`,
|
|
198
|
+
// which the model catalog tools (set_model, disable_model, reset_model)
|
|
199
|
+
// call via `modelCatalog.refreshNow()` after each write — there is no
|
|
200
|
+
// separate refresh tool.
|
|
201
|
+
const modelCatalog = await startModelCatalog(prisma);
|
|
104
202
|
const providers = options.providers ?? buildMcpProviders().providers;
|
|
105
203
|
await providers.executor.launch?.();
|
|
106
204
|
if (!options.schedulerAttached)
|
|
@@ -115,27 +213,19 @@ export async function startMcp(options = {}) {
|
|
|
115
213
|
registerAllTools(mcp, {
|
|
116
214
|
secretElicitationUrl: (token) => secretElicitationHost.urlFor(token),
|
|
117
215
|
secretElicitationProtocol: mcpConfig.secretElicitationProtocol,
|
|
216
|
+
refreshModelCatalog: () => modelCatalog.refreshNow(),
|
|
118
217
|
});
|
|
119
218
|
// stdio never carries per-call AuthInfo — one fixed, fully-trusted
|
|
120
219
|
// local identity for the whole connection, per the design's own
|
|
121
220
|
// "stdio local mode: no token; the operator is trusted."
|
|
122
221
|
const principal = await resolvePrincipal(mcpConfig.localPrincipal, prisma);
|
|
123
|
-
mcp.setFixedContext(
|
|
124
|
-
principal,
|
|
125
|
-
scopes: new Set(SCOPES_SUPPORTED),
|
|
126
|
-
canonicalUri: STDIO_PLACEHOLDER_URI,
|
|
127
|
-
providers,
|
|
128
|
-
db: prisma,
|
|
129
|
-
clientSupportsTasks: false,
|
|
130
|
-
// Placeholder — server.ts's resolveCtx overwrites this with the
|
|
131
|
-
// current call's real mcpReq on every dispatch.
|
|
132
|
-
mcpReq: { requestState: () => undefined },
|
|
133
|
-
});
|
|
222
|
+
mcp.setFixedContext(localOperatorContext(principal, providers, prisma));
|
|
134
223
|
const stdio = runStdioServer(mcp);
|
|
135
224
|
return {
|
|
136
225
|
close: async () => {
|
|
137
226
|
await closeQuietly(stdio.close(), "stdio transport close");
|
|
138
227
|
await closeQuietly(providers.executor.close?.(), "executor close");
|
|
228
|
+
modelCatalog.close();
|
|
139
229
|
},
|
|
140
230
|
};
|
|
141
231
|
}
|
|
@@ -158,11 +248,81 @@ export async function startMcp(options = {}) {
|
|
|
158
248
|
registerAllTools(mcp, {
|
|
159
249
|
secretElicitationUrl: (token) => Promise.resolve(`${httpOrigin}${SECRET_ELICITATION_PATH}?t=${encodeURIComponent(token)}`),
|
|
160
250
|
secretElicitationProtocol: mcpConfig.secretElicitationProtocol,
|
|
251
|
+
refreshModelCatalog: () => modelCatalog.refreshNow(),
|
|
161
252
|
});
|
|
253
|
+
const eventConfig = loadGitHubEventConfig();
|
|
254
|
+
const githubConfig = loadGitHubVcsConfig();
|
|
255
|
+
const reviewHosts = providers.reviewHosts;
|
|
256
|
+
const githubEvents = eventConfig.webhookSecret && reviewHosts?.github && githubConfig.appId && githubConfig.privateKey
|
|
257
|
+
? {
|
|
258
|
+
github: {
|
|
259
|
+
db: prisma,
|
|
260
|
+
executor: providers.executor,
|
|
261
|
+
hosts: reviewHosts,
|
|
262
|
+
repoAccess: providers.repoAccess ?? createRepoAccessGate({ db: prisma, hosts: reviewHosts }),
|
|
263
|
+
...(providers.issueTrackers ? { issueTrackers: providers.issueTrackers } : {}),
|
|
264
|
+
webhookSecret: eventConfig.webhookSecret,
|
|
265
|
+
appIdentity: (() => {
|
|
266
|
+
const client = new GitHubAppClient({
|
|
267
|
+
appId: githubConfig.appId,
|
|
268
|
+
privateKey: githubConfig.privateKey,
|
|
269
|
+
apiVersion: githubConfig.apiVersion,
|
|
270
|
+
});
|
|
271
|
+
return () => client.appIdentity();
|
|
272
|
+
})(),
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
: undefined;
|
|
276
|
+
mcpLog.info({ enabled: Boolean(githubEvents) }, "GitHub host events ingress");
|
|
277
|
+
const jiraConfig = loadJiraConfig();
|
|
278
|
+
const jiraEvents = jiraConfig && providers.issueTrackers?.jira
|
|
279
|
+
? {
|
|
280
|
+
db: prisma,
|
|
281
|
+
executor: providers.executor,
|
|
282
|
+
trackers: providers.issueTrackers,
|
|
283
|
+
webhookSecret: jiraConfig.webhookSecret,
|
|
284
|
+
}
|
|
285
|
+
: undefined;
|
|
286
|
+
mcpLog.info({ enabled: Boolean(jiraEvents) }, "Jira host events ingress");
|
|
287
|
+
if (jiraEvents) {
|
|
288
|
+
// Best effort: show which Jira account wardby acts as; never blocks startup.
|
|
289
|
+
void providers.issueTrackers?.jira?.identity().then(({ accountId, displayName, accountType }) => accountType === "atlassian"
|
|
290
|
+
? mcpLog.error({ accountId, displayName, accountType }, "Jira token belongs to a person's account; wardby refuses to act and the Jira ingress answers 503 until a service account token is configured")
|
|
291
|
+
: mcpLog.info({ accountId, displayName, accountType }, "Jira acting as"), (err) => mcpLog.warn({ err: err instanceof Error ? err.message : String(err) }, "could not read the Jira account identity"));
|
|
292
|
+
}
|
|
293
|
+
if (jiraConfig?.tokenExpiresAt && jiraConfig.tokenExpiresAt.getTime() - Date.now() < 14 * 24 * 60 * 60 * 1000) {
|
|
294
|
+
mcpLog.warn({ expiresAt: jiraConfig.tokenExpiresAt.toISOString() }, "the Jira API token expires within 14 days; rotate WARDBY_JIRA_API_TOKEN");
|
|
295
|
+
}
|
|
296
|
+
const hostEvents = githubEvents || jiraEvents
|
|
297
|
+
? { ...(githubEvents ? githubEvents : {}), ...(jiraEvents ? { jira: jiraEvents } : {}) }
|
|
298
|
+
: undefined;
|
|
299
|
+
const githubAuthorizer = providers.hostUserAuthorizers?.github;
|
|
300
|
+
const hostUserAuth = githubAuthorizer
|
|
301
|
+
? {
|
|
302
|
+
github: {
|
|
303
|
+
db: prisma,
|
|
304
|
+
authorizer: githubAuthorizer,
|
|
305
|
+
redirectUri: `${httpOrigin}${userCallbackPath("github")}`,
|
|
306
|
+
},
|
|
307
|
+
}
|
|
308
|
+
: undefined;
|
|
309
|
+
mcpLog.info({ enabled: Boolean(hostUserAuth) }, "GitHub account linking");
|
|
310
|
+
const canonicalHref = canonicalUrl(mcpConfig.canonicalUri).href;
|
|
311
|
+
const viewerBus = process.env.DATABASE_URL
|
|
312
|
+
? createViewerEventBus({ connectionString: process.env.DATABASE_URL })
|
|
313
|
+
: undefined;
|
|
314
|
+
const viewer = viewerBus
|
|
315
|
+
? createViewerApi({
|
|
316
|
+
db: prisma,
|
|
317
|
+
bus: viewerBus,
|
|
318
|
+
authenticate: (authorization) => authenticate({ authorization }, { authProvider, db: prisma, providers, canonicalUri: canonicalHref }),
|
|
319
|
+
canonicalUri: canonicalHref,
|
|
320
|
+
})
|
|
321
|
+
: undefined;
|
|
162
322
|
const http = await startHttpServer({
|
|
163
323
|
mcp,
|
|
164
324
|
config: {
|
|
165
|
-
canonicalUri:
|
|
325
|
+
canonicalUri: canonicalHref,
|
|
166
326
|
httpBind: mcpConfig.httpBind,
|
|
167
327
|
authProviderKind,
|
|
168
328
|
authorizationServer: authConfig.issuer,
|
|
@@ -170,6 +330,9 @@ export async function startMcp(options = {}) {
|
|
|
170
330
|
},
|
|
171
331
|
auth: { authProvider, db: prisma, providers },
|
|
172
332
|
selfHosted,
|
|
333
|
+
hostEvents,
|
|
334
|
+
hostUserAuth,
|
|
335
|
+
viewer,
|
|
173
336
|
});
|
|
174
337
|
const cleanupTimer = selfHosted
|
|
175
338
|
? setInterval(() => {
|
|
@@ -181,7 +344,12 @@ export async function startMcp(options = {}) {
|
|
|
181
344
|
if (cleanupTimer)
|
|
182
345
|
clearInterval(cleanupTimer);
|
|
183
346
|
await closeQuietly(http.close(), "HTTP transport close");
|
|
347
|
+
await closeQuietly(viewerBus?.close(), "viewer event bus close");
|
|
348
|
+
// Let the runs this instance is executing finish before the executor
|
|
349
|
+
// closes under them; a run abandoned here is lost, never resumed.
|
|
350
|
+
await waitForInFlightRuns(drainSeconds * 1000);
|
|
184
351
|
await closeQuietly(providers.executor.close?.(), "executor close");
|
|
352
|
+
modelCatalog.close();
|
|
185
353
|
},
|
|
186
354
|
};
|
|
187
355
|
}
|
package/dist/mcp/server.js
CHANGED
|
@@ -24,11 +24,15 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { McpServer, fromJsonSchema, createRequestStateCodec, CLIENT_CAPABILITIES_META_KEY, } from "@modelcontextprotocol/server";
|
|
26
26
|
import { randomBytes } from "node:crypto";
|
|
27
|
+
import { readFileSync } from "node:fs";
|
|
27
28
|
import { requireScope } from "./auth/resource-server.js";
|
|
28
|
-
import { McpError } from "./errors.js";
|
|
29
|
+
import { McpError, mapPrismaError } from "./errors.js";
|
|
29
30
|
import { TASKS_EXTENSION_ID, clientSupportsTasks } from "./capabilities.js";
|
|
30
|
-
import {
|
|
31
|
+
import { readableAgentsWhere } from "./auth/access.js";
|
|
32
|
+
import { grantedIds } from "../core/grants.js";
|
|
31
33
|
import { logger } from "../core/logger.js";
|
|
34
|
+
/** The package version, reported in MCP server info (package.json sits two levels up from src/mcp and dist/mcp). */
|
|
35
|
+
const SERVER_VERSION = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8")).version;
|
|
32
36
|
const REQUEST_STATE_KEY_BYTES = 32;
|
|
33
37
|
/**
|
|
34
38
|
* REQUEST_STATE_KEY (hex, 32 bytes) shares the requestState HMAC key across
|
|
@@ -54,7 +58,7 @@ function loadRequestStateKey(env) {
|
|
|
54
58
|
* with the per-agent MCP prompts registered below, which are the concrete,
|
|
55
59
|
* one-call way to actually do it.
|
|
56
60
|
*/
|
|
57
|
-
const SERVER_INSTRUCTIONS = 'wardby hosts reusable LLM agents (a system prompt, model, budget, and attached tools) that normally run on a schedule or webhook trigger. Every agent\'s full system prompt is available via list_agents/get_agent ("systemPrompt" field), and agents you can see are also registered as MCP prompts by name — you can adopt an agent\'s instructions and run them yourself, in this session, right now. This is a good way to shift work like code review left: e.g., before committing, run the "systemPrompt" of a code-review agent against your own working tree using your own tools, rather than waiting for a separately triggered run. Where a pulled prompt names a wardby-specific sandboxed tool, use your own equivalent tool for the same purpose instead.';
|
|
61
|
+
const SERVER_INSTRUCTIONS = 'wardby hosts reusable LLM agents (a system prompt, model, budget, and attached tools) that normally run on a schedule or webhook trigger. Every agent\'s full system prompt is available via list_agents/get_agent ("systemPrompt" field), and agents you can see are also registered as MCP prompts by name — you can adopt an agent\'s instructions and run them yourself, in this session, right now. This is a good way to shift work like code review left: e.g., before committing, run the "systemPrompt" of a code-review agent against your own working tree using your own tools, rather than waiting for a separately triggered run. Where a pulled prompt names a wardby-specific sandboxed tool, use your own equivalent tool for the same purpose instead. To set up a first agent — an architecture keeper or a builder — read the help article "agent-recipes" with get_help_article and follow its procedure.';
|
|
58
62
|
/** The MCP prompt body for one Agent — the message a client injects when a user invokes it (e.g. as a slash command). */
|
|
59
63
|
function agentPromptText(agent) {
|
|
60
64
|
return [
|
|
@@ -97,6 +101,7 @@ export function buildMcpServer(opts) {
|
|
|
97
101
|
return {
|
|
98
102
|
principal: extra.principal,
|
|
99
103
|
scopes: new Set(authInfo.scopes),
|
|
104
|
+
roles: extra.roles ?? [],
|
|
100
105
|
canonicalUri: opts.config.canonicalUri,
|
|
101
106
|
providers: opts.providers,
|
|
102
107
|
db: opts.db,
|
|
@@ -117,7 +122,7 @@ export function buildMcpServer(opts) {
|
|
|
117
122
|
requestHandlers.push({ method, scope: Array.isArray(scope) ? scope : [scope], handler });
|
|
118
123
|
}
|
|
119
124
|
const factory = async () => {
|
|
120
|
-
const mcpServer = new McpServer({ name: "wardby", version:
|
|
125
|
+
const mcpServer = new McpServer({ name: "wardby", version: SERVER_VERSION }, {
|
|
121
126
|
requestState: { verify: (state, ctx) => requestStateCodec.verify(state, ctx) },
|
|
122
127
|
instructions: SERVER_INSTRUCTIONS,
|
|
123
128
|
});
|
|
@@ -130,7 +135,14 @@ export function buildMcpServer(opts) {
|
|
|
130
135
|
}, async (args, sdkCtx) => {
|
|
131
136
|
const ctx = resolveCtx(sdkCtx);
|
|
132
137
|
requireScope(ctx, opts.config.canonicalUri, ...requiredScopes);
|
|
133
|
-
|
|
138
|
+
try {
|
|
139
|
+
return await spec.handler(args, ctx);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
// A raw Prisma error would reach the client verbatim (the SDK
|
|
143
|
+
// renders any thrown error's message) -- see mapPrismaError.
|
|
144
|
+
throw mapPrismaError(err);
|
|
145
|
+
}
|
|
134
146
|
});
|
|
135
147
|
}
|
|
136
148
|
// Non-spec (extension) methods need a { params, result } schema bundle
|
|
@@ -143,7 +155,12 @@ export function buildMcpServer(opts) {
|
|
|
143
155
|
mcpServer.server.setRequestHandler(method, { params: PERMISSIVE_SCHEMA }, async (params, sdkCtx) => {
|
|
144
156
|
const ctx = resolveCtx(sdkCtx);
|
|
145
157
|
requireScope(ctx, opts.config.canonicalUri, ...scope);
|
|
146
|
-
|
|
158
|
+
try {
|
|
159
|
+
return (await handler(params, ctx));
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
throw mapPrismaError(err);
|
|
163
|
+
}
|
|
147
164
|
});
|
|
148
165
|
}
|
|
149
166
|
// One MCP prompt per Agent this connection can see, so a client that
|
|
@@ -154,12 +171,16 @@ export function buildMcpServer(opts) {
|
|
|
154
171
|
// resolves it per-dispatch from the SDK's own per-call ServerContext,
|
|
155
172
|
// not at factory time) — stdio's fixedContext IS set by now
|
|
156
173
|
// (mcp/index.ts calls setFixedContext before serveStdio ever invokes
|
|
157
|
-
// this factory), so stdio sees every agent it
|
|
158
|
-
// HTTP conservatively falls back to
|
|
159
|
-
//
|
|
160
|
-
//
|
|
174
|
+
// this factory), so stdio sees every agent it can read;
|
|
175
|
+
// HTTP conservatively falls back to agents shared with everyone (a
|
|
176
|
+
// grant of at least read) until this factory can see request-scoped
|
|
177
|
+
// identity; stdio sees what its principal can read (the operator: all).
|
|
178
|
+
// A DB hiccup here must not break tool registration — this is a
|
|
179
|
+
// discoverability nicety, not core function.
|
|
161
180
|
try {
|
|
162
|
-
const where = fixedContext
|
|
181
|
+
const where = fixedContext
|
|
182
|
+
? await readableAgentsWhere(fixedContext, opts.db)
|
|
183
|
+
: { id: { in: await grantedIds(opts.db, "agent", null, "read") } };
|
|
163
184
|
const agents = await opts.db.agent.findMany({ where });
|
|
164
185
|
for (const agent of agents) {
|
|
165
186
|
mcpServer.registerPrompt(agent.name, {
|