@vibesdotdev/infra-doks 0.0.1

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.
Files changed (113) hide show
  1. package/README.md +107 -0
  2. package/SPEC.md +285 -0
  3. package/dist/client/digitalocean-app-deploy.client.d.ts +46 -0
  4. package/dist/client/digitalocean-app-deploy.client.d.ts.map +1 -0
  5. package/dist/client/digitalocean-app-deploy.client.js +135 -0
  6. package/dist/client/digitalocean-app-deploy.client.js.map +1 -0
  7. package/dist/client/index.d.ts +15 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +18 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/cloud/base.d.ts +33 -0
  12. package/dist/cloud/base.d.ts.map +1 -0
  13. package/dist/cloud/base.js +86 -0
  14. package/dist/cloud/base.js.map +1 -0
  15. package/dist/cloud/digitalocean.d.ts +33 -0
  16. package/dist/cloud/digitalocean.d.ts.map +1 -0
  17. package/dist/cloud/digitalocean.js +258 -0
  18. package/dist/cloud/digitalocean.js.map +1 -0
  19. package/dist/cloud/factory.d.ts +28 -0
  20. package/dist/cloud/factory.d.ts.map +1 -0
  21. package/dist/cloud/factory.js +151 -0
  22. package/dist/cloud/factory.js.map +1 -0
  23. package/dist/cloud/index.d.ts +12 -0
  24. package/dist/cloud/index.d.ts.map +1 -0
  25. package/dist/cloud/index.js +11 -0
  26. package/dist/cloud/index.js.map +1 -0
  27. package/dist/doks.plugin.d.ts +41 -0
  28. package/dist/doks.plugin.d.ts.map +1 -0
  29. package/dist/doks.plugin.js +287 -0
  30. package/dist/doks.plugin.js.map +1 -0
  31. package/dist/implementations/deployment.impl.d.ts +34 -0
  32. package/dist/implementations/deployment.impl.d.ts.map +1 -0
  33. package/dist/implementations/deployment.impl.js +86 -0
  34. package/dist/implementations/deployment.impl.js.map +1 -0
  35. package/dist/implementations/droplet.impl.d.ts +85 -0
  36. package/dist/implementations/droplet.impl.d.ts.map +1 -0
  37. package/dist/implementations/droplet.impl.js +113 -0
  38. package/dist/implementations/droplet.impl.js.map +1 -0
  39. package/dist/implementations/gitea.impl.d.ts +68 -0
  40. package/dist/implementations/gitea.impl.d.ts.map +1 -0
  41. package/dist/implementations/gitea.impl.js +295 -0
  42. package/dist/implementations/gitea.impl.js.map +1 -0
  43. package/dist/implementations/managed-db.impl.d.ts +25 -0
  44. package/dist/implementations/managed-db.impl.d.ts.map +1 -0
  45. package/dist/implementations/managed-db.impl.js +31 -0
  46. package/dist/implementations/managed-db.impl.js.map +1 -0
  47. package/dist/implementations/managed-redis.impl.d.ts +37 -0
  48. package/dist/implementations/managed-redis.impl.d.ts.map +1 -0
  49. package/dist/implementations/managed-redis.impl.js +40 -0
  50. package/dist/implementations/managed-redis.impl.js.map +1 -0
  51. package/dist/implementations/spaces.impl.d.ts +36 -0
  52. package/dist/implementations/spaces.impl.d.ts.map +1 -0
  53. package/dist/implementations/spaces.impl.js +40 -0
  54. package/dist/implementations/spaces.impl.js.map +1 -0
  55. package/dist/implementations/statefulset.impl.d.ts +65 -0
  56. package/dist/implementations/statefulset.impl.d.ts.map +1 -0
  57. package/dist/implementations/statefulset.impl.js +165 -0
  58. package/dist/implementations/statefulset.impl.js.map +1 -0
  59. package/dist/implementations/verdaccio.impl.d.ts +65 -0
  60. package/dist/implementations/verdaccio.impl.d.ts.map +1 -0
  61. package/dist/implementations/verdaccio.impl.js +259 -0
  62. package/dist/implementations/verdaccio.impl.js.map +1 -0
  63. package/dist/index.d.ts +15 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +19 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/kubernetes/index.d.ts +95 -0
  68. package/dist/kubernetes/index.d.ts.map +1 -0
  69. package/dist/kubernetes/index.js +625 -0
  70. package/dist/kubernetes/index.js.map +1 -0
  71. package/dist/secrets/index.d.ts +4 -0
  72. package/dist/secrets/index.d.ts.map +1 -0
  73. package/dist/secrets/index.js +4 -0
  74. package/dist/secrets/index.js.map +1 -0
  75. package/dist/secrets/vault.descriptor.d.ts +10 -0
  76. package/dist/secrets/vault.descriptor.d.ts.map +1 -0
  77. package/dist/secrets/vault.descriptor.js +25 -0
  78. package/dist/secrets/vault.descriptor.js.map +1 -0
  79. package/dist/secrets/vault.impl.cloud.d.ts +40 -0
  80. package/dist/secrets/vault.impl.cloud.d.ts.map +1 -0
  81. package/dist/secrets/vault.impl.cloud.js +178 -0
  82. package/dist/secrets/vault.impl.cloud.js.map +1 -0
  83. package/dist/secrets/vault.impl.d.ts +29 -0
  84. package/dist/secrets/vault.impl.d.ts.map +1 -0
  85. package/dist/secrets/vault.impl.js +137 -0
  86. package/dist/secrets/vault.impl.js.map +1 -0
  87. package/dist/types.d.ts +509 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +47 -0
  90. package/dist/types.js.map +1 -0
  91. package/package.json +145 -0
  92. package/src/client/digitalocean-app-deploy.client.ts +226 -0
  93. package/src/client/index.ts +24 -0
  94. package/src/cloud/base.ts +149 -0
  95. package/src/cloud/digitalocean.ts +363 -0
  96. package/src/cloud/factory.ts +190 -0
  97. package/src/cloud/index.ts +81 -0
  98. package/src/doks.plugin.ts +401 -0
  99. package/src/implementations/deployment.impl.ts +93 -0
  100. package/src/implementations/droplet.impl.ts +157 -0
  101. package/src/implementations/gitea.impl.ts +319 -0
  102. package/src/implementations/managed-db.impl.ts +37 -0
  103. package/src/implementations/managed-redis.impl.ts +49 -0
  104. package/src/implementations/spaces.impl.ts +52 -0
  105. package/src/implementations/statefulset.impl.ts +186 -0
  106. package/src/implementations/verdaccio.impl.ts +300 -0
  107. package/src/index.ts +136 -0
  108. package/src/kubernetes/index.ts +754 -0
  109. package/src/secrets/index.ts +9 -0
  110. package/src/secrets/vault.descriptor.ts +28 -0
  111. package/src/secrets/vault.impl.cloud.ts +278 -0
  112. package/src/secrets/vault.impl.ts +149 -0
  113. package/src/types.ts +563 -0
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # @vibesdotdev/infra-doks
2
+
3
+ DigitalOcean / DOKS adapter for Vibes runtime kinds. Supplies the
4
+ DigitalOcean / DOKS-flavored descriptor + implementation pairs the
5
+ runtime selects when scope resolves to a DO/cluster target.
6
+
7
+ The contract lives in [SPEC.md](./SPEC.md). This README is usage notes.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ bun add @vibesdotdev/infra-doks
13
+ ```
14
+
15
+ Workspace-internal — declared as `"@vibesdotdev/infra-doks": "workspace:*"`.
16
+
17
+ ## Plugin
18
+
19
+ ```ts
20
+ import doksPlugin from '@vibesdotdev/infra-doks/plugin';
21
+ import { createRuntime } from '@vibesdotdev/runtime';
22
+ import infraPlugin from '@vibesdotdev/infra-core/plugin';
23
+
24
+ const runtime = createRuntime();
25
+ await runtime.use(infraPlugin);
26
+ await runtime.use(doksPlugin);
27
+ ```
28
+
29
+ `doksPlugin` depends on the `infra` plugin from `infra-core`. Activate
30
+ `infra-core` first so the kinds are registered before `doksPlugin` adds
31
+ its loaders.
32
+
33
+ ## What's wired today
34
+
35
+ Only the `secrets/store` Vault pair. After bootstrap, the runtime can
36
+ resolve a HashiCorp Vault-backed `secrets/store` for environments
37
+ running inside a Kubernetes cluster:
38
+
39
+ ```ts
40
+ import { getVibesSecretsClient } from '@vibesdotdev/secrets/runtime/client';
41
+
42
+ const secrets = await getVibesSecretsClient();
43
+ const dbPassword = await secrets.get('staging', 'POSTGRES_PASSWORD');
44
+ ```
45
+
46
+ The Vault descriptor is `hardware: ['cloud']` only. It will not match on
47
+ consumer hardware. Auth uses (in order) descriptor `token`, the
48
+ `VAULT_TOKEN` env var, then exchanges the in-pod K8s service-account JWT
49
+ at `/var/run/secrets/kubernetes.io/serviceaccount/token` for a Vault
50
+ token via `/v1/auth/kubernetes/login`. All three failing throws.
51
+
52
+ Vault KV path layout matches the deployment Helm chart's secret groups:
53
+ `{mount}/app`, `{mount}/oauth`, `{mount}/artifacts`,
54
+ `{mount}/infrastructure`. New keys default to the `app` group.
55
+
56
+ ## What's not wired (migration debt)
57
+
58
+ The K8s and DO managed-service generators are exported but not
59
+ registered against `infra/*` kinds yet. They are usable as standalone
60
+ functions, but consuming them this way bypasses the runtime selection
61
+ flow:
62
+
63
+ ```ts
64
+ import { generateK8sDeployment } from '@vibesdotdev/infra-doks';
65
+
66
+ const manifest = generateK8sDeployment(workerDescriptor);
67
+ ```
68
+
69
+ See [SPEC.md](./SPEC.md) → **Migration debt** for the path to wiring
70
+ these as descriptor + impl pairs (mirroring the
71
+ [`infra-cloudflare`](../infra-cloudflare) plugin layout).
72
+
73
+ ## Vault tier mapping
74
+
75
+ The descriptor's `config.mount` is the default. At resolution time the
76
+ impl picks a mount per environment:
77
+
78
+ | `environment` | Vault mount |
79
+ | ------------- | ------------------- |
80
+ | `staging` | `staging` |
81
+ | `production` | `production` |
82
+ | anything else | `config.mount` (default `staging`) |
83
+
84
+ Override the default address or mount via the descriptor's `config`
85
+ record (string-valued, per the `secrets/store` schema).
86
+
87
+ ## Tests
88
+
89
+ ```sh
90
+ bun test packages/infra-doks
91
+ ```
92
+
93
+ Covers plugin shape and deterministic generator output. No live Vault,
94
+ Kubernetes, or DigitalOcean API access is exercised.
95
+
96
+ Type gate:
97
+
98
+ ```sh
99
+ bun --bun tsc -p packages/infra-doks/tsconfig.json --noEmit
100
+ ```
101
+
102
+ ## Related
103
+
104
+ - [`infra-core`](../infra-core) — kinds and base schemas.
105
+ - [`infra-cloudflare`](../infra-cloudflare) — sibling Cloudflare adapter.
106
+ - [`secrets`](../secrets) — `secrets/store` kind, interface, default impl.
107
+ - [`deploy`](../deploy) — orchestration that consumes the manifests.
package/SPEC.md ADDED
@@ -0,0 +1,285 @@
1
+ # @vibesdotdev/infra-doks
2
+
3
+ DigitalOcean / DOKS adapter for runtime kinds defined elsewhere: `infra/*`
4
+ from [`infra-core`](../infra-core/SPEC.md) and `secrets/store` from
5
+ [`secrets`](../secrets/SPEC.md). Each kind defines a base descriptor
6
+ schema, an implementation interface, and a pass-through default impl in
7
+ its owning package; this package supplies the DigitalOcean / DOKS
8
+ **descriptor + impl** pair the runtime selects when scope resolves to a
9
+ DO/cluster target. The canonical adapter pattern lives in
10
+ [`infra-cloudflare`](../infra-cloudflare/SPEC.md) — same plugin shape,
11
+ same `createRuntimeImplementation` bridge, same per-impl descriptor
12
+ schemas alongside the generators. Every adapter pair owned here is REGISTERED with the runtime via
13
+ `runtime.registerLoader` in `onActivate` (`vault`, `doks-deployment`,
14
+ `doks-statefulset` for queue and database, `do-managed-postgres`,
15
+ `do-managed-redis`, `do-spaces`, `gitea-doks`, `verdaccio-doks`, plus the
16
+ `digitalocean-droplet` sandbox). Whether each registration is reached by
17
+ an in-repo consumer is a separate question — see "Consumers" below.
18
+ Today the registered set splits roughly in half: `vault`,
19
+ `digitalocean-droplet`, `gitea-doks`, and `verdaccio-doks` have live
20
+ consumers; the rest are registered-only (and `infra/generate.ts` even
21
+ inlines a parallel shape for `doks-deployment` and `do-spaces` that
22
+ drifts from this package's generator).
23
+
24
+ ## Owns
25
+
26
+ - **Plugin descriptor:** `doksPlugin` (id `infra-doks`, depends on `infra`).
27
+ In `onActivate`, lazy-registers each pair via `runtime.registerLoader`.
28
+ Implementations are `await import()`-ed inside the loader, never at
29
+ module load.
30
+ - **`secrets/store` `vault` descriptor + impl** (`./secrets`). Descriptor in `vault.descriptor.ts`
31
+ (`backend: 'vault'`, `hardware: ['cloud']`,
32
+ `tiers: ['staging', 'production']`, default address
33
+ `http://vault.observability.svc.cluster.local:8200`, K8s auth method).
34
+ Impl in `vault.impl.ts` is a `SecretsStoreImplementation` walking the
35
+ fixed Vault KV v2 path groups `app`/`oauth`/`artifacts`/
36
+ `infrastructure`, defaulting new keys to `app`. HTTP client in
37
+ `vault.client.ts` (K8s service-account token exchange against
38
+ `/v1/auth/kubernetes/login`). Priority 30. `createVaultStore` wraps
39
+ the store in `createRuntimeImplementation`.
40
+ - **`infra/worker` `doks-deployment` descriptor + impl** (`./implementations/deployment`).
41
+ Adapter descriptor schema `DoksDeploymentDescriptorSchema` co-located with
42
+ `generateK8sDeployment` generator. Implementation produces a K8s
43
+ Deployment manifest. Priority 20.
44
+ - **`infra/queue` `doks-statefulset` descriptor + impl** (`./implementations/statefulset`).
45
+ Adapter descriptor schema `DoksQueueDescriptorSchema` co-located with
46
+ `generateK8sStatefulSet` generator for Kafka/Redpanda. Implementation
47
+ produces a K8s StatefulSet manifest. Priority 20.
48
+ - **`infra/database` `doks-statefulset` descriptor + impl** (`./implementations/statefulset`).
49
+ Adapter descriptor schema `DoksDatabaseDescriptorSchema` co-located with
50
+ `generateK8sStatefulSet` generator for self-hosted Postgres. Implementation
51
+ produces a K8s StatefulSet manifest. Priority 20.
52
+ - **`infra/database` `do-managed-postgres` descriptor + impl** (`./implementations/managed-db`).
53
+ Adapter descriptor schema `DOManagedPostgresDescriptorSchema` co-located with
54
+ `generateDOManagedDB` generator. Implementation produces a DO Managed Database
55
+ API spec. Priority 30 (higher than StatefulSet so managed is preferred when adapter
56
+ matches).
57
+ - **`infra/cache` `do-managed-redis` descriptor + impl** (`./implementations/managed-redis`).
58
+ Adapter descriptor schema `DOManagedRedisDescriptorSchema` co-located with
59
+ `generateDOManagedRedis` generator. Implementation produces a DO Managed Redis
60
+ API spec. Priority 20.
61
+ - **`infra/object-storage` `do-spaces` descriptor + impl** (`./implementations/spaces`).
62
+ Adapter descriptor schema `DOSpacesDescriptorSchema` co-located with
63
+ `generateDOSpaces` generator. Implementation produces a DO Spaces API spec.
64
+ Priority 20.
65
+ - **`infra/git-hosting` `gitea-doks` descriptor + impl** (`./implementations/gitea.impl`).
66
+ Adapter descriptor schema `GiteaDoksDescriptorSchema` co-located with
67
+ `generateGiteaManifest` generator. Implementation produces K8s
68
+ Deployment + Service + PersistentVolumeClaim + Ingress manifests for Gitea.
69
+ Priority 20.
70
+ - **`infra/package-registry` `verdaccio-doks` descriptor + impl** (`./implementations/verdaccio.impl`).
71
+ Adapter descriptor schema `VerdaccioDoksDescriptorSchema` co-located with
72
+ `generateVerdaccioManifest` generator. Implementation produces K8s
73
+ Deployment + Service + PersistentVolumeClaim + ConfigMap + Ingress manifests
74
+ for Verdaccio. Priority 20.
75
+ - **`infra/sandbox` `digitalocean-droplet` descriptor + impl**
76
+ (`./implementations/droplet`). Implements the `digitalocean-droplet`
77
+ variant of `infra/sandbox` whose schema already lives in
78
+ [`infra-core`](../infra-core/SPEC.md). Wires the existing
79
+ `DigitalOceanProvider` (`./cloud/digitalocean.ts`) into the runtime
80
+ kind resolution path: creates the droplet via DO `/v2/droplets`,
81
+ waits for `status: 'active'`, returns
82
+ `{ instanceId, publicIp, privateIp, region, createdAt }`. Optional
83
+ `cloudInitScript` is forwarded as `user_data`. Priority 20.
84
+ - **Manifest output types** (`./types`): K8s API subset (`K8sDeployment`,
85
+ `K8sStatefulSet`, `K8sService`, `K8sConfigMap`, `K8sSecret`,
86
+ `K8sContainer`, `K8sPodSpec`, `K8sPodTemplateSpec`, `K8sProbe`,
87
+ `K8sResourceRequirements`, `K8sLabelSelector`, `K8sVolumeClaimTemplate`)
88
+ and DO managed-service spec shapes (`DOManagedDBSpec`,
89
+ `DOManagedRedisSpec`, `DOSpacesSpec`).
90
+ - **Manifest generator functions** (`./implementations`): pure functions
91
+ `generateK8sDeployment`, `generateK8sStatefulSet`,
92
+ `generateDOManagedDB`, `generateDOManagedRedis`, `generateDOSpaces`,
93
+ `generateGiteaManifest`, `generateVerdaccioManifest`.
94
+ Each takes an adapter-specific descriptor and returns a manifest object,
95
+ namespace `vibes`, name `vibes-{descriptor.id}`.
96
+ - **`runtime/client` `digitalocean-app-deploy` descriptor + impl**
97
+ (`./client`). `DigitalOceanAppDeployClient extends BaseRuntimeClient`
98
+ exposes `deployApp(options): Promise<DeployAppResult>` — translates an
99
+ `AppDeployment` to a DO App spec and POSTs `/apps` (create) or PUTs
100
+ `/apps/{id}` (update) via the v2 REST API. Consumed by
101
+ [`infra-deploy`](../infra-deploy/SPEC.md)'s CLI run handler through the
102
+ published `getDigitalOceanAppDeployClient()` helper. Reads
103
+ `DIGITALOCEAN_API_TOKEN` from the operator's env (secrets-manager
104
+ brokerage tracked in `infra-deploy/SPEC.md` migration debt).
105
+
106
+ ## Does not own
107
+
108
+ - Infra runtime kinds and their base descriptor schemas →
109
+ [`infra-core`](../infra-core/SPEC.md).
110
+ - `secrets/store` kind, `SecretsStoreImplementation` interface, default
111
+ in-process impl, and env-requirement resolution →
112
+ [`secrets`](../secrets/SPEC.md).
113
+ - Cloudflare descriptor + impl pairs (Workers / Queues / R2 / KV /
114
+ cloudflare-api `secrets/store`) →
115
+ [`infra-cloudflare`](../infra-cloudflare/SPEC.md).
116
+ - `kubectl apply`, deployment orchestration, env materialization, and the
117
+ `infra/` workspace tree → [`infra-deploy`](../infra-deploy/SPEC.md).
118
+ - DigitalOcean API clients that actually create Managed DB / Redis /
119
+ Spaces resources. Generators here produce request-shaped specs only;
120
+ the only DO API client surface in this package is the
121
+ `DigitalOceanAppDeployClient` (App Platform deploys) and the existing
122
+ `DigitalOceanProvider` (droplets, volumes, VPCs) — both behind the
123
+ runtime kind resolution path, not via direct import.
124
+
125
+ ## Hard rules
126
+
127
+ - The plugin registers every implementation through
128
+ `runtime.registerLoader` in `onActivate`. Do not import
129
+ implementations at module load — Vault auth touches Node FS and the
130
+ network and must not run on `import`.
131
+ - Adapter packages provide descriptor + impl pairs for kinds defined
132
+ elsewhere. Defining a new kind here is a layering violation — add it
133
+ to its owning package (`infra-core`, `secrets`, …) first.
134
+ - The descriptor + impl unit follows infra-cloudflare's shape: each
135
+ `*.impl.ts` co-locates the adapter descriptor schema (extending the
136
+ base kind with adapter-specific fields), the generator, and the output
137
+ type; the plugin file holds the `create*Impl(input)` factory that
138
+ parses the descriptor and wraps the generator in
139
+ `createRuntimeImplementation`; `onActivate` calls `registerLoader` for
140
+ each pair. Do not split these layers across additional files.
141
+ - Each kind's implementation interface is defined in its owning package.
142
+ `secrets/store` requires the full `SecretsStoreImplementation` CRUD
143
+ interface; `infra/*` kinds expect `{ generateConfig: () => …Manifest }`
144
+ per the cloudflare precedent. Adapters fulfill the kind's interface
145
+ exactly; do not invent a parallel interface.
146
+ - Vault auth precedence: descriptor `token`, then `VAULT_TOKEN` env,
147
+ then exchange the K8s service-account JWT at
148
+ `/var/run/secrets/kubernetes.io/serviceaccount/token` for a Vault
149
+ token. Failing all three throws — never silently fall through.
150
+ - The `digitalocean-droplet` impl is the only path through which
151
+ `DigitalOceanProvider` (`./cloud/digitalocean.ts`) is reachable from
152
+ the runtime. Direct imports of `./cloud/digitalocean.ts` from
153
+ feature packages are layering violations; that class moves from
154
+ orphan to runtime-bound on this landing.
155
+ - Droplet creation is idempotent against the descriptor `id`: a second
156
+ call with the same id returns the existing droplet rather than
157
+ creating a duplicate. Tag droplets with `vibes:resourceId=<id>` to
158
+ make the lookup cheap.
159
+ - DO API token resolution: descriptor override →
160
+ `DIGITALOCEAN_API_TOKEN` env → `packages/secrets`
161
+ `cloud-credentials.digitalocean.token` once brokerage lands. Same
162
+ precedence the rest of this package uses.
163
+ - The Vault descriptor is `hardware: ['cloud']` only. It must not
164
+ register on consumer hardware; the in-cluster Vault address is
165
+ unreachable elsewhere.
166
+ - Manifest generators are pure: descriptor in, plain object out, no
167
+ I/O, no side effects. Probes, resource requests/limits, namespace
168
+ `vibes`, and the `vibes-{descriptor.id}` naming convention are part
169
+ of the contract — change them only with a deploy-side coordinated
170
+ update.
171
+ - Vault KV path groups (`app`, `oauth`, `artifacts`, `infrastructure`)
172
+ match the deployment Helm chart's secret groups. Adding a new group
173
+ requires updating this list and the chart in lockstep.
174
+ - Manifest generators are config transforms and stay pure; the only
175
+ runtime-bound clients that perform I/O are the `runtime/client`
176
+ `digitalocean-app-deploy` (App Platform deploys) and the existing
177
+ `digitalocean-droplet` `infra/sandbox` impl (droplets). Adding another
178
+ cloud-API surface means adding a new `runtime/client` or kind impl —
179
+ never a top-level export bypassing the runtime.
180
+ - The `digitalocean-app-deploy` client reads `DIGITALOCEAN_API_TOKEN`
181
+ from process env today (matches the `digitalocean-droplet` impl
182
+ precedence). End-state: resolve `cloud-credentials.digitalocean.token`
183
+ via `packages/secrets` per actor scope.
184
+
185
+ ## Consumers
186
+
187
+ Status of each impl pair's consumption path:
188
+
189
+ - **`secrets/store` → `vault`**: consumed by `infra/vault-setup.ts` via Vault HTTP
190
+ client; production-wired.
191
+ - **`infra/sandbox` → `digitalocean-droplet`**: consumed by
192
+ `packages/runner-adapter-digitalocean` (GPU on-demand inference). Required at
193
+ runtime — removing this loader breaks GPU runner activation.
194
+ - **`runtime/client` → `digitalocean-app-deploy`**: consumed by
195
+ [`infra-deploy`](../infra-deploy/SPEC.md) via
196
+ `getDigitalOceanAppDeployClient()` in
197
+ `packages/infra-deploy/src/cli/run/infra-deploy.run.cli-command.impl.ts`.
198
+ Required for `vibes infra deploy run` against DO App Platform apps.
199
+ - **`infra/git-hosting` → `gitea-doks`** and
200
+ **`infra/package-registry` → `verdaccio-doks`**: consumed by `infra/generate.ts`
201
+ via direct `generateGiteaManifest` / `generateVerdaccioManifest` imports
202
+ (not via the runtime resolver). Active in DOKS apply phase.
203
+ - **`infra/worker` → `doks-deployment`**, **`infra/queue` → `doks-statefulset`**,
204
+ **`infra/database` → `doks-statefulset` / `do-managed-postgres`**,
205
+ **`infra/cache` → `do-managed-redis`**, **`infra/object-storage` → `do-spaces`**:
206
+ registered with the runtime but no in-repo consumer resolves them yet.
207
+ `infra/generate.ts` inlines its own K8s Deployment YAML for the
208
+ `doks-deployment` workers (`ai-workers`, `crawl-workers`, `workbench-workers`)
209
+ with a DIFFERENT shape than `generateK8sDeployment` (different image prefix
210
+ `ghcr.io/vibes-dev` vs. `vibes/`, inline `env[]` vs. `envFrom: configMapRef`,
211
+ includes `HorizontalPodAutoscaler`). The infra-doks generator is the
212
+ canonical target shape; `infra/generate.ts` is the current production shape.
213
+ Consolidation needs a deploy-side coordinated test pass (apply against a
214
+ DOKS cluster, diff manifests) — tracked as migration debt below.
215
+
216
+ ## Migration debt
217
+
218
+ - [ ] **`infra/generate.ts` doks-deployment / do-spaces inlining drift.**
219
+ `infra/generate.ts` inlines K8s Deployment + HPA YAML and DO Spaces JSON
220
+ rather than routing through `generateK8sDeployment` / `generateDOSpaces`.
221
+ Reconciling requires aligning the infra-doks generators with the inline
222
+ shapes (add HPA support, default image prefix `ghcr.io/vibes-dev`, allow
223
+ inline env + secret env) and running an apply-dry-run diff against the
224
+ current `infra/generated/k8s-*-workers.yaml` files before flipping over.
225
+
226
+ - [ ] **`infra/git-hosting` and `infra/package-registry` impl pairs are new.**
227
+ `gitea.impl.ts` and `verdaccio.impl.ts` register `gitea-doks` and `verdaccio-doks`
228
+ loaders for the new kinds. Both implementations follow the existing impl pattern.
229
+ Full validation: `createRuntimeAsset` calls must validate `config` against the
230
+ kind's registered `descriptorSchema` once the runtime `config` field migration
231
+ in `runtime` is complete.
232
+
233
+ - [x] **Five DOKS/DO descriptor + impl pairs are unbuilt.** The generators
234
+ exist, but each impl file was missing its adapter descriptor schema,
235
+ the plugin was missing its `create*Impl(input)` factory, and
236
+ `onActivate` was missing the matching `registerLoader` call.
237
+ **Resolution:** Mirrored `infra-cloudflare` exactly:
238
+ - `infra/worker` ← `generateK8sDeployment` via `doks-deployment` loader (priority 20)
239
+ - `infra/queue` ← `generateK8sStatefulSet` via `doks-statefulset` loader (priority 20)
240
+ - `infra/database` ← `generateK8sStatefulSet` via `doks-statefulset` loader (priority 20)
241
+ and `generateDOManagedDB` via `do-managed-postgres` loader (priority 30)
242
+ - `infra/cache` ← `generateDOManagedRedis` via `do-managed-redis` loader (priority 20)
243
+ - `infra/object-storage` ← `generateDOSpaces` via `do-spaces` loader (priority 20)
244
+ Each implementation follows the `{ generateConfig: () => Manifest }` shape
245
+ per the cloudflare precedent.
246
+ - [x] **`package.json#exports` wildcard cleanup.**
247
+ **Resolution:** Replaced `"./implementations/*": "./src/implementations/*"` with
248
+ explicit per-impl subpaths:
249
+ - `./implementations/deployment`
250
+ - `./implementations/statefulset`
251
+ - `./implementations/managed-db`
252
+ - `./implementations/managed-redis`
253
+ - `./implementations/spaces`
254
+ Grep found no in-repo consumer of the wildcard.
255
+ - [x] **`infra-core`'s `deploymentProviderSchema` enum coordination.**
256
+ **Resolution:** This is already cross-recorded in [`infra-core`](../infra-core/SPEC.md)
257
+ migration debt. The `infra-doks` package provides the implementations; the enum
258
+ trim in `infra-core` is a separate action item tracked there.
259
+
260
+ ## Public entrypoints
261
+
262
+ `.`, `./plugin`, `./implementations/deployment`, `./implementations/statefulset`,
263
+ `./implementations/managed-db`, `./implementations/managed-redis`,
264
+ `./implementations/spaces`, `./implementations/gitea`, `./implementations/verdaccio`,
265
+ `./secrets`, `./cloud`, `./kubernetes`, `./types`, `./client`.
266
+
267
+ Wildcard / migration-era subpaths: None — the explicit per-impl subpaths above
268
+ replace the former `./implementations/*` wildcard.
269
+
270
+ ## Verification
271
+
272
+ `bun test` from `packages/infra-doks`. Covers plugin shape (`id`,
273
+ `dependencies`, `name`) and deterministic-output tests for each of
274
+ `deployment.impl`, `statefulset.impl`, `managed-db.impl`,
275
+ `managed-redis.impl`, `spaces.impl`. No live Vault, Kubernetes API, or
276
+ DigitalOcean API contact is exercised; those are deploy-time gates.
277
+ Type gate is `bun --bun tsc -p tsconfig.json --noEmit`.
278
+
279
+ ## Links
280
+
281
+ - [infra-core/SPEC.md](../infra-core/SPEC.md)
282
+ - [infra-cloudflare/SPEC.md](../infra-cloudflare/SPEC.md)
283
+ - [secrets/SPEC.md](../secrets/SPEC.md)
284
+ - [runtime/SPEC.md](../runtime/SPEC.md)
285
+ - [infra-deploy/SPEC.md](../infra-deploy/SPEC.md)
@@ -0,0 +1,46 @@
1
+ /**
2
+ * DigitalOcean App Platform Deploy Client
3
+ *
4
+ * Canonical `runtime/client` (id `digitalocean-app-deploy`) for creating or
5
+ * updating an App Platform application from an `AppDeployment` manifest.
6
+ * Uses the DigitalOcean REST API v2 directly (no `doctl` dependency).
7
+ *
8
+ * Consumers resolve via `getDigitalOceanAppDeployClient()` (preferred)
9
+ * or `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
10
+ *
11
+ * For the initial deploy, the DO App needs a source reference. The common case
12
+ * is a git repo reference — the CLI writes the app spec; the operator connects
13
+ * the git repo in the DO dashboard once. Subsequent calls update the spec.
14
+ *
15
+ * Credentials: reads `DIGITALOCEAN_API_TOKEN` from the operator's environment.
16
+ * (Secrets-manager integration is tracked in `infra-deploy/SPEC.md` Migration
17
+ * debt — once landed, this client will resolve the token via secrets/store.)
18
+ */
19
+ import type { VibesRuntime } from '@vibesdotdev/runtime';
20
+ import { BaseRuntimeClient, type RuntimeClientDescriptor } from '@vibesdotdev/runtime-client';
21
+ import type { AppDeployment } from '@vibesdotdev/infra-core/deployment';
22
+ export interface DeployAppOptions {
23
+ deployment: AppDeployment;
24
+ /** Existing DO App id (for updates). Omit to create a new App. */
25
+ appId?: string;
26
+ /** Region slug, e.g. 'nyc', 'sfo3', 'ams'. */
27
+ region?: string;
28
+ /** Git repo reference for the app source (github/gitlab). */
29
+ git?: {
30
+ repoCloneUrl?: string;
31
+ branch?: string;
32
+ };
33
+ /** Environment name for DO (e.g. 'production'). */
34
+ environmentName?: string;
35
+ dryRun?: boolean;
36
+ onLine?: (stream: 'stdout' | 'stderr', line: string) => void;
37
+ }
38
+ export interface DeployAppResult {
39
+ appId: string;
40
+ liveUrl?: string;
41
+ }
42
+ export declare class DigitalOceanAppDeployClient extends BaseRuntimeClient {
43
+ constructor(descriptor?: RuntimeClientDescriptor, context?: unknown, runtime?: VibesRuntime);
44
+ deployApp(options: DeployAppOptions): Promise<DeployAppResult>;
45
+ }
46
+ //# sourceMappingURL=digitalocean-app-deploy.client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digitalocean-app-deploy.client.d.ts","sourceRoot":"","sources":["../../src/client/digitalocean-app-deploy.client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACN,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAIxE,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,aAAa,CAAC;IAC1B,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,GAAG,CAAC,EAAE;QACL,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAiID,qBAAa,2BAA4B,SAAQ,iBAAiB;gBAEhE,UAAU,GAAE,uBAGX,EACD,OAAO,CAAC,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,YAAY;IAKjB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAmCpE"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * DigitalOcean App Platform Deploy Client
3
+ *
4
+ * Canonical `runtime/client` (id `digitalocean-app-deploy`) for creating or
5
+ * updating an App Platform application from an `AppDeployment` manifest.
6
+ * Uses the DigitalOcean REST API v2 directly (no `doctl` dependency).
7
+ *
8
+ * Consumers resolve via `getDigitalOceanAppDeployClient()` (preferred)
9
+ * or `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
10
+ *
11
+ * For the initial deploy, the DO App needs a source reference. The common case
12
+ * is a git repo reference — the CLI writes the app spec; the operator connects
13
+ * the git repo in the DO dashboard once. Subsequent calls update the spec.
14
+ *
15
+ * Credentials: reads `DIGITALOCEAN_API_TOKEN` from the operator's environment.
16
+ * (Secrets-manager integration is tracked in `infra-deploy/SPEC.md` Migration
17
+ * debt — once landed, this client will resolve the token via secrets/store.)
18
+ */
19
+ import { getRuntimeEnv } from '@vibesdotdev/runtime';
20
+ import { BaseRuntimeClient } from '@vibesdotdev/runtime-client';
21
+ const DO_API_BASE = 'https://api.digitalocean.com/v2';
22
+ function authHeader() {
23
+ const token = getRuntimeEnv('DIGITALOCEAN_API_TOKEN') ?? '';
24
+ if (!token) {
25
+ throw new Error('DIGITALOCEAN_API_TOKEN is not set. Generate one at https://cloud.digitalocean.com/account/api/tokens and set it in your env.');
26
+ }
27
+ return `Bearer ${token}`;
28
+ }
29
+ async function doFetch(path, init) {
30
+ const response = await fetch(`${DO_API_BASE}${path}`, {
31
+ ...init,
32
+ headers: {
33
+ Authorization: authHeader(),
34
+ 'Content-Type': 'application/json',
35
+ ...(init?.headers ?? {})
36
+ }
37
+ });
38
+ if (!response.ok) {
39
+ const body = await response.text();
40
+ throw new Error(`DO API ${response.status} ${path}: ${body}`);
41
+ }
42
+ if (response.status === 204)
43
+ return undefined;
44
+ return (await response.json());
45
+ }
46
+ function buildAppSpec(deployment, options) {
47
+ const envs = deployment.env
48
+ .filter((requirement) => typeof requirement.value === 'string')
49
+ .map((requirement) => ({
50
+ key: requirement.name,
51
+ value: requirement.value,
52
+ scope: 'RUN_AND_BUILD_TIME',
53
+ type: (requirement.secret ? 'SECRET' : 'GENERAL')
54
+ }));
55
+ const github = {
56
+ repo: options.git?.repoCloneUrl,
57
+ branch: options.git?.branch ?? 'main',
58
+ deploy_on_push: false
59
+ };
60
+ const isStaticRuntime = deployment.runtime === 'browser' || deployment.runtime === 'edge';
61
+ const sourceDir = deployment.build.appDir;
62
+ const outputDir = deployment.build.outputDir;
63
+ if (isStaticRuntime) {
64
+ return {
65
+ name: deployment.appId,
66
+ region: options.region ?? 'nyc',
67
+ static_sites: [
68
+ {
69
+ name: deployment.appId,
70
+ build_command: deployment.build.buildCommand,
71
+ source_dir: sourceDir,
72
+ output_dir: outputDir,
73
+ github: options.git?.repoCloneUrl ? github : undefined,
74
+ envs
75
+ }
76
+ ]
77
+ };
78
+ }
79
+ return {
80
+ name: deployment.appId,
81
+ region: options.region ?? 'nyc',
82
+ services: [
83
+ {
84
+ name: deployment.appId,
85
+ instance_count: 1,
86
+ instance_size_slug: 'apps-s-1vcpu-0.5gb',
87
+ http_port: 3000,
88
+ build_command: deployment.build.buildCommand,
89
+ run_command: 'node build',
90
+ source_dir: sourceDir,
91
+ github: options.git?.repoCloneUrl ? github : undefined,
92
+ envs,
93
+ health_check: { http_path: '/' }
94
+ }
95
+ ]
96
+ };
97
+ }
98
+ export class DigitalOceanAppDeployClient extends BaseRuntimeClient {
99
+ constructor(descriptor = {
100
+ id: 'digitalocean-app-deploy',
101
+ kind: 'runtime/client'
102
+ }, context, runtime) {
103
+ super(descriptor, context, runtime);
104
+ }
105
+ async deployApp(options) {
106
+ const { deployment, onLine } = options;
107
+ const spec = buildAppSpec(deployment, options);
108
+ if (options.dryRun) {
109
+ onLine?.('stdout', `[dry-run] DO App spec for '${deployment.appId}':`);
110
+ onLine?.('stdout', JSON.stringify(spec, null, 2));
111
+ return { appId: options.appId ?? '(new)' };
112
+ }
113
+ if (options.appId) {
114
+ onLine?.('stdout', `Updating DO App ${options.appId}...`);
115
+ const updated = await doFetch(`/apps/${options.appId}`, {
116
+ method: 'PUT',
117
+ body: JSON.stringify({ spec })
118
+ });
119
+ return {
120
+ appId: updated.app.id,
121
+ liveUrl: updated.app.live_url
122
+ };
123
+ }
124
+ onLine?.('stdout', `Creating DO App '${deployment.appId}'...`);
125
+ const created = await doFetch(`/apps`, {
126
+ method: 'POST',
127
+ body: JSON.stringify({ spec })
128
+ });
129
+ return {
130
+ appId: created.app.id,
131
+ liveUrl: created.app.live_url
132
+ };
133
+ }
134
+ }
135
+ //# sourceMappingURL=digitalocean-app-deploy.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digitalocean-app-deploy.client.js","sourceRoot":"","sources":["../../src/client/digitalocean-app-deploy.client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EACN,iBAAiB,EAEjB,MAAM,6BAA6B,CAAC;AAGrC,MAAM,WAAW,GAAG,iCAAiC,CAAC;AAmEtD,SAAS,UAAU;IAClB,MAAM,KAAK,GAAG,aAAa,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACd,8HAA8H,CAC9H,CAAC;IACH,CAAC;IACD,OAAO,UAAU,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,OAAO,CAAI,IAAY,EAAE,IAAkB;IACzD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,GAAG,IAAI,EAAE,EAAE;QACrD,GAAG,IAAI;QACP,OAAO,EAAE;YACR,aAAa,EAAE,UAAU,EAAE;YAC3B,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;SACxB;KACD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,UAAU,QAAQ,CAAC,MAAM,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,SAAc,CAAC;IACnD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,UAAyB,EAAE,OAAyB;IACzE,MAAM,IAAI,GAAgB,UAAU,CAAC,GAAG;SACtC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,OAAO,WAAW,CAAC,KAAK,KAAK,QAAQ,CAAC;SAC9D,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACtB,GAAG,EAAE,WAAW,CAAC,IAAI;QACrB,KAAK,EAAE,WAAW,CAAC,KAAe;QAClC,KAAK,EAAE,oBAA6B;QACpC,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAyB;KACzE,CAAC,CAAC,CAAC;IAEL,MAAM,MAAM,GAAgB;QAC3B,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY;QAC/B,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,IAAI,MAAM;QACrC,cAAc,EAAE,KAAK;KACrB,CAAC;IAEF,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,KAAK,SAAS,IAAI,UAAU,CAAC,OAAO,KAAK,MAAM,CAAC;IAC1F,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;IAC1C,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;IAE7C,IAAI,eAAe,EAAE,CAAC;QACrB,OAAO;YACN,IAAI,EAAE,UAAU,CAAC,KAAK;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YAC/B,YAAY,EAAE;gBACb;oBACC,IAAI,EAAE,UAAU,CAAC,KAAK;oBACtB,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,YAAY;oBAC5C,UAAU,EAAE,SAAS;oBACrB,UAAU,EAAE,SAAS;oBACrB,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;oBACtD,IAAI;iBACJ;aACD;SACD,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,EAAE,UAAU,CAAC,KAAK;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;QAC/B,QAAQ,EAAE;YACT;gBACC,IAAI,EAAE,UAAU,CAAC,KAAK;gBACtB,cAAc,EAAE,CAAC;gBACjB,kBAAkB,EAAE,oBAAoB;gBACxC,SAAS,EAAE,IAAI;gBACf,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,YAAY;gBAC5C,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,SAAS;gBACrB,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBACtD,IAAI;gBACJ,YAAY,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE;aAChC;SACD;KACD,CAAC;AACH,CAAC;AAED,MAAM,OAAO,2BAA4B,SAAQ,iBAAiB;IACjE,YACC,aAAsC;QACrC,EAAE,EAAE,yBAAyB;QAC7B,IAAI,EAAE,gBAAgB;KACtB,EACD,OAAiB,EACjB,OAAsB;QAEtB,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAyB;QACxC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QACvC,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAE/C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,EAAE,CAAC,QAAQ,EAAE,8BAA8B,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC;YACvE,MAAM,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClD,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5C,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,EAAE,CAAC,QAAQ,EAAE,mBAAmB,OAAO,CAAC,KAAK,KAAK,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,MAAM,OAAO,CAC5B,SAAS,OAAO,CAAC,KAAK,EAAE,EACxB;gBACC,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;aAC9B,CACD,CAAC;YACF,OAAO;gBACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;gBACrB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;aAC7B,CAAC;QACH,CAAC;QAED,MAAM,EAAE,CAAC,QAAQ,EAAE,oBAAoB,UAAU,CAAC,KAAK,MAAM,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,MAAM,OAAO,CAA6C,OAAO,EAAE;YAClF,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;SAC9B,CAAC,CAAC;QACH,OAAO;YACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;YACrB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;SAC7B,CAAC;IACH,CAAC;CACD"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Public surface for the infra-doks runtime clients.
3
+ *
4
+ * Consumers resolve the App Platform deploy client via
5
+ * `getDigitalOceanAppDeployClient()` (preferred) or, for type-pinned generic
6
+ * resolution, `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
7
+ *
8
+ * Requires `doksPlugin` to be registered with the runtime so the
9
+ * `runtime/client` descriptor + loader for id `digitalocean-app-deploy` are
10
+ * resolvable.
11
+ */
12
+ import { DigitalOceanAppDeployClient } from './digitalocean-app-deploy.client';
13
+ export { DigitalOceanAppDeployClient, type DeployAppOptions, type DeployAppResult } from './digitalocean-app-deploy.client';
14
+ export declare function getDigitalOceanAppDeployClient(): Promise<DigitalOceanAppDeployClient>;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,EACN,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,MAAM,kCAAkC,CAAC;AAE1C,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAE3F"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Public surface for the infra-doks runtime clients.
3
+ *
4
+ * Consumers resolve the App Platform deploy client via
5
+ * `getDigitalOceanAppDeployClient()` (preferred) or, for type-pinned generic
6
+ * resolution, `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
7
+ *
8
+ * Requires `doksPlugin` to be registered with the runtime so the
9
+ * `runtime/client` descriptor + loader for id `digitalocean-app-deploy` are
10
+ * resolvable.
11
+ */
12
+ import { getVibesClient } from '@vibesdotdev/runtime-client';
13
+ import { DigitalOceanAppDeployClient } from './digitalocean-app-deploy.client.js';
14
+ export { DigitalOceanAppDeployClient } from './digitalocean-app-deploy.client.js';
15
+ export async function getDigitalOceanAppDeployClient() {
16
+ return getVibesClient('digitalocean-app-deploy');
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,EACN,2BAA2B,EAG3B,MAAM,kCAAkC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,8BAA8B;IACnD,OAAO,cAAc,CAA8B,yBAAyB,CAAC,CAAC;AAC/E,CAAC"}