@build-astron-co/nimbus 0.2.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 (313) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +628 -0
  3. package/bin/nimbus +38 -0
  4. package/package.json +80 -0
  5. package/src/__tests__/app.test.ts +76 -0
  6. package/src/__tests__/audit.test.ts +877 -0
  7. package/src/__tests__/circuit-breaker.test.ts +116 -0
  8. package/src/__tests__/cli-run.test.ts +115 -0
  9. package/src/__tests__/context-manager.test.ts +502 -0
  10. package/src/__tests__/context.test.ts +242 -0
  11. package/src/__tests__/enterprise.test.ts +401 -0
  12. package/src/__tests__/generator.test.ts +433 -0
  13. package/src/__tests__/hooks.test.ts +582 -0
  14. package/src/__tests__/init.test.ts +436 -0
  15. package/src/__tests__/intent-parser.test.ts +229 -0
  16. package/src/__tests__/llm-router.test.ts +209 -0
  17. package/src/__tests__/lsp.test.ts +293 -0
  18. package/src/__tests__/modes.test.ts +336 -0
  19. package/src/__tests__/permissions.test.ts +338 -0
  20. package/src/__tests__/serve.test.ts +275 -0
  21. package/src/__tests__/sessions.test.ts +227 -0
  22. package/src/__tests__/sharing.test.ts +288 -0
  23. package/src/__tests__/snapshots.test.ts +581 -0
  24. package/src/__tests__/state-db.test.ts +334 -0
  25. package/src/__tests__/stream-with-tools.test.ts +732 -0
  26. package/src/__tests__/subagents.test.ts +176 -0
  27. package/src/__tests__/system-prompt.test.ts +169 -0
  28. package/src/__tests__/tool-converter.test.ts +256 -0
  29. package/src/__tests__/tool-schemas.test.ts +397 -0
  30. package/src/__tests__/tools.test.ts +143 -0
  31. package/src/__tests__/version.test.ts +49 -0
  32. package/src/agent/compaction-agent.ts +227 -0
  33. package/src/agent/context-manager.ts +435 -0
  34. package/src/agent/context.ts +427 -0
  35. package/src/agent/deploy-preview.ts +426 -0
  36. package/src/agent/index.ts +68 -0
  37. package/src/agent/loop.ts +717 -0
  38. package/src/agent/modes.ts +429 -0
  39. package/src/agent/permissions.ts +466 -0
  40. package/src/agent/subagents/base.ts +116 -0
  41. package/src/agent/subagents/cost.ts +51 -0
  42. package/src/agent/subagents/explore.ts +42 -0
  43. package/src/agent/subagents/general.ts +54 -0
  44. package/src/agent/subagents/index.ts +102 -0
  45. package/src/agent/subagents/infra.ts +59 -0
  46. package/src/agent/subagents/security.ts +69 -0
  47. package/src/agent/system-prompt.ts +436 -0
  48. package/src/app.ts +122 -0
  49. package/src/audit/activity-log.ts +290 -0
  50. package/src/audit/compliance-checker.ts +540 -0
  51. package/src/audit/cost-tracker.ts +318 -0
  52. package/src/audit/index.ts +23 -0
  53. package/src/audit/security-scanner.ts +596 -0
  54. package/src/auth/guard.ts +75 -0
  55. package/src/auth/index.ts +56 -0
  56. package/src/auth/oauth.ts +455 -0
  57. package/src/auth/providers.ts +470 -0
  58. package/src/auth/sso.ts +113 -0
  59. package/src/auth/store.ts +505 -0
  60. package/src/auth/types.ts +187 -0
  61. package/src/build.ts +141 -0
  62. package/src/cli/index.ts +16 -0
  63. package/src/cli/init.ts +854 -0
  64. package/src/cli/openapi-spec.ts +356 -0
  65. package/src/cli/run.ts +237 -0
  66. package/src/cli/serve-auth.ts +80 -0
  67. package/src/cli/serve.ts +462 -0
  68. package/src/cli/web.ts +67 -0
  69. package/src/cli.ts +1417 -0
  70. package/src/clients/core-engine-client.ts +227 -0
  71. package/src/clients/enterprise-client.ts +334 -0
  72. package/src/clients/generator-client.ts +351 -0
  73. package/src/clients/git-client.ts +627 -0
  74. package/src/clients/github-client.ts +410 -0
  75. package/src/clients/helm-client.ts +504 -0
  76. package/src/clients/index.ts +80 -0
  77. package/src/clients/k8s-client.ts +497 -0
  78. package/src/clients/llm-client.ts +161 -0
  79. package/src/clients/rest-client.ts +130 -0
  80. package/src/clients/service-discovery.ts +33 -0
  81. package/src/clients/terraform-client.ts +482 -0
  82. package/src/clients/tools-client.ts +1843 -0
  83. package/src/clients/ws-client.ts +115 -0
  84. package/src/commands/analyze/index.ts +352 -0
  85. package/src/commands/apply/helm.ts +473 -0
  86. package/src/commands/apply/index.ts +213 -0
  87. package/src/commands/apply/k8s.ts +454 -0
  88. package/src/commands/apply/terraform.ts +582 -0
  89. package/src/commands/ask.ts +167 -0
  90. package/src/commands/audit/index.ts +238 -0
  91. package/src/commands/auth-cloud.ts +294 -0
  92. package/src/commands/auth-list.ts +134 -0
  93. package/src/commands/auth-profile.ts +121 -0
  94. package/src/commands/auth-status.ts +141 -0
  95. package/src/commands/aws/ec2.ts +501 -0
  96. package/src/commands/aws/iam.ts +397 -0
  97. package/src/commands/aws/index.ts +133 -0
  98. package/src/commands/aws/lambda.ts +396 -0
  99. package/src/commands/aws/rds.ts +439 -0
  100. package/src/commands/aws/s3.ts +439 -0
  101. package/src/commands/aws/vpc.ts +393 -0
  102. package/src/commands/aws-discover.ts +649 -0
  103. package/src/commands/aws-terraform.ts +805 -0
  104. package/src/commands/azure/aks.ts +376 -0
  105. package/src/commands/azure/functions.ts +253 -0
  106. package/src/commands/azure/index.ts +116 -0
  107. package/src/commands/azure/storage.ts +478 -0
  108. package/src/commands/azure/vm.ts +355 -0
  109. package/src/commands/billing/index.ts +256 -0
  110. package/src/commands/chat.ts +314 -0
  111. package/src/commands/config.ts +346 -0
  112. package/src/commands/cost/cloud-cost-estimator.ts +266 -0
  113. package/src/commands/cost/estimator.ts +79 -0
  114. package/src/commands/cost/index.ts +594 -0
  115. package/src/commands/cost/parsers/terraform.ts +273 -0
  116. package/src/commands/cost/parsers/types.ts +25 -0
  117. package/src/commands/cost/pricing/aws.ts +544 -0
  118. package/src/commands/cost/pricing/azure.ts +499 -0
  119. package/src/commands/cost/pricing/gcp.ts +396 -0
  120. package/src/commands/cost/pricing/index.ts +40 -0
  121. package/src/commands/demo.ts +250 -0
  122. package/src/commands/doctor.ts +794 -0
  123. package/src/commands/drift/index.ts +439 -0
  124. package/src/commands/explain.ts +277 -0
  125. package/src/commands/feedback.ts +389 -0
  126. package/src/commands/fix.ts +324 -0
  127. package/src/commands/fs/index.ts +402 -0
  128. package/src/commands/gcp/compute.ts +325 -0
  129. package/src/commands/gcp/functions.ts +271 -0
  130. package/src/commands/gcp/gke.ts +438 -0
  131. package/src/commands/gcp/iam.ts +344 -0
  132. package/src/commands/gcp/index.ts +129 -0
  133. package/src/commands/gcp/storage.ts +284 -0
  134. package/src/commands/generate-helm.ts +1249 -0
  135. package/src/commands/generate-k8s.ts +1560 -0
  136. package/src/commands/generate-terraform.ts +1460 -0
  137. package/src/commands/gh/index.ts +863 -0
  138. package/src/commands/git/index.ts +1343 -0
  139. package/src/commands/helm/index.ts +1126 -0
  140. package/src/commands/help.ts +539 -0
  141. package/src/commands/history.ts +142 -0
  142. package/src/commands/import.ts +868 -0
  143. package/src/commands/index.ts +367 -0
  144. package/src/commands/init.ts +1046 -0
  145. package/src/commands/k8s/index.ts +1137 -0
  146. package/src/commands/login.ts +631 -0
  147. package/src/commands/logout.ts +83 -0
  148. package/src/commands/onboarding.ts +228 -0
  149. package/src/commands/plan/display.ts +279 -0
  150. package/src/commands/plan/index.ts +599 -0
  151. package/src/commands/preview.ts +452 -0
  152. package/src/commands/questionnaire.ts +1270 -0
  153. package/src/commands/resume.ts +55 -0
  154. package/src/commands/team/index.ts +346 -0
  155. package/src/commands/template.ts +232 -0
  156. package/src/commands/tf/index.ts +1034 -0
  157. package/src/commands/upgrade.ts +550 -0
  158. package/src/commands/usage/index.ts +134 -0
  159. package/src/commands/version.ts +170 -0
  160. package/src/compat/index.ts +2 -0
  161. package/src/compat/runtime.ts +12 -0
  162. package/src/compat/sqlite.ts +107 -0
  163. package/src/config/index.ts +17 -0
  164. package/src/config/manager.ts +530 -0
  165. package/src/config/safety-policy.ts +358 -0
  166. package/src/config/schema.ts +125 -0
  167. package/src/config/types.ts +527 -0
  168. package/src/context/context-db.ts +199 -0
  169. package/src/demo/index.ts +349 -0
  170. package/src/demo/scenarios/full-journey.ts +229 -0
  171. package/src/demo/scenarios/getting-started.ts +127 -0
  172. package/src/demo/scenarios/helm-release.ts +341 -0
  173. package/src/demo/scenarios/k8s-deployment.ts +194 -0
  174. package/src/demo/scenarios/terraform-vpc.ts +170 -0
  175. package/src/demo/types.ts +92 -0
  176. package/src/engine/cost-estimator.ts +438 -0
  177. package/src/engine/diagram-generator.ts +256 -0
  178. package/src/engine/drift-detector.ts +902 -0
  179. package/src/engine/executor.ts +1035 -0
  180. package/src/engine/index.ts +76 -0
  181. package/src/engine/orchestrator.ts +636 -0
  182. package/src/engine/planner.ts +720 -0
  183. package/src/engine/safety.ts +743 -0
  184. package/src/engine/verifier.ts +770 -0
  185. package/src/enterprise/audit.ts +348 -0
  186. package/src/enterprise/auth.ts +270 -0
  187. package/src/enterprise/billing.ts +822 -0
  188. package/src/enterprise/index.ts +17 -0
  189. package/src/enterprise/teams.ts +443 -0
  190. package/src/generator/best-practices.ts +1608 -0
  191. package/src/generator/helm.ts +630 -0
  192. package/src/generator/index.ts +37 -0
  193. package/src/generator/intent-parser.ts +514 -0
  194. package/src/generator/kubernetes.ts +976 -0
  195. package/src/generator/terraform.ts +1867 -0
  196. package/src/history/index.ts +8 -0
  197. package/src/history/manager.ts +322 -0
  198. package/src/history/types.ts +34 -0
  199. package/src/hooks/config.ts +432 -0
  200. package/src/hooks/engine.ts +391 -0
  201. package/src/hooks/index.ts +4 -0
  202. package/src/llm/auth-bridge.ts +198 -0
  203. package/src/llm/circuit-breaker.ts +140 -0
  204. package/src/llm/config-loader.ts +201 -0
  205. package/src/llm/cost-calculator.ts +171 -0
  206. package/src/llm/index.ts +8 -0
  207. package/src/llm/model-aliases.ts +115 -0
  208. package/src/llm/provider-registry.ts +63 -0
  209. package/src/llm/providers/anthropic.ts +433 -0
  210. package/src/llm/providers/bedrock.ts +477 -0
  211. package/src/llm/providers/google.ts +405 -0
  212. package/src/llm/providers/ollama.ts +767 -0
  213. package/src/llm/providers/openai-compatible.ts +340 -0
  214. package/src/llm/providers/openai.ts +328 -0
  215. package/src/llm/providers/openrouter.ts +338 -0
  216. package/src/llm/router.ts +1035 -0
  217. package/src/llm/types.ts +232 -0
  218. package/src/lsp/client.ts +298 -0
  219. package/src/lsp/languages.ts +116 -0
  220. package/src/lsp/manager.ts +278 -0
  221. package/src/mcp/client.ts +402 -0
  222. package/src/mcp/index.ts +5 -0
  223. package/src/mcp/manager.ts +133 -0
  224. package/src/nimbus.ts +214 -0
  225. package/src/plugins/index.ts +27 -0
  226. package/src/plugins/loader.ts +334 -0
  227. package/src/plugins/manager.ts +376 -0
  228. package/src/plugins/types.ts +284 -0
  229. package/src/scanners/cicd-scanner.ts +258 -0
  230. package/src/scanners/cloud-scanner.ts +466 -0
  231. package/src/scanners/framework-scanner.ts +469 -0
  232. package/src/scanners/iac-scanner.ts +388 -0
  233. package/src/scanners/index.ts +539 -0
  234. package/src/scanners/language-scanner.ts +276 -0
  235. package/src/scanners/package-manager-scanner.ts +277 -0
  236. package/src/scanners/types.ts +172 -0
  237. package/src/sessions/manager.ts +365 -0
  238. package/src/sessions/types.ts +44 -0
  239. package/src/sharing/sync.ts +296 -0
  240. package/src/sharing/viewer.ts +97 -0
  241. package/src/snapshots/index.ts +2 -0
  242. package/src/snapshots/manager.ts +530 -0
  243. package/src/state/artifacts.ts +147 -0
  244. package/src/state/audit.ts +137 -0
  245. package/src/state/billing.ts +240 -0
  246. package/src/state/checkpoints.ts +117 -0
  247. package/src/state/config.ts +67 -0
  248. package/src/state/conversations.ts +14 -0
  249. package/src/state/credentials.ts +154 -0
  250. package/src/state/db.ts +58 -0
  251. package/src/state/index.ts +26 -0
  252. package/src/state/messages.ts +115 -0
  253. package/src/state/projects.ts +123 -0
  254. package/src/state/schema.ts +236 -0
  255. package/src/state/sessions.ts +147 -0
  256. package/src/state/teams.ts +200 -0
  257. package/src/telemetry.ts +108 -0
  258. package/src/tools/aws-ops.ts +952 -0
  259. package/src/tools/azure-ops.ts +579 -0
  260. package/src/tools/file-ops.ts +593 -0
  261. package/src/tools/gcp-ops.ts +625 -0
  262. package/src/tools/git-ops.ts +773 -0
  263. package/src/tools/github-ops.ts +799 -0
  264. package/src/tools/helm-ops.ts +943 -0
  265. package/src/tools/index.ts +17 -0
  266. package/src/tools/k8s-ops.ts +819 -0
  267. package/src/tools/schemas/converter.ts +184 -0
  268. package/src/tools/schemas/devops.ts +612 -0
  269. package/src/tools/schemas/index.ts +73 -0
  270. package/src/tools/schemas/standard.ts +1144 -0
  271. package/src/tools/schemas/types.ts +705 -0
  272. package/src/tools/terraform-ops.ts +862 -0
  273. package/src/types/ambient.d.ts +193 -0
  274. package/src/types/config.ts +83 -0
  275. package/src/types/drift.ts +116 -0
  276. package/src/types/enterprise.ts +335 -0
  277. package/src/types/index.ts +20 -0
  278. package/src/types/plan.ts +44 -0
  279. package/src/types/request.ts +65 -0
  280. package/src/types/response.ts +54 -0
  281. package/src/types/service.ts +51 -0
  282. package/src/ui/App.tsx +997 -0
  283. package/src/ui/DeployPreview.tsx +169 -0
  284. package/src/ui/Header.tsx +68 -0
  285. package/src/ui/InputBox.tsx +350 -0
  286. package/src/ui/MessageList.tsx +585 -0
  287. package/src/ui/PermissionPrompt.tsx +151 -0
  288. package/src/ui/StatusBar.tsx +158 -0
  289. package/src/ui/ToolCallDisplay.tsx +409 -0
  290. package/src/ui/chat-ui.ts +853 -0
  291. package/src/ui/index.ts +33 -0
  292. package/src/ui/ink/index.ts +711 -0
  293. package/src/ui/streaming.ts +176 -0
  294. package/src/ui/types.ts +57 -0
  295. package/src/utils/analytics.ts +72 -0
  296. package/src/utils/cost-warning.ts +27 -0
  297. package/src/utils/env.ts +46 -0
  298. package/src/utils/errors.ts +69 -0
  299. package/src/utils/event-bus.ts +38 -0
  300. package/src/utils/index.ts +24 -0
  301. package/src/utils/logger.ts +171 -0
  302. package/src/utils/rate-limiter.ts +121 -0
  303. package/src/utils/service-auth.ts +49 -0
  304. package/src/utils/validation.ts +53 -0
  305. package/src/version.ts +4 -0
  306. package/src/watcher/index.ts +163 -0
  307. package/src/wizard/approval.ts +383 -0
  308. package/src/wizard/index.ts +25 -0
  309. package/src/wizard/prompts.ts +338 -0
  310. package/src/wizard/types.ts +171 -0
  311. package/src/wizard/ui.ts +556 -0
  312. package/src/wizard/wizard.ts +304 -0
  313. package/tsconfig.json +24 -0
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Cloud Cost Estimator
3
+ *
4
+ * Provides cost estimates for live cloud operations (EC2 start, RDS create,
5
+ * EKS create, etc.) so users see a cost warning before committing to
6
+ * billable actions.
7
+ *
8
+ * Pricing data is a simple static lookup table based on on-demand, us-east-1
9
+ * list prices. Monthly = hourly * 730. The goal is user awareness, not
10
+ * exact billing.
11
+ */
12
+
13
+ // Hours in a standard AWS billing month
14
+ const HOURS_PER_MONTH = 730;
15
+
16
+ // ------------------------------------------------------------------
17
+ // EC2 instance hourly pricing (on-demand, us-east-1, Linux)
18
+ // ------------------------------------------------------------------
19
+ const EC2_HOURLY: Record<string, number> = {
20
+ // T3 burstable
21
+ 't3.nano': 0.0052,
22
+ 't3.micro': 0.0104,
23
+ 't3.small': 0.0208,
24
+ 't3.medium': 0.0416,
25
+ 't3.large': 0.0832,
26
+ 't3.xlarge': 0.1664,
27
+ 't3.2xlarge': 0.3328,
28
+ // T3a (AMD)
29
+ 't3a.nano': 0.0047,
30
+ 't3a.micro': 0.0094,
31
+ 't3a.small': 0.0188,
32
+ 't3a.medium': 0.0376,
33
+ 't3a.large': 0.0752,
34
+ 't3a.xlarge': 0.1504,
35
+ // T2 burstable
36
+ 't2.nano': 0.0058,
37
+ 't2.micro': 0.0116,
38
+ 't2.small': 0.023,
39
+ 't2.medium': 0.0464,
40
+ 't2.large': 0.0928,
41
+ 't2.xlarge': 0.1856,
42
+ 't2.2xlarge': 0.3712,
43
+ // M5 general purpose
44
+ 'm5.large': 0.096,
45
+ 'm5.xlarge': 0.192,
46
+ 'm5.2xlarge': 0.384,
47
+ 'm5.4xlarge': 0.768,
48
+ // M6i general purpose
49
+ 'm6i.large': 0.096,
50
+ 'm6i.xlarge': 0.192,
51
+ 'm6i.2xlarge': 0.384,
52
+ // C5 compute optimized
53
+ 'c5.large': 0.085,
54
+ 'c5.xlarge': 0.17,
55
+ 'c5.2xlarge': 0.34,
56
+ 'c5.4xlarge': 0.68,
57
+ // R5 memory optimized
58
+ 'r5.large': 0.126,
59
+ 'r5.xlarge': 0.252,
60
+ 'r5.2xlarge': 0.504,
61
+ // GPU
62
+ 'p3.2xlarge': 3.06,
63
+ 'g4dn.xlarge': 0.526,
64
+ 'g4dn.2xlarge': 0.752,
65
+ };
66
+
67
+ // ------------------------------------------------------------------
68
+ // RDS instance hourly pricing (on-demand, us-east-1, Single-AZ)
69
+ // ------------------------------------------------------------------
70
+ const RDS_HOURLY: Record<string, number> = {
71
+ 'db.t3.micro': 0.017,
72
+ 'db.t3.small': 0.034,
73
+ 'db.t3.medium': 0.068,
74
+ 'db.t3.large': 0.136,
75
+ 'db.t3.xlarge': 0.272,
76
+ 'db.t4g.micro': 0.016,
77
+ 'db.t4g.small': 0.032,
78
+ 'db.t4g.medium': 0.065,
79
+ 'db.m5.large': 0.171,
80
+ 'db.m5.xlarge': 0.342,
81
+ 'db.m5.2xlarge': 0.684,
82
+ 'db.m6i.large': 0.171,
83
+ 'db.m6i.xlarge': 0.342,
84
+ 'db.r5.large': 0.24,
85
+ 'db.r5.xlarge': 0.48,
86
+ 'db.r5.2xlarge': 0.96,
87
+ 'db.r6i.large': 0.24,
88
+ 'db.r6i.xlarge': 0.48,
89
+ };
90
+
91
+ // ------------------------------------------------------------------
92
+ // Fixed hourly rates for managed services
93
+ // ------------------------------------------------------------------
94
+ const MANAGED_SERVICE_HOURLY: Record<string, number> = {
95
+ 'eks-cluster': 0.1,
96
+ 'nat-gateway': 0.045,
97
+ alb: 0.0225,
98
+ nlb: 0.0225,
99
+ 'vpn-gateway': 0.05,
100
+ 'elasticache-t3-medium': 0.068,
101
+ 'redshift-dc2-large': 0.25,
102
+ };
103
+
104
+ // ------------------------------------------------------------------
105
+ // Types
106
+ // ------------------------------------------------------------------
107
+
108
+ export type CloudOperation =
109
+ | 'ec2:StartInstances'
110
+ | 'ec2:RunInstances'
111
+ | 'rds:StartDBInstance'
112
+ | 'rds:CreateDBInstance'
113
+ | 'eks:CreateCluster'
114
+ | 'natgateway:Create'
115
+ | 'alb:Create'
116
+ | 'nlb:Create';
117
+
118
+ export interface CloudCostEstimate {
119
+ /** Estimated hourly cost in USD */
120
+ hourly: number;
121
+ /** Estimated monthly cost in USD (hourly * 730) */
122
+ monthly: number;
123
+ /** Human-readable description of the cost estimate */
124
+ description: string;
125
+ }
126
+
127
+ export interface CloudCostParams {
128
+ /** EC2 instance type (e.g. t3.micro) */
129
+ instanceType?: string;
130
+ /** RDS instance class (e.g. db.t3.micro) */
131
+ instanceClass?: string;
132
+ /** Number of instances / resources */
133
+ count?: number;
134
+ /** Whether RDS Multi-AZ is enabled (doubles compute cost) */
135
+ multiAz?: boolean;
136
+ }
137
+
138
+ // ------------------------------------------------------------------
139
+ // Main estimation function
140
+ // ------------------------------------------------------------------
141
+
142
+ /**
143
+ * Estimate the cost of a cloud operation.
144
+ *
145
+ * Returns null if the operation or resource type is not recognized.
146
+ */
147
+ export function estimateCloudCost(
148
+ operation: CloudOperation,
149
+ params: CloudCostParams = {}
150
+ ): CloudCostEstimate | null {
151
+ const count = params.count ?? 1;
152
+
153
+ switch (operation) {
154
+ case 'ec2:StartInstances':
155
+ case 'ec2:RunInstances': {
156
+ const type = params.instanceType || 't3.medium';
157
+ const hourlyPerUnit = EC2_HOURLY[type];
158
+ if (hourlyPerUnit === undefined) {
159
+ // Unknown type -- provide a generic estimate with a caveat
160
+ return {
161
+ hourly: 0.0416 * count,
162
+ monthly: 0.0416 * HOURS_PER_MONTH * count,
163
+ description: `EC2 ${type} x${count} (pricing unavailable, using t3.medium estimate)`,
164
+ };
165
+ }
166
+ const hourly = hourlyPerUnit * count;
167
+ return {
168
+ hourly,
169
+ monthly: hourly * HOURS_PER_MONTH,
170
+ description: `EC2 ${type}${count > 1 ? ` x${count}` : ''} on-demand`,
171
+ };
172
+ }
173
+
174
+ case 'rds:StartDBInstance':
175
+ case 'rds:CreateDBInstance': {
176
+ const cls = params.instanceClass || 'db.t3.medium';
177
+ const hourlyPerUnit = RDS_HOURLY[cls];
178
+ const multiAzMultiplier = params.multiAz ? 2 : 1;
179
+ if (hourlyPerUnit === undefined) {
180
+ const fallback = 0.068; // db.t3.medium default
181
+ const hourly = fallback * multiAzMultiplier * count;
182
+ return {
183
+ hourly,
184
+ monthly: hourly * HOURS_PER_MONTH,
185
+ description: `RDS ${cls}${params.multiAz ? ' Multi-AZ' : ''}${count > 1 ? ` x${count}` : ''} (pricing unavailable, using db.t3.medium estimate)`,
186
+ };
187
+ }
188
+ const hourly = hourlyPerUnit * multiAzMultiplier * count;
189
+ return {
190
+ hourly,
191
+ monthly: hourly * HOURS_PER_MONTH,
192
+ description: `RDS ${cls}${params.multiAz ? ' Multi-AZ' : ''}${count > 1 ? ` x${count}` : ''} on-demand`,
193
+ };
194
+ }
195
+
196
+ case 'eks:CreateCluster': {
197
+ const hourly = MANAGED_SERVICE_HOURLY['eks-cluster'] * count;
198
+ return {
199
+ hourly,
200
+ monthly: hourly * HOURS_PER_MONTH,
201
+ description: `EKS cluster control plane${count > 1 ? ` x${count}` : ''} ($0.10/hr fixed)`,
202
+ };
203
+ }
204
+
205
+ case 'natgateway:Create': {
206
+ const hourly = MANAGED_SERVICE_HOURLY['nat-gateway'] * count;
207
+ return {
208
+ hourly,
209
+ monthly: hourly * HOURS_PER_MONTH,
210
+ description: `NAT Gateway${count > 1 ? ` x${count}` : ''} ($0.045/hr + data processing charges)`,
211
+ };
212
+ }
213
+
214
+ case 'alb:Create': {
215
+ const hourly = MANAGED_SERVICE_HOURLY['alb'] * count;
216
+ return {
217
+ hourly,
218
+ monthly: hourly * HOURS_PER_MONTH,
219
+ description: `Application Load Balancer${count > 1 ? ` x${count}` : ''} ($0.0225/hr + LCU charges)`,
220
+ };
221
+ }
222
+
223
+ case 'nlb:Create': {
224
+ const hourly = MANAGED_SERVICE_HOURLY['nlb'] * count;
225
+ return {
226
+ hourly,
227
+ monthly: hourly * HOURS_PER_MONTH,
228
+ description: `Network Load Balancer${count > 1 ? ` x${count}` : ''} ($0.0225/hr + LCU charges)`,
229
+ };
230
+ }
231
+
232
+ default:
233
+ return null;
234
+ }
235
+ }
236
+
237
+ // ------------------------------------------------------------------
238
+ // Display helpers
239
+ // ------------------------------------------------------------------
240
+
241
+ /**
242
+ * Format a cost estimate into a human-readable warning string.
243
+ *
244
+ * Example output:
245
+ * "Estimated cost: ~$0.04/hour ($30.37/month) - EC2 t3.medium on-demand"
246
+ */
247
+ export function formatCostWarning(estimate: CloudCostEstimate): string {
248
+ const hourly =
249
+ estimate.hourly < 0.01 ? `$${estimate.hourly.toFixed(4)}` : `$${estimate.hourly.toFixed(2)}`;
250
+ const monthly = `$${estimate.monthly.toFixed(2)}`;
251
+ return `Estimated cost: ~${hourly}/hour (${monthly}/month) - ${estimate.description}`;
252
+ }
253
+
254
+ /**
255
+ * Resolve an EC2 instance type to its hourly cost, or undefined if unknown.
256
+ */
257
+ export function getEC2HourlyCost(instanceType: string): number | undefined {
258
+ return EC2_HOURLY[instanceType];
259
+ }
260
+
261
+ /**
262
+ * Resolve an RDS instance class to its hourly cost, or undefined if unknown.
263
+ */
264
+ export function getRDSHourlyCost(instanceClass: string): number | undefined {
265
+ return RDS_HOURLY[instanceClass];
266
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Built-in Cost Estimator
3
+ *
4
+ * Parses Terraform .tf files and estimates costs using a static pricing
5
+ * lookup table. This provides quick, offline cost estimates without
6
+ * requiring external tools like Infracost.
7
+ *
8
+ * For more accurate, real-time pricing, install Infracost.
9
+ */
10
+
11
+ import { TerraformParser } from './parsers/terraform';
12
+ import { getResourcePrice } from './pricing';
13
+ import type { CostEstimate, CostResource } from './index';
14
+
15
+ export class CostEstimator {
16
+ /**
17
+ * Estimate costs for a directory containing Terraform files.
18
+ *
19
+ * Reads all .tf files in the given directory, parses resource blocks,
20
+ * and looks up estimated pricing for each recognized resource type.
21
+ */
22
+ static async estimateDirectory(directory: string): Promise<CostEstimate> {
23
+ const parser = new TerraformParser();
24
+ const resources = await parser.parseDirectory(directory);
25
+
26
+ const costResources: CostResource[] = [];
27
+ const unsupportedTypes: Record<string, number> = {};
28
+
29
+ for (const resource of resources) {
30
+ const pricing = getResourcePrice(resource);
31
+ if (pricing) {
32
+ costResources.push({
33
+ name: `${resource.type}.${resource.name}`,
34
+ resourceType: resource.type,
35
+ monthlyCost: pricing.monthlyCost,
36
+ hourlyCost: pricing.hourlyCost,
37
+ monthlyQuantity: pricing.quantity,
38
+ unit: pricing.unit,
39
+ });
40
+ } else {
41
+ unsupportedTypes[resource.type] = (unsupportedTypes[resource.type] || 0) + 1;
42
+ }
43
+ }
44
+
45
+ const totalMonthlyCost = costResources.reduce((sum, r) => sum + r.monthlyCost, 0);
46
+ const totalHourlyCost = costResources.reduce((sum, r) => sum + (r.hourlyCost || 0), 0);
47
+
48
+ return {
49
+ version: '0.2',
50
+ currency: 'USD',
51
+ projects: [
52
+ {
53
+ name: directory.split('/').pop() || 'project',
54
+ metadata: { source: 'nimbus-builtin' },
55
+ pastTotalMonthlyCost: 0,
56
+ pastTotalHourlyCost: 0,
57
+ diffTotalMonthlyCost: 0,
58
+ diffTotalHourlyCost: 0,
59
+ totalMonthlyCost,
60
+ totalHourlyCost,
61
+ resources: costResources,
62
+ },
63
+ ],
64
+ totalMonthlyCost,
65
+ totalHourlyCost,
66
+ diffTotalMonthlyCost: 0,
67
+ timeGenerated: new Date().toISOString(),
68
+ summary: {
69
+ totalDetectedResources: resources.length,
70
+ totalSupportedResources: costResources.length,
71
+ totalUnsupportedResources: Object.values(unsupportedTypes).reduce((s, c) => s + c, 0),
72
+ totalUsageBasedResources: 0,
73
+ totalNoPriceResources: 0,
74
+ unsupportedResourceCounts: unsupportedTypes,
75
+ noPriceResourceCounts: {},
76
+ },
77
+ };
78
+ }
79
+ }