claude-code-templates 1.13.2 → 1.14.1

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.
@@ -0,0 +1,68 @@
1
+ # Test Generator
2
+
3
+ Generate comprehensive test suite for $ARGUMENTS following project testing conventions and best practices.
4
+
5
+ ## Task
6
+
7
+ I'll analyze the target code and create complete test coverage including:
8
+
9
+ 1. Unit tests for individual functions and methods
10
+ 2. Integration tests for component interactions
11
+ 3. Edge case and error handling tests
12
+ 4. Mock implementations for external dependencies
13
+ 5. Test utilities and helpers as needed
14
+ 6. Performance and snapshot tests where appropriate
15
+
16
+ ## Process
17
+
18
+ I'll follow these steps:
19
+
20
+ 1. Analyze the target file/component structure
21
+ 2. Identify all testable functions, methods, and behaviors
22
+ 3. Examine existing test patterns in the project
23
+ 4. Create test files following project naming conventions
24
+ 5. Implement comprehensive test cases with proper setup/teardown
25
+ 6. Add necessary mocks and test utilities
26
+ 7. Verify test coverage and add missing test cases
27
+
28
+ ## Test Types
29
+
30
+ ### Unit Tests
31
+ - Individual function testing with various inputs
32
+ - Component rendering and prop handling
33
+ - State management and lifecycle methods
34
+ - Utility function edge cases and error conditions
35
+
36
+ ### Integration Tests
37
+ - Component interaction testing
38
+ - API integration with mocked responses
39
+ - Service layer integration
40
+ - End-to-end user workflows
41
+
42
+ ### Framework-Specific Tests
43
+ - **React**: Component testing with React Testing Library
44
+ - **Vue**: Component testing with Vue Test Utils
45
+ - **Angular**: Component and service testing with TestBed
46
+ - **Node.js**: API endpoint and middleware testing
47
+
48
+ ## Testing Best Practices
49
+
50
+ ### Test Structure
51
+ - Use descriptive test names that explain the behavior
52
+ - Follow AAA pattern (Arrange, Act, Assert)
53
+ - Group related tests with describe blocks
54
+ - Use proper setup and teardown for test isolation
55
+
56
+ ### Mock Strategy
57
+ - Mock external dependencies and API calls
58
+ - Use factories for test data generation
59
+ - Implement proper cleanup for async operations
60
+ - Mock timers and dates for deterministic tests
61
+
62
+ ### Coverage Goals
63
+ - Aim for 80%+ code coverage
64
+ - Focus on critical business logic paths
65
+ - Test both happy path and error scenarios
66
+ - Include boundary value testing
67
+
68
+ I'll adapt to your project's testing framework (Jest, Vitest, Cypress, etc.) and follow established patterns.
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "DeepGraph Next.js MCP": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "mcp-code-graph@latest",
8
+ "vercel/next.js"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "DeepGraph React MCP": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "mcp-code-graph@latest",
8
+ "facebook/react"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "DeepGraph TypeScript MCP": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "mcp-code-graph@latest",
8
+ "microsoft/TypeScript"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "DeepGraph Vue MCP": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "mcp-code-graph@latest",
8
+ "vuejs/core"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "filesystem": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@modelcontextprotocol/server-filesystem",
8
+ "/path/to/allowed/files"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "github": {
4
+ "command": "npx",
5
+ "args": ["-y", "@modelcontextprotocol/server-github"],
6
+ "env": {
7
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "memory": {
4
+ "command": "npx",
5
+ "args": ["-y", "@modelcontextprotocol/server-memory"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "mysql": {
4
+ "command": "uvx",
5
+ "args": ["mcp-server-mysql"],
6
+ "env": {
7
+ "MYSQL_CONNECTION_STRING": "mysql://user:password@localhost:3306/dbname"
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "postgresql": {
4
+ "command": "npx",
5
+ "args": ["-y", "@modelcontextprotocol/server-postgres"],
6
+ "env": {
7
+ "POSTGRES_CONNECTION_STRING": "postgresql://user:password@localhost:5432/dbname"
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "fetch": {
4
+ "command": "npx",
5
+ "args": ["-y", "@modelcontextprotocol/server-fetch"]
6
+ }
7
+ }
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.13.2",
3
+ "version": "1.14.1",
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": {
@@ -86,6 +86,7 @@
86
86
  "bin/",
87
87
  "src/",
88
88
  "templates/",
89
+ "components/",
89
90
  "README.md"
90
91
  ],
91
92
  "devDependencies": {
@@ -16,6 +16,9 @@ class AgentsPage {
16
16
  };
17
17
  this.isInitialized = false;
18
18
 
19
+ // Initialize header component
20
+ this.headerComponent = null;
21
+
19
22
  // Pagination state for conversations
20
23
  this.pagination = {
21
24
  currentPage: 0,
@@ -586,22 +589,8 @@ class AgentsPage {
586
589
  async render() {
587
590
  this.container.innerHTML = `
588
591
  <div class="agents-page">
589
- <!-- Page Header -->
590
- <div class="page-header conversations-header">
591
- <div class="header-content">
592
- <div class="header-left">
593
- <div class="status-header">
594
- <span class="session-timer-status-dot active"></span>
595
- <h1 class="page-title">
596
- Claude Code web UI
597
- </h1>
598
- </div>
599
- <div class="page-subtitle">
600
- Monitor and analyze Claude Code agent interactions in real-time
601
- </div>
602
- </div>
603
- </div>
604
- </div>
592
+ <!-- Page Header (will be replaced by HeaderComponent) -->
593
+ <div id="agents-header-container"></div>
605
594
 
606
595
  <!-- Filters Section -->
607
596
  <div class="conversations-filters">
@@ -784,6 +773,28 @@ class AgentsPage {
784
773
 
785
774
  this.bindEvents();
786
775
  this.setupInfiniteScroll();
776
+ this.initializeHeaderComponent();
777
+ }
778
+
779
+ /**
780
+ * Initialize the header component
781
+ */
782
+ initializeHeaderComponent() {
783
+ const headerContainer = this.container.querySelector('#agents-header-container');
784
+ if (headerContainer && typeof HeaderComponent !== 'undefined') {
785
+ this.headerComponent = new HeaderComponent(headerContainer, {
786
+ title: 'Claude Code Chats',
787
+ subtitle: 'Monitor and analyze Claude Code agent interactions in real-time',
788
+ version: 'v1.13.2', // Fallback version
789
+ showVersionBadge: true,
790
+ showLastUpdate: true,
791
+ showThemeSwitch: true,
792
+ showGitHubLink: true,
793
+ dataService: this.dataService // Pass DataService for dynamic version loading
794
+ });
795
+
796
+ this.headerComponent.render();
797
+ }
787
798
  }
788
799
 
789
800
  /**
@@ -4716,6 +4727,12 @@ class AgentsPage {
4716
4727
  * Destroy agents page
4717
4728
  */
4718
4729
  destroy() {
4730
+ // Cleanup header component
4731
+ if (this.headerComponent) {
4732
+ this.headerComponent.destroy();
4733
+ this.headerComponent = null;
4734
+ }
4735
+
4719
4736
  // Cleanup components
4720
4737
  Object.values(this.components).forEach(component => {
4721
4738
  if (component.destroy) {
@@ -13,6 +13,9 @@ class DashboardPage {
13
13
  this.refreshInterval = null;
14
14
  this.isInitialized = false;
15
15
 
16
+ // Initialize header component
17
+ this.headerComponent = null;
18
+
16
19
  // Subscribe to state changes
17
20
  this.unsubscribe = this.stateService.subscribe(this.handleStateChange.bind(this));
18
21
  }
@@ -118,42 +121,8 @@ class DashboardPage {
118
121
  async render() {
119
122
  this.container.innerHTML = `
120
123
  <div class="dashboard-page">
121
- <!-- Page Header -->
122
- <div class="page-header">
123
- <div class="header-content">
124
- <div class="header-left">
125
- <div class="status-header">
126
- <span class="session-timer-status-dot active" id="session-status-dot"></span>
127
- <h1 class="page-title">
128
- Claude Code Analytics Dashboard
129
- <span class="version-badge">v1.10.1</span>
130
- </h1>
131
- </div>
132
- <div class="page-subtitle">
133
- Real-time monitoring and analytics for Claude Code sessions
134
- </div>
135
- <div class="last-update-header">
136
- <span class="last-update-label">last update:</span>
137
- <span id="last-update-header-text">Never</span>
138
- </div>
139
- </div>
140
- <div class="header-right">
141
- <div class="theme-switch-container" title="Toggle light/dark theme">
142
- <div class="theme-switch" id="header-theme-switch">
143
- <div class="theme-switch-track">
144
- <div class="theme-switch-thumb" id="header-theme-switch-thumb">
145
- <span class="theme-switch-icon">🌙</span>
146
- </div>
147
- </div>
148
- </div>
149
- </div>
150
- <a href="https://github.com/davila7/claude-code-templates" target="_blank" class="github-link" title="Star on GitHub">
151
- <span class="github-icon">⭐</span>
152
- Star on GitHub
153
- </a>
154
- </div>
155
- </div>
156
- </div>
124
+ <!-- Page Header (will be replaced by HeaderComponent) -->
125
+ <div id="dashboard-header-container"></div>
157
126
 
158
127
  <!-- Action Buttons -->
159
128
  <div class="action-buttons-container">
@@ -394,7 +363,28 @@ class DashboardPage {
394
363
  `;
395
364
 
396
365
  this.bindEvents();
397
- this.initializeTheme();
366
+ this.initializeHeaderComponent();
367
+ }
368
+
369
+ /**
370
+ * Initialize the header component
371
+ */
372
+ initializeHeaderComponent() {
373
+ const headerContainer = this.container.querySelector('#dashboard-header-container');
374
+ if (headerContainer && typeof HeaderComponent !== 'undefined') {
375
+ this.headerComponent = new HeaderComponent(headerContainer, {
376
+ title: 'Claude Code Analytics Dashboard',
377
+ subtitle: 'Real-time monitoring and analytics for Claude Code sessions',
378
+ version: 'v1.13.2', // Fallback version
379
+ showVersionBadge: true,
380
+ showLastUpdate: true,
381
+ showThemeSwitch: true,
382
+ showGitHubLink: true,
383
+ dataService: this.dataService // Pass DataService for dynamic version loading
384
+ });
385
+
386
+ this.headerComponent.render();
387
+ }
398
388
  }
399
389
 
400
390
  /**
@@ -884,11 +874,6 @@ class DashboardPage {
884
874
  retryBtn.addEventListener('click', () => this.loadInitialData());
885
875
  }
886
876
 
887
- // Theme toggle (header)
888
- const headerThemeSwitch = this.container.querySelector('#header-theme-switch');
889
- if (headerThemeSwitch) {
890
- headerThemeSwitch.addEventListener('click', () => this.toggleTheme());
891
- }
892
877
  }
893
878
 
894
879
  /**
@@ -2105,74 +2090,13 @@ class DashboardPage {
2105
2090
  }
2106
2091
  }
2107
2092
 
2108
- /**
2109
- * Initialize theme from localStorage
2110
- */
2111
- initializeTheme() {
2112
- const savedTheme = localStorage.getItem('claude-analytics-theme') || 'dark';
2113
- const body = document.body;
2114
- const headerThumb = this.container.querySelector('#header-theme-switch-thumb');
2115
- const headerIcon = headerThumb?.querySelector('.theme-switch-icon');
2116
-
2117
- body.setAttribute('data-theme', savedTheme);
2118
- if (headerThumb && headerIcon) {
2119
- if (savedTheme === 'light') {
2120
- headerThumb.classList.add('light');
2121
- headerIcon.textContent = '☀️';
2122
- } else {
2123
- headerThumb.classList.remove('light');
2124
- headerIcon.textContent = '🌙';
2125
- }
2126
- }
2127
- }
2128
-
2129
- /**
2130
- * Toggle theme between light and dark
2131
- */
2132
- toggleTheme() {
2133
- const body = document.body;
2134
- const headerThumb = this.container.querySelector('#header-theme-switch-thumb');
2135
- const headerIcon = headerThumb?.querySelector('.theme-switch-icon');
2136
-
2137
- // Also sync with global theme switch
2138
- const globalThumb = document.getElementById('themeSwitchThumb');
2139
- const globalIcon = globalThumb?.querySelector('.theme-switch-icon');
2140
-
2141
- const isLight = body.getAttribute('data-theme') === 'light';
2142
- const newTheme = isLight ? 'dark' : 'light';
2143
-
2144
- body.setAttribute('data-theme', newTheme);
2145
-
2146
- // Update header theme switch
2147
- if (headerThumb && headerIcon) {
2148
- headerThumb.classList.toggle('light', newTheme === 'light');
2149
- headerIcon.textContent = newTheme === 'light' ? '☀️' : '🌙';
2150
- }
2151
-
2152
- // Sync with global theme switch
2153
- if (globalThumb && globalIcon) {
2154
- globalThumb.classList.toggle('light', newTheme === 'light');
2155
- globalIcon.textContent = newTheme === 'light' ? '☀️' : '🌙';
2156
- }
2157
-
2158
- localStorage.setItem('claude-analytics-theme', newTheme);
2159
- }
2160
2093
 
2161
2094
  /**
2162
2095
  * Update last update time
2163
2096
  */
2164
2097
  updateLastUpdateTime() {
2165
- const currentTime = new Date().toLocaleTimeString();
2166
-
2167
- // Update both locations
2168
- const lastUpdateText = this.container.querySelector('#last-update-text');
2169
- const lastUpdateHeaderText = this.container.querySelector('#last-update-header-text');
2170
-
2171
- if (lastUpdateText) {
2172
- lastUpdateText.textContent = currentTime;
2173
- }
2174
- if (lastUpdateHeaderText) {
2175
- lastUpdateHeaderText.textContent = currentTime;
2098
+ if (this.headerComponent) {
2099
+ this.headerComponent.updateLastUpdateTime();
2176
2100
  }
2177
2101
  }
2178
2102
 
@@ -2252,6 +2176,12 @@ class DashboardPage {
2252
2176
  destroy() {
2253
2177
  this.stopPeriodicRefresh();
2254
2178
 
2179
+ // Cleanup header component
2180
+ if (this.headerComponent) {
2181
+ this.headerComponent.destroy();
2182
+ this.headerComponent = null;
2183
+ }
2184
+
2255
2185
  // Cleanup Chart.js instances specifically
2256
2186
  if (this.components.tokenChart) {
2257
2187
  this.components.tokenChart.destroy();