@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,955 @@
1
+ /**
2
+ * Init Command
3
+ *
4
+ * Initialize a Nimbus workspace in the current directory
5
+ * Performs comprehensive project scanning to detect:
6
+ * - Languages and versions
7
+ * - Frameworks
8
+ * - Package managers
9
+ * - Infrastructure as Code (Terraform, Pulumi, CDK, etc.)
10
+ * - CI/CD platforms
11
+ * - Cloud providers
12
+ */
13
+ import * as fs from 'fs';
14
+ import * as path from 'path';
15
+ import { ui } from '../wizard/ui';
16
+ import { select, input, confirm } from '../wizard/prompts';
17
+ import { createProjectScanner, generateProjectYaml, } from '../scanners';
18
+ import { initContextDatabase } from '../context/context-db';
19
+ const NIMBUS_DIR = '.nimbus';
20
+ const PROJECT_FILE = 'project.yaml';
21
+ const CONFIG_FILE = 'config.yaml';
22
+ // Template definitions
23
+ const TEMPLATES = {
24
+ vpc: {
25
+ description: 'AWS VPC with subnets, NAT gateway, and security groups',
26
+ files: {
27
+ 'terraform/main.tf': `# VPC Infrastructure
28
+ # Generated by Nimbus
29
+
30
+ terraform {
31
+ required_providers {
32
+ aws = {
33
+ source = "hashicorp/aws"
34
+ version = "~> 5.0"
35
+ }
36
+ }
37
+ }
38
+
39
+ provider "aws" {
40
+ region = var.aws_region
41
+ }
42
+
43
+ module "vpc" {
44
+ source = "terraform-aws-modules/vpc/aws"
45
+ version = "~> 5.0"
46
+
47
+ name = var.project_name
48
+ cidr = var.vpc_cidr
49
+
50
+ azs = var.availability_zones
51
+ private_subnets = var.private_subnet_cidrs
52
+ public_subnets = var.public_subnet_cidrs
53
+
54
+ enable_nat_gateway = true
55
+ single_nat_gateway = var.single_nat_gateway
56
+ enable_dns_hostnames = true
57
+ enable_dns_support = true
58
+
59
+ tags = var.tags
60
+ }
61
+ `,
62
+ 'terraform/variables.tf': `variable "project_name" {
63
+ description = "Name of the project"
64
+ type = string
65
+ }
66
+
67
+ variable "aws_region" {
68
+ description = "AWS region"
69
+ type = string
70
+ default = "us-east-1"
71
+ }
72
+
73
+ variable "vpc_cidr" {
74
+ description = "CIDR block for VPC"
75
+ type = string
76
+ default = "10.0.0.0/16"
77
+ }
78
+
79
+ variable "availability_zones" {
80
+ description = "Availability zones"
81
+ type = list(string)
82
+ default = ["us-east-1a", "us-east-1b", "us-east-1c"]
83
+ }
84
+
85
+ variable "private_subnet_cidrs" {
86
+ description = "CIDR blocks for private subnets"
87
+ type = list(string)
88
+ default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
89
+ }
90
+
91
+ variable "public_subnet_cidrs" {
92
+ description = "CIDR blocks for public subnets"
93
+ type = list(string)
94
+ default = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
95
+ }
96
+
97
+ variable "single_nat_gateway" {
98
+ description = "Use single NAT gateway for cost savings"
99
+ type = bool
100
+ default = true
101
+ }
102
+
103
+ variable "tags" {
104
+ description = "Tags to apply to resources"
105
+ type = map(string)
106
+ default = {}
107
+ }
108
+ `,
109
+ 'terraform/outputs.tf': `output "vpc_id" {
110
+ description = "VPC ID"
111
+ value = module.vpc.vpc_id
112
+ }
113
+
114
+ output "private_subnet_ids" {
115
+ description = "Private subnet IDs"
116
+ value = module.vpc.private_subnets
117
+ }
118
+
119
+ output "public_subnet_ids" {
120
+ description = "Public subnet IDs"
121
+ value = module.vpc.public_subnets
122
+ }
123
+
124
+ output "nat_gateway_ips" {
125
+ description = "NAT Gateway IPs"
126
+ value = module.vpc.nat_public_ips
127
+ }
128
+ `,
129
+ 'terraform/terraform.tfvars.example': `project_name = "my-project"
130
+ aws_region = "us-east-1"
131
+ vpc_cidr = "10.0.0.0/16"
132
+
133
+ tags = {
134
+ Environment = "dev"
135
+ ManagedBy = "terraform"
136
+ }
137
+ `,
138
+ },
139
+ },
140
+ eks: {
141
+ description: 'AWS EKS cluster with VPC and node groups',
142
+ files: {
143
+ 'terraform/main.tf': `# EKS Infrastructure
144
+ # Generated by Nimbus
145
+
146
+ terraform {
147
+ required_providers {
148
+ aws = {
149
+ source = "hashicorp/aws"
150
+ version = "~> 5.0"
151
+ }
152
+ kubernetes = {
153
+ source = "hashicorp/kubernetes"
154
+ version = "~> 2.0"
155
+ }
156
+ }
157
+ }
158
+
159
+ provider "aws" {
160
+ region = var.aws_region
161
+ }
162
+
163
+ module "vpc" {
164
+ source = "terraform-aws-modules/vpc/aws"
165
+ version = "~> 5.0"
166
+
167
+ name = "\${var.project_name}-vpc"
168
+ cidr = var.vpc_cidr
169
+
170
+ azs = var.availability_zones
171
+ private_subnets = var.private_subnet_cidrs
172
+ public_subnets = var.public_subnet_cidrs
173
+
174
+ enable_nat_gateway = true
175
+ single_nat_gateway = true
176
+ enable_dns_hostnames = true
177
+
178
+ public_subnet_tags = {
179
+ "kubernetes.io/role/elb" = 1
180
+ }
181
+
182
+ private_subnet_tags = {
183
+ "kubernetes.io/role/internal-elb" = 1
184
+ }
185
+
186
+ tags = var.tags
187
+ }
188
+
189
+ module "eks" {
190
+ source = "terraform-aws-modules/eks/aws"
191
+ version = "~> 19.0"
192
+
193
+ cluster_name = var.project_name
194
+ cluster_version = var.cluster_version
195
+
196
+ vpc_id = module.vpc.vpc_id
197
+ subnet_ids = module.vpc.private_subnets
198
+
199
+ cluster_endpoint_public_access = true
200
+
201
+ eks_managed_node_groups = {
202
+ default = {
203
+ min_size = var.node_min_size
204
+ max_size = var.node_max_size
205
+ desired_size = var.node_desired_size
206
+
207
+ instance_types = var.node_instance_types
208
+ capacity_type = "ON_DEMAND"
209
+ }
210
+ }
211
+
212
+ tags = var.tags
213
+ }
214
+ `,
215
+ 'terraform/variables.tf': `variable "project_name" {
216
+ description = "Name of the project / EKS cluster"
217
+ type = string
218
+ }
219
+
220
+ variable "aws_region" {
221
+ description = "AWS region"
222
+ type = string
223
+ default = "us-east-1"
224
+ }
225
+
226
+ variable "cluster_version" {
227
+ description = "Kubernetes version"
228
+ type = string
229
+ default = "1.28"
230
+ }
231
+
232
+ variable "vpc_cidr" {
233
+ description = "CIDR block for VPC"
234
+ type = string
235
+ default = "10.0.0.0/16"
236
+ }
237
+
238
+ variable "availability_zones" {
239
+ description = "Availability zones"
240
+ type = list(string)
241
+ default = ["us-east-1a", "us-east-1b"]
242
+ }
243
+
244
+ variable "private_subnet_cidrs" {
245
+ description = "CIDR blocks for private subnets"
246
+ type = list(string)
247
+ default = ["10.0.1.0/24", "10.0.2.0/24"]
248
+ }
249
+
250
+ variable "public_subnet_cidrs" {
251
+ description = "CIDR blocks for public subnets"
252
+ type = list(string)
253
+ default = ["10.0.101.0/24", "10.0.102.0/24"]
254
+ }
255
+
256
+ variable "node_instance_types" {
257
+ description = "Instance types for node group"
258
+ type = list(string)
259
+ default = ["t3.medium"]
260
+ }
261
+
262
+ variable "node_min_size" {
263
+ description = "Minimum number of nodes"
264
+ type = number
265
+ default = 1
266
+ }
267
+
268
+ variable "node_max_size" {
269
+ description = "Maximum number of nodes"
270
+ type = number
271
+ default = 5
272
+ }
273
+
274
+ variable "node_desired_size" {
275
+ description = "Desired number of nodes"
276
+ type = number
277
+ default = 2
278
+ }
279
+
280
+ variable "tags" {
281
+ description = "Tags to apply to resources"
282
+ type = map(string)
283
+ default = {}
284
+ }
285
+ `,
286
+ 'terraform/outputs.tf': `output "cluster_endpoint" {
287
+ description = "EKS cluster endpoint"
288
+ value = module.eks.cluster_endpoint
289
+ }
290
+
291
+ output "cluster_name" {
292
+ description = "EKS cluster name"
293
+ value = module.eks.cluster_name
294
+ }
295
+
296
+ output "cluster_certificate_authority_data" {
297
+ description = "Base64 encoded certificate data"
298
+ value = module.eks.cluster_certificate_authority_data
299
+ sensitive = true
300
+ }
301
+
302
+ output "configure_kubectl" {
303
+ description = "Configure kubectl"
304
+ value = "aws eks update-kubeconfig --region \${var.aws_region} --name \${module.eks.cluster_name}"
305
+ }
306
+ `,
307
+ },
308
+ },
309
+ 'full-stack': {
310
+ description: 'Complete AWS stack with VPC, EKS, RDS, and ElastiCache',
311
+ files: {
312
+ 'terraform/main.tf': `# Full Stack Infrastructure
313
+ # Generated by Nimbus
314
+
315
+ terraform {
316
+ required_providers {
317
+ aws = {
318
+ source = "hashicorp/aws"
319
+ version = "~> 5.0"
320
+ }
321
+ }
322
+ }
323
+
324
+ provider "aws" {
325
+ region = var.aws_region
326
+ }
327
+
328
+ # VPC
329
+ module "vpc" {
330
+ source = "terraform-aws-modules/vpc/aws"
331
+ version = "~> 5.0"
332
+
333
+ name = "\${var.project_name}-vpc"
334
+ cidr = "10.0.0.0/16"
335
+
336
+ azs = ["us-east-1a", "us-east-1b"]
337
+ private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
338
+ public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
339
+ database_subnets = ["10.0.201.0/24", "10.0.202.0/24"]
340
+
341
+ enable_nat_gateway = true
342
+ single_nat_gateway = true
343
+ enable_dns_hostnames = true
344
+
345
+ create_database_subnet_group = true
346
+
347
+ tags = var.tags
348
+ }
349
+
350
+ # EKS Cluster
351
+ module "eks" {
352
+ source = "terraform-aws-modules/eks/aws"
353
+ version = "~> 19.0"
354
+
355
+ cluster_name = "\${var.project_name}-cluster"
356
+ cluster_version = "1.28"
357
+
358
+ vpc_id = module.vpc.vpc_id
359
+ subnet_ids = module.vpc.private_subnets
360
+
361
+ cluster_endpoint_public_access = true
362
+
363
+ eks_managed_node_groups = {
364
+ default = {
365
+ min_size = 2
366
+ max_size = 10
367
+ desired_size = 3
368
+ instance_types = ["t3.medium"]
369
+ }
370
+ }
371
+
372
+ tags = var.tags
373
+ }
374
+
375
+ # RDS PostgreSQL
376
+ module "rds" {
377
+ source = "terraform-aws-modules/rds/aws"
378
+ version = "~> 6.0"
379
+
380
+ identifier = "\${var.project_name}-db"
381
+
382
+ engine = "postgres"
383
+ engine_version = "15"
384
+ family = "postgres15"
385
+ major_engine_version = "15"
386
+ instance_class = "db.t3.micro"
387
+
388
+ allocated_storage = 20
389
+ max_allocated_storage = 100
390
+
391
+ db_name = "app"
392
+ username = "dbadmin"
393
+ port = 5432
394
+
395
+ db_subnet_group_name = module.vpc.database_subnet_group_name
396
+ vpc_security_group_ids = [aws_security_group.rds.id]
397
+
398
+ maintenance_window = "Mon:00:00-Mon:03:00"
399
+ backup_window = "03:00-06:00"
400
+ backup_retention_period = 7
401
+
402
+ tags = var.tags
403
+ }
404
+
405
+ # ElastiCache Redis
406
+ resource "aws_elasticache_subnet_group" "main" {
407
+ name = "\${var.project_name}-cache-subnet"
408
+ subnet_ids = module.vpc.private_subnets
409
+ }
410
+
411
+ resource "aws_elasticache_cluster" "main" {
412
+ cluster_id = "\${var.project_name}-cache"
413
+ engine = "redis"
414
+ node_type = "cache.t3.micro"
415
+ num_cache_nodes = 1
416
+ parameter_group_name = "default.redis7"
417
+ port = 6379
418
+ subnet_group_name = aws_elasticache_subnet_group.main.name
419
+ security_group_ids = [aws_security_group.redis.id]
420
+
421
+ tags = var.tags
422
+ }
423
+
424
+ # Security Groups
425
+ resource "aws_security_group" "rds" {
426
+ name = "\${var.project_name}-rds-sg"
427
+ description = "Allow PostgreSQL from VPC"
428
+ vpc_id = module.vpc.vpc_id
429
+
430
+ ingress {
431
+ from_port = 5432
432
+ to_port = 5432
433
+ protocol = "tcp"
434
+ cidr_blocks = [module.vpc.vpc_cidr_block]
435
+ }
436
+
437
+ tags = var.tags
438
+ }
439
+
440
+ resource "aws_security_group" "redis" {
441
+ name = "\${var.project_name}-redis-sg"
442
+ description = "Allow Redis from VPC"
443
+ vpc_id = module.vpc.vpc_id
444
+
445
+ ingress {
446
+ from_port = 6379
447
+ to_port = 6379
448
+ protocol = "tcp"
449
+ cidr_blocks = [module.vpc.vpc_cidr_block]
450
+ }
451
+
452
+ tags = var.tags
453
+ }
454
+ `,
455
+ 'terraform/variables.tf': `variable "project_name" {
456
+ description = "Name of the project"
457
+ type = string
458
+ }
459
+
460
+ variable "aws_region" {
461
+ description = "AWS region"
462
+ type = string
463
+ default = "us-east-1"
464
+ }
465
+
466
+ variable "tags" {
467
+ description = "Tags to apply to resources"
468
+ type = map(string)
469
+ default = {
470
+ ManagedBy = "terraform"
471
+ }
472
+ }
473
+ `,
474
+ 'terraform/outputs.tf': `output "vpc_id" {
475
+ value = module.vpc.vpc_id
476
+ }
477
+
478
+ output "eks_cluster_endpoint" {
479
+ value = module.eks.cluster_endpoint
480
+ }
481
+
482
+ output "rds_endpoint" {
483
+ value = module.rds.db_instance_endpoint
484
+ }
485
+
486
+ output "redis_endpoint" {
487
+ value = aws_elasticache_cluster.main.cache_nodes[0].address
488
+ }
489
+ `,
490
+ },
491
+ },
492
+ minimal: {
493
+ description: 'Minimal Terraform setup with just provider configuration',
494
+ files: {
495
+ 'terraform/main.tf': `# Minimal Terraform Configuration
496
+ # Generated by Nimbus
497
+
498
+ terraform {
499
+ required_version = ">= 1.0"
500
+
501
+ required_providers {
502
+ aws = {
503
+ source = "hashicorp/aws"
504
+ version = "~> 5.0"
505
+ }
506
+ }
507
+
508
+ # Uncomment to use S3 backend
509
+ # backend "s3" {
510
+ # bucket = "your-terraform-state-bucket"
511
+ # key = "terraform.tfstate"
512
+ # region = "us-east-1"
513
+ # }
514
+ }
515
+
516
+ provider "aws" {
517
+ region = var.aws_region
518
+
519
+ default_tags {
520
+ tags = {
521
+ ManagedBy = "terraform"
522
+ Project = var.project_name
523
+ }
524
+ }
525
+ }
526
+ `,
527
+ 'terraform/variables.tf': `variable "project_name" {
528
+ description = "Name of the project"
529
+ type = string
530
+ }
531
+
532
+ variable "aws_region" {
533
+ description = "AWS region"
534
+ type = string
535
+ default = "us-east-1"
536
+ }
537
+
538
+ variable "environment" {
539
+ description = "Environment (dev, staging, prod)"
540
+ type = string
541
+ default = "dev"
542
+ }
543
+ `,
544
+ 'terraform/outputs.tf': `# Add outputs here as you create resources
545
+ `,
546
+ 'terraform/.gitignore': `# Terraform
547
+ *.tfstate
548
+ *.tfstate.*
549
+ .terraform/
550
+ .terraform.lock.hcl
551
+ *.tfvars
552
+ !*.tfvars.example
553
+ crash.log
554
+ override.tf
555
+ override.tf.json
556
+ *_override.tf
557
+ *_override.tf.json
558
+ `,
559
+ },
560
+ },
561
+ };
562
+ /**
563
+ * Generate template files
564
+ */
565
+ function generateTemplateFiles(templateName, outputDir, projectName) {
566
+ const template = TEMPLATES[templateName];
567
+ if (!template) {
568
+ return;
569
+ }
570
+ for (const [filePath, content] of Object.entries(template.files)) {
571
+ const fullPath = path.join(outputDir, filePath);
572
+ const dir = path.dirname(fullPath);
573
+ if (!fs.existsSync(dir)) {
574
+ fs.mkdirSync(dir, { recursive: true });
575
+ }
576
+ // Replace project name placeholder
577
+ const finalContent = content.replace(/\$\{var\.project_name\}/g, projectName);
578
+ fs.writeFileSync(fullPath, finalContent);
579
+ }
580
+ }
581
+ /**
582
+ * Create .gitignore entry for Nimbus
583
+ */
584
+ function createGitignoreEntry() {
585
+ return `
586
+ # Nimbus
587
+ .nimbus/
588
+ *.nimbus-session
589
+ `;
590
+ }
591
+ /**
592
+ * Display scan results in a summary table
593
+ */
594
+ function displayScanSummary(context) {
595
+ ui.newLine();
596
+ ui.section('Project Analysis');
597
+ // Languages
598
+ if (context.structure.languages.length > 0) {
599
+ ui.print(` ${ui.bold('Languages:')}`);
600
+ for (const lang of context.structure.languages.slice(0, 5)) {
601
+ const version = lang.version ? ` (${lang.version})` : '';
602
+ const confidence = lang.confidence === 'high' ? ui.color('●', 'green') : ui.color('○', 'yellow');
603
+ ui.print(` ${confidence} ${lang.name}${version}`);
604
+ }
605
+ if (context.structure.languages.length > 5) {
606
+ ui.print(ui.dim(` ... and ${context.structure.languages.length - 5} more`));
607
+ }
608
+ ui.newLine();
609
+ }
610
+ // Frameworks
611
+ if (context.structure.frameworks.length > 0) {
612
+ ui.print(` ${ui.bold('Frameworks:')}`);
613
+ for (const fw of context.structure.frameworks.slice(0, 5)) {
614
+ const version = fw.version ? ` (${fw.version})` : '';
615
+ const confidence = fw.confidence === 'high' ? ui.color('●', 'green') : ui.color('○', 'yellow');
616
+ ui.print(` ${confidence} ${fw.name}${version}`);
617
+ }
618
+ if (context.structure.frameworks.length > 5) {
619
+ ui.print(ui.dim(` ... and ${context.structure.frameworks.length - 5} more`));
620
+ }
621
+ ui.newLine();
622
+ }
623
+ // Package Managers
624
+ if (context.structure.packageManagers.length > 0) {
625
+ ui.print(` ${ui.bold('Package Managers:')}`);
626
+ const pmList = context.structure.packageManagers.map(pm => pm.name).join(', ');
627
+ ui.print(` ${pmList}`);
628
+ ui.newLine();
629
+ }
630
+ // Infrastructure
631
+ const hasInfra = context.files.terraform.length > 0 ||
632
+ context.files.kubernetes.length > 0 ||
633
+ context.files.docker.length > 0;
634
+ if (hasInfra) {
635
+ ui.print(` ${ui.bold('Infrastructure:')}`);
636
+ if (context.files.terraform.length > 0) {
637
+ ui.print(` ${ui.color('●', 'green')} Terraform (${context.files.terraform.length} files)`);
638
+ }
639
+ if (context.files.kubernetes.length > 0) {
640
+ ui.print(` ${ui.color('●', 'green')} Kubernetes (${context.files.kubernetes.length} files)`);
641
+ }
642
+ if (context.files.docker.length > 0) {
643
+ ui.print(` ${ui.color('●', 'green')} Docker (${context.files.docker.length} files)`);
644
+ }
645
+ ui.newLine();
646
+ }
647
+ // CI/CD
648
+ if (context.cicd.platform) {
649
+ ui.print(` ${ui.bold('CI/CD:')}`);
650
+ ui.print(` ${ui.color('●', 'green')} ${context.cicd.platform} (${context.cicd.workflows.length} workflows)`);
651
+ ui.newLine();
652
+ }
653
+ // Cloud Providers
654
+ if (context.cloud.providers.length > 0) {
655
+ ui.print(` ${ui.bold('Cloud Providers:')}`);
656
+ for (const provider of context.cloud.providers) {
657
+ ui.print(` ${ui.color('●', 'green')} ${provider.toUpperCase()}`);
658
+ }
659
+ if (context.cloud.regions.length > 0) {
660
+ ui.print(` ${ui.dim('Regions:')} ${context.cloud.regions.slice(0, 5).join(', ')}`);
661
+ }
662
+ ui.newLine();
663
+ }
664
+ // Git Info
665
+ if (context.git.isRepo) {
666
+ ui.print(` ${ui.bold('Git:')}`);
667
+ ui.print(` Branch: ${context.git.branch}`);
668
+ if (context.git.remote) {
669
+ ui.print(` Remote: ${context.git.remote}`);
670
+ }
671
+ ui.newLine();
672
+ }
673
+ // Project Type
674
+ ui.print(` ${ui.bold('Project Type:')} ${context.structure.type}`);
675
+ ui.newLine();
676
+ }
677
+ /**
678
+ * Create workspace config.yaml
679
+ */
680
+ function createWorkspaceConfig(options) {
681
+ const lines = [
682
+ '# Nimbus Workspace Configuration',
683
+ '# This file configures Nimbus for this project.',
684
+ '# See project.yaml for detected project context.',
685
+ '',
686
+ 'workspace:',
687
+ ` name: ${options.name}`,
688
+ ];
689
+ if (options.provider) {
690
+ lines.push(` defaultProvider: ${options.provider}`);
691
+ }
692
+ if (options.output) {
693
+ lines.push(` outputDirectory: ${options.output}`);
694
+ }
695
+ lines.push('');
696
+ lines.push('# Safety settings');
697
+ lines.push('safety:');
698
+ lines.push(' requireApproval: true');
699
+ lines.push(' protectedEnvironments: [production, prod]');
700
+ lines.push(' costThreshold: 500');
701
+ return `${lines.join('\n')}\n`;
702
+ }
703
+ /**
704
+ * Init command handler
705
+ */
706
+ export async function initCommand(options = {}) {
707
+ const cwd = process.cwd();
708
+ const nimbusDir = path.join(cwd, NIMBUS_DIR);
709
+ const projectPath = path.join(nimbusDir, PROJECT_FILE);
710
+ const configPath = path.join(nimbusDir, CONFIG_FILE);
711
+ // Check if already initialized
712
+ if (fs.existsSync(nimbusDir) && !options.force) {
713
+ ui.warning(`Nimbus workspace already exists at: ${nimbusDir}`);
714
+ if (!options.nonInteractive) {
715
+ const reinit = await confirm({
716
+ message: 'Reinitialize this workspace?',
717
+ defaultValue: false,
718
+ });
719
+ if (!reinit) {
720
+ ui.info('Workspace unchanged.');
721
+ return;
722
+ }
723
+ }
724
+ else {
725
+ ui.info('Use --force to reinitialize.');
726
+ return;
727
+ }
728
+ }
729
+ // Start scanning
730
+ ui.newLine();
731
+ ui.header('Initialize Nimbus Workspace', cwd);
732
+ const scanDepth = options.scanDepth || 'standard';
733
+ ui.startSpinner({ message: `Scanning project (${scanDepth} mode)...` });
734
+ // Create scanner and run scan
735
+ const scanner = createProjectScanner();
736
+ const scanOptions = {
737
+ depth: scanDepth,
738
+ instructions: options.instructions,
739
+ maxDepth: options.maxDepth,
740
+ };
741
+ let context;
742
+ try {
743
+ context = await scanner.scan(cwd, scanOptions);
744
+ ui.stopSpinnerSuccess('Project scan complete');
745
+ }
746
+ catch (error) {
747
+ ui.stopSpinnerFail('Project scan failed');
748
+ ui.error(error.message);
749
+ return;
750
+ }
751
+ // Display scan summary
752
+ displayScanSummary(context);
753
+ // Interactive configuration
754
+ let projectName = options.name || context.project.name;
755
+ let provider = options.provider;
756
+ let outputDir = options.output;
757
+ if (!options.nonInteractive) {
758
+ // Project name
759
+ projectName = await input({
760
+ message: 'Project name:',
761
+ defaultValue: context.project.name,
762
+ });
763
+ // Cloud provider - pre-select if detected
764
+ const detectedProvider = context.cloud.providers[0] || '';
765
+ const providerOptions = [
766
+ { label: 'AWS', value: 'aws', description: 'Amazon Web Services' },
767
+ { label: 'GCP', value: 'gcp', description: 'Google Cloud Platform' },
768
+ { label: 'Azure', value: 'azure', description: 'Microsoft Azure' },
769
+ { label: 'None', value: '', description: 'No default provider' },
770
+ ];
771
+ // Move detected provider to top
772
+ if (detectedProvider) {
773
+ const idx = providerOptions.findIndex(o => o.value === detectedProvider);
774
+ if (idx > 0) {
775
+ const [detected] = providerOptions.splice(idx, 1);
776
+ detected.label += ' (detected)';
777
+ providerOptions.unshift(detected);
778
+ }
779
+ }
780
+ provider = (await select({
781
+ message: 'Default cloud provider:',
782
+ options: providerOptions,
783
+ }));
784
+ // Output directory
785
+ const defaultOutput = context.files.terraform.length > 0 ? './terraform' : './infrastructure';
786
+ outputDir = await input({
787
+ message: 'Output directory for generated code:',
788
+ defaultValue: defaultOutput,
789
+ });
790
+ // Update .gitignore
791
+ const gitignorePath = path.join(cwd, '.gitignore');
792
+ if (fs.existsSync(gitignorePath)) {
793
+ const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
794
+ if (!gitignoreContent.includes('.nimbus/')) {
795
+ const updateGitignore = await confirm({
796
+ message: 'Add .nimbus/ to .gitignore?',
797
+ defaultValue: true,
798
+ });
799
+ if (updateGitignore) {
800
+ fs.appendFileSync(gitignorePath, createGitignoreEntry());
801
+ ui.success('Updated .gitignore');
802
+ }
803
+ }
804
+ }
805
+ }
806
+ else {
807
+ // Non-interactive: use detected or default values
808
+ provider = provider || context.cloud.providers[0] || '';
809
+ outputDir =
810
+ outputDir || (context.files.terraform.length > 0 ? './terraform' : './infrastructure');
811
+ }
812
+ // Update context with user-provided name
813
+ context.project.name = projectName;
814
+ // Create .nimbus directory
815
+ if (!fs.existsSync(nimbusDir)) {
816
+ fs.mkdirSync(nimbusDir, { recursive: true });
817
+ }
818
+ // Generate and write project.yaml
819
+ const projectYaml = generateProjectYaml(context);
820
+ fs.writeFileSync(projectPath, projectYaml);
821
+ // Generate and write config.yaml
822
+ const configContent = createWorkspaceConfig({
823
+ name: projectName,
824
+ provider: provider || undefined,
825
+ output: outputDir || undefined,
826
+ });
827
+ fs.writeFileSync(configPath, configContent);
828
+ // Create .gitkeep for empty directories
829
+ const gitkeepPath = path.join(nimbusDir, '.gitkeep');
830
+ if (!fs.existsSync(gitkeepPath)) {
831
+ fs.writeFileSync(gitkeepPath, '');
832
+ }
833
+ // Initialize context database
834
+ try {
835
+ const contextDb = initContextDatabase(cwd);
836
+ contextDb.recordCommand('init', `--name ${projectName}`, 'success');
837
+ contextDb.close();
838
+ }
839
+ catch {
840
+ // Non-critical: context DB is optional
841
+ }
842
+ // Generate template files if specified
843
+ if (options.template) {
844
+ const template = TEMPLATES[options.template];
845
+ if (template) {
846
+ ui.startSpinner({ message: `Generating ${options.template} template...` });
847
+ generateTemplateFiles(options.template, cwd, projectName);
848
+ ui.stopSpinnerSuccess(`Generated ${options.template} template`);
849
+ }
850
+ }
851
+ else if (!options.nonInteractive && context.files.terraform.length === 0) {
852
+ // Offer to generate a template if no existing Terraform
853
+ const useTemplate = await confirm({
854
+ message: 'No existing Terraform files found. Generate a starter template?',
855
+ defaultValue: true,
856
+ });
857
+ if (useTemplate) {
858
+ const templateChoice = await select({
859
+ message: 'Select a template:',
860
+ options: [
861
+ { label: 'Minimal', value: 'minimal', description: 'Basic provider setup' },
862
+ { label: 'VPC', value: 'vpc', description: 'AWS VPC with subnets and NAT' },
863
+ { label: 'EKS', value: 'eks', description: 'EKS cluster with VPC' },
864
+ { label: 'Full Stack', value: 'full-stack', description: 'VPC + EKS + RDS + Redis' },
865
+ ],
866
+ });
867
+ ui.startSpinner({ message: `Generating ${templateChoice} template...` });
868
+ generateTemplateFiles(templateChoice, cwd, projectName);
869
+ ui.stopSpinnerSuccess(`Generated ${templateChoice} template`);
870
+ }
871
+ }
872
+ // Prompt for telemetry opt-in
873
+ if (!options.nonInteractive) {
874
+ ui.newLine();
875
+ const enableTelemetry = await confirm({
876
+ message: 'Enable anonymous usage telemetry? (helps improve Nimbus)',
877
+ defaultValue: false,
878
+ });
879
+ if (enableTelemetry) {
880
+ try {
881
+ const { homedir } = await import('os');
882
+ const telemetryConfigPath = path.join(homedir(), '.nimbus', 'config.json');
883
+ const telemetryDir = path.join(homedir(), '.nimbus');
884
+ if (!fs.existsSync(telemetryDir)) {
885
+ fs.mkdirSync(telemetryDir, { recursive: true });
886
+ }
887
+ let telemetryConfig = {};
888
+ try {
889
+ if (fs.existsSync(telemetryConfigPath)) {
890
+ telemetryConfig = JSON.parse(fs.readFileSync(telemetryConfigPath, 'utf-8'));
891
+ }
892
+ }
893
+ catch {
894
+ /* ignore */
895
+ }
896
+ const { randomUUID } = await import('crypto');
897
+ telemetryConfig.telemetry = {
898
+ ...telemetryConfig.telemetry,
899
+ enabled: true,
900
+ anonymousId: telemetryConfig.telemetry?.anonymousId || randomUUID(),
901
+ };
902
+ fs.writeFileSync(telemetryConfigPath, JSON.stringify(telemetryConfig, null, 2));
903
+ ui.success('Telemetry enabled');
904
+ }
905
+ catch {
906
+ // Non-critical
907
+ }
908
+ }
909
+ }
910
+ ui.newLine();
911
+ ui.success(`Nimbus workspace initialized!`);
912
+ ui.newLine();
913
+ ui.print(` ${ui.dim('Project:')} ${projectName}`);
914
+ ui.print(` ${ui.dim('Type:')} ${context.structure.type}`);
915
+ ui.print(` ${ui.dim('Config:')} ${configPath}`);
916
+ ui.print(` ${ui.dim('Context:')} ${projectPath}`);
917
+ if (provider) {
918
+ ui.print(` ${ui.dim('Provider:')} ${provider}`);
919
+ }
920
+ if (outputDir) {
921
+ ui.print(` ${ui.dim('Output:')} ${outputDir}`);
922
+ }
923
+ ui.newLine();
924
+ // Show detected summary
925
+ const summaryItems = [];
926
+ if (context.structure.languages.length > 0) {
927
+ summaryItems.push(`${context.structure.languages.length} languages`);
928
+ }
929
+ if (context.structure.frameworks.length > 0) {
930
+ summaryItems.push(`${context.structure.frameworks.length} frameworks`);
931
+ }
932
+ if (context.files.terraform.length > 0) {
933
+ summaryItems.push('Terraform');
934
+ }
935
+ if (context.files.kubernetes.length > 0) {
936
+ summaryItems.push('Kubernetes');
937
+ }
938
+ if (context.cicd.platform) {
939
+ summaryItems.push(context.cicd.platform);
940
+ }
941
+ if (summaryItems.length > 0) {
942
+ ui.print(ui.dim(` Detected: ${summaryItems.join(', ')}`));
943
+ ui.newLine();
944
+ }
945
+ ui.print(ui.dim('Next steps:'));
946
+ ui.print(` ${ui.dim('1.')} Run ${ui.color('nimbus login', 'cyan')} to configure authentication`);
947
+ ui.print(` ${ui.dim('2.')} Run ${ui.color('nimbus chat', 'cyan')} to start a conversation`);
948
+ if (context.files.terraform.length > 0) {
949
+ ui.print(` ${ui.dim('3.')} Run ${ui.color('nimbus plan terraform', 'cyan')} to preview infrastructure`);
950
+ }
951
+ else {
952
+ ui.print(` ${ui.dim('3.')} Run ${ui.color('nimbus generate terraform', 'cyan')} to generate infrastructure`);
953
+ }
954
+ ui.newLine();
955
+ }