@build-astron-co/nimbus 0.2.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 (469) hide show
  1. package/bin/nimbus +26 -10
  2. package/bin/nimbus.cmd +41 -0
  3. package/bin/nimbus.mjs +70 -0
  4. package/completions/nimbus.bash +38 -0
  5. package/completions/nimbus.fish +48 -0
  6. package/completions/nimbus.zsh +81 -0
  7. package/dist/src/agent/compaction-agent.js +215 -0
  8. package/dist/src/agent/context-manager.js +385 -0
  9. package/dist/src/agent/context.js +322 -0
  10. package/dist/src/agent/deploy-preview.js +395 -0
  11. package/dist/src/agent/expand-files.js +95 -0
  12. package/dist/src/agent/index.js +18 -0
  13. package/dist/src/agent/loop.js +1535 -0
  14. package/dist/src/agent/modes.js +347 -0
  15. package/dist/src/agent/permissions.js +396 -0
  16. package/dist/src/agent/subagents/base.js +67 -0
  17. package/dist/src/agent/subagents/cost.js +45 -0
  18. package/dist/src/agent/subagents/explore.js +36 -0
  19. package/dist/src/agent/subagents/general.js +41 -0
  20. package/dist/src/agent/subagents/index.js +88 -0
  21. package/dist/src/agent/subagents/infra.js +52 -0
  22. package/dist/src/agent/subagents/security.js +60 -0
  23. package/dist/src/agent/system-prompt.js +860 -0
  24. package/dist/src/app.js +152 -0
  25. package/dist/src/audit/activity-log.js +209 -0
  26. package/dist/src/audit/compliance-checker.js +419 -0
  27. package/dist/src/audit/cost-tracker.js +231 -0
  28. package/dist/src/audit/index.js +10 -0
  29. package/dist/src/audit/security-scanner.js +490 -0
  30. package/dist/src/auth/guard.js +64 -0
  31. package/dist/src/auth/index.js +19 -0
  32. package/dist/src/auth/keychain.js +79 -0
  33. package/dist/src/auth/oauth.js +389 -0
  34. package/dist/src/auth/providers.js +415 -0
  35. package/dist/src/auth/sso.js +87 -0
  36. package/dist/src/auth/store.js +424 -0
  37. package/dist/src/auth/types.js +5 -0
  38. package/dist/src/cli/index.js +8 -0
  39. package/dist/src/cli/init.js +1048 -0
  40. package/dist/src/cli/openapi-spec.js +346 -0
  41. package/dist/src/cli/run.js +505 -0
  42. package/dist/src/cli/serve-auth.js +56 -0
  43. package/dist/src/cli/serve.js +432 -0
  44. package/dist/src/cli/web.js +50 -0
  45. package/dist/src/cli.js +1574 -0
  46. package/dist/src/clients/core-engine-client.js +156 -0
  47. package/dist/src/clients/enterprise-client.js +246 -0
  48. package/dist/src/clients/generator-client.js +219 -0
  49. package/dist/src/clients/git-client.js +367 -0
  50. package/dist/src/clients/github-client.js +229 -0
  51. package/dist/src/clients/helm-client.js +299 -0
  52. package/dist/src/clients/index.js +18 -0
  53. package/dist/src/clients/k8s-client.js +270 -0
  54. package/dist/src/clients/llm-client.js +119 -0
  55. package/dist/src/clients/rest-client.js +104 -0
  56. package/dist/src/clients/service-discovery.js +35 -0
  57. package/dist/src/clients/terraform-client.js +302 -0
  58. package/dist/src/clients/tools-client.js +1227 -0
  59. package/dist/src/clients/ws-client.js +93 -0
  60. package/dist/src/commands/alias.js +91 -0
  61. package/dist/src/commands/analyze/index.js +313 -0
  62. package/dist/src/commands/apply/helm.js +375 -0
  63. package/dist/src/commands/apply/index.js +176 -0
  64. package/dist/src/commands/apply/k8s.js +350 -0
  65. package/dist/src/commands/apply/terraform.js +465 -0
  66. package/dist/src/commands/ask.js +137 -0
  67. package/dist/src/commands/audit/index.js +322 -0
  68. package/dist/src/commands/auth-cloud.js +345 -0
  69. package/dist/src/commands/auth-list.js +112 -0
  70. package/dist/src/commands/auth-profile.js +104 -0
  71. package/dist/src/commands/auth-refresh.js +161 -0
  72. package/dist/src/commands/auth-status.js +122 -0
  73. package/dist/src/commands/aws/ec2.js +402 -0
  74. package/dist/src/commands/aws/iam.js +304 -0
  75. package/dist/src/commands/aws/index.js +108 -0
  76. package/dist/src/commands/aws/lambda.js +317 -0
  77. package/dist/src/commands/aws/rds.js +345 -0
  78. package/dist/src/commands/aws/s3.js +346 -0
  79. package/dist/src/commands/aws/vpc.js +302 -0
  80. package/dist/src/commands/aws-discover.js +413 -0
  81. package/dist/src/commands/aws-terraform.js +618 -0
  82. package/dist/src/commands/azure/aks.js +305 -0
  83. package/dist/src/commands/azure/functions.js +200 -0
  84. package/dist/src/commands/azure/index.js +93 -0
  85. package/dist/src/commands/azure/storage.js +378 -0
  86. package/dist/src/commands/azure/vm.js +291 -0
  87. package/dist/src/commands/billing/index.js +224 -0
  88. package/dist/src/commands/chat.js +259 -0
  89. package/dist/src/commands/completions.js +255 -0
  90. package/dist/src/commands/config.js +291 -0
  91. package/dist/src/commands/cost/cloud-cost-estimator.js +211 -0
  92. package/dist/src/commands/cost/estimator.js +73 -0
  93. package/dist/src/commands/cost/index.js +625 -0
  94. package/dist/src/commands/cost/parsers/terraform.js +234 -0
  95. package/dist/src/commands/cost/parsers/types.js +4 -0
  96. package/dist/src/commands/cost/pricing/aws.js +501 -0
  97. package/dist/src/commands/cost/pricing/azure.js +462 -0
  98. package/dist/src/commands/cost/pricing/gcp.js +359 -0
  99. package/dist/src/commands/cost/pricing/index.js +24 -0
  100. package/dist/src/commands/demo.js +196 -0
  101. package/dist/src/commands/deploy.js +215 -0
  102. package/dist/src/commands/doctor.js +1291 -0
  103. package/dist/src/commands/drift/index.js +674 -0
  104. package/dist/src/commands/explain.js +235 -0
  105. package/dist/src/commands/export.js +120 -0
  106. package/dist/src/commands/feedback.js +319 -0
  107. package/dist/src/commands/fix.js +263 -0
  108. package/dist/src/commands/fs/index.js +338 -0
  109. package/dist/src/commands/gcp/compute.js +266 -0
  110. package/dist/src/commands/gcp/functions.js +221 -0
  111. package/dist/src/commands/gcp/gke.js +357 -0
  112. package/dist/src/commands/gcp/iam.js +295 -0
  113. package/dist/src/commands/gcp/index.js +105 -0
  114. package/dist/src/commands/gcp/storage.js +232 -0
  115. package/dist/src/commands/generate-helm.js +1026 -0
  116. package/dist/src/commands/generate-k8s.js +1263 -0
  117. package/dist/src/commands/generate-terraform.js +1058 -0
  118. package/dist/src/commands/gh/index.js +663 -0
  119. package/dist/src/commands/git/index.js +1208 -0
  120. package/dist/src/commands/helm/index.js +985 -0
  121. package/dist/src/commands/help.js +639 -0
  122. package/dist/src/commands/history.js +120 -0
  123. package/dist/src/commands/import.js +782 -0
  124. package/dist/src/commands/incident.js +144 -0
  125. package/dist/src/commands/index.js +109 -0
  126. package/dist/src/commands/init.js +955 -0
  127. package/dist/src/commands/k8s/index.js +979 -0
  128. package/dist/src/commands/login.js +588 -0
  129. package/dist/src/commands/logout.js +61 -0
  130. package/dist/src/commands/logs.js +160 -0
  131. package/dist/src/commands/onboarding.js +382 -0
  132. package/dist/src/commands/pipeline.js +153 -0
  133. package/dist/src/commands/plan/display.js +216 -0
  134. package/dist/src/commands/plan/index.js +525 -0
  135. package/dist/src/commands/plugin.js +325 -0
  136. package/dist/src/commands/preview.js +356 -0
  137. package/dist/src/commands/profile.js +297 -0
  138. package/dist/src/commands/questionnaire.js +1021 -0
  139. package/dist/src/commands/resume.js +35 -0
  140. package/dist/src/commands/rollback.js +259 -0
  141. package/dist/src/commands/rollout.js +74 -0
  142. package/dist/src/commands/runbook.js +307 -0
  143. package/dist/src/commands/schedule.js +202 -0
  144. package/dist/src/commands/status.js +213 -0
  145. package/dist/src/commands/team/index.js +309 -0
  146. package/dist/src/commands/team-context.js +200 -0
  147. package/dist/src/commands/template.js +204 -0
  148. package/dist/src/commands/tf/index.js +989 -0
  149. package/dist/src/commands/upgrade.js +515 -0
  150. package/dist/src/commands/usage/index.js +118 -0
  151. package/dist/src/commands/version.js +145 -0
  152. package/dist/src/commands/watch.js +127 -0
  153. package/dist/src/compat/index.js +2 -0
  154. package/dist/src/compat/runtime.js +10 -0
  155. package/dist/src/compat/sqlite.js +144 -0
  156. package/dist/src/config/index.js +6 -0
  157. package/dist/src/config/manager.js +469 -0
  158. package/dist/src/config/mode-store.js +57 -0
  159. package/dist/src/config/profiles.js +66 -0
  160. package/dist/src/config/safety-policy.js +251 -0
  161. package/dist/src/config/schema.js +107 -0
  162. package/dist/src/config/types.js +311 -0
  163. package/dist/src/config/workspace-state.js +38 -0
  164. package/dist/src/context/context-db.js +138 -0
  165. package/dist/src/demo/index.js +295 -0
  166. package/dist/src/demo/scenarios/full-journey.js +226 -0
  167. package/dist/src/demo/scenarios/getting-started.js +124 -0
  168. package/dist/src/demo/scenarios/helm-release.js +334 -0
  169. package/dist/src/demo/scenarios/k8s-deployment.js +190 -0
  170. package/dist/src/demo/scenarios/terraform-vpc.js +167 -0
  171. package/dist/src/demo/types.js +6 -0
  172. package/dist/src/engine/cost-estimator.js +334 -0
  173. package/dist/src/engine/diagram-generator.js +192 -0
  174. package/dist/src/engine/drift-detector.js +688 -0
  175. package/dist/src/engine/executor.js +832 -0
  176. package/dist/src/engine/index.js +39 -0
  177. package/dist/src/engine/orchestrator.js +436 -0
  178. package/dist/src/engine/planner.js +616 -0
  179. package/dist/src/engine/safety.js +609 -0
  180. package/dist/src/engine/verifier.js +664 -0
  181. package/dist/src/enterprise/audit.js +241 -0
  182. package/dist/src/enterprise/auth.js +189 -0
  183. package/dist/src/enterprise/billing.js +512 -0
  184. package/dist/src/enterprise/index.js +16 -0
  185. package/dist/src/enterprise/teams.js +315 -0
  186. package/dist/src/generator/best-practices.js +1375 -0
  187. package/dist/src/generator/helm.js +495 -0
  188. package/dist/src/generator/index.js +11 -0
  189. package/dist/src/generator/intent-parser.js +420 -0
  190. package/dist/src/generator/kubernetes.js +773 -0
  191. package/dist/src/generator/terraform.js +1472 -0
  192. package/dist/src/history/index.js +6 -0
  193. package/dist/src/history/manager.js +199 -0
  194. package/dist/src/history/types.js +6 -0
  195. package/dist/src/hooks/config.js +318 -0
  196. package/dist/src/hooks/engine.js +317 -0
  197. package/dist/src/hooks/index.js +2 -0
  198. package/dist/src/llm/auth-bridge.js +157 -0
  199. package/dist/src/llm/circuit-breaker.js +116 -0
  200. package/dist/src/llm/config-loader.js +172 -0
  201. package/dist/src/llm/cost-calculator.js +137 -0
  202. package/dist/src/llm/index.js +7 -0
  203. package/dist/src/llm/model-aliases.js +99 -0
  204. package/dist/src/llm/provider-registry.js +57 -0
  205. package/dist/src/llm/providers/anthropic.js +430 -0
  206. package/dist/src/llm/providers/bedrock.js +409 -0
  207. package/dist/src/llm/providers/google.js +344 -0
  208. package/dist/src/llm/providers/ollama.js +661 -0
  209. package/dist/src/llm/providers/openai-compatible.js +289 -0
  210. package/dist/src/llm/providers/openai.js +284 -0
  211. package/dist/src/llm/providers/openrouter.js +293 -0
  212. package/dist/src/llm/router.js +844 -0
  213. package/dist/src/llm/types.js +69 -0
  214. package/dist/src/lsp/client.js +239 -0
  215. package/dist/src/lsp/languages.js +95 -0
  216. package/dist/src/lsp/manager.js +243 -0
  217. package/dist/src/mcp/client.js +289 -0
  218. package/dist/src/mcp/index.js +5 -0
  219. package/dist/src/mcp/manager.js +113 -0
  220. package/dist/src/nimbus.js +212 -0
  221. package/dist/src/plugins/index.js +13 -0
  222. package/dist/src/plugins/loader.js +280 -0
  223. package/dist/src/plugins/manager.js +282 -0
  224. package/dist/src/plugins/types.js +23 -0
  225. package/dist/src/scanners/cicd-scanner.js +230 -0
  226. package/dist/src/scanners/cloud-scanner.js +415 -0
  227. package/dist/src/scanners/framework-scanner.js +430 -0
  228. package/dist/src/scanners/iac-scanner.js +350 -0
  229. package/dist/src/scanners/index.js +454 -0
  230. package/dist/src/scanners/language-scanner.js +258 -0
  231. package/dist/src/scanners/package-manager-scanner.js +252 -0
  232. package/dist/src/scanners/types.js +6 -0
  233. package/dist/src/sessions/manager.js +395 -0
  234. package/dist/src/sessions/types.js +4 -0
  235. package/dist/src/sharing/sync.js +238 -0
  236. package/dist/src/sharing/viewer.js +131 -0
  237. package/dist/src/snapshots/index.js +1 -0
  238. package/dist/src/snapshots/manager.js +432 -0
  239. package/dist/src/state/artifacts.js +94 -0
  240. package/dist/src/state/audit.js +73 -0
  241. package/dist/src/state/billing.js +126 -0
  242. package/dist/src/state/checkpoints.js +81 -0
  243. package/dist/src/state/config.js +58 -0
  244. package/dist/src/state/conversations.js +7 -0
  245. package/dist/src/state/credentials.js +96 -0
  246. package/dist/src/state/db.js +53 -0
  247. package/dist/src/state/index.js +23 -0
  248. package/dist/src/state/messages.js +76 -0
  249. package/dist/src/state/projects.js +92 -0
  250. package/dist/src/state/schema.js +233 -0
  251. package/dist/src/state/sessions.js +79 -0
  252. package/dist/src/state/teams.js +131 -0
  253. package/dist/src/telemetry.js +91 -0
  254. package/dist/src/tools/aws-ops.js +747 -0
  255. package/dist/src/tools/azure-ops.js +491 -0
  256. package/dist/src/tools/file-ops.js +451 -0
  257. package/dist/src/tools/gcp-ops.js +559 -0
  258. package/dist/src/tools/git-ops.js +557 -0
  259. package/dist/src/tools/github-ops.js +460 -0
  260. package/dist/src/tools/helm-ops.js +634 -0
  261. package/dist/src/tools/index.js +16 -0
  262. package/dist/src/tools/k8s-ops.js +579 -0
  263. package/dist/src/tools/schemas/converter.js +129 -0
  264. package/dist/src/tools/schemas/devops.js +3319 -0
  265. package/dist/src/tools/schemas/index.js +19 -0
  266. package/dist/src/tools/schemas/standard.js +966 -0
  267. package/dist/src/tools/schemas/types.js +409 -0
  268. package/dist/src/tools/spawn-exec.js +109 -0
  269. package/dist/src/tools/terraform-ops.js +627 -0
  270. package/dist/src/types/config.js +1 -0
  271. package/dist/src/types/drift.js +4 -0
  272. package/dist/src/types/enterprise.js +5 -0
  273. package/dist/src/types/index.js +14 -0
  274. package/dist/src/types/plan.js +1 -0
  275. package/dist/src/types/request.js +1 -0
  276. package/dist/src/types/response.js +1 -0
  277. package/dist/src/types/service.js +1 -0
  278. package/dist/src/ui/App.js +1672 -0
  279. package/dist/src/ui/DeployPreview.js +60 -0
  280. package/dist/src/ui/FileDiffModal.js +108 -0
  281. package/dist/src/ui/Header.js +46 -0
  282. package/dist/src/ui/HelpModal.js +9 -0
  283. package/dist/src/ui/InputBox.js +408 -0
  284. package/dist/src/ui/MessageList.js +795 -0
  285. package/dist/src/ui/PermissionPrompt.js +72 -0
  286. package/dist/src/ui/StatusBar.js +109 -0
  287. package/dist/src/ui/TerminalPane.js +31 -0
  288. package/dist/src/ui/ToolCallDisplay.js +303 -0
  289. package/dist/src/ui/TreePane.js +83 -0
  290. package/dist/src/ui/chat-ui.js +721 -0
  291. package/dist/src/ui/index.js +11 -0
  292. package/dist/src/ui/ink/index.js +1325 -0
  293. package/dist/src/ui/streaming.js +137 -0
  294. package/dist/src/ui/theme.js +78 -0
  295. package/dist/src/ui/types.js +7 -0
  296. package/dist/src/utils/analytics.js +61 -0
  297. package/dist/src/utils/cost-warning.js +25 -0
  298. package/dist/src/utils/env.js +42 -0
  299. package/dist/src/utils/errors.js +54 -0
  300. package/dist/src/utils/event-bus.js +22 -0
  301. package/dist/src/utils/index.js +16 -0
  302. package/dist/src/utils/logger.js +150 -0
  303. package/dist/src/utils/rate-limiter.js +90 -0
  304. package/dist/src/utils/service-auth.js +36 -0
  305. package/dist/src/utils/validation.js +39 -0
  306. package/dist/src/version.js +3 -0
  307. package/dist/src/watcher/index.js +192 -0
  308. package/dist/src/wizard/approval.js +275 -0
  309. package/dist/src/wizard/index.js +13 -0
  310. package/dist/src/wizard/prompts.js +273 -0
  311. package/dist/src/wizard/types.js +4 -0
  312. package/dist/src/wizard/ui.js +453 -0
  313. package/dist/src/wizard/wizard.js +227 -0
  314. package/package.json +31 -23
  315. package/src/__tests__/alias.test.ts +133 -0
  316. package/src/__tests__/app.test.ts +1 -1
  317. package/src/__tests__/audit.test.ts +1 -1
  318. package/src/__tests__/circuit-breaker.test.ts +1 -1
  319. package/src/__tests__/cli-run.test.ts +237 -1
  320. package/src/__tests__/compat-sqlite.test.ts +68 -0
  321. package/src/__tests__/context-manager.test.ts +131 -1
  322. package/src/__tests__/context.test.ts +1 -1
  323. package/src/__tests__/devops-terminal-gaps.test.ts +718 -0
  324. package/src/__tests__/doctor.test.ts +48 -0
  325. package/src/__tests__/enterprise.test.ts +1 -1
  326. package/src/__tests__/export.test.ts +236 -0
  327. package/src/__tests__/gap-11-18-20.test.ts +958 -0
  328. package/src/__tests__/generator.test.ts +1 -1
  329. package/src/__tests__/helm-streaming.test.ts +127 -0
  330. package/src/__tests__/hooks.test.ts +1 -1
  331. package/src/__tests__/incident.test.ts +179 -0
  332. package/src/__tests__/init.test.ts +55 -4
  333. package/src/__tests__/intent-parser.test.ts +1 -1
  334. package/src/__tests__/llm-router.test.ts +1 -1
  335. package/src/__tests__/logs.test.ts +107 -0
  336. package/src/__tests__/loop-errors.test.ts +244 -0
  337. package/src/__tests__/lsp.test.ts +1 -1
  338. package/src/__tests__/modes.test.ts +1 -1
  339. package/src/__tests__/perf-optimizations.test.ts +847 -0
  340. package/src/__tests__/permissions.test.ts +1 -1
  341. package/src/__tests__/pipeline.test.ts +50 -0
  342. package/src/__tests__/polish-phase3.test.ts +340 -0
  343. package/src/__tests__/profile.test.ts +237 -0
  344. package/src/__tests__/rollback.test.ts +83 -0
  345. package/src/__tests__/runbook.test.ts +219 -0
  346. package/src/__tests__/schedule.test.ts +206 -0
  347. package/src/__tests__/serve.test.ts +1 -1
  348. package/src/__tests__/sessions.test.ts +96 -1
  349. package/src/__tests__/sharing.test.ts +53 -1
  350. package/src/__tests__/snapshots.test.ts +1 -1
  351. package/src/__tests__/standalone-migration.test.ts +199 -0
  352. package/src/__tests__/state-db.test.ts +1 -1
  353. package/src/__tests__/status.test.ts +158 -0
  354. package/src/__tests__/stream-with-tools.test.ts +71 -25
  355. package/src/__tests__/subagents.test.ts +1 -1
  356. package/src/__tests__/system-prompt.test.ts +82 -3
  357. package/src/__tests__/terminal-gap-v2.test.ts +395 -0
  358. package/src/__tests__/terminal-parity.test.ts +393 -0
  359. package/src/__tests__/tf-apply.test.ts +187 -0
  360. package/src/__tests__/tool-converter.test.ts +1 -1
  361. package/src/__tests__/tool-schemas.test.ts +209 -4
  362. package/src/__tests__/tools.test.ts +4 -3
  363. package/src/__tests__/version-json.test.ts +184 -0
  364. package/src/__tests__/version.test.ts +1 -1
  365. package/src/__tests__/watch.test.ts +129 -0
  366. package/src/agent/compaction-agent.ts +40 -1
  367. package/src/agent/context-manager.ts +67 -3
  368. package/src/agent/deploy-preview.ts +62 -1
  369. package/src/agent/expand-files.ts +108 -0
  370. package/src/agent/loop.ts +1312 -31
  371. package/src/agent/permissions.ts +51 -4
  372. package/src/agent/system-prompt.ts +573 -19
  373. package/src/app.ts +58 -0
  374. package/src/audit/security-scanner.ts +45 -0
  375. package/src/auth/keychain.ts +82 -0
  376. package/src/auth/oauth.ts +15 -5
  377. package/src/cli/init.ts +378 -5
  378. package/src/cli/run.ts +407 -16
  379. package/src/cli/serve.ts +78 -1
  380. package/src/cli/web.ts +10 -6
  381. package/src/cli.ts +312 -1
  382. package/src/clients/service-discovery.ts +30 -25
  383. package/src/commands/alias.ts +100 -0
  384. package/src/commands/audit/index.ts +121 -2
  385. package/src/commands/auth-cloud.ts +113 -0
  386. package/src/commands/auth-refresh.ts +187 -0
  387. package/src/commands/aws-discover.ts +144 -251
  388. package/src/commands/aws-terraform.ts +68 -118
  389. package/src/commands/chat.ts +9 -3
  390. package/src/commands/completions.ts +268 -0
  391. package/src/commands/config.ts +26 -0
  392. package/src/commands/cost/index.ts +218 -2
  393. package/src/commands/deploy.ts +260 -0
  394. package/src/commands/doctor.ts +744 -152
  395. package/src/commands/drift/index.ts +371 -23
  396. package/src/commands/export.ts +146 -0
  397. package/src/commands/generate-k8s.ts +9 -61
  398. package/src/commands/generate-terraform.ts +191 -449
  399. package/src/commands/help.ts +212 -36
  400. package/src/commands/history.ts +8 -1
  401. package/src/commands/incident.ts +166 -0
  402. package/src/commands/init.ts +5 -0
  403. package/src/commands/login.ts +86 -1
  404. package/src/commands/logs.ts +167 -0
  405. package/src/commands/onboarding.ts +211 -34
  406. package/src/commands/pipeline.ts +186 -0
  407. package/src/commands/plugin.ts +398 -0
  408. package/src/commands/profile.ts +342 -0
  409. package/src/commands/questionnaire.ts +0 -98
  410. package/src/commands/resume.ts +26 -34
  411. package/src/commands/rollback.ts +315 -0
  412. package/src/commands/rollout.ts +88 -0
  413. package/src/commands/runbook.ts +346 -0
  414. package/src/commands/schedule.ts +236 -0
  415. package/src/commands/status.ts +252 -0
  416. package/src/commands/team-context.ts +220 -0
  417. package/src/commands/template.ts +58 -57
  418. package/src/commands/tf/index.ts +70 -11
  419. package/src/commands/upgrade.ts +57 -0
  420. package/src/commands/version.ts +54 -50
  421. package/src/commands/watch.ts +153 -0
  422. package/src/compat/runtime.ts +1 -1
  423. package/src/compat/sqlite.ts +75 -5
  424. package/src/config/mode-store.ts +62 -0
  425. package/src/config/profiles.ts +84 -0
  426. package/src/config/types.ts +83 -1
  427. package/src/config/workspace-state.ts +53 -0
  428. package/src/engine/cost-estimator.ts +52 -10
  429. package/src/engine/executor.ts +33 -2
  430. package/src/engine/planner.ts +68 -1
  431. package/src/generator/terraform.ts +8 -0
  432. package/src/history/manager.ts +2 -74
  433. package/src/hooks/engine.ts +5 -4
  434. package/src/llm/cost-calculator.ts +2 -2
  435. package/src/llm/providers/anthropic.ts +50 -21
  436. package/src/llm/router.ts +76 -7
  437. package/src/lsp/languages.ts +3 -0
  438. package/src/lsp/manager.ts +21 -5
  439. package/src/nimbus.ts +37 -18
  440. package/src/sessions/manager.ts +108 -1
  441. package/src/sharing/sync.ts +4 -0
  442. package/src/sharing/viewer.ts +66 -0
  443. package/src/tools/file-ops.ts +22 -0
  444. package/src/tools/schemas/devops.ts +3007 -117
  445. package/src/tools/schemas/standard.ts +5 -1
  446. package/src/tools/schemas/types.ts +31 -1
  447. package/src/tools/spawn-exec.ts +148 -0
  448. package/src/ui/App.tsx +1183 -66
  449. package/src/ui/DeployPreview.tsx +62 -57
  450. package/src/ui/FileDiffModal.tsx +162 -0
  451. package/src/ui/Header.tsx +87 -24
  452. package/src/ui/HelpModal.tsx +57 -0
  453. package/src/ui/InputBox.tsx +163 -10
  454. package/src/ui/MessageList.tsx +487 -40
  455. package/src/ui/PermissionPrompt.tsx +17 -5
  456. package/src/ui/StatusBar.tsx +122 -3
  457. package/src/ui/TerminalPane.tsx +84 -0
  458. package/src/ui/ToolCallDisplay.tsx +252 -18
  459. package/src/ui/TreePane.tsx +132 -0
  460. package/src/ui/chat-ui.ts +41 -44
  461. package/src/ui/ink/index.ts +771 -38
  462. package/src/ui/streaming.ts +1 -1
  463. package/src/ui/theme.ts +104 -0
  464. package/src/ui/types.ts +18 -0
  465. package/src/version.ts +1 -1
  466. package/src/watcher/index.ts +66 -15
  467. package/src/wizard/types.ts +1 -0
  468. package/src/wizard/ui.ts +1 -1
  469. package/tsconfig.json +2 -2
@@ -7,13 +7,104 @@
7
7
  */
8
8
 
9
9
  import { writeFile } from 'node:fs/promises';
10
+ import { execFileSync } from 'node:child_process';
10
11
  import { logger } from '../utils';
11
- import { RestClient } from '../clients';
12
12
  import { createWizard, ui, select, multiSelect, type WizardStep, type StepResult } from '../wizard';
13
13
 
14
- // AWS Tools Service client
15
- const awsToolsUrl = process.env.AWS_TOOLS_SERVICE_URL || 'http://localhost:3009';
16
- const awsClient = new RestClient(awsToolsUrl);
14
+ // ---- CLI helpers ----
15
+
16
+ function cliGetAwsProfiles(): string[] {
17
+ try {
18
+ const out = execFileSync('aws', ['configure', 'list-profiles'], {
19
+ encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'],
20
+ }) as string;
21
+ return out.trim().split('\n').map(s => s.trim()).filter(Boolean);
22
+ } catch {
23
+ return ['default'];
24
+ }
25
+ }
26
+
27
+ function cliValidateAwsProfile(profile: string): { accountId?: string; valid: boolean; error?: string } {
28
+ try {
29
+ const out = execFileSync('aws', ['sts', 'get-caller-identity', '--profile', profile, '--output', 'json'], {
30
+ encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'],
31
+ }) as string;
32
+ const data = JSON.parse(out);
33
+ return { valid: true, accountId: data.Account };
34
+ } catch (e: any) {
35
+ return { valid: false, error: e.message?.slice(0, 100) };
36
+ }
37
+ }
38
+
39
+ function cliDiscoverResources(profile: string, regions?: string[], services?: string[]): DiscoveryInventory {
40
+ const env = { ...process.env, AWS_PROFILE: profile };
41
+ const resources: DiscoveredResource[] = [];
42
+ const byType: Record<string, number> = {};
43
+ const byRegion: Record<string, number> = {};
44
+ const byService: Record<string, number> = {};
45
+ const allServices = services || ['EC2', 'S3', 'RDS', 'EKS'];
46
+
47
+ const addResources = (items: Array<{ id: string; type: string; region: string; name?: string }>) => {
48
+ for (const item of items) {
49
+ resources.push({ id: item.id, type: item.type, region: item.region, name: item.name, properties: {} });
50
+ byType[item.type] = (byType[item.type] ?? 0) + 1;
51
+ byRegion[item.region] = (byRegion[item.region] ?? 0) + 1;
52
+ const svc = item.type.split('::')[0] ?? item.type;
53
+ byService[svc] = (byService[svc] ?? 0) + 1;
54
+ }
55
+ };
56
+
57
+ const targetRegions = regions?.length ? regions : ['us-east-1'];
58
+
59
+ for (const region of targetRegions) {
60
+ const regionEnv = { ...env, AWS_DEFAULT_REGION: region };
61
+
62
+ if (!services || allServices.includes('EC2') || allServices.includes('all')) {
63
+ try {
64
+ 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 }) as string;
65
+ const instances = JSON.parse(out).flat();
66
+ addResources(instances.map((i: any) => ({ id: i.id, type: 'AWS::EC2::Instance', region, name: i.name })));
67
+ } catch { /* skip */ }
68
+ }
69
+
70
+ if (!services || allServices.includes('RDS') || allServices.includes('all')) {
71
+ try {
72
+ const out = execFileSync('aws', ['rds', 'describe-db-instances', '--query', 'DBInstances[*].DBInstanceIdentifier', '--output', 'json'], { encoding: 'utf-8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'], env: regionEnv }) as string;
73
+ const dbs = JSON.parse(out);
74
+ addResources(dbs.map((id: string) => ({ id, type: 'AWS::RDS::DBInstance', region, name: id })));
75
+ } catch { /* skip */ }
76
+ }
77
+
78
+ if (!services || allServices.includes('EKS') || allServices.includes('all')) {
79
+ try {
80
+ const out = execFileSync('aws', ['eks', 'list-clusters', '--output', 'json'], { encoding: 'utf-8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'], env: regionEnv }) as string;
81
+ const clusters = JSON.parse(out).clusters ?? [];
82
+ addResources(clusters.map((name: string) => ({ id: name, type: 'AWS::EKS::Cluster', region, name })));
83
+ } catch { /* skip */ }
84
+ }
85
+ }
86
+
87
+ // S3 is global
88
+ if (!services || allServices.includes('S3') || allServices.includes('all')) {
89
+ try {
90
+ const out = execFileSync('aws', ['s3', 'ls'], { encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'], env }) as string;
91
+ const buckets = out.trim().split('\n').filter(Boolean).map(l => l.split(' ').pop()!);
92
+ addResources(buckets.map(name => ({ id: name, type: 'AWS::S3::Bucket', region: 'us-east-1', name })));
93
+ } catch { /* skip */ }
94
+ }
95
+
96
+ return {
97
+ resources,
98
+ byType,
99
+ byRegion,
100
+ byService,
101
+ summary: {
102
+ totalResources: resources.length,
103
+ resourcesByService: byService,
104
+ resourcesByRegion: byRegion,
105
+ },
106
+ };
107
+ }
17
108
 
18
109
  /**
19
110
  * Discovery context for wizard
@@ -160,35 +251,16 @@ function createWizardSteps(): WizardStep<AwsDiscoverContext>[] {
160
251
  * Step 1: AWS Configuration
161
252
  */
162
253
  async function awsConfigStep(ctx: AwsDiscoverContext): Promise<StepResult> {
163
- // Fetch available profiles
254
+ // Fetch available profiles via AWS CLI
164
255
  ui.startSpinner({ message: 'Fetching AWS profiles...' });
165
-
166
- let profiles: Array<{ name: string; source: string; region?: string; isSSO: boolean }> = [];
167
-
168
- try {
169
- const profilesResponse = await awsClient.get<{
170
- profiles: Array<{ name: string; source: string; region?: string; isSSO: boolean }>;
171
- }>('/api/aws/profiles');
172
-
173
- if (profilesResponse.success && profilesResponse.data?.profiles) {
174
- profiles = profilesResponse.data.profiles;
175
- }
176
-
177
- ui.stopSpinnerSuccess(`Found ${profiles.length} AWS profiles`);
178
- } catch (error) {
179
- ui.stopSpinnerFail('Could not fetch AWS profiles');
180
- profiles = [{ name: 'default', source: 'credentials', isSSO: false }];
181
- }
256
+ const profileNames = cliGetAwsProfiles();
257
+ ui.stopSpinnerSuccess(`Found ${profileNames.length} AWS profile(s)`);
182
258
 
183
259
  // Profile selection
184
260
  let selectedProfile = ctx.awsProfile;
185
261
 
186
262
  if (!selectedProfile) {
187
- const profileOptions = profiles.map(p => ({
188
- value: p.name,
189
- label: p.name + (p.isSSO ? ' (SSO)' : ''),
190
- description: `Source: ${p.source}${p.region ? `, Region: ${p.region}` : ''}`,
191
- }));
263
+ const profileOptions = profileNames.map(p => ({ value: p, label: p }));
192
264
 
193
265
  selectedProfile = await select({
194
266
  message: 'Select AWS profile:',
@@ -201,35 +273,18 @@ async function awsConfigStep(ctx: AwsDiscoverContext): Promise<StepResult> {
201
273
  }
202
274
  }
203
275
 
204
- // Validate credentials
276
+ // Validate credentials via AWS CLI
205
277
  ui.startSpinner({ message: `Validating credentials for profile "${selectedProfile}"...` });
278
+ const validation = cliValidateAwsProfile(selectedProfile);
206
279
 
207
- try {
208
- const validateResponse = await awsClient.post<{
209
- valid: boolean;
210
- accountId?: string;
211
- accountAlias?: string;
212
- error?: string;
213
- }>('/api/aws/profiles/validate', { profile: selectedProfile });
214
-
215
- if (!validateResponse.success || !validateResponse.data?.valid) {
216
- ui.stopSpinnerFail(`Invalid credentials: ${validateResponse.data?.error || 'Unknown error'}`);
217
- return { success: false, error: 'Invalid AWS credentials' };
218
- }
219
-
220
- ui.stopSpinnerSuccess(
221
- `Authenticated to account ${validateResponse.data.accountId}${
222
- validateResponse.data.accountAlias ? ` (${validateResponse.data.accountAlias})` : ''
223
- }`
224
- );
225
-
226
- ctx.awsAccountId = validateResponse.data.accountId;
227
- ctx.awsAccountAlias = validateResponse.data.accountAlias;
228
- } catch (error: any) {
229
- ui.stopSpinnerFail(`Failed to validate credentials: ${error.message}`);
230
- return { success: false, error: 'Credential validation failed' };
280
+ if (!validation.valid) {
281
+ ui.stopSpinnerFail(`Invalid credentials: ${validation.error || 'Unknown error'}`);
282
+ return { success: false, error: 'Invalid AWS credentials' };
231
283
  }
232
284
 
285
+ ui.stopSpinnerSuccess(`Authenticated to account ${validation.accountId || 'unknown'}`);
286
+ ctx.awsAccountId = validation.accountId;
287
+
233
288
  // Region selection
234
289
  ui.newLine();
235
290
 
@@ -253,32 +308,23 @@ async function awsConfigStep(ctx: AwsDiscoverContext): Promise<StepResult> {
253
308
  let selectedRegions: string[] = ctx.awsRegions || [];
254
309
 
255
310
  if (regionChoice === 'specific' && selectedRegions.length === 0) {
256
- // Fetch available regions
257
- ui.startSpinner({ message: 'Fetching available regions...' });
258
-
259
- try {
260
- const regionsResponse = await awsClient.get<{
261
- regions: Array<{ name: string; displayName: string }>;
262
- }>(`/api/aws/regions?profile=${selectedProfile}`);
263
-
264
- ui.stopSpinnerSuccess(`Found ${regionsResponse.data?.regions?.length || 0} regions`);
265
-
266
- if (regionsResponse.success && regionsResponse.data?.regions) {
267
- const regionOptions = regionsResponse.data.regions.map(r => ({
268
- value: r.name,
269
- label: `${r.name} - ${r.displayName}`,
270
- }));
271
-
272
- selectedRegions = (await multiSelect({
273
- message: 'Select regions to scan:',
274
- options: regionOptions,
275
- required: true,
276
- })) as string[];
277
- }
278
- } catch (error) {
279
- ui.stopSpinnerFail('Could not fetch regions');
280
- selectedRegions = ['us-east-1'];
281
- }
311
+ // Hardcoded common AWS regions (no service needed)
312
+ const regionOptions = [
313
+ { value: 'us-east-1', label: 'us-east-1 - N. Virginia' },
314
+ { value: 'us-east-2', label: 'us-east-2 - Ohio' },
315
+ { value: 'us-west-1', label: 'us-west-1 - N. California' },
316
+ { value: 'us-west-2', label: 'us-west-2 - Oregon' },
317
+ { value: 'eu-west-1', label: 'eu-west-1 - Ireland' },
318
+ { value: 'eu-central-1', label: 'eu-central-1 - Frankfurt' },
319
+ { value: 'ap-southeast-1', label: 'ap-southeast-1 - Singapore' },
320
+ { value: 'ap-northeast-1', label: 'ap-northeast-1 - Tokyo' },
321
+ ];
322
+
323
+ selectedRegions = (await multiSelect({
324
+ message: 'Select regions to scan:',
325
+ options: regionOptions,
326
+ required: true,
327
+ })) as string[];
282
328
  }
283
329
 
284
330
  return {
@@ -347,104 +393,17 @@ async function serviceSelectionStep(ctx: AwsDiscoverContext): Promise<StepResult
347
393
  }
348
394
 
349
395
  /**
350
- * Step 3: Discovery
396
+ * Step 3: Discovery — uses AWS CLI directly (no REST service)
351
397
  */
352
398
  async function discoveryStep(ctx: AwsDiscoverContext): Promise<StepResult> {
353
- ui.print(' Starting infrastructure discovery...');
354
- ui.newLine();
355
-
399
+ ui.startSpinner({ message: 'Discovering AWS infrastructure via CLI...' });
356
400
  try {
357
- // Start discovery
358
- const startResponse = await awsClient.post<{
359
- sessionId: string;
360
- status: string;
361
- }>('/api/aws/discover', {
362
- profile: ctx.awsProfile,
363
- regions: ctx.awsRegions || 'all',
364
- services: ctx.servicesToScan,
365
- excludeServices: ctx.excludeServices,
366
- });
367
-
368
- if (!startResponse.success || !startResponse.data?.sessionId) {
369
- return { success: false, error: 'Failed to start discovery' };
370
- }
371
-
372
- const sessionId = startResponse.data.sessionId;
373
- ctx.discoverySessionId = sessionId;
374
-
375
- // Poll for progress with visual feedback
376
- let completed = false;
377
- let lastUpdate = '';
378
-
379
- while (!completed) {
380
- await new Promise(resolve => setTimeout(resolve, 1000));
381
-
382
- const statusResponse = await awsClient.get<{
383
- status: string;
384
- progress: {
385
- regionsScanned: number;
386
- totalRegions: number;
387
- servicesScanned: number;
388
- totalServices: number;
389
- resourcesFound: number;
390
- currentRegion?: string;
391
- currentService?: string;
392
- errors: string[];
393
- };
394
- inventory?: DiscoveryInventory;
395
- }>(`/api/aws/discover/${sessionId}`);
396
-
397
- if (!statusResponse.success) {
398
- continue;
399
- }
400
-
401
- const { status, progress, inventory } = statusResponse.data!;
402
-
403
- // Build progress message
404
- const progressMsg = buildProgressMessage(progress);
405
- if (progressMsg !== lastUpdate) {
406
- ui.clearLine();
407
- ui.write(progressMsg);
408
- lastUpdate = progressMsg;
409
- }
410
-
411
- if (status === 'completed') {
412
- completed = true;
413
- ctx.inventory = inventory;
414
-
415
- ui.newLine();
416
- ui.newLine();
417
- ui.success(`Discovery complete! Found ${progress.resourcesFound} resources`);
418
-
419
- if (progress.errors.length > 0) {
420
- ui.newLine();
421
- ui.warning(`${progress.errors.length} errors occurred during discovery:`);
422
- for (const err of progress.errors.slice(0, 5)) {
423
- ui.print(` ${ui.dim(err)}`);
424
- }
425
- if (progress.errors.length > 5) {
426
- ui.print(` ${ui.dim(`... and ${progress.errors.length - 5} more`)}`);
427
- }
428
- }
429
- } else if (status === 'failed') {
430
- ui.newLine();
431
- ui.error('Discovery failed');
432
- return { success: false, error: 'Discovery failed' };
433
- } else if (status === 'cancelled') {
434
- ui.newLine();
435
- ui.warning('Discovery was cancelled');
436
- return { success: false, error: 'Discovery cancelled' };
437
- }
438
- }
439
-
440
- return {
441
- success: true,
442
- data: {
443
- discoverySessionId: sessionId,
444
- inventory: ctx.inventory,
445
- },
446
- };
401
+ const inventory = cliDiscoverResources(ctx.awsProfile || 'default', ctx.awsRegions, ctx.servicesToScan);
402
+ ctx.inventory = inventory;
403
+ ui.stopSpinnerSuccess(`Discovery complete! Found ${inventory.resources.length} resource(s)`);
404
+ return { success: true, data: { inventory } };
447
405
  } catch (error: any) {
406
+ ui.stopSpinnerFail('Discovery failed');
448
407
  return { success: false, error: error.message };
449
408
  }
450
409
  }
@@ -552,94 +511,28 @@ async function runNonInteractive(options: AwsDiscoverOptions): Promise<Discovery
552
511
  ui.info(`Regions: ${options.regions?.join(', ') || 'all'}`);
553
512
  ui.info(`Services: ${options.services?.join(', ') || 'all'}`);
554
513
 
555
- // Validate credentials
514
+ // Validate credentials via AWS CLI
556
515
  ui.startSpinner({ message: 'Validating credentials...' });
557
-
558
- try {
559
- const validateResponse = await awsClient.post<{
560
- valid: boolean;
561
- accountId?: string;
562
- error?: string;
563
- }>('/api/aws/profiles/validate', { profile: options.profile });
564
-
565
- if (!validateResponse.success || !validateResponse.data?.valid) {
566
- ui.stopSpinnerFail(`Invalid credentials: ${validateResponse.data?.error || 'Unknown error'}`);
567
- return null;
568
- }
569
-
570
- ui.stopSpinnerSuccess(`Authenticated to account ${validateResponse.data.accountId}`);
571
- } catch (error: any) {
572
- ui.stopSpinnerFail(`Credential validation failed: ${error.message}`);
516
+ const validation = cliValidateAwsProfile(options.profile!);
517
+ if (!validation.valid) {
518
+ ui.stopSpinnerFail(`Invalid credentials: ${validation.error || 'Unknown error'}`);
573
519
  return null;
574
520
  }
521
+ ui.stopSpinnerSuccess(`Authenticated to account ${validation.accountId || 'unknown'}`);
575
522
 
576
- // Start discovery
577
- ui.startSpinner({ message: 'Starting discovery...' });
578
-
523
+ // Discover via AWS CLI
524
+ ui.startSpinner({ message: 'Discovering infrastructure...' });
579
525
  try {
580
- const startResponse = await awsClient.post<{
581
- sessionId: string;
582
- }>('/api/aws/discover', {
583
- profile: options.profile,
584
- regions: options.regions || 'all',
585
- services: options.services,
586
- excludeServices: options.excludeServices,
587
- });
588
-
589
- if (!startResponse.success || !startResponse.data?.sessionId) {
590
- ui.stopSpinnerFail('Failed to start discovery');
591
- return null;
592
- }
593
-
594
- const sessionId = startResponse.data.sessionId;
595
- ui.stopSpinnerSuccess(`Discovery started (session: ${sessionId})`);
596
-
597
- // Poll for completion
598
- ui.startSpinner({ message: 'Scanning infrastructure...' });
599
-
600
- let completed = false;
601
- let inventory: DiscoveryInventory | undefined;
602
-
603
- while (!completed) {
604
- await new Promise(resolve => setTimeout(resolve, 2000));
526
+ const inventory = cliDiscoverResources(options.profile!, options.regions, options.services);
527
+ ui.stopSpinnerSuccess(`Discovery complete! Found ${inventory.resources.length} resource(s)`);
605
528
 
606
- const statusResponse = await awsClient.get<{
607
- status: string;
608
- progress: { resourcesFound: number };
609
- inventory?: DiscoveryInventory;
610
- }>(`/api/aws/discover/${sessionId}`);
529
+ displayInventorySummary(inventory);
611
530
 
612
- if (!statusResponse.success) {
613
- continue;
614
- }
615
-
616
- const { status, progress } = statusResponse.data!;
617
-
618
- ui.updateSpinner(`Scanning... ${progress.resourcesFound} resources found`);
619
-
620
- if (status === 'completed') {
621
- completed = true;
622
- inventory = statusResponse.data!.inventory;
623
- ui.stopSpinnerSuccess(`Discovery complete! Found ${progress.resourcesFound} resources`);
624
- } else if (status === 'failed' || status === 'cancelled') {
625
- ui.stopSpinnerFail(`Discovery ${status}`);
626
- return null;
627
- }
628
- }
629
-
630
- if (inventory) {
631
- // Display summary
632
- displayInventorySummary(inventory);
633
-
634
- // Save to file if requested
635
- if (options.outputFile) {
636
- await saveInventory(inventory, options.outputFile, options.outputFormat || 'json');
637
- }
638
-
639
- return inventory;
531
+ if (options.outputFile) {
532
+ await saveInventory(inventory, options.outputFile, options.outputFormat || 'json');
640
533
  }
641
534
 
642
- return null;
535
+ return inventory;
643
536
  } catch (error: any) {
644
537
  ui.stopSpinnerFail(`Discovery failed: ${error.message}`);
645
538
  return null;