claude-code-templates 1.28.5 → 1.28.6

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.6",
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 {
@@ -1718,9 +1709,57 @@
1718
1709
  animate();
1719
1710
  }
1720
1711
 
1712
+ // Frame counter for periodic recalculations
1713
+ let frameCount = 0;
1714
+
1721
1715
  // Animation loop
1716
+ // Collision detection and resolution
1717
+ function resolveCollisions() {
1718
+ const allNodes = [];
1719
+
1720
+ // Collect all nodes
1721
+ toolNodes.forEach(node => allNodes.push(node));
1722
+ componentNodes.forEach(node => allNodes.push(node));
1723
+ modelNodes.forEach(node => allNodes.push(node));
1724
+
1725
+ // Check each pair for collision
1726
+ for (let i = 0; i < allNodes.length; i++) {
1727
+ for (let j = i + 1; j < allNodes.length; j++) {
1728
+ const nodeA = allNodes[i];
1729
+ const nodeB = allNodes[j];
1730
+
1731
+ const dx = nodeB.x - nodeA.x;
1732
+ const dy = nodeB.y - nodeA.y;
1733
+ const distance = Math.sqrt(dx * dx + dy * dy);
1734
+ const minDistance = nodeA.size + nodeB.size + 10; // 10px padding
1735
+
1736
+ if (distance < minDistance && distance > 0) {
1737
+ // Nodes are overlapping, push them apart
1738
+ const overlap = minDistance - distance;
1739
+ const angle = Math.atan2(dy, dx);
1740
+
1741
+ // Move each node half the overlap distance
1742
+ const moveX = Math.cos(angle) * overlap * 0.5;
1743
+ const moveY = Math.sin(angle) * overlap * 0.5;
1744
+
1745
+ nodeA.x -= moveX;
1746
+ nodeA.y -= moveY;
1747
+ nodeB.x += moveX;
1748
+ nodeB.y += moveY;
1749
+
1750
+ // Also update target positions to prevent snapping back
1751
+ nodeA.targetX -= moveX * 0.1;
1752
+ nodeA.targetY -= moveY * 0.1;
1753
+ nodeB.targetX += moveX * 0.1;
1754
+ nodeB.targetY += moveY * 0.1;
1755
+ }
1756
+ }
1757
+ }
1758
+ }
1759
+
1722
1760
  function animate() {
1723
1761
  requestAnimationFrame(animate);
1762
+ frameCount++;
1724
1763
 
1725
1764
  // Clear canvas (before transform)
1726
1765
  ctx.fillStyle = '#0a0a0f';
@@ -1730,6 +1769,13 @@
1730
1769
  updateAnimationState();
1731
1770
  }
1732
1771
 
1772
+ // Recalculate percentages periodically (every 30 frames ~0.5s)
1773
+ if (frameCount % 30 === 0) {
1774
+ recalculateToolPercentages();
1775
+ recalculateComponentPercentages();
1776
+ recalculateModelPercentages();
1777
+ }
1778
+
1733
1779
  // Apply zoom and pan transformations
1734
1780
  ctx.save();
1735
1781
  ctx.translate(panX, panY);
@@ -1786,6 +1832,9 @@
1786
1832
  node.draw(ctx);
1787
1833
  });
1788
1834
 
1835
+ // Resolve collisions between all nodes
1836
+ resolveCollisions();
1837
+
1789
1838
  // Update and draw all nodes
1790
1839
  Object.values(branches).forEach(branch => {
1791
1840
  branch.nodes.forEach(node => {
@@ -1844,15 +1893,13 @@
1844
1893
 
1845
1894
  currentDayIndex = rangeStart + Math.floor(progress * rangeDuration);
1846
1895
 
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()}`;
1896
+ // Timeline and date display removed - no need to update
1897
+ // document.getElementById('timelineProgress').style.width = `${progress * 100}%`;
1898
+ // const date = new Date(animationData.startDate);
1899
+ // const dayOffset = currentDayIndex - rangeStart;
1900
+ // date.setDate(date.getDate() + dayOffset);
1901
+ // const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1902
+ // document.getElementById('currentDate').textContent = `${monthNames[date.getMonth()]} ${date.getDate()}`;
1856
1903
 
1857
1904
  // Process events
1858
1905
  let eventsThisFrame = 0;
@@ -1871,20 +1918,41 @@
1871
1918
  stats.conversations += event.count;
1872
1919
  stats.tools += actualToolCount;
1873
1920
 
1874
- // Add tool beams using actual counts
1921
+ // Add tool counts directly (optimized - no individual beams)
1875
1922
  if (event.toolCounts) {
1876
1923
  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
1924
+ // Get or create tool node and update count directly
1925
+ const toolColors = {
1926
+ 'Read': '#60a5fa', 'Write': '#34d399', 'Edit': '#fbbf24',
1927
+ 'Bash': '#f87171', 'TodoWrite': '#a78bfa', 'Task': '#fb923c',
1928
+ 'Glob': '#2dd4bf', 'Grep': '#c084fc', 'WebFetch': '#f472b6',
1929
+ 'WebSearch': '#818cf8', 'KillShell': '#ef4444', 'TaskOutput': '#06b6d4'
1930
+ };
1931
+ const color = toolColors[tool] || '#3b82f6';
1932
+ const node = getOrCreateToolNode(tool, color);
1933
+
1934
+ // Add all uses at once (much faster than creating beams)
1879
1935
  for (let i = 0; i < count; i++) {
1880
- setTimeout(() => addToolBeam(tool), Math.random() * 1000 + i * 50);
1936
+ node.addUse();
1881
1937
  }
1938
+
1939
+ // Create only ONE visual beam per tool (not per use)
1940
+ setTimeout(() => addToolBeam(tool), Math.random() * 300);
1941
+
1942
+ console.log(` šŸ”§ Tool ${tool}: +${count} uses (total: ${node.count})`);
1882
1943
  });
1883
1944
  } else {
1884
1945
  // Fallback to old method if toolCounts not available
1885
1946
  event.tools.forEach(tool => {
1886
- console.log(` šŸ”§ Adding tool beam: ${tool}`);
1887
- setTimeout(() => addToolBeam(tool), Math.random() * 500);
1947
+ const toolColors = {
1948
+ 'Read': '#60a5fa', 'Write': '#34d399', 'Edit': '#fbbf24',
1949
+ 'Bash': '#f87171', 'TodoWrite': '#a78bfa', 'Task': '#fb923c',
1950
+ 'Glob': '#2dd4bf', 'Grep': '#c084fc'
1951
+ };
1952
+ const color = toolColors[tool] || '#3b82f6';
1953
+ const node = getOrCreateToolNode(tool, color);
1954
+ node.addUse();
1955
+ setTimeout(() => addToolBeam(tool), Math.random() * 300);
1888
1956
  });
1889
1957
  }
1890
1958
 
@@ -2007,7 +2075,6 @@
2007
2075
  item.innerHTML = `
2008
2076
  <div class="legend-dot" style="background: ${model.color};"></div>
2009
2077
  <span>${model.name}</span>
2010
- <span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${model.count}</span>
2011
2078
  `;
2012
2079
  modelsList.appendChild(item);
2013
2080
  });
@@ -2037,7 +2104,6 @@
2037
2104
  item.innerHTML = `
2038
2105
  <div class="legend-dot" style="background: ${tool.color};"></div>
2039
2106
  <span>${tool.name}</span>
2040
- <span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${tool.count}</span>
2041
2107
  `;
2042
2108
  toolsList.appendChild(item);
2043
2109
  });
@@ -2074,7 +2140,6 @@
2074
2140
  item.innerHTML = `
2075
2141
  <div class="legend-dot" style="background: ${component.color};"></div>
2076
2142
  <span>${component.name}</span>
2077
- <span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${component.count}</span>
2078
2143
  `;
2079
2144
  componentsList.appendChild(item);
2080
2145
  });
@@ -2087,6 +2152,7 @@
2087
2152
  shownMilestones.clear();
2088
2153
  currentDayIndex = 0;
2089
2154
  beams = [];
2155
+ permanentConnections.clear(); // Clear permanent connection beams
2090
2156
  toolNodes.clear(); // Clear tool nodes
2091
2157
  uniqueTools.clear(); // Clear unique tools
2092
2158
  modelNodes.clear(); // Clear model nodes