@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,985 @@
1
+ /**
2
+ * Helm Commands
3
+ *
4
+ * CLI commands for Helm operations
5
+ */
6
+ import { helmClient } from '../../clients';
7
+ import { ui } from '../../wizard/ui';
8
+ import { confirmWithResourceName } from '../../wizard/approval';
9
+ import { showDestructionCostWarning } from '../../utils/cost-warning';
10
+ import { historyManager } from '../../history';
11
+ /**
12
+ * List Helm releases
13
+ */
14
+ export async function helmListCommand(options = {}) {
15
+ ui.header('Helm Releases');
16
+ if (options.allNamespaces) {
17
+ ui.info('Showing releases across all namespaces');
18
+ }
19
+ else if (options.namespace) {
20
+ ui.info(`Namespace: ${options.namespace}`);
21
+ }
22
+ ui.startSpinner({ message: 'Fetching Helm releases...' });
23
+ try {
24
+ const available = await helmClient.isAvailable();
25
+ if (!available) {
26
+ ui.stopSpinnerFail('Helm Tools Service not available');
27
+ ui.error('Please ensure the Helm Tools Service is running.');
28
+ return;
29
+ }
30
+ const result = await helmClient.list({
31
+ namespace: options.namespace,
32
+ allNamespaces: options.allNamespaces,
33
+ });
34
+ if (result.success) {
35
+ ui.stopSpinnerSuccess(`Found ${result.releases.length} releases`);
36
+ if (result.releases.length > 0) {
37
+ ui.table({
38
+ columns: [
39
+ { key: 'name', header: 'Name' },
40
+ { key: 'namespace', header: 'Namespace' },
41
+ { key: 'revision', header: 'Revision' },
42
+ { key: 'status', header: 'Status' },
43
+ { key: 'chart', header: 'Chart' },
44
+ { key: 'appVersion', header: 'App Version' },
45
+ { key: 'updated', header: 'Updated' },
46
+ ],
47
+ data: result.releases.map(release => ({
48
+ name: release.name,
49
+ namespace: release.namespace,
50
+ revision: release.revision,
51
+ status: release.status,
52
+ chart: release.chart,
53
+ appVersion: release.appVersion,
54
+ updated: release.updated,
55
+ })),
56
+ });
57
+ }
58
+ else {
59
+ ui.info('No releases found');
60
+ }
61
+ }
62
+ else {
63
+ ui.stopSpinnerFail('Failed to list releases');
64
+ if (result.error) {
65
+ ui.error(result.error);
66
+ }
67
+ }
68
+ }
69
+ catch (error) {
70
+ ui.stopSpinnerFail('Error listing Helm releases');
71
+ ui.error(error.message);
72
+ }
73
+ }
74
+ /**
75
+ * Install a Helm chart
76
+ */
77
+ export async function helmInstallCommand(releaseName, chart, options = {}) {
78
+ ui.header('Helm Install');
79
+ ui.info(`Release: ${releaseName}`);
80
+ ui.info(`Chart: ${chart}`);
81
+ if (options.namespace) {
82
+ ui.info(`Namespace: ${options.namespace}`);
83
+ }
84
+ if (options.version) {
85
+ ui.info(`Version: ${options.version}`);
86
+ }
87
+ ui.startSpinner({ message: `Installing ${chart}...` });
88
+ try {
89
+ const available = await helmClient.isAvailable();
90
+ if (!available) {
91
+ ui.stopSpinnerFail('Helm Tools Service not available');
92
+ ui.error('Please ensure the Helm Tools Service is running.');
93
+ return;
94
+ }
95
+ const result = await helmClient.install(releaseName, chart, {
96
+ namespace: options.namespace,
97
+ values: options.values,
98
+ valuesFile: options.valuesFile,
99
+ version: options.version,
100
+ wait: options.wait,
101
+ timeout: options.timeout,
102
+ createNamespace: options.createNamespace,
103
+ dryRun: options.dryRun,
104
+ });
105
+ if (result.success) {
106
+ ui.stopSpinnerSuccess(`Installed ${releaseName}`);
107
+ ui.info(`Status: ${result.release.status}`);
108
+ ui.info(`Revision: ${result.release.revision}`);
109
+ if (result.output) {
110
+ ui.box({ title: 'Output', content: result.output });
111
+ }
112
+ }
113
+ else {
114
+ ui.stopSpinnerFail('Failed to install chart');
115
+ if (result.error) {
116
+ ui.error(result.error);
117
+ }
118
+ }
119
+ }
120
+ catch (error) {
121
+ ui.stopSpinnerFail('Error installing Helm chart');
122
+ ui.error(error.message);
123
+ }
124
+ }
125
+ /**
126
+ * Upgrade a Helm release
127
+ */
128
+ export async function helmUpgradeCommand(releaseName, chart, options = {}) {
129
+ ui.header('Helm Upgrade');
130
+ ui.info(`Release: ${releaseName}`);
131
+ ui.info(`Chart: ${chart}`);
132
+ if (options.namespace) {
133
+ ui.info(`Namespace: ${options.namespace}`);
134
+ }
135
+ if (options.version) {
136
+ ui.info(`Version: ${options.version}`);
137
+ }
138
+ if (options.install) {
139
+ ui.info('Install if not exists: yes');
140
+ }
141
+ ui.startSpinner({ message: `Upgrading ${releaseName}...` });
142
+ try {
143
+ const available = await helmClient.isAvailable();
144
+ if (!available) {
145
+ ui.stopSpinnerFail('Helm Tools Service not available');
146
+ ui.error('Please ensure the Helm Tools Service is running.');
147
+ return;
148
+ }
149
+ const result = await helmClient.upgrade(releaseName, chart, {
150
+ namespace: options.namespace,
151
+ values: options.values,
152
+ valuesFile: options.valuesFile,
153
+ version: options.version,
154
+ wait: options.wait,
155
+ timeout: options.timeout,
156
+ install: options.install,
157
+ dryRun: options.dryRun,
158
+ });
159
+ if (result.success) {
160
+ ui.stopSpinnerSuccess(`Upgraded ${releaseName}`);
161
+ ui.info(`Status: ${result.release.status}`);
162
+ ui.info(`Revision: ${result.release.revision}`);
163
+ if (result.output) {
164
+ ui.box({ title: 'Output', content: result.output });
165
+ }
166
+ }
167
+ else {
168
+ ui.stopSpinnerFail('Failed to upgrade release');
169
+ if (result.error) {
170
+ ui.error(result.error);
171
+ }
172
+ }
173
+ }
174
+ catch (error) {
175
+ ui.stopSpinnerFail('Error upgrading Helm release');
176
+ ui.error(error.message);
177
+ }
178
+ }
179
+ /**
180
+ * Uninstall a Helm release
181
+ */
182
+ export async function helmUninstallCommand(releaseName, options = {}) {
183
+ ui.header('Helm Uninstall');
184
+ ui.info(`Release: ${releaseName}`);
185
+ if (options.namespace) {
186
+ ui.info(`Namespace: ${options.namespace}`);
187
+ }
188
+ // Show release info warning before destructive operation
189
+ ui.newLine();
190
+ ui.warning(`Destructive operation: uninstalling helm release "${releaseName}"`);
191
+ ui.print(` ${ui.color('Release:', 'yellow')} ${releaseName}`);
192
+ ui.print(` ${ui.color('Namespace:', 'yellow')} ${options.namespace || 'default'}`);
193
+ ui.print(` ${ui.color('Keep history:', 'yellow')} ${options.keepHistory ? 'yes' : 'no'}`);
194
+ ui.print(` ${ui.color('Impact:', 'red')} All resources managed by this release will be deleted.`);
195
+ // Attempt to show release details if service is available
196
+ try {
197
+ const available = await helmClient.isAvailable();
198
+ if (available) {
199
+ const statusResult = await helmClient.status(releaseName, {
200
+ namespace: options.namespace,
201
+ });
202
+ if (statusResult?.release) {
203
+ ui.print(` ${ui.color('Chart:', 'yellow')} ${statusResult.release.chart || 'unknown'}`);
204
+ ui.print(` ${ui.color('Revision:', 'yellow')} ${statusResult.release.revision || 'unknown'}`);
205
+ ui.print(` ${ui.color('Status:', 'yellow')} ${statusResult.release.status || 'unknown'}`);
206
+ }
207
+ }
208
+ }
209
+ catch {
210
+ // Best-effort release info display -- silently skip on failure
211
+ }
212
+ // Show cost warning before destructive operation
213
+ await showDestructionCostWarning(process.cwd());
214
+ // Require confirmation for destructive operation
215
+ if (!options.dryRun && !options.yes) {
216
+ const confirmed = await confirmWithResourceName(releaseName, 'helm release');
217
+ if (!confirmed) {
218
+ return;
219
+ }
220
+ }
221
+ ui.startSpinner({ message: `Uninstalling ${releaseName}...` });
222
+ try {
223
+ const available = await helmClient.isAvailable();
224
+ if (!available) {
225
+ ui.stopSpinnerFail('Helm Tools Service not available');
226
+ ui.error('Please ensure the Helm Tools Service is running.');
227
+ return;
228
+ }
229
+ const result = await helmClient.uninstall(releaseName, {
230
+ namespace: options.namespace,
231
+ keepHistory: options.keepHistory,
232
+ dryRun: options.dryRun,
233
+ });
234
+ if (result.success) {
235
+ ui.stopSpinnerSuccess(`Uninstalled ${releaseName}`);
236
+ if (result.output) {
237
+ ui.box({ title: 'Output', content: result.output });
238
+ }
239
+ }
240
+ else {
241
+ ui.stopSpinnerFail('Failed to uninstall release');
242
+ if (result.error) {
243
+ ui.error(result.error);
244
+ }
245
+ }
246
+ }
247
+ catch (error) {
248
+ ui.stopSpinnerFail('Error uninstalling Helm release');
249
+ ui.error(error.message);
250
+ }
251
+ }
252
+ /**
253
+ * Rollback a Helm release
254
+ */
255
+ export async function helmRollbackCommand(releaseName, revision, options = {}) {
256
+ ui.header('Helm Rollback');
257
+ ui.info(`Release: ${releaseName}`);
258
+ ui.info(`Revision: ${revision}`);
259
+ if (options.namespace) {
260
+ ui.info(`Namespace: ${options.namespace}`);
261
+ }
262
+ ui.startSpinner({ message: `Rolling back ${releaseName} to revision ${revision}...` });
263
+ try {
264
+ const available = await helmClient.isAvailable();
265
+ if (!available) {
266
+ ui.stopSpinnerFail('Helm Tools Service not available');
267
+ ui.error('Please ensure the Helm Tools Service is running.');
268
+ return;
269
+ }
270
+ const result = await helmClient.rollback(releaseName, revision, {
271
+ namespace: options.namespace,
272
+ wait: options.wait,
273
+ dryRun: options.dryRun,
274
+ });
275
+ if (result.success) {
276
+ ui.stopSpinnerSuccess(`Rolled back ${releaseName} to revision ${revision}`);
277
+ if (result.output) {
278
+ ui.box({ title: 'Output', content: result.output });
279
+ }
280
+ }
281
+ else {
282
+ ui.stopSpinnerFail('Failed to rollback release');
283
+ if (result.error) {
284
+ ui.error(result.error);
285
+ }
286
+ }
287
+ }
288
+ catch (error) {
289
+ ui.stopSpinnerFail('Error rolling back Helm release');
290
+ ui.error(error.message);
291
+ }
292
+ }
293
+ /**
294
+ * Show release history
295
+ */
296
+ export async function helmHistoryCommand(releaseName, options = {}) {
297
+ ui.header(`Helm History - ${releaseName}`);
298
+ if (options.namespace) {
299
+ ui.info(`Namespace: ${options.namespace}`);
300
+ }
301
+ ui.startSpinner({ message: 'Fetching release history...' });
302
+ try {
303
+ const available = await helmClient.isAvailable();
304
+ if (!available) {
305
+ ui.stopSpinnerFail('Helm Tools Service not available');
306
+ ui.error('Please ensure the Helm Tools Service is running.');
307
+ return;
308
+ }
309
+ const result = await helmClient.history(releaseName, {
310
+ namespace: options.namespace,
311
+ });
312
+ if (result.success) {
313
+ ui.stopSpinnerSuccess(`Found ${result.history.length} revisions`);
314
+ if (result.history.length > 0) {
315
+ // Display history - the history format can vary, so we just show it raw
316
+ for (const entry of result.history) {
317
+ ui.info(JSON.stringify(entry));
318
+ }
319
+ }
320
+ }
321
+ else {
322
+ ui.stopSpinnerFail('Failed to get release history');
323
+ if (result.error) {
324
+ ui.error(result.error);
325
+ }
326
+ }
327
+ }
328
+ catch (error) {
329
+ ui.stopSpinnerFail('Error getting Helm history');
330
+ ui.error(error.message);
331
+ }
332
+ }
333
+ /**
334
+ * Search for Helm charts
335
+ */
336
+ export async function helmSearchCommand(keyword, options = {}) {
337
+ ui.header(`Helm Search - "${keyword}"`);
338
+ if (options.repo) {
339
+ ui.info(`Repository: ${options.repo}`);
340
+ }
341
+ ui.startSpinner({ message: 'Searching for charts...' });
342
+ try {
343
+ const available = await helmClient.isAvailable();
344
+ if (!available) {
345
+ ui.stopSpinnerFail('Helm Tools Service not available');
346
+ ui.error('Please ensure the Helm Tools Service is running.');
347
+ return;
348
+ }
349
+ const result = await helmClient.search(keyword, {
350
+ repo: options.repo,
351
+ });
352
+ if (result.success) {
353
+ ui.stopSpinnerSuccess(`Found ${result.charts.length} charts`);
354
+ if (result.charts.length > 0) {
355
+ ui.table({
356
+ columns: [
357
+ { key: 'name', header: 'Name' },
358
+ { key: 'version', header: 'Version' },
359
+ { key: 'appVersion', header: 'App Version' },
360
+ { key: 'description', header: 'Description' },
361
+ ],
362
+ data: result.charts.map(chart => ({
363
+ name: chart.name,
364
+ version: chart.version,
365
+ appVersion: chart.appVersion,
366
+ description: chart.description,
367
+ })),
368
+ });
369
+ }
370
+ else {
371
+ ui.info('No charts found');
372
+ }
373
+ }
374
+ else {
375
+ ui.stopSpinnerFail('Failed to search charts');
376
+ if (result.error) {
377
+ ui.error(result.error);
378
+ }
379
+ }
380
+ }
381
+ catch (error) {
382
+ ui.stopSpinnerFail('Error searching Helm charts');
383
+ ui.error(error.message);
384
+ }
385
+ }
386
+ /**
387
+ * Add a Helm repository
388
+ */
389
+ export async function helmRepoAddCommand(name, url) {
390
+ ui.header('Helm Repo Add');
391
+ ui.info(`Name: ${name}`);
392
+ ui.info(`URL: ${url}`);
393
+ ui.startSpinner({ message: `Adding repository ${name}...` });
394
+ try {
395
+ const available = await helmClient.isAvailable();
396
+ if (!available) {
397
+ ui.stopSpinnerFail('Helm Tools Service not available');
398
+ ui.error('Please ensure the Helm Tools Service is running.');
399
+ return;
400
+ }
401
+ const result = await helmClient.repoAdd(name, url);
402
+ if (result.success) {
403
+ ui.stopSpinnerSuccess(`Added repository ${name}`);
404
+ if (result.output) {
405
+ ui.info(result.output);
406
+ }
407
+ }
408
+ else {
409
+ ui.stopSpinnerFail('Failed to add repository');
410
+ if (result.error) {
411
+ ui.error(result.error);
412
+ }
413
+ }
414
+ }
415
+ catch (error) {
416
+ ui.stopSpinnerFail('Error adding Helm repository');
417
+ ui.error(error.message);
418
+ }
419
+ }
420
+ /**
421
+ * Update Helm repositories
422
+ */
423
+ export async function helmRepoUpdateCommand() {
424
+ ui.header('Helm Repo Update');
425
+ ui.startSpinner({ message: 'Updating repositories...' });
426
+ try {
427
+ const available = await helmClient.isAvailable();
428
+ if (!available) {
429
+ ui.stopSpinnerFail('Helm Tools Service not available');
430
+ ui.error('Please ensure the Helm Tools Service is running.');
431
+ return;
432
+ }
433
+ const result = await helmClient.repoUpdate();
434
+ if (result.success) {
435
+ ui.stopSpinnerSuccess('Repositories updated');
436
+ if (result.output) {
437
+ ui.info(result.output);
438
+ }
439
+ }
440
+ else {
441
+ ui.stopSpinnerFail('Failed to update repositories');
442
+ if (result.error) {
443
+ ui.error(result.error);
444
+ }
445
+ }
446
+ }
447
+ catch (error) {
448
+ ui.stopSpinnerFail('Error updating Helm repositories');
449
+ ui.error(error.message);
450
+ }
451
+ }
452
+ /**
453
+ * Show chart information
454
+ */
455
+ export async function helmShowCommand(chart, options = {}) {
456
+ const sub = options.subcommand || 'all';
457
+ ui.header(`Helm Show ${sub} - ${chart}`);
458
+ if (options.version) {
459
+ ui.info(`Version: ${options.version}`);
460
+ }
461
+ ui.startSpinner({ message: `Fetching chart info for ${chart}...` });
462
+ try {
463
+ const available = await helmClient.isAvailable();
464
+ if (!available) {
465
+ ui.stopSpinnerFail('Helm Tools Service not available');
466
+ ui.error('Please ensure the Helm Tools Service is running.');
467
+ return;
468
+ }
469
+ const result = await helmClient.show(chart, {
470
+ subcommand: sub,
471
+ version: options.version,
472
+ });
473
+ if (result.success) {
474
+ ui.stopSpinnerSuccess(`Chart info retrieved`);
475
+ if (result.output) {
476
+ console.log(result.output);
477
+ }
478
+ }
479
+ else {
480
+ ui.stopSpinnerFail('Failed to show chart info');
481
+ if (result.error) {
482
+ ui.error(result.error);
483
+ }
484
+ }
485
+ }
486
+ catch (error) {
487
+ ui.stopSpinnerFail('Error showing chart info');
488
+ ui.error(error.message);
489
+ }
490
+ }
491
+ /**
492
+ * Lint a Helm chart
493
+ */
494
+ export async function helmLintCommand(chartPath, options = {}) {
495
+ ui.header('Helm Lint');
496
+ ui.info(`Chart: ${chartPath}`);
497
+ if (options.strict) {
498
+ ui.info('Mode: strict');
499
+ }
500
+ ui.startSpinner({ message: `Linting ${chartPath}...` });
501
+ try {
502
+ const available = await helmClient.isAvailable();
503
+ if (!available) {
504
+ ui.stopSpinnerFail('Helm Tools Service not available');
505
+ ui.error('Please ensure the Helm Tools Service is running.');
506
+ return;
507
+ }
508
+ const result = await helmClient.lint(chartPath, {
509
+ strict: options.strict,
510
+ valuesFiles: options.valuesFiles,
511
+ namespace: options.namespace,
512
+ });
513
+ if (result.success) {
514
+ const lintData = result.data;
515
+ const messages = lintData?.messages || [];
516
+ const errors = messages.filter((m) => m.severity === 'error');
517
+ const warnings = messages.filter((m) => m.severity === 'warning');
518
+ if (errors.length === 0) {
519
+ ui.stopSpinnerSuccess(`Chart linted successfully${warnings.length > 0 ? ` (${warnings.length} warnings)` : ''}`);
520
+ }
521
+ else {
522
+ ui.stopSpinnerFail(`Lint found ${errors.length} error(s)`);
523
+ }
524
+ if (messages.length > 0) {
525
+ ui.newLine();
526
+ for (const msg of messages) {
527
+ if (msg.severity === 'error') {
528
+ ui.error(` ${msg.message || msg}`);
529
+ }
530
+ else {
531
+ ui.warning(` ${msg.message || msg}`);
532
+ }
533
+ }
534
+ }
535
+ if (lintData?.output) {
536
+ ui.newLine();
537
+ ui.box({ title: 'Lint Output', content: lintData.output });
538
+ }
539
+ }
540
+ else {
541
+ ui.stopSpinnerFail('Lint failed');
542
+ if (result.error) {
543
+ ui.error(typeof result.error === 'string' ? result.error : 'Unknown error');
544
+ }
545
+ }
546
+ }
547
+ catch (error) {
548
+ ui.stopSpinnerFail('Error linting Helm chart');
549
+ ui.error(error.message);
550
+ }
551
+ }
552
+ /**
553
+ * Render chart templates locally without installing
554
+ */
555
+ export async function helmTemplateCommand(releaseName, chart, options = {}) {
556
+ ui.header('Helm Template');
557
+ ui.info(`Release name: ${releaseName}`);
558
+ ui.info(`Chart: ${chart}`);
559
+ if (options.namespace) {
560
+ ui.info(`Namespace: ${options.namespace}`);
561
+ }
562
+ if (options.version) {
563
+ ui.info(`Version: ${options.version}`);
564
+ }
565
+ ui.startSpinner({ message: `Rendering templates for ${chart}...` });
566
+ try {
567
+ const available = await helmClient.isAvailable();
568
+ if (!available) {
569
+ ui.stopSpinnerFail('Helm Tools Service not available');
570
+ ui.error('Please ensure the Helm Tools Service is running.');
571
+ return;
572
+ }
573
+ const result = await helmClient.template(releaseName, chart, {
574
+ namespace: options.namespace,
575
+ values: options.values,
576
+ valuesFile: options.valuesFile,
577
+ set: options.set,
578
+ version: options.version,
579
+ });
580
+ if (result.success) {
581
+ ui.stopSpinnerSuccess('Templates rendered successfully');
582
+ if (result.manifests) {
583
+ ui.newLine();
584
+ console.log(result.manifests);
585
+ }
586
+ }
587
+ else {
588
+ ui.stopSpinnerFail('Failed to render templates');
589
+ if (result.error) {
590
+ ui.error(result.error);
591
+ }
592
+ }
593
+ }
594
+ catch (error) {
595
+ ui.stopSpinnerFail('Error rendering Helm templates');
596
+ ui.error(error.message);
597
+ }
598
+ }
599
+ /**
600
+ * Package a chart directory into a chart archive
601
+ */
602
+ export async function helmPackageCommand(chartPath, options = {}) {
603
+ ui.header('Helm Package');
604
+ ui.info(`Chart path: ${chartPath}`);
605
+ if (options.destination) {
606
+ ui.info(`Destination: ${options.destination}`);
607
+ }
608
+ if (options.version) {
609
+ ui.info(`Version: ${options.version}`);
610
+ }
611
+ if (options.appVersion) {
612
+ ui.info(`App version: ${options.appVersion}`);
613
+ }
614
+ ui.startSpinner({ message: `Packaging chart ${chartPath}...` });
615
+ try {
616
+ const available = await helmClient.isAvailable();
617
+ if (!available) {
618
+ ui.stopSpinnerFail('Helm Tools Service not available');
619
+ ui.error('Please ensure the Helm Tools Service is running.');
620
+ return;
621
+ }
622
+ const result = await helmClient.package(chartPath, {
623
+ destination: options.destination,
624
+ version: options.version,
625
+ appVersion: options.appVersion,
626
+ dependencyUpdate: options.dependencyUpdate,
627
+ });
628
+ if (result.success) {
629
+ ui.stopSpinnerSuccess('Chart packaged successfully');
630
+ if (result.output) {
631
+ ui.box({ title: 'Output', content: result.output });
632
+ }
633
+ }
634
+ else {
635
+ ui.stopSpinnerFail('Failed to package chart');
636
+ if (result.error) {
637
+ ui.error(result.error);
638
+ }
639
+ }
640
+ }
641
+ catch (error) {
642
+ ui.stopSpinnerFail('Error packaging Helm chart');
643
+ ui.error(error.message);
644
+ }
645
+ }
646
+ /**
647
+ * Manage chart dependencies
648
+ */
649
+ export async function helmDependencyCommand(depSubcommand, chartPath) {
650
+ const action = depSubcommand === 'build' ? 'build' : 'update';
651
+ ui.header(`Helm Dependency ${action.charAt(0).toUpperCase() + action.slice(1)}`);
652
+ ui.info(`Chart path: ${chartPath}`);
653
+ ui.startSpinner({ message: `Running dependency ${action} for ${chartPath}...` });
654
+ try {
655
+ const available = await helmClient.isAvailable();
656
+ if (!available) {
657
+ ui.stopSpinnerFail('Helm Tools Service not available');
658
+ ui.error('Please ensure the Helm Tools Service is running.');
659
+ return;
660
+ }
661
+ const result = action === 'build'
662
+ ? await helmClient.dependencyBuild(chartPath)
663
+ : await helmClient.dependencyUpdate(chartPath);
664
+ if (result.success) {
665
+ ui.stopSpinnerSuccess(`Dependency ${action} completed`);
666
+ if (result.output) {
667
+ ui.box({ title: 'Output', content: result.output });
668
+ }
669
+ }
670
+ else {
671
+ ui.stopSpinnerFail(`Failed to ${action} dependencies`);
672
+ if (result.error) {
673
+ ui.error(result.error);
674
+ }
675
+ }
676
+ }
677
+ catch (error) {
678
+ ui.stopSpinnerFail(`Error running dependency ${action}`);
679
+ ui.error(error.message);
680
+ }
681
+ }
682
+ /**
683
+ * Show the status of a named release
684
+ */
685
+ export async function helmStatusCommand(releaseName, options = {}) {
686
+ ui.header(`Helm Status - ${releaseName}`);
687
+ if (options.namespace) {
688
+ ui.info(`Namespace: ${options.namespace}`);
689
+ }
690
+ if (options.revision !== undefined) {
691
+ ui.info(`Revision: ${options.revision}`);
692
+ }
693
+ ui.startSpinner({ message: `Fetching status for ${releaseName}...` });
694
+ try {
695
+ const available = await helmClient.isAvailable();
696
+ if (!available) {
697
+ ui.stopSpinnerFail('Helm Tools Service not available');
698
+ ui.error('Please ensure the Helm Tools Service is running.');
699
+ return;
700
+ }
701
+ const result = await helmClient.statusDetailed(releaseName, {
702
+ namespace: options.namespace,
703
+ revision: options.revision,
704
+ });
705
+ if (result.success) {
706
+ ui.stopSpinnerSuccess(`Status retrieved for ${releaseName}`);
707
+ if (result.status) {
708
+ const statusData = result.status;
709
+ if (typeof statusData === 'object') {
710
+ ui.newLine();
711
+ if (statusData.name) {
712
+ ui.info(`Name: ${statusData.name}`);
713
+ }
714
+ if (statusData.namespace) {
715
+ ui.info(`Namespace: ${statusData.namespace}`);
716
+ }
717
+ if (statusData.status) {
718
+ ui.info(`Status: ${statusData.status}`);
719
+ }
720
+ if (statusData.revision) {
721
+ ui.info(`Revision: ${statusData.revision}`);
722
+ }
723
+ if (statusData.chart) {
724
+ ui.info(`Chart: ${statusData.chart}`);
725
+ }
726
+ if (statusData.appVersion) {
727
+ ui.info(`App Ver: ${statusData.appVersion}`);
728
+ }
729
+ if (statusData.updated) {
730
+ ui.info(`Updated: ${statusData.updated}`);
731
+ }
732
+ if (statusData.description) {
733
+ ui.newLine();
734
+ ui.info(`Description: ${statusData.description}`);
735
+ }
736
+ if (statusData.notes) {
737
+ ui.newLine();
738
+ ui.box({ title: 'Notes', content: statusData.notes });
739
+ }
740
+ }
741
+ else if (typeof statusData === 'string') {
742
+ ui.newLine();
743
+ console.log(statusData);
744
+ }
745
+ }
746
+ }
747
+ else {
748
+ ui.stopSpinnerFail(`Failed to get status for ${releaseName}`);
749
+ if (result.error) {
750
+ ui.error(result.error);
751
+ }
752
+ }
753
+ }
754
+ catch (error) {
755
+ ui.stopSpinnerFail('Error fetching Helm release status');
756
+ ui.error(error.message);
757
+ }
758
+ }
759
+ /**
760
+ * Main helm command router
761
+ */
762
+ export async function helmCommand(subcommand, args) {
763
+ const options = {};
764
+ // Extract positional args and options
765
+ const positionalArgs = [];
766
+ for (let i = 0; i < args.length; i++) {
767
+ const arg = args[i];
768
+ if (arg === '-n' || arg === '--namespace') {
769
+ options.namespace = args[++i];
770
+ }
771
+ else if (arg === '-A' || arg === '--all-namespaces') {
772
+ options.allNamespaces = true;
773
+ }
774
+ else if (arg === '-f' || arg === '--values') {
775
+ options.valuesFile = args[++i];
776
+ }
777
+ else if (arg === '--version') {
778
+ options.version = args[++i];
779
+ }
780
+ else if (arg === '--wait') {
781
+ options.wait = true;
782
+ }
783
+ else if (arg === '--timeout') {
784
+ options.timeout = args[++i];
785
+ }
786
+ else if (arg === '--create-namespace') {
787
+ options.createNamespace = true;
788
+ }
789
+ else if (arg === '--dry-run') {
790
+ options.dryRun = true;
791
+ }
792
+ else if (arg === '--keep-history') {
793
+ options.keepHistory = true;
794
+ }
795
+ else if (arg === '-i' || arg === '--install') {
796
+ options.install = true;
797
+ }
798
+ else if (arg === '--yes' || arg === '-y') {
799
+ options.yes = true;
800
+ }
801
+ else if (arg === '--repo') {
802
+ options.repo = args[++i];
803
+ }
804
+ else if (arg === '--destination' || arg === '-d') {
805
+ options.destination = args[++i];
806
+ }
807
+ else if (arg === '--app-version') {
808
+ options.appVersion = args[++i];
809
+ }
810
+ else if (arg === '--dependency-update') {
811
+ options.dependencyUpdate = true;
812
+ }
813
+ else if (arg === '--revision') {
814
+ options.revision = parseInt(args[++i], 10);
815
+ }
816
+ else if (arg.startsWith('--set=')) {
817
+ const setExpr = arg.slice(6);
818
+ const eqIdx = setExpr.indexOf('=');
819
+ if (eqIdx !== -1) {
820
+ const key = setExpr.slice(0, eqIdx);
821
+ const value = setExpr.slice(eqIdx + 1);
822
+ options.set = options.set || {};
823
+ options.set[key] = value;
824
+ options.values = options.values || {};
825
+ options.values[key] = value;
826
+ }
827
+ }
828
+ else if (arg === '--set') {
829
+ const setExpr = args[++i] || '';
830
+ const eqIdx = setExpr.indexOf('=');
831
+ if (eqIdx !== -1) {
832
+ const key = setExpr.slice(0, eqIdx);
833
+ const value = setExpr.slice(eqIdx + 1);
834
+ options.set = options.set || {};
835
+ options.set[key] = value;
836
+ options.values = options.values || {};
837
+ options.values[key] = value;
838
+ }
839
+ }
840
+ else if (!arg.startsWith('-')) {
841
+ positionalArgs.push(arg);
842
+ }
843
+ }
844
+ const startTime = Date.now();
845
+ const entry = historyManager.addEntry('helm', [subcommand, ...args]);
846
+ try {
847
+ switch (subcommand) {
848
+ case 'list':
849
+ case 'ls':
850
+ await helmListCommand(options);
851
+ break;
852
+ case 'install':
853
+ if (positionalArgs.length < 2) {
854
+ ui.error('Usage: nimbus helm install <release-name> <chart>');
855
+ return;
856
+ }
857
+ await helmInstallCommand(positionalArgs[0], positionalArgs[1], options);
858
+ break;
859
+ case 'upgrade':
860
+ if (positionalArgs.length < 2) {
861
+ ui.error('Usage: nimbus helm upgrade <release-name> <chart>');
862
+ return;
863
+ }
864
+ await helmUpgradeCommand(positionalArgs[0], positionalArgs[1], options);
865
+ break;
866
+ case 'uninstall':
867
+ case 'delete':
868
+ if (positionalArgs.length < 1) {
869
+ ui.error('Usage: nimbus helm uninstall <release-name>');
870
+ return;
871
+ }
872
+ await helmUninstallCommand(positionalArgs[0], options);
873
+ break;
874
+ case 'rollback':
875
+ if (positionalArgs.length < 2) {
876
+ ui.error('Usage: nimbus helm rollback <release-name> <revision>');
877
+ return;
878
+ }
879
+ await helmRollbackCommand(positionalArgs[0], parseInt(positionalArgs[1], 10), options);
880
+ break;
881
+ case 'history':
882
+ if (positionalArgs.length < 1) {
883
+ ui.error('Usage: nimbus helm history <release-name>');
884
+ return;
885
+ }
886
+ await helmHistoryCommand(positionalArgs[0], options);
887
+ break;
888
+ case 'search':
889
+ if (positionalArgs.length < 1) {
890
+ ui.error('Usage: nimbus helm search <keyword>');
891
+ return;
892
+ }
893
+ await helmSearchCommand(positionalArgs[0], options);
894
+ break;
895
+ case 'show':
896
+ if (positionalArgs.length < 1) {
897
+ ui.error('Usage: nimbus helm show <chart> [--subcommand all|chart|readme|values|crds]');
898
+ return;
899
+ }
900
+ {
901
+ // First positional arg might be the subcommand (all, chart, readme, values, crds)
902
+ const validSubs = ['all', 'chart', 'readme', 'values', 'crds'];
903
+ let showSub = 'all';
904
+ let chartName = positionalArgs[0];
905
+ if (validSubs.includes(positionalArgs[0]) && positionalArgs[1]) {
906
+ showSub = positionalArgs[0];
907
+ chartName = positionalArgs[1];
908
+ }
909
+ await helmShowCommand(chartName, { ...options, subcommand: showSub });
910
+ }
911
+ break;
912
+ case 'repo':
913
+ if (positionalArgs[0] === 'add' && positionalArgs.length >= 3) {
914
+ await helmRepoAddCommand(positionalArgs[1], positionalArgs[2]);
915
+ }
916
+ else if (positionalArgs[0] === 'update') {
917
+ await helmRepoUpdateCommand();
918
+ }
919
+ else {
920
+ ui.error('Usage: nimbus helm repo add <name> <url> | nimbus helm repo update');
921
+ }
922
+ break;
923
+ case 'lint':
924
+ if (positionalArgs.length < 1) {
925
+ ui.error('Usage: nimbus helm lint <chart-path> [--strict]');
926
+ return;
927
+ }
928
+ {
929
+ const strict = args.includes('--strict');
930
+ const valuesFiles = [];
931
+ for (let i = 0; i < args.length; i++) {
932
+ if ((args[i] === '-f' || args[i] === '--values') && args[i + 1]) {
933
+ valuesFiles.push(args[i + 1]);
934
+ }
935
+ }
936
+ await helmLintCommand(positionalArgs[0], { ...options, strict, valuesFiles });
937
+ }
938
+ break;
939
+ case 'template':
940
+ if (positionalArgs.length < 2) {
941
+ ui.error('Usage: nimbus helm template <release-name> <chart> [--namespace <ns>] [--values <file>] [--set key=val] [--version <ver>]');
942
+ return;
943
+ }
944
+ await helmTemplateCommand(positionalArgs[0], positionalArgs[1], options);
945
+ break;
946
+ case 'package':
947
+ if (positionalArgs.length < 1) {
948
+ ui.error('Usage: nimbus helm package <chart-path> [--destination <dir>] [--version <ver>] [--app-version <ver>]');
949
+ return;
950
+ }
951
+ await helmPackageCommand(positionalArgs[0], options);
952
+ break;
953
+ case 'dependency':
954
+ case 'dep': {
955
+ // Supports: nimbus helm dependency update <chart-path>
956
+ // nimbus helm dependency build <chart-path>
957
+ const depSubcommand = positionalArgs[0] || 'update';
958
+ const depChartPath = positionalArgs[1];
959
+ if (!depChartPath) {
960
+ ui.error('Usage: nimbus helm dependency <update|build> <chart-path>');
961
+ return;
962
+ }
963
+ await helmDependencyCommand(depSubcommand, depChartPath);
964
+ break;
965
+ }
966
+ case 'status':
967
+ if (positionalArgs.length < 1) {
968
+ ui.error('Usage: nimbus helm status <release-name> [--namespace <ns>] [--revision <rev>]');
969
+ return;
970
+ }
971
+ await helmStatusCommand(positionalArgs[0], options);
972
+ break;
973
+ default:
974
+ ui.error(`Unknown helm subcommand: ${subcommand}`);
975
+ ui.info('Available commands: list, install, upgrade, uninstall, rollback, history, search, show, repo, lint, template, package, dependency, status');
976
+ }
977
+ historyManager.completeEntry(entry.id, 'success', Date.now() - startTime);
978
+ }
979
+ catch (error) {
980
+ historyManager.completeEntry(entry.id, 'failure', Date.now() - startTime, {
981
+ error: error.message,
982
+ });
983
+ throw error;
984
+ }
985
+ }