@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,579 @@
1
+ /**
2
+ * Kubernetes Operations — Embedded tool (stripped HTTP wrappers)
3
+ *
4
+ * Copied from services/k8s-tools-service/src/k8s/operations.ts
5
+ * Uses child_process instead of Bun.$ for portability in the embedded binary.
6
+ */
7
+ import { exec, spawn } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import { logger } from '../utils';
10
+ const execAsync = promisify(exec);
11
+ /**
12
+ * Kubernetes operations class wrapping kubectl CLI
13
+ */
14
+ export class KubernetesOperations {
15
+ kubectlPath;
16
+ kubeconfig;
17
+ context;
18
+ defaultNamespace;
19
+ constructor(config = {}) {
20
+ this.kubectlPath = 'kubectl';
21
+ this.kubeconfig = config.kubeconfig;
22
+ this.context = config.context;
23
+ this.defaultNamespace = config.namespace || 'default';
24
+ }
25
+ /**
26
+ * Build base kubectl command with common flags
27
+ */
28
+ buildBaseArgs() {
29
+ const args = [];
30
+ if (this.kubeconfig) {
31
+ args.push('--kubeconfig', this.kubeconfig);
32
+ }
33
+ if (this.context) {
34
+ args.push('--context', this.context);
35
+ }
36
+ return args;
37
+ }
38
+ /**
39
+ * Execute kubectl command
40
+ */
41
+ async execute(args) {
42
+ const baseArgs = this.buildBaseArgs();
43
+ const fullArgs = [...baseArgs, ...args];
44
+ const command = `${this.kubectlPath} ${fullArgs.join(' ')}`;
45
+ logger.debug(`Executing kubectl command: ${command}`);
46
+ try {
47
+ const result = await execAsync(command, {
48
+ maxBuffer: 10 * 1024 * 1024,
49
+ timeout: 120000,
50
+ });
51
+ return {
52
+ success: true,
53
+ output: result.stdout.trim(),
54
+ exitCode: 0,
55
+ };
56
+ }
57
+ catch (error) {
58
+ const exitCode = error.code ?? 1;
59
+ const stderr = error.stderr?.trim() || error.message;
60
+ const stdout = error.stdout?.trim() || '';
61
+ logger.error(`kubectl command failed: ${command}`, { exitCode, stderr });
62
+ return {
63
+ success: false,
64
+ output: stdout,
65
+ error: stderr,
66
+ exitCode,
67
+ };
68
+ }
69
+ }
70
+ /**
71
+ * Get Kubernetes resources
72
+ */
73
+ async get(options) {
74
+ const args = ['get', options.resource];
75
+ if (options.name) {
76
+ args.push(options.name);
77
+ }
78
+ if (options.allNamespaces) {
79
+ args.push('--all-namespaces');
80
+ }
81
+ else if (options.namespace) {
82
+ args.push('-n', options.namespace);
83
+ }
84
+ else {
85
+ args.push('-n', this.defaultNamespace);
86
+ }
87
+ if (options.selector) {
88
+ args.push('-l', options.selector);
89
+ }
90
+ if (options.output) {
91
+ args.push('-o', options.output);
92
+ }
93
+ return this.execute(args);
94
+ }
95
+ /**
96
+ * Apply a manifest to the cluster
97
+ */
98
+ async apply(options) {
99
+ const args = ['apply', '-f', '-'];
100
+ if (options.namespace) {
101
+ args.push('-n', options.namespace);
102
+ }
103
+ if (options.dryRun) {
104
+ args.push('--dry-run=client');
105
+ }
106
+ if (options.force) {
107
+ args.push('--force');
108
+ }
109
+ if (options.serverSide) {
110
+ args.push('--server-side');
111
+ }
112
+ const baseArgs = this.buildBaseArgs();
113
+ const fullArgs = [...baseArgs, ...args];
114
+ logger.debug(`Applying manifest with kubectl`);
115
+ try {
116
+ const result = await execAsync(`echo '${options.manifest.replace(/'/g, "'\\''")}' | ${this.kubectlPath} ${fullArgs.join(' ')}`, { maxBuffer: 10 * 1024 * 1024, timeout: 120000 });
117
+ return {
118
+ success: true,
119
+ output: result.stdout.trim(),
120
+ exitCode: 0,
121
+ };
122
+ }
123
+ catch (error) {
124
+ const exitCode = error.code ?? 1;
125
+ const stderr = error.stderr?.trim() || error.message;
126
+ return {
127
+ success: false,
128
+ output: '',
129
+ error: stderr,
130
+ exitCode,
131
+ };
132
+ }
133
+ }
134
+ /**
135
+ * Delete Kubernetes resources
136
+ */
137
+ async delete(options) {
138
+ const args = ['delete', options.resource];
139
+ if (options.name) {
140
+ args.push(options.name);
141
+ }
142
+ if (options.namespace) {
143
+ args.push('-n', options.namespace);
144
+ }
145
+ else {
146
+ args.push('-n', this.defaultNamespace);
147
+ }
148
+ if (options.selector) {
149
+ args.push('-l', options.selector);
150
+ }
151
+ if (options.force) {
152
+ args.push('--force');
153
+ }
154
+ if (options.gracePeriod !== undefined) {
155
+ args.push('--grace-period', options.gracePeriod.toString());
156
+ }
157
+ return this.execute(args);
158
+ }
159
+ /**
160
+ * Get logs from a pod
161
+ */
162
+ async logs(options) {
163
+ const args = ['logs', options.pod];
164
+ if (options.namespace) {
165
+ args.push('-n', options.namespace);
166
+ }
167
+ else {
168
+ args.push('-n', this.defaultNamespace);
169
+ }
170
+ if (options.container) {
171
+ args.push('-c', options.container);
172
+ }
173
+ if (options.follow) {
174
+ args.push('-f');
175
+ }
176
+ if (options.tail !== undefined) {
177
+ args.push('--tail', options.tail.toString());
178
+ }
179
+ if (options.previous) {
180
+ args.push('--previous');
181
+ }
182
+ if (options.since) {
183
+ args.push('--since', options.since);
184
+ }
185
+ if (options.timestamps) {
186
+ args.push('--timestamps');
187
+ }
188
+ return this.execute(args);
189
+ }
190
+ /**
191
+ * Execute command in a pod
192
+ */
193
+ async exec(options) {
194
+ const args = ['exec', options.pod];
195
+ if (options.namespace) {
196
+ args.push('-n', options.namespace);
197
+ }
198
+ else {
199
+ args.push('-n', this.defaultNamespace);
200
+ }
201
+ if (options.container) {
202
+ args.push('-c', options.container);
203
+ }
204
+ if (options.stdin) {
205
+ args.push('-i');
206
+ }
207
+ if (options.tty) {
208
+ args.push('-t');
209
+ }
210
+ args.push('--');
211
+ args.push(...options.command);
212
+ return this.execute(args);
213
+ }
214
+ /**
215
+ * Describe Kubernetes resources
216
+ */
217
+ async describe(options) {
218
+ const args = ['describe', options.resource];
219
+ if (options.name) {
220
+ args.push(options.name);
221
+ }
222
+ if (options.allNamespaces) {
223
+ args.push('--all-namespaces');
224
+ }
225
+ else if (options.namespace) {
226
+ args.push('-n', options.namespace);
227
+ }
228
+ else {
229
+ args.push('-n', this.defaultNamespace);
230
+ }
231
+ if (options.selector) {
232
+ args.push('-l', options.selector);
233
+ }
234
+ return this.execute(args);
235
+ }
236
+ /**
237
+ * Scale a deployment, replicaset, or statefulset
238
+ */
239
+ async scale(options) {
240
+ const args = [
241
+ 'scale',
242
+ `${options.resource}/${options.name}`,
243
+ '--replicas',
244
+ options.replicas.toString(),
245
+ ];
246
+ if (options.namespace) {
247
+ args.push('-n', options.namespace);
248
+ }
249
+ else {
250
+ args.push('-n', this.defaultNamespace);
251
+ }
252
+ return this.execute(args);
253
+ }
254
+ /**
255
+ * Manage rollouts
256
+ */
257
+ async rollout(options) {
258
+ const args = ['rollout', options.action, `${options.resource}/${options.name}`];
259
+ if (options.namespace) {
260
+ args.push('-n', options.namespace);
261
+ }
262
+ else {
263
+ args.push('-n', this.defaultNamespace);
264
+ }
265
+ if (options.action === 'undo' && options.revision !== undefined) {
266
+ args.push('--to-revision', options.revision.toString());
267
+ }
268
+ return this.execute(args);
269
+ }
270
+ /**
271
+ * Get cluster information
272
+ */
273
+ async clusterInfo() {
274
+ return this.execute(['cluster-info']);
275
+ }
276
+ /**
277
+ * Get current context
278
+ */
279
+ async currentContext() {
280
+ return this.execute(['config', 'current-context']);
281
+ }
282
+ /**
283
+ * Get list of contexts
284
+ */
285
+ async getContexts() {
286
+ return this.execute(['config', 'get-contexts', '-o', 'name']);
287
+ }
288
+ /**
289
+ * Set current context
290
+ */
291
+ async useContext(context) {
292
+ return this.execute(['config', 'use-context', context]);
293
+ }
294
+ /**
295
+ * Get namespaces
296
+ */
297
+ async getNamespaces() {
298
+ return this.execute(['get', 'namespaces', '-o', 'json']);
299
+ }
300
+ /**
301
+ * Create namespace
302
+ */
303
+ async createNamespace(name) {
304
+ return this.execute(['create', 'namespace', name]);
305
+ }
306
+ /**
307
+ * Delete namespace
308
+ */
309
+ async deleteNamespace(name) {
310
+ return this.execute(['delete', 'namespace', name]);
311
+ }
312
+ /**
313
+ * Get events in a namespace
314
+ */
315
+ async getEvents(namespace, fieldSelector) {
316
+ const args = ['get', 'events', '-o', 'json'];
317
+ if (namespace) {
318
+ args.push('-n', namespace);
319
+ }
320
+ else {
321
+ args.push('-n', this.defaultNamespace);
322
+ }
323
+ if (fieldSelector) {
324
+ args.push('--field-selector', fieldSelector);
325
+ }
326
+ return this.execute(args);
327
+ }
328
+ /**
329
+ * Top pods - show resource usage
330
+ */
331
+ async topPods(namespace, selector) {
332
+ const args = ['top', 'pods'];
333
+ if (namespace) {
334
+ args.push('-n', namespace);
335
+ }
336
+ else {
337
+ args.push('-n', this.defaultNamespace);
338
+ }
339
+ if (selector) {
340
+ args.push('-l', selector);
341
+ }
342
+ return this.execute(args);
343
+ }
344
+ /**
345
+ * Top nodes - show node resource usage
346
+ */
347
+ async topNodes() {
348
+ return this.execute(['top', 'nodes']);
349
+ }
350
+ /**
351
+ * Get API resources
352
+ */
353
+ async apiResources() {
354
+ return this.execute(['api-resources', '-o', 'wide']);
355
+ }
356
+ /**
357
+ * Get version information
358
+ */
359
+ async version() {
360
+ return this.execute(['version', '-o', 'json']);
361
+ }
362
+ /**
363
+ * Port forward to a pod or service
364
+ * Note: This starts a background process and returns immediately
365
+ */
366
+ async portForward(options) {
367
+ const args = ['port-forward'];
368
+ // Resource type and name
369
+ const resourceSpec = `${options.resource}/${options.name}`;
370
+ args.push(resourceSpec);
371
+ // Add ports
372
+ for (const port of options.ports) {
373
+ args.push(port);
374
+ }
375
+ // Namespace
376
+ if (options.namespace) {
377
+ args.push('-n', options.namespace);
378
+ }
379
+ else {
380
+ args.push('-n', this.defaultNamespace);
381
+ }
382
+ // Address to listen on
383
+ if (options.address) {
384
+ args.push('--address', options.address);
385
+ }
386
+ const baseArgs = this.buildBaseArgs();
387
+ const fullArgs = [...baseArgs, ...args];
388
+ logger.info(`Starting port-forward: ${this.kubectlPath} ${fullArgs.join(' ')}`);
389
+ // Spawn the port-forward as a background process
390
+ const proc = spawn(this.kubectlPath, fullArgs, {
391
+ stdio: ['ignore', 'pipe', 'pipe'],
392
+ });
393
+ // Wait briefly for the "Forwarding from..." confirmation or an error
394
+ const result = await new Promise(resolve => {
395
+ let stderr = '';
396
+ const timeout = setTimeout(() => {
397
+ // If no output after 5s, assume it started
398
+ proc.unref();
399
+ resolve({
400
+ success: true,
401
+ resource: resourceSpec,
402
+ ports: options.ports,
403
+ namespace: options.namespace || this.defaultNamespace,
404
+ address: options.address || '127.0.0.1',
405
+ message: `Port-forward started for ${resourceSpec}`,
406
+ pid: proc.pid,
407
+ });
408
+ }, 5000);
409
+ proc.stdout?.on('data', (data) => {
410
+ const output = data.toString();
411
+ if (output.includes('Forwarding from')) {
412
+ clearTimeout(timeout);
413
+ proc.unref();
414
+ resolve({
415
+ success: true,
416
+ resource: resourceSpec,
417
+ ports: options.ports,
418
+ namespace: options.namespace || this.defaultNamespace,
419
+ address: options.address || '127.0.0.1',
420
+ message: output.trim(),
421
+ pid: proc.pid,
422
+ });
423
+ }
424
+ });
425
+ proc.stderr?.on('data', (data) => {
426
+ stderr += data.toString();
427
+ });
428
+ proc.on('error', err => {
429
+ clearTimeout(timeout);
430
+ resolve({
431
+ success: false,
432
+ resource: resourceSpec,
433
+ ports: options.ports,
434
+ namespace: options.namespace || this.defaultNamespace,
435
+ address: options.address || '127.0.0.1',
436
+ message: `Port-forward failed: ${err.message}`,
437
+ });
438
+ });
439
+ proc.on('close', code => {
440
+ if (code !== 0) {
441
+ clearTimeout(timeout);
442
+ resolve({
443
+ success: false,
444
+ resource: resourceSpec,
445
+ ports: options.ports,
446
+ namespace: options.namespace || this.defaultNamespace,
447
+ address: options.address || '127.0.0.1',
448
+ message: stderr.trim() || `Port-forward exited with code ${code}`,
449
+ });
450
+ }
451
+ });
452
+ });
453
+ return result;
454
+ }
455
+ /**
456
+ * Copy files to/from a pod
457
+ */
458
+ async cp(options) {
459
+ const args = ['cp'];
460
+ if (options.namespace) {
461
+ args.push('-n', options.namespace);
462
+ }
463
+ else {
464
+ args.push('-n', this.defaultNamespace);
465
+ }
466
+ if (options.container) {
467
+ args.push('-c', options.container);
468
+ }
469
+ // Source and destination
470
+ args.push(options.source, options.destination);
471
+ return this.execute(args);
472
+ }
473
+ /**
474
+ * Label a resource
475
+ */
476
+ async label(options) {
477
+ const args = ['label', `${options.resource}/${options.name}`];
478
+ if (options.namespace) {
479
+ args.push('-n', options.namespace);
480
+ }
481
+ else {
482
+ args.push('-n', this.defaultNamespace);
483
+ }
484
+ // Add labels
485
+ for (const [key, value] of Object.entries(options.labels)) {
486
+ if (value === null) {
487
+ args.push(`${key}-`); // Remove label
488
+ }
489
+ else {
490
+ args.push(`${key}=${value}`);
491
+ }
492
+ }
493
+ if (options.overwrite) {
494
+ args.push('--overwrite');
495
+ }
496
+ return this.execute(args);
497
+ }
498
+ /**
499
+ * Annotate a resource
500
+ */
501
+ async annotate(options) {
502
+ const args = ['annotate', `${options.resource}/${options.name}`];
503
+ if (options.namespace) {
504
+ args.push('-n', options.namespace);
505
+ }
506
+ else {
507
+ args.push('-n', this.defaultNamespace);
508
+ }
509
+ // Add annotations
510
+ for (const [key, value] of Object.entries(options.annotations)) {
511
+ if (value === null) {
512
+ args.push(`${key}-`); // Remove annotation
513
+ }
514
+ else {
515
+ args.push(`${key}=${value}`);
516
+ }
517
+ }
518
+ if (options.overwrite) {
519
+ args.push('--overwrite');
520
+ }
521
+ return this.execute(args);
522
+ }
523
+ /**
524
+ * Patch a resource
525
+ */
526
+ async patch(options) {
527
+ const args = ['patch', options.resource, options.name];
528
+ if (options.namespace) {
529
+ args.push('-n', options.namespace);
530
+ }
531
+ else {
532
+ args.push('-n', this.defaultNamespace);
533
+ }
534
+ args.push('--type', options.type || 'strategic');
535
+ args.push('-p', JSON.stringify(options.patch));
536
+ return this.execute(args);
537
+ }
538
+ /**
539
+ * Cordon a node (mark as unschedulable)
540
+ */
541
+ async cordon(nodeName) {
542
+ return this.execute(['cordon', nodeName]);
543
+ }
544
+ /**
545
+ * Uncordon a node (mark as schedulable)
546
+ */
547
+ async uncordon(nodeName) {
548
+ return this.execute(['uncordon', nodeName]);
549
+ }
550
+ /**
551
+ * Drain a node
552
+ */
553
+ async drain(nodeName, options) {
554
+ const args = ['drain', nodeName];
555
+ if (options?.force) {
556
+ args.push('--force');
557
+ }
558
+ if (options?.ignoreDaemonsets) {
559
+ args.push('--ignore-daemonsets');
560
+ }
561
+ if (options?.deleteEmptyDirData) {
562
+ args.push('--delete-emptydir-data');
563
+ }
564
+ if (options?.gracePeriod !== undefined) {
565
+ args.push('--grace-period', options.gracePeriod.toString());
566
+ }
567
+ if (options?.timeout) {
568
+ args.push('--timeout', options.timeout);
569
+ }
570
+ return this.execute(args);
571
+ }
572
+ /**
573
+ * Taint a node
574
+ */
575
+ async taint(nodeName, taints) {
576
+ const args = ['taint', 'nodes', nodeName, ...taints];
577
+ return this.execute(args);
578
+ }
579
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Batch Conversion Utilities for Provider-Specific Tool Formats
3
+ *
4
+ * This module re-exports the individual converter functions from
5
+ * {@link module:tools/schemas/types} and adds convenience functions for
6
+ * converting arrays of {@link ToolDefinition}s to each supported LLM
7
+ * provider's expected tool format in a single call.
8
+ *
9
+ * The {@link toProviderFormat} function additionally accepts a
10
+ * {@link Provider} discriminator so callers can defer the choice of
11
+ * target format to runtime configuration.
12
+ *
13
+ * @module tools/schemas/converter
14
+ */
15
+ import { toAnthropicTool, toOpenAITool, toGoogleTool, zodToJsonSchema, } from './types';
16
+ // ---------------------------------------------------------------------------
17
+ // Re-exports -- individual converters and provider-specific types
18
+ // ---------------------------------------------------------------------------
19
+ export { toAnthropicTool, toOpenAITool, toGoogleTool, zodToJsonSchema };
20
+ // ---------------------------------------------------------------------------
21
+ // Batch Conversion Functions
22
+ // ---------------------------------------------------------------------------
23
+ /**
24
+ * Convert an array of tool definitions to Anthropic Messages API format.
25
+ *
26
+ * Each {@link ToolDefinition} is individually converted via
27
+ * {@link toAnthropicTool} and the results are returned as an array.
28
+ *
29
+ * @param tools - The tool definitions to convert.
30
+ * @returns An array of {@link AnthropicTool} objects ready for the API.
31
+ */
32
+ export function toAnthropicFormat(tools) {
33
+ return tools.map(toAnthropicTool);
34
+ }
35
+ /**
36
+ * Convert an array of tool definitions to OpenAI function-calling format.
37
+ *
38
+ * Each {@link ToolDefinition} is individually converted via
39
+ * {@link toOpenAITool} and the results are returned as an array.
40
+ *
41
+ * @param tools - The tool definitions to convert.
42
+ * @returns An array of {@link OpenAITool} objects ready for the API.
43
+ */
44
+ export function toOpenAIFormat(tools) {
45
+ return tools.map(toOpenAITool);
46
+ }
47
+ /**
48
+ * Convert an array of tool definitions to Google Generative AI format.
49
+ *
50
+ * Unlike Anthropic and OpenAI, Google expects all function declarations
51
+ * to be bundled inside a single tool object with a `functionDeclarations`
52
+ * array. This function delegates to {@link toGoogleTool} which handles
53
+ * that bundling.
54
+ *
55
+ * @param tools - The tool definitions to convert.
56
+ * @returns A single {@link GoogleTool} containing all declarations.
57
+ */
58
+ export function toGoogleFormat(tools) {
59
+ return toGoogleTool(tools);
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Provider-Aware Conversion
63
+ // ---------------------------------------------------------------------------
64
+ /**
65
+ * Convert an array of tool definitions to the wire format expected by a
66
+ * specific LLM provider.
67
+ *
68
+ * This is the primary entry point for code that determines the target
69
+ * provider at runtime (e.g. from user configuration). The mapping is:
70
+ *
71
+ * - `'anthropic'` and `'bedrock'` produce {@link AnthropicTool}[] (Bedrock
72
+ * uses Anthropic format for Claude models).
73
+ * - `'openai'`, `'ollama'`, `'openrouter'`, and `'openai-compatible'`
74
+ * produce {@link OpenAITool}[].
75
+ * - `'google'` produces a single {@link GoogleTool} object.
76
+ *
77
+ * If an unrecognized provider string is passed (possible when new
78
+ * providers are added before this function is updated), the function
79
+ * falls back to OpenAI format as it is the most widely supported.
80
+ *
81
+ * @param tools - The tool definitions to convert.
82
+ * @param provider - The target LLM provider identifier.
83
+ * @returns The converted tools in the provider-specific format.
84
+ */
85
+ export function toProviderFormat(tools, provider) {
86
+ switch (provider) {
87
+ case 'anthropic':
88
+ return toAnthropicFormat(tools);
89
+ case 'openai':
90
+ case 'ollama':
91
+ case 'openrouter':
92
+ case 'openai-compatible':
93
+ return toOpenAIFormat(tools);
94
+ case 'google':
95
+ return toGoogleFormat(tools);
96
+ case 'bedrock':
97
+ // Bedrock uses Anthropic format for Claude models
98
+ return toAnthropicFormat(tools);
99
+ default: {
100
+ // Exhaustive check: if a new Provider variant is added but not
101
+ // handled above, TypeScript will flag this assignment as an error.
102
+ const _exhaustive = provider;
103
+ void _exhaustive;
104
+ // Default to OpenAI format (most widely supported)
105
+ return toOpenAIFormat(tools);
106
+ }
107
+ }
108
+ }
109
+ // ---------------------------------------------------------------------------
110
+ // Utility Helpers
111
+ // ---------------------------------------------------------------------------
112
+ /**
113
+ * Extract the names of all tool definitions in the given array.
114
+ *
115
+ * Useful for logging, permission checks, or building tool-name allow/deny
116
+ * lists without pulling in the full definition objects.
117
+ *
118
+ * @param tools - The tool definitions to extract names from.
119
+ * @returns An array of tool name strings, preserving input order.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const names = getToolNames(registry.getAll());
124
+ * // ['read_file', 'write_file', 'terraform_apply']
125
+ * ```
126
+ */
127
+ export function getToolNames(tools) {
128
+ return tools.map(t => t.name);
129
+ }