claude-code-templates 1.28.5 → 1.28.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.28.5",
3
+ "version": "1.28.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": {
@@ -348,23 +348,41 @@ class YearInReview2025 {
348
348
  * @returns {Array} Heatmap data by week
349
349
  */
350
350
  generateActivityHeatmap(conversations) {
351
+ console.log(`\nšŸ”„šŸ”„šŸ”„ GENERATING HEATMAP for ${conversations.length} conversations\n`);
352
+
351
353
  // Create map of day -> activity count, tools, and models
352
354
  const dailyActivity = new Map();
353
355
 
354
- conversations.forEach(conv => {
356
+ conversations.forEach((conv, idx) => {
355
357
  if (conv.lastModified) {
356
358
  const date = new Date(conv.lastModified);
357
359
  const dayKey = date.toISOString().split('T')[0];
358
360
 
361
+ if (idx < 3) {
362
+ console.log(` šŸ“ Conv ${idx}: id=${conv.id}, tokens=${conv.tokens}, tokenUsage.total=${conv.tokenUsage?.total}`);
363
+ }
364
+
359
365
  const current = dailyActivity.get(dayKey) || {
360
366
  count: 0,
361
367
  tools: [],
362
368
  models: [],
363
369
  modelCounts: {},
364
- toolCounts: {}
370
+ toolCounts: {},
371
+ tokens: 0
365
372
  };
366
373
  current.count += 1;
367
374
 
375
+ // Add tokens from this conversation
376
+ if (conv.tokenUsage && conv.tokenUsage.total) {
377
+ current.tokens += conv.tokenUsage.total;
378
+ if (idx < 3) console.log(` šŸ’Ž Added ${conv.tokenUsage.total} tokens from conv ${conv.id} to ${dayKey}`);
379
+ } else if (conv.tokens) {
380
+ current.tokens += conv.tokens;
381
+ if (idx < 3) console.log(` šŸ’Ž Added ${conv.tokens} tokens (fallback) from conv ${conv.id} to ${dayKey}`);
382
+ } else {
383
+ if (idx < 3) console.log(` āš ļø Conv ${conv.id} has NO token data`);
384
+ }
385
+
368
386
  // Count tool usage with actual numbers from toolStats
369
387
  if (conv.toolUsage && conv.toolUsage.toolStats) {
370
388
  Object.entries(conv.toolUsage.toolStats).forEach(([tool, count]) => {
@@ -411,7 +429,8 @@ class YearInReview2025 {
411
429
  tools: [],
412
430
  models: [],
413
431
  toolCounts: {},
414
- modelCounts: {}
432
+ modelCounts: {},
433
+ tokens: 0
415
434
  };
416
435
 
417
436
  // Determine intensity level (0-4 like GitHub)
@@ -428,6 +447,7 @@ class YearInReview2025 {
428
447
  models: dayData.models,
429
448
  toolCounts: dayData.toolCounts,
430
449
  modelCounts: dayData.modelCounts,
450
+ tokens: dayData.tokens,
431
451
  level,
432
452
  day: currentDate.getDay()
433
453
  });
@@ -60,10 +60,7 @@
60
60
  }
61
61
 
62
62
  .current-date {
63
- font-size: 32px;
64
- font-weight: 700;
65
- color: var(--text-accent);
66
- margin-bottom: 15px;
63
+ display: none;
67
64
  }
68
65
 
69
66
  .stat-line {
@@ -134,13 +131,7 @@
134
131
  }
135
132
 
136
133
  .timeline {
137
- position: absolute;
138
- bottom: 30px;
139
- left: 50%;
140
- transform: translateX(-50%);
141
- width: 80%;
142
- max-width: 1000px;
143
- pointer-events: auto;
134
+ display: none;
144
135
  }
145
136
 
146
137
  .timeline-bar {
@@ -427,6 +418,7 @@
427
418
  let toolNodes = new Map(); // Map of tool name -> tool node
428
419
  let uniqueTools = new Map(); // Track unique tools with their colors
429
420
  let modelNodes = new Map(); // Map of model name -> model node
421
+ let toolQueue = []; // Queue for gradual tool processing
430
422
 
431
423
  // Mouse tracking
432
424
  let mouseX = 0;
@@ -1718,9 +1710,57 @@
1718
1710
  animate();
1719
1711
  }
1720
1712
 
1713
+ // Frame counter for periodic recalculations
1714
+ let frameCount = 0;
1715
+
1721
1716
  // Animation loop
1717
+ // Collision detection and resolution
1718
+ function resolveCollisions() {
1719
+ const allNodes = [];
1720
+
1721
+ // Collect all nodes
1722
+ toolNodes.forEach(node => allNodes.push(node));
1723
+ componentNodes.forEach(node => allNodes.push(node));
1724
+ modelNodes.forEach(node => allNodes.push(node));
1725
+
1726
+ // Check each pair for collision
1727
+ for (let i = 0; i < allNodes.length; i++) {
1728
+ for (let j = i + 1; j < allNodes.length; j++) {
1729
+ const nodeA = allNodes[i];
1730
+ const nodeB = allNodes[j];
1731
+
1732
+ const dx = nodeB.x - nodeA.x;
1733
+ const dy = nodeB.y - nodeA.y;
1734
+ const distance = Math.sqrt(dx * dx + dy * dy);
1735
+ const minDistance = nodeA.size + nodeB.size + 10; // 10px padding
1736
+
1737
+ if (distance < minDistance && distance > 0) {
1738
+ // Nodes are overlapping, push them apart
1739
+ const overlap = minDistance - distance;
1740
+ const angle = Math.atan2(dy, dx);
1741
+
1742
+ // Move each node half the overlap distance
1743
+ const moveX = Math.cos(angle) * overlap * 0.5;
1744
+ const moveY = Math.sin(angle) * overlap * 0.5;
1745
+
1746
+ nodeA.x -= moveX;
1747
+ nodeA.y -= moveY;
1748
+ nodeB.x += moveX;
1749
+ nodeB.y += moveY;
1750
+
1751
+ // Also update target positions to prevent snapping back
1752
+ nodeA.targetX -= moveX * 0.1;
1753
+ nodeA.targetY -= moveY * 0.1;
1754
+ nodeB.targetX += moveX * 0.1;
1755
+ nodeB.targetY += moveY * 0.1;
1756
+ }
1757
+ }
1758
+ }
1759
+ }
1760
+
1722
1761
  function animate() {
1723
1762
  requestAnimationFrame(animate);
1763
+ frameCount++;
1724
1764
 
1725
1765
  // Clear canvas (before transform)
1726
1766
  ctx.fillStyle = '#0a0a0f';
@@ -1730,6 +1770,28 @@
1730
1770
  updateAnimationState();
1731
1771
  }
1732
1772
 
1773
+ // Recalculate percentages periodically (every 30 frames ~0.5s)
1774
+ if (frameCount % 30 === 0) {
1775
+ recalculateToolPercentages();
1776
+ recalculateComponentPercentages();
1777
+ recalculateModelPercentages();
1778
+ }
1779
+
1780
+ // Process tool queue gradually (max 3 tools per frame to avoid lag)
1781
+ const toolsToProcessPerFrame = 3;
1782
+ for (let i = 0; i < toolsToProcessPerFrame && toolQueue.length > 0; i++) {
1783
+ const { tool, count, color } = toolQueue.shift();
1784
+ const node = getOrCreateToolNode(tool, color);
1785
+
1786
+ // Add all uses at once
1787
+ for (let j = 0; j < count; j++) {
1788
+ node.addUse();
1789
+ }
1790
+
1791
+ // Create only ONE visual beam per tool
1792
+ setTimeout(() => addToolBeam(tool), Math.random() * 300);
1793
+ }
1794
+
1733
1795
  // Apply zoom and pan transformations
1734
1796
  ctx.save();
1735
1797
  ctx.translate(panX, panY);
@@ -1786,6 +1848,9 @@
1786
1848
  node.draw(ctx);
1787
1849
  });
1788
1850
 
1851
+ // Resolve collisions between all nodes
1852
+ resolveCollisions();
1853
+
1789
1854
  // Update and draw all nodes
1790
1855
  Object.values(branches).forEach(branch => {
1791
1856
  branch.nodes.forEach(node => {
@@ -1844,15 +1909,13 @@
1844
1909
 
1845
1910
  currentDayIndex = rangeStart + Math.floor(progress * rangeDuration);
1846
1911
 
1847
- document.getElementById('timelineProgress').style.width = `${progress * 100}%`;
1848
-
1849
- // Use startDate from data
1850
- const date = new Date(animationData.startDate);
1851
- const dayOffset = currentDayIndex - rangeStart;
1852
- date.setDate(date.getDate() + dayOffset);
1853
-
1854
- const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1855
- document.getElementById('currentDate').textContent = `${monthNames[date.getMonth()]} ${date.getDate()}`;
1912
+ // Timeline and date display removed - no need to update
1913
+ // document.getElementById('timelineProgress').style.width = `${progress * 100}%`;
1914
+ // const date = new Date(animationData.startDate);
1915
+ // const dayOffset = currentDayIndex - rangeStart;
1916
+ // date.setDate(date.getDate() + dayOffset);
1917
+ // const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1918
+ // document.getElementById('currentDate').textContent = `${monthNames[date.getMonth()]} ${date.getDate()}`;
1856
1919
 
1857
1920
  // Process events
1858
1921
  let eventsThisFrame = 0;
@@ -1871,20 +1934,32 @@
1871
1934
  stats.conversations += event.count;
1872
1935
  stats.tools += actualToolCount;
1873
1936
 
1874
- // Add tool beams using actual counts
1937
+ // Add tool counts to queue for gradual processing
1875
1938
  if (event.toolCounts) {
1876
1939
  Object.entries(event.toolCounts).forEach(([tool, count]) => {
1877
- console.log(` šŸ”§ Adding ${count} beams for tool: ${tool}`);
1878
- // Create multiple beams based on actual usage count
1879
- for (let i = 0; i < count; i++) {
1880
- setTimeout(() => addToolBeam(tool), Math.random() * 1000 + i * 50);
1881
- }
1940
+ const toolColors = {
1941
+ 'Read': '#60a5fa', 'Write': '#34d399', 'Edit': '#fbbf24',
1942
+ 'Bash': '#f87171', 'TodoWrite': '#a78bfa', 'Task': '#fb923c',
1943
+ 'Glob': '#2dd4bf', 'Grep': '#c084fc', 'WebFetch': '#f472b6',
1944
+ 'WebSearch': '#818cf8', 'KillShell': '#ef4444', 'TaskOutput': '#06b6d4'
1945
+ };
1946
+ const color = toolColors[tool] || '#3b82f6';
1947
+
1948
+ // Add to queue for gradual processing
1949
+ toolQueue.push({ tool, count, color });
1882
1950
  });
1883
1951
  } else {
1884
1952
  // Fallback to old method if toolCounts not available
1885
1953
  event.tools.forEach(tool => {
1886
- console.log(` šŸ”§ Adding tool beam: ${tool}`);
1887
- setTimeout(() => addToolBeam(tool), Math.random() * 500);
1954
+ const toolColors = {
1955
+ 'Read': '#60a5fa', 'Write': '#34d399', 'Edit': '#fbbf24',
1956
+ 'Bash': '#f87171', 'TodoWrite': '#a78bfa', 'Task': '#fb923c',
1957
+ 'Glob': '#2dd4bf', 'Grep': '#c084fc'
1958
+ };
1959
+ const color = toolColors[tool] || '#3b82f6';
1960
+ const node = getOrCreateToolNode(tool, color);
1961
+ node.addUse();
1962
+ setTimeout(() => addToolBeam(tool), Math.random() * 300);
1888
1963
  });
1889
1964
  }
1890
1965
 
@@ -2007,7 +2082,6 @@
2007
2082
  item.innerHTML = `
2008
2083
  <div class="legend-dot" style="background: ${model.color};"></div>
2009
2084
  <span>${model.name}</span>
2010
- <span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${model.count}</span>
2011
2085
  `;
2012
2086
  modelsList.appendChild(item);
2013
2087
  });
@@ -2037,7 +2111,6 @@
2037
2111
  item.innerHTML = `
2038
2112
  <div class="legend-dot" style="background: ${tool.color};"></div>
2039
2113
  <span>${tool.name}</span>
2040
- <span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${tool.count}</span>
2041
2114
  `;
2042
2115
  toolsList.appendChild(item);
2043
2116
  });
@@ -2074,7 +2147,6 @@
2074
2147
  item.innerHTML = `
2075
2148
  <div class="legend-dot" style="background: ${component.color};"></div>
2076
2149
  <span>${component.name}</span>
2077
- <span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${component.count}</span>
2078
2150
  `;
2079
2151
  componentsList.appendChild(item);
2080
2152
  });
@@ -2087,6 +2159,8 @@
2087
2159
  shownMilestones.clear();
2088
2160
  currentDayIndex = 0;
2089
2161
  beams = [];
2162
+ permanentConnections.clear(); // Clear permanent connection beams
2163
+ toolQueue = []; // Clear tool processing queue
2090
2164
  toolNodes.clear(); // Clear tool nodes
2091
2165
  uniqueTools.clear(); // Clear unique tools
2092
2166
  modelNodes.clear(); // Clear model nodes