claude-code-templates 1.14.9 → 1.14.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.
@@ -35,8 +35,8 @@ console.log(chalk.hex('#F97316')('═══════════════
35
35
  console.log(
36
36
  chalk.hex('#D97706')('🚀 Setup Claude Code for any project language 🚀') +
37
37
  chalk.gray(`\n v${pkg.version}\n\n`) +
38
- chalk.blue('🌐 Templates: ') + chalk.underline('https://davila7.github.io/claude-code-templates/') + '\n' +
39
- chalk.blue('📖 Documentation: ') + chalk.underline('https://davila7.github.io/claude-code-templates/docu/')
38
+ chalk.blue('🌐 Templates: ') + chalk.underline('https://aitmpl.com') + '\n' +
39
+ chalk.blue('📖 Documentation: ') + chalk.underline('https://docs.aitmpl.com') + '\n'
40
40
  );
41
41
 
42
42
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.14.9",
3
+ "version": "1.14.12",
4
4
  "description": "CLI tool to setup Claude Code configurations with framework-specific commands, automation hooks and MCP Servers for your projects",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -305,15 +305,23 @@ async function installIndividualAgent(agentName, targetDir, options) {
305
305
  console.log(chalk.blue(`🤖 Installing agent: ${agentName}`));
306
306
 
307
307
  try {
308
- // Download agent directly from GitHub
309
- const githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/agents/${agentName}.md`;
308
+ // Support both category/agent-name and direct agent-name formats
309
+ let githubUrl;
310
+ if (agentName.includes('/')) {
311
+ // Category/agent format: deep-research-team/academic-researcher
312
+ githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/agents/${agentName}.md`;
313
+ } else {
314
+ // Direct agent format: api-security-audit
315
+ githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/agents/${agentName}.md`;
316
+ }
317
+
310
318
  console.log(chalk.gray(`📥 Downloading from GitHub (main branch)...`));
311
319
 
312
320
  const response = await fetch(githubUrl);
313
321
  if (!response.ok) {
314
322
  if (response.status === 404) {
315
323
  console.log(chalk.red(`❌ Agent "${agentName}" not found`));
316
- console.log(chalk.yellow('Available agents: api-security-audit, database-optimization, react-performance-optimization'));
324
+ await showAvailableAgents();
317
325
  return;
318
326
  }
319
327
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
@@ -325,8 +333,16 @@ async function installIndividualAgent(agentName, targetDir, options) {
325
333
  const agentsDir = path.join(targetDir, '.claude', 'agents');
326
334
  await fs.ensureDir(agentsDir);
327
335
 
328
- // Write the agent file
329
- const targetFile = path.join(agentsDir, `${agentName}.md`);
336
+ // Write the agent file - always to flat .claude/agents directory
337
+ let fileName;
338
+ if (agentName.includes('/')) {
339
+ const [category, filename] = agentName.split('/');
340
+ fileName = filename; // Extract just the filename, ignore category for installation
341
+ } else {
342
+ fileName = agentName;
343
+ }
344
+
345
+ const targetFile = path.join(agentsDir, `${fileName}.md`);
330
346
  await fs.writeFile(targetFile, agentContent, 'utf8');
331
347
 
332
348
  console.log(chalk.green(`✅ Agent "${agentName}" installed successfully!`));
@@ -349,8 +365,16 @@ async function installIndividualCommand(commandName, targetDir, options) {
349
365
  console.log(chalk.blue(`⚡ Installing command: ${commandName}`));
350
366
 
351
367
  try {
352
- // Download command directly from GitHub
353
- const githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/commands/${commandName}.md`;
368
+ // Support both category/command-name and direct command-name formats
369
+ let githubUrl;
370
+ if (commandName.includes('/')) {
371
+ // Category/command format: security/vulnerability-scan
372
+ githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/commands/${commandName}.md`;
373
+ } else {
374
+ // Direct command format: check-file
375
+ githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/commands/${commandName}.md`;
376
+ }
377
+
354
378
  console.log(chalk.gray(`📥 Downloading from GitHub (main branch)...`));
355
379
 
356
380
  const response = await fetch(githubUrl);
@@ -369,8 +393,17 @@ async function installIndividualCommand(commandName, targetDir, options) {
369
393
  const commandsDir = path.join(targetDir, '.claude', 'commands');
370
394
  await fs.ensureDir(commandsDir);
371
395
 
372
- // Write the command file
373
- const targetFile = path.join(commandsDir, `${commandName}.md`);
396
+ // Write the command file - always to flat .claude/commands directory
397
+ let fileName;
398
+ if (commandName.includes('/')) {
399
+ const [category, filename] = commandName.split('/');
400
+ fileName = filename; // Extract just the filename, ignore category for installation
401
+ } else {
402
+ fileName = commandName;
403
+ }
404
+
405
+ const targetFile = path.join(commandsDir, `${fileName}.md`);
406
+
374
407
  await fs.writeFile(targetFile, commandContent, 'utf8');
375
408
 
376
409
  console.log(chalk.green(`✅ Command "${commandName}" installed successfully!`));
@@ -393,8 +426,16 @@ async function installIndividualMCP(mcpName, targetDir, options) {
393
426
  console.log(chalk.blue(`🔌 Installing MCP: ${mcpName}`));
394
427
 
395
428
  try {
396
- // Download MCP directly from GitHub
397
- const githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/mcps/${mcpName}.json`;
429
+ // Support both category/mcp-name and direct mcp-name formats
430
+ let githubUrl;
431
+ if (mcpName.includes('/')) {
432
+ // Category/mcp format: database/mysql-integration
433
+ githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/mcps/${mcpName}.json`;
434
+ } else {
435
+ // Direct mcp format: web-fetch
436
+ githubUrl = `https://raw.githubusercontent.com/davila7/claude-code-templates/main/cli-tool/components/mcps/${mcpName}.json`;
437
+ }
438
+
398
439
  console.log(chalk.gray(`📥 Downloading from GitHub (main branch)...`));
399
440
 
400
441
  const response = await fetch(githubUrl);
@@ -480,4 +521,92 @@ function extractFrameworkFromAgent(content, agentName) {
480
521
  return 'none';
481
522
  }
482
523
 
524
+ /**
525
+ * Fetch available agents dynamically from GitHub repository
526
+ */
527
+ async function getAvailableAgentsFromGitHub() {
528
+ try {
529
+ const response = await fetch('https://api.github.com/repos/davila7/claude-code-templates/contents/cli-tool/components/agents');
530
+ if (!response.ok) {
531
+ throw new Error(`GitHub API error: ${response.status}`);
532
+ }
533
+
534
+ const contents = await response.json();
535
+ const agents = [];
536
+
537
+ for (const item of contents) {
538
+ if (item.type === 'file' && item.name.endsWith('.md')) {
539
+ // Direct agent file
540
+ agents.push({
541
+ name: item.name.replace('.md', ''),
542
+ path: item.name.replace('.md', ''),
543
+ category: 'root'
544
+ });
545
+ } else if (item.type === 'dir') {
546
+ // Category directory, fetch its contents
547
+ try {
548
+ const categoryResponse = await fetch(`https://api.github.com/repos/davila7/claude-code-templates/contents/cli-tool/components/agents/${item.name}`);
549
+ if (categoryResponse.ok) {
550
+ const categoryContents = await categoryResponse.json();
551
+ for (const categoryItem of categoryContents) {
552
+ if (categoryItem.type === 'file' && categoryItem.name.endsWith('.md')) {
553
+ agents.push({
554
+ name: categoryItem.name.replace('.md', ''),
555
+ path: `${item.name}/${categoryItem.name.replace('.md', '')}`,
556
+ category: item.name
557
+ });
558
+ }
559
+ }
560
+ }
561
+ } catch (error) {
562
+ console.warn(`Warning: Could not fetch category ${item.name}:`, error.message);
563
+ }
564
+ }
565
+ }
566
+
567
+ return agents;
568
+ } catch (error) {
569
+ console.warn('Warning: Could not fetch agents from GitHub, using fallback list');
570
+ // Fallback to basic list if GitHub API fails
571
+ return [
572
+ { name: 'api-security-audit', path: 'api-security-audit', category: 'root' },
573
+ { name: 'database-optimization', path: 'database-optimization', category: 'root' },
574
+ { name: 'react-performance-optimization', path: 'react-performance-optimization', category: 'root' }
575
+ ];
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Show available agents organized by category
581
+ */
582
+ async function showAvailableAgents() {
583
+ console.log(chalk.yellow('\n📋 Available Agents:'));
584
+ console.log(chalk.gray('Use format: category/agent-name or just agent-name for root level\n'));
585
+ console.log(chalk.gray('⏳ Fetching latest agents from GitHub...\n'));
586
+
587
+ const agents = await getAvailableAgentsFromGitHub();
588
+
589
+ // Group agents by category
590
+ const groupedAgents = agents.reduce((acc, agent) => {
591
+ const category = agent.category === 'root' ? '🤖 General Agents' : `📁 ${agent.category}`;
592
+ if (!acc[category]) acc[category] = [];
593
+ acc[category].push(agent);
594
+ return acc;
595
+ }, {});
596
+
597
+ // Display agents by category
598
+ Object.entries(groupedAgents).forEach(([category, categoryAgents]) => {
599
+ console.log(chalk.cyan(category));
600
+ categoryAgents.forEach(agent => {
601
+ console.log(chalk.gray(` • ${agent.path}`));
602
+ });
603
+ console.log('');
604
+ });
605
+
606
+ console.log(chalk.blue('Examples:'));
607
+ console.log(chalk.gray(' cct --agent api-security-audit'));
608
+ console.log(chalk.gray(' cct --agent deep-research-team/academic-researcher'));
609
+ console.log('');
610
+ }
611
+
483
612
  module.exports = { createClaudeConfig, showMainMenu };