proagents 1.6.7 → 1.6.9
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/lib/commands/ai.js +148 -19
- package/lib/commands/config.js +39 -12
- package/lib/commands/init.js +213 -25
- package/lib/commands/uninstall.js +63 -6
- package/package.json +1 -1
package/lib/commands/ai.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, cpSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
1
|
+
import { existsSync, cpSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
|
|
2
2
|
import { join, dirname } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { createInterface } from 'readline';
|
|
@@ -49,8 +49,9 @@ export function getPlatformById(id) {
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Interactive platform selection using readline
|
|
52
|
+
* @param {string[]} previouslySelected - Previously selected platforms (from interrupted setup)
|
|
52
53
|
*/
|
|
53
|
-
export async function selectPlatforms() {
|
|
54
|
+
export async function selectPlatforms(previouslySelected = []) {
|
|
54
55
|
const rl = createInterface({
|
|
55
56
|
input: process.stdin,
|
|
56
57
|
output: process.stdout
|
|
@@ -63,12 +64,16 @@ export async function selectPlatforms() {
|
|
|
63
64
|
|
|
64
65
|
let index = 1;
|
|
65
66
|
const indexMap = {};
|
|
67
|
+
const preSelectedIndices = [];
|
|
66
68
|
|
|
67
69
|
// IDE-based platforms
|
|
68
70
|
console.log(chalk.cyan.bold(` ${AI_PLATFORMS.ide.label}:`));
|
|
69
71
|
for (const platform of AI_PLATFORMS.ide.platforms) {
|
|
70
|
-
|
|
72
|
+
const wasSelected = previouslySelected && previouslySelected.includes(platform.id);
|
|
73
|
+
const marker = wasSelected ? chalk.green(' ✓ (previously selected)') : '';
|
|
74
|
+
console.log(chalk.white(` ${index}. ${platform.name}`) + chalk.gray(` - ${platform.desc}`) + marker);
|
|
71
75
|
indexMap[index] = platform.id;
|
|
76
|
+
if (wasSelected) preSelectedIndices.push(index);
|
|
72
77
|
index++;
|
|
73
78
|
}
|
|
74
79
|
|
|
@@ -77,16 +82,29 @@ export async function selectPlatforms() {
|
|
|
77
82
|
// Web-based platforms
|
|
78
83
|
console.log(chalk.cyan.bold(` ${AI_PLATFORMS.web.label}:`));
|
|
79
84
|
for (const platform of AI_PLATFORMS.web.platforms) {
|
|
80
|
-
|
|
85
|
+
const wasSelected = previouslySelected && previouslySelected.includes(platform.id);
|
|
86
|
+
const marker = wasSelected ? chalk.green(' ✓ (previously selected)') : '';
|
|
87
|
+
console.log(chalk.white(` ${index}. ${platform.name}`) + chalk.gray(` - ${platform.desc}`) + marker);
|
|
81
88
|
indexMap[index] = platform.id;
|
|
89
|
+
if (wasSelected) preSelectedIndices.push(index);
|
|
82
90
|
index++;
|
|
83
91
|
}
|
|
84
92
|
|
|
85
93
|
console.log('');
|
|
86
94
|
|
|
87
|
-
|
|
95
|
+
// Show default based on previous selection
|
|
96
|
+
const defaultHint = preSelectedIndices.length > 0
|
|
97
|
+
? `Enter for previous: ${preSelectedIndices.join(',')}`
|
|
98
|
+
: 'e.g., 1,2,3 or "all"';
|
|
99
|
+
|
|
100
|
+
const answer = await question(chalk.yellow(`Your selection (${defaultHint}): `));
|
|
88
101
|
rl.close();
|
|
89
102
|
|
|
103
|
+
// If user just pressed enter and we have previous selections, use them
|
|
104
|
+
if (answer.trim() === '' && preSelectedIndices.length > 0) {
|
|
105
|
+
return previouslySelected;
|
|
106
|
+
}
|
|
107
|
+
|
|
90
108
|
if (answer.toLowerCase() === 'all') {
|
|
91
109
|
return getAllPlatforms().map(p => p.id);
|
|
92
110
|
}
|
|
@@ -131,6 +149,46 @@ function extractProagentsSection(content) {
|
|
|
131
149
|
return null;
|
|
132
150
|
}
|
|
133
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Remove only ProAgents section from a file, keep user's original content
|
|
154
|
+
* Returns: 'deleted' (file removed), 'cleaned' (section removed), 'skipped' (no ProAgents section)
|
|
155
|
+
*/
|
|
156
|
+
function removeProagentsSectionFromFile(filePath) {
|
|
157
|
+
try {
|
|
158
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
159
|
+
|
|
160
|
+
const startIndex = content.indexOf(PROAGENTS_START);
|
|
161
|
+
const endIndex = content.indexOf(PROAGENTS_END);
|
|
162
|
+
|
|
163
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
164
|
+
// Has ProAgents section - remove it, keep the rest
|
|
165
|
+
const before = content.substring(0, startIndex).trim();
|
|
166
|
+
const after = content.substring(endIndex + PROAGENTS_END.length).trim();
|
|
167
|
+
const remaining = (before + '\n\n' + after).trim();
|
|
168
|
+
|
|
169
|
+
if (remaining.length === 0) {
|
|
170
|
+
// File only had ProAgents content - delete it
|
|
171
|
+
rmSync(filePath, { force: true });
|
|
172
|
+
return 'deleted';
|
|
173
|
+
} else {
|
|
174
|
+
// File has other content - keep it, remove only ProAgents section
|
|
175
|
+
writeFileSync(filePath, remaining + '\n');
|
|
176
|
+
return 'cleaned';
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
// No ProAgents markers - file was created by ProAgents (not merged)
|
|
180
|
+
// Check if it's a ProAgents-generated file by looking for ProAgents reference
|
|
181
|
+
if (content.includes('proagents') || content.includes('ProAgents') || content.includes('.proagents/')) {
|
|
182
|
+
rmSync(filePath, { force: true });
|
|
183
|
+
return 'deleted';
|
|
184
|
+
}
|
|
185
|
+
return 'skipped';
|
|
186
|
+
}
|
|
187
|
+
} catch (error) {
|
|
188
|
+
return 'skipped';
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
134
192
|
/**
|
|
135
193
|
* Merge ProAgents instructions with existing file content
|
|
136
194
|
* - If file doesn't exist: create with ProAgents content
|
|
@@ -247,6 +305,51 @@ export function loadPlatformConfig(configPath) {
|
|
|
247
305
|
}
|
|
248
306
|
}
|
|
249
307
|
|
|
308
|
+
/**
|
|
309
|
+
* Check if a file contains ProAgents content
|
|
310
|
+
*/
|
|
311
|
+
function hasProagentsContent(filePath) {
|
|
312
|
+
try {
|
|
313
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
314
|
+
// Check for ProAgents markers or references
|
|
315
|
+
return content.includes(PROAGENTS_START) ||
|
|
316
|
+
content.includes('.proagents/') ||
|
|
317
|
+
content.includes('ProAgents Commands');
|
|
318
|
+
} catch {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Detect installed platforms by checking for actual files with ProAgents content
|
|
325
|
+
* Only counts as installed if the file has ProAgents-related content
|
|
326
|
+
*/
|
|
327
|
+
export function detectInstalledPlatforms(targetDir) {
|
|
328
|
+
const installed = [];
|
|
329
|
+
|
|
330
|
+
for (const platform of getAllPlatforms()) {
|
|
331
|
+
const filePath = join(targetDir, platform.file);
|
|
332
|
+
if (existsSync(filePath) && hasProagentsContent(filePath)) {
|
|
333
|
+
installed.push(platform.id);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return installed;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Get installed platforms - combines config and file detection
|
|
342
|
+
* Returns platforms that are either in config OR have files present
|
|
343
|
+
*/
|
|
344
|
+
export function getInstalledPlatforms(targetDir, configPath) {
|
|
345
|
+
const fromConfig = loadPlatformConfig(configPath);
|
|
346
|
+
const fromFiles = detectInstalledPlatforms(targetDir);
|
|
347
|
+
|
|
348
|
+
// Merge both sources, remove duplicates
|
|
349
|
+
const combined = [...new Set([...fromConfig, ...fromFiles])];
|
|
350
|
+
return combined;
|
|
351
|
+
}
|
|
352
|
+
|
|
250
353
|
/**
|
|
251
354
|
* Show available platforms that can be added
|
|
252
355
|
*/
|
|
@@ -294,7 +397,7 @@ export async function aiAddCommand() {
|
|
|
294
397
|
const targetDir = process.cwd();
|
|
295
398
|
const proagentsDir = join(targetDir, '.proagents');
|
|
296
399
|
const sourceDir = join(__dirname, '..', '..', '.proagents');
|
|
297
|
-
const configPath = join(
|
|
400
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
298
401
|
|
|
299
402
|
// Check if proagents is initialized
|
|
300
403
|
if (!existsSync(proagentsDir)) {
|
|
@@ -302,8 +405,8 @@ export async function aiAddCommand() {
|
|
|
302
405
|
return;
|
|
303
406
|
}
|
|
304
407
|
|
|
305
|
-
//
|
|
306
|
-
const currentIds =
|
|
408
|
+
// Detect from both config AND actual files
|
|
409
|
+
const currentIds = getInstalledPlatforms(targetDir, configPath);
|
|
307
410
|
|
|
308
411
|
console.log(chalk.bold.blue('\nProAgents - Add AI Platform'));
|
|
309
412
|
console.log(chalk.blue('===========================\n'));
|
|
@@ -361,7 +464,7 @@ export async function aiAddCommand() {
|
|
|
361
464
|
}
|
|
362
465
|
|
|
363
466
|
console.log(chalk.gray('\nAI instruction files added to project root.'));
|
|
364
|
-
console.log(chalk.gray('Config updated in
|
|
467
|
+
console.log(chalk.gray('Config updated in proagents.config.yaml\n'));
|
|
365
468
|
}
|
|
366
469
|
|
|
367
470
|
/**
|
|
@@ -370,9 +473,10 @@ export async function aiAddCommand() {
|
|
|
370
473
|
export function aiListCommand() {
|
|
371
474
|
const targetDir = process.cwd();
|
|
372
475
|
const proagentsDir = join(targetDir, '.proagents');
|
|
373
|
-
const configPath = join(
|
|
476
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
374
477
|
|
|
375
|
-
|
|
478
|
+
// Detect from both config AND actual files
|
|
479
|
+
const currentIds = getInstalledPlatforms(targetDir, configPath);
|
|
376
480
|
|
|
377
481
|
console.log(chalk.bold.blue('\nProAgents - AI Platforms'));
|
|
378
482
|
console.log(chalk.blue('========================\n'));
|
|
@@ -387,17 +491,18 @@ export function aiListCommand() {
|
|
|
387
491
|
export async function aiRemoveCommand() {
|
|
388
492
|
const targetDir = process.cwd();
|
|
389
493
|
const proagentsDir = join(targetDir, '.proagents');
|
|
390
|
-
const configPath = join(
|
|
494
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
391
495
|
|
|
392
496
|
if (!existsSync(proagentsDir)) {
|
|
393
497
|
console.log(chalk.red('\n✗ ProAgents not initialized.\n'));
|
|
394
498
|
return;
|
|
395
499
|
}
|
|
396
500
|
|
|
397
|
-
|
|
501
|
+
// Detect from both config AND actual files
|
|
502
|
+
const currentIds = getInstalledPlatforms(targetDir, configPath);
|
|
398
503
|
|
|
399
504
|
if (currentIds.length === 0) {
|
|
400
|
-
console.log(chalk.yellow('\nNo AI platforms
|
|
505
|
+
console.log(chalk.yellow('\nNo AI platforms installed.\n'));
|
|
401
506
|
return;
|
|
402
507
|
}
|
|
403
508
|
|
|
@@ -443,12 +548,36 @@ export async function aiRemoveCommand() {
|
|
|
443
548
|
return;
|
|
444
549
|
}
|
|
445
550
|
|
|
446
|
-
// Remove from config
|
|
551
|
+
// Remove from config
|
|
447
552
|
const newIds = currentIds.filter(id => !toRemove.includes(id));
|
|
448
553
|
savePlatformConfig(newIds, configPath);
|
|
449
554
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
555
|
+
// Remove ProAgents sections from AI files (smart removal - keeps user content)
|
|
556
|
+
const results = { deleted: [], cleaned: [], skipped: [] };
|
|
557
|
+
|
|
558
|
+
for (const id of toRemove) {
|
|
559
|
+
const platform = getPlatformById(id);
|
|
560
|
+
if (!platform) continue;
|
|
561
|
+
|
|
562
|
+
const filePath = join(targetDir, platform.file);
|
|
563
|
+
if (existsSync(filePath)) {
|
|
564
|
+
const result = removeProagentsSectionFromFile(filePath);
|
|
565
|
+
if (result === 'deleted') {
|
|
566
|
+
results.deleted.push(platform.name);
|
|
567
|
+
} else if (result === 'cleaned') {
|
|
568
|
+
results.cleaned.push(platform.name);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Show results
|
|
574
|
+
console.log('');
|
|
575
|
+
if (results.deleted.length > 0) {
|
|
576
|
+
console.log(chalk.green(`✓ Removed: ${results.deleted.join(', ')}`));
|
|
577
|
+
}
|
|
578
|
+
if (results.cleaned.length > 0) {
|
|
579
|
+
console.log(chalk.green(`✓ Cleaned ProAgents section from: ${results.cleaned.join(', ')} (kept your custom config)`));
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
console.log(chalk.gray('\nConfig updated in proagents.config.yaml\n'));
|
|
454
583
|
}
|
package/lib/commands/config.js
CHANGED
|
@@ -28,12 +28,12 @@ export function configListCommand() {
|
|
|
28
28
|
// 1. Main Config
|
|
29
29
|
console.log(chalk.cyan.bold('1. Main Configuration'));
|
|
30
30
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
31
|
-
const configPath = join(
|
|
31
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
32
32
|
if (existsSync(configPath)) {
|
|
33
|
-
console.log(chalk.green(' ✓ ') + chalk.white('
|
|
33
|
+
console.log(chalk.green(' ✓ ') + chalk.white('proagents.config.yaml'));
|
|
34
34
|
console.log(chalk.gray(' Checkpoints, git settings, parallel features, etc.\n'));
|
|
35
35
|
} else {
|
|
36
|
-
console.log(chalk.yellow(' ○ ') + chalk.white('
|
|
36
|
+
console.log(chalk.yellow(' ○ ') + chalk.white('proagents.config.yaml') + chalk.gray(' (not created)\n'));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// 2. AI Platforms
|
|
@@ -184,7 +184,7 @@ export function configListCommand() {
|
|
|
184
184
|
*/
|
|
185
185
|
export function configShowCommand() {
|
|
186
186
|
const targetDir = process.cwd();
|
|
187
|
-
const configPath = join(targetDir, '
|
|
187
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
188
188
|
|
|
189
189
|
console.log('\n' + chalk.bold.blue('ProAgents Current Configuration'));
|
|
190
190
|
console.log(chalk.blue('================================\n'));
|
|
@@ -198,7 +198,7 @@ export function configShowCommand() {
|
|
|
198
198
|
const content = readFileSync(configPath, 'utf-8');
|
|
199
199
|
const config = yaml.load(content);
|
|
200
200
|
|
|
201
|
-
console.log(chalk.cyan('File: ') + chalk.white('
|
|
201
|
+
console.log(chalk.cyan('File: ') + chalk.white('proagents.config.yaml\n'));
|
|
202
202
|
console.log(chalk.gray('─────────────────────────────────────────────\n'));
|
|
203
203
|
console.log(content);
|
|
204
204
|
} catch (error) {
|
|
@@ -212,7 +212,7 @@ export function configShowCommand() {
|
|
|
212
212
|
*/
|
|
213
213
|
export function configEditCommand() {
|
|
214
214
|
const targetDir = process.cwd();
|
|
215
|
-
const configPath = join(targetDir, '
|
|
215
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
216
216
|
|
|
217
217
|
if (!existsSync(configPath)) {
|
|
218
218
|
console.log(chalk.yellow('\nConfig file not found. Run "proagents init" first.\n'));
|
|
@@ -220,7 +220,7 @@ export function configEditCommand() {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
console.log(chalk.cyan('\nTo edit configuration:\n'));
|
|
223
|
-
console.log(chalk.white(' Open: ') + chalk.green('
|
|
223
|
+
console.log(chalk.white(' Open: ') + chalk.green('proagents.config.yaml'));
|
|
224
224
|
console.log(chalk.white(' Docs: ') + chalk.green('.proagents/config/README.md\n'));
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -261,7 +261,7 @@ function parseValue(value) {
|
|
|
261
261
|
*/
|
|
262
262
|
export function configSetCommand(key, value) {
|
|
263
263
|
const targetDir = process.cwd();
|
|
264
|
-
const configPath = join(targetDir, '
|
|
264
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
265
265
|
|
|
266
266
|
console.log('');
|
|
267
267
|
|
|
@@ -297,7 +297,7 @@ export function configSetCommand(key, value) {
|
|
|
297
297
|
*/
|
|
298
298
|
export function configGetCommand(key) {
|
|
299
299
|
const targetDir = process.cwd();
|
|
300
|
-
const configPath = join(targetDir, '
|
|
300
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
301
301
|
|
|
302
302
|
console.log('');
|
|
303
303
|
|
|
@@ -324,13 +324,25 @@ export function configGetCommand(key) {
|
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Save config setup progress (for resume after interrupt)
|
|
329
|
+
*/
|
|
330
|
+
function saveSetupProgress(configPath, config, step) {
|
|
331
|
+
config._config_setup = {
|
|
332
|
+
last_step: step,
|
|
333
|
+
timestamp: new Date().toISOString()
|
|
334
|
+
};
|
|
335
|
+
const yamlContent = yaml.dump(config, { indent: 2, lineWidth: 120 });
|
|
336
|
+
writeFileSync(configPath, yamlContent);
|
|
337
|
+
}
|
|
338
|
+
|
|
327
339
|
/**
|
|
328
340
|
* Command: proagents config setup
|
|
329
341
|
* Interactive wizard for main configuration
|
|
330
342
|
*/
|
|
331
343
|
export async function configSetupCommand() {
|
|
332
344
|
const targetDir = process.cwd();
|
|
333
|
-
const configPath = join(targetDir, '
|
|
345
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
334
346
|
|
|
335
347
|
console.log('\n' + chalk.bold.blue('ProAgents Configuration Wizard'));
|
|
336
348
|
console.log(chalk.blue('===============================\n'));
|
|
@@ -366,15 +378,22 @@ export async function configSetupCommand() {
|
|
|
366
378
|
config = yaml.load(readFileSync(configPath, 'utf-8')) || {};
|
|
367
379
|
}
|
|
368
380
|
|
|
381
|
+
// Check for interrupted setup
|
|
382
|
+
if (config._config_setup) {
|
|
383
|
+
console.log(chalk.cyan('📋 Resuming with your previous choices...\n'));
|
|
384
|
+
}
|
|
385
|
+
|
|
369
386
|
console.log(chalk.cyan('Project Settings\n'));
|
|
370
387
|
|
|
371
388
|
// Project settings
|
|
372
389
|
config.project = config.project || {};
|
|
373
390
|
config.project.name = await question('Project name', config.project.name || 'My Project');
|
|
391
|
+
saveSetupProgress(configPath, config, 'project_name');
|
|
374
392
|
|
|
375
393
|
const projectTypes = ['web-frontend', 'fullstack', 'mobile', 'backend'];
|
|
376
394
|
console.log(chalk.gray(' Types: ' + projectTypes.join(', ')));
|
|
377
395
|
config.project.type = await question('Project type', config.project.type || 'fullstack');
|
|
396
|
+
saveSetupProgress(configPath, config, 'project_type');
|
|
378
397
|
|
|
379
398
|
console.log('\n' + chalk.cyan('Checkpoints (pause for approval)\n'));
|
|
380
399
|
|
|
@@ -386,12 +405,14 @@ export async function configSetupCommand() {
|
|
|
386
405
|
config.checkpoints.after_implementation = await yesNo('Pause after implementation?', config.checkpoints.after_implementation ?? false);
|
|
387
406
|
config.checkpoints.after_testing = await yesNo('Pause after testing?', config.checkpoints.after_testing ?? false);
|
|
388
407
|
config.checkpoints.before_deployment = await yesNo('Pause before deployment?', config.checkpoints.before_deployment ?? true);
|
|
408
|
+
saveSetupProgress(configPath, config, 'checkpoints');
|
|
389
409
|
|
|
390
410
|
console.log('\n' + chalk.cyan('Git Settings\n'));
|
|
391
411
|
|
|
392
412
|
// Git settings
|
|
393
413
|
config.git = config.git || {};
|
|
394
414
|
config.git.enabled = await yesNo('Enable git integration?', config.git.enabled ?? true);
|
|
415
|
+
saveSetupProgress(configPath, config, 'git_enabled');
|
|
395
416
|
|
|
396
417
|
if (config.git.enabled) {
|
|
397
418
|
config.git.branch_prefix = await question('Branch prefix', config.git.branch_prefix || 'feature/');
|
|
@@ -400,6 +421,7 @@ export async function configSetupCommand() {
|
|
|
400
421
|
console.log(chalk.gray(' Conventions: ' + conventions.join(', ')));
|
|
401
422
|
config.git.commit_convention = await question('Commit convention', config.git.commit_convention || 'conventional');
|
|
402
423
|
config.git.require_pr = await yesNo('Require pull requests?', config.git.require_pr ?? true);
|
|
424
|
+
saveSetupProgress(configPath, config, 'git');
|
|
403
425
|
}
|
|
404
426
|
|
|
405
427
|
console.log('\n' + chalk.cyan('Parallel Features\n'));
|
|
@@ -407,20 +429,25 @@ export async function configSetupCommand() {
|
|
|
407
429
|
// Parallel features
|
|
408
430
|
config.parallel_features = config.parallel_features || {};
|
|
409
431
|
config.parallel_features.enabled = await yesNo('Enable parallel features?', config.parallel_features.enabled ?? true);
|
|
432
|
+
saveSetupProgress(configPath, config, 'parallel_enabled');
|
|
410
433
|
|
|
411
434
|
if (config.parallel_features.enabled) {
|
|
412
435
|
const maxStr = await question('Max concurrent features', String(config.parallel_features.max_concurrent || 3));
|
|
413
436
|
config.parallel_features.max_concurrent = parseInt(maxStr) || 3;
|
|
437
|
+
saveSetupProgress(configPath, config, 'parallel');
|
|
414
438
|
}
|
|
415
439
|
|
|
416
440
|
rl.close();
|
|
417
441
|
|
|
418
|
-
//
|
|
442
|
+
// Remove setup progress marker (setup complete)
|
|
443
|
+
delete config._config_setup;
|
|
444
|
+
|
|
445
|
+
// Save final config
|
|
419
446
|
const header = `# ProAgents Configuration\n# Generated by setup wizard\n# Last updated: ${new Date().toISOString().split('T')[0]}\n\n`;
|
|
420
447
|
const yamlContent = yaml.dump(config, { indent: 2, lineWidth: 120 });
|
|
421
448
|
writeFileSync(configPath, header + yamlContent);
|
|
422
449
|
|
|
423
|
-
console.log(chalk.green('\n✓ Configuration saved to proagents
|
|
450
|
+
console.log(chalk.green('\n✓ Configuration saved to proagents.config.yaml\n'));
|
|
424
451
|
|
|
425
452
|
} catch (error) {
|
|
426
453
|
rl.close();
|
package/lib/commands/init.js
CHANGED
|
@@ -595,6 +595,77 @@ function detectProjectType(targetDir) {
|
|
|
595
595
|
return detectedTypes;
|
|
596
596
|
}
|
|
597
597
|
|
|
598
|
+
/**
|
|
599
|
+
* Check if setup was interrupted (incomplete)
|
|
600
|
+
* Returns true if .proagents exists but setup wasn't completed
|
|
601
|
+
*/
|
|
602
|
+
function checkIncompleteSetup(targetDir) {
|
|
603
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
604
|
+
const readmePath = join(targetDir, 'README.md');
|
|
605
|
+
const gitignorePath = join(targetDir, '.gitignore');
|
|
606
|
+
|
|
607
|
+
// Check 1: No config file in root = incomplete
|
|
608
|
+
if (!existsSync(configPath)) {
|
|
609
|
+
return true;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Check 2: No AI instruction files at all = incomplete
|
|
613
|
+
const aiFiles = ['CLAUDE.md', '.cursorrules', '.windsurfrules', 'CHATGPT.md', 'GEMINI.md'];
|
|
614
|
+
const hasAnyAiFile = aiFiles.some(f => existsSync(join(targetDir, f)));
|
|
615
|
+
if (!hasAnyAiFile) {
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Check 3: README exists but no ProAgents section = incomplete
|
|
620
|
+
if (existsSync(readmePath)) {
|
|
621
|
+
const readmeContent = readFileSync(readmePath, 'utf-8');
|
|
622
|
+
if (!readmeContent.includes('PROAGENTS:START')) {
|
|
623
|
+
return true;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Check 4: .gitignore exists but no proagents entry = incomplete
|
|
628
|
+
if (existsSync(gitignorePath)) {
|
|
629
|
+
const gitignoreContent = readFileSync(gitignorePath, 'utf-8');
|
|
630
|
+
if (!gitignoreContent.includes('.proagents')) {
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Prompt user for what to do with incomplete setup
|
|
640
|
+
*/
|
|
641
|
+
async function promptIncompleteSetupChoice() {
|
|
642
|
+
const rl = createInterface({
|
|
643
|
+
input: process.stdin,
|
|
644
|
+
output: process.stdout
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
const question = (prompt) => new Promise(resolve => rl.question(prompt, resolve));
|
|
648
|
+
|
|
649
|
+
console.log(chalk.cyan('What would you like to do?'));
|
|
650
|
+
console.log(chalk.white(' 1. Continue setup') + chalk.green(' (recommended)'));
|
|
651
|
+
console.log(chalk.gray(' Complete the remaining setup steps'));
|
|
652
|
+
console.log('');
|
|
653
|
+
console.log(chalk.white(' 2. Restart fresh'));
|
|
654
|
+
console.log(chalk.gray(' Remove everything and start over'));
|
|
655
|
+
console.log('');
|
|
656
|
+
console.log(chalk.white(' 3. Update only'));
|
|
657
|
+
console.log(chalk.gray(' Just update framework files, skip setup'));
|
|
658
|
+
console.log('');
|
|
659
|
+
|
|
660
|
+
const choice = await question(chalk.yellow(' Choose (1, 2, or 3, default=1): '));
|
|
661
|
+
rl.close();
|
|
662
|
+
|
|
663
|
+
const trimmed = choice.trim();
|
|
664
|
+
if (trimmed === '2') return 'restart';
|
|
665
|
+
if (trimmed === '3') return 'update';
|
|
666
|
+
return 'continue';
|
|
667
|
+
}
|
|
668
|
+
|
|
598
669
|
/**
|
|
599
670
|
* Prompt user for .gitignore preference
|
|
600
671
|
*/
|
|
@@ -626,8 +697,10 @@ async function promptGitignoreChoice() {
|
|
|
626
697
|
|
|
627
698
|
/**
|
|
628
699
|
* Interactive prompt for project configuration
|
|
700
|
+
* @param {string} targetDir - The target directory
|
|
701
|
+
* @param {object} existingConfig - Existing partial config from interrupted setup
|
|
629
702
|
*/
|
|
630
|
-
async function promptProjectConfig(targetDir) {
|
|
703
|
+
async function promptProjectConfig(targetDir, existingConfig = {}) {
|
|
631
704
|
const rl = createInterface({
|
|
632
705
|
input: process.stdin,
|
|
633
706
|
output: process.stdout
|
|
@@ -635,12 +708,19 @@ async function promptProjectConfig(targetDir) {
|
|
|
635
708
|
|
|
636
709
|
const question = (prompt) => new Promise(resolve => rl.question(prompt, resolve));
|
|
637
710
|
|
|
711
|
+
// Get saved values from interrupted setup
|
|
712
|
+
const savedProject = existingConfig.project || {};
|
|
713
|
+
const savedName = savedProject.name;
|
|
714
|
+
const savedType = savedProject.type;
|
|
715
|
+
|
|
638
716
|
// Detect project name
|
|
639
|
-
const detectedName = detectProjectName(targetDir);
|
|
717
|
+
const detectedName = savedName || detectProjectName(targetDir);
|
|
640
718
|
|
|
641
719
|
// Detect project types
|
|
642
720
|
const detectedTypes = detectProjectType(targetDir);
|
|
643
|
-
const topDetectedType =
|
|
721
|
+
const topDetectedType = savedType
|
|
722
|
+
? PROJECT_TYPES.find(t => t.id === savedType)
|
|
723
|
+
: (detectedTypes.length > 0 ? detectedTypes[0] : null);
|
|
644
724
|
|
|
645
725
|
// Detect tech stack
|
|
646
726
|
const detectedTechStack = detectTechStack(targetDir);
|
|
@@ -648,9 +728,16 @@ async function promptProjectConfig(targetDir) {
|
|
|
648
728
|
console.log(chalk.bold('\nProject Configuration'));
|
|
649
729
|
console.log(chalk.gray('─'.repeat(40) + '\n'));
|
|
650
730
|
|
|
731
|
+
// Show resume notice if we have saved values
|
|
732
|
+
if (savedName || savedType) {
|
|
733
|
+
console.log(chalk.cyan('📋 Resuming with your previous choices...\n'));
|
|
734
|
+
}
|
|
735
|
+
|
|
651
736
|
// Project Name
|
|
652
737
|
console.log(chalk.cyan('Project Name'));
|
|
653
|
-
if (
|
|
738
|
+
if (savedName) {
|
|
739
|
+
console.log(chalk.green(` Previously saved: ${savedName}`));
|
|
740
|
+
} else if (detectedName) {
|
|
654
741
|
console.log(chalk.gray(` Detected: ${detectedName}`));
|
|
655
742
|
}
|
|
656
743
|
const nameInput = await question(chalk.yellow(` Enter name (press Enter for "${detectedName}"): `));
|
|
@@ -765,6 +852,44 @@ function applyTemplate(templateId, targetDir) {
|
|
|
765
852
|
};
|
|
766
853
|
}
|
|
767
854
|
|
|
855
|
+
/**
|
|
856
|
+
* Load existing partial config (for resume after interrupted setup)
|
|
857
|
+
*/
|
|
858
|
+
function loadPartialConfig(configPath) {
|
|
859
|
+
if (!existsSync(configPath)) return {};
|
|
860
|
+
|
|
861
|
+
try {
|
|
862
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
863
|
+
return yaml.load(content) || {};
|
|
864
|
+
} catch {
|
|
865
|
+
return {};
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Save partial config progress (called after each setup step)
|
|
871
|
+
*/
|
|
872
|
+
function savePartialConfig(configPath, updates) {
|
|
873
|
+
let config = loadPartialConfig(configPath);
|
|
874
|
+
|
|
875
|
+
// Deep merge updates into config
|
|
876
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
877
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
878
|
+
config[key] = { ...(config[key] || {}), ...value };
|
|
879
|
+
} else {
|
|
880
|
+
config[key] = value;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Add setup progress marker
|
|
885
|
+
config._setup = config._setup || {};
|
|
886
|
+
config._setup.last_step = updates._step || config._setup.last_step;
|
|
887
|
+
config._setup.timestamp = new Date().toISOString();
|
|
888
|
+
|
|
889
|
+
const yamlContent = yaml.dump(config, { indent: 2, lineWidth: 120 });
|
|
890
|
+
writeFileSync(configPath, yamlContent);
|
|
891
|
+
}
|
|
892
|
+
|
|
768
893
|
/**
|
|
769
894
|
* Save project config to proagents.config.yaml
|
|
770
895
|
*/
|
|
@@ -829,6 +954,10 @@ export async function initCommand(options = {}) {
|
|
|
829
954
|
const targetDir = process.cwd();
|
|
830
955
|
const proagentsDir = join(targetDir, '.proagents');
|
|
831
956
|
const sourceDir = join(__dirname, '..', '..', '.proagents');
|
|
957
|
+
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
958
|
+
|
|
959
|
+
// Load any existing partial config (from interrupted setup)
|
|
960
|
+
const existingConfig = loadPartialConfig(configPath);
|
|
832
961
|
|
|
833
962
|
console.log('\n' + chalk.bold.blue('ProAgents Initialization'));
|
|
834
963
|
console.log(chalk.blue('========================\n'));
|
|
@@ -836,24 +965,56 @@ export async function initCommand(options = {}) {
|
|
|
836
965
|
// Check if already initialized
|
|
837
966
|
const alreadyInitialized = existsSync(proagentsDir);
|
|
838
967
|
|
|
968
|
+
// Check for incomplete setup (user killed terminal mid-setup)
|
|
969
|
+
const isIncompleteSetup = alreadyInitialized && checkIncompleteSetup(targetDir);
|
|
970
|
+
|
|
839
971
|
if (alreadyInitialized && !options.force) {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
972
|
+
if (isIncompleteSetup) {
|
|
973
|
+
// Incomplete setup detected - ask user what to do
|
|
974
|
+
console.log(chalk.yellow('⚠️ Incomplete setup detected!'));
|
|
975
|
+
console.log(chalk.gray(' Previous setup was interrupted before completion.\n'));
|
|
976
|
+
|
|
977
|
+
const choice = await promptIncompleteSetupChoice();
|
|
978
|
+
|
|
979
|
+
if (choice === 'continue') {
|
|
980
|
+
console.log(chalk.cyan('\nContinuing setup...\n'));
|
|
981
|
+
// Fall through to fresh install (but keep .proagents folder)
|
|
982
|
+
} else if (choice === 'restart') {
|
|
983
|
+
console.log(chalk.cyan('\nRestarting fresh setup...\n'));
|
|
984
|
+
rmSync(proagentsDir, { recursive: true, force: true });
|
|
985
|
+
// Fall through to fresh install
|
|
986
|
+
} else {
|
|
987
|
+
// Update only
|
|
988
|
+
console.log(chalk.cyan('\nRunning smart update...\n'));
|
|
989
|
+
try {
|
|
990
|
+
await smartUpdate(sourceDir, proagentsDir);
|
|
991
|
+
console.log(chalk.green('\n✓ ProAgents updated successfully!\n'));
|
|
992
|
+
return;
|
|
993
|
+
} catch (error) {
|
|
994
|
+
console.error(chalk.red('\n✗ Error updating ProAgents:'));
|
|
995
|
+
console.error(chalk.red(error.message));
|
|
996
|
+
process.exit(1);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
} else {
|
|
1000
|
+
// Complete setup exists - run smart update
|
|
1001
|
+
console.log(chalk.cyan('ℹ️ ProAgents detected. Running smart update...'));
|
|
1002
|
+
console.log(chalk.gray(' (Preserving your customizations)\n'));
|
|
843
1003
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
1004
|
+
try {
|
|
1005
|
+
await smartUpdate(sourceDir, proagentsDir);
|
|
1006
|
+
console.log(chalk.green('\n✓ ProAgents updated successfully!\n'));
|
|
1007
|
+
console.log(chalk.gray('Preserved:'));
|
|
1008
|
+
console.log(chalk.gray(' • active-features/ (your work in progress)'));
|
|
1009
|
+
console.log(chalk.gray(' • proagents.config.yaml (your values + new options merged)'));
|
|
1010
|
+
console.log(chalk.gray(' • .learning/ (learned patterns)'));
|
|
1011
|
+
console.log(chalk.gray(' • cache/ (analysis cache)\n'));
|
|
1012
|
+
return;
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
console.error(chalk.red('\n✗ Error updating ProAgents:'));
|
|
1015
|
+
console.error(chalk.red(error.message));
|
|
1016
|
+
process.exit(1);
|
|
1017
|
+
}
|
|
857
1018
|
}
|
|
858
1019
|
}
|
|
859
1020
|
|
|
@@ -949,6 +1110,12 @@ Generated by [ProAgents](https://github.com/prakashpro3/proAgents)
|
|
|
949
1110
|
} else {
|
|
950
1111
|
console.log(chalk.green('✓ Added .proagents/ local data to .gitignore'));
|
|
951
1112
|
}
|
|
1113
|
+
|
|
1114
|
+
// Save progress after gitignore choice
|
|
1115
|
+
savePartialConfig(configPath, {
|
|
1116
|
+
gitignore_mode: gitignoreChoice,
|
|
1117
|
+
_step: 'gitignore'
|
|
1118
|
+
});
|
|
952
1119
|
}
|
|
953
1120
|
|
|
954
1121
|
// Create placeholder CHANGELOG.md if not exists
|
|
@@ -1016,10 +1183,19 @@ No releases yet. Use \`pa:release\` to generate release notes.
|
|
|
1016
1183
|
}
|
|
1017
1184
|
console.log(chalk.green(`\n✓ Using template: ${PROJECT_TEMPLATES[options.template].name}`));
|
|
1018
1185
|
} else {
|
|
1019
|
-
// Interactive prompts
|
|
1020
|
-
projectConfig = await promptProjectConfig(targetDir);
|
|
1186
|
+
// Interactive prompts - pass existing config for pre-filling
|
|
1187
|
+
projectConfig = await promptProjectConfig(targetDir, existingConfig);
|
|
1021
1188
|
}
|
|
1022
1189
|
|
|
1190
|
+
// Save progress after project config
|
|
1191
|
+
savePartialConfig(configPath, {
|
|
1192
|
+
project: {
|
|
1193
|
+
name: projectConfig.name,
|
|
1194
|
+
type: projectConfig.type
|
|
1195
|
+
},
|
|
1196
|
+
_step: 'project_config'
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1023
1199
|
// Add ProAgents section to README.md (AI tools auto-read this)
|
|
1024
1200
|
const readmePath = join(targetDir, 'README.md');
|
|
1025
1201
|
const proagentsSection = `
|
|
@@ -1058,9 +1234,16 @@ For detailed commands, see \`./.proagents/PROAGENTS.md\`
|
|
|
1058
1234
|
selectedPlatforms = projectConfig.platforms;
|
|
1059
1235
|
console.log(chalk.gray(` Using template platforms: ${selectedPlatforms.join(', ')}`));
|
|
1060
1236
|
} else {
|
|
1061
|
-
|
|
1237
|
+
// Pass existing config for pre-selection
|
|
1238
|
+
selectedPlatforms = await selectPlatforms(existingConfig.ai_platforms);
|
|
1062
1239
|
}
|
|
1063
1240
|
|
|
1241
|
+
// Save progress after platform selection
|
|
1242
|
+
savePartialConfig(configPath, {
|
|
1243
|
+
ai_platforms: selectedPlatforms,
|
|
1244
|
+
_step: 'platforms'
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1064
1247
|
// Copy AI instruction files for selected platforms (merges with existing files)
|
|
1065
1248
|
const aiResults = copyPlatformFiles(selectedPlatforms, sourceDir, targetDir);
|
|
1066
1249
|
|
|
@@ -1074,11 +1257,16 @@ For detailed commands, see \`./.proagents/PROAGENTS.md\`
|
|
|
1074
1257
|
console.log(chalk.green(`✓ Merged with existing: ${aiResults.merged.join(', ')}`));
|
|
1075
1258
|
}
|
|
1076
1259
|
|
|
1077
|
-
// Save project and platform config
|
|
1078
|
-
const configPath = join(targetDir, 'proagents.config.yaml');
|
|
1260
|
+
// Save final project and platform config (removes _setup marker)
|
|
1079
1261
|
saveProjectConfig(projectConfig, configPath);
|
|
1080
1262
|
savePlatformConfig(selectedPlatforms, configPath);
|
|
1081
1263
|
|
|
1264
|
+
// Clean up setup progress marker
|
|
1265
|
+
const finalConfig = loadPartialConfig(configPath);
|
|
1266
|
+
delete finalConfig._setup;
|
|
1267
|
+
const yamlContent = yaml.dump(finalConfig, { indent: 2, lineWidth: 120 });
|
|
1268
|
+
writeFileSync(configPath, yamlContent);
|
|
1269
|
+
|
|
1082
1270
|
// Success message
|
|
1083
1271
|
console.log(chalk.green('\n✓ ProAgents initialized successfully!\n'));
|
|
1084
1272
|
|
|
@@ -19,6 +19,50 @@ const AI_FILES = [
|
|
|
19
19
|
'AI_INSTRUCTIONS.md',
|
|
20
20
|
];
|
|
21
21
|
|
|
22
|
+
// ProAgents markers used in merged files
|
|
23
|
+
const PROAGENTS_START = '<!-- PROAGENTS:START -->';
|
|
24
|
+
const PROAGENTS_END = '<!-- PROAGENTS:END -->';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Remove only ProAgents section from a file, keep user's original content
|
|
28
|
+
* Returns: 'deleted' (file removed), 'cleaned' (section removed), 'skipped' (no ProAgents section)
|
|
29
|
+
*/
|
|
30
|
+
function removeProagentsSectionFromFile(filePath) {
|
|
31
|
+
try {
|
|
32
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
33
|
+
|
|
34
|
+
const startIndex = content.indexOf(PROAGENTS_START);
|
|
35
|
+
const endIndex = content.indexOf(PROAGENTS_END);
|
|
36
|
+
|
|
37
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
38
|
+
// Has ProAgents section - remove it, keep the rest
|
|
39
|
+
const before = content.substring(0, startIndex).trim();
|
|
40
|
+
const after = content.substring(endIndex + PROAGENTS_END.length).trim();
|
|
41
|
+
const remaining = (before + '\n\n' + after).trim();
|
|
42
|
+
|
|
43
|
+
if (remaining.length === 0) {
|
|
44
|
+
// File only had ProAgents content - delete it
|
|
45
|
+
rmSync(filePath, { force: true });
|
|
46
|
+
return 'deleted';
|
|
47
|
+
} else {
|
|
48
|
+
// File has other content - keep it, remove only ProAgents section
|
|
49
|
+
writeFileSync(filePath, remaining + '\n');
|
|
50
|
+
return 'cleaned';
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
// No ProAgents markers - file was created by ProAgents (not merged)
|
|
54
|
+
// Check if it's a ProAgents-generated file by looking for ProAgents reference
|
|
55
|
+
if (content.includes('proagents') || content.includes('ProAgents') || content.includes('.proagents/')) {
|
|
56
|
+
rmSync(filePath, { force: true });
|
|
57
|
+
return 'deleted';
|
|
58
|
+
}
|
|
59
|
+
return 'skipped';
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return 'skipped';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
22
66
|
/**
|
|
23
67
|
* Command: proagents uninstall
|
|
24
68
|
*/
|
|
@@ -46,7 +90,7 @@ export async function uninstallCommand(options = {}) {
|
|
|
46
90
|
|
|
47
91
|
console.log(chalk.yellow('This will remove:'));
|
|
48
92
|
console.log(chalk.gray(' • ./.proagents/ folder'));
|
|
49
|
-
console.log(chalk.gray(' • AI
|
|
93
|
+
console.log(chalk.gray(' • ProAgents sections from AI files (keeps your original config)'));
|
|
50
94
|
console.log(chalk.gray(' • ProAgents section from README.md\n'));
|
|
51
95
|
|
|
52
96
|
const answer = await question(chalk.yellow('Are you sure? (yes/no): '));
|
|
@@ -66,26 +110,39 @@ export async function uninstallCommand(options = {}) {
|
|
|
66
110
|
console.log(chalk.green('✓ Removed ./.proagents/ folder'));
|
|
67
111
|
}
|
|
68
112
|
|
|
69
|
-
// 2. Remove AI instruction files from project root
|
|
113
|
+
// 2. Remove AI instruction files from project root (smart removal)
|
|
70
114
|
let aiFilesRemoved = 0;
|
|
115
|
+
let aiFilesCleaned = 0;
|
|
116
|
+
|
|
71
117
|
for (const file of AI_FILES) {
|
|
72
118
|
const filePath = join(targetDir, file);
|
|
73
119
|
if (existsSync(filePath)) {
|
|
74
|
-
|
|
75
|
-
|
|
120
|
+
const result = removeProagentsSectionFromFile(filePath);
|
|
121
|
+
if (result === 'deleted') {
|
|
122
|
+
aiFilesRemoved++;
|
|
123
|
+
} else if (result === 'cleaned') {
|
|
124
|
+
aiFilesCleaned++;
|
|
125
|
+
}
|
|
76
126
|
}
|
|
77
127
|
}
|
|
78
128
|
|
|
79
129
|
// Remove .github/copilot-instructions.md
|
|
80
130
|
const copilotPath = join(targetDir, '.github', 'copilot-instructions.md');
|
|
81
131
|
if (existsSync(copilotPath)) {
|
|
82
|
-
|
|
83
|
-
|
|
132
|
+
const result = removeProagentsSectionFromFile(copilotPath);
|
|
133
|
+
if (result === 'deleted') {
|
|
134
|
+
aiFilesRemoved++;
|
|
135
|
+
} else if (result === 'cleaned') {
|
|
136
|
+
aiFilesCleaned++;
|
|
137
|
+
}
|
|
84
138
|
}
|
|
85
139
|
|
|
86
140
|
if (aiFilesRemoved > 0) {
|
|
87
141
|
console.log(chalk.green(`✓ Removed ${aiFilesRemoved} AI instruction file(s)`));
|
|
88
142
|
}
|
|
143
|
+
if (aiFilesCleaned > 0) {
|
|
144
|
+
console.log(chalk.green(`✓ Cleaned ProAgents section from ${aiFilesCleaned} AI file(s) (kept original config)`));
|
|
145
|
+
}
|
|
89
146
|
|
|
90
147
|
// 3. Remove ProAgents section from README.md
|
|
91
148
|
const readmePath = join(targetDir, 'README.md');
|