@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
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Implementation: infra/package-registry -> verdaccio-doks
3
+ *
4
+ * Generates K8s manifests for a Verdaccio npm registry on DOKS.
5
+ */
6
+ import { createHash } from 'node:crypto';
7
+ import * as z from 'zod/v4';
8
+ import { createRuntimeImplementation } from '@vibesdotdev/runtime';
9
+ import { VerdaccioDoksPackageRegistryConfigSchema, PackageRegistryTypeSchema } from '@vibesdotdev/infra-core/kinds';
10
+ import { loadVerdaccioThemeAssets, VIBES_PRIMARY_HEX } from '@vibesdotdev/registry-theme';
11
+ import type { K8sDeployment, K8sService } from '../types.ts';
12
+
13
+ export const VerdaccioDoksDescriptorSchema = z.object({
14
+ kind: z.literal('infra/package-registry'),
15
+ id: z.string().min(1),
16
+ name: z.string().optional(),
17
+ description: z.string().optional(),
18
+ url: z.string().url(),
19
+ registryType: PackageRegistryTypeSchema.default('npm'),
20
+ scope: z.string().optional(),
21
+ upstreamUrl: z.string().url().optional(),
22
+ authRequired: z.boolean().default(true),
23
+ ssl: z.boolean().default(true),
24
+ env: z.array(z.object({
25
+ name: z.string().regex(/^[_A-Z0-9]+$/),
26
+ public: z.boolean().default(false),
27
+ required: z.boolean().default(true),
28
+ value: z.string().optional(),
29
+ secret: z.boolean().default(false),
30
+ description: z.string().optional(),
31
+ storeKey: z.string().min(1).optional()
32
+ })).optional(),
33
+ config: VerdaccioDoksPackageRegistryConfigSchema.extend({
34
+ adapter: z.literal('verdaccio-doks')
35
+ })
36
+ });
37
+
38
+ export type VerdaccioDoksDescriptorInput = z.input<typeof VerdaccioDoksDescriptorSchema>;
39
+ export type VerdaccioDoksDescriptor = z.infer<typeof VerdaccioDoksDescriptorSchema>;
40
+
41
+ export interface VerdaccioManifest {
42
+ deployment: K8sDeployment;
43
+ service: K8sService;
44
+ pvc: { apiVersion: string; kind: string; metadata: Record<string, unknown>; spec: Record<string, unknown> };
45
+ configMap: { apiVersion: string; kind: string; metadata: Record<string, unknown>; data: Record<string, string> };
46
+ ingress: { apiVersion: string; kind: string; metadata: Record<string, unknown>; spec: Record<string, unknown> };
47
+ }
48
+
49
+ function buildVerdaccioConfig(d: VerdaccioDoksDescriptor): string {
50
+ const cfg = d.config!;
51
+ const theme = loadVerdaccioThemeAssets();
52
+
53
+ // Verdaccio v5's metaScripts/scriptsBodyAfter render the array items via
54
+ // string interpolation in the HTML template — items must be RAW HTML
55
+ // strings, not { tag, attribs } objects. The latter render as
56
+ // "[object Object]".
57
+ const cssDataUri = `data:text/css;base64,${Buffer.from(theme.combinedCss).toString('base64')}`;
58
+ const cssTag = `<link rel="stylesheet" href="${cssDataUri}">`;
59
+
60
+ const lines: string[] = [
61
+ 'storage: /verdaccio/storage',
62
+ // url_prefix must be the PATH prefix (e.g. "/"), not the full origin.
63
+ // Setting the full origin causes Verdaccio to concat it with the request
64
+ // origin → base href becomes https://X/https://X/ and the SPA breaks.
65
+ 'url_prefix: /',
66
+ 'web:',
67
+ ' title: vibes packages',
68
+ ` logo: ${theme.logoDataUri}`,
69
+ ` primary_color: "${VIBES_PRIMARY_HEX}"`,
70
+ ' darkMode: enabled',
71
+ ' gravatar: true',
72
+ ' metaScripts:',
73
+ // Single-quoted YAML keeps the inner double-quotes and the long data URL intact.
74
+ ` - '${cssTag}'`
75
+ ];
76
+ if (theme.elementsBundle) {
77
+ const jsDataUri = `data:text/javascript;base64,${Buffer.from(theme.elementsBundle).toString('base64')}`;
78
+ const scriptTag = `<script type="module" src="${jsDataUri}"></script>`;
79
+ const brandBarMarkup = '<vibes-brand-bar app="packages"><vibes-account-menu slot="end"></vibes-account-menu></vibes-brand-bar>';
80
+ // Verdaccio v5.33's bundled middleware looks up `web.scriptsbodyBefore`
81
+ // (lowercase 'b' before Before). The capital-B `scriptsBodyBefore` was
82
+ // introduced later but the deprecated lowercase key is what's wired in
83
+ // the installed @verdaccio/middleware@8.0.0-next-8.1. Confirmed by
84
+ // grepping the actual /usr/local/lib/.../template.js in the pod.
85
+ lines.push(
86
+ ' scriptsbodyBefore:',
87
+ ` - '${brandBarMarkup}'`,
88
+ ` - '${scriptTag}'`
89
+ );
90
+ }
91
+ lines.push(
92
+ 'security:',
93
+ ' api:',
94
+ ' jwt:',
95
+ ' sign:',
96
+ ' expiresIn: 7d',
97
+ ' web:',
98
+ ' sign:',
99
+ ' expiresIn: 1d',
100
+ // Auth plugin disabled while the better-auth-jwt distribution is
101
+ // reworked — the previous setup-plugin init container tried to
102
+ // `git clone` the private monorepo, which fails unauthenticated.
103
+ // Falls back to Verdaccio's built-in htpasswd auth; if the htpasswd
104
+ // file is empty, no one can publish but reads are still permitted
105
+ // per the `access: $all` policy below.
106
+ 'auth:',
107
+ ' htpasswd:',
108
+ ' file: /verdaccio/storage/htpasswd',
109
+ ' max_users: -1',
110
+ 'plugins: /verdaccio/plugins',
111
+ 'packages:'
112
+ );
113
+ if (d.scope) {
114
+ const scopeName = d.scope.replace('@', '');
115
+ lines.push(` '@${scopeName}/*':`);
116
+ lines.push(' access: $all');
117
+ lines.push(' publish: $authenticated');
118
+ lines.push(' unpublish: $authenticated');
119
+ lines.push(' "**":');
120
+ lines.push(' access: $all');
121
+ lines.push(' publish: $authenticated');
122
+ lines.push(` proxy: ${new URL(cfg.upstreamNpmUrl).origin}`);
123
+ } else {
124
+ lines.push(' "**":');
125
+ lines.push(' access: $all');
126
+ lines.push(' publish: $authenticated');
127
+ lines.push(` proxy: ${new URL(cfg.upstreamNpmUrl).origin}`);
128
+ }
129
+ lines.push('logs:');
130
+ lines.push(' - type: stdout');
131
+ lines.push(' format: pretty');
132
+ lines.push(' level: http');
133
+ return lines.join('\n');
134
+ }
135
+
136
+ export function generateVerdaccioManifest(input: VerdaccioDoksDescriptorInput): VerdaccioManifest {
137
+ const d = VerdaccioDoksDescriptorSchema.parse(input);
138
+ const ns = 'vibes';
139
+ const name = `vibes-${d.id}`;
140
+ const pvcName = `${name}-data`;
141
+ const port = 4873;
142
+ const configKey = 'config.yaml';
143
+ const cfg = d.config!;
144
+ const secretName = 'verdaccio-secrets';
145
+ const pluginMountPath = '/verdaccio/plugins';
146
+
147
+ const configYaml = buildVerdaccioConfig(d);
148
+ const configChecksum = createHash('sha256').update(configYaml).digest('hex').slice(0, 16);
149
+
150
+ const deployment: K8sDeployment = {
151
+ apiVersion: 'apps/v1',
152
+ kind: 'Deployment',
153
+ metadata: {
154
+ name,
155
+ namespace: ns,
156
+ labels: { app: d.id, 'app.kubernetes.io/part-of': 'vibes' },
157
+ annotations: {
158
+ 'vibes.dev/verdaccio-plugin': 'better-auth-jwt',
159
+ 'secrets.hashicorp.com/rollout-restart': 'true'
160
+ }
161
+ },
162
+ spec: {
163
+ replicas: 1,
164
+ strategy: { type: 'Recreate' },
165
+ selector: { matchLabels: { app: d.id } },
166
+ template: {
167
+ metadata: {
168
+ labels: { app: d.id },
169
+ annotations: { 'vibes.dev/config-checksum': configChecksum }
170
+ },
171
+ spec: {
172
+ initContainers: [{
173
+ name: 'setup-plugin',
174
+ image: 'node:22-alpine',
175
+ command: ['sh', '-c', [
176
+ 'apk add --no-cache git',
177
+ `mkdir -p ${pluginMountPath}/better-auth-jwt`,
178
+ 'cd /tmp',
179
+ `git clone --depth 1 https://github.com/vibesdotdev/monorepo.git || git clone https://github.com/vibesdotdev/monorepo.git`,
180
+ 'cd monorepo/packages/verdaccio-better-auth-jwt',
181
+ 'npm install',
182
+ 'npm run build || true',
183
+ `cp -r ./dist/* ${pluginMountPath}/better-auth-jwt/ || true`,
184
+ 'echo "Plugin installed"'
185
+ ].join(' && ')],
186
+ volumeMounts: [
187
+ { name: 'plugins', mountPath: pluginMountPath }
188
+ ],
189
+ resources: {
190
+ requests: { cpu: '100m', memory: '64Mi' },
191
+ limits: { cpu: '500m', memory: '256Mi' }
192
+ }
193
+ }],
194
+ containers: [{
195
+ name: d.id,
196
+ image: cfg.dockerImage,
197
+ ports: [{ name: 'http', containerPort: port }],
198
+ envFrom: [{ secretRef: { name: secretName } }],
199
+ env: [
200
+ { name: 'VERDACCIO_PORT', value: String(port) },
201
+ { name: 'VERDACCIO_JWT_SECRET', valueFrom: { secretKeyRef: { name: secretName, key: 'jwt-secret' } } }
202
+ ],
203
+ volumeMounts: [
204
+ { name: 'storage', mountPath: '/verdaccio/storage' },
205
+ { name: 'config', mountPath: '/verdaccio/conf', readOnly: true },
206
+ { name: 'plugins', mountPath: pluginMountPath }
207
+ ],
208
+ livenessProbe: {
209
+ httpGet: { path: '/', port },
210
+ initialDelaySeconds: 30,
211
+ periodSeconds: 30
212
+ },
213
+ readinessProbe: {
214
+ httpGet: { path: '/-/ping', port },
215
+ periodSeconds: 10
216
+ },
217
+ resources: {
218
+ requests: { cpu: '100m', memory: '128Mi' },
219
+ limits: { cpu: '500m', memory: '512Mi' }
220
+ }
221
+ }],
222
+ volumes: [
223
+ { name: 'storage', persistentVolumeClaim: { claimName: pvcName } },
224
+ { name: 'config', configMap: { name: `${name}-config` } },
225
+ { name: 'plugins', emptyDir: {} }
226
+ ]
227
+ }
228
+ }
229
+ }
230
+ };
231
+
232
+ const service: K8sService = {
233
+ apiVersion: 'v1',
234
+ kind: 'Service',
235
+ metadata: { name, namespace: ns },
236
+ spec: {
237
+ type: 'ClusterIP',
238
+ selector: { app: d.id },
239
+ ports: [{ name: 'http', port, targetPort: port }]
240
+ }
241
+ };
242
+
243
+ const pvc = {
244
+ apiVersion: 'v1',
245
+ kind: 'PersistentVolumeClaim',
246
+ metadata: { name: pvcName, namespace: ns, labels: { app: d.id } },
247
+ spec: {
248
+ accessModes: ['ReadWriteOnce'],
249
+ resources: { requests: { storage: cfg.storageSize } }
250
+ }
251
+ };
252
+
253
+ const configMap = {
254
+ apiVersion: 'v1',
255
+ kind: 'ConfigMap',
256
+ metadata: { name: `${name}-config`, namespace: ns, labels: { app: d.id } },
257
+ data: { [configKey]: configYaml }
258
+ };
259
+
260
+ const ingress = {
261
+ apiVersion: 'networking.k8s.io/v1',
262
+ kind: 'Ingress',
263
+ metadata: {
264
+ name,
265
+ namespace: ns,
266
+ labels: { app: d.id },
267
+ annotations: {
268
+ 'cert-manager.io/cluster-issuer': 'letsencrypt-prod',
269
+ 'nginx.ingress.kubernetes.io/proxy-body-size': '100m'
270
+ }
271
+ },
272
+ spec: {
273
+ tls: [{ hosts: [cfg.domain], secretName: `${name}-tls` }],
274
+ rules: [{
275
+ host: cfg.domain,
276
+ http: {
277
+ paths: [{
278
+ path: '/',
279
+ pathType: 'Prefix' as const,
280
+ backend: { service: { name, port: { number: port } } }
281
+ }]
282
+ }
283
+ }]
284
+ }
285
+ };
286
+
287
+ return { deployment, service, pvc, configMap, ingress };
288
+ }
289
+
290
+ export function createVerdaccioImpl(input: VerdaccioDoksDescriptorInput) {
291
+ const descriptor = VerdaccioDoksDescriptorSchema.parse(input);
292
+ return createRuntimeImplementation({
293
+ id: 'verdaccio-doks',
294
+ kind: 'infra/package-registry',
295
+ priority: 20,
296
+ implementation: {
297
+ generateConfig: () => generateVerdaccioManifest(descriptor)
298
+ }
299
+ });
300
+ }
package/src/index.ts ADDED
@@ -0,0 +1,136 @@
1
+ // Implementations
2
+ export {
3
+ generateK8sDeployment,
4
+ DoksDeploymentDescriptorSchema,
5
+ type DoksDeploymentDescriptorInput,
6
+ type DoksDeploymentDescriptor
7
+ } from './implementations/deployment.impl';
8
+ export {
9
+ generateK8sStatefulSet,
10
+ DoksQueueDescriptorSchema,
11
+ DoksDatabaseDescriptorSchema,
12
+ type DoksQueueDescriptorInput,
13
+ type DoksQueueDescriptor,
14
+ type DoksDatabaseDescriptorInput,
15
+ type DoksDatabaseDescriptor
16
+ } from './implementations/statefulset.impl';
17
+ export {
18
+ generateDOManagedDB,
19
+ DOManagedPostgresDescriptorSchema,
20
+ type DOManagedPostgresDescriptorInput,
21
+ type DOManagedPostgresDescriptor
22
+ } from './implementations/managed-db.impl';
23
+ export {
24
+ generateDOSpaces,
25
+ DOSpacesDescriptorSchema,
26
+ type DOSpacesDescriptorInput,
27
+ type DOSpacesDescriptor
28
+ } from './implementations/spaces.impl';
29
+ export {
30
+ generateDOManagedRedis,
31
+ DOManagedRedisDescriptorSchema,
32
+ type DOManagedRedisDescriptorInput,
33
+ type DOManagedRedisDescriptor
34
+ } from './implementations/managed-redis.impl';
35
+ export {
36
+ generateGiteaManifest,
37
+ type GiteaManifest
38
+ } from './implementations/gitea.impl';
39
+ export {
40
+ generateVerdaccioManifest,
41
+ type VerdaccioManifest
42
+ } from './implementations/verdaccio.impl';
43
+
44
+ // Types
45
+ export type {
46
+ K8sDeployment,
47
+ K8sStatefulSet,
48
+ K8sService,
49
+ K8sConfigMap,
50
+ K8sSecret,
51
+ K8sContainer,
52
+ K8sPodSpec,
53
+ K8sPodTemplateSpec,
54
+ K8sMetadata,
55
+ K8sLabelSelector,
56
+ K8sResourceRequirements,
57
+ K8sProbe,
58
+ K8sVolumeClaimTemplate,
59
+ DOManagedDBSpec,
60
+ DOManagedRedisSpec,
61
+ DOSpacesSpec,
62
+ // Cloud provider types
63
+ CloudProvider,
64
+ CloudInstance,
65
+ InstanceConfig,
66
+ InstanceFilters,
67
+ CloudVolume,
68
+ VolumeConfig,
69
+ VolumeFilters,
70
+ SSHKey,
71
+ CloudProviderConfig,
72
+ InstanceStatus,
73
+ VolumeStatus,
74
+ CloudProviderError,
75
+ // Kubernetes types
76
+ K8sConfig,
77
+ K8sEnvironment,
78
+ PodSelector,
79
+ PodStatus,
80
+ LogOptions,
81
+ LogEntry,
82
+ LogStream,
83
+ DeploymentStatus,
84
+ ServiceInfo,
85
+ PodMetrics,
86
+ ResourceMetrics,
87
+ K8sEvent,
88
+ ExecOptions,
89
+ ExecResult,
90
+ PortForwardOptions,
91
+ PortForward,
92
+ ContainerState,
93
+ PodPhase,
94
+ ConditionStatus,
95
+ DeploymentConditionType,
96
+ ServiceType,
97
+ ServiceProtocol,
98
+ EventType,
99
+ K8sError,
100
+ K8sAuthError,
101
+ K8sNotFoundError
102
+ } from './types.ts';
103
+
104
+ // Secrets
105
+ export {
106
+ vaultDescriptor,
107
+ createVaultStore,
108
+ readKVSecret,
109
+ writeKVSecret,
110
+ deleteKVKey,
111
+ listKVPaths,
112
+ } from './secrets/index.ts';
113
+ export type { VaultClientConfig } from './secrets/index.ts';
114
+
115
+ // Cloud Provider (implementation classes only; types already exported above)
116
+ export {
117
+ BaseCloudProvider,
118
+ DigitalOceanProvider,
119
+ createCloudProvider,
120
+ getCloudProviderFromEnv,
121
+ validateCloudProviderConfig,
122
+ } from './cloud/index.ts';
123
+
124
+ // Kubernetes Client
125
+ export { KubernetesClient } from './kubernetes/index.ts';
126
+
127
+ // Plugin
128
+ export { default as doksPlugin } from './doks.plugin';
129
+
130
+ // Runtime clients
131
+ export {
132
+ DigitalOceanAppDeployClient,
133
+ getDigitalOceanAppDeployClient,
134
+ type DeployAppOptions,
135
+ type DeployAppResult
136
+ } from './client/index.ts';