@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,36 @@
1
+ import { logger } from './logger';
2
+ const SERVICE_TOKEN_HEADER = 'x-internal-service-token';
3
+ export function validateServiceToken(req) {
4
+ const expectedToken = process.env.INTERNAL_SERVICE_TOKEN;
5
+ if (!expectedToken) {
6
+ return true;
7
+ }
8
+ const providedToken = req.headers.get(SERVICE_TOKEN_HEADER);
9
+ return providedToken === expectedToken;
10
+ }
11
+ export function serviceAuthMiddleware(req) {
12
+ const expectedToken = process.env.INTERNAL_SERVICE_TOKEN;
13
+ if (!expectedToken) {
14
+ return null;
15
+ }
16
+ const url = new URL(req.url);
17
+ const path = url.pathname;
18
+ if (path === '/health' || path.startsWith('/swagger') || path === '/api/openapi.json') {
19
+ return null;
20
+ }
21
+ if (!path.startsWith('/api/')) {
22
+ return null;
23
+ }
24
+ if (!validateServiceToken(req)) {
25
+ logger.warn(`Unauthorized service request to ${path}`);
26
+ return Response.json({ success: false, error: 'Unauthorized: invalid or missing service token' }, { status: 401 });
27
+ }
28
+ return null;
29
+ }
30
+ export function getServiceAuthHeaders() {
31
+ const token = process.env.INTERNAL_SERVICE_TOKEN;
32
+ if (!token) {
33
+ return {};
34
+ }
35
+ return { [SERVICE_TOKEN_HEADER]: token };
36
+ }
@@ -0,0 +1,39 @@
1
+ import { ValidationError } from './errors';
2
+ export function validateRequired(value, fieldName, service) {
3
+ if (value === undefined || value === null || value === '') {
4
+ throw new ValidationError(`Field '${fieldName}' is required`, service, { field: fieldName });
5
+ }
6
+ }
7
+ export function validateString(value, fieldName, service) {
8
+ if (typeof value !== 'string') {
9
+ throw new ValidationError(`Field '${fieldName}' must be a string`, service, {
10
+ field: fieldName,
11
+ received: typeof value,
12
+ });
13
+ }
14
+ return value;
15
+ }
16
+ export function validateNumber(value, fieldName, service) {
17
+ if (typeof value !== 'number' || isNaN(value)) {
18
+ throw new ValidationError(`Field '${fieldName}' must be a number`, service, {
19
+ field: fieldName,
20
+ received: typeof value,
21
+ });
22
+ }
23
+ return value;
24
+ }
25
+ export function validateBoolean(value, fieldName, service) {
26
+ if (typeof value !== 'boolean') {
27
+ throw new ValidationError(`Field '${fieldName}' must be a boolean`, service, {
28
+ field: fieldName,
29
+ received: typeof value,
30
+ });
31
+ }
32
+ return value;
33
+ }
34
+ export function validateEnum(value, fieldName, allowedValues, service) {
35
+ if (typeof value !== 'string' || !allowedValues.includes(value)) {
36
+ throw new ValidationError(`Field '${fieldName}' must be one of: ${allowedValues.join(', ')}`, service, { field: fieldName, received: value, allowed: allowedValues });
37
+ }
38
+ return value;
39
+ }
@@ -0,0 +1,3 @@
1
+ export const VERSION = '0.4.0';
2
+ const _RAW_BUILD_DATE = '__BUILD_DATE__';
3
+ export const BUILD_DATE = _RAW_BUILD_DATE.startsWith('__') ? 'dev' : _RAW_BUILD_DATE;
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Filesystem Watcher
3
+ *
4
+ * Watches the project directory for file changes and emits events
5
+ * that the agent loop can respond to (e.g., re-reading modified files).
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import { EventEmitter } from 'node:events';
10
+ export class FileWatcher extends EventEmitter {
11
+ rootDir;
12
+ watcher = null;
13
+ /** Circular ring buffer for file-change events (avoids O(n) shift on cap). */
14
+ changesBuffer;
15
+ changesHead = 0; // index of the next write slot
16
+ changesSize = 0; // number of valid entries currently stored
17
+ maxChanges = 100;
18
+ ignorePatterns = [
19
+ 'node_modules',
20
+ '.git',
21
+ 'dist',
22
+ 'coverage',
23
+ '.nimbus',
24
+ '__pycache__',
25
+ '.terraform',
26
+ ];
27
+ constructor(rootDir) {
28
+ super();
29
+ this.rootDir = rootDir;
30
+ this.changesBuffer = new Array(this.maxChanges);
31
+ }
32
+ /** Push a change event into the ring buffer (O(1)). */
33
+ pushChange(event) {
34
+ this.changesBuffer[this.changesHead] = event;
35
+ this.changesHead = (this.changesHead + 1) % this.maxChanges;
36
+ if (this.changesSize < this.maxChanges) {
37
+ this.changesSize++;
38
+ }
39
+ }
40
+ /** Return all stored change events in chronological order. */
41
+ getOrderedChanges() {
42
+ if (this.changesSize === 0)
43
+ return [];
44
+ const start = this.changesSize < this.maxChanges
45
+ ? 0
46
+ : this.changesHead; // oldest slot when buffer is full
47
+ const result = new Array(this.changesSize);
48
+ for (let i = 0; i < this.changesSize; i++) {
49
+ result[i] = this.changesBuffer[(start + i) % this.maxChanges];
50
+ }
51
+ return result;
52
+ }
53
+ /**
54
+ * Start watching the project directory.
55
+ */
56
+ start() {
57
+ if (this.watcher) {
58
+ return;
59
+ }
60
+ try {
61
+ this.watcher = fs.watch(this.rootDir, { recursive: true }, (eventType, filename) => {
62
+ if (!filename) {
63
+ return;
64
+ }
65
+ // Skip ignored paths
66
+ const parts = filename.split(path.sep);
67
+ if (parts.some(p => this.ignorePatterns.includes(p))) {
68
+ return;
69
+ }
70
+ // Skip hidden files
71
+ if (parts.some(p => p.startsWith('.') && p !== '.env')) {
72
+ return;
73
+ }
74
+ const event = {
75
+ type: eventType,
76
+ path: path.join(this.rootDir, filename),
77
+ timestamp: Date.now(),
78
+ };
79
+ this.pushChange(event);
80
+ this.emit('change', event);
81
+ });
82
+ // recursive:true is only supported on macOS and Windows.
83
+ // On Linux, fs.watch silently ignores the flag and only watches the root dir.
84
+ if (process.platform === 'linux') {
85
+ // Watch key subdirectories individually as a workaround
86
+ const subdirs = ['src', 'lib', 'app', 'packages', 'services', 'test', 'tests', 'scripts'];
87
+ for (const sub of subdirs) {
88
+ const subPath = path.join(this.rootDir, sub);
89
+ try {
90
+ if (fs.existsSync(subPath) && fs.statSync(subPath).isDirectory()) {
91
+ fs.watch(subPath, { recursive: false }, (eventType, filename) => {
92
+ if (!filename) {
93
+ return;
94
+ }
95
+ const fullPath = path.join(subPath, filename);
96
+ const relParts = path.relative(this.rootDir, fullPath).split(path.sep);
97
+ if (relParts.some(p => this.ignorePatterns.includes(p))) {
98
+ return;
99
+ }
100
+ if (relParts.some(p => p.startsWith('.') && p !== '.env')) {
101
+ return;
102
+ }
103
+ const event = {
104
+ type: eventType,
105
+ path: fullPath,
106
+ timestamp: Date.now(),
107
+ };
108
+ this.pushChange(event);
109
+ this.emit('change', event);
110
+ });
111
+ }
112
+ }
113
+ catch {
114
+ /* non-critical */
115
+ }
116
+ }
117
+ }
118
+ }
119
+ catch {
120
+ // Watching is non-critical -- some systems don't support recursive watch
121
+ }
122
+ }
123
+ /**
124
+ * Stop watching.
125
+ */
126
+ stop() {
127
+ if (this.watcher) {
128
+ this.watcher.close();
129
+ this.watcher = null;
130
+ }
131
+ }
132
+ /**
133
+ * Get recent changes since a timestamp.
134
+ */
135
+ getChangesSince(timestamp) {
136
+ return this.getOrderedChanges().filter(c => c.timestamp > timestamp);
137
+ }
138
+ /**
139
+ * Get a summary of recent changes for the agent context.
140
+ * When `devopsOnly` is true, filters to DevOps-relevant files only:
141
+ * .tf, .yaml, .yml, Dockerfile, docker-compose.*, Jenkinsfile, .github/workflows/*.
142
+ */
143
+ getSummary(since, devopsOnly = false) {
144
+ const relevant = since ? this.getChangesSince(since) : this.getOrderedChanges();
145
+ if (relevant.length === 0) {
146
+ return '';
147
+ }
148
+ const filtered = devopsOnly
149
+ ? relevant.filter(c => {
150
+ const f = c.path.toLowerCase();
151
+ const base = path.basename(f);
152
+ return (f.endsWith('.tf') ||
153
+ f.endsWith('.tfvars') ||
154
+ f.endsWith('.yaml') ||
155
+ f.endsWith('.yml') ||
156
+ base === 'dockerfile' ||
157
+ base.startsWith('dockerfile.') ||
158
+ base.startsWith('docker-compose') ||
159
+ base === 'jenkinsfile' ||
160
+ f.includes('.github/workflows'));
161
+ })
162
+ : relevant;
163
+ if (filtered.length === 0) {
164
+ return '';
165
+ }
166
+ const uniquePaths = [...new Set(filtered.map(c => c.path))];
167
+ const lines = uniquePaths.slice(-20).map(p => {
168
+ const rel = path.relative(this.rootDir, p);
169
+ // Categorize for DevOps context
170
+ let category = '';
171
+ const lower = rel.toLowerCase();
172
+ if (lower.endsWith('.tf') || lower.endsWith('.tfvars'))
173
+ category = ' [terraform]';
174
+ else if (lower.endsWith('.yaml') || lower.endsWith('.yml'))
175
+ category = ' [yaml/k8s]';
176
+ else if (lower.includes('dockerfile'))
177
+ category = ' [docker]';
178
+ return ` - ${rel}${category}`;
179
+ });
180
+ return `Files changed externally:\n${lines.join('\n')}`;
181
+ }
182
+ /**
183
+ * Clear the change history.
184
+ */
185
+ clearChanges() {
186
+ this.changesHead = 0;
187
+ this.changesSize = 0;
188
+ }
189
+ get isWatching() {
190
+ return this.watcher !== null;
191
+ }
192
+ }
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Approval Workflow Component
3
+ *
4
+ * Displays approval prompts for risky operations
5
+ */
6
+ import { ui } from './ui';
7
+ import { confirm, input } from './prompts';
8
+ /**
9
+ * Display an approval prompt and return the result
10
+ */
11
+ export async function promptForApproval(config) {
12
+ ui.newLine();
13
+ // Draw approval box
14
+ drawApprovalBox(config);
15
+ // Display risks
16
+ displayRisks(config.risks);
17
+ // Display affected resources if any
18
+ if (config.affectedResources && config.affectedResources.length > 0) {
19
+ displayAffectedResources(config.affectedResources);
20
+ }
21
+ // Display estimated cost if available
22
+ if (config.estimatedCost !== undefined) {
23
+ displayEstimatedCost(config.estimatedCost);
24
+ }
25
+ ui.newLine();
26
+ // Require confirmation for critical operations
27
+ const hasCritical = config.risks.some(r => r.severity === 'critical');
28
+ const hasDestructive = config.operation.toLowerCase().includes('destroy') ||
29
+ config.operation.toLowerCase().includes('delete');
30
+ if (hasCritical || hasDestructive || config.requireConfirmation) {
31
+ const confirmWord = config.confirmationWord || 'yes';
32
+ const userInput = await input({
33
+ message: `Type "${confirmWord}" to confirm:`,
34
+ defaultValue: '',
35
+ });
36
+ if (userInput.toLowerCase() !== confirmWord.toLowerCase()) {
37
+ ui.newLine();
38
+ ui.warning('Operation cancelled - confirmation word did not match');
39
+ return {
40
+ approved: false,
41
+ reason: 'Confirmation word mismatch',
42
+ timestamp: new Date(),
43
+ };
44
+ }
45
+ }
46
+ else {
47
+ // Simple confirmation
48
+ const proceed = await confirm({
49
+ message: 'Do you want to proceed with this operation?',
50
+ defaultValue: false,
51
+ });
52
+ if (!proceed) {
53
+ ui.newLine();
54
+ ui.info('Operation cancelled by user');
55
+ return {
56
+ approved: false,
57
+ reason: 'User declined',
58
+ timestamp: new Date(),
59
+ };
60
+ }
61
+ }
62
+ ui.newLine();
63
+ ui.success('Operation approved');
64
+ return {
65
+ approved: true,
66
+ approvedBy: process.env.USER || 'unknown',
67
+ timestamp: new Date(),
68
+ };
69
+ }
70
+ /**
71
+ * Draw the approval box header
72
+ */
73
+ function drawApprovalBox(config) {
74
+ const width = 60;
75
+ const borderColor = getSeverityColor(getHighestSeverity(config.risks));
76
+ ui.print(ui.color(`╔${'═'.repeat(width - 2)}╗`, borderColor));
77
+ // Title
78
+ const titleLine = ` APPROVAL REQUIRED `;
79
+ const padding = Math.floor((width - 2 - titleLine.length) / 2);
80
+ ui.print(ui.color('║', borderColor) +
81
+ ' '.repeat(padding) +
82
+ ui.bold(ui.color(titleLine, 'yellow')) +
83
+ ' '.repeat(width - 2 - padding - titleLine.length) +
84
+ ui.color('║', borderColor));
85
+ ui.print(ui.color(`╠${'═'.repeat(width - 2)}╣`, borderColor));
86
+ // Operation
87
+ const opLine = ` Operation: ${config.operation}`;
88
+ ui.print(ui.color('║', borderColor) + opLine.padEnd(width - 2) + ui.color('║', borderColor));
89
+ // Environment if available
90
+ if (config.environment) {
91
+ const envLine = ` Environment: ${config.environment}`;
92
+ ui.print(ui.color('║', borderColor) +
93
+ ui.color(envLine.padEnd(width - 2), 'yellow') +
94
+ ui.color('║', borderColor));
95
+ }
96
+ ui.print(ui.color(`╚${'═'.repeat(width - 2)}╝`, borderColor));
97
+ }
98
+ /**
99
+ * Display the list of risks
100
+ */
101
+ function displayRisks(risks) {
102
+ if (risks.length === 0) {
103
+ return;
104
+ }
105
+ ui.newLine();
106
+ ui.print(ui.bold(' Identified Risks:'));
107
+ ui.newLine();
108
+ // Sort by severity
109
+ const sortedRisks = [...risks].sort((a, b) => {
110
+ const order = { critical: 0, high: 1, medium: 2, low: 3 };
111
+ return order[a.severity] - order[b.severity];
112
+ });
113
+ for (const risk of sortedRisks) {
114
+ const icon = getSeverityIcon(risk.severity);
115
+ const color = getSeverityColor(risk.severity);
116
+ const label = `[${risk.severity.toUpperCase()}]`.padEnd(10);
117
+ ui.print(` ${icon} ${ui.color(label, color)} ${risk.message}`);
118
+ // Show details if available
119
+ if (risk.details) {
120
+ for (const [key, value] of Object.entries(risk.details)) {
121
+ ui.print(ui.dim(` ${key}: ${value}`));
122
+ }
123
+ }
124
+ }
125
+ }
126
+ /**
127
+ * Display affected resources
128
+ */
129
+ function displayAffectedResources(resources) {
130
+ ui.newLine();
131
+ ui.print(ui.bold(' Affected Resources:'));
132
+ ui.newLine();
133
+ const maxDisplay = 10;
134
+ const displayResources = resources.slice(0, maxDisplay);
135
+ for (const resource of displayResources) {
136
+ ui.print(` ${ui.color('•', 'cyan')} ${resource}`);
137
+ }
138
+ if (resources.length > maxDisplay) {
139
+ ui.print(ui.dim(` ... and ${resources.length - maxDisplay} more`));
140
+ }
141
+ }
142
+ /**
143
+ * Display estimated cost
144
+ */
145
+ function displayEstimatedCost(cost) {
146
+ ui.newLine();
147
+ ui.print(ui.bold(' Estimated Cost:'));
148
+ ui.newLine();
149
+ const costStr = `$${cost.toFixed(2)}/month`;
150
+ const color = cost > 1000 ? 'red' : cost > 500 ? 'yellow' : 'green';
151
+ ui.print(` ${ui.color(costStr, color)}`);
152
+ }
153
+ /**
154
+ * Get the highest severity from a list of risks
155
+ */
156
+ function getHighestSeverity(risks) {
157
+ const order = ['critical', 'high', 'medium', 'low'];
158
+ for (const severity of order) {
159
+ if (risks.some(r => r.severity === severity)) {
160
+ return severity;
161
+ }
162
+ }
163
+ return 'low';
164
+ }
165
+ /**
166
+ * Get icon for severity level
167
+ */
168
+ function getSeverityIcon(severity) {
169
+ switch (severity) {
170
+ case 'critical':
171
+ return '🔴';
172
+ case 'high':
173
+ return '🟠';
174
+ case 'medium':
175
+ return '🟡';
176
+ case 'low':
177
+ return '🔵';
178
+ default:
179
+ return '⚪';
180
+ }
181
+ }
182
+ /**
183
+ * Get color for severity level
184
+ */
185
+ function getSeverityColor(severity) {
186
+ switch (severity) {
187
+ case 'critical':
188
+ return 'red';
189
+ case 'high':
190
+ return 'yellow';
191
+ case 'medium':
192
+ return 'cyan';
193
+ case 'low':
194
+ return 'blue';
195
+ default:
196
+ return 'white';
197
+ }
198
+ }
199
+ /**
200
+ * Quick approval check without full prompt
201
+ * Returns true if the operation should proceed based on policy
202
+ */
203
+ export function shouldAutoApprove(operation, risks) {
204
+ // Never auto-approve if there are critical risks
205
+ if (risks.some(r => r.severity === 'critical')) {
206
+ return false;
207
+ }
208
+ // Never auto-approve destructive operations
209
+ if (['destroy', 'delete', 'terminate'].some(op => operation.toLowerCase().includes(op))) {
210
+ return false;
211
+ }
212
+ // Auto-approve if all risks are low severity
213
+ if (risks.every(r => r.severity === 'low')) {
214
+ return true;
215
+ }
216
+ return false;
217
+ }
218
+ /**
219
+ * Confirm a destructive operation by requiring the user to type the resource name.
220
+ * Returns true only if the typed name matches exactly.
221
+ */
222
+ export async function confirmWithResourceName(resourceName, resourceType) {
223
+ ui.newLine();
224
+ // Display warning box
225
+ const width = 60;
226
+ ui.print(ui.color(`╔${'═'.repeat(width - 2)}╗`, 'red'));
227
+ const titleLine = ' DESTRUCTIVE OPERATION ';
228
+ const padding = Math.floor((width - 2 - titleLine.length) / 2);
229
+ ui.print(ui.color('║', 'red') +
230
+ ' '.repeat(padding) +
231
+ ui.bold(ui.color(titleLine, 'yellow')) +
232
+ ' '.repeat(width - 2 - padding - titleLine.length) +
233
+ ui.color('║', 'red'));
234
+ ui.print(ui.color(`╠${'═'.repeat(width - 2)}╣`, 'red'));
235
+ const typeLine = ` Resource type: ${resourceType}`;
236
+ ui.print(ui.color('║', 'red') + typeLine.padEnd(width - 2) + ui.color('║', 'red'));
237
+ const nameLine = ` Resource name: ${resourceName}`;
238
+ ui.print(ui.color('║', 'red') + ui.color(nameLine.padEnd(width - 2), 'yellow') + ui.color('║', 'red'));
239
+ const warnLine = ' This action CANNOT be undone.';
240
+ ui.print(ui.color('║', 'red') + ui.color(warnLine.padEnd(width - 2), 'red') + ui.color('║', 'red'));
241
+ ui.print(ui.color(`╚${'═'.repeat(width - 2)}╝`, 'red'));
242
+ ui.newLine();
243
+ const userInput = await input({
244
+ message: `Type '${resourceName}' to confirm deletion:`,
245
+ defaultValue: '',
246
+ });
247
+ if (userInput !== resourceName) {
248
+ ui.newLine();
249
+ ui.warning('Operation cancelled - resource name did not match');
250
+ return false;
251
+ }
252
+ ui.newLine();
253
+ ui.success('Deletion confirmed');
254
+ return true;
255
+ }
256
+ /**
257
+ * Display a safety summary without approval prompt
258
+ */
259
+ export function displaySafetySummary(config) {
260
+ if (config.risks.length === 0) {
261
+ ui.success(`Safety check passed for: ${config.operation}`);
262
+ return;
263
+ }
264
+ ui.newLine();
265
+ ui.print(ui.bold(' Safety Check Summary:'));
266
+ ui.newLine();
267
+ displayRisks(config.risks);
268
+ ui.newLine();
269
+ if (config.passed) {
270
+ ui.success('All safety checks passed');
271
+ }
272
+ else {
273
+ ui.error('Safety checks failed - operation blocked');
274
+ }
275
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Interactive Wizard Framework
3
+ *
4
+ * Exports all wizard-related functionality
5
+ */
6
+ // Types
7
+ export * from './types';
8
+ // UI utilities
9
+ export { WizardUI, ui } from './ui';
10
+ // Prompt utilities
11
+ export { select, multiSelect, confirm, input, pathInput, pressEnter, actionSelect, } from './prompts';
12
+ // Wizard framework
13
+ export { Wizard, createWizard, stepBuilders } from './wizard';