claude-code-templates 1.11.0 → 1.12.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
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": {
@@ -31,7 +31,6 @@
31
31
  "dev:link": "npm link",
32
32
  "dev:unlink": "npm unlink -g claude-code-templates",
33
33
  "pretest:commands": "npm run dev:link",
34
- "prepublishOnly": "echo 'Skipping tests for emergency publish'",
35
34
  "analytics:start": "node src/analytics.js",
36
35
  "analytics:test": "npm run test:analytics"
37
36
  },
@@ -101,7 +101,7 @@ class ConversationAnalyzer {
101
101
 
102
102
  try {
103
103
  // Extract project name from path
104
- const projectFromPath = this.extractProjectFromPath(filePath);
104
+ const projectFromPath = await this.extractProjectFromPath(filePath);
105
105
 
106
106
  // Use cached parsed conversation if available
107
107
  const parsedMessages = await this.getParsedConversation(filePath);
@@ -113,6 +113,9 @@ class ConversationAnalyzer {
113
113
  // Calculate tool usage data with caching
114
114
  const toolUsage = await this.getCachedToolUsage(filePath, parsedMessages);
115
115
 
116
+ const projectFromConversation = await this.extractProjectFromConversation(filePath);
117
+ const finalProject = projectFromConversation || projectFromPath;
118
+
116
119
  const conversation = {
117
120
  id: filename.replace('.jsonl', ''),
118
121
  filename: filename,
@@ -125,7 +128,7 @@ class ConversationAnalyzer {
125
128
  tokenUsage: tokenUsage,
126
129
  modelInfo: modelInfo,
127
130
  toolUsage: toolUsage,
128
- project: projectFromPath || this.extractProjectFromConversation(parsedMessages),
131
+ project: finalProject,
129
132
  status: stateCalculator.determineConversationStatus(parsedMessages, stats.mtime),
130
133
  conversationState: stateCalculator.determineConversationState(parsedMessages, stats.mtime),
131
134
  statusSquares: await this.getCachedStatusSquares(filePath, parsedMessages),
@@ -433,11 +436,11 @@ class ConversationAnalyzer {
433
436
  }
434
437
 
435
438
  /**
436
- * Extract project name from Claude directory file path
439
+ * Extract project name from Claude directory file path using settings.json
437
440
  * @param {string} filePath - Full path to conversation file
438
- * @returns {string|null} Project name or null
441
+ * @returns {Promise<string|null>} Project name or null
439
442
  */
440
- extractProjectFromPath(filePath) {
443
+ async extractProjectFromPath(filePath) {
441
444
  // Extract project name from file path like:
442
445
  // /Users/user/.claude/projects/-Users-user-Projects-MyProject/conversation.jsonl
443
446
  const pathParts = filePath.split('/');
@@ -445,34 +448,73 @@ class ConversationAnalyzer {
445
448
 
446
449
  if (projectIndex !== -1 && projectIndex + 1 < pathParts.length) {
447
450
  const projectDir = pathParts[projectIndex + 1];
448
- // Clean up the project directory name
449
- const cleanName = projectDir
450
- .replace(/^-/, '')
451
- .replace(/-/g, '/')
452
- .split('/')
453
- .pop() || 'Unknown';
454
-
455
- return cleanName;
451
+
452
+ // Try to read the settings.json file for this project
453
+ try {
454
+ const projectPath = path.join(path.dirname(filePath)); // Directory containing the conversation file
455
+ const settingsPath = path.join(projectPath, 'settings.json');
456
+
457
+ if (await fs.pathExists(settingsPath)) {
458
+ const settingsContent = await fs.readFile(settingsPath, 'utf8');
459
+ const settings = JSON.parse(settingsContent);
460
+
461
+ if (settings.projectName) {
462
+ return settings.projectName;
463
+ }
464
+
465
+ // If no projectName in settings, try to extract from projectPath
466
+ if (settings.projectPath) {
467
+ return path.basename(settings.projectPath);
468
+ }
469
+ }
470
+ } catch (error) {
471
+ // If we can't read settings.json, fall back to parsing the directory name
472
+ console.warn(chalk.yellow(`Warning: Could not read settings.json for project ${projectDir}:`, error.message));
473
+ }
474
+
475
+ // Fallback: we'll extract project name from conversation content instead
476
+ // For now, return null to trigger reading from conversation file
477
+ return null;
456
478
  }
457
479
 
458
480
  return null;
459
481
  }
460
482
 
483
+
461
484
  /**
462
485
  * Attempt to extract project information from conversation content
463
- * @param {Array} messages - Array of message objects
464
- * @returns {string} Project name or 'Unknown'
465
- */
466
- extractProjectFromConversation(messages) {
467
- // Try to extract project information from conversation
468
- for (const message of messages.slice(0, 5)) {
469
- if (message.content && typeof message.content === 'string') {
470
- const pathMatch = message.content.match(/\/([^\/\s]+)$/);
471
- if (pathMatch) {
472
- return pathMatch[1];
486
+ * @param {string} filePath - Path to the conversation file
487
+ * @returns {Promise<string>} Project name or 'Unknown'
488
+ */
489
+ async extractProjectFromConversation(filePath) {
490
+ try {
491
+ // Read the conversation file and look for cwd field
492
+ const content = await this.getFileContent(filePath);
493
+ const lines = content.trim().split('\n').filter(line => line.trim());
494
+
495
+ for (const line of lines.slice(0, 10)) { // Check first 10 lines
496
+ try {
497
+ const item = JSON.parse(line);
498
+
499
+ // Look for cwd field in the message
500
+ if (item.cwd) {
501
+ const projectName = path.basename(item.cwd);
502
+ return projectName;
503
+ }
504
+
505
+ // Also check if it's in nested objects
506
+ if (item.message && item.message.cwd) {
507
+ return path.basename(item.message.cwd);
508
+ }
509
+ } catch (parseError) {
510
+ // Skip invalid JSON lines
511
+ continue;
473
512
  }
474
513
  }
514
+ } catch (error) {
515
+ console.warn(chalk.yellow(`Warning: Could not extract project from conversation ${filePath}:`, error.message));
475
516
  }
517
+
476
518
  return 'Unknown';
477
519
  }
478
520