@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.
- package/README.md +24 -9
- package/dist/agents/codemie-code/agent.js +2 -2
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/config.d.ts.map +1 -1
- package/dist/agents/codemie-code/config.js +12 -4
- package/dist/agents/codemie-code/config.js.map +1 -1
- package/dist/agents/codemie-code/tools/planning.d.ts +1 -1
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +5 -4
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts +1 -5
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +5 -26
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/plugins/claude.plugin.js +1 -1
- package/dist/agents/plugins/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/codemie-code.plugin.js +1 -1
- package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
- package/dist/agents/plugins/codex.plugin.js +2 -2
- package/dist/agents/plugins/codex.plugin.js.map +1 -1
- package/dist/agents/plugins/deepagents.plugin.js +1 -1
- package/dist/agents/plugins/deepagents.plugin.js.map +1 -1
- package/dist/agents/plugins/gemini.plugin.js +1 -1
- package/dist/agents/plugins/gemini.plugin.js.map +1 -1
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +3 -11
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/remote-submission/cursor-manager.d.ts +1 -1
- package/dist/analytics/remote-submission/cursor-manager.js +2 -2
- package/dist/analytics/remote-submission/cursor-manager.js.map +1 -1
- package/dist/analytics/remote-submission/index.d.ts +2 -2
- package/dist/analytics/remote-submission/index.d.ts.map +1 -1
- package/dist/analytics/remote-submission/index.js +1 -1
- package/dist/analytics/remote-submission/index.js.map +1 -1
- package/dist/analytics/remote-submission/lock-manager.d.ts +1 -1
- package/dist/analytics/remote-submission/lock-manager.js +2 -2
- package/dist/analytics/remote-submission/lock-manager.js.map +1 -1
- package/dist/analytics/remote-submission/metric-transformer.d.ts +2 -30
- package/dist/analytics/remote-submission/metric-transformer.d.ts.map +1 -1
- package/dist/analytics/remote-submission/metric-transformer.js +24 -117
- package/dist/analytics/remote-submission/metric-transformer.js.map +1 -1
- package/dist/analytics/remote-submission/submitter.d.ts +1 -0
- package/dist/analytics/remote-submission/submitter.d.ts.map +1 -1
- package/dist/analytics/remote-submission/submitter.js +18 -37
- package/dist/analytics/remote-submission/submitter.js.map +1 -1
- package/dist/analytics/remote-submission/types.d.ts +5 -51
- package/dist/analytics/remote-submission/types.d.ts.map +1 -1
- package/dist/analytics/remote-submission/types.js.map +1 -1
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +10 -5
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/doctor/checks/AIConfigCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/AIConfigCheck.js +12 -5
- package/dist/cli/commands/doctor/checks/AIConfigCheck.js.map +1 -1
- package/dist/cli/commands/doctor/formatter.d.ts +1 -1
- package/dist/cli/commands/doctor/formatter.d.ts.map +1 -1
- package/dist/cli/commands/doctor/formatter.js +1 -6
- package/dist/cli/commands/doctor/formatter.js.map +1 -1
- package/dist/cli/commands/doctor/index.d.ts.map +1 -1
- package/dist/cli/commands/doctor/index.js +23 -8
- package/dist/cli/commands/doctor/index.js.map +1 -1
- package/dist/cli/commands/doctor/type-adapters.d.ts +18 -0
- package/dist/cli/commands/doctor/type-adapters.d.ts.map +1 -0
- package/dist/cli/commands/doctor/type-adapters.js +75 -0
- package/dist/cli/commands/doctor/type-adapters.js.map +1 -0
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +1 -6
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +0 -5
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/profile.js +90 -12
- package/dist/cli/commands/profile.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +159 -660
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/providers/core/base/BaseHealthCheck.d.ts +57 -0
- package/dist/providers/core/base/BaseHealthCheck.d.ts.map +1 -0
- package/dist/providers/core/base/BaseHealthCheck.js +121 -0
- package/dist/providers/core/base/BaseHealthCheck.js.map +1 -0
- package/dist/providers/core/base/BaseModelProxy.d.ts +45 -0
- package/dist/providers/core/base/BaseModelProxy.d.ts.map +1 -0
- package/dist/providers/core/base/BaseModelProxy.js +43 -0
- package/dist/providers/core/base/BaseModelProxy.js.map +1 -0
- package/dist/providers/core/base/http-client.d.ts +57 -0
- package/dist/providers/core/base/http-client.d.ts.map +1 -0
- package/dist/providers/core/base/http-client.js +240 -0
- package/dist/providers/core/base/http-client.js.map +1 -0
- package/dist/providers/core/decorators.d.ts +13 -0
- package/dist/providers/core/decorators.d.ts.map +1 -0
- package/dist/providers/core/decorators.js +15 -0
- package/dist/providers/core/decorators.js.map +1 -0
- package/dist/providers/core/index.d.ts +13 -0
- package/dist/providers/core/index.d.ts.map +1 -0
- package/dist/providers/core/index.js +14 -0
- package/dist/providers/core/index.js.map +1 -0
- package/dist/providers/core/registry.d.ts +66 -0
- package/dist/providers/core/registry.d.ts.map +1 -0
- package/dist/providers/core/registry.js +105 -0
- package/dist/providers/core/registry.js.map +1 -0
- package/dist/providers/core/types.d.ts +285 -0
- package/dist/providers/core/types.d.ts.map +1 -0
- package/dist/providers/core/types.js +7 -0
- package/dist/providers/core/types.js.map +1 -0
- package/dist/providers/index.d.ts +20 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +22 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/integration/setup-ui.d.ts +76 -0
- package/dist/providers/integration/setup-ui.d.ts.map +1 -0
- package/dist/providers/integration/setup-ui.js +141 -0
- package/dist/providers/integration/setup-ui.js.map +1 -0
- package/dist/providers/plugins/litellm/index.d.ts +8 -0
- package/dist/providers/plugins/litellm/index.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/index.js +12 -0
- package/dist/providers/plugins/litellm/index.js.map +1 -0
- package/dist/providers/plugins/litellm/litellm.models.d.ts +27 -0
- package/dist/providers/plugins/litellm/litellm.models.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/litellm.models.js +48 -0
- package/dist/providers/plugins/litellm/litellm.models.js.map +1 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts +8 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.js +52 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.js.map +1 -0
- package/dist/providers/plugins/litellm/litellm.template.d.ts +11 -0
- package/dist/providers/plugins/litellm/litellm.template.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/litellm.template.js +59 -0
- package/dist/providers/plugins/litellm/litellm.template.js.map +1 -0
- package/dist/providers/plugins/ollama/index.d.ts +11 -0
- package/dist/providers/plugins/ollama/index.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/index.js +11 -0
- package/dist/providers/plugins/ollama/index.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.health.d.ts +48 -0
- package/dist/providers/plugins/ollama/ollama.health.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.health.js +87 -0
- package/dist/providers/plugins/ollama/ollama.health.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.models.d.ts +47 -0
- package/dist/providers/plugins/ollama/ollama.models.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.models.js +252 -0
- package/dist/providers/plugins/ollama/ollama.models.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts +16 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.js +164 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.template.d.ts +11 -0
- package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.template.js +87 -0
- package/dist/providers/plugins/ollama/ollama.template.js.map +1 -0
- package/dist/providers/plugins/sso/index.d.ts +12 -0
- package/dist/providers/plugins/sso/index.d.ts.map +1 -0
- package/dist/providers/plugins/sso/index.js +12 -0
- package/dist/providers/plugins/sso/index.js.map +1 -0
- package/dist/providers/plugins/sso/sso.auth.d.ts +50 -0
- package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -0
- package/dist/{utils/sso-auth.js → providers/plugins/sso/sso.auth.js} +37 -2
- package/dist/providers/plugins/sso/sso.auth.js.map +1 -0
- package/dist/providers/plugins/sso/sso.health.d.ts +44 -0
- package/dist/providers/plugins/sso/sso.health.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.health.js +178 -0
- package/dist/providers/plugins/sso/sso.health.js.map +1 -0
- package/dist/{utils/codemie-model-fetcher.d.ts → providers/plugins/sso/sso.http-client.d.ts} +16 -5
- package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.http-client.js +187 -0
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -0
- package/dist/providers/plugins/sso/sso.models.d.ts +48 -0
- package/dist/providers/plugins/sso/sso.models.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.models.js +139 -0
- package/dist/providers/plugins/sso/sso.models.js.map +1 -0
- package/dist/providers/plugins/sso/sso.setup-steps.d.ts +16 -0
- package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.setup-steps.js +145 -0
- package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -0
- package/dist/providers/plugins/sso/sso.template.d.ts +11 -0
- package/dist/providers/plugins/sso/sso.template.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.template.js +35 -0
- package/dist/providers/plugins/sso/sso.template.js.map +1 -0
- package/dist/proxy/errors.d.ts.map +1 -0
- package/dist/proxy/errors.js.map +1 -0
- package/dist/proxy/http-client.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/http-client.js +1 -1
- package/dist/proxy/http-client.js.map +1 -0
- package/dist/proxy/plugins/header-injection.plugin.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/header-injection.plugin.js +7 -3
- package/dist/proxy/plugins/header-injection.plugin.js.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/index.d.ts +2 -2
- package/dist/proxy/plugins/index.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/index.js +3 -5
- package/dist/proxy/plugins/index.js.map +1 -0
- package/dist/proxy/plugins/logging.plugin.d.ts +22 -0
- package/dist/proxy/plugins/logging.plugin.d.ts.map +1 -0
- package/dist/proxy/plugins/logging.plugin.js +92 -0
- package/dist/proxy/plugins/logging.plugin.js.map +1 -0
- package/dist/proxy/plugins/registry.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/registry.js +1 -1
- package/dist/proxy/plugins/registry.js.map +1 -0
- package/dist/proxy/plugins/sso-auth.plugin.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/sso-auth.plugin.js +1 -1
- package/dist/proxy/plugins/sso-auth.plugin.js.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/types.d.ts +3 -3
- package/dist/proxy/plugins/types.d.ts.map +1 -0
- package/dist/proxy/plugins/types.js.map +1 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/utils/codemie-proxy.d.ts +5 -4
- package/dist/utils/codemie-proxy.d.ts.map +1 -1
- package/dist/utils/codemie-proxy.js +31 -26
- package/dist/utils/codemie-proxy.js.map +1 -1
- package/dist/utils/config-loader.d.ts +1 -6
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +30 -90
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/credential-store.d.ts +1 -1
- package/dist/utils/credential-store.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +0 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.d.ts +0 -11
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.js +0 -264
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.js.map +0 -1
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.d.ts +0 -12
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.js +0 -12
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.js.map +0 -1
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.d.ts +0 -11
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.js +0 -97
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.js.map +0 -1
- package/dist/cli/commands/doctor/providers/index.d.ts +0 -30
- package/dist/cli/commands/doctor/providers/index.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/index.js +0 -66
- package/dist/cli/commands/doctor/providers/index.js.map +0 -1
- package/dist/types/sso.d.ts +0 -42
- package/dist/types/sso.d.ts.map +0 -1
- package/dist/types/sso.js +0 -2
- package/dist/types/sso.js.map +0 -1
- package/dist/utils/async-tips.d.ts +0 -64
- package/dist/utils/async-tips.d.ts.map +0 -1
- package/dist/utils/async-tips.js +0 -203
- package/dist/utils/async-tips.js.map +0 -1
- package/dist/utils/codemie-integration-validator.d.ts +0 -18
- package/dist/utils/codemie-integration-validator.d.ts.map +0 -1
- package/dist/utils/codemie-integration-validator.js +0 -119
- package/dist/utils/codemie-integration-validator.js.map +0 -1
- package/dist/utils/codemie-model-fetcher.d.ts.map +0 -1
- package/dist/utils/codemie-model-fetcher.js +0 -317
- package/dist/utils/codemie-model-fetcher.js.map +0 -1
- package/dist/utils/health-checker.d.ts +0 -20
- package/dist/utils/health-checker.d.ts.map +0 -1
- package/dist/utils/health-checker.js +0 -172
- package/dist/utils/health-checker.js.map +0 -1
- package/dist/utils/model-fetcher.d.ts +0 -21
- package/dist/utils/model-fetcher.d.ts.map +0 -1
- package/dist/utils/model-fetcher.js +0 -148
- package/dist/utils/model-fetcher.js.map +0 -1
- package/dist/utils/proxy/errors.d.ts.map +0 -1
- package/dist/utils/proxy/errors.js.map +0 -1
- package/dist/utils/proxy/http-client.d.ts.map +0 -1
- package/dist/utils/proxy/http-client.js.map +0 -1
- package/dist/utils/proxy/plugins/analytics.plugin.d.ts +0 -19
- package/dist/utils/proxy/plugins/analytics.plugin.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/analytics.plugin.js +0 -84
- package/dist/utils/proxy/plugins/analytics.plugin.js.map +0 -1
- package/dist/utils/proxy/plugins/header-injection.plugin.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/header-injection.plugin.js.map +0 -1
- package/dist/utils/proxy/plugins/index.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/index.js.map +0 -1
- package/dist/utils/proxy/plugins/registry.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/registry.js.map +0 -1
- package/dist/utils/proxy/plugins/sso-auth.plugin.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/sso-auth.plugin.js.map +0 -1
- package/dist/utils/proxy/plugins/types.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/types.js.map +0 -1
- package/dist/utils/proxy/types.d.ts.map +0 -1
- package/dist/utils/proxy/types.js.map +0 -1
- package/dist/utils/sso-auth.d.ts +0 -15
- package/dist/utils/sso-auth.d.ts.map +0 -1
- package/dist/utils/sso-auth.js.map +0 -1
- package/dist/utils/tips.d.ts +0 -35
- package/dist/utils/tips.d.ts.map +0 -1
- package/dist/utils/tips.js +0 -93
- package/dist/utils/tips.js.map +0 -1
- /package/dist/{utils/proxy → proxy}/errors.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/errors.js +0 -0
- /package/dist/{utils/proxy → proxy}/http-client.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/header-injection.plugin.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/registry.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/sso-auth.plugin.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/types.js +0 -0
- /package/dist/{utils/proxy → proxy}/types.d.ts +0 -0
- /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 {
|
|
8
|
-
import {
|
|
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: '
|
|
113
|
-
message: '
|
|
114
|
-
choices:
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
//
|
|
123
|
-
console.log(chalk.white('
|
|
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:
|
|
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:
|
|
137
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
const
|
|
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
|
-
|
|
289
|
-
|
|
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
|
-
|
|
385
|
-
|
|
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
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
-
|
|
468
|
-
|
|
155
|
+
// Step 6: Enable analytics (only for first profile)
|
|
156
|
+
let enableAnalytics = false;
|
|
469
157
|
if (!isUpdate) {
|
|
470
|
-
const
|
|
471
|
-
|
|
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
|
-
|
|
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
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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(
|
|
177
|
+
await ConfigLoader.saveMultiProviderConfig(multiConfig);
|
|
639
178
|
}
|
|
640
179
|
}
|
|
641
|
-
saveSpinner.succeed(chalk.green(`Profile "${finalProfileName}" saved
|
|
642
|
-
//
|
|
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
|
-
//
|
|
661
|
-
|
|
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
|
-
|
|
670
|
-
|
|
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
|
-
|
|
762
|
-
|
|
763
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|