fraim-framework 2.0.82 ā 2.0.83
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/dist/src/cli/api/get-provider-client.js +41 -0
- package/dist/src/cli/api/provider-client.js +107 -0
- package/dist/src/cli/commands/add-ide.js +144 -77
- package/dist/src/cli/commands/add-provider.js +61 -221
- package/dist/src/cli/commands/doctor.js +4 -1
- package/dist/src/cli/commands/init-project.js +24 -35
- package/dist/src/cli/commands/setup.js +247 -563
- package/dist/src/cli/commands/test-mcp.js +35 -1
- package/dist/src/cli/doctor/check-runner.js +6 -3
- package/dist/src/cli/doctor/checks/global-setup-checks.js +5 -6
- package/dist/src/cli/doctor/checks/ide-config-checks.js +44 -23
- package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +324 -146
- package/dist/src/cli/doctor/checks/scripts-checks.js +2 -2
- package/dist/src/cli/fraim.js +42 -1
- package/dist/src/cli/mcp/ide-formats.js +243 -0
- package/dist/src/cli/mcp/mcp-server-builder.js +48 -0
- package/dist/src/cli/mcp/mcp-server-registry.js +159 -0
- package/dist/src/cli/mcp/types.js +3 -0
- package/dist/src/cli/providers/local-provider-registry.js +145 -0
- package/dist/src/cli/providers/provider-registry.js +230 -0
- package/dist/src/cli/setup/auto-mcp-setup.js +56 -118
- package/dist/src/cli/setup/mcp-config-generator.js +64 -321
- package/dist/src/cli/setup/provider-prompts.js +300 -0
- package/package.json +2 -1
- package/dist/src/cli/commands/install.js +0 -86
- package/dist/src/cli/setup/token-validator.js +0 -57
|
@@ -9,11 +9,13 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
9
9
|
const prompts_1 = __importDefault(require("prompts"));
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
|
-
const token_validator_1 = require("../setup/token-validator");
|
|
13
12
|
const mcp_config_generator_1 = require("../setup/mcp-config-generator");
|
|
14
13
|
const ide_detector_1 = require("../setup/ide-detector");
|
|
15
14
|
const script_sync_utils_1 = require("../utils/script-sync-utils");
|
|
16
15
|
const mcp_config_generator_2 = require("../setup/mcp-config-generator");
|
|
16
|
+
const provider_registry_1 = require("../providers/provider-registry");
|
|
17
|
+
const provider_prompts_1 = require("../setup/provider-prompts");
|
|
18
|
+
const get_provider_client_1 = require("../api/get-provider-client");
|
|
17
19
|
const loadGlobalConfig = () => {
|
|
18
20
|
const globalConfigPath = path_1.default.join((0, script_sync_utils_1.getUserFraimDir)(), 'config.json');
|
|
19
21
|
if (!fs_1.default.existsSync(globalConfigPath)) {
|
|
@@ -30,147 +32,6 @@ const saveGlobalConfig = (config) => {
|
|
|
30
32
|
const globalConfigPath = path_1.default.join((0, script_sync_utils_1.getUserFraimDir)(), 'config.json');
|
|
31
33
|
fs_1.default.writeFileSync(globalConfigPath, JSON.stringify(config, null, 2));
|
|
32
34
|
};
|
|
33
|
-
const promptForGitHubToken = async () => {
|
|
34
|
-
console.log(chalk_1.default.blue('\nš GitHub Token'));
|
|
35
|
-
console.log(chalk_1.default.gray('Create a token at: https://github.com/settings/tokens'));
|
|
36
|
-
console.log(chalk_1.default.gray('Required scopes: repo, read:org, read:user\n'));
|
|
37
|
-
const response = await (0, prompts_1.default)({
|
|
38
|
-
type: 'password',
|
|
39
|
-
name: 'token',
|
|
40
|
-
message: 'Enter your GitHub token (ghp_...):',
|
|
41
|
-
validate: (value) => {
|
|
42
|
-
if (!value)
|
|
43
|
-
return 'Token is required';
|
|
44
|
-
if (!(0, token_validator_1.isValidTokenFormat)(value, 'github')) {
|
|
45
|
-
return 'Invalid GitHub token format (should start with ghp_)';
|
|
46
|
-
}
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
if (!response.token) {
|
|
51
|
-
throw new Error('GitHub token is required');
|
|
52
|
-
}
|
|
53
|
-
return response.token;
|
|
54
|
-
};
|
|
55
|
-
const promptForGitLabToken = async () => {
|
|
56
|
-
console.log(chalk_1.default.blue('\nš GitLab Token'));
|
|
57
|
-
console.log(chalk_1.default.gray('Create a token at: https://gitlab.com/-/profile/personal_access_tokens'));
|
|
58
|
-
console.log(chalk_1.default.gray('Required scopes: api, read_api, read_repository\n'));
|
|
59
|
-
const response = await (0, prompts_1.default)({
|
|
60
|
-
type: 'password',
|
|
61
|
-
name: 'token',
|
|
62
|
-
message: 'Enter your GitLab token (glpat-...):',
|
|
63
|
-
validate: (value) => {
|
|
64
|
-
if (!value)
|
|
65
|
-
return 'Token is required';
|
|
66
|
-
if (!(0, token_validator_1.isValidTokenFormat)(value, 'gitlab')) {
|
|
67
|
-
return 'Invalid GitLab token format (should start with glpat-)';
|
|
68
|
-
}
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
if (!response.token) {
|
|
73
|
-
throw new Error('GitLab token is required');
|
|
74
|
-
}
|
|
75
|
-
return response.token;
|
|
76
|
-
};
|
|
77
|
-
const promptForADOToken = async () => {
|
|
78
|
-
console.log(chalk_1.default.blue('\nš Azure DevOps Token'));
|
|
79
|
-
console.log(chalk_1.default.gray('Create a token at: https://dev.azure.com/<org>/_usersSettings/tokens'));
|
|
80
|
-
console.log(chalk_1.default.gray('Required scopes: Code (Read & Write), Work Items (Read & Write)\n'));
|
|
81
|
-
const response = await (0, prompts_1.default)({
|
|
82
|
-
type: 'password',
|
|
83
|
-
name: 'token',
|
|
84
|
-
message: 'Enter your Azure DevOps PAT:',
|
|
85
|
-
validate: (value) => {
|
|
86
|
-
if (!value)
|
|
87
|
-
return 'Token is required';
|
|
88
|
-
if (value.length < 20)
|
|
89
|
-
return 'Token seems too short';
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
if (!response.token) {
|
|
94
|
-
throw new Error('Azure DevOps token is required');
|
|
95
|
-
}
|
|
96
|
-
return response.token;
|
|
97
|
-
};
|
|
98
|
-
const promptForJiraCredentials = async (options) => {
|
|
99
|
-
// If all options provided, skip prompts (non-interactive mode)
|
|
100
|
-
if (options.url && options.email && options.token) {
|
|
101
|
-
const baseUrl = options.url.replace(/^https?:\/\//, '').replace(/\/$/, '');
|
|
102
|
-
// Validate token format
|
|
103
|
-
if (!(0, token_validator_1.isValidTokenFormat)(options.token, 'jira')) {
|
|
104
|
-
throw new Error('Invalid Jira token format');
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
baseUrl,
|
|
108
|
-
email: options.email,
|
|
109
|
-
token: options.token
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
console.log(chalk_1.default.blue('\nš Jira Credentials'));
|
|
113
|
-
console.log(chalk_1.default.gray('Create a token at: https://id.atlassian.com/manage-profile/security/api-tokens\n'));
|
|
114
|
-
// Prompt for base URL
|
|
115
|
-
const urlResponse = await (0, prompts_1.default)({
|
|
116
|
-
type: 'text',
|
|
117
|
-
name: 'url',
|
|
118
|
-
message: 'Jira instance URL (e.g., company.atlassian.net):',
|
|
119
|
-
initial: options.url,
|
|
120
|
-
validate: (value) => {
|
|
121
|
-
if (!value)
|
|
122
|
-
return 'URL is required';
|
|
123
|
-
// Remove protocol if provided
|
|
124
|
-
const cleaned = value.replace(/^https?:\/\//, '').replace(/\/$/, '');
|
|
125
|
-
if (!cleaned.includes('.'))
|
|
126
|
-
return 'Invalid URL format';
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
if (!urlResponse.url) {
|
|
131
|
-
throw new Error('Jira URL is required');
|
|
132
|
-
}
|
|
133
|
-
const baseUrl = urlResponse.url.replace(/^https?:\/\//, '').replace(/\/$/, '');
|
|
134
|
-
// Prompt for email
|
|
135
|
-
const emailResponse = await (0, prompts_1.default)({
|
|
136
|
-
type: 'text',
|
|
137
|
-
name: 'email',
|
|
138
|
-
message: 'Jira account email:',
|
|
139
|
-
initial: options.email,
|
|
140
|
-
validate: (value) => {
|
|
141
|
-
if (!value)
|
|
142
|
-
return 'Email is required';
|
|
143
|
-
if (!value.includes('@'))
|
|
144
|
-
return 'Invalid email format';
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
if (!emailResponse.email) {
|
|
149
|
-
throw new Error('Jira email is required');
|
|
150
|
-
}
|
|
151
|
-
// Prompt for token
|
|
152
|
-
const tokenResponse = await (0, prompts_1.default)({
|
|
153
|
-
type: 'password',
|
|
154
|
-
name: 'token',
|
|
155
|
-
message: 'Jira API token:',
|
|
156
|
-
validate: (value) => {
|
|
157
|
-
if (!value)
|
|
158
|
-
return 'Token is required';
|
|
159
|
-
if (!(0, token_validator_1.isValidTokenFormat)(value, 'jira')) {
|
|
160
|
-
return 'Invalid Jira token format';
|
|
161
|
-
}
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
if (!tokenResponse.token) {
|
|
166
|
-
throw new Error('Jira token is required');
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
baseUrl,
|
|
170
|
-
email: emailResponse.email,
|
|
171
|
-
token: tokenResponse.token
|
|
172
|
-
};
|
|
173
|
-
};
|
|
174
35
|
const updateIDEConfigs = async (provider, config) => {
|
|
175
36
|
const detectedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
176
37
|
if (detectedIDEs.length === 0) {
|
|
@@ -183,10 +44,7 @@ const updateIDEConfigs = async (provider, config) => {
|
|
|
183
44
|
gitlab: config.tokens?.gitlab,
|
|
184
45
|
jira: config.tokens?.jira
|
|
185
46
|
};
|
|
186
|
-
const
|
|
187
|
-
baseUrl: config.jiraConfig.baseUrl,
|
|
188
|
-
email: config.jiraConfig.email
|
|
189
|
-
} : undefined;
|
|
47
|
+
const providerConfigs = config.providerConfigs || {};
|
|
190
48
|
for (const ide of detectedIDEs) {
|
|
191
49
|
try {
|
|
192
50
|
const configPath = (0, ide_detector_1.expandPath)(ide.configPath);
|
|
@@ -196,7 +54,7 @@ const updateIDEConfigs = async (provider, config) => {
|
|
|
196
54
|
if (fs_1.default.existsSync(configPath)) {
|
|
197
55
|
ideConfig = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
198
56
|
}
|
|
199
|
-
const mcpConfig = (0, mcp_config_generator_1.generateMCPConfig)(ide.configType, config.apiKey, tokenConfig,
|
|
57
|
+
const mcpConfig = await (0, mcp_config_generator_1.generateMCPConfig)(ide.configType, config.apiKey, tokenConfig, providerConfigs);
|
|
200
58
|
const serversKey = ide.configType === 'vscode' ? 'servers' : 'mcpServers';
|
|
201
59
|
if (!ideConfig[serversKey]) {
|
|
202
60
|
ideConfig[serversKey] = {};
|
|
@@ -211,7 +69,7 @@ const updateIDEConfigs = async (provider, config) => {
|
|
|
211
69
|
}
|
|
212
70
|
else if (ide.configFormat === 'toml') {
|
|
213
71
|
// TOML-based config (Codex, Zed)
|
|
214
|
-
const mcpConfigToml = (0, mcp_config_generator_1.generateMCPConfig)(ide.configType, config.apiKey, tokenConfig,
|
|
72
|
+
const mcpConfigToml = await (0, mcp_config_generator_1.generateMCPConfig)(ide.configType, config.apiKey, tokenConfig, providerConfigs);
|
|
215
73
|
if (fs_1.default.existsSync(configPath)) {
|
|
216
74
|
const existingContent = fs_1.default.readFileSync(configPath, 'utf8');
|
|
217
75
|
// Merge only the new provider's server
|
|
@@ -275,81 +133,63 @@ const runAddProvider = async (provider, options) => {
|
|
|
275
133
|
config.tokens = {};
|
|
276
134
|
}
|
|
277
135
|
// Check if provider already configured
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
136
|
+
const providerName = await (0, provider_registry_1.getProviderDisplayName)(provider);
|
|
137
|
+
const hasExistingConfig = config.tokens[provider] ||
|
|
138
|
+
(provider === 'jira' && config.providerConfigs?.jiraConfig?.baseUrl);
|
|
139
|
+
if (hasExistingConfig) {
|
|
140
|
+
const displayInfo = provider === 'jira' && config.providerConfigs?.jiraConfig?.baseUrl
|
|
141
|
+
? ` (${config.providerConfigs.jiraConfig.baseUrl})`
|
|
142
|
+
: '';
|
|
143
|
+
console.log(chalk_1.default.yellow(`ā ļø ${providerName} is already configured${displayInfo}`));
|
|
144
|
+
// Skip prompt if FRAIM_FORCE_OVERWRITE is set (for testing)
|
|
145
|
+
if (!process.env.FRAIM_FORCE_OVERWRITE) {
|
|
146
|
+
const response = await (0, prompts_1.default)({
|
|
147
|
+
type: 'confirm',
|
|
148
|
+
name: 'overwrite',
|
|
149
|
+
message: `Overwrite existing ${providerName} configuration?`,
|
|
150
|
+
initial: false
|
|
151
|
+
});
|
|
152
|
+
if (!response.overwrite) {
|
|
153
|
+
console.log(chalk_1.default.gray('Cancelled.'));
|
|
154
|
+
process.exit(0);
|
|
293
155
|
}
|
|
294
156
|
}
|
|
295
157
|
}
|
|
296
|
-
|
|
297
|
-
if (config.tokens[provider]) {
|
|
298
|
-
console.log(chalk_1.default.yellow(`ā ļø ${provider.toUpperCase()} token already exists`));
|
|
299
|
-
// Skip prompt if FRAIM_FORCE_OVERWRITE is set (for testing)
|
|
300
|
-
if (!process.env.FRAIM_FORCE_OVERWRITE) {
|
|
301
|
-
const response = await (0, prompts_1.default)({
|
|
302
|
-
type: 'confirm',
|
|
303
|
-
name: 'overwrite',
|
|
304
|
-
message: `Overwrite existing ${provider.toUpperCase()} token?`,
|
|
305
|
-
initial: false
|
|
306
|
-
});
|
|
307
|
-
if (!response.overwrite) {
|
|
308
|
-
console.log(chalk_1.default.gray('Cancelled.'));
|
|
309
|
-
process.exit(0);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
// Get credentials based on provider
|
|
158
|
+
// Get credentials using generic prompt system
|
|
315
159
|
try {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
config.tokens.github = token;
|
|
329
|
-
}
|
|
330
|
-
else if (provider === 'gitlab') {
|
|
331
|
-
const token = options.token || await promptForGitLabToken();
|
|
332
|
-
config.tokens.gitlab = token;
|
|
333
|
-
}
|
|
334
|
-
else if (provider === 'ado') {
|
|
335
|
-
const token = options.token || await promptForADOToken();
|
|
336
|
-
config.tokens.ado = token;
|
|
337
|
-
}
|
|
338
|
-
else if (provider === 'jira') {
|
|
339
|
-
const credentials = await promptForJiraCredentials(options);
|
|
340
|
-
config.tokens.jira = credentials.token;
|
|
341
|
-
config.jiraConfig = {
|
|
342
|
-
baseUrl: credentials.baseUrl,
|
|
343
|
-
email: credentials.email
|
|
160
|
+
// Build provided tokens/configs from CLI options
|
|
161
|
+
const providedTokens = {};
|
|
162
|
+
const providedConfigs = {};
|
|
163
|
+
if (options.token) {
|
|
164
|
+
providedTokens[provider] = options.token;
|
|
165
|
+
}
|
|
166
|
+
// Handle provider-specific config options (e.g., Jira URL and email)
|
|
167
|
+
if (options.url || options.email) {
|
|
168
|
+
providedConfigs[provider] = {
|
|
169
|
+
...(options.url && { baseUrl: options.url.replace(/^https?:\/\//, '').replace(/\/$/, '') }),
|
|
170
|
+
...(options.email && { email: options.email })
|
|
344
171
|
};
|
|
345
172
|
}
|
|
173
|
+
// Get credentials using generic prompt system
|
|
174
|
+
const client = (0, get_provider_client_1.getProviderClient)();
|
|
175
|
+
const creds = await (0, provider_prompts_1.promptForProviderCredentials)(client, provider, providedTokens[provider], providedConfigs[provider]);
|
|
176
|
+
// Save token
|
|
177
|
+
config.tokens[provider] = creds.token;
|
|
178
|
+
// Save provider-specific config if present
|
|
179
|
+
if (creds.config) {
|
|
180
|
+
if (!config.providerConfigs) {
|
|
181
|
+
config.providerConfigs = {};
|
|
182
|
+
}
|
|
183
|
+
config.providerConfigs[`${provider}Config`] = creds.config;
|
|
184
|
+
}
|
|
346
185
|
// Save updated config
|
|
347
186
|
saveGlobalConfig(config);
|
|
348
|
-
console.log(chalk_1.default.green(`\nā
${
|
|
187
|
+
console.log(chalk_1.default.green(`\nā
${providerName} credentials saved to global config`));
|
|
349
188
|
// Update IDE configs
|
|
350
189
|
await updateIDEConfigs(provider, config);
|
|
351
|
-
// Offer mode switch if adding
|
|
352
|
-
|
|
190
|
+
// Offer mode switch if adding a provider with issues capability
|
|
191
|
+
const providerDef = await (0, provider_registry_1.getProvider)(provider);
|
|
192
|
+
if (providerDef?.capabilities.includes('issues') && provider === 'jira') {
|
|
353
193
|
await offerModeSwitch(config);
|
|
354
194
|
}
|
|
355
195
|
console.log(chalk_1.default.green('\nš Provider added successfully!'));
|
|
@@ -366,17 +206,17 @@ const runAddProvider = async (provider, options) => {
|
|
|
366
206
|
};
|
|
367
207
|
exports.runAddProvider = runAddProvider;
|
|
368
208
|
exports.addProviderCommand = new commander_1.Command('add-provider')
|
|
369
|
-
.description(
|
|
370
|
-
.argument('<provider>',
|
|
209
|
+
.description(`Add or update a provider after initial setup`)
|
|
210
|
+
.argument('<provider>', `Provider to add`)
|
|
371
211
|
.option('--token <token>', 'Provider token (will prompt if not provided)')
|
|
372
|
-
.option('--email <email>', 'Email (
|
|
373
|
-
.option('--url <url>', 'Instance URL (
|
|
374
|
-
.option('--no-validate', 'Skip token validation
|
|
212
|
+
.option('--email <email>', 'Email (for providers that require it)')
|
|
213
|
+
.option('--url <url>', 'Instance URL (for providers that require it)')
|
|
214
|
+
.option('--no-validate', 'Skip token validation')
|
|
375
215
|
.action(async (provider, options) => {
|
|
376
|
-
|
|
377
|
-
|
|
216
|
+
if (!(await (0, provider_registry_1.isValidProviderId)(provider))) {
|
|
217
|
+
const allProviderIds = await (0, provider_registry_1.getAllProviderIds)();
|
|
378
218
|
console.log(chalk_1.default.red(`ā Invalid provider: ${provider}`));
|
|
379
|
-
console.log(chalk_1.default.yellow(`Valid providers: ${
|
|
219
|
+
console.log(chalk_1.default.yellow(`Valid providers: ${allProviderIds.join(', ')}`));
|
|
380
220
|
process.exit(1);
|
|
381
221
|
}
|
|
382
222
|
await (0, exports.runAddProvider)(provider, options);
|
|
@@ -129,13 +129,16 @@ exports.doctorCommand = new commander_1.Command('doctor')
|
|
|
129
129
|
else {
|
|
130
130
|
console.log((0, console_reporter_1.formatConsoleOutput)(result, options));
|
|
131
131
|
}
|
|
132
|
-
// Set exit code
|
|
132
|
+
// Set exit code based on results
|
|
133
133
|
if (result.summary.errors > 0) {
|
|
134
134
|
process.exit(2);
|
|
135
135
|
}
|
|
136
136
|
else if (result.summary.warnings > 0) {
|
|
137
137
|
process.exit(1);
|
|
138
138
|
}
|
|
139
|
+
else {
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
139
142
|
}
|
|
140
143
|
catch (error) {
|
|
141
144
|
const duration = Date.now() - startTime;
|
|
@@ -15,6 +15,7 @@ const platform_detection_1 = require("../utils/platform-detection");
|
|
|
15
15
|
const version_utils_1 = require("../utils/version-utils");
|
|
16
16
|
const ide_detector_1 = require("../setup/ide-detector");
|
|
17
17
|
const codex_local_config_1 = require("../setup/codex-local-config");
|
|
18
|
+
const provider_registry_1 = require("../providers/provider-registry");
|
|
18
19
|
const promptForJiraProjectKey = async (jiraBaseUrl) => {
|
|
19
20
|
console.log(chalk_1.default.blue('\nš« Jira Project Configuration'));
|
|
20
21
|
console.log(chalk_1.default.gray(`Jira instance: ${jiraBaseUrl}`));
|
|
@@ -51,7 +52,7 @@ const checkGlobalSetup = () => {
|
|
|
51
52
|
exists: true,
|
|
52
53
|
mode: config.mode || 'integrated',
|
|
53
54
|
tokens: config.tokens || {},
|
|
54
|
-
|
|
55
|
+
providerConfigs: config.providerConfigs || {}
|
|
55
56
|
};
|
|
56
57
|
}
|
|
57
58
|
catch {
|
|
@@ -98,41 +99,27 @@ const runInitProject = async () => {
|
|
|
98
99
|
// Determine issue tracking configuration
|
|
99
100
|
let issueTracking;
|
|
100
101
|
// In split mode with Jira configured, use Jira for issue tracking
|
|
101
|
-
|
|
102
|
+
const jiraConfig = globalSetup.providerConfigs?.jiraConfig;
|
|
103
|
+
if (preferredMode === 'split' && globalSetup.tokens?.jira && jiraConfig?.baseUrl) {
|
|
102
104
|
// Prompt for Jira project key (project-specific)
|
|
103
105
|
const projectKey = process.env.FRAIM_JIRA_PROJECT_KEY ||
|
|
104
|
-
await promptForJiraProjectKey(
|
|
106
|
+
await promptForJiraProjectKey(jiraConfig.baseUrl);
|
|
105
107
|
issueTracking = {
|
|
106
108
|
provider: 'jira',
|
|
107
|
-
baseUrl:
|
|
109
|
+
baseUrl: jiraConfig.baseUrl,
|
|
108
110
|
projectKey: projectKey,
|
|
109
|
-
email:
|
|
111
|
+
email: jiraConfig.email
|
|
110
112
|
};
|
|
111
113
|
console.log(chalk_1.default.blue(` Code Repository: ${detection.provider.toUpperCase()}`));
|
|
112
114
|
console.log(chalk_1.default.blue(` Issue Tracking: JIRA (${projectKey})`));
|
|
113
115
|
}
|
|
114
116
|
else {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
: detection.provider === 'ado'
|
|
123
|
-
? {
|
|
124
|
-
provider: 'ado',
|
|
125
|
-
organization: detection.repository.organization,
|
|
126
|
-
project: detection.repository.project,
|
|
127
|
-
name: detection.repository.name
|
|
128
|
-
}
|
|
129
|
-
: {
|
|
130
|
-
provider: 'gitlab',
|
|
131
|
-
namespace: detection.repository.namespace,
|
|
132
|
-
name: detection.repository.name,
|
|
133
|
-
projectPath: detection.repository.projectPath
|
|
134
|
-
};
|
|
135
|
-
console.log(chalk_1.default.blue(` Platform: ${detection.provider.toUpperCase()}`));
|
|
117
|
+
issueTracking = {
|
|
118
|
+
provider: detection.provider,
|
|
119
|
+
...detection.repository
|
|
120
|
+
};
|
|
121
|
+
const providerDef = await (0, provider_registry_1.getProvider)(detection.provider);
|
|
122
|
+
console.log(chalk_1.default.blue(` Platform: ${providerDef?.displayName || detection.provider.toUpperCase()}`));
|
|
136
123
|
}
|
|
137
124
|
config = {
|
|
138
125
|
version: (0, version_utils_1.getFraimVersion)(),
|
|
@@ -143,17 +130,19 @@ const runInitProject = async () => {
|
|
|
143
130
|
issueTracking,
|
|
144
131
|
customizations: {}
|
|
145
132
|
};
|
|
146
|
-
|
|
147
|
-
|
|
133
|
+
// Display repository info based on available fields
|
|
134
|
+
const repo = detection.repository;
|
|
135
|
+
if (repo.owner && repo.name) {
|
|
136
|
+
console.log(chalk_1.default.gray(` Repository: ${repo.owner}/${repo.name}`));
|
|
148
137
|
}
|
|
149
|
-
else if (
|
|
150
|
-
console.log(chalk_1.default.gray(` Organization: ${
|
|
151
|
-
console.log(chalk_1.default.gray(` Project: ${
|
|
152
|
-
console.log(chalk_1.default.gray(` Repository: ${
|
|
138
|
+
else if (repo.organization && repo.project && repo.name) {
|
|
139
|
+
console.log(chalk_1.default.gray(` Organization: ${repo.organization}`));
|
|
140
|
+
console.log(chalk_1.default.gray(` Project: ${repo.project}`));
|
|
141
|
+
console.log(chalk_1.default.gray(` Repository: ${repo.name}`));
|
|
153
142
|
}
|
|
154
|
-
else if (
|
|
155
|
-
console.log(chalk_1.default.gray(` Namespace: ${
|
|
156
|
-
console.log(chalk_1.default.gray(` Repository: ${
|
|
143
|
+
else if (repo.namespace && repo.name) {
|
|
144
|
+
console.log(chalk_1.default.gray(` Namespace: ${repo.namespace || '(none)'}`));
|
|
145
|
+
console.log(chalk_1.default.gray(` Repository: ${repo.name}`));
|
|
157
146
|
}
|
|
158
147
|
}
|
|
159
148
|
else {
|