@build-astron-co/nimbus 0.3.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 (441) hide show
  1. package/bin/nimbus.cmd +41 -0
  2. package/bin/nimbus.mjs +70 -0
  3. package/completions/nimbus.bash +38 -0
  4. package/completions/nimbus.fish +48 -0
  5. package/completions/nimbus.zsh +81 -0
  6. package/dist/src/agent/compaction-agent.js +215 -0
  7. package/dist/src/agent/context-manager.js +385 -0
  8. package/dist/src/agent/context.js +322 -0
  9. package/dist/src/agent/deploy-preview.js +395 -0
  10. package/dist/src/agent/expand-files.js +95 -0
  11. package/dist/src/agent/index.js +18 -0
  12. package/dist/src/agent/loop.js +1535 -0
  13. package/dist/src/agent/modes.js +347 -0
  14. package/dist/src/agent/permissions.js +396 -0
  15. package/dist/src/agent/subagents/base.js +67 -0
  16. package/dist/src/agent/subagents/cost.js +45 -0
  17. package/dist/src/agent/subagents/explore.js +36 -0
  18. package/dist/src/agent/subagents/general.js +41 -0
  19. package/dist/src/agent/subagents/index.js +88 -0
  20. package/dist/src/agent/subagents/infra.js +52 -0
  21. package/dist/src/agent/subagents/security.js +60 -0
  22. package/dist/src/agent/system-prompt.js +860 -0
  23. package/dist/src/app.js +152 -0
  24. package/dist/src/audit/activity-log.js +209 -0
  25. package/dist/src/audit/compliance-checker.js +419 -0
  26. package/dist/src/audit/cost-tracker.js +231 -0
  27. package/dist/src/audit/index.js +10 -0
  28. package/dist/src/audit/security-scanner.js +490 -0
  29. package/dist/src/auth/guard.js +64 -0
  30. package/dist/src/auth/index.js +19 -0
  31. package/dist/src/auth/keychain.js +79 -0
  32. package/dist/src/auth/oauth.js +389 -0
  33. package/dist/src/auth/providers.js +415 -0
  34. package/dist/src/auth/sso.js +87 -0
  35. package/dist/src/auth/store.js +424 -0
  36. package/dist/src/auth/types.js +5 -0
  37. package/dist/src/cli/index.js +8 -0
  38. package/dist/src/cli/init.js +1048 -0
  39. package/dist/src/cli/openapi-spec.js +346 -0
  40. package/dist/src/cli/run.js +505 -0
  41. package/dist/src/cli/serve-auth.js +56 -0
  42. package/dist/src/cli/serve.js +432 -0
  43. package/dist/src/cli/web.js +50 -0
  44. package/dist/src/cli.js +1574 -0
  45. package/dist/src/clients/core-engine-client.js +156 -0
  46. package/dist/src/clients/enterprise-client.js +246 -0
  47. package/dist/src/clients/generator-client.js +219 -0
  48. package/dist/src/clients/git-client.js +367 -0
  49. package/dist/src/clients/github-client.js +229 -0
  50. package/dist/src/clients/helm-client.js +299 -0
  51. package/dist/src/clients/index.js +18 -0
  52. package/dist/src/clients/k8s-client.js +270 -0
  53. package/dist/src/clients/llm-client.js +119 -0
  54. package/dist/src/clients/rest-client.js +104 -0
  55. package/dist/src/clients/service-discovery.js +35 -0
  56. package/dist/src/clients/terraform-client.js +302 -0
  57. package/dist/src/clients/tools-client.js +1227 -0
  58. package/dist/src/clients/ws-client.js +93 -0
  59. package/dist/src/commands/alias.js +91 -0
  60. package/dist/src/commands/analyze/index.js +313 -0
  61. package/dist/src/commands/apply/helm.js +375 -0
  62. package/dist/src/commands/apply/index.js +176 -0
  63. package/dist/src/commands/apply/k8s.js +350 -0
  64. package/dist/src/commands/apply/terraform.js +465 -0
  65. package/dist/src/commands/ask.js +137 -0
  66. package/dist/src/commands/audit/index.js +322 -0
  67. package/dist/src/commands/auth-cloud.js +345 -0
  68. package/dist/src/commands/auth-list.js +112 -0
  69. package/dist/src/commands/auth-profile.js +104 -0
  70. package/dist/src/commands/auth-refresh.js +161 -0
  71. package/dist/src/commands/auth-status.js +122 -0
  72. package/dist/src/commands/aws/ec2.js +402 -0
  73. package/dist/src/commands/aws/iam.js +304 -0
  74. package/dist/src/commands/aws/index.js +108 -0
  75. package/dist/src/commands/aws/lambda.js +317 -0
  76. package/dist/src/commands/aws/rds.js +345 -0
  77. package/dist/src/commands/aws/s3.js +346 -0
  78. package/dist/src/commands/aws/vpc.js +302 -0
  79. package/dist/src/commands/aws-discover.js +413 -0
  80. package/dist/src/commands/aws-terraform.js +618 -0
  81. package/dist/src/commands/azure/aks.js +305 -0
  82. package/dist/src/commands/azure/functions.js +200 -0
  83. package/dist/src/commands/azure/index.js +93 -0
  84. package/dist/src/commands/azure/storage.js +378 -0
  85. package/dist/src/commands/azure/vm.js +291 -0
  86. package/dist/src/commands/billing/index.js +224 -0
  87. package/dist/src/commands/chat.js +259 -0
  88. package/dist/src/commands/completions.js +255 -0
  89. package/dist/src/commands/config.js +291 -0
  90. package/dist/src/commands/cost/cloud-cost-estimator.js +211 -0
  91. package/dist/src/commands/cost/estimator.js +73 -0
  92. package/dist/src/commands/cost/index.js +625 -0
  93. package/dist/src/commands/cost/parsers/terraform.js +234 -0
  94. package/dist/src/commands/cost/parsers/types.js +4 -0
  95. package/dist/src/commands/cost/pricing/aws.js +501 -0
  96. package/dist/src/commands/cost/pricing/azure.js +462 -0
  97. package/dist/src/commands/cost/pricing/gcp.js +359 -0
  98. package/dist/src/commands/cost/pricing/index.js +24 -0
  99. package/dist/src/commands/demo.js +196 -0
  100. package/dist/src/commands/deploy.js +215 -0
  101. package/dist/src/commands/doctor.js +1291 -0
  102. package/dist/src/commands/drift/index.js +674 -0
  103. package/dist/src/commands/explain.js +235 -0
  104. package/dist/src/commands/export.js +120 -0
  105. package/dist/src/commands/feedback.js +319 -0
  106. package/dist/src/commands/fix.js +263 -0
  107. package/dist/src/commands/fs/index.js +338 -0
  108. package/dist/src/commands/gcp/compute.js +266 -0
  109. package/dist/src/commands/gcp/functions.js +221 -0
  110. package/dist/src/commands/gcp/gke.js +357 -0
  111. package/dist/src/commands/gcp/iam.js +295 -0
  112. package/dist/src/commands/gcp/index.js +105 -0
  113. package/dist/src/commands/gcp/storage.js +232 -0
  114. package/dist/src/commands/generate-helm.js +1026 -0
  115. package/dist/src/commands/generate-k8s.js +1263 -0
  116. package/dist/src/commands/generate-terraform.js +1058 -0
  117. package/dist/src/commands/gh/index.js +663 -0
  118. package/dist/src/commands/git/index.js +1208 -0
  119. package/dist/src/commands/helm/index.js +985 -0
  120. package/dist/src/commands/help.js +639 -0
  121. package/dist/src/commands/history.js +120 -0
  122. package/dist/src/commands/import.js +782 -0
  123. package/dist/src/commands/incident.js +144 -0
  124. package/dist/src/commands/index.js +109 -0
  125. package/dist/src/commands/init.js +955 -0
  126. package/dist/src/commands/k8s/index.js +979 -0
  127. package/dist/src/commands/login.js +588 -0
  128. package/dist/src/commands/logout.js +61 -0
  129. package/dist/src/commands/logs.js +160 -0
  130. package/dist/src/commands/onboarding.js +382 -0
  131. package/dist/src/commands/pipeline.js +153 -0
  132. package/dist/src/commands/plan/display.js +216 -0
  133. package/dist/src/commands/plan/index.js +525 -0
  134. package/dist/src/commands/plugin.js +325 -0
  135. package/dist/src/commands/preview.js +356 -0
  136. package/dist/src/commands/profile.js +297 -0
  137. package/dist/src/commands/questionnaire.js +1021 -0
  138. package/dist/src/commands/resume.js +35 -0
  139. package/dist/src/commands/rollback.js +259 -0
  140. package/dist/src/commands/rollout.js +74 -0
  141. package/dist/src/commands/runbook.js +307 -0
  142. package/dist/src/commands/schedule.js +202 -0
  143. package/dist/src/commands/status.js +213 -0
  144. package/dist/src/commands/team/index.js +309 -0
  145. package/dist/src/commands/team-context.js +200 -0
  146. package/dist/src/commands/template.js +204 -0
  147. package/dist/src/commands/tf/index.js +989 -0
  148. package/dist/src/commands/upgrade.js +515 -0
  149. package/dist/src/commands/usage/index.js +118 -0
  150. package/dist/src/commands/version.js +145 -0
  151. package/dist/src/commands/watch.js +127 -0
  152. package/dist/src/compat/index.js +2 -0
  153. package/dist/src/compat/runtime.js +10 -0
  154. package/dist/src/compat/sqlite.js +144 -0
  155. package/dist/src/config/index.js +6 -0
  156. package/dist/src/config/manager.js +469 -0
  157. package/dist/src/config/mode-store.js +57 -0
  158. package/dist/src/config/profiles.js +66 -0
  159. package/dist/src/config/safety-policy.js +251 -0
  160. package/dist/src/config/schema.js +107 -0
  161. package/dist/src/config/types.js +311 -0
  162. package/dist/src/config/workspace-state.js +38 -0
  163. package/dist/src/context/context-db.js +138 -0
  164. package/dist/src/demo/index.js +295 -0
  165. package/dist/src/demo/scenarios/full-journey.js +226 -0
  166. package/dist/src/demo/scenarios/getting-started.js +124 -0
  167. package/dist/src/demo/scenarios/helm-release.js +334 -0
  168. package/dist/src/demo/scenarios/k8s-deployment.js +190 -0
  169. package/dist/src/demo/scenarios/terraform-vpc.js +167 -0
  170. package/dist/src/demo/types.js +6 -0
  171. package/dist/src/engine/cost-estimator.js +334 -0
  172. package/dist/src/engine/diagram-generator.js +192 -0
  173. package/dist/src/engine/drift-detector.js +688 -0
  174. package/dist/src/engine/executor.js +832 -0
  175. package/dist/src/engine/index.js +39 -0
  176. package/dist/src/engine/orchestrator.js +436 -0
  177. package/dist/src/engine/planner.js +616 -0
  178. package/dist/src/engine/safety.js +609 -0
  179. package/dist/src/engine/verifier.js +664 -0
  180. package/dist/src/enterprise/audit.js +241 -0
  181. package/dist/src/enterprise/auth.js +189 -0
  182. package/dist/src/enterprise/billing.js +512 -0
  183. package/dist/src/enterprise/index.js +16 -0
  184. package/dist/src/enterprise/teams.js +315 -0
  185. package/dist/src/generator/best-practices.js +1375 -0
  186. package/dist/src/generator/helm.js +495 -0
  187. package/dist/src/generator/index.js +11 -0
  188. package/dist/src/generator/intent-parser.js +420 -0
  189. package/dist/src/generator/kubernetes.js +773 -0
  190. package/dist/src/generator/terraform.js +1472 -0
  191. package/dist/src/history/index.js +6 -0
  192. package/dist/src/history/manager.js +199 -0
  193. package/dist/src/history/types.js +6 -0
  194. package/dist/src/hooks/config.js +318 -0
  195. package/dist/src/hooks/engine.js +317 -0
  196. package/dist/src/hooks/index.js +2 -0
  197. package/dist/src/llm/auth-bridge.js +157 -0
  198. package/dist/src/llm/circuit-breaker.js +116 -0
  199. package/dist/src/llm/config-loader.js +172 -0
  200. package/dist/src/llm/cost-calculator.js +137 -0
  201. package/dist/src/llm/index.js +7 -0
  202. package/dist/src/llm/model-aliases.js +99 -0
  203. package/dist/src/llm/provider-registry.js +57 -0
  204. package/dist/src/llm/providers/anthropic.js +430 -0
  205. package/dist/src/llm/providers/bedrock.js +409 -0
  206. package/dist/src/llm/providers/google.js +344 -0
  207. package/dist/src/llm/providers/ollama.js +661 -0
  208. package/dist/src/llm/providers/openai-compatible.js +289 -0
  209. package/dist/src/llm/providers/openai.js +284 -0
  210. package/dist/src/llm/providers/openrouter.js +293 -0
  211. package/dist/src/llm/router.js +844 -0
  212. package/dist/src/llm/types.js +69 -0
  213. package/dist/src/lsp/client.js +239 -0
  214. package/dist/src/lsp/languages.js +95 -0
  215. package/dist/src/lsp/manager.js +243 -0
  216. package/dist/src/mcp/client.js +289 -0
  217. package/dist/src/mcp/index.js +5 -0
  218. package/dist/src/mcp/manager.js +113 -0
  219. package/dist/src/nimbus.js +212 -0
  220. package/dist/src/plugins/index.js +13 -0
  221. package/dist/src/plugins/loader.js +280 -0
  222. package/dist/src/plugins/manager.js +282 -0
  223. package/dist/src/plugins/types.js +23 -0
  224. package/dist/src/scanners/cicd-scanner.js +230 -0
  225. package/dist/src/scanners/cloud-scanner.js +415 -0
  226. package/dist/src/scanners/framework-scanner.js +430 -0
  227. package/dist/src/scanners/iac-scanner.js +350 -0
  228. package/dist/src/scanners/index.js +454 -0
  229. package/dist/src/scanners/language-scanner.js +258 -0
  230. package/dist/src/scanners/package-manager-scanner.js +252 -0
  231. package/dist/src/scanners/types.js +6 -0
  232. package/dist/src/sessions/manager.js +395 -0
  233. package/dist/src/sessions/types.js +4 -0
  234. package/dist/src/sharing/sync.js +238 -0
  235. package/dist/src/sharing/viewer.js +131 -0
  236. package/dist/src/snapshots/index.js +1 -0
  237. package/dist/src/snapshots/manager.js +432 -0
  238. package/dist/src/state/artifacts.js +94 -0
  239. package/dist/src/state/audit.js +73 -0
  240. package/dist/src/state/billing.js +126 -0
  241. package/dist/src/state/checkpoints.js +81 -0
  242. package/dist/src/state/config.js +58 -0
  243. package/dist/src/state/conversations.js +7 -0
  244. package/dist/src/state/credentials.js +96 -0
  245. package/dist/src/state/db.js +53 -0
  246. package/dist/src/state/index.js +23 -0
  247. package/dist/src/state/messages.js +76 -0
  248. package/dist/src/state/projects.js +92 -0
  249. package/dist/src/state/schema.js +233 -0
  250. package/dist/src/state/sessions.js +79 -0
  251. package/dist/src/state/teams.js +131 -0
  252. package/dist/src/telemetry.js +91 -0
  253. package/dist/src/tools/aws-ops.js +747 -0
  254. package/dist/src/tools/azure-ops.js +491 -0
  255. package/dist/src/tools/file-ops.js +451 -0
  256. package/dist/src/tools/gcp-ops.js +559 -0
  257. package/dist/src/tools/git-ops.js +557 -0
  258. package/dist/src/tools/github-ops.js +460 -0
  259. package/dist/src/tools/helm-ops.js +634 -0
  260. package/dist/src/tools/index.js +16 -0
  261. package/dist/src/tools/k8s-ops.js +579 -0
  262. package/dist/src/tools/schemas/converter.js +129 -0
  263. package/dist/src/tools/schemas/devops.js +3319 -0
  264. package/dist/src/tools/schemas/index.js +19 -0
  265. package/dist/src/tools/schemas/standard.js +966 -0
  266. package/dist/src/tools/schemas/types.js +409 -0
  267. package/dist/src/tools/spawn-exec.js +109 -0
  268. package/dist/src/tools/terraform-ops.js +627 -0
  269. package/dist/src/types/config.js +1 -0
  270. package/dist/src/types/drift.js +4 -0
  271. package/dist/src/types/enterprise.js +5 -0
  272. package/dist/src/types/index.js +14 -0
  273. package/dist/src/types/plan.js +1 -0
  274. package/dist/src/types/request.js +1 -0
  275. package/dist/src/types/response.js +1 -0
  276. package/dist/src/types/service.js +1 -0
  277. package/dist/src/ui/App.js +1672 -0
  278. package/dist/src/ui/DeployPreview.js +60 -0
  279. package/dist/src/ui/FileDiffModal.js +108 -0
  280. package/dist/src/ui/Header.js +46 -0
  281. package/dist/src/ui/HelpModal.js +9 -0
  282. package/dist/src/ui/InputBox.js +408 -0
  283. package/dist/src/ui/MessageList.js +795 -0
  284. package/dist/src/ui/PermissionPrompt.js +72 -0
  285. package/dist/src/ui/StatusBar.js +109 -0
  286. package/dist/src/ui/TerminalPane.js +31 -0
  287. package/dist/src/ui/ToolCallDisplay.js +303 -0
  288. package/dist/src/ui/TreePane.js +83 -0
  289. package/dist/src/ui/chat-ui.js +721 -0
  290. package/dist/src/ui/index.js +11 -0
  291. package/dist/src/ui/ink/index.js +1325 -0
  292. package/dist/src/ui/streaming.js +137 -0
  293. package/dist/src/ui/theme.js +78 -0
  294. package/dist/src/ui/types.js +7 -0
  295. package/dist/src/utils/analytics.js +61 -0
  296. package/dist/src/utils/cost-warning.js +25 -0
  297. package/dist/src/utils/env.js +42 -0
  298. package/dist/src/utils/errors.js +54 -0
  299. package/dist/src/utils/event-bus.js +22 -0
  300. package/dist/src/utils/index.js +16 -0
  301. package/dist/src/utils/logger.js +150 -0
  302. package/dist/src/utils/rate-limiter.js +90 -0
  303. package/dist/src/utils/service-auth.js +36 -0
  304. package/dist/src/utils/validation.js +39 -0
  305. package/dist/src/version.js +3 -0
  306. package/dist/src/watcher/index.js +192 -0
  307. package/dist/src/wizard/approval.js +275 -0
  308. package/dist/src/wizard/index.js +13 -0
  309. package/dist/src/wizard/prompts.js +273 -0
  310. package/dist/src/wizard/types.js +4 -0
  311. package/dist/src/wizard/ui.js +453 -0
  312. package/dist/src/wizard/wizard.js +227 -0
  313. package/package.json +22 -15
  314. package/src/__tests__/alias.test.ts +133 -0
  315. package/src/__tests__/cli-run.test.ts +237 -1
  316. package/src/__tests__/compat-sqlite.test.ts +68 -0
  317. package/src/__tests__/context-manager.test.ts +130 -0
  318. package/src/__tests__/devops-terminal-gaps.test.ts +718 -0
  319. package/src/__tests__/doctor.test.ts +48 -0
  320. package/src/__tests__/export.test.ts +236 -0
  321. package/src/__tests__/gap-11-18-20.test.ts +958 -0
  322. package/src/__tests__/helm-streaming.test.ts +127 -0
  323. package/src/__tests__/incident.test.ts +179 -0
  324. package/src/__tests__/init.test.ts +54 -3
  325. package/src/__tests__/logs.test.ts +107 -0
  326. package/src/__tests__/loop-errors.test.ts +244 -0
  327. package/src/__tests__/perf-optimizations.test.ts +847 -0
  328. package/src/__tests__/pipeline.test.ts +50 -0
  329. package/src/__tests__/polish-phase3.test.ts +340 -0
  330. package/src/__tests__/profile.test.ts +237 -0
  331. package/src/__tests__/rollback.test.ts +83 -0
  332. package/src/__tests__/runbook.test.ts +219 -0
  333. package/src/__tests__/schedule.test.ts +206 -0
  334. package/src/__tests__/sessions.test.ts +95 -0
  335. package/src/__tests__/standalone-migration.test.ts +199 -0
  336. package/src/__tests__/status.test.ts +158 -0
  337. package/src/__tests__/stream-with-tools.test.ts +49 -1
  338. package/src/__tests__/system-prompt.test.ts +81 -2
  339. package/src/__tests__/terminal-gap-v2.test.ts +395 -0
  340. package/src/__tests__/terminal-parity.test.ts +393 -0
  341. package/src/__tests__/tf-apply.test.ts +187 -0
  342. package/src/__tests__/tool-schemas.test.ts +209 -4
  343. package/src/__tests__/version-json.test.ts +184 -0
  344. package/src/__tests__/watch.test.ts +129 -0
  345. package/src/agent/compaction-agent.ts +40 -1
  346. package/src/agent/context-manager.ts +67 -3
  347. package/src/agent/deploy-preview.ts +62 -1
  348. package/src/agent/expand-files.ts +108 -0
  349. package/src/agent/loop.ts +1312 -31
  350. package/src/agent/permissions.ts +51 -4
  351. package/src/agent/system-prompt.ts +573 -19
  352. package/src/app.ts +58 -0
  353. package/src/audit/security-scanner.ts +45 -0
  354. package/src/auth/keychain.ts +82 -0
  355. package/src/cli/init.ts +378 -5
  356. package/src/cli/run.ts +407 -16
  357. package/src/cli/serve.ts +78 -1
  358. package/src/cli/web.ts +10 -6
  359. package/src/cli.ts +312 -1
  360. package/src/clients/service-discovery.ts +30 -25
  361. package/src/commands/alias.ts +100 -0
  362. package/src/commands/audit/index.ts +121 -2
  363. package/src/commands/auth-cloud.ts +113 -0
  364. package/src/commands/auth-refresh.ts +187 -0
  365. package/src/commands/aws-discover.ts +144 -251
  366. package/src/commands/aws-terraform.ts +68 -118
  367. package/src/commands/chat.ts +9 -3
  368. package/src/commands/completions.ts +268 -0
  369. package/src/commands/config.ts +26 -0
  370. package/src/commands/cost/index.ts +218 -2
  371. package/src/commands/deploy.ts +260 -0
  372. package/src/commands/doctor.ts +744 -152
  373. package/src/commands/drift/index.ts +371 -23
  374. package/src/commands/export.ts +146 -0
  375. package/src/commands/generate-k8s.ts +9 -61
  376. package/src/commands/generate-terraform.ts +191 -449
  377. package/src/commands/help.ts +212 -36
  378. package/src/commands/history.ts +8 -1
  379. package/src/commands/incident.ts +166 -0
  380. package/src/commands/init.ts +5 -0
  381. package/src/commands/login.ts +86 -1
  382. package/src/commands/logs.ts +167 -0
  383. package/src/commands/onboarding.ts +211 -34
  384. package/src/commands/pipeline.ts +186 -0
  385. package/src/commands/plugin.ts +398 -0
  386. package/src/commands/profile.ts +342 -0
  387. package/src/commands/questionnaire.ts +0 -98
  388. package/src/commands/resume.ts +26 -34
  389. package/src/commands/rollback.ts +315 -0
  390. package/src/commands/rollout.ts +88 -0
  391. package/src/commands/runbook.ts +346 -0
  392. package/src/commands/schedule.ts +236 -0
  393. package/src/commands/status.ts +252 -0
  394. package/src/commands/team-context.ts +220 -0
  395. package/src/commands/template.ts +58 -57
  396. package/src/commands/tf/index.ts +70 -11
  397. package/src/commands/upgrade.ts +57 -0
  398. package/src/commands/version.ts +54 -50
  399. package/src/commands/watch.ts +153 -0
  400. package/src/compat/sqlite.ts +75 -5
  401. package/src/config/mode-store.ts +62 -0
  402. package/src/config/profiles.ts +84 -0
  403. package/src/config/types.ts +83 -1
  404. package/src/config/workspace-state.ts +53 -0
  405. package/src/engine/cost-estimator.ts +52 -10
  406. package/src/engine/executor.ts +33 -2
  407. package/src/engine/planner.ts +68 -1
  408. package/src/generator/terraform.ts +8 -0
  409. package/src/history/manager.ts +2 -74
  410. package/src/llm/cost-calculator.ts +2 -2
  411. package/src/llm/providers/anthropic.ts +50 -21
  412. package/src/llm/router.ts +76 -7
  413. package/src/lsp/languages.ts +3 -0
  414. package/src/lsp/manager.ts +20 -4
  415. package/src/nimbus.ts +34 -1
  416. package/src/sessions/manager.ts +108 -1
  417. package/src/sharing/viewer.ts +66 -0
  418. package/src/tools/file-ops.ts +22 -0
  419. package/src/tools/schemas/devops.ts +3007 -117
  420. package/src/tools/schemas/standard.ts +5 -1
  421. package/src/tools/schemas/types.ts +31 -1
  422. package/src/tools/spawn-exec.ts +148 -0
  423. package/src/ui/App.tsx +1183 -66
  424. package/src/ui/DeployPreview.tsx +62 -57
  425. package/src/ui/FileDiffModal.tsx +162 -0
  426. package/src/ui/Header.tsx +87 -24
  427. package/src/ui/HelpModal.tsx +57 -0
  428. package/src/ui/InputBox.tsx +163 -10
  429. package/src/ui/MessageList.tsx +487 -40
  430. package/src/ui/PermissionPrompt.tsx +17 -5
  431. package/src/ui/StatusBar.tsx +122 -3
  432. package/src/ui/TerminalPane.tsx +84 -0
  433. package/src/ui/ToolCallDisplay.tsx +252 -18
  434. package/src/ui/TreePane.tsx +132 -0
  435. package/src/ui/chat-ui.ts +41 -44
  436. package/src/ui/ink/index.ts +771 -38
  437. package/src/ui/theme.ts +104 -0
  438. package/src/ui/types.ts +18 -0
  439. package/src/version.ts +1 -1
  440. package/src/watcher/index.ts +66 -15
  441. package/src/wizard/types.ts +1 -0
@@ -0,0 +1,395 @@
1
+ /**
2
+ * Deploy Preview
3
+ *
4
+ * Generates dry-run previews for infrastructure changes with
5
+ * blast radius analysis. Shows what will be created, modified,
6
+ * or destroyed before the user approves execution.
7
+ */
8
+ import { exec } from 'node:child_process';
9
+ import { promisify } from 'node:util';
10
+ const execAsync = promisify(exec);
11
+ /**
12
+ * Generate a deploy preview for the given action.
13
+ *
14
+ * Dispatches to the appropriate provider-specific preview generator
15
+ * based on the action keyword (terraform, kubectl/kubernetes, or helm).
16
+ *
17
+ * @param action - The action keyword (e.g., "terraform apply", "kubectl apply", "helm install")
18
+ * @param workdir - Working directory containing the IaC files
19
+ * @returns DeployPreview result
20
+ */
21
+ export async function generateDeployPreview(action, workdir) {
22
+ const actionLower = action.toLowerCase();
23
+ if (actionLower.includes('terraform')) {
24
+ return generateTerraformPreview(workdir);
25
+ }
26
+ if (actionLower.includes('kubectl') || actionLower.includes('kubernetes')) {
27
+ return generateKubectlPreview(action, workdir);
28
+ }
29
+ if (actionLower.includes('helm')) {
30
+ return generateHelmPreview(action, workdir);
31
+ }
32
+ return {
33
+ tool: 'unknown',
34
+ action,
35
+ workdir,
36
+ changes: [],
37
+ summary: { toCreate: 0, toUpdate: 0, toDestroy: 0, toReplace: 0, unchanged: 0 },
38
+ rawOutput: '',
39
+ success: false,
40
+ error: `Unsupported action for deploy preview: ${action}`,
41
+ };
42
+ }
43
+ /**
44
+ * Format a deploy preview into a human-readable string.
45
+ *
46
+ * Produces a summary block with change counts, a detailed change list
47
+ * using +/~/- symbols, optional cost impact, and a blast-radius warning
48
+ * when destructive operations are present.
49
+ *
50
+ * @param preview - The deploy preview to format
51
+ * @returns Formatted multi-line string suitable for terminal display
52
+ */
53
+ export function formatDeployPreview(preview) {
54
+ if (!preview.success) {
55
+ return `Deploy Preview Failed\n${'='.repeat(40)}\n\nError: ${preview.error}\n`;
56
+ }
57
+ const lines = [];
58
+ lines.push(`Deploy Preview: ${preview.tool} ${preview.action}`);
59
+ lines.push('='.repeat(50));
60
+ lines.push(`Working directory: ${preview.workdir}`);
61
+ lines.push('');
62
+ // Summary
63
+ const { toCreate, toUpdate, toDestroy, toReplace, unchanged } = preview.summary;
64
+ lines.push('Summary:');
65
+ if (toCreate > 0) {
66
+ lines.push(` + ${toCreate} to create`);
67
+ }
68
+ if (toUpdate > 0) {
69
+ lines.push(` ~ ${toUpdate} to update`);
70
+ }
71
+ if (toReplace > 0) {
72
+ lines.push(` +/- ${toReplace} to replace`);
73
+ }
74
+ if (toDestroy > 0) {
75
+ lines.push(` - ${toDestroy} to destroy`);
76
+ }
77
+ if (unchanged > 0) {
78
+ lines.push(` = ${unchanged} unchanged`);
79
+ }
80
+ lines.push('');
81
+ // Detailed changes
82
+ if (preview.changes.length > 0) {
83
+ lines.push('Changes:');
84
+ for (const change of preview.changes) {
85
+ const symbol = getChangeSymbol(change.action);
86
+ const detail = change.details ? ` (${change.details})` : '';
87
+ lines.push(` ${symbol} ${change.resource}${detail}`);
88
+ }
89
+ lines.push('');
90
+ }
91
+ // Cost impact
92
+ if (preview.costImpact) {
93
+ lines.push(`Cost Impact: ${preview.costImpact}`);
94
+ lines.push('');
95
+ }
96
+ // Blast radius warning
97
+ if (toDestroy > 0) {
98
+ lines.push('WARNING: This operation will DESTROY resources.');
99
+ lines.push('');
100
+ }
101
+ return lines.join('\n');
102
+ }
103
+ // ---------------------------------------------------------------
104
+ // Provider-specific preview generators
105
+ // ---------------------------------------------------------------
106
+ /**
107
+ * Run `terraform plan` and parse the human-readable output into
108
+ * structured {@link ResourceChange} entries.
109
+ */
110
+ async function generateTerraformPreview(workdir) {
111
+ const base = {
112
+ tool: 'terraform',
113
+ action: 'apply',
114
+ workdir,
115
+ };
116
+ try {
117
+ // Run terraform plan with JSON output
118
+ const { stdout, stderr } = await execAsync('terraform plan -no-color -detailed-exitcode 2>&1 || true', { cwd: workdir, timeout: 300_000, maxBuffer: 10 * 1024 * 1024 });
119
+ const output = stdout || stderr;
120
+ const changes = parseTerraformPlanOutput(output);
121
+ const summary = summarizeChanges(changes);
122
+ // Try infracost for real cost delta (best-effort, non-blocking)
123
+ let costImpact;
124
+ try {
125
+ const { stdout: icOut } = await execAsync(`infracost breakdown --path ${workdir} --format json`, { timeout: 60_000, maxBuffer: 5 * 1024 * 1024 });
126
+ const ic = JSON.parse(icOut);
127
+ const totalMonthly = parseFloat(ic.totalMonthlyCost ?? '0').toFixed(2);
128
+ const diff = parseFloat(ic.diffTotalMonthlyCost ?? '0');
129
+ const sign = diff > 0 ? '+' : '';
130
+ costImpact = `$${totalMonthly}/month${diff !== 0 ? ` (${sign}$${diff.toFixed(2)} change)` : ' (no change)'}`;
131
+ }
132
+ catch {
133
+ // infracost not installed or failed — omit cost impact
134
+ }
135
+ return {
136
+ ...base,
137
+ changes,
138
+ summary,
139
+ rawOutput: output,
140
+ costImpact,
141
+ success: true,
142
+ };
143
+ }
144
+ catch (error) {
145
+ const msg = error instanceof Error ? error.message : String(error);
146
+ return {
147
+ ...base,
148
+ changes: [],
149
+ summary: { toCreate: 0, toUpdate: 0, toDestroy: 0, toReplace: 0, unchanged: 0 },
150
+ rawOutput: '',
151
+ success: false,
152
+ error: msg,
153
+ };
154
+ }
155
+ }
156
+ /**
157
+ * Run `kubectl diff` against the current cluster state and parse
158
+ * the unified-diff output into {@link ResourceChange} entries.
159
+ */
160
+ async function generateKubectlPreview(action, workdir) {
161
+ const base = {
162
+ tool: 'kubectl',
163
+ action,
164
+ workdir,
165
+ };
166
+ try {
167
+ const { stdout } = await execAsync('kubectl diff -f . 2>&1 || true', {
168
+ cwd: workdir,
169
+ timeout: 60_000,
170
+ maxBuffer: 10 * 1024 * 1024,
171
+ });
172
+ const changes = parseKubectlDiffOutput(stdout);
173
+ const summary = summarizeChanges(changes);
174
+ return {
175
+ ...base,
176
+ changes,
177
+ summary,
178
+ rawOutput: stdout,
179
+ success: true,
180
+ };
181
+ }
182
+ catch (error) {
183
+ const msg = error instanceof Error ? error.message : String(error);
184
+ return {
185
+ ...base,
186
+ changes: [],
187
+ summary: { toCreate: 0, toUpdate: 0, toDestroy: 0, toReplace: 0, unchanged: 0 },
188
+ rawOutput: '',
189
+ success: false,
190
+ error: msg,
191
+ };
192
+ }
193
+ }
194
+ /**
195
+ * Run `helm template` to render the chart locally and report the
196
+ * rendered manifests as a single create change.
197
+ */
198
+ async function generateHelmPreview(action, workdir) {
199
+ const base = {
200
+ tool: 'helm',
201
+ action,
202
+ workdir,
203
+ };
204
+ try {
205
+ // Use helm template to show what would be deployed
206
+ const { stdout } = await execAsync('helm template . 2>&1', {
207
+ cwd: workdir,
208
+ timeout: 60_000,
209
+ maxBuffer: 10 * 1024 * 1024,
210
+ });
211
+ return {
212
+ ...base,
213
+ changes: [{ resource: 'helm-chart', action: 'create', details: 'Template rendered' }],
214
+ summary: { toCreate: 1, toUpdate: 0, toDestroy: 0, toReplace: 0, unchanged: 0 },
215
+ rawOutput: stdout,
216
+ success: true,
217
+ };
218
+ }
219
+ catch (error) {
220
+ const msg = error instanceof Error ? error.message : String(error);
221
+ return {
222
+ ...base,
223
+ changes: [],
224
+ summary: { toCreate: 0, toUpdate: 0, toDestroy: 0, toReplace: 0, unchanged: 0 },
225
+ rawOutput: '',
226
+ success: false,
227
+ error: msg,
228
+ };
229
+ }
230
+ }
231
+ // ---------------------------------------------------------------
232
+ // G9: Multi-file diff batch builder for Terraform plan output
233
+ // ---------------------------------------------------------------
234
+ /**
235
+ * G9: Build a FileDiffBatch from a Terraform plan preview.
236
+ *
237
+ * Parses the resource changes in the plan and represents each modified
238
+ * resource as a synthetic diff entry so they can be reviewed via the
239
+ * existing FileDiffModal batch flow.
240
+ *
241
+ * @param preview - DeployPreview from generateTerraformPreview
242
+ * @returns Array of file-diff entries suitable for FileDiffBatch.files
243
+ */
244
+ export function buildFileDiffBatchFromPlan(preview) {
245
+ return preview.changes.map(change => {
246
+ const actionLine = getChangeSymbolStr(change.action);
247
+ const diff = [
248
+ `--- a/${change.resource}`,
249
+ `+++ b/${change.resource}`,
250
+ `@@ -0,0 +1,1 @@`,
251
+ `${actionLine} ${change.resource}${change.details ? ` # ${change.details}` : ''}`,
252
+ ].join('\n');
253
+ return {
254
+ filePath: change.resource,
255
+ diff,
256
+ toolName: 'terraform',
257
+ };
258
+ });
259
+ }
260
+ function getChangeSymbolStr(action) {
261
+ switch (action) {
262
+ case 'create': return '+';
263
+ case 'update': return '~';
264
+ case 'destroy': return '-';
265
+ case 'replace': return '+/-';
266
+ default: return ' ';
267
+ }
268
+ }
269
+ // ---------------------------------------------------------------
270
+ // Output parsers
271
+ // ---------------------------------------------------------------
272
+ /**
273
+ * Parse the human-readable `terraform plan` output into structured
274
+ * {@link ResourceChange} entries.
275
+ *
276
+ * Recognises lines such as:
277
+ * `# aws_instance.web will be created`
278
+ * `# aws_instance.web will be updated in-place`
279
+ * `# aws_instance.web will be destroyed`
280
+ * `# aws_instance.web must be replaced`
281
+ *
282
+ * Falls back to the summary line (`Plan: X to add, Y to change, Z to destroy.`)
283
+ * when no individual resource lines are found.
284
+ */
285
+ export function parseTerraformPlanOutput(output) {
286
+ const changes = [];
287
+ const lines = output.split('\n');
288
+ for (const line of lines) {
289
+ // Match lines like: " # aws_instance.web will be created"
290
+ const createMatch = line.match(/^\s*#\s+(\S+)\s+will be created/);
291
+ if (createMatch) {
292
+ changes.push({ resource: createMatch[1], action: 'create' });
293
+ continue;
294
+ }
295
+ const updateMatch = line.match(/^\s*#\s+(\S+)\s+will be updated/);
296
+ if (updateMatch) {
297
+ changes.push({ resource: updateMatch[1], action: 'update' });
298
+ continue;
299
+ }
300
+ const destroyMatch = line.match(/^\s*#\s+(\S+)\s+will be destroyed/);
301
+ if (destroyMatch) {
302
+ changes.push({ resource: destroyMatch[1], action: 'destroy' });
303
+ continue;
304
+ }
305
+ const replaceMatch = line.match(/^\s*#\s+(\S+)\s+must be replaced/);
306
+ if (replaceMatch) {
307
+ changes.push({ resource: replaceMatch[1], action: 'replace' });
308
+ continue;
309
+ }
310
+ // Also match: "Plan: X to add, Y to change, Z to destroy."
311
+ const summaryMatch = line.match(/Plan:\s+(\d+)\s+to add,\s+(\d+)\s+to change,\s+(\d+)\s+to destroy/);
312
+ if (summaryMatch && changes.length === 0) {
313
+ // If we didn't find specific resources, create generic entries
314
+ const toAdd = parseInt(summaryMatch[1]);
315
+ const toChange = parseInt(summaryMatch[2]);
316
+ const toDestroy = parseInt(summaryMatch[3]);
317
+ for (let i = 0; i < toAdd; i++) {
318
+ changes.push({ resource: `resource_${i + 1}`, action: 'create' });
319
+ }
320
+ for (let i = 0; i < toChange; i++) {
321
+ changes.push({ resource: `resource_${toAdd + i + 1}`, action: 'update' });
322
+ }
323
+ for (let i = 0; i < toDestroy; i++) {
324
+ changes.push({ resource: `resource_${toAdd + toChange + i + 1}`, action: 'destroy' });
325
+ }
326
+ }
327
+ }
328
+ return changes;
329
+ }
330
+ /**
331
+ * Parse `kubectl diff` unified-diff output into structured
332
+ * {@link ResourceChange} entries.
333
+ *
334
+ * Each `diff -u` header is treated as a separate resource update.
335
+ * An empty or "no changes" output yields an empty array.
336
+ */
337
+ function parseKubectlDiffOutput(output) {
338
+ const changes = [];
339
+ const resourceRegex = /^diff -u.*\/(\S+)/gm;
340
+ let match;
341
+ while ((match = resourceRegex.exec(output)) !== null) {
342
+ changes.push({ resource: match[1], action: 'update' });
343
+ }
344
+ // If output is empty, no changes
345
+ if (output.trim() === '' || output.includes('no changes')) {
346
+ return [];
347
+ }
348
+ // If we found no specific resources but have output, assume updates
349
+ if (changes.length === 0 && output.trim().length > 0) {
350
+ changes.push({ resource: 'kubernetes-resources', action: 'update' });
351
+ }
352
+ return changes;
353
+ }
354
+ /**
355
+ * Aggregate an array of {@link ResourceChange} entries into the
356
+ * summary counts used by {@link DeployPreview}.
357
+ */
358
+ function summarizeChanges(changes) {
359
+ return {
360
+ toCreate: changes.filter(c => c.action === 'create').length,
361
+ toUpdate: changes.filter(c => c.action === 'update').length,
362
+ toDestroy: changes.filter(c => c.action === 'destroy').length,
363
+ toReplace: changes.filter(c => c.action === 'replace').length,
364
+ unchanged: changes.filter(c => c.action === 'no-op').length,
365
+ };
366
+ }
367
+ /**
368
+ * Map a {@link ResourceChange} action to a single-character symbol
369
+ * for display in the formatted preview.
370
+ *
371
+ * | Action | Symbol |
372
+ * |-----------|--------|
373
+ * | create | `+` |
374
+ * | update | `~` |
375
+ * | destroy | `-` |
376
+ * | replace | `+/-` |
377
+ * | read | `>` |
378
+ * | no-op | `=` |
379
+ */
380
+ function getChangeSymbol(action) {
381
+ switch (action) {
382
+ case 'create':
383
+ return '+';
384
+ case 'update':
385
+ return '~';
386
+ case 'destroy':
387
+ return '-';
388
+ case 'replace':
389
+ return '+/-';
390
+ case 'read':
391
+ return '>';
392
+ case 'no-op':
393
+ return '=';
394
+ }
395
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Shared @file reference expansion utility.
3
+ *
4
+ * Replaces @path/to/file references in a prompt with the file contents
5
+ * wrapped in <file> tags. Files larger than 10KB are truncated.
6
+ *
7
+ * Security: blocks path traversal (../../etc/passwd) and sensitive file patterns.
8
+ *
9
+ * Special tokens (G22):
10
+ * @workspace — concatenates all .tf files in cwd (up to 50KB)
11
+ * @cluster — instructs the agent to use the kubectl tool (async call not possible here)
12
+ */
13
+ import * as fs from 'node:fs';
14
+ import * as path from 'node:path';
15
+ /** Sensitive file patterns that should never be expanded. */
16
+ const SENSITIVE_FILE_RE = /(\.env|\.pem|\.key|\.p12|\.pfx|id_rsa|id_ed25519|credentials|\.netrc)$/i;
17
+ /**
18
+ * Expand @file references in a prompt string.
19
+ * Replaces @path/to/file with the file contents wrapped in <file> tags.
20
+ * Files larger than 10KB are truncated.
21
+ *
22
+ * Security: blocks path traversal outside the project root and sensitive
23
+ * file patterns (.env, .pem, .key, credentials, etc.).
24
+ */
25
+ export function expandFileReferences(text, cwd = process.cwd()) {
26
+ const fileRefs = text.match(/@([\w./_-]+)/g);
27
+ if (!fileRefs)
28
+ return text;
29
+ let expanded = text;
30
+ // G22: Handle @workspace special token — concatenate all .tf files
31
+ if (expanded.includes('@workspace')) {
32
+ try {
33
+ const tfFiles = fs.readdirSync(cwd).filter(f => f.endsWith('.tf'));
34
+ if (tfFiles.length > 0) {
35
+ const parts = [];
36
+ let totalSize = 0;
37
+ const MAX_SIZE = 50_000;
38
+ for (const file of tfFiles) {
39
+ if (totalSize >= MAX_SIZE) {
40
+ parts.push('... [truncated — 50KB limit reached]');
41
+ break;
42
+ }
43
+ try {
44
+ const content = fs.readFileSync(path.join(cwd, file), 'utf-8');
45
+ parts.push(`\n<file path="${file}">\n${content.slice(0, Math.min(content.length, MAX_SIZE - totalSize))}\n</file>`);
46
+ totalSize += content.length;
47
+ }
48
+ catch { /* skip unreadable files */ }
49
+ }
50
+ expanded = expanded.replace('@workspace', parts.join('\n'));
51
+ }
52
+ else {
53
+ expanded = expanded.replace('@workspace', '[No .tf files found in current directory]');
54
+ }
55
+ }
56
+ catch {
57
+ expanded = expanded.replace('@workspace', '[Error reading workspace files]');
58
+ }
59
+ }
60
+ // G22: Handle @cluster special token — kubectl get all
61
+ // @cluster requires an async kubectl call — guide agent to use the kubectl tool instead
62
+ if (expanded.includes('@cluster')) {
63
+ expanded = expanded.replace('@cluster', '[Use the kubectl tool with action=get and args="all -A" to retrieve cluster resources]');
64
+ }
65
+ for (const ref of fileRefs) {
66
+ // Skip special tokens already handled above
67
+ if (ref === '@workspace' || ref === '@cluster') {
68
+ continue;
69
+ }
70
+ const filePath = ref.slice(1);
71
+ try {
72
+ const resolved = path.resolve(cwd, filePath);
73
+ // Security: block path traversal outside project root
74
+ const rel = path.relative(cwd, resolved);
75
+ if (rel.startsWith('..') || path.isAbsolute(rel)) {
76
+ expanded = expanded.replace(ref, `[File blocked: path "${filePath}" is outside the project directory]`);
77
+ continue;
78
+ }
79
+ // Security: block sensitive file patterns
80
+ if (SENSITIVE_FILE_RE.test(resolved)) {
81
+ expanded = expanded.replace(ref, `[File blocked: "${filePath}" matches sensitive file pattern]`);
82
+ continue;
83
+ }
84
+ const content = fs.readFileSync(resolved, 'utf-8');
85
+ const truncated = content.length > 10_000
86
+ ? `${content.slice(0, 10_000)}\n... (truncated — showing 10,000 of ${content.length.toLocaleString()} chars)`
87
+ : content;
88
+ expanded = expanded.replace(ref, `\n<file path="${filePath}">\n${truncated}\n</file>`);
89
+ }
90
+ catch {
91
+ // File not found — leave the @reference as-is
92
+ }
93
+ }
94
+ return expanded;
95
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Agent System — Barrel re-exports
3
+ *
4
+ * Core agentic loop, system prompt builder, permission engine,
5
+ * context manager, and subagent system.
6
+ */
7
+ // Core agentic loop
8
+ export { runAgentLoop, getToolsForMode, } from './loop';
9
+ // System prompt builder
10
+ export { buildSystemPrompt, loadNimbusMd, } from './system-prompt';
11
+ // Permission engine
12
+ export { checkPermission, createPermissionState, approveForSession, approveActionForSession, } from './permissions';
13
+ // Context manager — @file/@folder reference resolution
14
+ export { resolveReferences, buildContextInjection, fuzzyFileSearch, } from './context';
15
+ // Deploy preview system
16
+ export { generateDeployPreview, formatDeployPreview, } from './deploy-preview';
17
+ // Subagent system
18
+ export { Subagent, createSubagent, parseAgentMention, createExploreSubagent, createInfraSubagent, createSecuritySubagent, createCostSubagent, createGeneralSubagent, } from './subagents';