kadi-deploy 0.19.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.
Files changed (52) hide show
  1. package/.env.example +6 -0
  2. package/.prettierrc +6 -0
  3. package/README.md +589 -0
  4. package/agent.json +23 -0
  5. package/index.js +11 -0
  6. package/package.json +42 -0
  7. package/quick-command.txt +92 -0
  8. package/scripts/preflight.js +458 -0
  9. package/scripts/preflight.sh +300 -0
  10. package/src/cli/bid-selector.ts +222 -0
  11. package/src/cli/colors.ts +216 -0
  12. package/src/cli/index.ts +11 -0
  13. package/src/cli/prompts.ts +190 -0
  14. package/src/cli/spinners.ts +165 -0
  15. package/src/commands/deploy-local.ts +475 -0
  16. package/src/commands/deploy.ts +1342 -0
  17. package/src/commands/down.ts +679 -0
  18. package/src/commands/index.ts +10 -0
  19. package/src/commands/lock.ts +571 -0
  20. package/src/config/agent-loader.ts +177 -0
  21. package/src/config/index.ts +9 -0
  22. package/src/display/deployment-info.ts +220 -0
  23. package/src/display/pricing.ts +137 -0
  24. package/src/display/resources.ts +234 -0
  25. package/src/enhanced-registry-manager.ts +892 -0
  26. package/src/index.ts +307 -0
  27. package/src/infrastructure/registry.ts +269 -0
  28. package/src/schemas/profiles.ts +529 -0
  29. package/src/secrets/broker-urls.ts +109 -0
  30. package/src/secrets/handshake.ts +407 -0
  31. package/src/secrets/index.ts +69 -0
  32. package/src/secrets/inject-env.ts +171 -0
  33. package/src/secrets/nonce.ts +31 -0
  34. package/src/secrets/normalize.ts +204 -0
  35. package/src/secrets/prepare.ts +152 -0
  36. package/src/secrets/validate.ts +243 -0
  37. package/src/secrets/vault.ts +80 -0
  38. package/src/types/akash.ts +116 -0
  39. package/src/types/container-registry-ability.d.ts +158 -0
  40. package/src/types/external.ts +49 -0
  41. package/src/types.ts +211 -0
  42. package/src/utils/akt-price.ts +74 -0
  43. package/tests/agent-loader.test.ts +239 -0
  44. package/tests/autonomous.test.ts +244 -0
  45. package/tests/down.test.ts +1143 -0
  46. package/tests/lock.test.ts +1148 -0
  47. package/tests/nonce.test.ts +34 -0
  48. package/tests/normalize.test.ts +270 -0
  49. package/tests/secrets-schema.test.ts +301 -0
  50. package/tests/types.test.ts +198 -0
  51. package/tsconfig.json +18 -0
  52. package/vitest.config.ts +9 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Type Compatibility Tests
3
+ *
4
+ * Verifies that kadi-deploy's types and interfaces are compatible
5
+ * with deploy-ability v0.0.8's autonomous deployment API.
6
+ *
7
+ * These are compile-time tests — if this file compiles, types are compatible.
8
+ */
9
+
10
+ import { describe, it, expect } from 'vitest';
11
+ import type {
12
+ DeployOptions,
13
+ ResolvedDeployOptions,
14
+ AgentConfig,
15
+ DeploymentContext,
16
+ } from '../src/types.js';
17
+ import type {
18
+ AutonomousDeploymentConfig,
19
+ BidFilterCriteria,
20
+ SecretsProvider,
21
+ BidStrategy,
22
+ } from '@kadi.build/deploy-ability/akash';
23
+
24
+ // ─────────────────────────────────────────────────────────
25
+ // Compile-time type compatibility checks
26
+ // ─────────────────────────────────────────────────────────
27
+
28
+ describe('type compatibility with deploy-ability v0.0.8', () => {
29
+ it('DeployOptions supports all autonomous fields', () => {
30
+ const opts: DeployOptions = {
31
+ autonomous: true,
32
+ bidStrategy: 'balanced',
33
+ bidMaxPrice: 500,
34
+ requireAudited: true,
35
+ secretsVault: 'my-vault',
36
+ autoApproveSecrets: true,
37
+ secretTimeout: 120000,
38
+ };
39
+
40
+ expect(opts.autonomous).toBe(true);
41
+ expect(opts.bidStrategy).toBe('balanced');
42
+ expect(opts.bidMaxPrice).toBe(500);
43
+ expect(opts.requireAudited).toBe(true);
44
+ expect(opts.secretsVault).toBe('my-vault');
45
+ });
46
+
47
+ it('ResolvedDeployOptions supports all autonomous fields', () => {
48
+ const resolved: ResolvedDeployOptions = {
49
+ target: 'akash',
50
+ network: 'mainnet',
51
+ engine: 'docker',
52
+ useRemoteRegistry: false,
53
+ registryDuration: 600000,
54
+ tunnelService: 'kadi',
55
+ interactive: false,
56
+ dryRun: false,
57
+ verbose: false,
58
+ yes: true,
59
+ showCommands: false,
60
+ project: '/tmp/test',
61
+ autonomous: true,
62
+ bidStrategy: 'most-reliable',
63
+ bidMaxPrice: 1000,
64
+ requireAudited: true,
65
+ secretsVault: 'global',
66
+ };
67
+
68
+ expect(resolved.autonomous).toBe(true);
69
+ expect(resolved.bidStrategy).toBe('most-reliable');
70
+ });
71
+
72
+ it('BidStrategy values match DeployOptions bidStrategy type', () => {
73
+ // All valid BidStrategy values should be assignable to DeployOptions.bidStrategy
74
+ const strategies: BidStrategy[] = ['cheapest', 'most-reliable', 'balanced'];
75
+ strategies.forEach((s) => {
76
+ const opts: DeployOptions = { bidStrategy: s };
77
+ expect(opts.bidStrategy).toBe(s);
78
+ });
79
+ });
80
+
81
+ it('BidFilterCriteria can be constructed from CLI flags', () => {
82
+ const filter: BidFilterCriteria = {
83
+ maxPricePerBlock: 500,
84
+ requireAudited: true,
85
+ };
86
+
87
+ expect(filter.maxPricePerBlock).toBe(500);
88
+ expect(filter.requireAudited).toBe(true);
89
+ });
90
+
91
+ it('BidFilterCriteria supports all optional fields', () => {
92
+ const filter: BidFilterCriteria = {
93
+ maxPricePerBlock: 1000,
94
+ minUptime: { value: 0.95, period: '7d' },
95
+ requireAudited: true,
96
+ preferredRegions: ['us-east', 'eu-west'],
97
+ requireOnline: true,
98
+ };
99
+
100
+ expect(filter.minUptime?.value).toBe(0.95);
101
+ expect(filter.preferredRegions).toHaveLength(2);
102
+ });
103
+
104
+ it('SecretsProvider interface is implementable', () => {
105
+ // Verifies the CLI shim shape matches SecretsProvider
106
+ const provider: SecretsProvider = {
107
+ async getMnemonic(): Promise<string> {
108
+ return 'test mnemonic phrase';
109
+ },
110
+ async getCertificate() {
111
+ return null;
112
+ },
113
+ async storeCertificate(_cert) {
114
+ // no-op
115
+ },
116
+ };
117
+
118
+ expect(provider.getMnemonic).toBeDefined();
119
+ expect(provider.getCertificate).toBeDefined();
120
+ expect(provider.storeCertificate).toBeDefined();
121
+ });
122
+
123
+ it('AutonomousDeploymentConfig can be constructed from CLI flags', () => {
124
+ const secretsProvider: SecretsProvider = {
125
+ async getMnemonic() { return 'test mnemonic'; },
126
+ };
127
+
128
+ const config: AutonomousDeploymentConfig = {
129
+ secrets: secretsProvider,
130
+ bidStrategy: 'balanced',
131
+ bidFilter: {
132
+ maxPricePerBlock: 500,
133
+ requireAudited: true,
134
+ },
135
+ };
136
+
137
+ expect(config.secrets).toBe(secretsProvider);
138
+ expect(config.bidStrategy).toBe('balanced');
139
+ expect(config.bidFilter?.maxPricePerBlock).toBe(500);
140
+ });
141
+
142
+ it('AutonomousDeploymentConfig works with minimal fields', () => {
143
+ const secretsProvider: SecretsProvider = {
144
+ async getMnemonic() { return 'test'; },
145
+ };
146
+
147
+ // Only secrets is required
148
+ const config: AutonomousDeploymentConfig = {
149
+ secrets: secretsProvider,
150
+ };
151
+
152
+ expect(config.secrets).toBeDefined();
153
+ expect(config.bidStrategy).toBeUndefined();
154
+ expect(config.bidFilter).toBeUndefined();
155
+ });
156
+
157
+ it('AgentConfig supports brokers for secrets handshake', () => {
158
+ const config: AgentConfig = {
159
+ name: 'test-agent',
160
+ version: '1.0.0',
161
+ deploy: {
162
+ production: {
163
+ target: 'akash',
164
+ secrets: {
165
+ vault: 'global',
166
+ required: ['API_KEY'],
167
+ },
168
+ },
169
+ },
170
+ brokers: {
171
+ default: 'wss://broker.kadi.build/kadi',
172
+ },
173
+ };
174
+
175
+ expect(config.brokers?.default).toBe('wss://broker.kadi.build/kadi');
176
+ });
177
+ });
178
+
179
+ // ─────────────────────────────────────────────────────────
180
+ // Tunnel service type tests
181
+ // ─────────────────────────────────────────────────────────
182
+
183
+ describe('tunnel service types', () => {
184
+ it('kadi is a valid tunnel service', () => {
185
+ const opts: DeployOptions = { tunnelService: 'kadi' };
186
+ expect(opts.tunnelService).toBe('kadi');
187
+ });
188
+
189
+ it('localtunnel is a valid tunnel service', () => {
190
+ const opts: DeployOptions = { tunnelService: 'localtunnel' };
191
+ expect(opts.tunnelService).toBe('localtunnel');
192
+ });
193
+
194
+ it('ngrok and serveo are valid tunnel services', () => {
195
+ expect({ tunnelService: 'ngrok' } as DeployOptions).toBeDefined();
196
+ expect({ tunnelService: 'serveo' } as DeployOptions).toBeDefined();
197
+ });
198
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "node16",
6
+ "allowSyntheticDefaultImports": true,
7
+ "esModuleInterop": true,
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "declaration": true,
12
+ "outDir": "./dist",
13
+ "rootDir": "./src",
14
+ "noImplicitAny": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
18
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ include: ['tests/**/*.test.ts'],
7
+ testTimeout: 10000,
8
+ },
9
+ });