@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
@@ -0,0 +1,525 @@
1
+ /**
2
+ * Plan Command
3
+ *
4
+ * Preview infrastructure changes for Terraform, Kubernetes, and Helm
5
+ *
6
+ * Usage: nimbus plan [options]
7
+ */
8
+ import { logger } from '../../utils';
9
+ import { ui } from '../../wizard';
10
+ import { terraformClient, k8sClient } from '../../clients';
11
+ import { displayPlan } from './display';
12
+ // Re-export display utilities
13
+ export { displayPlan } from './display';
14
+ /**
15
+ * Parse plan options from args
16
+ */
17
+ export function parsePlanOptions(args) {
18
+ const options = {};
19
+ for (let i = 0; i < args.length; i++) {
20
+ const arg = args[i];
21
+ if (arg === '--type' && args[i + 1]) {
22
+ options.type = args[++i];
23
+ }
24
+ else if ((arg === '--target' || arg === '-t') && args[i + 1]) {
25
+ options.target = args[++i];
26
+ }
27
+ else if (arg === '--out' && args[i + 1]) {
28
+ options.out = args[++i];
29
+ }
30
+ else if (arg === '--detailed' || arg === '-d') {
31
+ options.detailed = true;
32
+ }
33
+ else if (arg === '--json') {
34
+ options.json = true;
35
+ }
36
+ else if ((arg === '--namespace' || arg === '-n') && args[i + 1]) {
37
+ options.namespace = args[++i];
38
+ }
39
+ else if (arg === '--var' && args[i + 1]) {
40
+ const varArg = args[++i];
41
+ const [key, ...valueParts] = varArg.split('=');
42
+ options.var = options.var || {};
43
+ options.var[key] = valueParts.join('=');
44
+ }
45
+ else if (arg === '--var-file' && args[i + 1]) {
46
+ options.varFile = args[++i];
47
+ }
48
+ else if (!arg.startsWith('-') && !options.target) {
49
+ options.target = arg;
50
+ }
51
+ }
52
+ return options;
53
+ }
54
+ /**
55
+ * Detect infrastructure type from current directory
56
+ */
57
+ async function detectInfraType(targetPath) {
58
+ const fs = await import('fs/promises');
59
+ const path = await import('path');
60
+ const basePath = targetPath || '.';
61
+ // Check for Terraform files
62
+ try {
63
+ const files = await fs.readdir(basePath);
64
+ if (files.some(f => f.endsWith('.tf'))) {
65
+ return 'terraform';
66
+ }
67
+ }
68
+ catch {
69
+ // Directory doesn't exist or can't be read
70
+ }
71
+ // Check for Kubernetes manifests
72
+ try {
73
+ const files = await fs.readdir(basePath);
74
+ const yamlFiles = files.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
75
+ for (const file of yamlFiles.slice(0, 5)) {
76
+ // Check first 5 files
77
+ try {
78
+ const content = await fs.readFile(path.join(basePath, file), 'utf-8');
79
+ if (content.includes('apiVersion:') && content.includes('kind:')) {
80
+ return 'k8s';
81
+ }
82
+ }
83
+ catch {
84
+ continue;
85
+ }
86
+ }
87
+ }
88
+ catch {
89
+ // Ignore
90
+ }
91
+ // Check for Helm chart
92
+ try {
93
+ await fs.access(path.join(basePath, 'Chart.yaml'));
94
+ return 'helm';
95
+ }
96
+ catch {
97
+ // No Chart.yaml
98
+ }
99
+ // Check if target is a specific file
100
+ if (targetPath) {
101
+ if (targetPath.endsWith('.tf')) {
102
+ return 'terraform';
103
+ }
104
+ if (targetPath.endsWith('.yaml') || targetPath.endsWith('.yml')) {
105
+ return 'k8s';
106
+ }
107
+ }
108
+ return null;
109
+ }
110
+ /**
111
+ * Run Terraform plan
112
+ */
113
+ async function runTerraformPlan(options) {
114
+ const directory = options.target || '.';
115
+ // Check if terraform client is available
116
+ const clientAvailable = await terraformClient.isAvailable();
117
+ if (clientAvailable) {
118
+ const result = await terraformClient.plan(directory, {
119
+ vars: options.var,
120
+ varFile: options.varFile,
121
+ out: options.out,
122
+ });
123
+ // Parse changes from output
124
+ const addMatch = result.output.match(/(\d+) to add/);
125
+ const changeMatch = result.output.match(/(\d+) to change/);
126
+ const destroyMatch = result.output.match(/(\d+) to destroy/);
127
+ return {
128
+ type: 'terraform',
129
+ success: result.success,
130
+ error: result.error,
131
+ changes: result.hasChanges
132
+ ? {
133
+ add: parseInt(addMatch?.[1] || '0', 10),
134
+ change: parseInt(changeMatch?.[1] || '0', 10),
135
+ destroy: parseInt(destroyMatch?.[1] || '0', 10),
136
+ }
137
+ : { add: 0, change: 0, destroy: 0 },
138
+ raw: options.detailed ? result.output : undefined,
139
+ };
140
+ }
141
+ else {
142
+ // Fall back to local terraform CLI
143
+ return runLocalTerraformPlan(options);
144
+ }
145
+ }
146
+ /**
147
+ * Run local Terraform plan
148
+ */
149
+ async function runLocalTerraformPlan(options) {
150
+ const { execFileSync } = await import('child_process');
151
+ const directory = options.target || '.';
152
+ // Build command args (using execFileSync to prevent shell injection)
153
+ const args = ['plan', '-no-color'];
154
+ if (options.var) {
155
+ for (const [key, value] of Object.entries(options.var)) {
156
+ args.push('-var', `${key}=${value}`);
157
+ }
158
+ }
159
+ if (options.varFile) {
160
+ args.push('-var-file', options.varFile);
161
+ }
162
+ if (options.out) {
163
+ args.push('-out', options.out);
164
+ }
165
+ try {
166
+ const output = execFileSync('terraform', args, {
167
+ cwd: directory,
168
+ encoding: 'utf-8',
169
+ timeout: 300000, // 5 minutes
170
+ });
171
+ // Parse output for changes
172
+ const addMatch = output.match(/(\d+) to add/);
173
+ const changeMatch = output.match(/(\d+) to change/);
174
+ const destroyMatch = output.match(/(\d+) to destroy/);
175
+ const changes = {
176
+ add: parseInt(addMatch?.[1] || '0', 10),
177
+ change: parseInt(changeMatch?.[1] || '0', 10),
178
+ destroy: parseInt(destroyMatch?.[1] || '0', 10),
179
+ };
180
+ // Parse resource changes
181
+ const resources = [];
182
+ const resourceMatches = output.matchAll(/# ([\w.-]+\.[\w.-]+) will be (created|updated|destroyed|read)/g);
183
+ for (const match of resourceMatches) {
184
+ const actionMap = {
185
+ created: 'create',
186
+ updated: 'update',
187
+ destroyed: 'delete',
188
+ read: 'read',
189
+ };
190
+ resources.push({
191
+ action: actionMap[match[2]] || match[2],
192
+ resource: match[1],
193
+ address: match[1],
194
+ });
195
+ }
196
+ return {
197
+ type: 'terraform',
198
+ success: true,
199
+ changes,
200
+ resources,
201
+ raw: options.detailed ? output : undefined,
202
+ };
203
+ }
204
+ catch (error) {
205
+ return {
206
+ type: 'terraform',
207
+ success: false,
208
+ error: error.message || 'Terraform plan failed',
209
+ raw: error.stdout || error.stderr,
210
+ };
211
+ }
212
+ }
213
+ /**
214
+ * Run Kubernetes dry-run plan
215
+ */
216
+ async function runK8sPlan(options) {
217
+ const manifests = options.target || '.';
218
+ const fs = await import('fs/promises');
219
+ const path = await import('path');
220
+ // Read manifest files
221
+ let manifestContent;
222
+ const resources = [];
223
+ try {
224
+ const stat = await fs.stat(manifests);
225
+ if (stat.isDirectory()) {
226
+ const files = await fs.readdir(manifests);
227
+ const yamlFiles = files.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
228
+ if (yamlFiles.length === 0) {
229
+ return {
230
+ type: 'k8s',
231
+ success: false,
232
+ error: 'No YAML manifests found in directory',
233
+ };
234
+ }
235
+ const contents = await Promise.all(yamlFiles.map(f => fs.readFile(path.join(manifests, f), 'utf-8')));
236
+ manifestContent = contents.join('\n---\n');
237
+ }
238
+ else {
239
+ manifestContent = await fs.readFile(manifests, 'utf-8');
240
+ }
241
+ }
242
+ catch (error) {
243
+ return {
244
+ type: 'k8s',
245
+ success: false,
246
+ error: `Failed to read manifests: ${error.message}`,
247
+ };
248
+ }
249
+ // Parse manifests to list resources
250
+ const documents = manifestContent.split(/^---$/m);
251
+ for (const doc of documents) {
252
+ const trimmed = doc.trim();
253
+ if (!trimmed) {
254
+ continue;
255
+ }
256
+ const kindMatch = trimmed.match(/^kind:\s*(.+)$/m);
257
+ const nameMatch = trimmed.match(/^\s+name:\s*(.+)$/m);
258
+ const namespaceMatch = trimmed.match(/^\s+namespace:\s*(.+)$/m);
259
+ if (kindMatch && nameMatch) {
260
+ resources.push({
261
+ action: 'apply', // K8s apply is idempotent
262
+ resource: `${kindMatch[1].trim()}/${nameMatch[1].trim()}`,
263
+ address: namespaceMatch
264
+ ? `${namespaceMatch[1].trim()}/${kindMatch[1].trim()}/${nameMatch[1].trim()}`
265
+ : `default/${kindMatch[1].trim()}/${nameMatch[1].trim()}`,
266
+ });
267
+ }
268
+ }
269
+ // Check if k8s client is available for dry-run
270
+ const clientAvailable = await k8sClient.isAvailable();
271
+ if (clientAvailable) {
272
+ const result = await k8sClient.apply(manifestContent, {
273
+ namespace: options.namespace,
274
+ dryRun: true,
275
+ });
276
+ return {
277
+ type: 'k8s',
278
+ success: result.success,
279
+ error: result.error,
280
+ changes: {
281
+ add: result.created?.length || 0,
282
+ change: result.configured?.length || 0,
283
+ destroy: 0,
284
+ },
285
+ resources,
286
+ raw: options.detailed ? result.output : undefined,
287
+ };
288
+ }
289
+ // Return parsed resources without dry-run validation
290
+ return {
291
+ type: 'k8s',
292
+ success: true,
293
+ changes: {
294
+ add: resources.length,
295
+ change: 0,
296
+ destroy: 0,
297
+ },
298
+ resources,
299
+ raw: options.detailed ? manifestContent : undefined,
300
+ };
301
+ }
302
+ /**
303
+ * Run Helm diff plan
304
+ */
305
+ async function runHelmPlan(options) {
306
+ const target = options.target || '.';
307
+ const { execFileSync } = await import('child_process');
308
+ // Check if helm-diff plugin is available
309
+ try {
310
+ const pluginOutput = execFileSync('helm', ['plugin', 'list'], {
311
+ encoding: 'utf-8',
312
+ stdio: 'pipe',
313
+ });
314
+ if (!pluginOutput.includes('diff')) {
315
+ // helm-diff not installed, use template comparison
316
+ return runHelmTemplatePlan(options);
317
+ }
318
+ }
319
+ catch {
320
+ // helm-diff not installed, use template comparison
321
+ return runHelmTemplatePlan(options);
322
+ }
323
+ // Use helm diff for existing releases
324
+ // First, need to determine release name
325
+ let releaseName = target;
326
+ let chartPath = '.';
327
+ // If target is a path, try to extract release name from values
328
+ if (target.includes('/') || target === '.') {
329
+ chartPath = target;
330
+ const fs = await import('fs/promises');
331
+ const path = await import('path');
332
+ try {
333
+ // Look for release name in values file
334
+ const valuesFiles = ['values.yaml', 'values.yml'];
335
+ for (const vf of valuesFiles) {
336
+ try {
337
+ const content = await fs.readFile(path.join(chartPath, vf), 'utf-8');
338
+ const nameMatch = content.match(/release[Nn]ame:\s*(.+)/);
339
+ if (nameMatch) {
340
+ releaseName = nameMatch[1].trim();
341
+ break;
342
+ }
343
+ }
344
+ catch {
345
+ continue;
346
+ }
347
+ }
348
+ }
349
+ catch {
350
+ // Use directory name as release name
351
+ releaseName = path.basename(path.resolve(chartPath));
352
+ }
353
+ }
354
+ try {
355
+ // Use execFileSync with args array to prevent shell injection
356
+ const diffArgs = ['diff', 'upgrade', releaseName, chartPath];
357
+ if (options.namespace) {
358
+ diffArgs.push('-n', options.namespace);
359
+ }
360
+ const output = execFileSync('helm', diffArgs, {
361
+ encoding: 'utf-8',
362
+ timeout: 60000,
363
+ });
364
+ // Parse diff output
365
+ const addMatch = output.match(/^\+[^+]/gm);
366
+ const removeMatch = output.match(/^-[^-]/gm);
367
+ return {
368
+ type: 'helm',
369
+ success: true,
370
+ changes: {
371
+ add: addMatch?.length || 0,
372
+ change: 0,
373
+ destroy: removeMatch?.length || 0,
374
+ },
375
+ raw: options.detailed ? output : undefined,
376
+ };
377
+ }
378
+ catch {
379
+ // Release might not exist
380
+ return runHelmTemplatePlan(options);
381
+ }
382
+ }
383
+ /**
384
+ * Run Helm template plan (for new releases)
385
+ */
386
+ async function runHelmTemplatePlan(options) {
387
+ const chartPath = options.target || '.';
388
+ const { execFileSync } = await import('child_process');
389
+ try {
390
+ // Use execFileSync with args array to prevent shell injection
391
+ const templateArgs = ['template', chartPath];
392
+ if (options.namespace) {
393
+ templateArgs.push('-n', options.namespace);
394
+ }
395
+ const output = execFileSync('helm', templateArgs, {
396
+ encoding: 'utf-8',
397
+ timeout: 60000,
398
+ });
399
+ // Parse rendered manifests
400
+ const resources = [];
401
+ const documents = output.split(/^---$/m);
402
+ for (const doc of documents) {
403
+ const trimmed = doc.trim();
404
+ if (!trimmed) {
405
+ continue;
406
+ }
407
+ const kindMatch = trimmed.match(/^kind:\s*(.+)$/m);
408
+ const nameMatch = trimmed.match(/^\s+name:\s*(.+)$/m);
409
+ if (kindMatch && nameMatch) {
410
+ resources.push({
411
+ action: 'create',
412
+ resource: `${kindMatch[1].trim()}/${nameMatch[1].trim()}`,
413
+ address: `${kindMatch[1].trim()}/${nameMatch[1].trim()}`,
414
+ });
415
+ }
416
+ }
417
+ return {
418
+ type: 'helm',
419
+ success: true,
420
+ changes: {
421
+ add: resources.length,
422
+ change: 0,
423
+ destroy: 0,
424
+ },
425
+ resources,
426
+ raw: options.detailed ? output : undefined,
427
+ };
428
+ }
429
+ catch (error) {
430
+ return {
431
+ type: 'helm',
432
+ success: false,
433
+ error: error.message || 'Helm template failed',
434
+ raw: error.stdout || error.stderr,
435
+ };
436
+ }
437
+ }
438
+ /**
439
+ * Capitalize first letter
440
+ */
441
+ function capitalizeFirst(str) {
442
+ return str.charAt(0).toUpperCase() + str.slice(1);
443
+ }
444
+ /**
445
+ * Run the plan command
446
+ */
447
+ export async function planCommand(options = {}) {
448
+ // Redact sensitive variables from logs
449
+ const { var: _vars, ...safeOptions } = options;
450
+ logger.info('Running plan command', {
451
+ ...safeOptions,
452
+ var: options.var ? '[REDACTED]' : undefined,
453
+ });
454
+ // Detect or use specified type
455
+ let type = options.type;
456
+ if (!type || type === 'auto') {
457
+ ui.startSpinner({ message: 'Detecting infrastructure type...' });
458
+ const detectedType = await detectInfraType(options.target);
459
+ ui.stopSpinnerSuccess('');
460
+ if (!detectedType) {
461
+ ui.error('Could not detect infrastructure type');
462
+ ui.newLine();
463
+ ui.info('Usage: nimbus plan [options]');
464
+ ui.info('');
465
+ ui.info('Options:');
466
+ ui.info(' --type <type> Infrastructure type: terraform, k8s, helm');
467
+ ui.info(' --target <path> Target directory or file');
468
+ ui.info(' --detailed Show detailed plan output');
469
+ ui.info('');
470
+ ui.info('Examples:');
471
+ ui.info(' nimbus plan');
472
+ ui.info(' nimbus plan --type terraform');
473
+ ui.info(' nimbus plan --target ./manifests --type k8s');
474
+ process.exit(1);
475
+ }
476
+ type = detectedType;
477
+ ui.info(`Detected infrastructure type: ${type}`);
478
+ ui.newLine();
479
+ }
480
+ ui.header(`${capitalizeFirst(type)} Plan`);
481
+ ui.info(`Target: ${options.target || '.'}`);
482
+ ui.newLine();
483
+ ui.startSpinner({ message: 'Creating execution plan...' });
484
+ let plan;
485
+ switch (type) {
486
+ case 'terraform':
487
+ plan = await runTerraformPlan(options);
488
+ break;
489
+ case 'k8s':
490
+ plan = await runK8sPlan(options);
491
+ break;
492
+ case 'helm':
493
+ plan = await runHelmPlan(options);
494
+ break;
495
+ default:
496
+ ui.stopSpinnerFail(`Unknown type: ${type}`);
497
+ process.exit(1);
498
+ }
499
+ if (!plan.success) {
500
+ ui.stopSpinnerFail('Plan failed');
501
+ ui.error(plan.error || 'Unknown error');
502
+ if (plan.raw) {
503
+ ui.newLine();
504
+ ui.print(plan.raw);
505
+ }
506
+ process.exit(1);
507
+ }
508
+ ui.stopSpinnerSuccess('Plan created');
509
+ ui.newLine();
510
+ // Display the plan
511
+ if (options.json) {
512
+ console.log(JSON.stringify(plan, null, 2));
513
+ }
514
+ else {
515
+ displayPlan(plan, options.detailed);
516
+ }
517
+ // Save plan output if requested (Terraform only)
518
+ if (options.out && type === 'terraform') {
519
+ ui.newLine();
520
+ ui.info(`Plan saved to: ${options.out}`);
521
+ ui.info('Apply with: nimbus apply terraform');
522
+ }
523
+ }
524
+ // Export as default
525
+ export default planCommand;