@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
@@ -5,11 +5,11 @@
5
5
  * based on mode, tools, NIMBUS.md, subagent state, and environment context.
6
6
  */
7
7
 
8
- import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
8
+ import { describe, test, expect, beforeEach, afterEach } from 'vitest';
9
9
  import * as fs from 'node:fs';
10
10
  import * as path from 'node:path';
11
11
  import * as os from 'node:os';
12
- import { buildSystemPrompt, loadNimbusMd } from '../agent/system-prompt';
12
+ import { buildSystemPrompt, loadNimbusMd, extractForbiddenRules } from '../agent/system-prompt';
13
13
  import type { ToolDefinition } from '../tools/schemas/types';
14
14
  import { z } from 'zod';
15
15
 
@@ -51,7 +51,9 @@ describe('buildSystemPrompt', () => {
51
51
  test('includes base identity', () => {
52
52
  const prompt = buildSystemPrompt({ mode: 'build', tools: [] });
53
53
  expect(prompt).toContain('You are Nimbus');
54
- expect(prompt).toContain('AI-powered DevOps');
54
+ // C2: new DevOps-operator-first framing
55
+ expect(prompt).toContain('autonomous DevOps operator');
56
+ expect(prompt).toContain('RUN commands and query live state');
55
57
  });
56
58
 
57
59
  test('includes mode-specific instructions for "plan"', () => {
@@ -167,3 +169,80 @@ describe('loadNimbusMd', () => {
167
169
  expect(result).toBe('root-level');
168
170
  });
169
171
  });
172
+
173
+ // ===========================================================================
174
+ // G14: extractForbiddenRules
175
+ // ===========================================================================
176
+
177
+ describe('extractForbiddenRules (G14)', () => {
178
+ test('extracts bullet items from ## Forbidden section', () => {
179
+ const content = `
180
+ ## Safety Rules
181
+
182
+ - Do not break prod
183
+
184
+ ## Forbidden
185
+
186
+ - Never destroy the production database
187
+ - Never delete the S3 bucket
188
+ - Never run rm -rf /
189
+
190
+ ## Custom Instructions
191
+
192
+ Some other stuff
193
+ `;
194
+ const rules = extractForbiddenRules(content);
195
+ expect(rules).toHaveLength(3);
196
+ expect(rules[0]).toBe('Never destroy the production database');
197
+ expect(rules[1]).toBe('Never delete the S3 bucket');
198
+ expect(rules[2]).toBe('Never run rm -rf /');
199
+ });
200
+
201
+ test('returns empty array when no Forbidden section', () => {
202
+ const content = '## Safety Rules\n\n- Be careful\n';
203
+ expect(extractForbiddenRules(content)).toEqual([]);
204
+ });
205
+
206
+ test('ignores HTML comment lines', () => {
207
+ const content = `
208
+ ## Forbidden
209
+
210
+ <!-- Example: - Never destroy the database -->
211
+ - Never touch prod
212
+ `;
213
+ const rules = extractForbiddenRules(content);
214
+ expect(rules).toHaveLength(1);
215
+ expect(rules[0]).toBe('Never touch prod');
216
+ });
217
+
218
+ test('G14: prompt includes HARD CONSTRAINTS block when Forbidden section has entries', () => {
219
+ const nimbusContent = `
220
+ ## Forbidden
221
+
222
+ - Never destroy the production database
223
+ - Never run terraform destroy in prod
224
+ `;
225
+ const prompt = buildSystemPrompt({
226
+ mode: 'build',
227
+ tools: [],
228
+ nimbusInstructions: nimbusContent,
229
+ });
230
+ expect(prompt).toContain('HARD CONSTRAINTS');
231
+ expect(prompt).toContain('Never destroy the production database');
232
+ expect(prompt).toContain('STRICTLY FORBIDDEN');
233
+ });
234
+
235
+ test('G14: prompt does not include HARD CONSTRAINTS when Forbidden section is empty/comments', () => {
236
+ const nimbusContent = `
237
+ ## Forbidden
238
+
239
+ <!-- List operations Nimbus must never perform in this project -->
240
+ `;
241
+ const prompt = buildSystemPrompt({
242
+ mode: 'build',
243
+ tools: [],
244
+ nimbusInstructions: nimbusContent,
245
+ });
246
+ expect(prompt).not.toContain('HARD CONSTRAINTS');
247
+ });
248
+ });
@@ -0,0 +1,395 @@
1
+ /**
2
+ * Terminal Gap Fix Plan v2 Tests
3
+ *
4
+ * Validates confirmed gaps from the second deep investigation of Nimbus vs
5
+ * OpenCode terminal parity. Tests are pure source-level checks (no runtime
6
+ * rendering) so they run fast and reliably in CI.
7
+ *
8
+ * Coverage:
9
+ * C1 — Terminal resize listener
10
+ * C2 — Dynamic maxVisible (not hardcoded 500)
11
+ * C3 — Ollama provider file exists and exports OllamaProvider
12
+ * C4 — LSP manager emits 'lsp-unavailable'
13
+ * C5 — stderr lines colored dim-red in spawn-exec
14
+ * C6 — awsRegion injected into system-prompt resource inventory
15
+ * H1 — auth-cloud.ts contains SSO/OAuth CLI delegation
16
+ * H2 — MessageList.tsx has highlightText helper
17
+ * H3 — drift/index.ts contains ConfigMap drift check
18
+ * H4 — PermissionPrompt.tsx has RISK_DESCRIPTIONS
19
+ * H5 — App.tsx has modeToast state
20
+ * L1 — Header.tsx uses [P]/[B]/[D]; App.tsx uses [OK]/[!!]
21
+ * L2 — InputBox.tsx has 10_000 paste guard
22
+ * L3 — ink/index.ts has "list my kubernetes pods" welcome hint
23
+ */
24
+
25
+ import { describe, it, expect } from 'vitest';
26
+ import { readFileSync } from 'node:fs';
27
+ import { join } from 'node:path';
28
+
29
+ const src = (rel: string) => readFileSync(join(process.cwd(), rel), 'utf-8');
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // C1 — Terminal resize listener
33
+ // ---------------------------------------------------------------------------
34
+
35
+ describe('C1 — terminal resize listener', () => {
36
+ it('ink/index.ts listens to process.stdout resize event', () => {
37
+ const code = src('src/ui/ink/index.ts');
38
+ expect(code).toContain("process.stdout.on('resize'");
39
+ });
40
+
41
+ it('ink/index.ts handles SIGWINCH', () => {
42
+ const code = src('src/ui/ink/index.ts');
43
+ expect(code).toContain("process.on('SIGWINCH'");
44
+ });
45
+
46
+ it('App.tsx accepts columns prop', () => {
47
+ const code = src('src/ui/App.tsx');
48
+ expect(code).toContain('columns?:');
49
+ });
50
+
51
+ it('MessageList.tsx accepts columns prop', () => {
52
+ const code = src('src/ui/MessageList.tsx');
53
+ expect(code).toContain('columns?:');
54
+ });
55
+ });
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // C2 — Dynamic maxVisible
59
+ // ---------------------------------------------------------------------------
60
+
61
+ describe('C2 — dynamic maxVisible (not hardcoded 500)', () => {
62
+ it('MessageList no longer uses hardcoded 500 as default', () => {
63
+ const code = src('src/ui/MessageList.tsx');
64
+ // The default should now use process.stdout.rows, not = 500
65
+ expect(code).toContain('process.stdout.rows');
66
+ });
67
+
68
+ it('MessageList uses useMemo for visible slice', () => {
69
+ const code = src('src/ui/MessageList.tsx');
70
+ expect(code).toContain('useMemo');
71
+ // Should contain effectiveMaxVisible computation
72
+ expect(code).toContain('effectiveMaxVisible');
73
+ });
74
+
75
+ it('MessageList shows ↑ N earlier messages hint when truncated', () => {
76
+ const code = src('src/ui/MessageList.tsx');
77
+ expect(code).toContain('\u2191');
78
+ });
79
+ });
80
+
81
+ // ---------------------------------------------------------------------------
82
+ // C3 — Ollama provider
83
+ // ---------------------------------------------------------------------------
84
+
85
+ describe('C3 — Ollama provider', () => {
86
+ it('src/llm/providers/ollama.ts exists and exports OllamaProvider', async () => {
87
+ const { OllamaProvider } = await import('../llm/providers/ollama');
88
+ expect(typeof OllamaProvider).toBe('function');
89
+ });
90
+
91
+ it('ollama.ts references OLLAMA_BASE_URL', () => {
92
+ const code = src('src/llm/providers/ollama.ts');
93
+ expect(code).toContain('OLLAMA_BASE_URL');
94
+ });
95
+
96
+ it('router.ts imports OllamaProvider', () => {
97
+ const code = src('src/llm/router.ts');
98
+ expect(code).toContain('OllamaProvider');
99
+ });
100
+
101
+ it('onboarding.ts has Ollama option (supportsBaseUrl or no API key required)', () => {
102
+ const code = src('src/commands/onboarding.ts');
103
+ // Ollama is handled via supportsBaseUrl branch
104
+ expect(code).toContain('supportsBaseUrl');
105
+ });
106
+ });
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // C4 — LSP unavailability event
110
+ // ---------------------------------------------------------------------------
111
+
112
+ describe('C4 — LSP unavailability event', () => {
113
+ it('LSPManager extends EventEmitter', () => {
114
+ const code = src('src/lsp/manager.ts');
115
+ expect(code).toContain('extends EventEmitter');
116
+ });
117
+
118
+ it('LSPManager has failedLSPs set', () => {
119
+ const code = src('src/lsp/manager.ts');
120
+ expect(code).toContain('failedLSPs');
121
+ });
122
+
123
+ it("LSPManager emits 'lsp-unavailable' when server not found", () => {
124
+ const code = src('src/lsp/manager.ts');
125
+ expect(code).toContain("emit('lsp-unavailable'");
126
+ });
127
+
128
+ it('ink/index.ts listens to lsp-unavailable and adds system message', () => {
129
+ const code = src('src/ui/ink/index.ts');
130
+ expect(code).toContain('lsp-unavailable');
131
+ expect(code).toContain('[LSP]');
132
+ });
133
+ });
134
+
135
+ // ---------------------------------------------------------------------------
136
+ // C5 — stderr ANSI color prefix
137
+ // ---------------------------------------------------------------------------
138
+
139
+ describe('C5 — stderr visually distinct from stdout', () => {
140
+ it('spawn-exec.ts prefixes stderr with dim-red ANSI code', () => {
141
+ const code = src('src/tools/spawn-exec.ts');
142
+ expect(code).toContain('\\x1b[2;31m');
143
+ // The ANSI reset code
144
+ expect(code).toContain('\\x1b[0m');
145
+ });
146
+
147
+ it('spawn-exec.ts separates tagged stderr buffer from raw stderr', () => {
148
+ const code = src('src/tools/spawn-exec.ts');
149
+ expect(code).toContain('tagged');
150
+ });
151
+ });
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // C6 — awsRegion in system prompt resource inventory
155
+ // ---------------------------------------------------------------------------
156
+
157
+ describe('C6 — awsRegion in system prompt resource inventory', () => {
158
+ it('system-prompt.ts includes awsRegion standalone entry in resource inventory', () => {
159
+ const code = src('src/agent/system-prompt.ts');
160
+ expect(code).toContain('AWS default region');
161
+ expect(code).toContain('awsRegion');
162
+ });
163
+ });
164
+
165
+ // ---------------------------------------------------------------------------
166
+ // H1 — Auth cloud SSO/OAuth CLI delegation
167
+ // ---------------------------------------------------------------------------
168
+
169
+ describe('H1 — cloud SSO/OAuth CLI delegation', () => {
170
+ it('auth-cloud.ts contains aws sso login', () => {
171
+ const code = src('src/commands/auth-cloud.ts');
172
+ expect(code).toContain('aws sso login');
173
+ });
174
+
175
+ it('auth-cloud.ts contains gcloud auth login', () => {
176
+ const code = src('src/commands/auth-cloud.ts');
177
+ expect(code).toContain('gcloud');
178
+ expect(code).toContain('auth login');
179
+ });
180
+
181
+ it('auth-cloud.ts contains az login --use-device-code', () => {
182
+ const code = src('src/commands/auth-cloud.ts');
183
+ expect(code).toContain('--use-device-code');
184
+ });
185
+
186
+ it('auth-cloud.ts exports loginCloudCommand', () => {
187
+ const code = src('src/commands/auth-cloud.ts');
188
+ expect(code).toContain('export async function loginCloudCommand');
189
+ });
190
+ });
191
+
192
+ // ---------------------------------------------------------------------------
193
+ // H2 — /search text highlight
194
+ // ---------------------------------------------------------------------------
195
+
196
+ describe('H2 — search text highlighting', () => {
197
+ it('MessageList.tsx has highlightText function', () => {
198
+ const code = src('src/ui/MessageList.tsx');
199
+ expect(code).toContain('function highlightText');
200
+ });
201
+
202
+ it('highlightText renders yellow bold for matches', () => {
203
+ const code = src('src/ui/MessageList.tsx');
204
+ expect(code).toContain("color=\"yellow\"");
205
+ expect(code).toContain('bold');
206
+ });
207
+
208
+ it('MessageRow accepts searchQuery prop', () => {
209
+ const code = src('src/ui/MessageList.tsx');
210
+ expect(code).toContain('searchQuery?: string');
211
+ });
212
+ });
213
+
214
+ // ---------------------------------------------------------------------------
215
+ // H3 — K8s drift detection
216
+ // ---------------------------------------------------------------------------
217
+
218
+ describe('H3 — K8s ConfigMap/Secret drift detection', () => {
219
+ it('drift/index.ts exports checkK8sDrift', () => {
220
+ const code = src('src/commands/drift/index.ts');
221
+ expect(code).toContain('export async function checkK8sDrift');
222
+ });
223
+
224
+ it('checkK8sDrift checks configmap resources', () => {
225
+ const code = src('src/commands/drift/index.ts');
226
+ expect(code).toContain('configmap');
227
+ });
228
+
229
+ it('checkK8sDrift supports --update-baseline', () => {
230
+ const code = src('src/commands/drift/index.ts');
231
+ expect(code).toContain('updateBaseline');
232
+ expect(code).toContain('drift-baseline.json');
233
+ });
234
+
235
+ it('driftCommand handles k8s subcommand', () => {
236
+ const code = src('src/commands/drift/index.ts');
237
+ expect(code).toContain("case 'k8s':");
238
+ });
239
+ });
240
+
241
+ // ---------------------------------------------------------------------------
242
+ // H4 — PermissionPrompt risk descriptions
243
+ // ---------------------------------------------------------------------------
244
+
245
+ describe('H4 — PermissionPrompt risk descriptions', () => {
246
+ it('PermissionPrompt.tsx has RISK_DESCRIPTIONS constant', () => {
247
+ const code = src('src/ui/PermissionPrompt.tsx');
248
+ expect(code).toContain('RISK_DESCRIPTIONS');
249
+ });
250
+
251
+ it('RISK_DESCRIPTIONS covers all four risk tiers', () => {
252
+ const code = src('src/ui/PermissionPrompt.tsx');
253
+ expect(code).toContain('Read-only');
254
+ expect(code).toContain('Modifies local files');
255
+ expect(code).toContain('System or cloud operation');
256
+ expect(code).toContain('Destructive or irreversible');
257
+ });
258
+
259
+ it('keyboard legend uses = separators', () => {
260
+ const code = src('src/ui/PermissionPrompt.tsx');
261
+ expect(code).toContain('=approve');
262
+ expect(code).toContain('=reject');
263
+ });
264
+ });
265
+
266
+ // ---------------------------------------------------------------------------
267
+ // H5 — Mode change toast
268
+ // ---------------------------------------------------------------------------
269
+
270
+ describe('H5 — mode change toast', () => {
271
+ it('App.tsx has modeToast state', () => {
272
+ const code = src('src/ui/App.tsx');
273
+ expect(code).toContain('modeToast');
274
+ });
275
+
276
+ it('modeToast is set on Tab mode cycle', () => {
277
+ const code = src('src/ui/App.tsx');
278
+ expect(code).toContain('setModeToast');
279
+ expect(code).toContain('→');
280
+ expect(code).toContain('mode');
281
+ });
282
+
283
+ it('StatusBar renders modeToast prop', () => {
284
+ const code = src('src/ui/StatusBar.tsx');
285
+ expect(code).toContain('modeToast');
286
+ });
287
+ });
288
+
289
+ // ---------------------------------------------------------------------------
290
+ // L1 — Emoji → ASCII icons
291
+ // ---------------------------------------------------------------------------
292
+
293
+ describe('L1 — emoji replaced with ASCII icons', () => {
294
+ it('Header.tsx uses [P] for plan mode', () => {
295
+ const code = src('src/ui/Header.tsx');
296
+ expect(code).toContain('[P] PLAN');
297
+ });
298
+
299
+ it('Header.tsx uses [B] for build mode', () => {
300
+ const code = src('src/ui/Header.tsx');
301
+ expect(code).toContain('[B] BUILD');
302
+ });
303
+
304
+ it('Header.tsx uses [D] for deploy mode', () => {
305
+ const code = src('src/ui/Header.tsx');
306
+ expect(code).toContain('[D] DEPLOY');
307
+ });
308
+
309
+ it('Header.tsx uses [+] for LLM health ok (not ●)', () => {
310
+ const code = src('src/ui/Header.tsx');
311
+ expect(code).toContain('[+]');
312
+ expect(code).not.toContain('● ok');
313
+ });
314
+
315
+ it('App.tsx uses [OK] instead of ✓', () => {
316
+ const code = src('src/ui/App.tsx');
317
+ expect(code).toContain('[OK]');
318
+ // Should not contain raw ✓ in message content strings
319
+ expect(code).not.toMatch(/content: `✓/);
320
+ });
321
+
322
+ it('App.tsx uses [!!] instead of ⚠ for prod warnings', () => {
323
+ const code = src('src/ui/App.tsx');
324
+ expect(code).toContain('[!!]');
325
+ // Should not contain raw ⚠ unicode in message content
326
+ expect(code).not.toMatch(/content: `\\u26a0/);
327
+ });
328
+
329
+ it('ink/index.ts uses [md] instead of 📄 for NIMBUS.md reload', () => {
330
+ const code = src('src/ui/ink/index.ts');
331
+ expect(code).toContain('[md] NIMBUS.md reloaded');
332
+ });
333
+ });
334
+
335
+ // ---------------------------------------------------------------------------
336
+ // L2 — Large paste guard
337
+ // ---------------------------------------------------------------------------
338
+
339
+ describe('L2 — large paste guard in InputBox', () => {
340
+ it('InputBox.tsx truncates input at 10_000 characters', () => {
341
+ const code = src('src/ui/InputBox.tsx');
342
+ expect(code).toMatch(/10[_,]?000/);
343
+ });
344
+
345
+ it('InputBox.tsx uses safeV for setValue', () => {
346
+ const code = src('src/ui/InputBox.tsx');
347
+ expect(code).toContain('safeV');
348
+ expect(code).toContain('setValue(safeV)');
349
+ });
350
+ });
351
+
352
+ // ---------------------------------------------------------------------------
353
+ // L3 — First-time welcome hints
354
+ // ---------------------------------------------------------------------------
355
+
356
+ describe('L3 — first-time user DevOps welcome hints', () => {
357
+ it('ink/index.ts shows "list my kubernetes pods" hint when no NIMBUS.md', () => {
358
+ const code = src('src/ui/ink/index.ts');
359
+ expect(code).toContain('list my kubernetes pods');
360
+ });
361
+
362
+ it('ink/index.ts shows "run terraform plan" hint', () => {
363
+ const code = src('src/ui/ink/index.ts');
364
+ expect(code).toContain('run terraform plan');
365
+ });
366
+
367
+ it('ink/index.ts shows helm releases hint', () => {
368
+ const code = src('src/ui/ink/index.ts');
369
+ expect(code).toContain('helm releases');
370
+ });
371
+
372
+ it('ink/index.ts hints are conditional on no nimbusInstructions', () => {
373
+ const code = src('src/ui/ink/index.ts');
374
+ expect(code).toContain('!nimbusInstructions');
375
+ });
376
+ });
377
+
378
+ // ---------------------------------------------------------------------------
379
+ // M2 — Timeout error with label and seconds
380
+ // ---------------------------------------------------------------------------
381
+
382
+ describe('M2 — improved timeout error message', () => {
383
+ it('spawn-exec.ts has label option in SpawnOptions', () => {
384
+ const code = src('src/tools/spawn-exec.ts');
385
+ expect(code).toContain('label?:');
386
+ });
387
+
388
+ it('spawn-exec.ts timeout error shows seconds not ms', () => {
389
+ const code = src('src/tools/spawn-exec.ts');
390
+ expect(code).toContain('timed out after');
391
+ expect(code).toContain('s.');
392
+ // Should use Math.round to convert ms to seconds
393
+ expect(code).toContain('Math.round');
394
+ });
395
+ });