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,234 @@
1
+ /**
2
+ * Service Resources Display Utilities
3
+ *
4
+ * Formats and displays service resource allocations from deploy-ability's
5
+ * AkashDeploymentData.services field.
6
+ *
7
+ * @module display/resources
8
+ */
9
+
10
+ import type { AkashDeploymentData } from '@kadi.build/deploy-ability/types';
11
+ import { formatKeyValue, dim, bold, info } from '../cli/colors.js';
12
+
13
+ /**
14
+ * Displays service resources in a formatted manner
15
+ *
16
+ * Shows both aggregated totals and detailed resource specs for each service.
17
+ *
18
+ * @param services - Services array from AkashDeploymentData
19
+ * @param indent - Indentation level (default: 2)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * displayServiceResources(deploymentData.services);
24
+ * // Output:
25
+ * // Services:
26
+ * // web (4 replicas):
27
+ * // Total: 5.0 CPU, 10Gi RAM, 5Gi Storage
28
+ * // Specs:
29
+ * // - 3× 1.0 CPU, 2Gi RAM, 1Gi Storage
30
+ * // - 1× 2.0 CPU, 4Gi RAM, 2Gi Storage
31
+ * ```
32
+ */
33
+ export function displayServiceResources(
34
+ services: AkashDeploymentData['services'],
35
+ indent: number = 2
36
+ ): void {
37
+ if (!services || services.length === 0) {
38
+ return;
39
+ }
40
+
41
+ const prefix = ' '.repeat(indent);
42
+
43
+ for (const service of services) {
44
+ console.log(`${prefix}${bold(service.name)} ${dim(`(${service.replicaCount} ${service.replicaCount === 1 ? 'replica' : 'replicas'})`)}:`);
45
+
46
+ // Display aggregated totals
47
+ console.log(
48
+ `${prefix} ${formatKeyValue('Total Resources', `${service.totalResources.cpu} CPU, ${service.totalResources.memory} RAM, ${service.totalResources.storage} Storage`)}`
49
+ );
50
+
51
+ // Display detailed specs if there are multiple configurations
52
+ if (service.resourceSpecs.length > 1) {
53
+ console.log(`${prefix} ${dim('Resource Specs:')}`);
54
+ for (const spec of service.resourceSpecs) {
55
+ console.log(
56
+ `${prefix} ${dim('•')} ${info(`${spec.count}×`)} ${spec.cpu} CPU, ${spec.memory} RAM, ${spec.storage} Storage`
57
+ );
58
+ }
59
+ } else if (service.resourceSpecs.length === 1) {
60
+ // Single spec - show replica configuration
61
+ const spec = service.resourceSpecs[0];
62
+ console.log(
63
+ `${prefix} ${formatKeyValue('Per Replica', `${spec.cpu} CPU, ${spec.memory} RAM, ${spec.storage} Storage`)}`
64
+ );
65
+ }
66
+
67
+ console.log('');
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Gets a compact one-line resource summary for a service
73
+ *
74
+ * Useful for displaying in summaries or lists.
75
+ *
76
+ * @param service - Service object from AkashDeploymentData.services
77
+ * @returns Formatted resource string
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const summary = getResourceSummary(service);
82
+ * console.log(`web: ${summary}`);
83
+ * // Output: "web: 4 replicas • 5.0 CPU, 10Gi RAM, 5Gi Storage"
84
+ * ```
85
+ */
86
+ export function getResourceSummary(
87
+ service: NonNullable<AkashDeploymentData['services']>[number]
88
+ ): string {
89
+ return `${service.replicaCount} ${service.replicaCount === 1 ? 'replica' : 'replicas'} • ${service.totalResources.cpu} CPU, ${service.totalResources.memory} RAM, ${service.totalResources.storage} Storage`;
90
+ }
91
+
92
+ /**
93
+ * Displays all services in a compact table format
94
+ *
95
+ * Shows service name, replica count, and total resources in a clean layout.
96
+ *
97
+ * @param services - Services array from AkashDeploymentData
98
+ * @param indent - Indentation level (default: 0)
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * displayServicesTable(deploymentData.services);
103
+ * // Output:
104
+ * // Services:
105
+ * // web 4 replicas 5.0 CPU 10Gi RAM 5Gi Storage
106
+ * // api 2 replicas 2.0 CPU 4Gi RAM 2Gi Storage
107
+ * ```
108
+ */
109
+ export function displayServicesTable(
110
+ services: AkashDeploymentData['services'],
111
+ indent: number = 0
112
+ ): void {
113
+ if (!services || services.length === 0) {
114
+ return;
115
+ }
116
+
117
+ const prefix = ' '.repeat(indent);
118
+
119
+ console.log(`${prefix}${bold('Services:')}`);
120
+
121
+ // Calculate column widths
122
+ const nameWidth = Math.max(...services.map(s => s.name.length), 7);
123
+ const replicaWidth = 12;
124
+ const cpuWidth = 10;
125
+ const memWidth = 10;
126
+ const storageWidth = 12;
127
+
128
+ // Display each service
129
+ for (const service of services) {
130
+ const name = service.name.padEnd(nameWidth);
131
+ const replicas = `${service.replicaCount} ${service.replicaCount === 1 ? 'replica ' : 'replicas'}`.padEnd(replicaWidth);
132
+ const cpu = service.totalResources.cpu.padEnd(cpuWidth);
133
+ const mem = service.totalResources.memory.padEnd(memWidth);
134
+ const storage = service.totalResources.storage.padEnd(storageWidth);
135
+
136
+ console.log(
137
+ `${prefix} ${name} ${dim(replicas)} ${info(cpu)} ${info(mem)} ${info(storage)}`
138
+ );
139
+ }
140
+
141
+ console.log('');
142
+ }
143
+
144
+ /**
145
+ * Calculates total resources across all services
146
+ *
147
+ * Useful for showing overall deployment resource usage.
148
+ *
149
+ * @param services - Services array from AkashDeploymentData
150
+ * @returns Total CPU, memory, and storage
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const totals = calculateTotalResources(deploymentData.services);
155
+ * console.log(`Total: ${totals.cpu} CPU, ${totals.memory} RAM, ${totals.storage} Storage`);
156
+ * ```
157
+ */
158
+ export function calculateTotalResources(
159
+ services: AkashDeploymentData['services']
160
+ ): { cpu: number; memory: number; storage: number } {
161
+ if (!services || services.length === 0) {
162
+ return { cpu: 0, memory: 0, storage: 0 };
163
+ }
164
+
165
+ let totalCpu = 0;
166
+ let totalMemory = 0;
167
+ let totalStorage = 0;
168
+
169
+ for (const service of services) {
170
+ // Parse CPU (e.g., "5.0" -> 5.0)
171
+ totalCpu += parseFloat(service.totalResources.cpu) || 0;
172
+
173
+ // Parse memory (e.g., "10Gi" -> bytes)
174
+ totalMemory += parseResourceValue(service.totalResources.memory);
175
+
176
+ // Parse storage (e.g., "5Gi" -> bytes)
177
+ totalStorage += parseResourceValue(service.totalResources.storage);
178
+ }
179
+
180
+ return {
181
+ cpu: totalCpu,
182
+ memory: totalMemory,
183
+ storage: totalStorage
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Parses a resource string to bytes
189
+ *
190
+ * Converts strings like "10Gi", "512Mi", "1Ti" to byte values.
191
+ *
192
+ * @param value - Resource string
193
+ * @returns Value in bytes
194
+ */
195
+ function parseResourceValue(value: string): number {
196
+ const match = value.match(/^([\d.]+)(Ki|Mi|Gi|Ti|Pi)?$/);
197
+ if (!match) return 0;
198
+
199
+ const num = parseFloat(match[1]);
200
+ const unit = match[2] || '';
201
+
202
+ const multipliers: Record<string, number> = {
203
+ '': 1,
204
+ 'Ki': 1024,
205
+ 'Mi': 1024 * 1024,
206
+ 'Gi': 1024 * 1024 * 1024,
207
+ 'Ti': 1024 * 1024 * 1024 * 1024,
208
+ 'Pi': 1024 * 1024 * 1024 * 1024 * 1024
209
+ };
210
+
211
+ return num * (multipliers[unit] || 1);
212
+ }
213
+
214
+ /**
215
+ * Formats bytes to human-readable string
216
+ *
217
+ * @param bytes - Byte value
218
+ * @returns Formatted string (e.g., "10Gi", "512Mi")
219
+ */
220
+ export function formatBytes(bytes: number): string {
221
+ if (bytes === 0) return '0';
222
+
223
+ const units = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi'];
224
+ let unitIndex = 0;
225
+ let value = bytes;
226
+
227
+ while (value >= 1024 && unitIndex < units.length - 1) {
228
+ value /= 1024;
229
+ unitIndex++;
230
+ }
231
+
232
+ const formatted = value.toFixed(2).replace(/\.?0+$/, '');
233
+ return `${formatted}${units[unitIndex]}`;
234
+ }