@codemieai/code 0.0.15 → 0.0.16

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 (296) hide show
  1. package/README.md +24 -9
  2. package/dist/agents/codemie-code/agent.js +2 -2
  3. package/dist/agents/codemie-code/agent.js.map +1 -1
  4. package/dist/agents/codemie-code/config.d.ts.map +1 -1
  5. package/dist/agents/codemie-code/config.js +12 -4
  6. package/dist/agents/codemie-code/config.js.map +1 -1
  7. package/dist/agents/codemie-code/tools/planning.d.ts +1 -1
  8. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  9. package/dist/agents/core/AgentCLI.js +5 -4
  10. package/dist/agents/core/AgentCLI.js.map +1 -1
  11. package/dist/agents/core/BaseAgentAdapter.d.ts +1 -5
  12. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  13. package/dist/agents/core/BaseAgentAdapter.js +5 -26
  14. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  15. package/dist/agents/plugins/claude.plugin.js +1 -1
  16. package/dist/agents/plugins/claude.plugin.js.map +1 -1
  17. package/dist/agents/plugins/codemie-code.plugin.js +1 -1
  18. package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
  19. package/dist/agents/plugins/codex.plugin.js +2 -2
  20. package/dist/agents/plugins/codex.plugin.js.map +1 -1
  21. package/dist/agents/plugins/deepagents.plugin.js +1 -1
  22. package/dist/agents/plugins/deepagents.plugin.js.map +1 -1
  23. package/dist/agents/plugins/gemini.plugin.js +1 -1
  24. package/dist/agents/plugins/gemini.plugin.js.map +1 -1
  25. package/dist/analytics/index.d.ts.map +1 -1
  26. package/dist/analytics/index.js +3 -11
  27. package/dist/analytics/index.js.map +1 -1
  28. package/dist/analytics/remote-submission/cursor-manager.d.ts +1 -1
  29. package/dist/analytics/remote-submission/cursor-manager.js +2 -2
  30. package/dist/analytics/remote-submission/cursor-manager.js.map +1 -1
  31. package/dist/analytics/remote-submission/index.d.ts +2 -2
  32. package/dist/analytics/remote-submission/index.d.ts.map +1 -1
  33. package/dist/analytics/remote-submission/index.js +1 -1
  34. package/dist/analytics/remote-submission/index.js.map +1 -1
  35. package/dist/analytics/remote-submission/lock-manager.d.ts +1 -1
  36. package/dist/analytics/remote-submission/lock-manager.js +2 -2
  37. package/dist/analytics/remote-submission/lock-manager.js.map +1 -1
  38. package/dist/analytics/remote-submission/metric-transformer.d.ts +2 -30
  39. package/dist/analytics/remote-submission/metric-transformer.d.ts.map +1 -1
  40. package/dist/analytics/remote-submission/metric-transformer.js +24 -117
  41. package/dist/analytics/remote-submission/metric-transformer.js.map +1 -1
  42. package/dist/analytics/remote-submission/submitter.d.ts +1 -0
  43. package/dist/analytics/remote-submission/submitter.d.ts.map +1 -1
  44. package/dist/analytics/remote-submission/submitter.js +18 -37
  45. package/dist/analytics/remote-submission/submitter.js.map +1 -1
  46. package/dist/analytics/remote-submission/types.d.ts +5 -51
  47. package/dist/analytics/remote-submission/types.d.ts.map +1 -1
  48. package/dist/analytics/remote-submission/types.js.map +1 -1
  49. package/dist/cli/commands/auth.d.ts.map +1 -1
  50. package/dist/cli/commands/auth.js +10 -5
  51. package/dist/cli/commands/auth.js.map +1 -1
  52. package/dist/cli/commands/doctor/checks/AIConfigCheck.d.ts.map +1 -1
  53. package/dist/cli/commands/doctor/checks/AIConfigCheck.js +12 -5
  54. package/dist/cli/commands/doctor/checks/AIConfigCheck.js.map +1 -1
  55. package/dist/cli/commands/doctor/formatter.d.ts +1 -1
  56. package/dist/cli/commands/doctor/formatter.d.ts.map +1 -1
  57. package/dist/cli/commands/doctor/formatter.js +1 -6
  58. package/dist/cli/commands/doctor/formatter.js.map +1 -1
  59. package/dist/cli/commands/doctor/index.d.ts.map +1 -1
  60. package/dist/cli/commands/doctor/index.js +23 -8
  61. package/dist/cli/commands/doctor/index.js.map +1 -1
  62. package/dist/cli/commands/doctor/type-adapters.d.ts +18 -0
  63. package/dist/cli/commands/doctor/type-adapters.d.ts.map +1 -0
  64. package/dist/cli/commands/doctor/type-adapters.js +75 -0
  65. package/dist/cli/commands/doctor/type-adapters.js.map +1 -0
  66. package/dist/cli/commands/install.d.ts.map +1 -1
  67. package/dist/cli/commands/install.js +1 -6
  68. package/dist/cli/commands/install.js.map +1 -1
  69. package/dist/cli/commands/list.d.ts.map +1 -1
  70. package/dist/cli/commands/list.js +0 -5
  71. package/dist/cli/commands/list.js.map +1 -1
  72. package/dist/cli/commands/profile.js +90 -12
  73. package/dist/cli/commands/profile.js.map +1 -1
  74. package/dist/cli/commands/setup.d.ts.map +1 -1
  75. package/dist/cli/commands/setup.js +159 -660
  76. package/dist/cli/commands/setup.js.map +1 -1
  77. package/dist/cli/index.d.ts +1 -1
  78. package/dist/cli/index.d.ts.map +1 -1
  79. package/dist/cli/index.js +4 -1
  80. package/dist/cli/index.js.map +1 -1
  81. package/dist/providers/core/base/BaseHealthCheck.d.ts +57 -0
  82. package/dist/providers/core/base/BaseHealthCheck.d.ts.map +1 -0
  83. package/dist/providers/core/base/BaseHealthCheck.js +121 -0
  84. package/dist/providers/core/base/BaseHealthCheck.js.map +1 -0
  85. package/dist/providers/core/base/BaseModelProxy.d.ts +45 -0
  86. package/dist/providers/core/base/BaseModelProxy.d.ts.map +1 -0
  87. package/dist/providers/core/base/BaseModelProxy.js +43 -0
  88. package/dist/providers/core/base/BaseModelProxy.js.map +1 -0
  89. package/dist/providers/core/base/http-client.d.ts +57 -0
  90. package/dist/providers/core/base/http-client.d.ts.map +1 -0
  91. package/dist/providers/core/base/http-client.js +240 -0
  92. package/dist/providers/core/base/http-client.js.map +1 -0
  93. package/dist/providers/core/decorators.d.ts +13 -0
  94. package/dist/providers/core/decorators.d.ts.map +1 -0
  95. package/dist/providers/core/decorators.js +15 -0
  96. package/dist/providers/core/decorators.js.map +1 -0
  97. package/dist/providers/core/index.d.ts +13 -0
  98. package/dist/providers/core/index.d.ts.map +1 -0
  99. package/dist/providers/core/index.js +14 -0
  100. package/dist/providers/core/index.js.map +1 -0
  101. package/dist/providers/core/registry.d.ts +66 -0
  102. package/dist/providers/core/registry.d.ts.map +1 -0
  103. package/dist/providers/core/registry.js +105 -0
  104. package/dist/providers/core/registry.js.map +1 -0
  105. package/dist/providers/core/types.d.ts +285 -0
  106. package/dist/providers/core/types.d.ts.map +1 -0
  107. package/dist/providers/core/types.js +7 -0
  108. package/dist/providers/core/types.js.map +1 -0
  109. package/dist/providers/index.d.ts +20 -0
  110. package/dist/providers/index.d.ts.map +1 -0
  111. package/dist/providers/index.js +22 -0
  112. package/dist/providers/index.js.map +1 -0
  113. package/dist/providers/integration/setup-ui.d.ts +76 -0
  114. package/dist/providers/integration/setup-ui.d.ts.map +1 -0
  115. package/dist/providers/integration/setup-ui.js +141 -0
  116. package/dist/providers/integration/setup-ui.js.map +1 -0
  117. package/dist/providers/plugins/litellm/index.d.ts +8 -0
  118. package/dist/providers/plugins/litellm/index.d.ts.map +1 -0
  119. package/dist/providers/plugins/litellm/index.js +12 -0
  120. package/dist/providers/plugins/litellm/index.js.map +1 -0
  121. package/dist/providers/plugins/litellm/litellm.models.d.ts +27 -0
  122. package/dist/providers/plugins/litellm/litellm.models.d.ts.map +1 -0
  123. package/dist/providers/plugins/litellm/litellm.models.js +48 -0
  124. package/dist/providers/plugins/litellm/litellm.models.js.map +1 -0
  125. package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts +8 -0
  126. package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts.map +1 -0
  127. package/dist/providers/plugins/litellm/litellm.setup-steps.js +52 -0
  128. package/dist/providers/plugins/litellm/litellm.setup-steps.js.map +1 -0
  129. package/dist/providers/plugins/litellm/litellm.template.d.ts +11 -0
  130. package/dist/providers/plugins/litellm/litellm.template.d.ts.map +1 -0
  131. package/dist/providers/plugins/litellm/litellm.template.js +59 -0
  132. package/dist/providers/plugins/litellm/litellm.template.js.map +1 -0
  133. package/dist/providers/plugins/ollama/index.d.ts +11 -0
  134. package/dist/providers/plugins/ollama/index.d.ts.map +1 -0
  135. package/dist/providers/plugins/ollama/index.js +11 -0
  136. package/dist/providers/plugins/ollama/index.js.map +1 -0
  137. package/dist/providers/plugins/ollama/ollama.health.d.ts +48 -0
  138. package/dist/providers/plugins/ollama/ollama.health.d.ts.map +1 -0
  139. package/dist/providers/plugins/ollama/ollama.health.js +87 -0
  140. package/dist/providers/plugins/ollama/ollama.health.js.map +1 -0
  141. package/dist/providers/plugins/ollama/ollama.models.d.ts +47 -0
  142. package/dist/providers/plugins/ollama/ollama.models.d.ts.map +1 -0
  143. package/dist/providers/plugins/ollama/ollama.models.js +252 -0
  144. package/dist/providers/plugins/ollama/ollama.models.js.map +1 -0
  145. package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts +16 -0
  146. package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -0
  147. package/dist/providers/plugins/ollama/ollama.setup-steps.js +164 -0
  148. package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -0
  149. package/dist/providers/plugins/ollama/ollama.template.d.ts +11 -0
  150. package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -0
  151. package/dist/providers/plugins/ollama/ollama.template.js +87 -0
  152. package/dist/providers/plugins/ollama/ollama.template.js.map +1 -0
  153. package/dist/providers/plugins/sso/index.d.ts +12 -0
  154. package/dist/providers/plugins/sso/index.d.ts.map +1 -0
  155. package/dist/providers/plugins/sso/index.js +12 -0
  156. package/dist/providers/plugins/sso/index.js.map +1 -0
  157. package/dist/providers/plugins/sso/sso.auth.d.ts +50 -0
  158. package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -0
  159. package/dist/{utils/sso-auth.js → providers/plugins/sso/sso.auth.js} +37 -2
  160. package/dist/providers/plugins/sso/sso.auth.js.map +1 -0
  161. package/dist/providers/plugins/sso/sso.health.d.ts +44 -0
  162. package/dist/providers/plugins/sso/sso.health.d.ts.map +1 -0
  163. package/dist/providers/plugins/sso/sso.health.js +178 -0
  164. package/dist/providers/plugins/sso/sso.health.js.map +1 -0
  165. package/dist/{utils/codemie-model-fetcher.d.ts → providers/plugins/sso/sso.http-client.d.ts} +16 -5
  166. package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -0
  167. package/dist/providers/plugins/sso/sso.http-client.js +187 -0
  168. package/dist/providers/plugins/sso/sso.http-client.js.map +1 -0
  169. package/dist/providers/plugins/sso/sso.models.d.ts +48 -0
  170. package/dist/providers/plugins/sso/sso.models.d.ts.map +1 -0
  171. package/dist/providers/plugins/sso/sso.models.js +139 -0
  172. package/dist/providers/plugins/sso/sso.models.js.map +1 -0
  173. package/dist/providers/plugins/sso/sso.setup-steps.d.ts +16 -0
  174. package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -0
  175. package/dist/providers/plugins/sso/sso.setup-steps.js +145 -0
  176. package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -0
  177. package/dist/providers/plugins/sso/sso.template.d.ts +11 -0
  178. package/dist/providers/plugins/sso/sso.template.d.ts.map +1 -0
  179. package/dist/providers/plugins/sso/sso.template.js +35 -0
  180. package/dist/providers/plugins/sso/sso.template.js.map +1 -0
  181. package/dist/proxy/errors.d.ts.map +1 -0
  182. package/dist/proxy/errors.js.map +1 -0
  183. package/dist/proxy/http-client.d.ts.map +1 -0
  184. package/dist/{utils/proxy → proxy}/http-client.js +1 -1
  185. package/dist/proxy/http-client.js.map +1 -0
  186. package/dist/proxy/plugins/header-injection.plugin.d.ts.map +1 -0
  187. package/dist/{utils/proxy → proxy}/plugins/header-injection.plugin.js +7 -3
  188. package/dist/proxy/plugins/header-injection.plugin.js.map +1 -0
  189. package/dist/{utils/proxy → proxy}/plugins/index.d.ts +2 -2
  190. package/dist/proxy/plugins/index.d.ts.map +1 -0
  191. package/dist/{utils/proxy → proxy}/plugins/index.js +3 -5
  192. package/dist/proxy/plugins/index.js.map +1 -0
  193. package/dist/proxy/plugins/logging.plugin.d.ts +22 -0
  194. package/dist/proxy/plugins/logging.plugin.d.ts.map +1 -0
  195. package/dist/proxy/plugins/logging.plugin.js +92 -0
  196. package/dist/proxy/plugins/logging.plugin.js.map +1 -0
  197. package/dist/proxy/plugins/registry.d.ts.map +1 -0
  198. package/dist/{utils/proxy → proxy}/plugins/registry.js +1 -1
  199. package/dist/proxy/plugins/registry.js.map +1 -0
  200. package/dist/proxy/plugins/sso-auth.plugin.d.ts.map +1 -0
  201. package/dist/{utils/proxy → proxy}/plugins/sso-auth.plugin.js +1 -1
  202. package/dist/proxy/plugins/sso-auth.plugin.js.map +1 -0
  203. package/dist/{utils/proxy → proxy}/plugins/types.d.ts +3 -3
  204. package/dist/proxy/plugins/types.d.ts.map +1 -0
  205. package/dist/proxy/plugins/types.js.map +1 -0
  206. package/dist/proxy/types.d.ts.map +1 -0
  207. package/dist/proxy/types.js.map +1 -0
  208. package/dist/utils/codemie-proxy.d.ts +5 -4
  209. package/dist/utils/codemie-proxy.d.ts.map +1 -1
  210. package/dist/utils/codemie-proxy.js +31 -26
  211. package/dist/utils/codemie-proxy.js.map +1 -1
  212. package/dist/utils/config-loader.d.ts +1 -6
  213. package/dist/utils/config-loader.d.ts.map +1 -1
  214. package/dist/utils/config-loader.js +30 -90
  215. package/dist/utils/config-loader.js.map +1 -1
  216. package/dist/utils/credential-store.d.ts +1 -1
  217. package/dist/utils/credential-store.d.ts.map +1 -1
  218. package/dist/utils/logger.d.ts.map +1 -1
  219. package/dist/utils/logger.js +0 -2
  220. package/dist/utils/logger.js.map +1 -1
  221. package/package.json +1 -1
  222. package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.d.ts +0 -11
  223. package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.d.ts.map +0 -1
  224. package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.js +0 -264
  225. package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.js.map +0 -1
  226. package/dist/cli/commands/doctor/providers/BaseProviderCheck.d.ts +0 -12
  227. package/dist/cli/commands/doctor/providers/BaseProviderCheck.d.ts.map +0 -1
  228. package/dist/cli/commands/doctor/providers/BaseProviderCheck.js +0 -12
  229. package/dist/cli/commands/doctor/providers/BaseProviderCheck.js.map +0 -1
  230. package/dist/cli/commands/doctor/providers/StandardProviderCheck.d.ts +0 -11
  231. package/dist/cli/commands/doctor/providers/StandardProviderCheck.d.ts.map +0 -1
  232. package/dist/cli/commands/doctor/providers/StandardProviderCheck.js +0 -97
  233. package/dist/cli/commands/doctor/providers/StandardProviderCheck.js.map +0 -1
  234. package/dist/cli/commands/doctor/providers/index.d.ts +0 -30
  235. package/dist/cli/commands/doctor/providers/index.d.ts.map +0 -1
  236. package/dist/cli/commands/doctor/providers/index.js +0 -66
  237. package/dist/cli/commands/doctor/providers/index.js.map +0 -1
  238. package/dist/types/sso.d.ts +0 -42
  239. package/dist/types/sso.d.ts.map +0 -1
  240. package/dist/types/sso.js +0 -2
  241. package/dist/types/sso.js.map +0 -1
  242. package/dist/utils/async-tips.d.ts +0 -64
  243. package/dist/utils/async-tips.d.ts.map +0 -1
  244. package/dist/utils/async-tips.js +0 -203
  245. package/dist/utils/async-tips.js.map +0 -1
  246. package/dist/utils/codemie-integration-validator.d.ts +0 -18
  247. package/dist/utils/codemie-integration-validator.d.ts.map +0 -1
  248. package/dist/utils/codemie-integration-validator.js +0 -119
  249. package/dist/utils/codemie-integration-validator.js.map +0 -1
  250. package/dist/utils/codemie-model-fetcher.d.ts.map +0 -1
  251. package/dist/utils/codemie-model-fetcher.js +0 -317
  252. package/dist/utils/codemie-model-fetcher.js.map +0 -1
  253. package/dist/utils/health-checker.d.ts +0 -20
  254. package/dist/utils/health-checker.d.ts.map +0 -1
  255. package/dist/utils/health-checker.js +0 -172
  256. package/dist/utils/health-checker.js.map +0 -1
  257. package/dist/utils/model-fetcher.d.ts +0 -21
  258. package/dist/utils/model-fetcher.d.ts.map +0 -1
  259. package/dist/utils/model-fetcher.js +0 -148
  260. package/dist/utils/model-fetcher.js.map +0 -1
  261. package/dist/utils/proxy/errors.d.ts.map +0 -1
  262. package/dist/utils/proxy/errors.js.map +0 -1
  263. package/dist/utils/proxy/http-client.d.ts.map +0 -1
  264. package/dist/utils/proxy/http-client.js.map +0 -1
  265. package/dist/utils/proxy/plugins/analytics.plugin.d.ts +0 -19
  266. package/dist/utils/proxy/plugins/analytics.plugin.d.ts.map +0 -1
  267. package/dist/utils/proxy/plugins/analytics.plugin.js +0 -84
  268. package/dist/utils/proxy/plugins/analytics.plugin.js.map +0 -1
  269. package/dist/utils/proxy/plugins/header-injection.plugin.d.ts.map +0 -1
  270. package/dist/utils/proxy/plugins/header-injection.plugin.js.map +0 -1
  271. package/dist/utils/proxy/plugins/index.d.ts.map +0 -1
  272. package/dist/utils/proxy/plugins/index.js.map +0 -1
  273. package/dist/utils/proxy/plugins/registry.d.ts.map +0 -1
  274. package/dist/utils/proxy/plugins/registry.js.map +0 -1
  275. package/dist/utils/proxy/plugins/sso-auth.plugin.d.ts.map +0 -1
  276. package/dist/utils/proxy/plugins/sso-auth.plugin.js.map +0 -1
  277. package/dist/utils/proxy/plugins/types.d.ts.map +0 -1
  278. package/dist/utils/proxy/plugins/types.js.map +0 -1
  279. package/dist/utils/proxy/types.d.ts.map +0 -1
  280. package/dist/utils/proxy/types.js.map +0 -1
  281. package/dist/utils/sso-auth.d.ts +0 -15
  282. package/dist/utils/sso-auth.d.ts.map +0 -1
  283. package/dist/utils/sso-auth.js.map +0 -1
  284. package/dist/utils/tips.d.ts +0 -35
  285. package/dist/utils/tips.d.ts.map +0 -1
  286. package/dist/utils/tips.js +0 -93
  287. package/dist/utils/tips.js.map +0 -1
  288. /package/dist/{utils/proxy → proxy}/errors.d.ts +0 -0
  289. /package/dist/{utils/proxy → proxy}/errors.js +0 -0
  290. /package/dist/{utils/proxy → proxy}/http-client.d.ts +0 -0
  291. /package/dist/{utils/proxy → proxy}/plugins/header-injection.plugin.d.ts +0 -0
  292. /package/dist/{utils/proxy → proxy}/plugins/registry.d.ts +0 -0
  293. /package/dist/{utils/proxy → proxy}/plugins/sso-auth.plugin.d.ts +0 -0
  294. /package/dist/{utils/proxy → proxy}/plugins/types.js +0 -0
  295. /package/dist/{utils/proxy → proxy}/types.d.ts +0 -0
  296. /package/dist/{utils/proxy → proxy}/types.js +0 -0
@@ -4,47 +4,8 @@ import chalk from 'chalk';
4
4
  import ora from 'ora';
5
5
  import { ConfigLoader } from '../../utils/config-loader.js';
6
6
  import { logger } from '../../utils/logger.js';
7
- import { checkProviderHealth } from '../../utils/health-checker.js';
8
- import { fetchAvailableModels } from '../../utils/model-fetcher.js';
9
- import { CodeMieSSO } from '../../utils/sso-auth.js';
10
- import { fetchCodeMieModels } from '../../utils/codemie-model-fetcher.js';
11
- import { validateCodeMieIntegrations } from '../../utils/codemie-integration-validator.js';
12
- const PROVIDERS = [
13
- {
14
- name: 'CodeMie SSO (Recommended - Enterprise Authentication)',
15
- value: 'ai-run-sso',
16
- baseUrl: '', // Will be resolved from CodeMie URL
17
- models: [] // Will be fetched from CodeMie /v1/llm_models endpoint
18
- },
19
- {
20
- name: 'Google Gemini (Direct API Access)',
21
- value: 'gemini',
22
- baseUrl: 'https://generativelanguage.googleapis.com',
23
- models: ['gemini-2.5-flash', 'gemini-2.5-pro', 'gemini-1.5-pro', 'gemini-1.5-flash']
24
- },
25
- {
26
- name: 'LiteLLM Proxy (OpenAI-compatible Gateway)',
27
- value: 'litellm',
28
- baseUrl: 'https://litellm.example.com',
29
- models: ['claude-4-5-sonnet', 'claude-opus-4', 'gpt-4.1', 'gpt-5']
30
- },
31
- {
32
- name: 'AWS Bedrock (Claude via AWS)',
33
- value: 'bedrock',
34
- baseUrl: '',
35
- models: [
36
- 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',
37
- 'us.anthropic.claude-opus-4-0-20250514-v1:0',
38
- 'anthropic.claude-3-5-sonnet-20241022-v2:0'
39
- ]
40
- },
41
- {
42
- name: 'Azure OpenAI (for GPT models and Codex)',
43
- value: 'azure',
44
- baseUrl: '',
45
- models: []
46
- }
47
- ];
7
+ import { ProviderRegistry } from '../../providers/index.js';
8
+ import { getAllProviderChoices, displaySetupSuccess, displaySetupError, getAllModelChoices, displaySetupInstructions } from '../../providers/integration/setup-ui.js';
48
9
  export function createSetupCommand() {
49
10
  const command = new Command('setup');
50
11
  command
@@ -88,558 +49,136 @@ async function runSetupWizard(force) {
88
49
  console.log(`${activeMarker}${chalk.white(name)} (${profile.provider})`);
89
50
  });
90
51
  console.log('');
91
- }
92
- const { action } = await inquirer.prompt([
93
- {
94
- type: 'list',
95
- name: 'action',
96
- message: 'What would you like to do?',
97
- choices: [
98
- { name: 'Add a new profile', value: 'add' },
99
- { name: 'Update an existing profile', value: 'update' },
100
- { name: 'Cancel', value: 'cancel' }
101
- ]
102
- }
103
- ]);
104
- if (action === 'cancel') {
105
- console.log(chalk.yellow('\nSetup cancelled.\n'));
106
- return;
107
- }
108
- if (action === 'update') {
109
- const { selectedProfile } = await inquirer.prompt([
52
+ const { action } = await inquirer.prompt([
110
53
  {
111
54
  type: 'list',
112
- name: 'selectedProfile',
113
- message: 'Select profile to update:',
114
- choices: profiles.map(p => ({ name: p.name, value: p.name }))
55
+ name: 'action',
56
+ message: 'What would you like to do?',
57
+ choices: [
58
+ { name: 'Add a new profile', value: 'add' },
59
+ { name: 'Update an existing profile', value: 'update' },
60
+ { name: 'Cancel', value: 'cancel' }
61
+ ]
115
62
  }
116
63
  ]);
117
- profileName = selectedProfile;
118
- isUpdate = true;
119
- console.log(chalk.white(`\nUpdating profile: ${chalk.cyan(profileName)}\n`));
64
+ if (action === 'cancel') {
65
+ console.log(chalk.yellow('\nSetup cancelled.\n'));
66
+ return;
67
+ }
68
+ if (action === 'update') {
69
+ const { selectedProfile } = await inquirer.prompt([
70
+ {
71
+ type: 'list',
72
+ name: 'selectedProfile',
73
+ message: 'Select profile to update:',
74
+ choices: profiles.map(p => ({ name: p.name, value: p.name }))
75
+ }
76
+ ]);
77
+ profileName = selectedProfile;
78
+ isUpdate = true;
79
+ console.log(chalk.white(`\nUpdating profile: ${chalk.cyan(profileName)}\n`));
80
+ }
81
+ else {
82
+ // Adding new profile - will ask for name at the end
83
+ console.log(chalk.white('\nConfiguring new profile...\n'));
84
+ }
120
85
  }
121
86
  else {
122
- // Adding new profile - will ask for name at the end
123
- console.log(chalk.white('\nConfiguring new profile...\n'));
87
+ // Config file exists but no profiles - treat as fresh setup
88
+ console.log(chalk.white("Let's configure your AI assistant.\n"));
124
89
  }
125
90
  }
126
91
  else {
127
92
  // First time setup - will create default profile or ask for name at the end
128
93
  console.log(chalk.white("Let's configure your AI assistant.\n"));
129
94
  }
130
- // Step 1: Choose provider (ai-run-sso is now first/default)
95
+ // Step 1: Get all registered providers from ProviderRegistry
96
+ const registeredProviders = ProviderRegistry.getAllProviders();
97
+ const allProviderChoices = getAllProviderChoices(registeredProviders);
131
98
  const { provider } = await inquirer.prompt([
132
99
  {
133
100
  type: 'list',
134
101
  name: 'provider',
135
- message: 'Choose your LLM provider:',
136
- choices: PROVIDERS.map(p => ({ name: p.name, value: p.value })),
137
- default: 'ai-run-sso' // Make SSO the default
102
+ message: 'Choose your LLM provider:\n',
103
+ choices: allProviderChoices,
104
+ pageSize: 15,
105
+ // Default to highest priority provider (SSO has priority 0)
106
+ default: allProviderChoices[0]?.value
138
107
  }
139
108
  ]);
140
- if (provider === 'ai-run-sso') {
141
- await handleAiRunSSOSetup(profileName, isUpdate);
142
- return; // Early return for SSO flow
109
+ // Get setup steps from provider registry
110
+ const setupSteps = ProviderRegistry.getSetupSteps(provider);
111
+ if (!setupSteps) {
112
+ throw new Error(`Provider "${provider}" does not have setup steps configured`);
143
113
  }
144
- const selectedProvider = PROVIDERS.find(p => p.value === provider);
145
- // Step 2: Provider details
146
- let baseUrl = selectedProvider.baseUrl;
147
- let apiKey = '';
148
- let model = selectedProvider.models[0] || '';
149
- // Special handling for AWS Bedrock
150
- if (provider === 'bedrock') {
151
- console.log(chalk.bold.cyan('\n📝 AWS Bedrock Configuration\n'));
152
- console.log(chalk.white('AWS Bedrock requires AWS access credentials and region configuration.'));
153
- console.log(chalk.white('AWS credentials can be configured in multiple ways:\n'));
154
- console.log(chalk.white(' 1. AWS CLI profiles (recommended): ~/.aws/credentials'));
155
- console.log(chalk.white(' 2. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY'));
156
- console.log(chalk.white(' 3. IAM roles (for EC2/ECS instances)\n'));
157
- // Check if AWS credentials might be available
158
- const hasAwsCli = await (async () => {
159
- try {
160
- const { exec } = await import('../../utils/exec.js');
161
- await exec('aws', ['--version']);
162
- return true;
163
- }
164
- catch {
165
- return false;
166
- }
167
- })();
168
- const hasAwsEnvVars = !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
169
- if (!hasAwsCli && !hasAwsEnvVars) {
170
- console.log(chalk.yellow('⚠️ AWS CLI not detected and no AWS environment variables found.\n'));
171
- console.log(chalk.white('Please configure AWS credentials before proceeding:\n'));
172
- console.log(chalk.cyan(' Option 1: Install and configure AWS CLI'));
173
- console.log(chalk.white(' $ ') + chalk.green('aws configure'));
174
- console.log(chalk.white(' Enter your AWS Access Key ID and Secret Access Key\n'));
175
- console.log(chalk.cyan(' Option 2: Set environment variables'));
176
- console.log(chalk.white(' $ ') + chalk.green('export AWS_ACCESS_KEY_ID="your-access-key"'));
177
- console.log(chalk.white(' $ ') + chalk.green('export AWS_SECRET_ACCESS_KEY="your-secret-key"\n'));
178
- const { continueAnyway } = await inquirer.prompt([
179
- {
180
- type: 'confirm',
181
- name: 'continueAnyway',
182
- message: 'Continue with Bedrock setup anyway?',
183
- default: false
184
- }
185
- ]);
186
- if (!continueAnyway) {
187
- console.log(chalk.yellow('\nBedrock setup cancelled. Please configure AWS credentials first.\n'));
188
- process.exit(0);
189
- }
190
- }
191
- else if (hasAwsCli) {
192
- console.log(chalk.green('✓ AWS CLI detected\n'));
193
- }
194
- else if (hasAwsEnvVars) {
195
- console.log(chalk.green('✓ AWS environment variables detected\n'));
196
- }
197
- // Ask for AWS configuration
198
- const { awsRegion, awsProfile, useProfile } = await inquirer.prompt([
199
- {
200
- type: 'confirm',
201
- name: 'useProfile',
202
- message: 'Use AWS CLI profile?',
203
- default: hasAwsCli,
204
- when: hasAwsCli
205
- },
206
- {
207
- type: 'input',
208
- name: 'awsProfile',
209
- message: 'AWS profile name:',
210
- default: 'default',
211
- when: (answers) => answers.useProfile
212
- },
213
- {
214
- type: 'input',
215
- name: 'awsRegion',
216
- message: 'AWS Region:',
217
- default: 'us-west-2',
218
- validate: (input) => input.trim() !== '' || 'AWS region is required'
219
- }
220
- ]);
221
- // Set environment variables for Bedrock
222
- process.env.AWS_REGION = awsRegion ? awsRegion.trim() : awsRegion;
223
- process.env.CLAUDE_CODE_USE_BEDROCK = '1';
224
- if (useProfile && awsProfile) {
225
- process.env.AWS_PROFILE = awsProfile ? awsProfile.trim() : awsProfile;
226
- }
227
- console.log(chalk.green('\n✓ Bedrock configuration set'));
228
- console.log(chalk.white(' AWS_REGION=' + (awsRegion ? awsRegion.trim() : awsRegion)));
229
- if (useProfile && awsProfile) {
230
- console.log(chalk.white(' AWS_PROFILE=' + (awsProfile ? awsProfile.trim() : awsProfile)));
231
- }
232
- console.log(chalk.white(' CLAUDE_CODE_USE_BEDROCK=1\n'));
233
- // For Bedrock, we don't need base URL or API key (uses AWS credentials)
234
- baseUrl = 'bedrock';
235
- apiKey = 'bedrock'; // Placeholder
236
- }
237
- else if (!baseUrl) {
238
- // Custom provider - ask for base URL
239
- const answers = await inquirer.prompt([
240
- {
241
- type: 'input',
242
- name: 'baseUrl',
243
- message: 'Enter API base URL:',
244
- validate: (input) => input.trim() !== '' || 'Base URL is required'
245
- }
246
- ]);
247
- baseUrl = answers.baseUrl ? answers.baseUrl.trim() : answers.baseUrl;
248
- }
249
- else {
250
- // Prompt for base URL directly (no default)
251
- const { customUrl } = await inquirer.prompt([
252
- {
253
- type: 'input',
254
- name: 'customUrl',
255
- message: `Enter base URL (default: ${baseUrl}):`,
256
- validate: (input) => {
257
- // Allow empty input to use default
258
- if (input.trim() === '')
259
- return true;
260
- // Otherwise validate it's not just whitespace
261
- return input.trim() !== '' || 'Base URL is required';
262
- }
263
- }
264
- ]);
265
- // Use custom URL if provided, otherwise keep default
266
- if (customUrl && customUrl.trim() !== '') {
267
- baseUrl = customUrl.trim();
114
+ // Use plugin-based setup flow
115
+ await handlePluginSetup(provider, setupSteps, profileName, isUpdate);
116
+ }
117
+ /**
118
+ * Handle plugin-based setup flow
119
+ *
120
+ * Uses ProviderSetupSteps from ProviderRegistry for clean, extensible setup
121
+ */
122
+ async function handlePluginSetup(providerName, setupSteps, profileName, isUpdate) {
123
+ try {
124
+ const providerTemplate = ProviderRegistry.getProvider(providerName);
125
+ // Display setup instructions if available
126
+ if (providerTemplate) {
127
+ displaySetupInstructions(providerTemplate);
268
128
  }
269
- }
270
- // API Key (skip for Bedrock as it uses AWS credentials)
271
- if (provider !== 'bedrock') {
272
- const { apiKeyInput } = await inquirer.prompt([
273
- {
274
- type: 'password',
275
- name: 'apiKeyInput',
276
- message: 'Enter your API key:',
277
- mask: '*',
278
- validate: (input) => input.trim() !== '' || 'API key is required'
279
- }
280
- ]);
281
- apiKey = apiKeyInput ? apiKeyInput.trim() : apiKeyInput;
282
- }
283
- // Step 2.5: Validate credentials and fetch models
284
- let availableModels = [];
285
- if (provider !== 'bedrock') {
286
- const healthSpinner = ora('Validating credentials...').start();
129
+ // Step 1: Get credentials
130
+ const credentials = await setupSteps.getCredentials(isUpdate);
131
+ // Step 2: Fetch models
132
+ const modelsSpinner = ora('Fetching available models...').start();
133
+ let models = [];
287
134
  try {
288
- const healthCheck = await checkProviderHealth(baseUrl, apiKey);
289
- if (!healthCheck.success) {
290
- healthSpinner.fail(chalk.red('Validation failed'));
291
- console.log(chalk.red(` Error: ${healthCheck.message}\n`));
292
- const { continueAnyway } = await inquirer.prompt([
293
- {
294
- type: 'confirm',
295
- name: 'continueAnyway',
296
- message: 'Continue with setup anyway?',
297
- default: false
298
- }
299
- ]);
300
- if (!continueAnyway) {
301
- console.log(chalk.yellow('\nSetup cancelled. Please check your credentials.\n'));
302
- return;
303
- }
304
- }
305
- else {
306
- healthSpinner.succeed(chalk.green('Credentials validated'));
307
- // Fetch available models
308
- const modelsSpinner = ora('Fetching available models...').start();
309
- try {
310
- availableModels = await fetchAvailableModels({
311
- provider,
312
- baseUrl,
313
- apiKey,
314
- model: 'temp', // Temporary, not used for fetching
315
- timeout: 300
316
- });
317
- if (availableModels.length > 0) {
318
- modelsSpinner.succeed(chalk.green(`Found ${availableModels.length} available models`));
319
- }
320
- else {
321
- modelsSpinner.warn(chalk.yellow('No models found - will use manual entry'));
322
- }
323
- }
324
- catch {
325
- modelsSpinner.warn(chalk.yellow('Could not fetch models - will use manual entry'));
326
- availableModels = [];
327
- }
328
- }
329
- }
330
- catch (error) {
331
- healthSpinner.fail(chalk.red('Validation error'));
332
- console.log(chalk.red(` ${error instanceof Error ? error.message : String(error)}\n`));
333
- const { continueAnyway } = await inquirer.prompt([
334
- {
335
- type: 'confirm',
336
- name: 'continueAnyway',
337
- message: 'Continue with setup anyway?',
338
- default: false
339
- }
340
- ]);
341
- if (!continueAnyway) {
342
- console.log(chalk.yellow('\nSetup cancelled.\n'));
343
- return;
344
- }
345
- }
346
- }
347
- // Model selection
348
- // Use fetched models if available, otherwise fall back to provider defaults
349
- const modelChoices = availableModels.length > 0
350
- ? availableModels
351
- : selectedProvider.models;
352
- if (modelChoices.length > 0) {
353
- // Add custom option at the end
354
- const choices = [
355
- ...modelChoices,
356
- { name: chalk.white('Custom model (manual entry)...'), value: 'custom' }
357
- ];
358
- const { selectedModel } = await inquirer.prompt([
359
- {
360
- type: 'list',
361
- name: 'selectedModel',
362
- message: availableModels.length > 0
363
- ? `Choose a model (${availableModels.length} available):`
364
- : 'Choose a model:',
365
- choices,
366
- pageSize: 15
367
- }
368
- ]);
369
- if (selectedModel === 'custom') {
370
- const { customModel } = await inquirer.prompt([
371
- {
372
- type: 'input',
373
- name: 'customModel',
374
- message: 'Enter model name:',
375
- validate: (input) => input.trim() !== '' || 'Model is required'
376
- }
377
- ]);
378
- model = customModel ? customModel.trim() : customModel;
379
- }
380
- else {
381
- model = selectedModel;
135
+ models = await setupSteps.fetchModels(credentials);
136
+ modelsSpinner.succeed(chalk.green(`Found ${models.length} available models`));
382
137
  }
383
- }
384
- else {
385
- const { modelInput } = await inquirer.prompt([
386
- {
387
- type: 'input',
388
- name: 'modelInput',
389
- message: 'Enter model name:',
390
- validate: (input) => input.trim() !== '' || 'Model is required'
391
- }
392
- ]);
393
- model = modelInput ? modelInput.trim() : modelInput;
394
- }
395
- // Step 3: Ask for profile name (if creating new)
396
- if (!isUpdate && profileName === null) {
397
- const profiles = await ConfigLoader.listProfiles();
398
- const existingNames = profiles.map(p => p.name);
399
- // Suggest a default name based on provider
400
- let defaultName = 'default';
401
- if (existingNames.length > 0) {
402
- // If profiles exist, suggest provider-based name
403
- defaultName = provider === 'ai-run-sso' ? 'codemie-sso' : provider;
404
- // Make it unique if needed
405
- let counter = 1;
406
- let suggestedName = defaultName;
407
- while (existingNames.includes(suggestedName)) {
408
- suggestedName = `${defaultName}-${counter}`;
409
- counter++;
410
- }
411
- defaultName = suggestedName;
138
+ catch {
139
+ modelsSpinner.warn(chalk.yellow('Could not fetch models - will use manual entry'));
140
+ models = [];
412
141
  }
413
- const { newProfileName } = await inquirer.prompt([
414
- {
415
- type: 'input',
416
- name: 'newProfileName',
417
- message: 'Enter a name for this profile:',
418
- default: defaultName,
419
- validate: (input) => {
420
- if (!input.trim())
421
- return 'Profile name is required';
422
- if (existingNames.includes(input.trim())) {
423
- return 'A profile with this name already exists';
424
- }
425
- return true;
426
- }
427
- }
428
- ]);
429
- profileName = newProfileName ? newProfileName.trim() : newProfileName;
430
- }
431
- // Step 4: Enable analytics by default (only for first-time setup)
432
- let enableAnalytics = false;
433
- if (!isUpdate) {
434
- const profiles = await ConfigLoader.listProfiles();
435
- const isFirstProfile = profiles.length === 0;
436
- if (isFirstProfile) {
437
- enableAnalytics = true;
142
+ // Step 3: Model selection
143
+ const selectedModel = await promptForModelSelection(models, providerTemplate);
144
+ // Step 3.5: Install model if provider supports it (e.g., Ollama)
145
+ if (providerTemplate?.supportsModelInstallation && setupSteps.installModel) {
146
+ await setupSteps.installModel(credentials, selectedModel, models);
438
147
  }
439
- }
440
- // Step 5: Save configuration as profile
441
- const profile = {
442
- name: profileName,
443
- provider,
444
- baseUrl,
445
- apiKey,
446
- model,
447
- timeout: 300,
448
- debug: false
449
- };
450
- const spinner = ora('Saving profile...').start();
451
- try {
452
- await ConfigLoader.saveProfile(profileName, profile);
453
- // Save analytics config if this is first profile
454
- if (enableAnalytics !== false) {
455
- const config = await ConfigLoader.loadMultiProviderConfig();
456
- if (!config.analytics) {
457
- config.analytics = {
458
- enabled: enableAnalytics,
459
- target: 'local',
460
- localPath: '~/.codemie/analytics',
461
- flushInterval: 5000,
462
- maxBufferSize: 100
463
- };
464
- await ConfigLoader.saveMultiProviderConfig(config);
465
- }
148
+ // Step 4: Build configuration
149
+ const config = setupSteps.buildConfig(credentials, selectedModel);
150
+ // Step 5: Ask for profile name (if creating new)
151
+ let finalProfileName = profileName;
152
+ if (!isUpdate && profileName === null) {
153
+ finalProfileName = await promptForProfileName(providerName);
466
154
  }
467
- spinner.succeed(chalk.green(`Profile "${profileName}" saved to ~/.codemie/config.json`));
468
- // If this is a new profile, ask if user wants to switch to it
155
+ // Step 6: Enable analytics (only for first profile)
156
+ let enableAnalytics = false;
469
157
  if (!isUpdate) {
470
- const activeProfile = await ConfigLoader.getActiveProfileName();
471
- if (activeProfile !== profileName) {
472
- const { switchToNew } = await inquirer.prompt([
473
- {
474
- type: 'confirm',
475
- name: 'switchToNew',
476
- message: `Switch to profile "${profileName}" as active?`,
477
- default: true
478
- }
479
- ]);
480
- if (switchToNew) {
481
- await ConfigLoader.switchProfile(profileName);
482
- console.log(chalk.green(`✓ Switched to profile "${profileName}"`));
483
- }
484
- }
158
+ const profiles = await ConfigLoader.listProfiles();
159
+ enableAnalytics = profiles.length === 0;
485
160
  }
486
- }
487
- catch (error) {
488
- spinner.fail(chalk.red('Failed to save profile'));
489
- throw error;
490
- }
491
- // Success message
492
- console.log(chalk.bold.green(`\n✅ Profile "${profileName}" configured successfully!\n`));
493
- console.log(chalk.cyan(`🔗 Provider: ${provider}`));
494
- console.log(chalk.cyan(`🤖 Model: ${model}`));
495
- console.log(chalk.cyan(`📁 Config: ~/.codemie/config.json\n`));
496
- console.log(chalk.bold(`🚀 Ready to use! Try: ${chalk.white('codemie-code "test task"')}\n`));
497
- }
498
- async function handleAiRunSSOSetup(profileName, isUpdate) {
499
- console.log(chalk.bold.cyan('\n🔐 CodeMie SSO Configuration\n'));
500
- // Step 1: Get CodeMie URL
501
- const { codeMieUrl } = await inquirer.prompt([
502
- {
503
- type: 'input',
504
- name: 'codeMieUrl',
505
- message: 'Enter CodeMie URL:',
506
- default: 'https://codemie.lab.epam.com',
507
- validate: (input) => {
508
- const trimmed = input.trim();
509
- if (!trimmed)
510
- return 'CodeMie URL is required';
511
- if (!trimmed.startsWith('http'))
512
- return 'URL must start with http:// or https://';
513
- try {
514
- new URL(trimmed);
515
- return true;
516
- }
517
- catch {
518
- return 'Please enter a valid URL';
519
- }
520
- }
521
- }
522
- ]);
523
- // Trim the URL to ensure no leading/trailing spaces
524
- const trimmedCodeMieUrl = codeMieUrl ? codeMieUrl.trim() : codeMieUrl;
525
- // Step 2: Proceed directly to SSO authentication (no connectivity check)
526
- // Following the same pattern as codemie-ide-plugin which trusts the SSO endpoint
527
- // Step 3: Launch SSO Authentication
528
- console.log(chalk.white('\nStarting SSO authentication...\n'));
529
- const authSpinner = ora('Launching browser for authentication...').start();
530
- try {
531
- const sso = new CodeMieSSO();
532
- const authResult = await sso.authenticate({ codeMieUrl: trimmedCodeMieUrl, timeout: 120000 });
533
- if (!authResult.success) {
534
- authSpinner.fail(chalk.red('SSO authentication failed'));
535
- console.log(chalk.red(` Error: ${authResult.error}\n`));
536
- return;
537
- }
538
- authSpinner.succeed(chalk.green('SSO authentication successful'));
539
- // Step 4a: Validate CodeMie integrations
540
- const integrationsSpinner = ora('Checking CodeMie integrations...').start();
541
- let selectedIntegration;
161
+ // Step 7: Save profile
162
+ const saveSpinner = ora('Saving profile...').start();
542
163
  try {
543
- selectedIntegration = await validateCodeMieIntegrations(authResult, integrationsSpinner);
544
- if (selectedIntegration) {
545
- integrationsSpinner.succeed(chalk.green('CodeMie integration selected'));
546
- }
547
- else {
548
- integrationsSpinner.info(chalk.white('Continuing without integration'));
549
- }
550
- }
551
- catch {
552
- integrationsSpinner.stop();
553
- // Error details already displayed by validateCodeMieIntegrations
554
- return;
555
- }
556
- // Step 4b: Fetch available models from CodeMie
557
- const modelsSpinner = ora('Fetching available models from CodeMie...').start();
558
- try {
559
- const models = await fetchCodeMieModels(authResult.apiUrl, authResult.cookies);
560
- modelsSpinner.succeed(chalk.green(`Found ${models.length} available models`));
561
- // Step 5: Model selection
562
- const selectedModel = await promptForModelSelection(models);
563
- // Step 6: Ask for profile name (if creating new)
564
- let finalProfileName = profileName;
565
- if (!isUpdate && profileName === null) {
566
- const profiles = await ConfigLoader.listProfiles();
567
- const existingNames = profiles.map(p => p.name);
568
- // Suggest a default name
569
- let defaultName = 'codemie-sso';
570
- if (existingNames.length > 0) {
571
- let counter = 1;
572
- let suggestedName = defaultName;
573
- while (existingNames.includes(suggestedName)) {
574
- suggestedName = `${defaultName}-${counter}`;
575
- counter++;
576
- }
577
- defaultName = suggestedName;
578
- }
579
- else {
580
- defaultName = 'default';
581
- }
582
- const { newProfileName } = await inquirer.prompt([
583
- {
584
- type: 'input',
585
- name: 'newProfileName',
586
- message: 'Enter a name for this profile:',
587
- default: defaultName,
588
- validate: (input) => {
589
- if (!input.trim())
590
- return 'Profile name is required';
591
- if (existingNames.includes(input.trim())) {
592
- return 'A profile with this name already exists';
593
- }
594
- return true;
595
- }
596
- }
597
- ]);
598
- finalProfileName = newProfileName ? newProfileName.trim() : newProfileName;
599
- }
600
- // Step 6.5: Enable analytics by default (only for first-time setup)
601
- let enableAnalytics = false;
602
- if (!isUpdate) {
603
- const profiles = await ConfigLoader.listProfiles();
604
- const isFirstProfile = profiles.length === 0;
605
- if (isFirstProfile) {
606
- enableAnalytics = true;
607
- }
608
- }
609
- // Step 7: Save configuration as profile
610
- const profile = {
611
- name: finalProfileName,
612
- provider: 'ai-run-sso',
613
- authMethod: 'sso',
614
- codeMieUrl: trimmedCodeMieUrl,
615
- baseUrl: authResult.apiUrl,
616
- apiKey: 'sso-authenticated',
617
- model: selectedModel,
618
- timeout: 300,
619
- debug: false
620
- };
621
- // Only add integration if one was selected
622
- if (selectedIntegration) {
623
- profile.codeMieIntegration = selectedIntegration;
624
- }
625
- const saveSpinner = ora('Saving profile...').start();
626
- await ConfigLoader.saveProfile(finalProfileName, profile);
627
- // Save analytics config if this is first profile
628
- if (enableAnalytics !== false) {
629
- const config = await ConfigLoader.loadMultiProviderConfig();
630
- if (!config.analytics) {
631
- config.analytics = {
632
- enabled: enableAnalytics,
164
+ config.name = finalProfileName;
165
+ await ConfigLoader.saveProfile(finalProfileName, config);
166
+ // Save analytics config if first profile
167
+ if (enableAnalytics) {
168
+ const multiConfig = await ConfigLoader.loadMultiProviderConfig();
169
+ if (!multiConfig.analytics) {
170
+ multiConfig.analytics = {
171
+ enabled: true,
633
172
  target: 'local',
634
173
  localPath: '~/.codemie/analytics',
635
174
  flushInterval: 5000,
636
175
  maxBufferSize: 100
637
176
  };
638
- await ConfigLoader.saveMultiProviderConfig(config);
177
+ await ConfigLoader.saveMultiProviderConfig(multiConfig);
639
178
  }
640
179
  }
641
- saveSpinner.succeed(chalk.green(`Profile "${finalProfileName}" saved to ~/.codemie/config.json`));
642
- // If this is a new profile, ask if user wants to switch to it
180
+ saveSpinner.succeed(chalk.green(`Profile "${finalProfileName}" saved`));
181
+ // Switch to new profile if needed
643
182
  if (!isUpdate) {
644
183
  const activeProfile = await ConfigLoader.getActiveProfileName();
645
184
  if (activeProfile !== finalProfileName) {
@@ -657,113 +196,68 @@ async function handleAiRunSSOSetup(profileName, isUpdate) {
657
196
  }
658
197
  }
659
198
  }
660
- // Success message
661
- console.log(chalk.bold.green(`\n✅ Profile "${finalProfileName}" configured successfully!\n`));
662
- console.log(chalk.cyan(`🔗 Connected to: ${trimmedCodeMieUrl}`));
663
- console.log(chalk.cyan(`🔑 Authentication: SSO (session stored securely)`));
664
- console.log(chalk.cyan(`🤖 Selected Model: ${selectedModel}`));
665
- console.log(chalk.cyan(`📁 Config saved to: ~/.codemie/config.json\n`));
666
- console.log(chalk.bold(`🚀 Ready to use! Try: ${chalk.white('codemie-code "test task"')}\n`));
199
+ // Display success
200
+ displaySetupSuccess(finalProfileName, providerName, selectedModel);
667
201
  }
668
202
  catch (error) {
669
- modelsSpinner.fail(chalk.red('Failed to fetch models'));
670
- console.log(chalk.red(` Error: ${error instanceof Error ? error.message : String(error)}\n`));
671
- // Continue with manual model entry
672
- const { manualModel } = await inquirer.prompt([
673
- {
674
- type: 'input',
675
- name: 'manualModel',
676
- message: 'Enter model name manually:',
677
- default: 'claude-4-5-sonnet',
678
- validate: (input) => input.trim() !== '' || 'Model name is required'
679
- }
680
- ]);
681
- // Ask for profile name (if creating new)
682
- let finalProfileName = profileName;
683
- if (!isUpdate && profileName === null) {
684
- const profiles = await ConfigLoader.listProfiles();
685
- const existingNames = profiles.map(p => p.name);
686
- let defaultName = 'codemie-sso';
687
- if (existingNames.length > 0) {
688
- let counter = 1;
689
- let suggestedName = defaultName;
690
- while (existingNames.includes(suggestedName)) {
691
- suggestedName = `${defaultName}-${counter}`;
692
- counter++;
693
- }
694
- defaultName = suggestedName;
695
- }
696
- else {
697
- defaultName = 'default';
698
- }
699
- const { newProfileName } = await inquirer.prompt([
700
- {
701
- type: 'input',
702
- name: 'newProfileName',
703
- message: 'Enter a name for this profile:',
704
- default: defaultName,
705
- validate: (input) => {
706
- if (!input.trim())
707
- return 'Profile name is required';
708
- if (existingNames.includes(input.trim())) {
709
- return 'A profile with this name already exists';
710
- }
711
- return true;
712
- }
713
- }
714
- ]);
715
- finalProfileName = newProfileName ? newProfileName.trim() : newProfileName;
716
- }
717
- // Enable analytics by default (only for first-time setup)
718
- let enableAnalytics = false;
719
- if (!isUpdate) {
720
- const profiles = await ConfigLoader.listProfiles();
721
- const isFirstProfile = profiles.length === 0;
722
- if (isFirstProfile) {
723
- enableAnalytics = true;
724
- }
725
- }
726
- // Save config with manual model as profile
727
- const profile = {
728
- name: finalProfileName,
729
- provider: 'ai-run-sso',
730
- authMethod: 'sso',
731
- codeMieUrl: trimmedCodeMieUrl,
732
- baseUrl: authResult.apiUrl,
733
- apiKey: 'sso-authenticated',
734
- model: manualModel ? manualModel.trim() : manualModel,
735
- timeout: 300,
736
- debug: false
737
- };
738
- // Only add integration if one was selected
739
- if (selectedIntegration) {
740
- profile.codeMieIntegration = selectedIntegration;
741
- }
742
- await ConfigLoader.saveProfile(finalProfileName, profile);
743
- // Save analytics config if this is first profile
744
- if (enableAnalytics !== false) {
745
- const config = await ConfigLoader.loadMultiProviderConfig();
746
- if (!config.analytics) {
747
- config.analytics = {
748
- enabled: enableAnalytics,
749
- target: 'local',
750
- localPath: '~/.codemie/analytics',
751
- flushInterval: 5000,
752
- maxBufferSize: 100
753
- };
754
- await ConfigLoader.saveMultiProviderConfig(config);
755
- }
756
- }
757
- console.log(chalk.green(`\n✅ Profile "${finalProfileName}" saved with manual model selection.\n`));
203
+ saveSpinner.fail(chalk.red('Failed to save profile'));
204
+ throw error;
758
205
  }
759
206
  }
760
207
  catch (error) {
761
- authSpinner.fail(chalk.red('Authentication error'));
762
- console.log(chalk.red(` ${error instanceof Error ? error.message : String(error)}\n`));
763
- return;
208
+ const errorMessage = error instanceof Error ? error.message : String(error);
209
+ const providerTemplate = ProviderRegistry.getProvider(providerName);
210
+ displaySetupError(new Error(errorMessage), providerTemplate?.setupInstructions);
211
+ throw error;
764
212
  }
765
213
  }
766
- async function promptForModelSelection(models) {
214
+ /**
215
+ * Prompt for profile name
216
+ *
217
+ * Generates unique default name and validates input
218
+ */
219
+ async function promptForProfileName(providerName) {
220
+ const profiles = await ConfigLoader.listProfiles();
221
+ const existingNames = profiles.map(p => p.name);
222
+ // Suggest a default name based on provider template
223
+ let defaultName = 'default';
224
+ if (existingNames.length > 0) {
225
+ // If profiles exist, use provider's defaultProfileName or provider name
226
+ const providerTemplate = ProviderRegistry.getProvider(providerName);
227
+ defaultName = providerTemplate?.defaultProfileName || providerName;
228
+ // Make it unique if needed
229
+ let counter = 1;
230
+ let suggestedName = defaultName;
231
+ while (existingNames.includes(suggestedName)) {
232
+ suggestedName = `${defaultName}-${counter}`;
233
+ counter++;
234
+ }
235
+ defaultName = suggestedName;
236
+ }
237
+ const { newProfileName } = await inquirer.prompt([
238
+ {
239
+ type: 'input',
240
+ name: 'newProfileName',
241
+ message: 'Enter a name for this profile:',
242
+ default: defaultName,
243
+ validate: (input) => {
244
+ if (!input.trim())
245
+ return 'Profile name is required';
246
+ if (existingNames.includes(input.trim())) {
247
+ return 'A profile with this name already exists';
248
+ }
249
+ return true;
250
+ }
251
+ }
252
+ ]);
253
+ return newProfileName ? newProfileName.trim() : newProfileName;
254
+ }
255
+ /**
256
+ * Prompt for model selection with metadata
257
+ *
258
+ * Uses getAllModelChoices for enriched display
259
+ */
260
+ async function promptForModelSelection(models, providerTemplate) {
767
261
  if (models.length === 0) {
768
262
  const { manualModel } = await inquirer.prompt([
769
263
  {
@@ -776,9 +270,9 @@ async function promptForModelSelection(models) {
776
270
  ]);
777
271
  return manualModel ? manualModel.trim() : manualModel;
778
272
  }
779
- // Add custom option at the end
273
+ // Use getAllModelChoices for enriched display with metadata
780
274
  const choices = [
781
- ...models,
275
+ ...getAllModelChoices(models, providerTemplate),
782
276
  { name: chalk.white('Custom model (manual entry)...'), value: 'custom' }
783
277
  ];
784
278
  const { selectedModel } = await inquirer.prompt([
@@ -803,4 +297,9 @@ async function promptForModelSelection(models) {
803
297
  }
804
298
  return selectedModel;
805
299
  }
300
+ /*
301
+ * Note: Old SSO setup function (handleAiRunSSOSetup) has been removed.
302
+ * It has been replaced by the plugin-based SSOSetupSteps in src/providers/plugins/sso/
303
+ * All SSO setup logic is now handled through the ProviderRegistry plugin system.
304
+ */
806
305
  //# sourceMappingURL=setup.js.map