@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,309 @@
1
+ /**
2
+ * Team Commands
3
+ * Team collaboration CLI commands
4
+ */
5
+ import { ui } from '../../wizard/ui';
6
+ import { teamClient } from '../../clients/enterprise-client';
7
+ import { getAuthStore } from '../../auth';
8
+ /**
9
+ * Get current user ID from auth store
10
+ */
11
+ function getCurrentUserId() {
12
+ const authStore = getAuthStore();
13
+ const auth = authStore.load();
14
+ const userId = auth?.identity?.github?.username;
15
+ if (!userId) {
16
+ throw new Error('Not authenticated. Run `nimbus login` first.');
17
+ }
18
+ return userId;
19
+ }
20
+ /**
21
+ * Get current team ID from config or environment
22
+ */
23
+ function getCurrentTeamId() {
24
+ return process.env.NIMBUS_TEAM_ID || null;
25
+ }
26
+ /**
27
+ * Parse team create options
28
+ */
29
+ export function parseTeamCreateOptions(args) {
30
+ const options = {};
31
+ for (let i = 0; i < args.length; i++) {
32
+ const arg = args[i];
33
+ if (arg === '--non-interactive') {
34
+ options.nonInteractive = true;
35
+ }
36
+ else if (!arg.startsWith('-') && !options.name) {
37
+ options.name = arg;
38
+ }
39
+ }
40
+ return options;
41
+ }
42
+ /**
43
+ * Parse team invite options
44
+ */
45
+ export function parseTeamInviteOptions(args) {
46
+ const options = {};
47
+ for (let i = 0; i < args.length; i++) {
48
+ const arg = args[i];
49
+ if (arg === '--role' && args[i + 1]) {
50
+ options.role = args[++i];
51
+ }
52
+ else if (arg === '--non-interactive') {
53
+ options.nonInteractive = true;
54
+ }
55
+ else if (!arg.startsWith('-') && !options.email) {
56
+ options.email = arg;
57
+ }
58
+ }
59
+ return options;
60
+ }
61
+ /**
62
+ * Parse team members options
63
+ */
64
+ export function parseTeamMembersOptions(args) {
65
+ const options = {};
66
+ for (let i = 0; i < args.length; i++) {
67
+ const arg = args[i];
68
+ if (arg === '--json') {
69
+ options.json = true;
70
+ }
71
+ else if (arg === '--non-interactive') {
72
+ options.nonInteractive = true;
73
+ }
74
+ }
75
+ return options;
76
+ }
77
+ /**
78
+ * Parse team remove options
79
+ */
80
+ export function parseTeamRemoveOptions(args) {
81
+ const options = {};
82
+ for (let i = 0; i < args.length; i++) {
83
+ const arg = args[i];
84
+ if (arg === '--force' || arg === '-f') {
85
+ options.force = true;
86
+ }
87
+ else if (arg === '--non-interactive') {
88
+ options.nonInteractive = true;
89
+ }
90
+ else if (!arg.startsWith('-') && !options.email) {
91
+ options.email = arg;
92
+ }
93
+ }
94
+ return options;
95
+ }
96
+ /**
97
+ * Parse team switch options
98
+ */
99
+ export function parseTeamSwitchOptions(args) {
100
+ const options = {};
101
+ for (let i = 0; i < args.length; i++) {
102
+ const arg = args[i];
103
+ if (arg === '--non-interactive') {
104
+ options.nonInteractive = true;
105
+ }
106
+ else if (!arg.startsWith('-') && !options.teamId) {
107
+ options.teamId = arg;
108
+ }
109
+ }
110
+ return options;
111
+ }
112
+ /**
113
+ * Team create command
114
+ */
115
+ export async function teamCreateCommand(options) {
116
+ try {
117
+ const name = options.name;
118
+ if (!name) {
119
+ ui.error('Team name is required');
120
+ ui.info('Usage: nimbus team create <name>');
121
+ return;
122
+ }
123
+ const userId = getCurrentUserId();
124
+ ui.startSpinner({ message: 'Creating team...' });
125
+ const team = await teamClient.createTeam({ name, ownerId: userId });
126
+ ui.stopSpinnerSuccess(`Team "${team.name}" created`);
127
+ ui.newLine();
128
+ ui.info(`Team ID: ${team.id}`);
129
+ ui.info(`To use this team, run: nimbus team switch ${team.id}`);
130
+ ui.info(`Or set environment variable: export NIMBUS_TEAM_ID=${team.id}`);
131
+ }
132
+ catch (error) {
133
+ ui.stopSpinnerFail('Failed to create team');
134
+ ui.error(error.message);
135
+ }
136
+ }
137
+ /**
138
+ * Team invite command
139
+ */
140
+ export async function teamInviteCommand(options) {
141
+ try {
142
+ const email = options.email;
143
+ if (!email) {
144
+ ui.error('Email is required');
145
+ ui.info('Usage: nimbus team invite <email> [--role member|admin|viewer]');
146
+ return;
147
+ }
148
+ const teamId = getCurrentTeamId();
149
+ if (!teamId) {
150
+ ui.error('No team selected. Run `nimbus team switch <team-id>` first.');
151
+ return;
152
+ }
153
+ ui.startSpinner({ message: `Inviting ${email}...` });
154
+ const member = await teamClient.inviteMember(teamId, {
155
+ email,
156
+ role: options.role || 'member',
157
+ });
158
+ ui.stopSpinnerSuccess(`Invited ${email} as ${member.role}`);
159
+ }
160
+ catch (error) {
161
+ ui.stopSpinnerFail('Failed to invite member');
162
+ ui.error(error.message);
163
+ }
164
+ }
165
+ /**
166
+ * Team members command
167
+ */
168
+ export async function teamMembersCommand(options) {
169
+ try {
170
+ const teamId = getCurrentTeamId();
171
+ if (!teamId) {
172
+ ui.error('No team selected. Run `nimbus team switch <team-id>` first.');
173
+ return;
174
+ }
175
+ ui.startSpinner({ message: 'Fetching members...' });
176
+ const members = await teamClient.listMembers(teamId);
177
+ ui.stopSpinnerSuccess(`Found ${members.length} members`);
178
+ if (options.json) {
179
+ console.log(JSON.stringify(members, null, 2));
180
+ return;
181
+ }
182
+ ui.newLine();
183
+ ui.table({
184
+ columns: [
185
+ { key: 'email', header: 'Email' },
186
+ { key: 'role', header: 'Role' },
187
+ { key: 'joinedAt', header: 'Joined' },
188
+ ],
189
+ data: members.map(m => ({
190
+ email: m.user?.email || m.userId,
191
+ role: m.role,
192
+ joinedAt: new Date(m.joinedAt).toLocaleDateString(),
193
+ })),
194
+ });
195
+ }
196
+ catch (error) {
197
+ ui.stopSpinnerFail('Failed to list members');
198
+ ui.error(error.message);
199
+ }
200
+ }
201
+ /**
202
+ * Team remove command
203
+ */
204
+ export async function teamRemoveCommand(options) {
205
+ try {
206
+ const email = options.email;
207
+ if (!email) {
208
+ ui.error('Email is required');
209
+ ui.info('Usage: nimbus team remove <email>');
210
+ return;
211
+ }
212
+ const teamId = getCurrentTeamId();
213
+ if (!teamId) {
214
+ ui.error('No team selected. Run `nimbus team switch <team-id>` first.');
215
+ return;
216
+ }
217
+ // First, find the user ID by email from members list
218
+ const members = await teamClient.listMembers(teamId);
219
+ const member = members.find(m => m.user?.email === email);
220
+ if (!member) {
221
+ ui.error(`Member with email ${email} not found`);
222
+ return;
223
+ }
224
+ ui.startSpinner({ message: `Removing ${email}...` });
225
+ await teamClient.removeMember(teamId, member.userId);
226
+ ui.stopSpinnerSuccess(`Removed ${email} from team`);
227
+ }
228
+ catch (error) {
229
+ ui.stopSpinnerFail('Failed to remove member');
230
+ ui.error(error.message);
231
+ }
232
+ }
233
+ /**
234
+ * Team switch command
235
+ */
236
+ export async function teamSwitchCommand(options) {
237
+ try {
238
+ const userId = getCurrentUserId();
239
+ // If no team ID provided, list teams for selection
240
+ if (!options.teamId) {
241
+ ui.startSpinner({ message: 'Fetching teams...' });
242
+ const teams = await teamClient.listTeams(userId);
243
+ ui.stopSpinnerSuccess(`Found ${teams.length} teams`);
244
+ if (teams.length === 0) {
245
+ ui.info('No teams found. Create one with `nimbus team create <name>`');
246
+ return;
247
+ }
248
+ ui.newLine();
249
+ ui.info('Available teams:');
250
+ for (const team of teams) {
251
+ ui.print(` ${team.id} - ${team.name} (${team.plan})`);
252
+ }
253
+ ui.newLine();
254
+ ui.info('To switch: nimbus team switch <team-id>');
255
+ ui.info('Or set: export NIMBUS_TEAM_ID=<team-id>');
256
+ return;
257
+ }
258
+ // Verify team exists and user has access
259
+ ui.startSpinner({ message: 'Switching team...' });
260
+ const team = await teamClient.getTeam(options.teamId);
261
+ if (!team) {
262
+ ui.stopSpinnerFail('Team not found');
263
+ return;
264
+ }
265
+ ui.stopSpinnerSuccess(`Switched to team "${team.name}"`);
266
+ ui.newLine();
267
+ ui.info(`Set this environment variable to persist:`);
268
+ ui.print(` export NIMBUS_TEAM_ID=${team.id}`);
269
+ }
270
+ catch (error) {
271
+ ui.stopSpinnerFail('Failed to switch team');
272
+ ui.error(error.message);
273
+ }
274
+ }
275
+ /**
276
+ * Main team command dispatcher
277
+ */
278
+ export async function teamCommand(subcommand, args) {
279
+ switch (subcommand) {
280
+ case 'create':
281
+ await teamCreateCommand(parseTeamCreateOptions(args));
282
+ break;
283
+ case 'invite':
284
+ await teamInviteCommand(parseTeamInviteOptions(args));
285
+ break;
286
+ case 'members':
287
+ await teamMembersCommand(parseTeamMembersOptions(args));
288
+ break;
289
+ case 'remove':
290
+ await teamRemoveCommand(parseTeamRemoveOptions(args));
291
+ break;
292
+ case 'switch':
293
+ await teamSwitchCommand(parseTeamSwitchOptions(args));
294
+ break;
295
+ case 'list':
296
+ await teamSwitchCommand(parseTeamSwitchOptions([])); // List mode
297
+ break;
298
+ default:
299
+ ui.error(`Unknown team command: ${subcommand}`);
300
+ ui.newLine();
301
+ ui.info('Available team commands:');
302
+ ui.print(' nimbus team create <name> - Create a new team');
303
+ ui.print(' nimbus team invite <email> - Invite a member');
304
+ ui.print(' nimbus team members - List team members');
305
+ ui.print(' nimbus team remove <email> - Remove a member');
306
+ ui.print(' nimbus team switch [team-id] - Switch to a team');
307
+ ui.print(' nimbus team list - List your teams');
308
+ }
309
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Team NIMBUS.md Distribution (L6)
3
+ *
4
+ * Share project context files with team members.
5
+ *
6
+ * nimbus team-context push — share current NIMBUS.md via sharing service
7
+ * nimbus team-context pull <url> — download NIMBUS.md, show diff, prompt before overwrite
8
+ *
9
+ * Also supports NIMBUS_INSTRUCTIONS_URL env var: on startup, fetch that URL
10
+ * and use as NIMBUS.md if local file not present.
11
+ */
12
+ import * as fs from 'node:fs';
13
+ import * as path from 'node:path';
14
+ import { ui } from '../wizard/ui';
15
+ const NIMBUS_MD_PATHS = [
16
+ path.join(process.cwd(), 'NIMBUS.md'),
17
+ path.join(process.cwd(), '.nimbus', 'NIMBUS.md'),
18
+ ];
19
+ function findLocalNimbusMd() {
20
+ for (const p of NIMBUS_MD_PATHS) {
21
+ if (fs.existsSync(p))
22
+ return p;
23
+ }
24
+ return null;
25
+ }
26
+ function computeDiff(oldContent, newContent) {
27
+ const oldLines = oldContent.split('\n');
28
+ const newLines = newContent.split('\n');
29
+ const lines = [];
30
+ const maxLen = Math.max(oldLines.length, newLines.length);
31
+ for (let i = 0; i < maxLen; i++) {
32
+ const old = oldLines[i];
33
+ const newLine = newLines[i];
34
+ if (old === undefined) {
35
+ lines.push(`+ ${newLine}`);
36
+ }
37
+ else if (newLine === undefined) {
38
+ lines.push(`- ${old}`);
39
+ }
40
+ else if (old !== newLine) {
41
+ lines.push(`- ${old}`);
42
+ lines.push(`+ ${newLine}`);
43
+ }
44
+ }
45
+ return lines.join('\n');
46
+ }
47
+ /** Path to the team.md file in the current project's .nimbus/ directory */
48
+ const TEAM_MD_PATH = path.join(process.cwd(), '.nimbus', 'team.md');
49
+ /** Regex to strip lines containing sensitive info */
50
+ const SENSITIVE_PATTERN = /SENSITIVE:/i;
51
+ /** Strip lines containing "SENSITIVE:" from NIMBUS.md before sharing */
52
+ function stripSensitiveLines(content) {
53
+ return content
54
+ .split('\n')
55
+ .filter(line => !SENSITIVE_PATTERN.test(line))
56
+ .join('\n');
57
+ }
58
+ /**
59
+ * Merge non-duplicate sections from teamContent into localContent.
60
+ * Sections are identified by Markdown headings (## ...).
61
+ */
62
+ function mergeSections(localContent, teamContent) {
63
+ // Split into sections by heading
64
+ const sectionRegex = /(?=^#{1,3} .+$)/m;
65
+ const localSections = localContent.split(sectionRegex);
66
+ const teamSections = teamContent.split(sectionRegex);
67
+ const localHeadings = new Set(localSections
68
+ .map(s => s.match(/^(#{1,3} .+)$/m)?.[1]?.trim())
69
+ .filter(Boolean));
70
+ const newSections = teamSections.filter(s => {
71
+ const heading = s.match(/^(#{1,3} .+)$/m)?.[1]?.trim();
72
+ return heading && !localHeadings.has(heading);
73
+ });
74
+ if (newSections.length === 0)
75
+ return localContent;
76
+ const merged = localContent.trimEnd() + '\n\n' + newSections.join('\n').trimStart();
77
+ return merged;
78
+ }
79
+ export async function teamContextCommand(subcommand, args) {
80
+ switch (subcommand) {
81
+ case 'push': {
82
+ // Git-based push: read NIMBUS.md, strip SENSITIVE lines, write to .nimbus/team.md
83
+ const localPath = findLocalNimbusMd();
84
+ if (!localPath) {
85
+ ui.warning('No NIMBUS.md found in current directory. Run `nimbus init` first.');
86
+ return;
87
+ }
88
+ const content = fs.readFileSync(localPath, 'utf-8');
89
+ const sanitized = stripSensitiveLines(content);
90
+ // Ensure .nimbus/ directory exists
91
+ const nimbusDir = path.dirname(TEAM_MD_PATH);
92
+ if (!fs.existsSync(nimbusDir)) {
93
+ fs.mkdirSync(nimbusDir, { recursive: true });
94
+ }
95
+ fs.writeFileSync(TEAM_MD_PATH, sanitized, 'utf-8');
96
+ ui.print(`${ui.color('✓', 'green')} Written sanitized context to ${TEAM_MD_PATH}`);
97
+ ui.dim(`Removed all lines containing "SENSITIVE:"`);
98
+ ui.newLine();
99
+ // Stage the file with git
100
+ try {
101
+ const { execFileSync } = await import('node:child_process');
102
+ execFileSync('git', ['add', TEAM_MD_PATH], {
103
+ encoding: 'utf-8',
104
+ stdio: ['pipe', 'pipe', 'pipe'],
105
+ timeout: 10_000,
106
+ });
107
+ ui.print(`${ui.color('✓', 'green')} Staged .nimbus/team.md with git`);
108
+ ui.print(' Next step: git commit -m "chore: update team context" && git push');
109
+ }
110
+ catch {
111
+ ui.dim('(git stage skipped — not a git repo or git not in PATH)');
112
+ ui.print(' Copy .nimbus/team.md to your repository and commit/push it manually.');
113
+ }
114
+ ui.newLine();
115
+ ui.info('Note: Add .nimbus/team.md to version control (do NOT add .nimbus/team.md to .gitignore).');
116
+ ui.dim('Add NIMBUS.md to .gitignore if it contains sensitive local config.');
117
+ break;
118
+ }
119
+ case 'pull': {
120
+ // Git-based pull: read .nimbus/team.md from cwd, diff, merge
121
+ if (!fs.existsSync(TEAM_MD_PATH)) {
122
+ ui.error(`.nimbus/team.md not found in ${process.cwd()}`);
123
+ ui.dim('Run `git pull` to fetch the latest team context, then re-run this command.');
124
+ return;
125
+ }
126
+ const teamContent = fs.readFileSync(TEAM_MD_PATH, 'utf-8');
127
+ const targetPath = NIMBUS_MD_PATHS[0];
128
+ const existing = fs.existsSync(targetPath) ? fs.readFileSync(targetPath, 'utf-8') : null;
129
+ if (existing) {
130
+ const diff = computeDiff(existing, teamContent);
131
+ if (!diff) {
132
+ ui.info('NIMBUS.md is already up to date with team.md.');
133
+ return;
134
+ }
135
+ ui.header('NIMBUS.md vs .nimbus/team.md diff');
136
+ for (const line of diff.split('\n')) {
137
+ if (line.startsWith('+')) {
138
+ ui.print(ui.color(line, 'green'));
139
+ }
140
+ else if (line.startsWith('-')) {
141
+ ui.print(ui.color(line, 'red'));
142
+ }
143
+ else {
144
+ ui.print(line);
145
+ }
146
+ }
147
+ ui.newLine();
148
+ // Prompt for confirmation
149
+ const { input: inputPrompt } = await import('../wizard/prompts');
150
+ const answer = await inputPrompt({
151
+ message: 'Merge new sections from team.md into NIMBUS.md? [y/N]',
152
+ defaultValue: 'N',
153
+ });
154
+ if (answer.toLowerCase() !== 'y') {
155
+ ui.info('Aborted — NIMBUS.md not changed.');
156
+ return;
157
+ }
158
+ // Merge: append non-duplicate sections
159
+ const merged = mergeSections(existing, teamContent);
160
+ fs.writeFileSync(targetPath, merged, 'utf-8');
161
+ ui.print(`${ui.color('✓', 'green')} Merged team context into ${targetPath}`);
162
+ }
163
+ else {
164
+ // No local NIMBUS.md — use team.md as starting point
165
+ fs.writeFileSync(targetPath, teamContent, 'utf-8');
166
+ ui.print(`${ui.color('✓', 'green')} Created ${targetPath} from .nimbus/team.md`);
167
+ }
168
+ ui.newLine();
169
+ ui.dim('Note: Add NIMBUS.md to .gitignore to keep local config private.');
170
+ ui.dim('Add .nimbus/team.md to version control to share project context with team.');
171
+ break;
172
+ }
173
+ default:
174
+ ui.print('Usage: nimbus team-context <push|pull>');
175
+ ui.print('');
176
+ ui.print(' push Strip SENSITIVE: lines from NIMBUS.md, write to .nimbus/team.md, and git add');
177
+ ui.print(' pull Read .nimbus/team.md, diff against NIMBUS.md, merge on confirmation');
178
+ }
179
+ }
180
+ /**
181
+ * Fetch NIMBUS.md from NIMBUS_INSTRUCTIONS_URL env var.
182
+ * Called on startup when no local NIMBUS.md exists.
183
+ */
184
+ export async function fetchRemoteNimbusMd() {
185
+ const url = process.env.NIMBUS_INSTRUCTIONS_URL;
186
+ if (!url)
187
+ return null;
188
+ const localPath = findLocalNimbusMd();
189
+ if (localPath)
190
+ return null; // local file takes priority
191
+ try {
192
+ const response = await fetch(url, { signal: AbortSignal.timeout(10_000) });
193
+ if (!response.ok)
194
+ return null;
195
+ return await response.text();
196
+ }
197
+ catch {
198
+ return null;
199
+ }
200
+ }