claude-code-templates 1.20.0 → 1.20.2

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.
@@ -23,21 +23,23 @@ function colorizeTitle(text) {
23
23
  .join('');
24
24
  }
25
25
 
26
- console.clear();
27
- console.log(chalk.hex('#F97316')('════════════════════════════════════════════════════════════════'));
28
- console.log('\n');
29
- console.log(' 🔮 ' + colorizeTitle(title));
30
- console.log('\n');
31
- console.log(' ' + chalk.hex('#FDBA74')(subtitle));
32
- console.log('\n');
33
- console.log(chalk.hex('#F97316')('════════════════════════════════════════════════════════════════\n'));
26
+ function showBanner() {
27
+ console.clear();
28
+ console.log(chalk.hex('#F97316')('════════════════════════════════════════════════════════════════'));
29
+ console.log('\n');
30
+ console.log(' 🔮 ' + colorizeTitle(title));
31
+ console.log('\n');
32
+ console.log(' ' + chalk.hex('#FDBA74')(subtitle));
33
+ console.log('\n');
34
+ console.log(chalk.hex('#F97316')('════════════════════════════════════════════════════════════════\n'));
34
35
 
35
- console.log(
36
- chalk.hex('#D97706')('🚀 Setup Claude Code for any project language 🚀') +
37
- chalk.gray(`\n v${pkg.version}\n\n`) +
38
- chalk.blue('🌐 Templates: ') + chalk.underline('https://aitmpl.com') + '\n' +
39
- chalk.blue('📖 Documentation: ') + chalk.underline('https://docs.aitmpl.com') + '\n'
40
- );
36
+ console.log(
37
+ chalk.hex('#D97706')('🚀 Setup Claude Code for any project language 🚀') +
38
+ chalk.gray(`\n v${pkg.version}\n\n`) +
39
+ chalk.blue('🌐 Templates: ') + chalk.underline('https://aitmpl.com') + '\n' +
40
+ chalk.blue('📖 Documentation: ') + chalk.underline('https://docs.aitmpl.com') + '\n'
41
+ );
42
+ }
41
43
 
42
44
  program
43
45
  .name('create-claude-config')
@@ -72,6 +74,15 @@ program
72
74
  .option('--update-agent <agent>', 'update a global agent to the latest version')
73
75
  .action(async (options) => {
74
76
  try {
77
+ // Only show banner for non-agent-list commands
78
+ const isQuietCommand = options.listAgents ||
79
+ options.removeAgent ||
80
+ options.updateAgent;
81
+
82
+ if (!isQuietCommand) {
83
+ showBanner();
84
+ }
85
+
75
86
  await createClaudeConfig(options);
76
87
  } catch (error) {
77
88
  console.error(chalk.red('Error:'), error.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.20.0",
3
+ "version": "1.20.2",
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
@@ -607,6 +607,7 @@ async function installIndividualSetting(settingName, targetDir, options) {
607
607
  if (response.status === 404) {
608
608
  console.log(chalk.red(`❌ Setting "${settingName}" not found`));
609
609
  console.log(chalk.yellow('Available settings: enable-telemetry, disable-telemetry, allow-npm-commands, deny-sensitive-files, use-sonnet, use-haiku, retention-7-days, retention-90-days'));
610
+ console.log(chalk.yellow('Available statuslines: statusline/context-monitor'));
610
611
  return;
611
612
  }
612
613
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
@@ -615,9 +616,39 @@ async function installIndividualSetting(settingName, targetDir, options) {
615
616
  const settingConfigText = await response.text();
616
617
  const settingConfig = JSON.parse(settingConfigText);
617
618
 
618
- // Remove description field before merging
619
+ // Check if there are additional files to download (e.g., Python scripts)
620
+ const additionalFiles = {};
621
+
622
+ // For statusline settings, check if there's a corresponding Python file
623
+ if (settingName.includes('statusline/')) {
624
+ const pythonFileName = settingName.split('/')[1] + '.py';
625
+ const pythonUrl = githubUrl.replace('.json', '.py');
626
+
627
+ try {
628
+ console.log(chalk.gray(`📥 Downloading Python script: ${pythonFileName}...`));
629
+ const pythonResponse = await fetch(pythonUrl);
630
+ if (pythonResponse.ok) {
631
+ const pythonContent = await pythonResponse.text();
632
+ additionalFiles['.claude/scripts/' + pythonFileName] = {
633
+ content: pythonContent,
634
+ executable: true
635
+ };
636
+ }
637
+ } catch (error) {
638
+ console.log(chalk.yellow(`⚠️ Could not download Python script: ${error.message}`));
639
+ }
640
+ }
641
+
642
+ // Extract and handle additional files before removing them from config
643
+ const configFiles = settingConfig.files || {};
644
+
645
+ // Merge downloaded files with config files
646
+ Object.assign(additionalFiles, configFiles);
647
+
648
+ // Remove description and files fields before merging
619
649
  if (settingConfig && typeof settingConfig === 'object') {
620
650
  delete settingConfig.description;
651
+ delete settingConfig.files;
621
652
  }
622
653
 
623
654
  // Use shared locations if provided (batch mode), otherwise ask user
@@ -817,6 +848,37 @@ async function installIndividualSetting(settingName, targetDir, options) {
817
848
  // Write the merged configuration
818
849
  await fs.writeJson(actualTargetFile, mergedConfig, { spaces: 2 });
819
850
 
851
+ // Install additional files if any exist
852
+ if (Object.keys(additionalFiles).length > 0) {
853
+ console.log(chalk.blue(`📄 Installing ${Object.keys(additionalFiles).length} additional file(s)...`));
854
+
855
+ for (const [filePath, fileConfig] of Object.entries(additionalFiles)) {
856
+ try {
857
+ // Resolve tilde (~) to home directory
858
+ const resolvedFilePath = filePath.startsWith('~')
859
+ ? path.join(require('os').homedir(), filePath.slice(1))
860
+ : path.resolve(currentTargetDir, filePath);
861
+
862
+ // Ensure directory exists
863
+ await fs.ensureDir(path.dirname(resolvedFilePath));
864
+
865
+ // Write file content
866
+ await fs.writeFile(resolvedFilePath, fileConfig.content, 'utf8');
867
+
868
+ // Make file executable if specified
869
+ if (fileConfig.executable) {
870
+ await fs.chmod(resolvedFilePath, 0o755);
871
+ console.log(chalk.gray(`🔧 Made executable: ${resolvedFilePath}`));
872
+ }
873
+
874
+ console.log(chalk.green(`✅ File installed: ${resolvedFilePath}`));
875
+
876
+ } catch (fileError) {
877
+ console.log(chalk.red(`❌ Failed to install file ${filePath}: ${fileError.message}`));
878
+ }
879
+ }
880
+ }
881
+
820
882
  if (!options.silent) {
821
883
  console.log(chalk.green(`✅ Setting "${settingName}" installed successfully in ${installLocation}!`));
822
884
  console.log(chalk.cyan(`📁 Configuration merged into: ${actualTargetFile}`));
@@ -265,7 +265,10 @@ if (!fs.existsSync(agentPath)) {
265
265
  process.exit(1);
266
266
  }
267
267
 
268
- const systemPrompt = fs.readFileSync(agentPath, 'utf8');
268
+ const rawSystemPrompt = fs.readFileSync(agentPath, 'utf8');
269
+
270
+ // Remove YAML front matter if present to get clean system prompt
271
+ const systemPrompt = rawSystemPrompt.replace(/^---[\\s\\S]*?---\\n/, '').trim();
269
272
 
270
273
  // Parse arguments and detect context
271
274
  const args = process.argv.slice(2);
@@ -275,6 +278,8 @@ let explicitDirs = [];
275
278
  let autoDetect = true;
276
279
 
277
280
  // Parse command line arguments
281
+ let verbose = false;
282
+
278
283
  for (let i = 0; i < args.length; i++) {
279
284
  const arg = args[i];
280
285
 
@@ -286,6 +291,8 @@ for (let i = 0; i < args.length; i++) {
286
291
  autoDetect = false;
287
292
  } else if (arg === '--no-auto') {
288
293
  autoDetect = false;
294
+ } else if (arg === '--verbose' || arg === '-v') {
295
+ verbose = true;
289
296
  } else if (arg === '--help' || arg === '-h') {
290
297
  console.log('Usage: ${agentName} [options] "your prompt"');
291
298
  console.log('');
@@ -294,6 +301,7 @@ for (let i = 0; i < args.length; i++) {
294
301
  console.log(' --file <path> Include specific file');
295
302
  console.log(' --dir <path> Include specific directory');
296
303
  console.log(' --no-auto Disable auto-detection');
304
+ console.log(' --verbose, -v Enable verbose debugging output');
297
305
  console.log('');
298
306
  console.log('Examples:');
299
307
  console.log(' ${agentName} "review for security issues" # Auto-detect');
@@ -385,8 +393,20 @@ const escapedSystemPrompt = systemPrompt.replace(/"/g, '\\\\"').replace(/\`/g, '
385
393
  const finalPrompt = userInput + contextPrompt;
386
394
  const escapedFinalPrompt = finalPrompt.replace(/"/g, '\\\\"').replace(/\`/g, '\\\\\`');
387
395
 
388
- // Build Claude command with SDK
389
- const claudeCmd = \`claude -p "\${escapedFinalPrompt}" --append-system-prompt "\${escapedSystemPrompt}"\`;
396
+ // Build Claude command with SDK - use --system-prompt instead of --append-system-prompt for better control
397
+ const claudeCmd = \`claude -p "\${escapedFinalPrompt}" --system-prompt "\${escapedSystemPrompt}"\${verbose ? ' --verbose' : ''}\`;
398
+
399
+ // Debug output if verbose
400
+ if (verbose) {
401
+ console.log('\\n🔍 DEBUG MODE - Command Details:');
402
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
403
+ console.log('📝 User Input:', userInput);
404
+ console.log('📁 Project Context:', contextPrompt ? 'Auto-detected' : 'None');
405
+ console.log('🎯 Final Prompt Length:', finalPrompt.length, 'characters');
406
+ console.log('🤖 System Prompt Preview:', systemPrompt.substring(0, 150) + '...');
407
+ console.log('⚡ Claude Command:', claudeCmd);
408
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n');
409
+ }
390
410
 
391
411
  // Show loading indicator
392
412
  const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];