claude-code-templates 1.5.6 → 1.5.7
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 +73 -15
package/package.json
CHANGED
package/src/analytics.js
CHANGED
|
@@ -137,7 +137,8 @@ class ClaudeAnalytics {
|
|
|
137
137
|
created: stats.birthtime,
|
|
138
138
|
tokens: this.estimateTokens(content),
|
|
139
139
|
project: projectFromPath || this.extractProjectFromConversation(parsedMessages),
|
|
140
|
-
status: this.determineConversationStatus(parsedMessages, stats.mtime)
|
|
140
|
+
status: this.determineConversationStatus(parsedMessages, stats.mtime),
|
|
141
|
+
conversationState: this.determineConversationState(parsedMessages, stats.mtime)
|
|
141
142
|
};
|
|
142
143
|
|
|
143
144
|
conversations.push(conversation);
|
|
@@ -249,28 +250,57 @@ class ClaudeAnalytics {
|
|
|
249
250
|
const lastMessageTime = new Date(lastMessage.timestamp);
|
|
250
251
|
const lastMessageMinutesAgo = (now - lastMessageTime) / (1000 * 60);
|
|
251
252
|
|
|
252
|
-
//
|
|
253
|
+
// Simplified status logic - typing is now part of active
|
|
254
|
+
if (lastMessage.role === 'user' && lastMessageMinutesAgo < 3) {
|
|
255
|
+
return 'active';
|
|
256
|
+
} else if (lastMessage.role === 'assistant' && lastMessageMinutesAgo < 5) {
|
|
257
|
+
return 'active';
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Fallback to file modification time for edge cases
|
|
261
|
+
if (minutesAgo < 5) return 'active';
|
|
262
|
+
if (minutesAgo < 60) return 'recent';
|
|
263
|
+
return 'inactive';
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
determineConversationState(messages, lastModified) {
|
|
267
|
+
const now = new Date();
|
|
268
|
+
const timeDiff = now - lastModified;
|
|
269
|
+
const minutesAgo = timeDiff / (1000 * 60);
|
|
270
|
+
|
|
271
|
+
if (messages.length === 0) {
|
|
272
|
+
return minutesAgo < 5 ? 'Waiting for input...' : 'Idle';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Sort messages by timestamp to get the actual conversation flow
|
|
276
|
+
const sortedMessages = messages.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
|
|
277
|
+
const lastMessage = sortedMessages[sortedMessages.length - 1];
|
|
278
|
+
const lastMessageTime = new Date(lastMessage.timestamp);
|
|
279
|
+
const lastMessageMinutesAgo = (now - lastMessageTime) / (1000 * 60);
|
|
280
|
+
|
|
281
|
+
// Detailed conversation state logic
|
|
253
282
|
if (lastMessage.role === 'user') {
|
|
254
283
|
// User sent last message
|
|
255
284
|
if (lastMessageMinutesAgo < 0.5) {
|
|
256
|
-
|
|
257
|
-
return 'typing';
|
|
285
|
+
return 'Claude Code working...';
|
|
258
286
|
} else if (lastMessageMinutesAgo < 3) {
|
|
259
|
-
|
|
260
|
-
|
|
287
|
+
return 'Awaiting response...';
|
|
288
|
+
} else {
|
|
289
|
+
return 'User typing...';
|
|
261
290
|
}
|
|
262
291
|
} else if (lastMessage.role === 'assistant') {
|
|
263
292
|
// Assistant sent last message
|
|
264
293
|
if (lastMessageMinutesAgo < 2) {
|
|
265
|
-
|
|
266
|
-
|
|
294
|
+
return 'Awaiting user input...';
|
|
295
|
+
} else if (lastMessageMinutesAgo < 5) {
|
|
296
|
+
return 'User may be typing...';
|
|
267
297
|
}
|
|
268
298
|
}
|
|
269
299
|
|
|
270
|
-
// Fallback
|
|
271
|
-
if (minutesAgo < 5) return 'active';
|
|
272
|
-
if (minutesAgo < 60) return '
|
|
273
|
-
return '
|
|
300
|
+
// Fallback states
|
|
301
|
+
if (minutesAgo < 5) return 'Recently active';
|
|
302
|
+
if (minutesAgo < 60) return 'Idle';
|
|
303
|
+
return 'Inactive';
|
|
274
304
|
}
|
|
275
305
|
|
|
276
306
|
determineProjectStatus(lastActivity) {
|
|
@@ -733,12 +763,25 @@ async function createWebDashboard() {
|
|
|
733
763
|
color: #7d8590;
|
|
734
764
|
}
|
|
735
765
|
|
|
736
|
-
.
|
|
766
|
+
.conversation-state {
|
|
737
767
|
color: #d57455;
|
|
738
|
-
font-
|
|
768
|
+
font-style: italic;
|
|
769
|
+
font-size: 0.8rem;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
.conversation-state.working {
|
|
773
|
+
animation: working-pulse 1.5s infinite;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
.conversation-state.typing {
|
|
739
777
|
animation: typing-pulse 1.5s infinite;
|
|
740
778
|
}
|
|
741
779
|
|
|
780
|
+
@keyframes working-pulse {
|
|
781
|
+
0%, 100% { opacity: 1; }
|
|
782
|
+
50% { opacity: 0.7; }
|
|
783
|
+
}
|
|
784
|
+
|
|
742
785
|
@keyframes typing-pulse {
|
|
743
786
|
0%, 100% { opacity: 1; }
|
|
744
787
|
50% { opacity: 0.6; }
|
|
@@ -960,7 +1003,6 @@ async function createWebDashboard() {
|
|
|
960
1003
|
<span class="filter-label">filter sessions:</span>
|
|
961
1004
|
<div class="filter-buttons">
|
|
962
1005
|
<button class="filter-btn active" data-filter="active">active</button>
|
|
963
|
-
<button class="filter-btn" data-filter="typing">typing</button>
|
|
964
1006
|
<button class="filter-btn" data-filter="recent">recent</button>
|
|
965
1007
|
<button class="filter-btn" data-filter="inactive">inactive</button>
|
|
966
1008
|
<button class="filter-btn" data-filter="all">all</button>
|
|
@@ -975,6 +1017,7 @@ async function createWebDashboard() {
|
|
|
975
1017
|
<th>messages</th>
|
|
976
1018
|
<th>tokens</th>
|
|
977
1019
|
<th>last activity</th>
|
|
1020
|
+
<th>conversation state</th>
|
|
978
1021
|
<th>status</th>
|
|
979
1022
|
</tr>
|
|
980
1023
|
</thead>
|
|
@@ -1074,6 +1117,7 @@ async function createWebDashboard() {
|
|
|
1074
1117
|
<td class="session-messages">\${conv.messageCount}</td>
|
|
1075
1118
|
<td class="session-tokens">\${conv.tokens.toLocaleString()}</td>
|
|
1076
1119
|
<td class="session-time">\${formatTime(conv.lastModified)}</td>
|
|
1120
|
+
<td class="conversation-state \${getStateClass(conv.conversationState)}">\${conv.conversationState}</td>
|
|
1077
1121
|
<td class="status-\${conv.status}">\${conv.status}</td>
|
|
1078
1122
|
</tr>
|
|
1079
1123
|
\`).join('');
|
|
@@ -1102,6 +1146,16 @@ async function createWebDashboard() {
|
|
|
1102
1146
|
});
|
|
1103
1147
|
}
|
|
1104
1148
|
|
|
1149
|
+
function getStateClass(conversationState) {
|
|
1150
|
+
if (conversationState.includes('working') || conversationState.includes('Working')) {
|
|
1151
|
+
return 'working';
|
|
1152
|
+
}
|
|
1153
|
+
if (conversationState.includes('typing') || conversationState.includes('Typing')) {
|
|
1154
|
+
return 'typing';
|
|
1155
|
+
}
|
|
1156
|
+
return '';
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1105
1159
|
// Filter button handlers
|
|
1106
1160
|
document.addEventListener('DOMContentLoaded', function() {
|
|
1107
1161
|
const filterButtons = document.querySelectorAll('.filter-btn');
|
|
@@ -1184,6 +1238,10 @@ async function createWebDashboard() {
|
|
|
1184
1238
|
<div class="info-label">last modified</div>
|
|
1185
1239
|
<div class="info-value">\${new Date(session.lastModified).toLocaleString()}</div>
|
|
1186
1240
|
</div>
|
|
1241
|
+
<div class="info-item">
|
|
1242
|
+
<div class="info-label">conversation state</div>
|
|
1243
|
+
<div class="info-value conversation-state \${getStateClass(session.conversationState)}">\${session.conversationState}</div>
|
|
1244
|
+
</div>
|
|
1187
1245
|
<div class="info-item">
|
|
1188
1246
|
<div class="info-label">status</div>
|
|
1189
1247
|
<div class="info-value status-\${session.status}">\${session.status}</div>
|