claude-code-templates 1.28.4 ā 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.
|
|
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
|
});
|
|
@@ -904,19 +924,54 @@ class YearInReview2025 {
|
|
|
904
924
|
}
|
|
905
925
|
|
|
906
926
|
const subagents = Array.from(agentData.values());
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
927
|
+
|
|
928
|
+
// Group subagents by type for cleaner visualization
|
|
929
|
+
const groupedByType = {};
|
|
930
|
+
subagents.forEach(agent => {
|
|
931
|
+
const type = agent.type || 'Unknown';
|
|
932
|
+
if (!groupedByType[type]) {
|
|
933
|
+
groupedByType[type] = { count: 0, timestamps: [] };
|
|
934
|
+
}
|
|
935
|
+
groupedByType[type].count++;
|
|
936
|
+
if (agent.timestamp && agent.timestamp.getFullYear() === 2025) {
|
|
937
|
+
groupedByType[type].timestamps.push(agent.timestamp);
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
// Create events grouped by type (one event per type per day)
|
|
942
|
+
const subagentEvents = [];
|
|
943
|
+
Object.entries(groupedByType).forEach(([type, data]) => {
|
|
944
|
+
// Group timestamps by day to avoid too many events
|
|
945
|
+
const dayMap = new Map();
|
|
946
|
+
data.timestamps.forEach(ts => {
|
|
947
|
+
const dayKey = ts.toISOString().split('T')[0];
|
|
948
|
+
if (!dayMap.has(dayKey)) {
|
|
949
|
+
dayMap.set(dayKey, { count: 0, timestamp: ts });
|
|
950
|
+
}
|
|
951
|
+
dayMap.get(dayKey).count++;
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
// Create one event per day per type
|
|
955
|
+
dayMap.forEach((dayData, dayKey) => {
|
|
956
|
+
subagentEvents.push({
|
|
957
|
+
name: type, // Just "Plan" or "Explore", not "Plan-a68a"
|
|
958
|
+
timestamp: dayData.timestamp,
|
|
959
|
+
type: type,
|
|
960
|
+
count: dayData.count // How many times used that day
|
|
961
|
+
});
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
subagentEvents.sort((a, b) => a.timestamp - b.timestamp);
|
|
915
966
|
|
|
916
967
|
return {
|
|
917
|
-
subagents:
|
|
968
|
+
subagents: Object.entries(groupedByType).map(([type, data]) => ({
|
|
969
|
+
type,
|
|
970
|
+
count: data.count
|
|
971
|
+
})),
|
|
918
972
|
total: subagents.length,
|
|
919
|
-
events: subagentEvents
|
|
973
|
+
events: subagentEvents,
|
|
974
|
+
grouped: groupedByType // Include grouped data for display
|
|
920
975
|
};
|
|
921
976
|
} catch (error) {
|
|
922
977
|
console.warn('Could not analyze subagents:', error.message);
|
|
@@ -60,10 +60,7 @@
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
.current-date {
|
|
63
|
-
|
|
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
|
-
|
|
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 {
|
|
@@ -1637,19 +1628,20 @@
|
|
|
1637
1628
|
}
|
|
1638
1629
|
|
|
1639
1630
|
if (data.subagents && data.subagents.events) {
|
|
1640
|
-
console.log(`š¤ Adding ${data.subagents.events.length} subagent events to timeline`);
|
|
1631
|
+
console.log(`š¤ Adding ${data.subagents.events.length} subagent events to timeline (grouped by type)`);
|
|
1641
1632
|
data.subagents.events.forEach((event, index) => {
|
|
1642
1633
|
const eventDate = new Date(event.timestamp);
|
|
1643
1634
|
const eventDayOfYear = getDayOfYear(eventDate);
|
|
1644
1635
|
timeline.push({
|
|
1645
1636
|
type: 'component-layer2',
|
|
1646
1637
|
componentType: 'subagent',
|
|
1647
|
-
name: event.name,
|
|
1638
|
+
name: event.name, // Now just "Plan" or "Explore", not "Plan-a68a"
|
|
1648
1639
|
date: eventDate,
|
|
1649
|
-
dayOfYear: eventDayOfYear
|
|
1640
|
+
dayOfYear: eventDayOfYear,
|
|
1641
|
+
count: event.count || 1 // How many times used that day
|
|
1650
1642
|
});
|
|
1651
1643
|
if (index === 0) {
|
|
1652
|
-
console.log(` - First subagent "${event.name}": date=${eventDate.toLocaleDateString()}, dayOfYear=${eventDayOfYear.toFixed(3)}`);
|
|
1644
|
+
console.log(` - First subagent "${event.name}": date=${eventDate.toLocaleDateString()}, dayOfYear=${eventDayOfYear.toFixed(3)}, count=${event.count || 1}`);
|
|
1653
1645
|
}
|
|
1654
1646
|
});
|
|
1655
1647
|
}
|
|
@@ -1717,9 +1709,57 @@
|
|
|
1717
1709
|
animate();
|
|
1718
1710
|
}
|
|
1719
1711
|
|
|
1712
|
+
// Frame counter for periodic recalculations
|
|
1713
|
+
let frameCount = 0;
|
|
1714
|
+
|
|
1720
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
|
+
|
|
1721
1760
|
function animate() {
|
|
1722
1761
|
requestAnimationFrame(animate);
|
|
1762
|
+
frameCount++;
|
|
1723
1763
|
|
|
1724
1764
|
// Clear canvas (before transform)
|
|
1725
1765
|
ctx.fillStyle = '#0a0a0f';
|
|
@@ -1729,6 +1769,13 @@
|
|
|
1729
1769
|
updateAnimationState();
|
|
1730
1770
|
}
|
|
1731
1771
|
|
|
1772
|
+
// Recalculate percentages periodically (every 30 frames ~0.5s)
|
|
1773
|
+
if (frameCount % 30 === 0) {
|
|
1774
|
+
recalculateToolPercentages();
|
|
1775
|
+
recalculateComponentPercentages();
|
|
1776
|
+
recalculateModelPercentages();
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1732
1779
|
// Apply zoom and pan transformations
|
|
1733
1780
|
ctx.save();
|
|
1734
1781
|
ctx.translate(panX, panY);
|
|
@@ -1785,6 +1832,9 @@
|
|
|
1785
1832
|
node.draw(ctx);
|
|
1786
1833
|
});
|
|
1787
1834
|
|
|
1835
|
+
// Resolve collisions between all nodes
|
|
1836
|
+
resolveCollisions();
|
|
1837
|
+
|
|
1788
1838
|
// Update and draw all nodes
|
|
1789
1839
|
Object.values(branches).forEach(branch => {
|
|
1790
1840
|
branch.nodes.forEach(node => {
|
|
@@ -1843,15 +1893,13 @@
|
|
|
1843
1893
|
|
|
1844
1894
|
currentDayIndex = rangeStart + Math.floor(progress * rangeDuration);
|
|
1845
1895
|
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
//
|
|
1849
|
-
const
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
1854
|
-
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()}`;
|
|
1855
1903
|
|
|
1856
1904
|
// Process events
|
|
1857
1905
|
let eventsThisFrame = 0;
|
|
@@ -1870,20 +1918,41 @@
|
|
|
1870
1918
|
stats.conversations += event.count;
|
|
1871
1919
|
stats.tools += actualToolCount;
|
|
1872
1920
|
|
|
1873
|
-
// Add tool
|
|
1921
|
+
// Add tool counts directly (optimized - no individual beams)
|
|
1874
1922
|
if (event.toolCounts) {
|
|
1875
1923
|
Object.entries(event.toolCounts).forEach(([tool, count]) => {
|
|
1876
|
-
|
|
1877
|
-
|
|
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)
|
|
1878
1935
|
for (let i = 0; i < count; i++) {
|
|
1879
|
-
|
|
1936
|
+
node.addUse();
|
|
1880
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})`);
|
|
1881
1943
|
});
|
|
1882
1944
|
} else {
|
|
1883
1945
|
// Fallback to old method if toolCounts not available
|
|
1884
1946
|
event.tools.forEach(tool => {
|
|
1885
|
-
|
|
1886
|
-
|
|
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);
|
|
1887
1956
|
});
|
|
1888
1957
|
}
|
|
1889
1958
|
|
|
@@ -1922,13 +1991,18 @@
|
|
|
1922
1991
|
// showEvent(`Installed: ${event.name}`); // Disabled - notifications removed
|
|
1923
1992
|
} else if (event.type === 'component-layer2') {
|
|
1924
1993
|
const node = getOrCreateComponentNode(event.name, event.componentType);
|
|
1925
|
-
|
|
1994
|
+
|
|
1995
|
+
// Add uses based on event count (for grouped subagents)
|
|
1996
|
+
const useCount = event.count || 1;
|
|
1997
|
+
for (let j = 0; j < useCount; j++) {
|
|
1998
|
+
node.addUse();
|
|
1999
|
+
}
|
|
1926
2000
|
|
|
1927
2001
|
// Create beam to this component node
|
|
1928
2002
|
const beam = new Beam(node, event.name);
|
|
1929
2003
|
beams.push(beam);
|
|
1930
2004
|
|
|
1931
|
-
console.log(`š· ${event.componentType}: ${event.name} at ${event.date?.toLocaleDateString()} (
|
|
2005
|
+
console.log(`š· ${event.componentType}: ${event.name} at ${event.date?.toLocaleDateString()} (added: ${useCount}, total: ${node.count}, size: ${node.targetSize.toFixed(1)})`);
|
|
1932
2006
|
}
|
|
1933
2007
|
}
|
|
1934
2008
|
});
|
|
@@ -2001,7 +2075,6 @@
|
|
|
2001
2075
|
item.innerHTML = `
|
|
2002
2076
|
<div class="legend-dot" style="background: ${model.color};"></div>
|
|
2003
2077
|
<span>${model.name}</span>
|
|
2004
|
-
<span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${model.count}</span>
|
|
2005
2078
|
`;
|
|
2006
2079
|
modelsList.appendChild(item);
|
|
2007
2080
|
});
|
|
@@ -2031,7 +2104,6 @@
|
|
|
2031
2104
|
item.innerHTML = `
|
|
2032
2105
|
<div class="legend-dot" style="background: ${tool.color};"></div>
|
|
2033
2106
|
<span>${tool.name}</span>
|
|
2034
|
-
<span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${tool.count}</span>
|
|
2035
2107
|
`;
|
|
2036
2108
|
toolsList.appendChild(item);
|
|
2037
2109
|
});
|
|
@@ -2068,7 +2140,6 @@
|
|
|
2068
2140
|
item.innerHTML = `
|
|
2069
2141
|
<div class="legend-dot" style="background: ${component.color};"></div>
|
|
2070
2142
|
<span>${component.name}</span>
|
|
2071
|
-
<span style="margin-left: auto; color: rgba(255,255,255,0.5); font-size: 11px;">${component.count}</span>
|
|
2072
2143
|
`;
|
|
2073
2144
|
componentsList.appendChild(item);
|
|
2074
2145
|
});
|
|
@@ -2081,6 +2152,7 @@
|
|
|
2081
2152
|
shownMilestones.clear();
|
|
2082
2153
|
currentDayIndex = 0;
|
|
2083
2154
|
beams = [];
|
|
2155
|
+
permanentConnections.clear(); // Clear permanent connection beams
|
|
2084
2156
|
toolNodes.clear(); // Clear tool nodes
|
|
2085
2157
|
uniqueTools.clear(); // Clear unique tools
|
|
2086
2158
|
modelNodes.clear(); // Clear model nodes
|