claude-team-dashboard 1.2.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/dist/sw.js ADDED
@@ -0,0 +1,105 @@
1
+ const CACHE_NAME = 'agent-dashboard-v3';
2
+ const PRECACHE_URLS = [
3
+ '/',
4
+ '/index.html',
5
+ '/manifest.json'
6
+ ];
7
+
8
+ // Install: precache core assets
9
+ self.addEventListener('install', (event) => {
10
+ event.waitUntil(
11
+ caches.open(CACHE_NAME).then((cache) => {
12
+ return cache.addAll(PRECACHE_URLS);
13
+ })
14
+ );
15
+ self.skipWaiting();
16
+ });
17
+
18
+ // Activate: clean up old caches
19
+ self.addEventListener('activate', (event) => {
20
+ event.waitUntil(
21
+ caches.keys().then((cacheNames) => {
22
+ return Promise.all(
23
+ cacheNames
24
+ .filter((name) => name !== CACHE_NAME)
25
+ .map((name) => caches.delete(name))
26
+ );
27
+ })
28
+ );
29
+ self.clients.claim();
30
+ });
31
+
32
+ // Fetch: Network First for API, Cache First for static assets
33
+ self.addEventListener('fetch', (event) => {
34
+ const { request } = event;
35
+ const url = new URL(request.url);
36
+
37
+ // Skip non-GET requests
38
+ if (request.method !== 'GET') return;
39
+
40
+ // Skip non-http(s) schemes (e.g. chrome-extension://)
41
+ if (!url.protocol.startsWith('http')) return;
42
+
43
+ // Skip WebSocket upgrade requests
44
+ if (request.headers.get('upgrade') === 'websocket') return;
45
+
46
+ // Always fetch HTML navigation requests fresh (never cache the shell)
47
+ if (request.mode === 'navigate') {
48
+ event.respondWith(networkFirst(request));
49
+ return;
50
+ }
51
+
52
+ // Network First for API routes
53
+ if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/api')) {
54
+ event.respondWith(networkFirst(request));
55
+ return;
56
+ }
57
+
58
+ // Always network-first for JS/CSS assets (Vite hash-busts them already)
59
+ if (url.pathname.startsWith('/assets/')) {
60
+ event.respondWith(networkFirst(request));
61
+ return;
62
+ }
63
+
64
+ // Cache First for other static assets (icons, manifest, etc.)
65
+ event.respondWith(cacheFirst(request));
66
+ });
67
+
68
+ async function networkFirst(request) {
69
+ try {
70
+ const response = await fetch(request);
71
+ if (response.ok) {
72
+ const cache = await caches.open(CACHE_NAME);
73
+ cache.put(request, response.clone());
74
+ }
75
+ return response;
76
+ } catch (err) {
77
+ const cached = await caches.match(request);
78
+ if (cached) return cached;
79
+ return new Response(JSON.stringify({ error: 'Offline', message: 'No cached data available' }), {
80
+ status: 503,
81
+ headers: { 'Content-Type': 'application/json' }
82
+ });
83
+ }
84
+ }
85
+
86
+ async function cacheFirst(request) {
87
+ const cached = await caches.match(request);
88
+ if (cached) return cached;
89
+
90
+ try {
91
+ const response = await fetch(request);
92
+ if (response.ok) {
93
+ const cache = await caches.open(CACHE_NAME);
94
+ cache.put(request, response.clone());
95
+ }
96
+ return response;
97
+ } catch (err) {
98
+ // For navigation requests, return cached index.html (SPA fallback)
99
+ if (request.mode === 'navigate') {
100
+ const cachedIndex = await caches.match('/index.html');
101
+ if (cachedIndex) return cachedIndex;
102
+ }
103
+ return new Response('Offline', { status: 503 });
104
+ }
105
+ }
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "claude-team-dashboard",
3
+ "version": "1.2.6",
4
+ "description": "Real-time monitoring dashboard for Claude Code agent teams",
5
+ "main": "server.js",
6
+ "bin": {
7
+ "claude-dashboard": "start.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "public",
12
+ "server.js",
13
+ "start.js",
14
+ "cleanup.js",
15
+ "config.js"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18.0.0"
19
+ },
20
+ "scripts": {
21
+ "start": "node start.js",
22
+ "cleanup": "node cleanup.js",
23
+ "restart": "node cleanup.js && node start.js",
24
+ "dev:server": "node server.js",
25
+ "dev:client": "vite",
26
+ "dev": "vite",
27
+ "server": "node server.js",
28
+ "build": "vite build",
29
+ "prepare": "vite build",
30
+ "preview": "vite preview",
31
+ "test": "vitest",
32
+ "test:ui": "vitest --ui",
33
+ "test:coverage": "vitest --coverage",
34
+ "test:e2e": "playwright test"
35
+ },
36
+ "keywords": [
37
+ "claude",
38
+ "agent",
39
+ "dashboard",
40
+ "monitoring",
41
+ "react",
42
+ "websocket",
43
+ "real-time"
44
+ ],
45
+ "author": "mukul975 <https://github.com/mukul975>",
46
+ "license": "MIT",
47
+ "type": "commonjs",
48
+ "dependencies": {
49
+ "chokidar": "^5.0.0",
50
+ "compression": "^1.8.1",
51
+ "cors": "^2.8.6",
52
+ "express": "^5.2.1",
53
+ "express-rate-limit": "^8.2.1",
54
+ "helmet": "^8.1.0",
55
+ "ws": "^8.19.0"
56
+ },
57
+ "devDependencies": {
58
+ "@playwright/test": "^1.58.2",
59
+ "@tailwindcss/vite": "^4.2.0",
60
+ "@testing-library/jest-dom": "^6.9.1",
61
+ "@testing-library/react": "^16.3.2",
62
+ "@testing-library/user-event": "^14.6.1",
63
+ "@vitejs/plugin-react": "^5.1.3",
64
+ "@vitest/coverage-v8": "^4.0.18",
65
+ "babel-plugin-react-compiler": "^1.0.0",
66
+ "d3": "^7.9.0",
67
+ "dayjs": "^1.11.19",
68
+ "jsdom": "^28.0.0",
69
+ "jsfuzz": "^1.0.1",
70
+ "license-checker": "^25.0.1",
71
+ "lucide-react": "^0.563.0",
72
+ "prop-types": "^15.8.1",
73
+ "react": "^19.2.4",
74
+ "react-dom": "^19.2.4",
75
+ "react-hot-toast": "^2.6.0",
76
+ "recharts": "^3.7.0",
77
+ "tailwindcss": "^4.2.0",
78
+ "vite": "^7.3.1",
79
+ "vitest": "^4.0.18"
80
+ }
81
+ }
Binary file
Binary file
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "Claude Code Agent Dashboard",
3
+ "short_name": "AgentDash",
4
+ "description": "Real-time monitoring dashboard for Claude Code agent teams",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#111827",
8
+ "theme_color": "#f97316",
9
+ "orientation": "any",
10
+ "icons": [
11
+ { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
12
+ { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
13
+ ],
14
+ "categories": ["productivity", "developer tools"]
15
+ }
package/public/sw.js ADDED
@@ -0,0 +1,105 @@
1
+ const CACHE_NAME = 'agent-dashboard-v3';
2
+ const PRECACHE_URLS = [
3
+ '/',
4
+ '/index.html',
5
+ '/manifest.json'
6
+ ];
7
+
8
+ // Install: precache core assets
9
+ self.addEventListener('install', (event) => {
10
+ event.waitUntil(
11
+ caches.open(CACHE_NAME).then((cache) => {
12
+ return cache.addAll(PRECACHE_URLS);
13
+ })
14
+ );
15
+ self.skipWaiting();
16
+ });
17
+
18
+ // Activate: clean up old caches
19
+ self.addEventListener('activate', (event) => {
20
+ event.waitUntil(
21
+ caches.keys().then((cacheNames) => {
22
+ return Promise.all(
23
+ cacheNames
24
+ .filter((name) => name !== CACHE_NAME)
25
+ .map((name) => caches.delete(name))
26
+ );
27
+ })
28
+ );
29
+ self.clients.claim();
30
+ });
31
+
32
+ // Fetch: Network First for API, Cache First for static assets
33
+ self.addEventListener('fetch', (event) => {
34
+ const { request } = event;
35
+ const url = new URL(request.url);
36
+
37
+ // Skip non-GET requests
38
+ if (request.method !== 'GET') return;
39
+
40
+ // Skip non-http(s) schemes (e.g. chrome-extension://)
41
+ if (!url.protocol.startsWith('http')) return;
42
+
43
+ // Skip WebSocket upgrade requests
44
+ if (request.headers.get('upgrade') === 'websocket') return;
45
+
46
+ // Always fetch HTML navigation requests fresh (never cache the shell)
47
+ if (request.mode === 'navigate') {
48
+ event.respondWith(networkFirst(request));
49
+ return;
50
+ }
51
+
52
+ // Network First for API routes
53
+ if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/api')) {
54
+ event.respondWith(networkFirst(request));
55
+ return;
56
+ }
57
+
58
+ // Always network-first for JS/CSS assets (Vite hash-busts them already)
59
+ if (url.pathname.startsWith('/assets/')) {
60
+ event.respondWith(networkFirst(request));
61
+ return;
62
+ }
63
+
64
+ // Cache First for other static assets (icons, manifest, etc.)
65
+ event.respondWith(cacheFirst(request));
66
+ });
67
+
68
+ async function networkFirst(request) {
69
+ try {
70
+ const response = await fetch(request);
71
+ if (response.ok) {
72
+ const cache = await caches.open(CACHE_NAME);
73
+ cache.put(request, response.clone());
74
+ }
75
+ return response;
76
+ } catch (err) {
77
+ const cached = await caches.match(request);
78
+ if (cached) return cached;
79
+ return new Response(JSON.stringify({ error: 'Offline', message: 'No cached data available' }), {
80
+ status: 503,
81
+ headers: { 'Content-Type': 'application/json' }
82
+ });
83
+ }
84
+ }
85
+
86
+ async function cacheFirst(request) {
87
+ const cached = await caches.match(request);
88
+ if (cached) return cached;
89
+
90
+ try {
91
+ const response = await fetch(request);
92
+ if (response.ok) {
93
+ const cache = await caches.open(CACHE_NAME);
94
+ cache.put(request, response.clone());
95
+ }
96
+ return response;
97
+ } catch (err) {
98
+ // For navigation requests, return cached index.html (SPA fallback)
99
+ if (request.mode === 'navigate') {
100
+ const cachedIndex = await caches.match('/index.html');
101
+ if (cachedIndex) return cachedIndex;
102
+ }
103
+ return new Response('Offline', { status: 503 });
104
+ }
105
+ }