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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/analytics.js +73 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.5.6",
3
+ "version": "1.5.7",
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/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
- // Advanced status logic
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
- // Very recent user message, likely typing or waiting for response
257
- return 'typing';
285
+ return 'Claude Code working...';
258
286
  } else if (lastMessageMinutesAgo < 3) {
259
- // Recent user message, waiting for assistant
260
- return 'active';
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
- // Recent assistant response, conversation is active
266
- return 'active';
294
+ return 'Awaiting user input...';
295
+ } else if (lastMessageMinutesAgo < 5) {
296
+ return 'User may be typing...';
267
297
  }
268
298
  }
269
299
 
270
- // Fallback to file modification time for edge cases
271
- if (minutesAgo < 5) return 'active';
272
- if (minutesAgo < 60) return 'recent';
273
- return 'inactive';
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
- .status-typing {
766
+ .conversation-state {
737
767
  color: #d57455;
738
- font-weight: bold;
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>