proagents 1.0.10 → 1.0.12

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.
@@ -0,0 +1,596 @@
1
+ import { existsSync, readdirSync, readFileSync, writeFileSync, cpSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { createInterface } from 'readline';
5
+ import chalk from 'chalk';
6
+ import yaml from 'js-yaml';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ /**
12
+ * Command: proagents config list
13
+ * Shows all configurable options
14
+ */
15
+ export function configListCommand() {
16
+ const targetDir = process.cwd();
17
+ const proagentsDir = join(targetDir, 'proagents');
18
+
19
+ console.log('\n' + chalk.bold.blue('ProAgents Configuration Options'));
20
+ console.log(chalk.blue('================================\n'));
21
+
22
+ // Check if ProAgents is initialized
23
+ if (!existsSync(proagentsDir)) {
24
+ console.log(chalk.yellow('ProAgents not initialized. Run "proagents init" first.\n'));
25
+ return;
26
+ }
27
+
28
+ // 1. Main Config
29
+ console.log(chalk.cyan.bold('1. Main Configuration'));
30
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
31
+ const configPath = join(proagentsDir, 'proagents.config.yaml');
32
+ if (existsSync(configPath)) {
33
+ console.log(chalk.green(' ✓ ') + chalk.white('proagents/proagents.config.yaml'));
34
+ console.log(chalk.gray(' Checkpoints, git settings, parallel features, etc.\n'));
35
+ } else {
36
+ console.log(chalk.yellow(' ○ ') + chalk.white('proagents/proagents.config.yaml') + chalk.gray(' (not created)\n'));
37
+ }
38
+
39
+ // 2. AI Platforms
40
+ console.log(chalk.cyan.bold('2. AI Platforms'));
41
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
42
+ console.log(chalk.gray(' Manage with: ') + chalk.cyan('proagents ai list/add/remove'));
43
+
44
+ try {
45
+ const config = yaml.load(readFileSync(configPath, 'utf-8'));
46
+ if (config.ai_platforms && config.ai_platforms.length > 0) {
47
+ console.log(chalk.green(' ✓ ') + chalk.white(`Installed: ${config.ai_platforms.join(', ')}`));
48
+ } else {
49
+ console.log(chalk.yellow(' ○ ') + chalk.white('No platforms configured'));
50
+ }
51
+ } catch {
52
+ console.log(chalk.yellow(' ○ ') + chalk.white('No platforms configured'));
53
+ }
54
+ console.log('');
55
+
56
+ // 3. Integration Templates
57
+ console.log(chalk.cyan.bold('3. Integration Configs'));
58
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
59
+ console.log(chalk.gray(' Copy template and remove ".template." to customize:\n'));
60
+
61
+ const integrations = [
62
+ { template: 'jira.template.yaml', user: 'jira.yaml', desc: 'Jira integration' },
63
+ { template: 'github.template.yaml', user: 'github.yaml', desc: 'GitHub integration' },
64
+ { template: 'slack.template.yaml', user: 'slack.yaml', desc: 'Slack notifications' },
65
+ { template: 'linear.template.yaml', user: 'linear.yaml', desc: 'Linear integration' },
66
+ { template: 'notion.template.yaml', user: 'notion.yaml', desc: 'Notion integration' },
67
+ ];
68
+
69
+ for (const item of integrations) {
70
+ const userPath = join(proagentsDir, 'config', 'integrations', item.user);
71
+ const templatePath = join(proagentsDir, 'config', 'integrations', item.template);
72
+
73
+ if (existsSync(userPath)) {
74
+ console.log(chalk.green(' ✓ ') + chalk.white(item.user) + chalk.gray(` - ${item.desc} (customized)`));
75
+ } else if (existsSync(templatePath)) {
76
+ console.log(chalk.yellow(' ○ ') + chalk.white(item.template) + chalk.gray(` - ${item.desc}`));
77
+ }
78
+ }
79
+ console.log('');
80
+
81
+ // 4. Standards Templates
82
+ console.log(chalk.cyan.bold('4. Coding Standards'));
83
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
84
+ console.log(chalk.gray(' Copy template and remove ".template." to customize:\n'));
85
+
86
+ const standards = [
87
+ { template: 'coding-standards.template.md', user: 'coding-standards.md', desc: 'Code style rules' },
88
+ { template: 'architecture-rules.template.md', user: 'architecture-rules.md', desc: 'Architecture patterns' },
89
+ { template: 'naming-conventions.template.md', user: 'naming-conventions.md', desc: 'Naming rules' },
90
+ { template: 'testing-standards.template.md', user: 'testing-standards.md', desc: 'Testing requirements' },
91
+ ];
92
+
93
+ for (const item of standards) {
94
+ const userPath = join(proagentsDir, 'config', 'standards', item.user);
95
+ const templatePath = join(proagentsDir, 'config', 'standards', item.template);
96
+
97
+ if (existsSync(userPath)) {
98
+ console.log(chalk.green(' ✓ ') + chalk.white(item.user) + chalk.gray(` - ${item.desc} (customized)`));
99
+ } else if (existsSync(templatePath)) {
100
+ console.log(chalk.yellow(' ○ ') + chalk.white(item.template) + chalk.gray(` - ${item.desc}`));
101
+ }
102
+ }
103
+ console.log('');
104
+
105
+ // 5. Custom Rules
106
+ console.log(chalk.cyan.bold('5. Custom Rules'));
107
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
108
+ console.log(chalk.gray(' Copy template and remove ".template." to customize:\n'));
109
+
110
+ const rules = [
111
+ { template: 'custom-rules.template.yaml', user: 'custom-rules.yaml', desc: 'Custom validation rules' },
112
+ { template: 'validation-rules.template.yaml', user: 'validation-rules.yaml', desc: 'Code validation rules' },
113
+ ];
114
+
115
+ for (const item of rules) {
116
+ const userPath = join(proagentsDir, 'config', 'rules', item.user);
117
+ const templatePath = join(proagentsDir, 'config', 'rules', item.template);
118
+
119
+ if (existsSync(userPath)) {
120
+ console.log(chalk.green(' ✓ ') + chalk.white(item.user) + chalk.gray(` - ${item.desc} (customized)`));
121
+ } else if (existsSync(templatePath)) {
122
+ console.log(chalk.yellow(' ○ ') + chalk.white(item.template) + chalk.gray(` - ${item.desc}`));
123
+ }
124
+ }
125
+ console.log('');
126
+
127
+ // 6. Code Templates
128
+ console.log(chalk.cyan.bold('6. Code Templates'));
129
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
130
+ console.log(chalk.gray(' Copy template and remove ".template." to customize:\n'));
131
+
132
+ const codeTemplates = [
133
+ { template: 'component.template.tsx', user: 'component.tsx', desc: 'React component template' },
134
+ { template: 'hook.template.ts', user: 'hook.ts', desc: 'React hook template' },
135
+ { template: 'api-route.template.ts', user: 'api-route.ts', desc: 'API route template' },
136
+ { template: 'test.template.ts', user: 'test.ts', desc: 'Test file template' },
137
+ ];
138
+
139
+ for (const item of codeTemplates) {
140
+ const userPath = join(proagentsDir, 'config', 'templates', item.user);
141
+ const templatePath = join(proagentsDir, 'config', 'templates', item.template);
142
+
143
+ if (existsSync(userPath)) {
144
+ console.log(chalk.green(' ✓ ') + chalk.white(item.user) + chalk.gray(` - ${item.desc} (customized)`));
145
+ } else if (existsSync(templatePath)) {
146
+ console.log(chalk.yellow(' ○ ') + chalk.white(item.template) + chalk.gray(` - ${item.desc}`));
147
+ }
148
+ }
149
+ console.log('');
150
+
151
+ // 7. Preserved Folders
152
+ console.log(chalk.cyan.bold('7. User Data (Never Overwritten)'));
153
+ console.log(chalk.gray(' ─────────────────────────────────────────'));
154
+
155
+ const preserved = [
156
+ { path: 'active-features', desc: 'Your work in progress' },
157
+ { path: '.learning', desc: 'Learned patterns' },
158
+ { path: 'cache', desc: 'Analysis cache' },
159
+ ];
160
+
161
+ for (const item of preserved) {
162
+ const fullPath = join(proagentsDir, item.path);
163
+ if (existsSync(fullPath)) {
164
+ console.log(chalk.green(' ✓ ') + chalk.white(`proagents/${item.path}/`) + chalk.gray(` - ${item.desc}`));
165
+ } else {
166
+ console.log(chalk.yellow(' ○ ') + chalk.white(`proagents/${item.path}/`) + chalk.gray(` - ${item.desc} (empty)`));
167
+ }
168
+ }
169
+ console.log('');
170
+
171
+ // Summary
172
+ console.log(chalk.gray('─────────────────────────────────────────────'));
173
+ console.log(chalk.white('Legend: ') + chalk.green('✓ customized ') + chalk.yellow('○ using default'));
174
+ console.log('');
175
+ console.log(chalk.gray('To customize a template:'));
176
+ console.log(chalk.cyan(' cp proagents/config/standards/coding-standards.template.md \\'));
177
+ console.log(chalk.cyan(' proagents/config/standards/coding-standards.md'));
178
+ console.log(chalk.gray('\nThen edit the new file with your settings.\n'));
179
+ }
180
+
181
+ /**
182
+ * Command: proagents config show
183
+ * Shows current config values
184
+ */
185
+ export function configShowCommand() {
186
+ const targetDir = process.cwd();
187
+ const configPath = join(targetDir, 'proagents', 'proagents.config.yaml');
188
+
189
+ console.log('\n' + chalk.bold.blue('ProAgents Current Configuration'));
190
+ console.log(chalk.blue('================================\n'));
191
+
192
+ if (!existsSync(configPath)) {
193
+ console.log(chalk.yellow('Config file not found. Run "proagents init" first.\n'));
194
+ return;
195
+ }
196
+
197
+ try {
198
+ const content = readFileSync(configPath, 'utf-8');
199
+ const config = yaml.load(content);
200
+
201
+ console.log(chalk.cyan('File: ') + chalk.white('proagents/proagents.config.yaml\n'));
202
+ console.log(chalk.gray('─────────────────────────────────────────────\n'));
203
+ console.log(content);
204
+ } catch (error) {
205
+ console.log(chalk.red('Error reading config: ' + error.message + '\n'));
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Command: proagents config edit
211
+ * Opens config in default editor
212
+ */
213
+ export function configEditCommand() {
214
+ const targetDir = process.cwd();
215
+ const configPath = join(targetDir, 'proagents', 'proagents.config.yaml');
216
+
217
+ if (!existsSync(configPath)) {
218
+ console.log(chalk.yellow('\nConfig file not found. Run "proagents init" first.\n'));
219
+ return;
220
+ }
221
+
222
+ console.log(chalk.cyan('\nTo edit configuration:\n'));
223
+ console.log(chalk.white(' Open: ') + chalk.green('proagents/proagents.config.yaml'));
224
+ console.log(chalk.white(' Docs: ') + chalk.green('proagents/config/README.md\n'));
225
+ }
226
+
227
+ /**
228
+ * Helper: Get nested value from object using dot notation
229
+ */
230
+ function getNestedValue(obj, path) {
231
+ return path.split('.').reduce((current, key) => current?.[key], obj);
232
+ }
233
+
234
+ /**
235
+ * Helper: Set nested value in object using dot notation
236
+ */
237
+ function setNestedValue(obj, path, value) {
238
+ const keys = path.split('.');
239
+ const lastKey = keys.pop();
240
+ const target = keys.reduce((current, key) => {
241
+ if (!(key in current)) current[key] = {};
242
+ return current[key];
243
+ }, obj);
244
+ target[lastKey] = value;
245
+ }
246
+
247
+ /**
248
+ * Helper: Parse value to appropriate type
249
+ */
250
+ function parseValue(value) {
251
+ if (value === 'true') return true;
252
+ if (value === 'false') return false;
253
+ if (value === 'null') return null;
254
+ if (!isNaN(value) && value !== '') return Number(value);
255
+ return value;
256
+ }
257
+
258
+ /**
259
+ * Command: proagents config set <key> <value>
260
+ * Set a single config value
261
+ */
262
+ export function configSetCommand(key, value) {
263
+ const targetDir = process.cwd();
264
+ const configPath = join(targetDir, 'proagents', 'proagents.config.yaml');
265
+
266
+ console.log('');
267
+
268
+ if (!existsSync(configPath)) {
269
+ console.log(chalk.yellow('Config file not found. Run "proagents init" first.\n'));
270
+ return;
271
+ }
272
+
273
+ try {
274
+ const content = readFileSync(configPath, 'utf-8');
275
+ const config = yaml.load(content) || {};
276
+
277
+ const oldValue = getNestedValue(config, key);
278
+ const newValue = parseValue(value);
279
+
280
+ setNestedValue(config, key, newValue);
281
+
282
+ const header = `# ProAgents Configuration\n# Last updated: ${new Date().toISOString().split('T')[0]}\n\n`;
283
+ const yamlContent = yaml.dump(config, { indent: 2, lineWidth: 120 });
284
+ writeFileSync(configPath, header + yamlContent);
285
+
286
+ console.log(chalk.green('✓ Configuration updated'));
287
+ console.log(chalk.gray(` ${key}: `) + chalk.yellow(String(oldValue ?? '(not set)')) + chalk.gray(' → ') + chalk.green(String(newValue)));
288
+ console.log('');
289
+ } catch (error) {
290
+ console.log(chalk.red('Error updating config: ' + error.message + '\n'));
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Command: proagents config get <key>
296
+ * Get a single config value
297
+ */
298
+ export function configGetCommand(key) {
299
+ const targetDir = process.cwd();
300
+ const configPath = join(targetDir, 'proagents', 'proagents.config.yaml');
301
+
302
+ console.log('');
303
+
304
+ if (!existsSync(configPath)) {
305
+ console.log(chalk.yellow('Config file not found. Run "proagents init" first.\n'));
306
+ return;
307
+ }
308
+
309
+ try {
310
+ const content = readFileSync(configPath, 'utf-8');
311
+ const config = yaml.load(content) || {};
312
+ const value = getNestedValue(config, key);
313
+
314
+ if (value === undefined) {
315
+ console.log(chalk.yellow(`${key}: `) + chalk.gray('(not set)\n'));
316
+ } else if (typeof value === 'object') {
317
+ console.log(chalk.cyan(`${key}:`));
318
+ console.log(yaml.dump(value, { indent: 2 }));
319
+ } else {
320
+ console.log(chalk.cyan(`${key}: `) + chalk.white(String(value)) + '\n');
321
+ }
322
+ } catch (error) {
323
+ console.log(chalk.red('Error reading config: ' + error.message + '\n'));
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Command: proagents config setup
329
+ * Interactive wizard for main configuration
330
+ */
331
+ export async function configSetupCommand() {
332
+ const targetDir = process.cwd();
333
+ const configPath = join(targetDir, 'proagents', 'proagents.config.yaml');
334
+
335
+ console.log('\n' + chalk.bold.blue('ProAgents Configuration Wizard'));
336
+ console.log(chalk.blue('===============================\n'));
337
+
338
+ if (!existsSync(join(targetDir, 'proagents'))) {
339
+ console.log(chalk.yellow('ProAgents not initialized. Run "proagents init" first.\n'));
340
+ return;
341
+ }
342
+
343
+ const rl = createInterface({
344
+ input: process.stdin,
345
+ output: process.stdout
346
+ });
347
+
348
+ const question = (prompt, defaultVal) => new Promise(resolve => {
349
+ const defaultStr = defaultVal !== undefined ? ` (${defaultVal})` : '';
350
+ rl.question(chalk.white(prompt) + chalk.gray(defaultStr) + chalk.white(': '), (answer) => {
351
+ resolve(answer || defaultVal);
352
+ });
353
+ });
354
+
355
+ const yesNo = async (prompt, defaultVal = true) => {
356
+ const defaultStr = defaultVal ? 'Y/n' : 'y/N';
357
+ const answer = await question(prompt + ` (${defaultStr})`, '');
358
+ if (answer === '') return defaultVal;
359
+ return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
360
+ };
361
+
362
+ try {
363
+ // Load existing config or create new
364
+ let config = {};
365
+ if (existsSync(configPath)) {
366
+ config = yaml.load(readFileSync(configPath, 'utf-8')) || {};
367
+ }
368
+
369
+ console.log(chalk.cyan('Project Settings\n'));
370
+
371
+ // Project settings
372
+ config.project = config.project || {};
373
+ config.project.name = await question('Project name', config.project.name || 'My Project');
374
+
375
+ const projectTypes = ['web-frontend', 'fullstack', 'mobile', 'backend'];
376
+ console.log(chalk.gray(' Types: ' + projectTypes.join(', ')));
377
+ config.project.type = await question('Project type', config.project.type || 'fullstack');
378
+
379
+ console.log('\n' + chalk.cyan('Checkpoints (pause for approval)\n'));
380
+
381
+ // Checkpoints
382
+ config.checkpoints = config.checkpoints || {};
383
+ config.checkpoints.after_analysis = await yesNo('Pause after analysis?', config.checkpoints.after_analysis ?? true);
384
+ config.checkpoints.after_requirements = await yesNo('Pause after requirements?', config.checkpoints.after_requirements ?? false);
385
+ config.checkpoints.after_design = await yesNo('Pause after design?', config.checkpoints.after_design ?? true);
386
+ config.checkpoints.after_implementation = await yesNo('Pause after implementation?', config.checkpoints.after_implementation ?? false);
387
+ config.checkpoints.after_testing = await yesNo('Pause after testing?', config.checkpoints.after_testing ?? false);
388
+ config.checkpoints.before_deployment = await yesNo('Pause before deployment?', config.checkpoints.before_deployment ?? true);
389
+
390
+ console.log('\n' + chalk.cyan('Git Settings\n'));
391
+
392
+ // Git settings
393
+ config.git = config.git || {};
394
+ config.git.enabled = await yesNo('Enable git integration?', config.git.enabled ?? true);
395
+
396
+ if (config.git.enabled) {
397
+ config.git.branch_prefix = await question('Branch prefix', config.git.branch_prefix || 'feature/');
398
+
399
+ const conventions = ['conventional', 'simple', 'custom'];
400
+ console.log(chalk.gray(' Conventions: ' + conventions.join(', ')));
401
+ config.git.commit_convention = await question('Commit convention', config.git.commit_convention || 'conventional');
402
+ config.git.require_pr = await yesNo('Require pull requests?', config.git.require_pr ?? true);
403
+ }
404
+
405
+ console.log('\n' + chalk.cyan('Parallel Features\n'));
406
+
407
+ // Parallel features
408
+ config.parallel_features = config.parallel_features || {};
409
+ config.parallel_features.enabled = await yesNo('Enable parallel features?', config.parallel_features.enabled ?? true);
410
+
411
+ if (config.parallel_features.enabled) {
412
+ const maxStr = await question('Max concurrent features', String(config.parallel_features.max_concurrent || 3));
413
+ config.parallel_features.max_concurrent = parseInt(maxStr) || 3;
414
+ }
415
+
416
+ rl.close();
417
+
418
+ // Save config
419
+ const header = `# ProAgents Configuration\n# Generated by setup wizard\n# Last updated: ${new Date().toISOString().split('T')[0]}\n\n`;
420
+ const yamlContent = yaml.dump(config, { indent: 2, lineWidth: 120 });
421
+ writeFileSync(configPath, header + yamlContent);
422
+
423
+ console.log(chalk.green('\n✓ Configuration saved to proagents/proagents.config.yaml\n'));
424
+
425
+ } catch (error) {
426
+ rl.close();
427
+ console.log(chalk.red('\nError: ' + error.message + '\n'));
428
+ }
429
+ }
430
+
431
+ // All customizable templates
432
+ const CUSTOMIZABLE_TEMPLATES = {
433
+ integrations: {
434
+ label: 'Integrations',
435
+ path: 'config/integrations',
436
+ items: [
437
+ { template: 'jira.template.yaml', user: 'jira.yaml', desc: 'Jira project management' },
438
+ { template: 'github.template.yaml', user: 'github.yaml', desc: 'GitHub integration' },
439
+ { template: 'slack.template.yaml', user: 'slack.yaml', desc: 'Slack notifications' },
440
+ { template: 'linear.template.yaml', user: 'linear.yaml', desc: 'Linear project management' },
441
+ { template: 'notion.template.yaml', user: 'notion.yaml', desc: 'Notion documentation' },
442
+ ]
443
+ },
444
+ standards: {
445
+ label: 'Coding Standards',
446
+ path: 'config/standards',
447
+ items: [
448
+ { template: 'coding-standards.template.md', user: 'coding-standards.md', desc: 'Code style rules' },
449
+ { template: 'architecture-rules.template.md', user: 'architecture-rules.md', desc: 'Architecture patterns' },
450
+ { template: 'naming-conventions.template.md', user: 'naming-conventions.md', desc: 'Naming conventions' },
451
+ { template: 'testing-standards.template.md', user: 'testing-standards.md', desc: 'Testing requirements' },
452
+ ]
453
+ },
454
+ rules: {
455
+ label: 'Custom Rules',
456
+ path: 'config/rules',
457
+ items: [
458
+ { template: 'custom-rules.template.yaml', user: 'custom-rules.yaml', desc: 'Custom validation rules' },
459
+ { template: 'validation-rules.template.yaml', user: 'validation-rules.yaml', desc: 'Code validation rules' },
460
+ ]
461
+ },
462
+ templates: {
463
+ label: 'Code Templates',
464
+ path: 'config/templates',
465
+ items: [
466
+ { template: 'component.template.tsx', user: 'component.tsx', desc: 'React component template' },
467
+ { template: 'hook.template.ts', user: 'hook.ts', desc: 'React hook template' },
468
+ { template: 'api-route.template.ts', user: 'api-route.ts', desc: 'API route template' },
469
+ { template: 'test.template.ts', user: 'test.ts', desc: 'Test file template' },
470
+ ]
471
+ }
472
+ };
473
+
474
+ /**
475
+ * Command: proagents config customize
476
+ * Interactive template customization
477
+ */
478
+ export async function configCustomizeCommand() {
479
+ const targetDir = process.cwd();
480
+ const proagentsDir = join(targetDir, 'proagents');
481
+
482
+ console.log('\n' + chalk.bold.blue('ProAgents Template Customization'));
483
+ console.log(chalk.blue('=================================\n'));
484
+
485
+ if (!existsSync(proagentsDir)) {
486
+ console.log(chalk.yellow('ProAgents not initialized. Run "proagents init" first.\n'));
487
+ return;
488
+ }
489
+
490
+ const rl = createInterface({
491
+ input: process.stdin,
492
+ output: process.stdout
493
+ });
494
+
495
+ const question = (prompt) => new Promise(resolve => rl.question(prompt, resolve));
496
+
497
+ // Show categories
498
+ console.log(chalk.cyan('Select a category to customize:\n'));
499
+
500
+ const categories = Object.entries(CUSTOMIZABLE_TEMPLATES);
501
+ let index = 1;
502
+ const categoryMap = {};
503
+
504
+ for (const [key, category] of categories) {
505
+ console.log(chalk.white(` ${index}. ${category.label}`));
506
+ categoryMap[index] = key;
507
+ index++;
508
+ }
509
+
510
+ console.log('');
511
+ const categoryAnswer = await question(chalk.yellow('Category number (or "q" to quit): '));
512
+
513
+ if (categoryAnswer.toLowerCase() === 'q') {
514
+ rl.close();
515
+ console.log('');
516
+ return;
517
+ }
518
+
519
+ const categoryKey = categoryMap[parseInt(categoryAnswer)];
520
+ if (!categoryKey) {
521
+ rl.close();
522
+ console.log(chalk.red('\nInvalid selection.\n'));
523
+ return;
524
+ }
525
+
526
+ const category = CUSTOMIZABLE_TEMPLATES[categoryKey];
527
+
528
+ // Show templates in category
529
+ console.log('\n' + chalk.cyan(`${category.label} Templates:\n`));
530
+
531
+ index = 1;
532
+ const templateMap = {};
533
+ const availableTemplates = [];
534
+
535
+ for (const item of category.items) {
536
+ const userPath = join(proagentsDir, category.path, item.user);
537
+ const templatePath = join(proagentsDir, category.path, item.template);
538
+
539
+ if (existsSync(userPath)) {
540
+ console.log(chalk.green(` ${index}. ✓ ${item.user}`) + chalk.gray(` - ${item.desc} (already customized)`));
541
+ } else if (existsSync(templatePath)) {
542
+ console.log(chalk.yellow(` ${index}. ○ ${item.template}`) + chalk.gray(` - ${item.desc}`));
543
+ availableTemplates.push(index);
544
+ }
545
+ templateMap[index] = item;
546
+ index++;
547
+ }
548
+
549
+ if (availableTemplates.length === 0) {
550
+ rl.close();
551
+ console.log(chalk.green('\nAll templates in this category are already customized!\n'));
552
+ return;
553
+ }
554
+
555
+ console.log('');
556
+ const templateAnswer = await question(chalk.yellow('Template number(s) to customize (e.g., 1,2 or "all"): '));
557
+ rl.close();
558
+
559
+ if (templateAnswer.toLowerCase() === 'q' || templateAnswer === '') {
560
+ console.log('');
561
+ return;
562
+ }
563
+
564
+ let selectedIndices = [];
565
+ if (templateAnswer.toLowerCase() === 'all') {
566
+ selectedIndices = availableTemplates;
567
+ } else {
568
+ selectedIndices = templateAnswer.split(',').map(s => parseInt(s.trim())).filter(n => !isNaN(n) && availableTemplates.includes(n));
569
+ }
570
+
571
+ if (selectedIndices.length === 0) {
572
+ console.log(chalk.yellow('\nNo valid templates selected.\n'));
573
+ return;
574
+ }
575
+
576
+ // Copy selected templates
577
+ console.log('');
578
+ for (const idx of selectedIndices) {
579
+ const item = templateMap[idx];
580
+ if (!item) continue;
581
+
582
+ const templatePath = join(proagentsDir, category.path, item.template);
583
+ const userPath = join(proagentsDir, category.path, item.user);
584
+
585
+ if (existsSync(templatePath) && !existsSync(userPath)) {
586
+ try {
587
+ cpSync(templatePath, userPath);
588
+ console.log(chalk.green(`✓ Created ${category.path}/${item.user}`));
589
+ } catch (error) {
590
+ console.log(chalk.red(`✗ Failed to create ${item.user}: ${error.message}`));
591
+ }
592
+ }
593
+ }
594
+
595
+ console.log(chalk.gray('\nEdit the created files to customize your settings.\n'));
596
+ }
@@ -30,26 +30,74 @@ export async function helpCommand() {
30
30
  console.log(chalk.cyan('proagents fix "desc" --upgrade') + ' Upgrade to full workflow');
31
31
  console.log('');
32
32
 
33
+ // AI Platforms
34
+ console.log(chalk.bold.white('AI Platforms'));
35
+ console.log(chalk.gray('─'.repeat(40)));
36
+ console.log(chalk.cyan('proagents ai list') + ' List installed AI platforms');
37
+ console.log(chalk.cyan('proagents ai add') + ' Add more AI platforms');
38
+ console.log(chalk.cyan('proagents ai remove') + ' Remove AI platforms');
39
+ console.log('');
40
+
41
+ // Configuration
42
+ console.log(chalk.bold.white('Configuration'));
43
+ console.log(chalk.gray('─'.repeat(40)));
44
+ console.log(chalk.cyan('proagents config list') + ' Show all configurable options');
45
+ console.log(chalk.cyan('proagents config show') + ' Show current config values');
46
+ console.log(chalk.cyan('proagents config set K V') + ' Set a config value');
47
+ console.log(chalk.cyan('proagents config get K') + ' Get a config value');
48
+ console.log(chalk.cyan('proagents config setup') + ' Interactive setup wizard');
49
+ console.log(chalk.cyan('proagents config customize') + ' Copy templates to customize');
50
+ console.log('');
51
+
33
52
  // Status & Info
34
53
  console.log(chalk.bold.white('Status & Info'));
35
54
  console.log(chalk.gray('─'.repeat(40)));
36
55
  console.log(chalk.cyan('proagents status') + ' Show ProAgents status');
37
56
  console.log(chalk.cyan('proagents docs') + ' Open documentation');
38
57
  console.log(chalk.cyan('proagents commands') + ' Show this help');
58
+ console.log(chalk.cyan('proagents uninstall') + ' Remove ProAgents from project');
39
59
  console.log(chalk.cyan('proagents --version') + ' Show version');
40
60
  console.log('');
41
61
 
42
62
  // Commands for AI Assistants
43
63
  console.log(chalk.bold.white('Commands (for AI Assistants)'));
44
64
  console.log(chalk.gray('─'.repeat(40)));
45
- console.log(chalk.cyan('pa:init') + ' Initialize ProAgents');
46
- console.log(chalk.cyan('pa:feature "name"') + ' Start a feature');
47
- console.log(chalk.cyan('pa:fix "description"') + ' Quick bug fix');
48
- console.log(chalk.cyan('pa:status') + ' Check status');
49
- console.log(chalk.cyan('pa:doc') + ' Generate documentation');
50
- console.log(chalk.cyan('pa:qa') + ' Quality assurance');
51
- console.log(chalk.cyan('pa:test') + ' Run tests');
52
- console.log(chalk.cyan('pa:deploy') + ' Deployment workflow');
65
+ console.log(chalk.gray('Initialization:'));
66
+ console.log(chalk.cyan(' pa:init') + ' Initialize ProAgents');
67
+ console.log(chalk.cyan(' pa:help') + ' Show all commands');
68
+ console.log(chalk.cyan(' pa:status') + ' Check status');
69
+ console.log(chalk.gray('Feature Development:'));
70
+ console.log(chalk.cyan(' pa:feature "name"') + ' Start a feature');
71
+ console.log(chalk.cyan(' pa:feature-start') + ' Start new feature');
72
+ console.log(chalk.cyan(' pa:feature-status') + ' Feature status');
73
+ console.log(chalk.cyan(' pa:feature-list') + ' List features');
74
+ console.log(chalk.cyan(' pa:feature-complete') + ' Complete feature');
75
+ console.log(chalk.cyan(' pa:fix "bug"') + ' Quick bug fix');
76
+ console.log(chalk.gray('Documentation:'));
77
+ console.log(chalk.cyan(' pa:doc') + ' Documentation options');
78
+ console.log(chalk.cyan(' pa:doc-full') + ' Full documentation');
79
+ console.log(chalk.cyan(' pa:doc-moderate') + ' Balanced docs');
80
+ console.log(chalk.cyan(' pa:doc-lite') + ' Quick reference');
81
+ console.log(chalk.gray('Quality & Testing:'));
82
+ console.log(chalk.cyan(' pa:qa') + ' Quality assurance');
83
+ console.log(chalk.cyan(' pa:test') + ' Run tests');
84
+ console.log(chalk.cyan(' pa:review') + ' Code review');
85
+ console.log(chalk.gray('Deployment:'));
86
+ console.log(chalk.cyan(' pa:deploy') + ' Deployment workflow');
87
+ console.log(chalk.cyan(' pa:rollback') + ' Rollback procedures');
88
+ console.log(chalk.gray('AI Platforms:'));
89
+ console.log(chalk.cyan(' pa:ai-list') + ' List AI platforms');
90
+ console.log(chalk.cyan(' pa:ai-add') + ' Add AI platforms');
91
+ console.log(chalk.cyan(' pa:ai-remove') + ' Remove AI platforms');
92
+ console.log(chalk.gray('Configuration:'));
93
+ console.log(chalk.cyan(' pa:config') + ' Show configuration');
94
+ console.log(chalk.cyan(' pa:config-list') + ' List all options');
95
+ console.log(chalk.cyan(' pa:config-set K V') + ' Set config value');
96
+ console.log(chalk.cyan(' pa:config-get K') + ' Get config value');
97
+ console.log(chalk.cyan(' pa:config-setup') + ' Config wizard');
98
+ console.log(chalk.cyan(' pa:config-customize') + ' Copy templates');
99
+ console.log(chalk.gray('Utilities:'));
100
+ console.log(chalk.cyan(' pa:uninstall') + ' Remove ProAgents');
53
101
  console.log('');
54
102
 
55
103
  // Examples