@wardby/cli 0.1.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 +131 -0
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +282 -0
- package/bin/wardby.js +3 -0
- package/deploy/local/docker-compose.yml +19 -0
- package/dist/claude-coding-worker/driver.d.ts +70 -0
- package/dist/claude-coding-worker/driver.js +128 -0
- package/dist/claude-coding-worker/main.d.ts +2 -0
- package/dist/claude-coding-worker/main.js +41 -0
- package/dist/claude-coding-worker/sdk.d.ts +4 -0
- package/dist/claude-coding-worker/sdk.js +43 -0
- package/dist/claude-coding-worker/tool-relay.d.ts +1 -0
- package/dist/claude-coding-worker/tool-relay.js +9 -0
- package/dist/cli-help.d.ts +1 -0
- package/dist/cli-help.js +20 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.js +629 -0
- package/dist/coding/observability.d.ts +59 -0
- package/dist/coding/observability.js +77 -0
- package/dist/coding/profile.d.ts +88 -0
- package/dist/coding/profile.js +137 -0
- package/dist/coding/protocol.d.ts +345 -0
- package/dist/coding/protocol.js +445 -0
- package/dist/coding/provider.d.ts +4 -0
- package/dist/coding/provider.js +18 -0
- package/dist/coding-proxy/main.d.ts +1 -0
- package/dist/coding-proxy/main.js +51 -0
- package/dist/coding-worker/artifact.d.ts +16 -0
- package/dist/coding-worker/artifact.js +37 -0
- package/dist/coding-worker/driver.d.ts +46 -0
- package/dist/coding-worker/driver.js +158 -0
- package/dist/coding-worker/errors.d.ts +1 -0
- package/dist/coding-worker/errors.js +23 -0
- package/dist/coding-worker/isolation-probe.d.ts +1 -0
- package/dist/coding-worker/isolation-probe.js +146 -0
- package/dist/coding-worker/keeper.d.ts +4 -0
- package/dist/coding-worker/keeper.js +29 -0
- package/dist/coding-worker/main.d.ts +2 -0
- package/dist/coding-worker/main.js +43 -0
- package/dist/coding-worker/sdk.d.ts +26 -0
- package/dist/coding-worker/sdk.js +28 -0
- package/dist/coding-worker/types.d.ts +64 -0
- package/dist/coding-worker/types.js +1 -0
- package/dist/config/providers.d.ts +158 -0
- package/dist/config/providers.js +162 -0
- package/dist/core/budget-groups.d.ts +72 -0
- package/dist/core/budget-groups.js +149 -0
- package/dist/core/budget.d.ts +63 -0
- package/dist/core/budget.js +69 -0
- package/dist/core/coding-queue.d.ts +32 -0
- package/dist/core/coding-queue.js +54 -0
- package/dist/core/cron.d.ts +31 -0
- package/dist/core/cron.js +43 -0
- package/dist/core/datastores.d.ts +41 -0
- package/dist/core/datastores.js +105 -0
- package/dist/core/db.d.ts +2 -0
- package/dist/core/db.js +2 -0
- package/dist/core/dispatch.d.ts +81 -0
- package/dist/core/dispatch.js +184 -0
- package/dist/core/engine-native.d.ts +29 -0
- package/dist/core/engine-native.js +259 -0
- package/dist/core/http-runtime.d.ts +7 -0
- package/dist/core/http-runtime.js +101 -0
- package/dist/core/lease.d.ts +13 -0
- package/dist/core/lease.js +22 -0
- package/dist/core/logger.d.ts +13 -0
- package/dist/core/logger.js +45 -0
- package/dist/core/memory-tools.d.ts +11 -0
- package/dist/core/memory-tools.js +122 -0
- package/dist/core/reconciler.d.ts +45 -0
- package/dist/core/reconciler.js +152 -0
- package/dist/core/runner.d.ts +87 -0
- package/dist/core/runner.js +529 -0
- package/dist/core/scheduler.d.ts +47 -0
- package/dist/core/scheduler.js +121 -0
- package/dist/core/secrets.d.ts +46 -0
- package/dist/core/secrets.js +100 -0
- package/dist/core/subagent-memory-tools.d.ts +18 -0
- package/dist/core/subagent-memory-tools.js +121 -0
- package/dist/core/timing.d.ts +7 -0
- package/dist/core/timing.js +7 -0
- package/dist/core/webhooks.d.ts +23 -0
- package/dist/core/webhooks.js +113 -0
- package/dist/env.d.ts +11 -0
- package/dist/env.js +13 -0
- package/dist/import/budgets.d.ts +16 -0
- package/dist/import/budgets.js +21 -0
- package/dist/import/bundle.d.ts +16 -0
- package/dist/import/bundle.js +61 -0
- package/dist/import/cli-args.d.ts +2 -0
- package/dist/import/cli-args.js +44 -0
- package/dist/import/create.d.ts +34 -0
- package/dist/import/create.js +363 -0
- package/dist/import/index.d.ts +25 -0
- package/dist/import/index.js +130 -0
- package/dist/import/model-gate.d.ts +1 -0
- package/dist/import/model-gate.js +3 -0
- package/dist/import/neutral-schema.d.ts +369 -0
- package/dist/import/neutral-schema.js +109 -0
- package/dist/import/preflight.d.ts +41 -0
- package/dist/import/preflight.js +71 -0
- package/dist/import/report.d.ts +5 -0
- package/dist/import/report.js +98 -0
- package/dist/import/tool-scan.d.ts +8 -0
- package/dist/import/tool-scan.js +20 -0
- package/dist/mcp/auth/ownership.d.ts +113 -0
- package/dist/mcp/auth/ownership.js +87 -0
- package/dist/mcp/auth/principal.d.ts +9 -0
- package/dist/mcp/auth/principal.js +9 -0
- package/dist/mcp/auth/resource-server.d.ts +47 -0
- package/dist/mcp/auth/resource-server.js +82 -0
- package/dist/mcp/auth/self-hosted/browser.d.ts +3 -0
- package/dist/mcp/auth/self-hosted/browser.js +273 -0
- package/dist/mcp/auth/self-hosted/cli.d.ts +2 -0
- package/dist/mcp/auth/self-hosted/cli.js +39 -0
- package/dist/mcp/auth/self-hosted/credentials.d.ts +58 -0
- package/dist/mcp/auth/self-hosted/credentials.js +106 -0
- package/dist/mcp/auth/self-hosted/rate-limit.d.ts +13 -0
- package/dist/mcp/auth/self-hosted/rate-limit.js +20 -0
- package/dist/mcp/auth/self-hosted/session.d.ts +36 -0
- package/dist/mcp/auth/self-hosted/session.js +110 -0
- package/dist/mcp/capabilities.d.ts +11 -0
- package/dist/mcp/capabilities.js +10 -0
- package/dist/mcp/context.d.ts +46 -0
- package/dist/mcp/context.js +1 -0
- package/dist/mcp/errors.d.ts +13 -0
- package/dist/mcp/errors.js +22 -0
- package/dist/mcp/index.d.ts +32 -0
- package/dist/mcp/index.js +187 -0
- package/dist/mcp/jsonrpc.d.ts +8 -0
- package/dist/mcp/jsonrpc.js +1 -0
- package/dist/mcp/server.d.ts +107 -0
- package/dist/mcp/server.js +203 -0
- package/dist/mcp/tasks/manager.d.ts +63 -0
- package/dist/mcp/tasks/manager.js +103 -0
- package/dist/mcp/tools/agents.d.ts +2 -0
- package/dist/mcp/tools/agents.js +375 -0
- package/dist/mcp/tools/budget-groups.d.ts +2 -0
- package/dist/mcp/tools/budget-groups.js +136 -0
- package/dist/mcp/tools/datastore.d.ts +2 -0
- package/dist/mcp/tools/datastore.js +217 -0
- package/dist/mcp/tools/memory.d.ts +3 -0
- package/dist/mcp/tools/memory.js +60 -0
- package/dist/mcp/tools/models.d.ts +8 -0
- package/dist/mcp/tools/models.js +15 -0
- package/dist/mcp/tools/runs.d.ts +2 -0
- package/dist/mcp/tools/runs.js +61 -0
- package/dist/mcp/tools/scheduling.d.ts +2 -0
- package/dist/mcp/tools/scheduling.js +48 -0
- package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -0
- package/dist/mcp/tools/secret-elicitation-form.js +93 -0
- package/dist/mcp/tools/secret-elicitation-server.d.ts +5 -0
- package/dist/mcp/tools/secret-elicitation-server.js +57 -0
- package/dist/mcp/tools/secret-elicitation.d.ts +38 -0
- package/dist/mcp/tools/secret-elicitation.js +52 -0
- package/dist/mcp/tools/secrets.d.ts +13 -0
- package/dist/mcp/tools/secrets.js +124 -0
- package/dist/mcp/tools/subagents.d.ts +2 -0
- package/dist/mcp/tools/subagents.js +133 -0
- package/dist/mcp/tools/text-result.d.ts +6 -0
- package/dist/mcp/tools/text-result.js +3 -0
- package/dist/mcp/tools/tools.d.ts +2 -0
- package/dist/mcp/tools/tools.js +211 -0
- package/dist/mcp/tools/trigger.d.ts +2 -0
- package/dist/mcp/tools/trigger.js +120 -0
- package/dist/mcp/tools/webhooks.d.ts +2 -0
- package/dist/mcp/tools/webhooks.js +34 -0
- package/dist/mcp/transport/http-limits.d.ts +17 -0
- package/dist/mcp/transport/http-limits.js +92 -0
- package/dist/mcp/transport/stdio.d.ts +23 -0
- package/dist/mcp/transport/stdio.js +6 -0
- package/dist/mcp/transport/streamable-http.d.ts +34 -0
- package/dist/mcp/transport/streamable-http.js +158 -0
- package/dist/mcp/unattended-schedules.d.ts +15 -0
- package/dist/mcp/unattended-schedules.js +21 -0
- package/dist/mcp/webhooks/ingress.d.ts +17 -0
- package/dist/mcp/webhooks/ingress.js +33 -0
- package/dist/observability/config.d.ts +6 -0
- package/dist/observability/config.js +20 -0
- package/dist/observability/metrics-server.d.ts +11 -0
- package/dist/observability/metrics-server.js +47 -0
- package/dist/observability/metrics.d.ts +36 -0
- package/dist/observability/metrics.js +158 -0
- package/dist/providers/auth/authorization-server.d.ts +41 -0
- package/dist/providers/auth/authorization-server.js +1 -0
- package/dist/providers/auth/delegating.d.ts +44 -0
- package/dist/providers/auth/delegating.js +105 -0
- package/dist/providers/auth/index.d.ts +11 -0
- package/dist/providers/auth/index.js +20 -0
- package/dist/providers/auth/release-gate.d.ts +1 -0
- package/dist/providers/auth/release-gate.js +4 -0
- package/dist/providers/auth/self-hosted.d.ts +78 -0
- package/dist/providers/auth/self-hosted.js +377 -0
- package/dist/providers/auth/subject.d.ts +1 -0
- package/dist/providers/auth/subject.js +6 -0
- package/dist/providers/auth/types.d.ts +63 -0
- package/dist/providers/auth/types.js +22 -0
- package/dist/providers/coding-proxy/deny-port.d.ts +5 -0
- package/dist/providers/coding-proxy/deny-port.js +45 -0
- package/dist/providers/coding-proxy/environment-credentials.d.ts +7 -0
- package/dist/providers/coding-proxy/environment-credentials.js +16 -0
- package/dist/providers/coding-proxy/index.d.ts +7 -0
- package/dist/providers/coding-proxy/index.js +7 -0
- package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -0
- package/dist/providers/coding-proxy/memory-ledger.js +103 -0
- package/dist/providers/coding-proxy/metering.d.ts +20 -0
- package/dist/providers/coding-proxy/metering.js +161 -0
- package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +213 -0
- package/dist/providers/coding-proxy/proxy.d.ts +75 -0
- package/dist/providers/coding-proxy/proxy.js +721 -0
- package/dist/providers/coding-proxy/runtime.d.ts +18 -0
- package/dist/providers/coding-proxy/runtime.js +39 -0
- package/dist/providers/coding-proxy/secure-fetch.d.ts +9 -0
- package/dist/providers/coding-proxy/secure-fetch.js +72 -0
- package/dist/providers/coding-proxy/server.d.ts +17 -0
- package/dist/providers/coding-proxy/server.js +139 -0
- package/dist/providers/coding-proxy/types.d.ts +99 -0
- package/dist/providers/coding-proxy/types.js +1 -0
- package/dist/providers/datastore/index.d.ts +2 -0
- package/dist/providers/datastore/index.js +2 -0
- package/dist/providers/datastore/postgres.d.ts +20 -0
- package/dist/providers/datastore/postgres.js +130 -0
- package/dist/providers/datastore/scoped.d.ts +10 -0
- package/dist/providers/datastore/scoped.js +46 -0
- package/dist/providers/datastore/types.d.ts +31 -0
- package/dist/providers/datastore/types.js +7 -0
- package/dist/providers/email/types.d.ts +46 -0
- package/dist/providers/email/types.js +8 -0
- package/dist/providers/engine/index.d.ts +1 -0
- package/dist/providers/engine/index.js +1 -0
- package/dist/providers/engine/types.d.ts +67 -0
- package/dist/providers/engine/types.js +16 -0
- package/dist/providers/executor/build.d.ts +6 -0
- package/dist/providers/executor/build.js +15 -0
- package/dist/providers/executor/composition.d.ts +14 -0
- package/dist/providers/executor/composition.js +123 -0
- package/dist/providers/executor/container.d.ts +184 -0
- package/dist/providers/executor/container.js +936 -0
- package/dist/providers/executor/dbos-status.d.ts +50 -0
- package/dist/providers/executor/dbos-status.js +64 -0
- package/dist/providers/executor/dbos.d.ts +53 -0
- package/dist/providers/executor/dbos.js +269 -0
- package/dist/providers/executor/in-process.d.ts +18 -0
- package/dist/providers/executor/in-process.js +38 -0
- package/dist/providers/executor/index.d.ts +8 -0
- package/dist/providers/executor/index.js +8 -0
- package/dist/providers/executor/routing.d.ts +48 -0
- package/dist/providers/executor/routing.js +70 -0
- package/dist/providers/executor/types.d.ts +55 -0
- package/dist/providers/executor/types.js +1 -0
- package/dist/providers/index.d.ts +43 -0
- package/dist/providers/index.js +18 -0
- package/dist/providers/jobs/docker-isolation.d.ts +166 -0
- package/dist/providers/jobs/docker-isolation.js +724 -0
- package/dist/providers/jobs/docker.d.ts +127 -0
- package/dist/providers/jobs/docker.js +1027 -0
- package/dist/providers/jobs/fake-kubernetes-api.d.ts +98 -0
- package/dist/providers/jobs/fake-kubernetes-api.js +142 -0
- package/dist/providers/jobs/fake.d.ts +23 -0
- package/dist/providers/jobs/fake.js +132 -0
- package/dist/providers/jobs/kubernetes-api.d.ts +60 -0
- package/dist/providers/jobs/kubernetes-api.js +20 -0
- package/dist/providers/jobs/kubernetes-client.d.ts +36 -0
- package/dist/providers/jobs/kubernetes-client.js +171 -0
- package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +49 -0
- package/dist/providers/jobs/kubernetes-dry-run-fixture.js +141 -0
- package/dist/providers/jobs/kubernetes-isolation.d.ts +147 -0
- package/dist/providers/jobs/kubernetes-isolation.js +607 -0
- package/dist/providers/jobs/kubernetes-platform.d.ts +177 -0
- package/dist/providers/jobs/kubernetes-platform.js +280 -0
- package/dist/providers/jobs/kubernetes-preflight.d.ts +59 -0
- package/dist/providers/jobs/kubernetes-preflight.js +339 -0
- package/dist/providers/jobs/kubernetes-witness.d.ts +10 -0
- package/dist/providers/jobs/kubernetes-witness.js +193 -0
- package/dist/providers/jobs/kubernetes.d.ts +127 -0
- package/dist/providers/jobs/kubernetes.js +874 -0
- package/dist/providers/jobs/safe-extract.d.ts +9 -0
- package/dist/providers/jobs/safe-extract.js +325 -0
- package/dist/providers/jobs/types.d.ts +78 -0
- package/dist/providers/jobs/types.js +6 -0
- package/dist/providers/jobs/workspace-swap.d.ts +2 -0
- package/dist/providers/jobs/workspace-swap.js +47 -0
- package/dist/providers/llm/anthropic.d.ts +13 -0
- package/dist/providers/llm/anthropic.js +21 -0
- package/dist/providers/llm/bedrock.d.ts +19 -0
- package/dist/providers/llm/bedrock.js +33 -0
- package/dist/providers/llm/claude-messages.d.ts +106 -0
- package/dist/providers/llm/claude-messages.js +157 -0
- package/dist/providers/llm/claude-provider.d.ts +40 -0
- package/dist/providers/llm/claude-provider.js +31 -0
- package/dist/providers/llm/index.d.ts +10 -0
- package/dist/providers/llm/index.js +10 -0
- package/dist/providers/llm/openai.d.ts +23 -0
- package/dist/providers/llm/openai.js +156 -0
- package/dist/providers/llm/pricing-anthropic.d.ts +4 -0
- package/dist/providers/llm/pricing-anthropic.js +30 -0
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +12 -0
- package/dist/providers/llm/pricing-bedrock-claude.js +37 -0
- package/dist/providers/llm/pricing-core.d.ts +26 -0
- package/dist/providers/llm/pricing-core.js +17 -0
- package/dist/providers/llm/pricing.d.ts +30 -0
- package/dist/providers/llm/pricing.js +74 -0
- package/dist/providers/llm/registration.d.ts +8 -0
- package/dist/providers/llm/registration.js +39 -0
- package/dist/providers/llm/routing.d.ts +25 -0
- package/dist/providers/llm/routing.js +32 -0
- package/dist/providers/llm/types.d.ts +85 -0
- package/dist/providers/llm/types.js +12 -0
- package/dist/providers/memory/index.d.ts +2 -0
- package/dist/providers/memory/index.js +2 -0
- package/dist/providers/memory/postgres.d.ts +20 -0
- package/dist/providers/memory/postgres.js +72 -0
- package/dist/providers/memory/types.d.ts +32 -0
- package/dist/providers/memory/types.js +17 -0
- package/dist/providers/secrets/app-key.d.ts +8 -0
- package/dist/providers/secrets/app-key.js +50 -0
- package/dist/providers/secrets/index.d.ts +10 -0
- package/dist/providers/secrets/index.js +13 -0
- package/dist/providers/secrets/transfer-envelope.d.ts +12 -0
- package/dist/providers/secrets/transfer-envelope.js +35 -0
- package/dist/providers/secrets/types.d.ts +18 -0
- package/dist/providers/secrets/types.js +12 -0
- package/dist/providers/storage/types.d.ts +18 -0
- package/dist/providers/storage/types.js +7 -0
- package/dist/providers/vcs/git.d.ts +105 -0
- package/dist/providers/vcs/git.js +710 -0
- package/dist/providers/vcs/github.d.ts +105 -0
- package/dist/providers/vcs/github.js +394 -0
- package/dist/providers/vcs/index.d.ts +6 -0
- package/dist/providers/vcs/index.js +26 -0
- package/dist/providers/vcs/types.d.ts +118 -0
- package/dist/providers/vcs/types.js +1 -0
- package/dist/sandbox/bounded-json.d.ts +2 -0
- package/dist/sandbox/bounded-json.js +36 -0
- package/dist/sandbox/bridge.d.ts +15 -0
- package/dist/sandbox/bridge.js +78 -0
- package/dist/sandbox/eval-core.d.ts +37 -0
- package/dist/sandbox/eval-core.js +159 -0
- package/dist/sandbox/fetch-policy.d.ts +24 -0
- package/dist/sandbox/fetch-policy.js +96 -0
- package/dist/sandbox/generated/zod-to-json-schema.bundle.js +5 -0
- package/dist/sandbox/generated/zod.bundle.js +1 -0
- package/dist/sandbox/host-functions.d.ts +29 -0
- package/dist/sandbox/host-functions.js +168 -0
- package/dist/sandbox/limits.d.ts +39 -0
- package/dist/sandbox/limits.js +39 -0
- package/dist/sandbox/parser-worker/__fixtures__/crash.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/crash.js +6 -0
- package/dist/sandbox/parser-worker/__fixtures__/echo.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/echo.js +5 -0
- package/dist/sandbox/parser-worker/__fixtures__/reject.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/reject.js +5 -0
- package/dist/sandbox/parser-worker/__fixtures__/spin-forever.d.ts +1 -0
- package/dist/sandbox/parser-worker/__fixtures__/spin-forever.js +11 -0
- package/dist/sandbox/parser-worker/pool.d.ts +13 -0
- package/dist/sandbox/parser-worker/pool.js +111 -0
- package/dist/sandbox/parser-worker/worker.d.ts +14 -0
- package/dist/sandbox/parser-worker/worker.js +63 -0
- package/dist/sandbox/pii-redaction.d.ts +1 -0
- package/dist/sandbox/pii-redaction.js +29 -0
- package/dist/sandbox/prelude.d.ts +26 -0
- package/dist/sandbox/prelude.js +408 -0
- package/dist/sandbox/quickjs-module.d.ts +13 -0
- package/dist/sandbox/quickjs-module.js +19 -0
- package/dist/sandbox/run-in-sandbox.d.ts +34 -0
- package/dist/sandbox/run-in-sandbox.js +53 -0
- package/dist/sandbox/safe-fetch.d.ts +26 -0
- package/dist/sandbox/safe-fetch.js +140 -0
- package/dist/sandbox/tool-capabilities.d.ts +66 -0
- package/dist/sandbox/tool-capabilities.js +103 -0
- package/dist/sandbox/zod-params.d.ts +22 -0
- package/dist/sandbox/zod-params.js +60 -0
- package/dist/serve.d.ts +14 -0
- package/dist/serve.js +54 -0
- package/dist/wardby-bin.d.ts +2 -0
- package/dist/wardby-bin.js +20 -0
- package/package.json +123 -0
- package/prisma/migrations/20260905000000_init/migration.sql +34 -0
- package/prisma/migrations/20260905010000_scheduler_durability/migration.sql +31 -0
- package/prisma/migrations/20260905020000_tools_multiturn/migration.sql +47 -0
- package/prisma/migrations/20260905030000_cache_tool_json_schema/migration.sql +13 -0
- package/prisma/migrations/20260906000000_mcp_phase4/migration.sql +115 -0
- package/prisma/migrations/20260906010000_run_final_text/migration.sql +7 -0
- package/prisma/migrations/20260906020000_run_turns/migration.sql +6 -0
- package/prisma/migrations/20260906030000_task_principal_id/migration.sql +5 -0
- package/prisma/migrations/20260906040000_secure_self_hosted_oauth/migration.sql +67 -0
- package/prisma/migrations/20260906050000_phase5_coding_agents/migration.sql +52 -0
- package/prisma/migrations/20260906060000_tool_capability_scoping/migration.sql +22 -0
- package/prisma/migrations/20260906070000_datastore_pii_flag/migration.sql +6 -0
- package/prisma/migrations/20260906080000_secret_elicitation_outcomes/migration.sql +13 -0
- package/prisma/migrations/20260907010000_coding_proxy_ledger/migration.sql +57 -0
- package/prisma/migrations/20260907020000_budget_groups/migration.sql +24 -0
- package/prisma/migrations/20260907030000_coding_webhook_task_override/migration.sql +4 -0
- package/prisma/migrations/20260908010000_run_execution_backend/migration.sql +2 -0
- package/prisma/migrations/20260908020000_coding_run_audit_metadata/migration.sql +7 -0
- package/prisma/migrations/20260910010000_agent_secret_bound_name/migration.sql +16 -0
- package/prisma/migrations/20260911010000_coding_worker_toolchains/migration.sql +5 -0
- package/prisma/migrations/20260912010000_coding_provider_contract/migration.sql +24 -0
- package/prisma/migrations/20260912020000_coding_proxy_protocol/migration.sql +10 -0
- package/prisma/migrations/20260912030000_agent_memory/migration.sql +18 -0
- package/prisma/migrations/20260912040000_named_shared_datastores/migration.sql +68 -0
- package/prisma/migrations/20260913000000_run_trigger_webhook/migration.sql +2 -0
- package/prisma/migrations/20260913010000_agent_sub_agent/migration.sql +32 -0
- package/prisma/migrations/20260913020000_run_task_override/migration.sql +5 -0
- package/prisma/migrations/20260913030000_coding_run_root/migration.sql +11 -0
- package/prisma/migrations/20260922010000_coding_run_queued_at/migration.sql +8 -0
- package/prisma/migrations/20260922020000_coding_workspace_disk/migration.sql +8 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +723 -0
- package/scripts/git-askpass.sh +11 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { V1ConfigMap, V1Endpoints, V1NetworkPolicy, V1Pod, V1Secret, V1Service } from "@kubernetes/client-node";
|
|
2
|
+
import type { Readable, Writable } from "node:stream";
|
|
3
|
+
import { type KubernetesApi, type KubernetesExecOptions } from "./kubernetes-api.js";
|
|
4
|
+
export interface FakeExecCall {
|
|
5
|
+
namespace: string;
|
|
6
|
+
pod: string;
|
|
7
|
+
container: string;
|
|
8
|
+
command: string[];
|
|
9
|
+
stdin?: Readable;
|
|
10
|
+
stdout?: Writable;
|
|
11
|
+
}
|
|
12
|
+
type Kind = "configmap" | "secret" | "pod" | "networkpolicy" | "service" | "endpoints";
|
|
13
|
+
type Obj = {
|
|
14
|
+
metadata?: {
|
|
15
|
+
name?: string;
|
|
16
|
+
namespace?: string;
|
|
17
|
+
resourceVersion?: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/** In-memory KubernetesApi for unit tests. Tests drive pod status and exec behavior directly. */
|
|
21
|
+
export declare class FakeKubernetesApi implements KubernetesApi {
|
|
22
|
+
readonly objects: Map<string, Obj>;
|
|
23
|
+
readonly namespaces: Set<string>;
|
|
24
|
+
readonly execCalls: FakeExecCall[];
|
|
25
|
+
readonly deletedPods: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
gracePeriodSeconds: number;
|
|
28
|
+
}>;
|
|
29
|
+
/** Returns the exit code; write to stdout / read stdin as the command would. Default: exit 0, no output. */
|
|
30
|
+
onExec: (call: FakeExecCall) => Promise<number>;
|
|
31
|
+
/** The admission chain a dry-run create runs through. Default: echo the pod back unchanged. */
|
|
32
|
+
onDryRunCreatePod: (namespace: string, body: V1Pod) => Promise<V1Pod>;
|
|
33
|
+
logs: Map<string, string>;
|
|
34
|
+
/** What readApiServerVersion reports; tests that care about provenance set it. */
|
|
35
|
+
apiServerVersion: string;
|
|
36
|
+
private version;
|
|
37
|
+
private key;
|
|
38
|
+
private create;
|
|
39
|
+
private read;
|
|
40
|
+
private delete;
|
|
41
|
+
/** Test helper: overwrite an object without a resourceVersion check (e.g. to set pod status). */
|
|
42
|
+
put<T extends Obj>(kind: Kind, namespace: string, body: T): void;
|
|
43
|
+
createConfigMap(namespace: string, body: V1ConfigMap): Promise<V1ConfigMap>;
|
|
44
|
+
readConfigMap(namespace: string, name: string): Promise<V1ConfigMap | undefined>;
|
|
45
|
+
replaceConfigMap(namespace: string, name: string, body: V1ConfigMap): Promise<{
|
|
46
|
+
metadata: {
|
|
47
|
+
namespace: string;
|
|
48
|
+
resourceVersion: string;
|
|
49
|
+
annotations?: {
|
|
50
|
+
[key: string]: string;
|
|
51
|
+
};
|
|
52
|
+
creationTimestamp?: Date;
|
|
53
|
+
deletionGracePeriodSeconds?: number;
|
|
54
|
+
deletionTimestamp?: Date;
|
|
55
|
+
finalizers?: Array<string>;
|
|
56
|
+
generateName?: string;
|
|
57
|
+
generation?: number;
|
|
58
|
+
labels?: {
|
|
59
|
+
[key: string]: string;
|
|
60
|
+
};
|
|
61
|
+
managedFields?: Array<import("@kubernetes/client-node").V1ManagedFieldsEntry>;
|
|
62
|
+
name?: string;
|
|
63
|
+
ownerReferences?: Array<import("@kubernetes/client-node").V1OwnerReference>;
|
|
64
|
+
selfLink?: string;
|
|
65
|
+
uid?: string;
|
|
66
|
+
};
|
|
67
|
+
apiVersion?: string;
|
|
68
|
+
binaryData?: {
|
|
69
|
+
[key: string]: string;
|
|
70
|
+
};
|
|
71
|
+
data?: {
|
|
72
|
+
[key: string]: string;
|
|
73
|
+
};
|
|
74
|
+
immutable?: boolean;
|
|
75
|
+
kind?: string;
|
|
76
|
+
}>;
|
|
77
|
+
createSecret(namespace: string, body: V1Secret): Promise<V1Secret>;
|
|
78
|
+
deleteSecret(namespace: string, name: string): Promise<void>;
|
|
79
|
+
createPod(namespace: string, body: V1Pod): Promise<V1Pod>;
|
|
80
|
+
/**
|
|
81
|
+
* A dry-run create persists nothing, but it is still a create: the API server runs the same
|
|
82
|
+
* validation and name checks, so a nameless body and a colliding name both fail exactly as
|
|
83
|
+
* they would on a real create. Tests override `onDryRunCreatePod` to model an admission chain.
|
|
84
|
+
*/
|
|
85
|
+
dryRunCreatePod(namespace: string, body: V1Pod): Promise<V1Pod>;
|
|
86
|
+
readPod(namespace: string, name: string): Promise<V1Pod | undefined>;
|
|
87
|
+
deletePod(namespace: string, name: string, gracePeriodSeconds: number): Promise<void>;
|
|
88
|
+
createNetworkPolicy(namespace: string, body: V1NetworkPolicy): Promise<V1NetworkPolicy>;
|
|
89
|
+
readNetworkPolicy(namespace: string, name: string): Promise<V1NetworkPolicy | undefined>;
|
|
90
|
+
deleteNetworkPolicy(namespace: string, name: string): Promise<void>;
|
|
91
|
+
readService(namespace: string, name: string): Promise<V1Service | undefined>;
|
|
92
|
+
readEndpoints(namespace: string, name: string): Promise<V1Endpoints | undefined>;
|
|
93
|
+
readApiServerVersion(): Promise<string>;
|
|
94
|
+
readNamespace(name: string): Promise<boolean>;
|
|
95
|
+
exec(namespace: string, pod: string, container: string, command: string[], options: KubernetesExecOptions): Promise<number>;
|
|
96
|
+
readLogTail(namespace: string, pod: string, container: string, tailLines: number, limitBytes: number): Promise<string>;
|
|
97
|
+
}
|
|
98
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { KubernetesAlreadyExistsError, KubernetesConflictError, KubernetesNotFoundError, } from "./kubernetes-api.js";
|
|
2
|
+
/** In-memory KubernetesApi for unit tests. Tests drive pod status and exec behavior directly. */
|
|
3
|
+
export class FakeKubernetesApi {
|
|
4
|
+
objects = new Map();
|
|
5
|
+
namespaces = new Set(["wardby-coding"]);
|
|
6
|
+
execCalls = [];
|
|
7
|
+
deletedPods = [];
|
|
8
|
+
/** Returns the exit code; write to stdout / read stdin as the command would. Default: exit 0, no output. */
|
|
9
|
+
onExec = async ({ stdout, stdin }) => {
|
|
10
|
+
stdin?.resume();
|
|
11
|
+
stdout?.end();
|
|
12
|
+
return 0;
|
|
13
|
+
};
|
|
14
|
+
/** The admission chain a dry-run create runs through. Default: echo the pod back unchanged. */
|
|
15
|
+
onDryRunCreatePod = async (_namespace, body) => body;
|
|
16
|
+
logs = new Map();
|
|
17
|
+
/** What readApiServerVersion reports; tests that care about provenance set it. */
|
|
18
|
+
apiServerVersion = "v1.33.0";
|
|
19
|
+
version = 0;
|
|
20
|
+
key(kind, namespace, name) {
|
|
21
|
+
return `${kind}/${namespace}/${name}`;
|
|
22
|
+
}
|
|
23
|
+
create(kind, namespace, body) {
|
|
24
|
+
const name = body.metadata?.name;
|
|
25
|
+
if (!name)
|
|
26
|
+
throw new Error("fake_name_required");
|
|
27
|
+
const key = this.key(kind, namespace, name);
|
|
28
|
+
if (this.objects.has(key))
|
|
29
|
+
throw new KubernetesAlreadyExistsError(key);
|
|
30
|
+
const stored = structuredClone({
|
|
31
|
+
...body,
|
|
32
|
+
metadata: { ...body.metadata, namespace, resourceVersion: String(++this.version) },
|
|
33
|
+
});
|
|
34
|
+
this.objects.set(key, stored);
|
|
35
|
+
return structuredClone(stored);
|
|
36
|
+
}
|
|
37
|
+
read(kind, namespace, name) {
|
|
38
|
+
const found = this.objects.get(this.key(kind, namespace, name));
|
|
39
|
+
return found ? structuredClone(found) : undefined;
|
|
40
|
+
}
|
|
41
|
+
delete(kind, namespace, name) {
|
|
42
|
+
this.objects.delete(this.key(kind, namespace, name));
|
|
43
|
+
}
|
|
44
|
+
/** Test helper: overwrite an object without a resourceVersion check (e.g. to set pod status). */
|
|
45
|
+
put(kind, namespace, body) {
|
|
46
|
+
const name = body.metadata?.name;
|
|
47
|
+
this.objects.set(this.key(kind, namespace, name), {
|
|
48
|
+
...structuredClone(body),
|
|
49
|
+
metadata: { ...body.metadata, namespace, resourceVersion: String(++this.version) },
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async createConfigMap(namespace, body) {
|
|
53
|
+
return this.create("configmap", namespace, body);
|
|
54
|
+
}
|
|
55
|
+
async readConfigMap(namespace, name) {
|
|
56
|
+
return this.read("configmap", namespace, name);
|
|
57
|
+
}
|
|
58
|
+
async replaceConfigMap(namespace, name, body) {
|
|
59
|
+
const key = this.key("configmap", namespace, name);
|
|
60
|
+
const current = this.objects.get(key);
|
|
61
|
+
if (!current)
|
|
62
|
+
throw new KubernetesNotFoundError(key);
|
|
63
|
+
if (body.metadata?.resourceVersion !== current.metadata?.resourceVersion)
|
|
64
|
+
throw new KubernetesConflictError(key);
|
|
65
|
+
const stored = structuredClone({
|
|
66
|
+
...body,
|
|
67
|
+
metadata: { ...body.metadata, namespace, resourceVersion: String(++this.version) },
|
|
68
|
+
});
|
|
69
|
+
this.objects.set(key, stored);
|
|
70
|
+
return structuredClone(stored);
|
|
71
|
+
}
|
|
72
|
+
async createSecret(namespace, body) {
|
|
73
|
+
return this.create("secret", namespace, body);
|
|
74
|
+
}
|
|
75
|
+
async deleteSecret(namespace, name) {
|
|
76
|
+
this.delete("secret", namespace, name);
|
|
77
|
+
}
|
|
78
|
+
async createPod(namespace, body) {
|
|
79
|
+
return this.create("pod", namespace, body);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A dry-run create persists nothing, but it is still a create: the API server runs the same
|
|
83
|
+
* validation and name checks, so a nameless body and a colliding name both fail exactly as
|
|
84
|
+
* they would on a real create. Tests override `onDryRunCreatePod` to model an admission chain.
|
|
85
|
+
*/
|
|
86
|
+
async dryRunCreatePod(namespace, body) {
|
|
87
|
+
const name = body.metadata?.name;
|
|
88
|
+
if (!name)
|
|
89
|
+
throw new Error("fake_name_required");
|
|
90
|
+
const key = this.key("pod", namespace, name);
|
|
91
|
+
if (this.objects.has(key))
|
|
92
|
+
throw new KubernetesAlreadyExistsError(key);
|
|
93
|
+
return this.onDryRunCreatePod(namespace, structuredClone(body));
|
|
94
|
+
}
|
|
95
|
+
async readPod(namespace, name) {
|
|
96
|
+
return this.read("pod", namespace, name);
|
|
97
|
+
}
|
|
98
|
+
async deletePod(namespace, name, gracePeriodSeconds) {
|
|
99
|
+
this.deletedPods.push({ name, gracePeriodSeconds });
|
|
100
|
+
this.delete("pod", namespace, name);
|
|
101
|
+
}
|
|
102
|
+
async createNetworkPolicy(namespace, body) {
|
|
103
|
+
return this.create("networkpolicy", namespace, body);
|
|
104
|
+
}
|
|
105
|
+
async readNetworkPolicy(namespace, name) {
|
|
106
|
+
return this.read("networkpolicy", namespace, name);
|
|
107
|
+
}
|
|
108
|
+
async deleteNetworkPolicy(namespace, name) {
|
|
109
|
+
this.delete("networkpolicy", namespace, name);
|
|
110
|
+
}
|
|
111
|
+
async readService(namespace, name) {
|
|
112
|
+
return this.read("service", namespace, name);
|
|
113
|
+
}
|
|
114
|
+
async readEndpoints(namespace, name) {
|
|
115
|
+
return this.read("endpoints", namespace, name);
|
|
116
|
+
}
|
|
117
|
+
async readApiServerVersion() {
|
|
118
|
+
return this.apiServerVersion;
|
|
119
|
+
}
|
|
120
|
+
async readNamespace(name) {
|
|
121
|
+
return this.namespaces.has(name);
|
|
122
|
+
}
|
|
123
|
+
async exec(namespace, pod, container, command, options) {
|
|
124
|
+
// Like the real API: exec into a missing pod or an unknown container fails instead of succeeding
|
|
125
|
+
// silently, so no test can pass on behaviour a cluster would reject. (The adapter's timeoutMs is
|
|
126
|
+
// not modelled: tests drive slow execs through onExec directly.)
|
|
127
|
+
const target = this.read("pod", namespace, pod);
|
|
128
|
+
if (!target)
|
|
129
|
+
throw new KubernetesNotFoundError(this.key("pod", namespace, pod));
|
|
130
|
+
const containers = [...(target.spec?.containers ?? []), ...(target.spec?.initContainers ?? [])];
|
|
131
|
+
if (!containers.some((entry) => entry.name === container)) {
|
|
132
|
+
throw new KubernetesNotFoundError(`${this.key("pod", namespace, pod)}/${container}`);
|
|
133
|
+
}
|
|
134
|
+
const call = { namespace, pod, container, command, stdin: options.stdin, stdout: options.stdout };
|
|
135
|
+
this.execCalls.push(call);
|
|
136
|
+
return this.onExec(call);
|
|
137
|
+
}
|
|
138
|
+
async readLogTail(namespace, pod, container, tailLines, limitBytes) {
|
|
139
|
+
const lines = (this.logs.get(`${namespace}/${pod}/${container}`) ?? "").split("\n").slice(-tailLines).join("\n");
|
|
140
|
+
return Buffer.from(lines).subarray(0, limitBytes).toString();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { JobHandle, JobLauncher, JobResult, JobSpec, JobStatus } from "./types.js";
|
|
2
|
+
export interface FakeJobPlan {
|
|
3
|
+
/** Status returned by each successive poll; the final entry remains stable. */
|
|
4
|
+
statusScript?: JobStatus[];
|
|
5
|
+
result?: JobResult;
|
|
6
|
+
}
|
|
7
|
+
export declare class FakeJobLauncher implements JobLauncher {
|
|
8
|
+
private readonly jobs;
|
|
9
|
+
private readonly runIds;
|
|
10
|
+
private readonly plans;
|
|
11
|
+
private nextId;
|
|
12
|
+
queuePlan(plan: FakeJobPlan): void;
|
|
13
|
+
launch(spec: JobSpec): Promise<JobHandle>;
|
|
14
|
+
status(handle: JobHandle): Promise<JobStatus>;
|
|
15
|
+
collect(handle: JobHandle): Promise<JobResult>;
|
|
16
|
+
stop(handle: JobHandle, _reason?: string): Promise<void>;
|
|
17
|
+
remove(handle: JobHandle): Promise<void>;
|
|
18
|
+
finish(handle: JobHandle, result?: JobResult): Promise<void>;
|
|
19
|
+
lose(handle: JobHandle): Promise<void>;
|
|
20
|
+
private transition;
|
|
21
|
+
private findRecord;
|
|
22
|
+
private requireRecord;
|
|
23
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
const BACKEND = "fake";
|
|
3
|
+
const TERMINAL_STATES = new Set(["succeeded", "failed", "stopped", "lost"]);
|
|
4
|
+
function clone(value) {
|
|
5
|
+
return structuredClone(value);
|
|
6
|
+
}
|
|
7
|
+
function resultFor(status) {
|
|
8
|
+
switch (status.state) {
|
|
9
|
+
case "succeeded":
|
|
10
|
+
return { exitCode: 0, reason: "completed" };
|
|
11
|
+
case "failed":
|
|
12
|
+
return { exitCode: 1, reason: "failed" };
|
|
13
|
+
case "stopped":
|
|
14
|
+
return { exitCode: 143, reason: "stopped" };
|
|
15
|
+
case "lost":
|
|
16
|
+
return { exitCode: 1, reason: "lost" };
|
|
17
|
+
default:
|
|
18
|
+
throw new Error("job_not_terminal");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function statusFor(result) {
|
|
22
|
+
switch (result.reason) {
|
|
23
|
+
case "completed":
|
|
24
|
+
return { state: "succeeded" };
|
|
25
|
+
case "stopped":
|
|
26
|
+
return { state: "stopped" };
|
|
27
|
+
case "lost":
|
|
28
|
+
return { state: "lost" };
|
|
29
|
+
case "failed":
|
|
30
|
+
return { state: "failed" };
|
|
31
|
+
case "timed_out":
|
|
32
|
+
return { state: "failed", reason: "timed_out" };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class FakeJobLauncher {
|
|
36
|
+
jobs = new Map();
|
|
37
|
+
runIds = new Map();
|
|
38
|
+
plans = [];
|
|
39
|
+
nextId = 1;
|
|
40
|
+
queuePlan(plan) {
|
|
41
|
+
this.plans.push(clone(plan));
|
|
42
|
+
}
|
|
43
|
+
async launch(spec) {
|
|
44
|
+
const existingId = this.runIds.get(spec.runId);
|
|
45
|
+
if (existingId) {
|
|
46
|
+
const existing = this.jobs.get(existingId);
|
|
47
|
+
if (!existing)
|
|
48
|
+
throw new Error("job_state_corrupt");
|
|
49
|
+
if (!isDeepStrictEqual(existing.spec, spec))
|
|
50
|
+
throw new Error("job_spec_conflict");
|
|
51
|
+
return clone(existing.handle);
|
|
52
|
+
}
|
|
53
|
+
const handle = { backend: BACKEND, id: `job-${String(this.nextId++).padStart(4, "0")}` };
|
|
54
|
+
const plan = this.plans.shift() ?? {};
|
|
55
|
+
const statusScript = plan.statusScript?.length ? clone(plan.statusScript) : [{ state: "pending" }];
|
|
56
|
+
const record = {
|
|
57
|
+
handle,
|
|
58
|
+
spec: clone(spec),
|
|
59
|
+
status: { state: "pending" },
|
|
60
|
+
statusScript,
|
|
61
|
+
statusCursor: 0,
|
|
62
|
+
plannedResult: plan.result ? clone(plan.result) : undefined,
|
|
63
|
+
removed: false,
|
|
64
|
+
};
|
|
65
|
+
this.jobs.set(handle.id, record);
|
|
66
|
+
this.runIds.set(spec.runId, handle.id);
|
|
67
|
+
return clone(handle);
|
|
68
|
+
}
|
|
69
|
+
async status(handle) {
|
|
70
|
+
const record = this.requireRecord(handle);
|
|
71
|
+
if (!TERMINAL_STATES.has(record.status.state)) {
|
|
72
|
+
const scripted = record.statusScript[Math.min(record.statusCursor, record.statusScript.length - 1)];
|
|
73
|
+
record.statusCursor += 1;
|
|
74
|
+
this.transition(record, scripted, TERMINAL_STATES.has(scripted.state) ? record.plannedResult : undefined);
|
|
75
|
+
}
|
|
76
|
+
return clone(record.status);
|
|
77
|
+
}
|
|
78
|
+
async collect(handle) {
|
|
79
|
+
const record = this.requireRecord(handle);
|
|
80
|
+
if (!TERMINAL_STATES.has(record.status.state) || !record.result)
|
|
81
|
+
throw new Error("job_not_terminal");
|
|
82
|
+
return clone(record.result);
|
|
83
|
+
}
|
|
84
|
+
async stop(handle, _reason) {
|
|
85
|
+
const record = this.findRecord(handle);
|
|
86
|
+
if (!record || record.removed || TERMINAL_STATES.has(record.status.state))
|
|
87
|
+
return;
|
|
88
|
+
this.transition(record, { state: "stopped" });
|
|
89
|
+
}
|
|
90
|
+
async remove(handle) {
|
|
91
|
+
const record = this.findRecord(handle);
|
|
92
|
+
if (!record || record.removed)
|
|
93
|
+
return;
|
|
94
|
+
if (!TERMINAL_STATES.has(record.status.state))
|
|
95
|
+
throw new Error("job_not_terminal");
|
|
96
|
+
record.removed = true;
|
|
97
|
+
}
|
|
98
|
+
async finish(handle, result = { exitCode: 0, reason: "completed" }) {
|
|
99
|
+
const record = this.requireRecord(handle);
|
|
100
|
+
this.transition(record, statusFor(result), result);
|
|
101
|
+
}
|
|
102
|
+
async lose(handle) {
|
|
103
|
+
const record = this.requireRecord(handle);
|
|
104
|
+
this.transition(record, { state: "lost" });
|
|
105
|
+
}
|
|
106
|
+
transition(record, next, result) {
|
|
107
|
+
if (TERMINAL_STATES.has(record.status.state))
|
|
108
|
+
return;
|
|
109
|
+
if (record.status.state === "running" && next.state === "pending") {
|
|
110
|
+
throw new Error("job_illegal_transition");
|
|
111
|
+
}
|
|
112
|
+
if (result && statusFor(result).state !== next.state)
|
|
113
|
+
throw new Error("job_result_status_mismatch");
|
|
114
|
+
record.status = clone(next);
|
|
115
|
+
if (TERMINAL_STATES.has(next.state)) {
|
|
116
|
+
record.result = clone(result ?? resultFor(next));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
findRecord(handle) {
|
|
120
|
+
if (handle.backend !== BACKEND)
|
|
121
|
+
throw new Error("job_backend_mismatch");
|
|
122
|
+
return this.jobs.get(handle.id);
|
|
123
|
+
}
|
|
124
|
+
requireRecord(handle) {
|
|
125
|
+
const record = this.findRecord(handle);
|
|
126
|
+
if (!record)
|
|
127
|
+
throw new Error("job_not_found");
|
|
128
|
+
if (record.removed)
|
|
129
|
+
throw new Error("job_removed");
|
|
130
|
+
return record;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The only surface KubernetesJobLauncher uses to reach a cluster. Kept narrow
|
|
3
|
+
* so every launcher behavior is unit-tested against FakeKubernetesApi and
|
|
4
|
+
* re-proven against a real cluster by kubernetes.integration.test.ts.
|
|
5
|
+
*/
|
|
6
|
+
import type { V1ConfigMap, V1Endpoints, V1NetworkPolicy, V1Pod, V1Secret, V1Service } from "@kubernetes/client-node";
|
|
7
|
+
import type { Readable, Writable } from "node:stream";
|
|
8
|
+
export declare class KubernetesNotFoundError extends Error {
|
|
9
|
+
constructor(message?: string);
|
|
10
|
+
}
|
|
11
|
+
/** Stale resourceVersion on replace. */
|
|
12
|
+
export declare class KubernetesConflictError extends Error {
|
|
13
|
+
constructor(message?: string);
|
|
14
|
+
}
|
|
15
|
+
/** Create of an existing name. */
|
|
16
|
+
export declare class KubernetesAlreadyExistsError extends Error {
|
|
17
|
+
constructor(message?: string);
|
|
18
|
+
}
|
|
19
|
+
export interface KubernetesExecOptions {
|
|
20
|
+
stdin?: Readable;
|
|
21
|
+
stdout?: Writable;
|
|
22
|
+
timeoutMs: number;
|
|
23
|
+
}
|
|
24
|
+
/** Deletes are idempotent (a missing object is not an error). Reads return `undefined` for a missing object. */
|
|
25
|
+
export interface KubernetesApi {
|
|
26
|
+
createConfigMap(namespace: string, body: V1ConfigMap): Promise<V1ConfigMap>;
|
|
27
|
+
readConfigMap(namespace: string, name: string): Promise<V1ConfigMap | undefined>;
|
|
28
|
+
replaceConfigMap(namespace: string, name: string, body: V1ConfigMap): Promise<V1ConfigMap>;
|
|
29
|
+
createSecret(namespace: string, body: V1Secret): Promise<V1Secret>;
|
|
30
|
+
deleteSecret(namespace: string, name: string): Promise<void>;
|
|
31
|
+
createPod(namespace: string, body: V1Pod): Promise<V1Pod>;
|
|
32
|
+
/**
|
|
33
|
+
* Server-side dry-run create: the API server runs the whole admission chain and returns the
|
|
34
|
+
* mutated object without persisting anything. Used only by src/tools/capture-autopilot-dry-run.ts;
|
|
35
|
+
* never by the launcher, which must not let a cluster tell it what it is allowed to change.
|
|
36
|
+
*/
|
|
37
|
+
dryRunCreatePod(namespace: string, body: V1Pod): Promise<V1Pod>;
|
|
38
|
+
readPod(namespace: string, name: string): Promise<V1Pod | undefined>;
|
|
39
|
+
deletePod(namespace: string, name: string, gracePeriodSeconds: number): Promise<void>;
|
|
40
|
+
createNetworkPolicy(namespace: string, body: V1NetworkPolicy): Promise<V1NetworkPolicy>;
|
|
41
|
+
readNetworkPolicy(namespace: string, name: string): Promise<V1NetworkPolicy | undefined>;
|
|
42
|
+
deleteNetworkPolicy(namespace: string, name: string): Promise<void>;
|
|
43
|
+
readService(namespace: string, name: string): Promise<V1Service | undefined>;
|
|
44
|
+
/**
|
|
45
|
+
* Reads a Service's Endpoints by name. EndpointSlice is the durable successor to this core/v1
|
|
46
|
+
* resource (migrating to it is a follow-up); Endpoints is read by name so RBAC stays one object wide.
|
|
47
|
+
*/
|
|
48
|
+
readEndpoints(namespace: string, name: string): Promise<V1Endpoints | undefined>;
|
|
49
|
+
readNamespace(name: string): Promise<boolean>;
|
|
50
|
+
/** Runs a command in a container; resolves with its exit code. Never uses a shell. */
|
|
51
|
+
exec(namespace: string, pod: string, container: string, command: string[], options: KubernetesExecOptions): Promise<number>;
|
|
52
|
+
/**
|
|
53
|
+
* The API server's reported version (`gitVersion`, e.g. `v1.33.4-gke.1000`). Read-only and
|
|
54
|
+
* cluster-wide; used by src/tools/capture-fixture.ts to stamp a capture with the server that
|
|
55
|
+
* produced it, so a fixture cannot claim provenance it never recorded.
|
|
56
|
+
*/
|
|
57
|
+
readApiServerVersion(): Promise<string>;
|
|
58
|
+
/** Reads at most `limitBytes` of the last `tailLines` lines of a container's log. */
|
|
59
|
+
readLogTail(namespace: string, pod: string, container: string, tailLines: number, limitBytes: number): Promise<string>;
|
|
60
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class KubernetesNotFoundError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "KubernetesNotFoundError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/** Stale resourceVersion on replace. */
|
|
8
|
+
export class KubernetesConflictError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "KubernetesConflictError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Create of an existing name. */
|
|
15
|
+
export class KubernetesAlreadyExistsError extends Error {
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = "KubernetesAlreadyExistsError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KubernetesApi over @kubernetes/client-node 2.x. A thin mapping: each seam
|
|
3
|
+
* method is one client call plus HTTP-status translation into the seam's
|
|
4
|
+
* error classes. Proven against a real cluster by kubernetes.integration.test.ts.
|
|
5
|
+
*/
|
|
6
|
+
import { type V1ConfigMap, type V1Endpoints, type V1NetworkPolicy, type V1Pod, type V1Secret, type V1Service } from "@kubernetes/client-node";
|
|
7
|
+
import { type KubernetesApi, type KubernetesExecOptions } from "./kubernetes-api.js";
|
|
8
|
+
export interface ClientNodeKubernetesApiOptions {
|
|
9
|
+
/** kubeconfig context to use; defaults to the current context (or in-cluster credentials). */
|
|
10
|
+
context?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class ClientNodeKubernetesApi implements KubernetesApi {
|
|
13
|
+
private readonly config;
|
|
14
|
+
private readonly core;
|
|
15
|
+
private readonly networking;
|
|
16
|
+
private readonly version;
|
|
17
|
+
constructor(options?: ClientNodeKubernetesApiOptions);
|
|
18
|
+
createConfigMap(namespace: string, body: V1ConfigMap): Promise<V1ConfigMap>;
|
|
19
|
+
readConfigMap(namespace: string, name: string): Promise<V1ConfigMap | undefined>;
|
|
20
|
+
replaceConfigMap(namespace: string, name: string, body: V1ConfigMap): Promise<V1ConfigMap>;
|
|
21
|
+
createSecret(namespace: string, body: V1Secret): Promise<V1Secret>;
|
|
22
|
+
deleteSecret(namespace: string, name: string): Promise<void>;
|
|
23
|
+
createPod(namespace: string, body: V1Pod): Promise<V1Pod>;
|
|
24
|
+
dryRunCreatePod(namespace: string, body: V1Pod): Promise<V1Pod>;
|
|
25
|
+
readPod(namespace: string, name: string): Promise<V1Pod | undefined>;
|
|
26
|
+
deletePod(namespace: string, name: string, gracePeriodSeconds: number): Promise<void>;
|
|
27
|
+
createNetworkPolicy(namespace: string, body: V1NetworkPolicy): Promise<V1NetworkPolicy>;
|
|
28
|
+
readNetworkPolicy(namespace: string, name: string): Promise<V1NetworkPolicy | undefined>;
|
|
29
|
+
deleteNetworkPolicy(namespace: string, name: string): Promise<void>;
|
|
30
|
+
readService(namespace: string, name: string): Promise<V1Service | undefined>;
|
|
31
|
+
readEndpoints(namespace: string, name: string): Promise<V1Endpoints | undefined>;
|
|
32
|
+
readApiServerVersion(): Promise<string>;
|
|
33
|
+
readNamespace(name: string): Promise<boolean>;
|
|
34
|
+
exec(namespace: string, pod: string, container: string, command: string[], options: KubernetesExecOptions): Promise<number>;
|
|
35
|
+
readLogTail(namespace: string, pod: string, container: string, tailLines: number, limitBytes: number): Promise<string>;
|
|
36
|
+
}
|