claude-code-templates 1.5.1 → 1.5.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.
- package/package.json +1 -1
- package/src/analytics.js +59 -11
package/package.json
CHANGED
package/src/analytics.js
CHANGED
|
@@ -70,12 +70,33 @@ class ClaudeAnalytics {
|
|
|
70
70
|
const conversations = [];
|
|
71
71
|
|
|
72
72
|
try {
|
|
73
|
-
|
|
74
|
-
const
|
|
73
|
+
// Search for .jsonl files recursively in all subdirectories
|
|
74
|
+
const findJsonlFiles = async (dir) => {
|
|
75
|
+
const files = [];
|
|
76
|
+
const items = await fs.readdir(dir);
|
|
77
|
+
|
|
78
|
+
for (const item of items) {
|
|
79
|
+
const itemPath = path.join(dir, item);
|
|
80
|
+
const stats = await fs.stat(itemPath);
|
|
81
|
+
|
|
82
|
+
if (stats.isDirectory()) {
|
|
83
|
+
// Recursively search subdirectories
|
|
84
|
+
const subFiles = await findJsonlFiles(itemPath);
|
|
85
|
+
files.push(...subFiles);
|
|
86
|
+
} else if (item.endsWith('.jsonl')) {
|
|
87
|
+
files.push(itemPath);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return files;
|
|
92
|
+
};
|
|
75
93
|
|
|
76
|
-
|
|
77
|
-
|
|
94
|
+
const jsonlFiles = await findJsonlFiles(this.claudeDir);
|
|
95
|
+
console.log(chalk.blue(`Found ${jsonlFiles.length} conversation files`));
|
|
96
|
+
|
|
97
|
+
for (const filePath of jsonlFiles) {
|
|
78
98
|
const stats = await fs.stat(filePath);
|
|
99
|
+
const filename = path.basename(filePath);
|
|
79
100
|
|
|
80
101
|
try {
|
|
81
102
|
const content = await fs.readFile(filePath, 'utf8');
|
|
@@ -88,21 +109,25 @@ class ClaudeAnalytics {
|
|
|
88
109
|
}
|
|
89
110
|
}).filter(Boolean);
|
|
90
111
|
|
|
112
|
+
// Extract project name from path
|
|
113
|
+
const projectFromPath = this.extractProjectFromPath(filePath);
|
|
114
|
+
|
|
91
115
|
const conversation = {
|
|
92
|
-
id:
|
|
93
|
-
filename:
|
|
116
|
+
id: filename.replace('.jsonl', ''),
|
|
117
|
+
filename: filename,
|
|
118
|
+
filePath: filePath,
|
|
94
119
|
messageCount: messages.length,
|
|
95
120
|
fileSize: stats.size,
|
|
96
121
|
lastModified: stats.mtime,
|
|
97
122
|
created: stats.birthtime,
|
|
98
123
|
tokens: this.estimateTokens(content),
|
|
99
|
-
project: this.extractProjectFromConversation(messages),
|
|
124
|
+
project: projectFromPath || this.extractProjectFromConversation(messages),
|
|
100
125
|
status: this.determineConversationStatus(messages, stats.mtime)
|
|
101
126
|
};
|
|
102
127
|
|
|
103
128
|
conversations.push(conversation);
|
|
104
129
|
} catch (error) {
|
|
105
|
-
console.warn(chalk.yellow(`Warning: Could not parse ${
|
|
130
|
+
console.warn(chalk.yellow(`Warning: Could not parse ${filename}:`, error.message));
|
|
106
131
|
}
|
|
107
132
|
}
|
|
108
133
|
|
|
@@ -160,6 +185,27 @@ class ClaudeAnalytics {
|
|
|
160
185
|
return Math.ceil(text.length / 4);
|
|
161
186
|
}
|
|
162
187
|
|
|
188
|
+
extractProjectFromPath(filePath) {
|
|
189
|
+
// Extract project name from file path like:
|
|
190
|
+
// /Users/user/.claude/projects/-Users-user-Projects-MyProject/conversation.jsonl
|
|
191
|
+
const pathParts = filePath.split('/');
|
|
192
|
+
const projectIndex = pathParts.findIndex(part => part === 'projects');
|
|
193
|
+
|
|
194
|
+
if (projectIndex !== -1 && projectIndex + 1 < pathParts.length) {
|
|
195
|
+
const projectDir = pathParts[projectIndex + 1];
|
|
196
|
+
// Clean up the project directory name
|
|
197
|
+
const cleanName = projectDir
|
|
198
|
+
.replace(/^-/, '')
|
|
199
|
+
.replace(/-/g, '/')
|
|
200
|
+
.split('/')
|
|
201
|
+
.pop() || 'Unknown';
|
|
202
|
+
|
|
203
|
+
return cleanName;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
|
|
163
209
|
extractProjectFromConversation(messages) {
|
|
164
210
|
// Try to extract project information from conversation
|
|
165
211
|
for (const message of messages.slice(0, 5)) {
|
|
@@ -233,8 +279,10 @@ class ClaudeAnalytics {
|
|
|
233
279
|
setupFileWatchers() {
|
|
234
280
|
console.log(chalk.blue('👀 Setting up file watchers for real-time updates...'));
|
|
235
281
|
|
|
236
|
-
// Watch conversation files
|
|
237
|
-
const conversationWatcher = chokidar.watch(
|
|
282
|
+
// Watch conversation files recursively in all subdirectories
|
|
283
|
+
const conversationWatcher = chokidar.watch([
|
|
284
|
+
path.join(this.claudeDir, '**/*.jsonl')
|
|
285
|
+
], {
|
|
238
286
|
persistent: true,
|
|
239
287
|
ignoreInitial: true
|
|
240
288
|
});
|
|
@@ -257,7 +305,7 @@ class ClaudeAnalytics {
|
|
|
257
305
|
const projectWatcher = chokidar.watch(this.claudeDir, {
|
|
258
306
|
persistent: true,
|
|
259
307
|
ignoreInitial: true,
|
|
260
|
-
depth:
|
|
308
|
+
depth: 2 // Increased depth to catch subdirectories
|
|
261
309
|
});
|
|
262
310
|
|
|
263
311
|
projectWatcher.on('addDir', async () => {
|