agents-templated 1.2.9 → 1.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/cli.js +141 -177
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -181,9 +181,9 @@ program
181
181
 
182
182
  console.log(chalk.green.bold('\nInstallation complete!\n'));
183
183
  console.log(chalk.cyan('Next steps:'));
184
- console.log(chalk.white(' 1. Review AGENTS.md for generic AI assistant guide'));
184
+ console.log(chalk.white(' 1. Review AGENTS.MD for generic AI assistant guide'));
185
185
  console.log(chalk.white(' 2. Review agent-docs/ARCHITECTURE.md for project guidelines'));
186
- console.log(chalk.white(' 3. Review AGENTS.md for AI assistant guide'));
186
+ console.log(chalk.white(' 3. Review AGENTS.MD for AI assistant guide'));
187
187
  console.log(chalk.white(' 4. Configure your AI assistant (Cursor, Copilot, etc.)'));
188
188
  console.log(chalk.white(' 5. Adapt the rules to your technology stack\n'));
189
189
 
@@ -195,89 +195,69 @@ program
195
195
 
196
196
  program
197
197
  .command('wizard')
198
- .description('Interactive setup wizard with tech stack recommendations')
198
+ .description('Interactive setup wizard')
199
199
  .action(async () => {
200
200
  try {
201
201
  const templateDir = getTemplatesDir();
202
+ const targetDir = process.cwd();
202
203
  console.log(chalk.blue.bold('\nšŸ§™ Agents Templated Setup Wizard\n'));
203
204
  console.log(chalk.gray('Let\'s set up your project with the right patterns and guidelines.\n'));
204
205
 
205
- // Step 1: Tech stack selection
206
- const stackAnswers = await inquirer.prompt([
207
- {
208
- type: 'list',
209
- name: 'category',
210
- message: 'What type of project is this?',
211
- choices: [
212
- { name: '🌐 Full-stack Web Application', value: 'fullstack' },
213
- { name: 'āš›ļø Frontend Only', value: 'frontend' },
214
- { name: 'šŸ”§ Backend API', value: 'backend' },
215
- { name: 'šŸ“¦ NPM Package/Library', value: 'package' },
216
- { name: 'šŸ¤– CLI Tool', value: 'cli' },
217
- { name: 'šŸŽÆ Custom/Other', value: 'custom' }
218
- ]
219
- }
220
- ]);
206
+ const hasExistingSetup = await hasInstalledTemplates(targetDir);
207
+ if (hasExistingSetup) {
208
+ console.log(chalk.cyan('Detected an existing agents-templated setup in this project.\n'));
221
209
 
222
- let techStack = {};
223
-
224
- if (stackAnswers.category === 'fullstack' || stackAnswers.category === 'frontend') {
225
- const frontendAnswers = await inquirer.prompt([
210
+ const modeAnswer = await inquirer.prompt([
226
211
  {
227
212
  type: 'list',
228
- name: 'framework',
229
- message: 'Which frontend framework?',
213
+ name: 'mode',
214
+ message: 'How would you like to proceed?',
230
215
  choices: [
231
- 'React / Next.js',
232
- 'Vue / Nuxt',
233
- 'Angular',
234
- 'Svelte / SvelteKit',
235
- 'Vanilla JS / HTML',
236
- 'Other'
237
- ]
216
+ { name: 'Update existing setup (recommended)', value: 'update' },
217
+ { name: 'Run full setup flow', value: 'setup' }
218
+ ],
219
+ default: 'update'
238
220
  }
239
221
  ]);
240
- techStack.frontend = frontendAnswers.framework;
241
- }
242
222
 
243
- if (stackAnswers.category === 'fullstack' || stackAnswers.category === 'backend') {
244
- const backendAnswers = await inquirer.prompt([
245
- {
246
- type: 'list',
247
- name: 'framework',
248
- message: 'Which backend framework?',
249
- choices: [
250
- 'Node.js (Express/Fastify)',
251
- 'Python (Django/FastAPI)',
252
- 'Go',
253
- 'Rust',
254
- 'Java / Spring Boot',
255
- 'Ruby on Rails',
256
- 'PHP (Laravel)',
257
- 'Other'
258
- ]
259
- },
260
- {
261
- type: 'list',
262
- name: 'database',
263
- message: 'Which database?',
264
- choices: [
265
- 'PostgreSQL',
266
- 'MySQL / MariaDB',
267
- 'MongoDB',
268
- 'SQLite',
269
- 'Supabase',
270
- 'Firebase',
271
- 'None / Not sure yet',
272
- 'Other'
273
- ]
274
- }
275
- ]);
276
- techStack.backend = backendAnswers.framework;
277
- techStack.database = backendAnswers.database;
223
+ if (modeAnswer.mode === 'update') {
224
+ const updateAnswers = await inquirer.prompt([
225
+ {
226
+ type: 'checkbox',
227
+ name: 'components',
228
+ message: 'Select components to update:',
229
+ choices: [
230
+ { name: 'All components', value: 'all', checked: true },
231
+ { name: 'Documentation (agent-docs/)', value: 'docs' },
232
+ { name: 'Agent Rules (security, testing, database, etc.)', value: 'rules' },
233
+ { name: 'Skills (reusable agent capabilities)', value: 'skills' },
234
+ { name: 'AI Agent instructions (Cursor, Copilot, VSCode, Gemini)', value: 'github' }
235
+ ],
236
+ validate: (answer) => {
237
+ if (answer.length === 0) {
238
+ return 'You must choose at least one component.';
239
+ }
240
+ return true;
241
+ }
242
+ },
243
+ {
244
+ type: 'confirm',
245
+ name: 'overwrite',
246
+ message: 'Overwrite existing files while updating?',
247
+ default: true
248
+ }
249
+ ]);
250
+
251
+ console.log(chalk.blue('\nšŸ“¦ Updating selected components...\n'));
252
+ await updateSelectedComponents(targetDir, templateDir, updateAnswers.components, updateAnswers.overwrite);
253
+
254
+ console.log(chalk.green.bold('\nāœ… Update complete!\n'));
255
+ console.log(chalk.gray('Tip: run "agents-templated validate" to verify your setup.\n'));
256
+ return;
257
+ }
278
258
  }
279
259
 
280
- // Step 2: Component selection
260
+ // Component selection
281
261
  const componentAnswers = await inquirer.prompt([
282
262
  {
283
263
  type: 'checkbox',
@@ -307,7 +287,6 @@ program
307
287
  // Step 3: Install components
308
288
  console.log(chalk.blue('\nšŸ“¦ Installing components...\n'));
309
289
 
310
- const targetDir = process.cwd();
311
290
  const options = {
312
291
  force: componentAnswers.overwrite,
313
292
  docs: componentAnswers.components.includes('docs'),
@@ -354,60 +333,25 @@ program
354
333
  await copyFiles(templateDir, targetDir, [
355
334
  '.cursorrules',
356
335
  '.github/copilot-instructions.md',
357
- 'AGENTS.md',
336
+ 'AGENTS.MD',
358
337
  'CLAUDE.md',
359
338
  'GEMINI.md'
360
339
  ], options.force);
361
340
  console.log(chalk.gray(' āœ“ Cursor (.cursorrules)'));
362
341
  console.log(chalk.gray(' āœ“ GitHub Copilot (.github/copilot-instructions.md)'));
363
- console.log(chalk.gray(' āœ“ Generic AI (AGENTS.md)'));
342
+ console.log(chalk.gray(' āœ“ Generic AI (AGENTS.MD)'));
364
343
  console.log(chalk.gray(' āœ“ Claude (CLAUDE.md)'));
365
344
  console.log(chalk.gray(' āœ“ Google Gemini (GEMINI.md)'));
366
345
  }
367
346
 
368
- // Step 4: Show recommendations
347
+ // Show summary and next steps
369
348
  console.log(chalk.green.bold('\nāœ… Installation complete!\n'));
370
349
 
371
- console.log(chalk.blue('šŸ“‹ Your Project Setup:\n'));
372
- if (techStack.frontend) console.log(chalk.white(` Frontend: ${techStack.frontend}`));
373
- if (techStack.backend) console.log(chalk.white(` Backend: ${techStack.backend}`));
374
- if (techStack.database) console.log(chalk.white(` Database: ${techStack.database}`));
375
-
376
350
  console.log(chalk.cyan('\nšŸ“š Next Steps:\n'));
377
- console.log(chalk.white(' 1. Review AGENTS.md for AI assistant guide'));
351
+ console.log(chalk.white(' 1. Review AGENTS.MD for AI assistant guide'));
378
352
  console.log(chalk.white(' 2. Review agent-docs/ARCHITECTURE.md for project guidelines'));
379
- console.log(chalk.white(' 3. Review AGENTS.md for AI assistant guide'));
380
- console.log(chalk.white(' 3. Customize agents/rules/*.mdc for your tech stack'));
381
-
382
- if (techStack.frontend || techStack.backend) {
383
- console.log(chalk.cyan('\nšŸ“¦ Recommended Packages:\n'));
384
-
385
- if (techStack.frontend?.includes('React')) {
386
- console.log(chalk.white(' npm install react react-dom next typescript'));
387
- console.log(chalk.white(' npm install -D @types/react @types/node'));
388
- } else if (techStack.frontend?.includes('Vue')) {
389
- console.log(chalk.white(' npm install vue nuxt typescript'));
390
- } else if (techStack.frontend?.includes('Svelte')) {
391
- console.log(chalk.white(' npm install svelte @sveltejs/kit typescript'));
392
- }
393
-
394
- if (techStack.backend?.includes('Node.js')) {
395
- console.log(chalk.white(' npm install express zod dotenv'));
396
- console.log(chalk.white(' npm install -D @types/express'));
397
- } else if (techStack.backend?.includes('Python')) {
398
- console.log(chalk.white(' pip install django djangorestframework pydantic'));
399
- } else if (techStack.backend?.includes('Go')) {
400
- console.log(chalk.white(' go get github.com/gin-gonic/gin'));
401
- }
402
-
403
- if (techStack.database?.includes('PostgreSQL')) {
404
- console.log(chalk.white(' npm install @prisma/client (or) npm install pg'));
405
- } else if (techStack.database?.includes('MongoDB')) {
406
- console.log(chalk.white(' npm install mongoose'));
407
- } else if (techStack.database?.includes('Supabase')) {
408
- console.log(chalk.white(' npm install @supabase/supabase-js'));
409
- }
410
- }
353
+ console.log(chalk.white(' 3. Review AGENTS.MD for AI assistant guide'));
354
+ console.log(chalk.white(' 4. Customize agents/rules/*.mdc for your tech stack'));
411
355
 
412
356
  console.log(chalk.cyan('\nšŸ”’ Security Reminder:\n'));
413
357
  console.log(chalk.white(' • Review agents/rules/security.mdc'));
@@ -455,10 +399,12 @@ program
455
399
  let passed = [];
456
400
 
457
401
  // Check documentation files
458
- if (await fs.pathExists(path.join(targetDir, 'AGENTS.md'))) {
459
- passed.push(`āœ“ AGENTS.md found`);
402
+ if (await fs.pathExists(path.join(targetDir, 'AGENTS.MD'))) {
403
+ passed.push(`āœ“ AGENTS.MD found`);
404
+ } else if (await fs.pathExists(path.join(targetDir, 'AGENTS.md'))) {
405
+ passed.push(`āœ“ AGENTS.md found (legacy filename)`);
460
406
  } else {
461
- warnings.push(`⚠ AGENTS.md missing - run 'agents-templated init --docs'`);
407
+ warnings.push(`⚠ AGENTS.MD missing - run 'agents-templated init --docs'`);
462
408
  }
463
409
 
464
410
  const docFiles = ['ARCHITECTURE.md'];
@@ -639,6 +585,60 @@ async function copyDirectory(sourceDir, targetDir, force = false) {
639
585
  }
640
586
  }
641
587
 
588
+ async function hasInstalledTemplates(targetDir) {
589
+ return await fs.pathExists(path.join(targetDir, 'AGENTS.MD')) ||
590
+ await fs.pathExists(path.join(targetDir, 'AGENTS.md')) ||
591
+ await fs.pathExists(path.join(targetDir, 'agents'));
592
+ }
593
+
594
+ async function updateSelectedComponents(targetDir, templateDir, selectedComponents, overwrite = true) {
595
+ const components = selectedComponents.includes('all')
596
+ ? ['docs', 'rules', 'skills', 'github']
597
+ : selectedComponents;
598
+
599
+ if (components.includes('docs')) {
600
+ console.log(chalk.yellow('Updating documentation files...'));
601
+ await fs.ensureDir(path.join(targetDir, 'agent-docs'));
602
+ await copyDirectory(
603
+ path.join(templateDir, 'agent-docs'),
604
+ path.join(targetDir, 'agent-docs'),
605
+ overwrite
606
+ );
607
+ }
608
+
609
+ if (components.includes('rules')) {
610
+ console.log(chalk.yellow('Updating agent rules...'));
611
+ await fs.ensureDir(path.join(targetDir, 'agents', 'rules'));
612
+ await copyDirectory(
613
+ path.join(templateDir, 'agents', 'rules'),
614
+ path.join(targetDir, 'agents', 'rules'),
615
+ overwrite
616
+ );
617
+ }
618
+
619
+ if (components.includes('skills')) {
620
+ console.log(chalk.yellow('Updating skills...'));
621
+ await fs.ensureDir(path.join(targetDir, 'agents', 'skills'));
622
+ await copyDirectory(
623
+ path.join(templateDir, 'agents', 'skills'),
624
+ path.join(targetDir, 'agents', 'skills'),
625
+ overwrite
626
+ );
627
+ }
628
+
629
+ if (components.includes('github')) {
630
+ console.log(chalk.yellow('Updating AI agent instructions...'));
631
+ await fs.ensureDir(path.join(targetDir, '.github'));
632
+ await copyFiles(templateDir, targetDir, [
633
+ '.cursorrules',
634
+ '.github/copilot-instructions.md',
635
+ 'AGENTS.MD',
636
+ 'CLAUDE.md',
637
+ 'GEMINI.md'
638
+ ], overwrite);
639
+ }
640
+ }
641
+
642
642
  program
643
643
  .command('update')
644
644
  .description('Check for and apply template updates')
@@ -657,8 +657,7 @@ program
657
657
  console.log(chalk.blue.bold('\nšŸ”„ Checking for template updates...\n'));
658
658
 
659
659
  // Check if templates are installed
660
- const hasTemplates = await fs.pathExists(path.join(targetDir, 'AGENTS.md')) ||
661
- await fs.pathExists(path.join(targetDir, 'agents'));
660
+ const hasTemplates = await hasInstalledTemplates(targetDir);
662
661
 
663
662
  if (!hasTemplates) {
664
663
  console.log(chalk.yellow('No templates detected in this directory.'));
@@ -678,46 +677,7 @@ program
678
677
 
679
678
  console.log(chalk.blue('šŸ“¦ Updating selected components...\n'));
680
679
 
681
- if (selectedComponents.includes('docs')) {
682
- console.log(chalk.yellow('Updating documentation files...'));
683
- await fs.ensureDir(path.join(targetDir, 'agent-docs'));
684
- await copyDirectory(
685
- path.join(templateDir, 'agent-docs'),
686
- path.join(targetDir, 'agent-docs'),
687
- true
688
- );
689
- }
690
-
691
- if (selectedComponents.includes('rules')) {
692
- console.log(chalk.yellow('Updating agent rules...'));
693
- await fs.ensureDir(path.join(targetDir, 'agents', 'rules'));
694
- await copyDirectory(
695
- path.join(templateDir, 'agents', 'rules'),
696
- path.join(targetDir, 'agents', 'rules'),
697
- true
698
- );
699
- }
700
-
701
- if (selectedComponents.includes('skills')) {
702
- console.log(chalk.yellow('Updating skills...'));
703
- await fs.ensureDir(path.join(targetDir, 'agents', 'skills'));
704
- await copyDirectory(
705
- path.join(templateDir, 'agents', 'skills'),
706
- path.join(targetDir, 'agents', 'skills'),
707
- true
708
- );
709
- }
710
-
711
- if (selectedComponents.includes('github')) {
712
- console.log(chalk.yellow('Updating AI agent instructions...'));
713
- await fs.ensureDir(path.join(targetDir, '.github'));
714
- await copyFiles(templateDir, targetDir, [
715
- '.cursorrules',
716
- '.github/copilot-instructions.md',
717
- 'CLAUDE.md',
718
- 'GEMINI.md'
719
- ], true);
720
- }
680
+ await updateSelectedComponents(targetDir, templateDir, selectedComponents, true);
721
681
 
722
682
  console.log(chalk.green.bold('\nāœ… Selected component updates applied successfully!\n'));
723
683
  process.exit(0);
@@ -725,28 +685,32 @@ program
725
685
 
726
686
  // List potential updates
727
687
  const updates = [];
688
+ const rootAgentsTargetFile = (await fs.pathExists(path.join(targetDir, 'AGENTS.MD')))
689
+ ? 'AGENTS.MD'
690
+ : ((await fs.pathExists(path.join(targetDir, 'AGENTS.md'))) ? 'AGENTS.md' : 'AGENTS.MD');
691
+
728
692
  const checkFiles = [
729
- { file: 'AGENTS.md', component: 'root' },
730
- { file: 'agent-docs/ARCHITECTURE.md', component: 'docs' },
731
- { file: 'agents/rules/security.mdc', component: 'rules' },
732
- { file: 'agents/rules/testing.mdc', component: 'rules' },
733
- { file: 'agents/rules/core.mdc', component: 'rules' },
734
- { file: 'agents/skills/README.md', component: 'skills' },
735
- { file: 'agents/skills/find-skills/SKILL.md', component: 'skills' },
736
- { file: 'agents/skills/ui-ux-pro-max/SKILL.md', component: 'skills' },
737
- { file: '.github/copilot-instructions.md', component: 'github' }
693
+ { targetFile: rootAgentsTargetFile, templateFile: 'AGENTS.MD', component: 'root' },
694
+ { targetFile: 'agent-docs/ARCHITECTURE.md', templateFile: 'agent-docs/ARCHITECTURE.md', component: 'docs' },
695
+ { targetFile: 'agents/rules/security.mdc', templateFile: 'agents/rules/security.mdc', component: 'rules' },
696
+ { targetFile: 'agents/rules/testing.mdc', templateFile: 'agents/rules/testing.mdc', component: 'rules' },
697
+ { targetFile: 'agents/rules/core.mdc', templateFile: 'agents/rules/core.mdc', component: 'rules' },
698
+ { targetFile: 'agents/skills/README.md', templateFile: 'agents/skills/README.md', component: 'skills' },
699
+ { targetFile: 'agents/skills/find-skills/SKILL.md', templateFile: 'agents/skills/find-skills/SKILL.md', component: 'skills' },
700
+ { targetFile: 'agents/skills/ui-ux-pro-max/SKILL.md', templateFile: 'agents/skills/ui-ux-pro-max/SKILL.md', component: 'skills' },
701
+ { targetFile: '.github/copilot-instructions.md', templateFile: '.github/copilot-instructions.md', component: 'github' }
738
702
  ];
739
703
 
740
- for (const {file, component} of checkFiles) {
741
- const targetPath = path.join(targetDir, file);
742
- const templatePath = path.join(templateDir, file);
704
+ for (const {targetFile, templateFile, component} of checkFiles) {
705
+ const targetPath = path.join(targetDir, targetFile);
706
+ const templatePath = path.join(templateDir, templateFile);
743
707
 
744
708
  if (await fs.pathExists(targetPath) && await fs.pathExists(templatePath)) {
745
709
  const targetContent = await fs.readFile(targetPath, 'utf8');
746
710
  const templateContent = await fs.readFile(templatePath, 'utf8');
747
711
 
748
712
  if (targetContent !== templateContent) {
749
- updates.push({ file, component });
713
+ updates.push({ targetFile, templateFile, component });
750
714
  }
751
715
  }
752
716
  }
@@ -757,8 +721,8 @@ program
757
721
  }
758
722
 
759
723
  console.log(chalk.yellow(`Found ${updates.length} file(s) with updates available:\n`));
760
- updates.forEach(({ file }) => {
761
- console.log(chalk.white(` šŸ“„ ${file}`));
724
+ updates.forEach(({ targetFile }) => {
725
+ console.log(chalk.white(` šŸ“„ ${targetFile}`));
762
726
  });
763
727
  console.log('');
764
728
 
@@ -785,18 +749,18 @@ program
785
749
  // Apply updates
786
750
  console.log(chalk.blue('\nšŸ“¦ Applying updates...\n'));
787
751
 
788
- for (const { file } of updates) {
789
- const targetPath = path.join(targetDir, file);
790
- const templatePath = path.join(templateDir, file);
752
+ for (const { targetFile, templateFile } of updates) {
753
+ const targetPath = path.join(targetDir, targetFile);
754
+ const templatePath = path.join(templateDir, templateFile);
791
755
 
792
756
  // Backup original file
793
757
  const backupPath = `${targetPath}.backup`;
794
758
  await fs.copy(targetPath, backupPath);
795
- console.log(chalk.gray(` Backed up: ${file}.backup`));
759
+ console.log(chalk.gray(` Backed up: ${targetFile}.backup`));
796
760
 
797
761
  // Copy new version
798
762
  await fs.copy(templatePath, targetPath, { overwrite: true });
799
- console.log(chalk.green(` āœ“ Updated: ${file}`));
763
+ console.log(chalk.green(` āœ“ Updated: ${targetFile}`));
800
764
  }
801
765
 
802
766
  console.log(chalk.green.bold('\nāœ… Updates applied successfully!\n'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-templated",
3
- "version": "1.2.9",
3
+ "version": "1.2.10",
4
4
  "description": "Technology-agnostic development template with multi-AI agent support (Cursor, Copilot, VSCode, Gemini), security-first patterns, and comprehensive testing guidelines",
5
5
  "main": "index.js",
6
6
  "bin": {