@build-astron-co/nimbus 0.3.0 → 0.4.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 (441) hide show
  1. package/bin/nimbus.cmd +41 -0
  2. package/bin/nimbus.mjs +70 -0
  3. package/completions/nimbus.bash +38 -0
  4. package/completions/nimbus.fish +48 -0
  5. package/completions/nimbus.zsh +81 -0
  6. package/dist/src/agent/compaction-agent.js +215 -0
  7. package/dist/src/agent/context-manager.js +385 -0
  8. package/dist/src/agent/context.js +322 -0
  9. package/dist/src/agent/deploy-preview.js +395 -0
  10. package/dist/src/agent/expand-files.js +95 -0
  11. package/dist/src/agent/index.js +18 -0
  12. package/dist/src/agent/loop.js +1535 -0
  13. package/dist/src/agent/modes.js +347 -0
  14. package/dist/src/agent/permissions.js +396 -0
  15. package/dist/src/agent/subagents/base.js +67 -0
  16. package/dist/src/agent/subagents/cost.js +45 -0
  17. package/dist/src/agent/subagents/explore.js +36 -0
  18. package/dist/src/agent/subagents/general.js +41 -0
  19. package/dist/src/agent/subagents/index.js +88 -0
  20. package/dist/src/agent/subagents/infra.js +52 -0
  21. package/dist/src/agent/subagents/security.js +60 -0
  22. package/dist/src/agent/system-prompt.js +860 -0
  23. package/dist/src/app.js +152 -0
  24. package/dist/src/audit/activity-log.js +209 -0
  25. package/dist/src/audit/compliance-checker.js +419 -0
  26. package/dist/src/audit/cost-tracker.js +231 -0
  27. package/dist/src/audit/index.js +10 -0
  28. package/dist/src/audit/security-scanner.js +490 -0
  29. package/dist/src/auth/guard.js +64 -0
  30. package/dist/src/auth/index.js +19 -0
  31. package/dist/src/auth/keychain.js +79 -0
  32. package/dist/src/auth/oauth.js +389 -0
  33. package/dist/src/auth/providers.js +415 -0
  34. package/dist/src/auth/sso.js +87 -0
  35. package/dist/src/auth/store.js +424 -0
  36. package/dist/src/auth/types.js +5 -0
  37. package/dist/src/cli/index.js +8 -0
  38. package/dist/src/cli/init.js +1048 -0
  39. package/dist/src/cli/openapi-spec.js +346 -0
  40. package/dist/src/cli/run.js +505 -0
  41. package/dist/src/cli/serve-auth.js +56 -0
  42. package/dist/src/cli/serve.js +432 -0
  43. package/dist/src/cli/web.js +50 -0
  44. package/dist/src/cli.js +1574 -0
  45. package/dist/src/clients/core-engine-client.js +156 -0
  46. package/dist/src/clients/enterprise-client.js +246 -0
  47. package/dist/src/clients/generator-client.js +219 -0
  48. package/dist/src/clients/git-client.js +367 -0
  49. package/dist/src/clients/github-client.js +229 -0
  50. package/dist/src/clients/helm-client.js +299 -0
  51. package/dist/src/clients/index.js +18 -0
  52. package/dist/src/clients/k8s-client.js +270 -0
  53. package/dist/src/clients/llm-client.js +119 -0
  54. package/dist/src/clients/rest-client.js +104 -0
  55. package/dist/src/clients/service-discovery.js +35 -0
  56. package/dist/src/clients/terraform-client.js +302 -0
  57. package/dist/src/clients/tools-client.js +1227 -0
  58. package/dist/src/clients/ws-client.js +93 -0
  59. package/dist/src/commands/alias.js +91 -0
  60. package/dist/src/commands/analyze/index.js +313 -0
  61. package/dist/src/commands/apply/helm.js +375 -0
  62. package/dist/src/commands/apply/index.js +176 -0
  63. package/dist/src/commands/apply/k8s.js +350 -0
  64. package/dist/src/commands/apply/terraform.js +465 -0
  65. package/dist/src/commands/ask.js +137 -0
  66. package/dist/src/commands/audit/index.js +322 -0
  67. package/dist/src/commands/auth-cloud.js +345 -0
  68. package/dist/src/commands/auth-list.js +112 -0
  69. package/dist/src/commands/auth-profile.js +104 -0
  70. package/dist/src/commands/auth-refresh.js +161 -0
  71. package/dist/src/commands/auth-status.js +122 -0
  72. package/dist/src/commands/aws/ec2.js +402 -0
  73. package/dist/src/commands/aws/iam.js +304 -0
  74. package/dist/src/commands/aws/index.js +108 -0
  75. package/dist/src/commands/aws/lambda.js +317 -0
  76. package/dist/src/commands/aws/rds.js +345 -0
  77. package/dist/src/commands/aws/s3.js +346 -0
  78. package/dist/src/commands/aws/vpc.js +302 -0
  79. package/dist/src/commands/aws-discover.js +413 -0
  80. package/dist/src/commands/aws-terraform.js +618 -0
  81. package/dist/src/commands/azure/aks.js +305 -0
  82. package/dist/src/commands/azure/functions.js +200 -0
  83. package/dist/src/commands/azure/index.js +93 -0
  84. package/dist/src/commands/azure/storage.js +378 -0
  85. package/dist/src/commands/azure/vm.js +291 -0
  86. package/dist/src/commands/billing/index.js +224 -0
  87. package/dist/src/commands/chat.js +259 -0
  88. package/dist/src/commands/completions.js +255 -0
  89. package/dist/src/commands/config.js +291 -0
  90. package/dist/src/commands/cost/cloud-cost-estimator.js +211 -0
  91. package/dist/src/commands/cost/estimator.js +73 -0
  92. package/dist/src/commands/cost/index.js +625 -0
  93. package/dist/src/commands/cost/parsers/terraform.js +234 -0
  94. package/dist/src/commands/cost/parsers/types.js +4 -0
  95. package/dist/src/commands/cost/pricing/aws.js +501 -0
  96. package/dist/src/commands/cost/pricing/azure.js +462 -0
  97. package/dist/src/commands/cost/pricing/gcp.js +359 -0
  98. package/dist/src/commands/cost/pricing/index.js +24 -0
  99. package/dist/src/commands/demo.js +196 -0
  100. package/dist/src/commands/deploy.js +215 -0
  101. package/dist/src/commands/doctor.js +1291 -0
  102. package/dist/src/commands/drift/index.js +674 -0
  103. package/dist/src/commands/explain.js +235 -0
  104. package/dist/src/commands/export.js +120 -0
  105. package/dist/src/commands/feedback.js +319 -0
  106. package/dist/src/commands/fix.js +263 -0
  107. package/dist/src/commands/fs/index.js +338 -0
  108. package/dist/src/commands/gcp/compute.js +266 -0
  109. package/dist/src/commands/gcp/functions.js +221 -0
  110. package/dist/src/commands/gcp/gke.js +357 -0
  111. package/dist/src/commands/gcp/iam.js +295 -0
  112. package/dist/src/commands/gcp/index.js +105 -0
  113. package/dist/src/commands/gcp/storage.js +232 -0
  114. package/dist/src/commands/generate-helm.js +1026 -0
  115. package/dist/src/commands/generate-k8s.js +1263 -0
  116. package/dist/src/commands/generate-terraform.js +1058 -0
  117. package/dist/src/commands/gh/index.js +663 -0
  118. package/dist/src/commands/git/index.js +1208 -0
  119. package/dist/src/commands/helm/index.js +985 -0
  120. package/dist/src/commands/help.js +639 -0
  121. package/dist/src/commands/history.js +120 -0
  122. package/dist/src/commands/import.js +782 -0
  123. package/dist/src/commands/incident.js +144 -0
  124. package/dist/src/commands/index.js +109 -0
  125. package/dist/src/commands/init.js +955 -0
  126. package/dist/src/commands/k8s/index.js +979 -0
  127. package/dist/src/commands/login.js +588 -0
  128. package/dist/src/commands/logout.js +61 -0
  129. package/dist/src/commands/logs.js +160 -0
  130. package/dist/src/commands/onboarding.js +382 -0
  131. package/dist/src/commands/pipeline.js +153 -0
  132. package/dist/src/commands/plan/display.js +216 -0
  133. package/dist/src/commands/plan/index.js +525 -0
  134. package/dist/src/commands/plugin.js +325 -0
  135. package/dist/src/commands/preview.js +356 -0
  136. package/dist/src/commands/profile.js +297 -0
  137. package/dist/src/commands/questionnaire.js +1021 -0
  138. package/dist/src/commands/resume.js +35 -0
  139. package/dist/src/commands/rollback.js +259 -0
  140. package/dist/src/commands/rollout.js +74 -0
  141. package/dist/src/commands/runbook.js +307 -0
  142. package/dist/src/commands/schedule.js +202 -0
  143. package/dist/src/commands/status.js +213 -0
  144. package/dist/src/commands/team/index.js +309 -0
  145. package/dist/src/commands/team-context.js +200 -0
  146. package/dist/src/commands/template.js +204 -0
  147. package/dist/src/commands/tf/index.js +989 -0
  148. package/dist/src/commands/upgrade.js +515 -0
  149. package/dist/src/commands/usage/index.js +118 -0
  150. package/dist/src/commands/version.js +145 -0
  151. package/dist/src/commands/watch.js +127 -0
  152. package/dist/src/compat/index.js +2 -0
  153. package/dist/src/compat/runtime.js +10 -0
  154. package/dist/src/compat/sqlite.js +144 -0
  155. package/dist/src/config/index.js +6 -0
  156. package/dist/src/config/manager.js +469 -0
  157. package/dist/src/config/mode-store.js +57 -0
  158. package/dist/src/config/profiles.js +66 -0
  159. package/dist/src/config/safety-policy.js +251 -0
  160. package/dist/src/config/schema.js +107 -0
  161. package/dist/src/config/types.js +311 -0
  162. package/dist/src/config/workspace-state.js +38 -0
  163. package/dist/src/context/context-db.js +138 -0
  164. package/dist/src/demo/index.js +295 -0
  165. package/dist/src/demo/scenarios/full-journey.js +226 -0
  166. package/dist/src/demo/scenarios/getting-started.js +124 -0
  167. package/dist/src/demo/scenarios/helm-release.js +334 -0
  168. package/dist/src/demo/scenarios/k8s-deployment.js +190 -0
  169. package/dist/src/demo/scenarios/terraform-vpc.js +167 -0
  170. package/dist/src/demo/types.js +6 -0
  171. package/dist/src/engine/cost-estimator.js +334 -0
  172. package/dist/src/engine/diagram-generator.js +192 -0
  173. package/dist/src/engine/drift-detector.js +688 -0
  174. package/dist/src/engine/executor.js +832 -0
  175. package/dist/src/engine/index.js +39 -0
  176. package/dist/src/engine/orchestrator.js +436 -0
  177. package/dist/src/engine/planner.js +616 -0
  178. package/dist/src/engine/safety.js +609 -0
  179. package/dist/src/engine/verifier.js +664 -0
  180. package/dist/src/enterprise/audit.js +241 -0
  181. package/dist/src/enterprise/auth.js +189 -0
  182. package/dist/src/enterprise/billing.js +512 -0
  183. package/dist/src/enterprise/index.js +16 -0
  184. package/dist/src/enterprise/teams.js +315 -0
  185. package/dist/src/generator/best-practices.js +1375 -0
  186. package/dist/src/generator/helm.js +495 -0
  187. package/dist/src/generator/index.js +11 -0
  188. package/dist/src/generator/intent-parser.js +420 -0
  189. package/dist/src/generator/kubernetes.js +773 -0
  190. package/dist/src/generator/terraform.js +1472 -0
  191. package/dist/src/history/index.js +6 -0
  192. package/dist/src/history/manager.js +199 -0
  193. package/dist/src/history/types.js +6 -0
  194. package/dist/src/hooks/config.js +318 -0
  195. package/dist/src/hooks/engine.js +317 -0
  196. package/dist/src/hooks/index.js +2 -0
  197. package/dist/src/llm/auth-bridge.js +157 -0
  198. package/dist/src/llm/circuit-breaker.js +116 -0
  199. package/dist/src/llm/config-loader.js +172 -0
  200. package/dist/src/llm/cost-calculator.js +137 -0
  201. package/dist/src/llm/index.js +7 -0
  202. package/dist/src/llm/model-aliases.js +99 -0
  203. package/dist/src/llm/provider-registry.js +57 -0
  204. package/dist/src/llm/providers/anthropic.js +430 -0
  205. package/dist/src/llm/providers/bedrock.js +409 -0
  206. package/dist/src/llm/providers/google.js +344 -0
  207. package/dist/src/llm/providers/ollama.js +661 -0
  208. package/dist/src/llm/providers/openai-compatible.js +289 -0
  209. package/dist/src/llm/providers/openai.js +284 -0
  210. package/dist/src/llm/providers/openrouter.js +293 -0
  211. package/dist/src/llm/router.js +844 -0
  212. package/dist/src/llm/types.js +69 -0
  213. package/dist/src/lsp/client.js +239 -0
  214. package/dist/src/lsp/languages.js +95 -0
  215. package/dist/src/lsp/manager.js +243 -0
  216. package/dist/src/mcp/client.js +289 -0
  217. package/dist/src/mcp/index.js +5 -0
  218. package/dist/src/mcp/manager.js +113 -0
  219. package/dist/src/nimbus.js +212 -0
  220. package/dist/src/plugins/index.js +13 -0
  221. package/dist/src/plugins/loader.js +280 -0
  222. package/dist/src/plugins/manager.js +282 -0
  223. package/dist/src/plugins/types.js +23 -0
  224. package/dist/src/scanners/cicd-scanner.js +230 -0
  225. package/dist/src/scanners/cloud-scanner.js +415 -0
  226. package/dist/src/scanners/framework-scanner.js +430 -0
  227. package/dist/src/scanners/iac-scanner.js +350 -0
  228. package/dist/src/scanners/index.js +454 -0
  229. package/dist/src/scanners/language-scanner.js +258 -0
  230. package/dist/src/scanners/package-manager-scanner.js +252 -0
  231. package/dist/src/scanners/types.js +6 -0
  232. package/dist/src/sessions/manager.js +395 -0
  233. package/dist/src/sessions/types.js +4 -0
  234. package/dist/src/sharing/sync.js +238 -0
  235. package/dist/src/sharing/viewer.js +131 -0
  236. package/dist/src/snapshots/index.js +1 -0
  237. package/dist/src/snapshots/manager.js +432 -0
  238. package/dist/src/state/artifacts.js +94 -0
  239. package/dist/src/state/audit.js +73 -0
  240. package/dist/src/state/billing.js +126 -0
  241. package/dist/src/state/checkpoints.js +81 -0
  242. package/dist/src/state/config.js +58 -0
  243. package/dist/src/state/conversations.js +7 -0
  244. package/dist/src/state/credentials.js +96 -0
  245. package/dist/src/state/db.js +53 -0
  246. package/dist/src/state/index.js +23 -0
  247. package/dist/src/state/messages.js +76 -0
  248. package/dist/src/state/projects.js +92 -0
  249. package/dist/src/state/schema.js +233 -0
  250. package/dist/src/state/sessions.js +79 -0
  251. package/dist/src/state/teams.js +131 -0
  252. package/dist/src/telemetry.js +91 -0
  253. package/dist/src/tools/aws-ops.js +747 -0
  254. package/dist/src/tools/azure-ops.js +491 -0
  255. package/dist/src/tools/file-ops.js +451 -0
  256. package/dist/src/tools/gcp-ops.js +559 -0
  257. package/dist/src/tools/git-ops.js +557 -0
  258. package/dist/src/tools/github-ops.js +460 -0
  259. package/dist/src/tools/helm-ops.js +634 -0
  260. package/dist/src/tools/index.js +16 -0
  261. package/dist/src/tools/k8s-ops.js +579 -0
  262. package/dist/src/tools/schemas/converter.js +129 -0
  263. package/dist/src/tools/schemas/devops.js +3319 -0
  264. package/dist/src/tools/schemas/index.js +19 -0
  265. package/dist/src/tools/schemas/standard.js +966 -0
  266. package/dist/src/tools/schemas/types.js +409 -0
  267. package/dist/src/tools/spawn-exec.js +109 -0
  268. package/dist/src/tools/terraform-ops.js +627 -0
  269. package/dist/src/types/config.js +1 -0
  270. package/dist/src/types/drift.js +4 -0
  271. package/dist/src/types/enterprise.js +5 -0
  272. package/dist/src/types/index.js +14 -0
  273. package/dist/src/types/plan.js +1 -0
  274. package/dist/src/types/request.js +1 -0
  275. package/dist/src/types/response.js +1 -0
  276. package/dist/src/types/service.js +1 -0
  277. package/dist/src/ui/App.js +1672 -0
  278. package/dist/src/ui/DeployPreview.js +60 -0
  279. package/dist/src/ui/FileDiffModal.js +108 -0
  280. package/dist/src/ui/Header.js +46 -0
  281. package/dist/src/ui/HelpModal.js +9 -0
  282. package/dist/src/ui/InputBox.js +408 -0
  283. package/dist/src/ui/MessageList.js +795 -0
  284. package/dist/src/ui/PermissionPrompt.js +72 -0
  285. package/dist/src/ui/StatusBar.js +109 -0
  286. package/dist/src/ui/TerminalPane.js +31 -0
  287. package/dist/src/ui/ToolCallDisplay.js +303 -0
  288. package/dist/src/ui/TreePane.js +83 -0
  289. package/dist/src/ui/chat-ui.js +721 -0
  290. package/dist/src/ui/index.js +11 -0
  291. package/dist/src/ui/ink/index.js +1325 -0
  292. package/dist/src/ui/streaming.js +137 -0
  293. package/dist/src/ui/theme.js +78 -0
  294. package/dist/src/ui/types.js +7 -0
  295. package/dist/src/utils/analytics.js +61 -0
  296. package/dist/src/utils/cost-warning.js +25 -0
  297. package/dist/src/utils/env.js +42 -0
  298. package/dist/src/utils/errors.js +54 -0
  299. package/dist/src/utils/event-bus.js +22 -0
  300. package/dist/src/utils/index.js +16 -0
  301. package/dist/src/utils/logger.js +150 -0
  302. package/dist/src/utils/rate-limiter.js +90 -0
  303. package/dist/src/utils/service-auth.js +36 -0
  304. package/dist/src/utils/validation.js +39 -0
  305. package/dist/src/version.js +3 -0
  306. package/dist/src/watcher/index.js +192 -0
  307. package/dist/src/wizard/approval.js +275 -0
  308. package/dist/src/wizard/index.js +13 -0
  309. package/dist/src/wizard/prompts.js +273 -0
  310. package/dist/src/wizard/types.js +4 -0
  311. package/dist/src/wizard/ui.js +453 -0
  312. package/dist/src/wizard/wizard.js +227 -0
  313. package/package.json +22 -15
  314. package/src/__tests__/alias.test.ts +133 -0
  315. package/src/__tests__/cli-run.test.ts +237 -1
  316. package/src/__tests__/compat-sqlite.test.ts +68 -0
  317. package/src/__tests__/context-manager.test.ts +130 -0
  318. package/src/__tests__/devops-terminal-gaps.test.ts +718 -0
  319. package/src/__tests__/doctor.test.ts +48 -0
  320. package/src/__tests__/export.test.ts +236 -0
  321. package/src/__tests__/gap-11-18-20.test.ts +958 -0
  322. package/src/__tests__/helm-streaming.test.ts +127 -0
  323. package/src/__tests__/incident.test.ts +179 -0
  324. package/src/__tests__/init.test.ts +54 -3
  325. package/src/__tests__/logs.test.ts +107 -0
  326. package/src/__tests__/loop-errors.test.ts +244 -0
  327. package/src/__tests__/perf-optimizations.test.ts +847 -0
  328. package/src/__tests__/pipeline.test.ts +50 -0
  329. package/src/__tests__/polish-phase3.test.ts +340 -0
  330. package/src/__tests__/profile.test.ts +237 -0
  331. package/src/__tests__/rollback.test.ts +83 -0
  332. package/src/__tests__/runbook.test.ts +219 -0
  333. package/src/__tests__/schedule.test.ts +206 -0
  334. package/src/__tests__/sessions.test.ts +95 -0
  335. package/src/__tests__/standalone-migration.test.ts +199 -0
  336. package/src/__tests__/status.test.ts +158 -0
  337. package/src/__tests__/stream-with-tools.test.ts +49 -1
  338. package/src/__tests__/system-prompt.test.ts +81 -2
  339. package/src/__tests__/terminal-gap-v2.test.ts +395 -0
  340. package/src/__tests__/terminal-parity.test.ts +393 -0
  341. package/src/__tests__/tf-apply.test.ts +187 -0
  342. package/src/__tests__/tool-schemas.test.ts +209 -4
  343. package/src/__tests__/version-json.test.ts +184 -0
  344. package/src/__tests__/watch.test.ts +129 -0
  345. package/src/agent/compaction-agent.ts +40 -1
  346. package/src/agent/context-manager.ts +67 -3
  347. package/src/agent/deploy-preview.ts +62 -1
  348. package/src/agent/expand-files.ts +108 -0
  349. package/src/agent/loop.ts +1312 -31
  350. package/src/agent/permissions.ts +51 -4
  351. package/src/agent/system-prompt.ts +573 -19
  352. package/src/app.ts +58 -0
  353. package/src/audit/security-scanner.ts +45 -0
  354. package/src/auth/keychain.ts +82 -0
  355. package/src/cli/init.ts +378 -5
  356. package/src/cli/run.ts +407 -16
  357. package/src/cli/serve.ts +78 -1
  358. package/src/cli/web.ts +10 -6
  359. package/src/cli.ts +312 -1
  360. package/src/clients/service-discovery.ts +30 -25
  361. package/src/commands/alias.ts +100 -0
  362. package/src/commands/audit/index.ts +121 -2
  363. package/src/commands/auth-cloud.ts +113 -0
  364. package/src/commands/auth-refresh.ts +187 -0
  365. package/src/commands/aws-discover.ts +144 -251
  366. package/src/commands/aws-terraform.ts +68 -118
  367. package/src/commands/chat.ts +9 -3
  368. package/src/commands/completions.ts +268 -0
  369. package/src/commands/config.ts +26 -0
  370. package/src/commands/cost/index.ts +218 -2
  371. package/src/commands/deploy.ts +260 -0
  372. package/src/commands/doctor.ts +744 -152
  373. package/src/commands/drift/index.ts +371 -23
  374. package/src/commands/export.ts +146 -0
  375. package/src/commands/generate-k8s.ts +9 -61
  376. package/src/commands/generate-terraform.ts +191 -449
  377. package/src/commands/help.ts +212 -36
  378. package/src/commands/history.ts +8 -1
  379. package/src/commands/incident.ts +166 -0
  380. package/src/commands/init.ts +5 -0
  381. package/src/commands/login.ts +86 -1
  382. package/src/commands/logs.ts +167 -0
  383. package/src/commands/onboarding.ts +211 -34
  384. package/src/commands/pipeline.ts +186 -0
  385. package/src/commands/plugin.ts +398 -0
  386. package/src/commands/profile.ts +342 -0
  387. package/src/commands/questionnaire.ts +0 -98
  388. package/src/commands/resume.ts +26 -34
  389. package/src/commands/rollback.ts +315 -0
  390. package/src/commands/rollout.ts +88 -0
  391. package/src/commands/runbook.ts +346 -0
  392. package/src/commands/schedule.ts +236 -0
  393. package/src/commands/status.ts +252 -0
  394. package/src/commands/team-context.ts +220 -0
  395. package/src/commands/template.ts +58 -57
  396. package/src/commands/tf/index.ts +70 -11
  397. package/src/commands/upgrade.ts +57 -0
  398. package/src/commands/version.ts +54 -50
  399. package/src/commands/watch.ts +153 -0
  400. package/src/compat/sqlite.ts +75 -5
  401. package/src/config/mode-store.ts +62 -0
  402. package/src/config/profiles.ts +84 -0
  403. package/src/config/types.ts +83 -1
  404. package/src/config/workspace-state.ts +53 -0
  405. package/src/engine/cost-estimator.ts +52 -10
  406. package/src/engine/executor.ts +33 -2
  407. package/src/engine/planner.ts +68 -1
  408. package/src/generator/terraform.ts +8 -0
  409. package/src/history/manager.ts +2 -74
  410. package/src/llm/cost-calculator.ts +2 -2
  411. package/src/llm/providers/anthropic.ts +50 -21
  412. package/src/llm/router.ts +76 -7
  413. package/src/lsp/languages.ts +3 -0
  414. package/src/lsp/manager.ts +20 -4
  415. package/src/nimbus.ts +34 -1
  416. package/src/sessions/manager.ts +108 -1
  417. package/src/sharing/viewer.ts +66 -0
  418. package/src/tools/file-ops.ts +22 -0
  419. package/src/tools/schemas/devops.ts +3007 -117
  420. package/src/tools/schemas/standard.ts +5 -1
  421. package/src/tools/schemas/types.ts +31 -1
  422. package/src/tools/spawn-exec.ts +148 -0
  423. package/src/ui/App.tsx +1183 -66
  424. package/src/ui/DeployPreview.tsx +62 -57
  425. package/src/ui/FileDiffModal.tsx +162 -0
  426. package/src/ui/Header.tsx +87 -24
  427. package/src/ui/HelpModal.tsx +57 -0
  428. package/src/ui/InputBox.tsx +163 -10
  429. package/src/ui/MessageList.tsx +487 -40
  430. package/src/ui/PermissionPrompt.tsx +17 -5
  431. package/src/ui/StatusBar.tsx +122 -3
  432. package/src/ui/TerminalPane.tsx +84 -0
  433. package/src/ui/ToolCallDisplay.tsx +252 -18
  434. package/src/ui/TreePane.tsx +132 -0
  435. package/src/ui/chat-ui.ts +41 -44
  436. package/src/ui/ink/index.ts +771 -38
  437. package/src/ui/theme.ts +104 -0
  438. package/src/ui/types.ts +18 -0
  439. package/src/version.ts +1 -1
  440. package/src/watcher/index.ts +66 -15
  441. package/src/wizard/types.ts +1 -0
@@ -0,0 +1,413 @@
1
+ /**
2
+ * AWS Discover Command
3
+ *
4
+ * Interactive and non-interactive AWS infrastructure discovery
5
+ *
6
+ * Usage: nimbus aws discover [options]
7
+ */
8
+ import { writeFile } from 'node:fs/promises';
9
+ import { execFileSync } from 'node:child_process';
10
+ import { logger } from '../utils';
11
+ import { createWizard, ui, select, multiSelect } from '../wizard';
12
+ // ---- CLI helpers ----
13
+ function cliGetAwsProfiles() {
14
+ try {
15
+ const out = execFileSync('aws', ['configure', 'list-profiles'], {
16
+ encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'],
17
+ });
18
+ return out.trim().split('\n').map(s => s.trim()).filter(Boolean);
19
+ }
20
+ catch {
21
+ return ['default'];
22
+ }
23
+ }
24
+ function cliValidateAwsProfile(profile) {
25
+ try {
26
+ const out = execFileSync('aws', ['sts', 'get-caller-identity', '--profile', profile, '--output', 'json'], {
27
+ encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'],
28
+ });
29
+ const data = JSON.parse(out);
30
+ return { valid: true, accountId: data.Account };
31
+ }
32
+ catch (e) {
33
+ return { valid: false, error: e.message?.slice(0, 100) };
34
+ }
35
+ }
36
+ function cliDiscoverResources(profile, regions, services) {
37
+ const env = { ...process.env, AWS_PROFILE: profile };
38
+ const resources = [];
39
+ const byType = {};
40
+ const byRegion = {};
41
+ const byService = {};
42
+ const allServices = services || ['EC2', 'S3', 'RDS', 'EKS'];
43
+ const addResources = (items) => {
44
+ for (const item of items) {
45
+ resources.push({ id: item.id, type: item.type, region: item.region, name: item.name, properties: {} });
46
+ byType[item.type] = (byType[item.type] ?? 0) + 1;
47
+ byRegion[item.region] = (byRegion[item.region] ?? 0) + 1;
48
+ const svc = item.type.split('::')[0] ?? item.type;
49
+ byService[svc] = (byService[svc] ?? 0) + 1;
50
+ }
51
+ };
52
+ const targetRegions = regions?.length ? regions : ['us-east-1'];
53
+ for (const region of targetRegions) {
54
+ const regionEnv = { ...env, AWS_DEFAULT_REGION: region };
55
+ if (!services || allServices.includes('EC2') || allServices.includes('all')) {
56
+ try {
57
+ const out = execFileSync('aws', ['ec2', 'describe-instances', '--query', 'Reservations[*].Instances[*].{id:InstanceId,name:Tags[?Key==`Name`].Value|[0]}', '--output', 'json'], { encoding: 'utf-8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'], env: regionEnv });
58
+ const instances = JSON.parse(out).flat();
59
+ addResources(instances.map((i) => ({ id: i.id, type: 'AWS::EC2::Instance', region, name: i.name })));
60
+ }
61
+ catch { /* skip */ }
62
+ }
63
+ if (!services || allServices.includes('RDS') || allServices.includes('all')) {
64
+ try {
65
+ const out = execFileSync('aws', ['rds', 'describe-db-instances', '--query', 'DBInstances[*].DBInstanceIdentifier', '--output', 'json'], { encoding: 'utf-8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'], env: regionEnv });
66
+ const dbs = JSON.parse(out);
67
+ addResources(dbs.map((id) => ({ id, type: 'AWS::RDS::DBInstance', region, name: id })));
68
+ }
69
+ catch { /* skip */ }
70
+ }
71
+ if (!services || allServices.includes('EKS') || allServices.includes('all')) {
72
+ try {
73
+ const out = execFileSync('aws', ['eks', 'list-clusters', '--output', 'json'], { encoding: 'utf-8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'], env: regionEnv });
74
+ const clusters = JSON.parse(out).clusters ?? [];
75
+ addResources(clusters.map((name) => ({ id: name, type: 'AWS::EKS::Cluster', region, name })));
76
+ }
77
+ catch { /* skip */ }
78
+ }
79
+ }
80
+ // S3 is global
81
+ if (!services || allServices.includes('S3') || allServices.includes('all')) {
82
+ try {
83
+ const out = execFileSync('aws', ['s3', 'ls'], { encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'], env });
84
+ const buckets = out.trim().split('\n').filter(Boolean).map(l => l.split(' ').pop());
85
+ addResources(buckets.map(name => ({ id: name, type: 'AWS::S3::Bucket', region: 'us-east-1', name })));
86
+ }
87
+ catch { /* skip */ }
88
+ }
89
+ return {
90
+ resources,
91
+ byType,
92
+ byRegion,
93
+ byService,
94
+ summary: {
95
+ totalResources: resources.length,
96
+ resourcesByService: byService,
97
+ resourcesByRegion: byRegion,
98
+ },
99
+ };
100
+ }
101
+ /**
102
+ * Run the AWS discover command
103
+ */
104
+ export async function awsDiscoverCommand(options = {}) {
105
+ logger.info('Starting AWS infrastructure discovery');
106
+ // Non-interactive mode
107
+ if (options.nonInteractive) {
108
+ return await runNonInteractive(options);
109
+ }
110
+ // Interactive wizard mode
111
+ const wizard = createWizard({
112
+ title: 'nimbus aws discover',
113
+ description: 'Discover AWS infrastructure resources',
114
+ initialContext: {
115
+ awsProfile: options.profile,
116
+ awsRegions: options.regions,
117
+ servicesToScan: options.services,
118
+ excludeServices: options.excludeServices,
119
+ },
120
+ steps: createWizardSteps(),
121
+ onEvent: event => {
122
+ logger.debug('Wizard event', { type: event.type });
123
+ },
124
+ });
125
+ const result = await wizard.run();
126
+ if (result.success && result.context.inventory) {
127
+ ui.newLine();
128
+ displayInventorySummary(result.context.inventory);
129
+ // Handle output options
130
+ if (options.outputFile) {
131
+ await saveInventory(result.context.inventory, options.outputFile, options.outputFormat || 'json');
132
+ }
133
+ return result.context.inventory;
134
+ }
135
+ else {
136
+ ui.error(`Discovery failed: ${result.error?.message || 'Unknown error'}`);
137
+ return null;
138
+ }
139
+ }
140
+ /**
141
+ * Create wizard steps
142
+ */
143
+ function createWizardSteps() {
144
+ return [
145
+ // Step 1: AWS Configuration
146
+ {
147
+ id: 'aws-config',
148
+ title: 'AWS Configuration',
149
+ description: 'Configure AWS profile and regions to scan',
150
+ execute: awsConfigStep,
151
+ },
152
+ // Step 2: Service Selection
153
+ {
154
+ id: 'services',
155
+ title: 'Service Selection',
156
+ description: 'Select which AWS services to scan',
157
+ execute: serviceSelectionStep,
158
+ },
159
+ // Step 3: Discovery
160
+ {
161
+ id: 'discovery',
162
+ title: 'Infrastructure Discovery',
163
+ description: 'Scanning your AWS infrastructure...',
164
+ execute: discoveryStep,
165
+ },
166
+ ];
167
+ }
168
+ /**
169
+ * Step 1: AWS Configuration
170
+ */
171
+ async function awsConfigStep(ctx) {
172
+ // Fetch available profiles via AWS CLI
173
+ ui.startSpinner({ message: 'Fetching AWS profiles...' });
174
+ const profileNames = cliGetAwsProfiles();
175
+ ui.stopSpinnerSuccess(`Found ${profileNames.length} AWS profile(s)`);
176
+ // Profile selection
177
+ let selectedProfile = ctx.awsProfile;
178
+ if (!selectedProfile) {
179
+ const profileOptions = profileNames.map(p => ({ value: p, label: p }));
180
+ selectedProfile = await select({
181
+ message: 'Select AWS profile:',
182
+ options: profileOptions,
183
+ defaultValue: 'default',
184
+ });
185
+ if (!selectedProfile) {
186
+ return { success: false, error: 'No profile selected' };
187
+ }
188
+ }
189
+ // Validate credentials via AWS CLI
190
+ ui.startSpinner({ message: `Validating credentials for profile "${selectedProfile}"...` });
191
+ const validation = cliValidateAwsProfile(selectedProfile);
192
+ if (!validation.valid) {
193
+ ui.stopSpinnerFail(`Invalid credentials: ${validation.error || 'Unknown error'}`);
194
+ return { success: false, error: 'Invalid AWS credentials' };
195
+ }
196
+ ui.stopSpinnerSuccess(`Authenticated to account ${validation.accountId || 'unknown'}`);
197
+ ctx.awsAccountId = validation.accountId;
198
+ // Region selection
199
+ ui.newLine();
200
+ const regionChoice = await select({
201
+ message: 'Select regions to scan:',
202
+ options: [
203
+ {
204
+ value: 'all',
205
+ label: 'All enabled regions',
206
+ description: 'Scan all regions enabled for your account',
207
+ },
208
+ {
209
+ value: 'specific',
210
+ label: 'Specific regions',
211
+ description: 'Select specific regions to scan',
212
+ },
213
+ ],
214
+ defaultValue: ctx.awsRegions?.length ? 'specific' : 'all',
215
+ });
216
+ let selectedRegions = ctx.awsRegions || [];
217
+ if (regionChoice === 'specific' && selectedRegions.length === 0) {
218
+ // Hardcoded common AWS regions (no service needed)
219
+ const regionOptions = [
220
+ { value: 'us-east-1', label: 'us-east-1 - N. Virginia' },
221
+ { value: 'us-east-2', label: 'us-east-2 - Ohio' },
222
+ { value: 'us-west-1', label: 'us-west-1 - N. California' },
223
+ { value: 'us-west-2', label: 'us-west-2 - Oregon' },
224
+ { value: 'eu-west-1', label: 'eu-west-1 - Ireland' },
225
+ { value: 'eu-central-1', label: 'eu-central-1 - Frankfurt' },
226
+ { value: 'ap-southeast-1', label: 'ap-southeast-1 - Singapore' },
227
+ { value: 'ap-northeast-1', label: 'ap-northeast-1 - Tokyo' },
228
+ ];
229
+ selectedRegions = (await multiSelect({
230
+ message: 'Select regions to scan:',
231
+ options: regionOptions,
232
+ required: true,
233
+ }));
234
+ }
235
+ return {
236
+ success: true,
237
+ data: {
238
+ awsProfile: selectedProfile,
239
+ awsRegions: regionChoice === 'all' ? undefined : selectedRegions,
240
+ },
241
+ };
242
+ }
243
+ /**
244
+ * Step 2: Service Selection
245
+ */
246
+ async function serviceSelectionStep(ctx) {
247
+ if (ctx.servicesToScan && ctx.servicesToScan.length > 0) {
248
+ // Services already specified
249
+ ui.info(`Services to scan: ${ctx.servicesToScan.join(', ')}`);
250
+ return { success: true, data: { servicesToScan: ctx.servicesToScan } };
251
+ }
252
+ const serviceChoice = await select({
253
+ message: 'Select services to scan:',
254
+ options: [
255
+ {
256
+ value: 'all',
257
+ label: 'All supported services',
258
+ description: 'EC2, S3, RDS, Lambda, VPC, IAM, ECS, EKS, DynamoDB, CloudFront',
259
+ },
260
+ {
261
+ value: 'specific',
262
+ label: 'Specific services',
263
+ description: 'Select specific services to scan',
264
+ },
265
+ ],
266
+ defaultValue: 'all',
267
+ });
268
+ if (serviceChoice === 'all') {
269
+ return { success: true, data: { servicesToScan: undefined } };
270
+ }
271
+ const serviceOptions = [
272
+ { value: 'EC2', label: 'EC2', description: 'Instances, volumes, security groups, AMIs' },
273
+ { value: 'S3', label: 'S3', description: 'Buckets and bucket policies' },
274
+ { value: 'RDS', label: 'RDS', description: 'Database instances and clusters' },
275
+ { value: 'Lambda', label: 'Lambda', description: 'Functions and layers' },
276
+ { value: 'VPC', label: 'VPC', description: 'VPCs, subnets, route tables, NAT gateways' },
277
+ { value: 'IAM', label: 'IAM', description: 'Roles, policies, users, groups' },
278
+ { value: 'ECS', label: 'ECS', description: 'Clusters, services, task definitions' },
279
+ { value: 'EKS', label: 'EKS', description: 'Clusters and node groups' },
280
+ { value: 'DynamoDB', label: 'DynamoDB', description: 'Tables' },
281
+ { value: 'CloudFront', label: 'CloudFront', description: 'Distributions' },
282
+ ];
283
+ const selectedServices = await multiSelect({
284
+ message: 'Select services to scan:',
285
+ options: serviceOptions,
286
+ required: true,
287
+ });
288
+ return {
289
+ success: true,
290
+ data: { servicesToScan: selectedServices },
291
+ };
292
+ }
293
+ /**
294
+ * Step 3: Discovery — uses AWS CLI directly (no REST service)
295
+ */
296
+ async function discoveryStep(ctx) {
297
+ ui.startSpinner({ message: 'Discovering AWS infrastructure via CLI...' });
298
+ try {
299
+ const inventory = cliDiscoverResources(ctx.awsProfile || 'default', ctx.awsRegions, ctx.servicesToScan);
300
+ ctx.inventory = inventory;
301
+ ui.stopSpinnerSuccess(`Discovery complete! Found ${inventory.resources.length} resource(s)`);
302
+ return { success: true, data: { inventory } };
303
+ }
304
+ catch (error) {
305
+ ui.stopSpinnerFail('Discovery failed');
306
+ return { success: false, error: error.message };
307
+ }
308
+ }
309
+ /**
310
+ * Build progress message
311
+ */
312
+ function buildProgressMessage(progress) {
313
+ const parts = [
314
+ ` Regions: ${progress.regionsScanned}/${progress.totalRegions}`,
315
+ `Services: ${progress.servicesScanned}/${progress.totalServices}`,
316
+ `Resources: ${progress.resourcesFound}`,
317
+ ];
318
+ if (progress.currentRegion && progress.currentService) {
319
+ parts.push(`Current: ${progress.currentRegion}/${progress.currentService}`);
320
+ }
321
+ else if (progress.currentRegion) {
322
+ parts.push(`Current: ${progress.currentRegion}`);
323
+ }
324
+ return parts.join(' | ');
325
+ }
326
+ /**
327
+ * Display inventory summary
328
+ */
329
+ function displayInventorySummary(inventory) {
330
+ ui.box({
331
+ title: 'Discovery Summary',
332
+ content: [
333
+ `Total Resources: ${inventory.resources.length}`,
334
+ '',
335
+ 'By Service:',
336
+ ...Object.entries(inventory.byService || {}).map(([service, count]) => ` ${service}: ${count}`),
337
+ '',
338
+ 'By Region:',
339
+ ...Object.entries(inventory.byRegion || {}).map(([region, count]) => ` ${region}: ${count}`),
340
+ ],
341
+ style: 'rounded',
342
+ borderColor: 'cyan',
343
+ padding: 1,
344
+ });
345
+ }
346
+ /**
347
+ * Save inventory to file
348
+ */
349
+ async function saveInventory(inventory, outputFile, format) {
350
+ let content;
351
+ if (format === 'json') {
352
+ content = JSON.stringify(inventory, null, 2);
353
+ }
354
+ else if (format === 'summary') {
355
+ content = [
356
+ `# AWS Infrastructure Discovery Summary`,
357
+ ``,
358
+ `Total Resources: ${inventory.resources.length}`,
359
+ ``,
360
+ `## By Service`,
361
+ ...Object.entries(inventory.byService || {}).map(([service, count]) => `- ${service}: ${count}`),
362
+ ``,
363
+ `## By Region`,
364
+ ...Object.entries(inventory.byRegion || {}).map(([region, count]) => `- ${region}: ${count}`),
365
+ ].join('\n');
366
+ }
367
+ else {
368
+ // Table format - CSV-like
369
+ const headers = ['ID', 'Type', 'Region', 'Name'];
370
+ const rows = inventory.resources.map(r => [r.id, r.type, r.region, r.name || '']);
371
+ content = [headers.join(','), ...rows.map(r => r.join(','))].join('\n');
372
+ }
373
+ await writeFile(outputFile, content, 'utf-8');
374
+ ui.success(`Inventory saved to ${outputFile}`);
375
+ }
376
+ /**
377
+ * Run in non-interactive mode
378
+ */
379
+ async function runNonInteractive(options) {
380
+ ui.header('nimbus aws discover', 'Non-interactive mode');
381
+ // Validate required options
382
+ if (!options.profile) {
383
+ ui.error('Profile is required in non-interactive mode (--profile)');
384
+ process.exit(1);
385
+ }
386
+ ui.info(`Using profile: ${options.profile}`);
387
+ ui.info(`Regions: ${options.regions?.join(', ') || 'all'}`);
388
+ ui.info(`Services: ${options.services?.join(', ') || 'all'}`);
389
+ // Validate credentials via AWS CLI
390
+ ui.startSpinner({ message: 'Validating credentials...' });
391
+ const validation = cliValidateAwsProfile(options.profile);
392
+ if (!validation.valid) {
393
+ ui.stopSpinnerFail(`Invalid credentials: ${validation.error || 'Unknown error'}`);
394
+ return null;
395
+ }
396
+ ui.stopSpinnerSuccess(`Authenticated to account ${validation.accountId || 'unknown'}`);
397
+ // Discover via AWS CLI
398
+ ui.startSpinner({ message: 'Discovering infrastructure...' });
399
+ try {
400
+ const inventory = cliDiscoverResources(options.profile, options.regions, options.services);
401
+ ui.stopSpinnerSuccess(`Discovery complete! Found ${inventory.resources.length} resource(s)`);
402
+ displayInventorySummary(inventory);
403
+ if (options.outputFile) {
404
+ await saveInventory(inventory, options.outputFile, options.outputFormat || 'json');
405
+ }
406
+ return inventory;
407
+ }
408
+ catch (error) {
409
+ ui.stopSpinnerFail(`Discovery failed: ${error.message}`);
410
+ return null;
411
+ }
412
+ }
413
+ export default awsDiscoverCommand;