claude-mpm 4.2.44__py3-none-any.whl → 4.2.51__py3-none-any.whl
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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +43 -1
- claude_mpm/agents/INSTRUCTIONS.md +75 -1
- claude_mpm/agents/WORKFLOW.md +46 -1
- claude_mpm/agents/frontmatter_validator.py +20 -12
- claude_mpm/agents/templates/nextjs_engineer.json +277 -0
- claude_mpm/agents/templates/python_engineer.json +289 -0
- claude_mpm/agents/templates/react_engineer.json +11 -3
- claude_mpm/agents/templates/security.json +50 -9
- claude_mpm/cli/commands/agents.py +2 -2
- claude_mpm/cli/commands/uninstall.py +1 -2
- claude_mpm/cli/interactive/agent_wizard.py +3 -3
- claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
- claude_mpm/cli/parsers/agents_parser.py +1 -1
- claude_mpm/constants.py +1 -1
- claude_mpm/core/error_handler.py +2 -4
- claude_mpm/core/file_utils.py +4 -12
- claude_mpm/core/log_manager.py +8 -5
- claude_mpm/core/logger.py +1 -1
- claude_mpm/core/logging_utils.py +6 -6
- claude_mpm/core/unified_agent_registry.py +18 -4
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
- claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
- claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
- claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
- claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
- claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
- claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
- claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
- claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js +2 -1076
- claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
- claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
- claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -465
- claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/built/connection-manager.js +536 -0
- claude_mpm/dashboard/static/built/dashboard.js +1 -1
- claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/built/react/events.js +30 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
- claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
- claude_mpm/dashboard/static/built/shared/logger.js +385 -0
- claude_mpm/dashboard/static/built/shared/page-structure.js +251 -0
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
- claude_mpm/dashboard/static/built/socket-client.js +1 -1
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/css/dashboard.css +28 -5
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/dist/dashboard.js +1 -1
- claude_mpm/dashboard/static/dist/react/events.js +30 -0
- claude_mpm/dashboard/static/dist/socket-client.js +1 -1
- claude_mpm/dashboard/static/events.html +607 -0
- claude_mpm/dashboard/static/index.html +713 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
- claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
- claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
- claude_mpm/dashboard/static/js/components/code-viewer.js +306 -66
- claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
- claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
- claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
- claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +285 -85
- claude_mpm/dashboard/static/js/components/working-directory.js +3 -0
- claude_mpm/dashboard/static/js/dashboard.js +61 -33
- claude_mpm/dashboard/static/js/socket-client.js +12 -8
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/legacy/activity.html +736 -0
- claude_mpm/dashboard/static/legacy/agents.html +786 -0
- claude_mpm/dashboard/static/legacy/files.html +747 -0
- claude_mpm/dashboard/static/legacy/tools.html +831 -0
- claude_mpm/dashboard/static/monitors-index.html +218 -0
- claude_mpm/dashboard/static/monitors.html +431 -0
- claude_mpm/dashboard/static/production/events.html +659 -0
- claude_mpm/dashboard/static/production/main.html +715 -0
- claude_mpm/dashboard/static/production/monitors.html +483 -0
- claude_mpm/dashboard/static/socket.io.min.js +7 -0
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
- claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
- claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
- claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
- claude_mpm/dashboard/templates/index.html +79 -9
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +1 -1
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +25 -8
- claude_mpm/services/agents/deployment/agent_validator.py +3 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +13 -4
- claude_mpm/services/agents/local_template_manager.py +2 -6
- claude_mpm/services/monitor/daemon.py +1 -2
- claude_mpm/services/monitor/daemon_manager.py +2 -5
- claude_mpm/services/monitor/event_emitter.py +2 -2
- claude_mpm/services/monitor/handlers/code_analysis.py +4 -6
- claude_mpm/services/monitor/handlers/hooks.py +2 -4
- claude_mpm/services/monitor/server.py +27 -4
- claude_mpm/tools/code_tree_analyzer.py +2 -2
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/METADATA +1 -1
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/RECORD +146 -81
- claude_mpm/dashboard/static/test-browser-monitor.html +0 -470
- claude_mpm/dashboard/static/test-simple.html +0 -97
- /claude_mpm/dashboard/static/{test_debug.html → test-archive/test_debug.html} +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/WHEEL +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,385 @@
|
|
1
|
+
/**
|
2
|
+
* Logger Service
|
3
|
+
*
|
4
|
+
* Centralized logging service with levels, formatting, and performance timing.
|
5
|
+
* Provides consistent logging across dashboard components.
|
6
|
+
*
|
7
|
+
* @module logger
|
8
|
+
*/
|
9
|
+
|
10
|
+
class Logger {
|
11
|
+
constructor() {
|
12
|
+
this.logLevels = {
|
13
|
+
DEBUG: 0,
|
14
|
+
INFO: 1,
|
15
|
+
WARN: 2,
|
16
|
+
ERROR: 3,
|
17
|
+
NONE: 4
|
18
|
+
};
|
19
|
+
|
20
|
+
this.currentLevel = this.logLevels.INFO;
|
21
|
+
this.enableTimestamps = true;
|
22
|
+
this.enableColors = true;
|
23
|
+
this.logHistory = [];
|
24
|
+
this.maxHistorySize = 500;
|
25
|
+
this.performanceMarks = new Map();
|
26
|
+
this.componentLoggers = new Map();
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Set the current log level
|
31
|
+
* @param {string|number} level - Log level name or value
|
32
|
+
*/
|
33
|
+
setLevel(level) {
|
34
|
+
if (typeof level === 'string') {
|
35
|
+
level = level.toUpperCase();
|
36
|
+
if (level in this.logLevels) {
|
37
|
+
this.currentLevel = this.logLevels[level];
|
38
|
+
}
|
39
|
+
} else if (typeof level === 'number') {
|
40
|
+
this.currentLevel = level;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Create a logger for a specific component
|
46
|
+
* @param {string} componentName - Name of the component
|
47
|
+
* @returns {Object} Component logger instance
|
48
|
+
*/
|
49
|
+
createComponentLogger(componentName) {
|
50
|
+
if (this.componentLoggers.has(componentName)) {
|
51
|
+
return this.componentLoggers.get(componentName);
|
52
|
+
}
|
53
|
+
|
54
|
+
const componentLogger = {
|
55
|
+
debug: (...args) => this.debug(`[${componentName}]`, ...args),
|
56
|
+
info: (...args) => this.info(`[${componentName}]`, ...args),
|
57
|
+
warn: (...args) => this.warn(`[${componentName}]`, ...args),
|
58
|
+
error: (...args) => this.error(`[${componentName}]`, ...args),
|
59
|
+
time: (label) => this.time(`${componentName}:${label}`),
|
60
|
+
timeEnd: (label) => this.timeEnd(`${componentName}:${label}`),
|
61
|
+
group: (label) => this.group(`${componentName}: ${label}`),
|
62
|
+
groupEnd: () => this.groupEnd()
|
63
|
+
};
|
64
|
+
|
65
|
+
this.componentLoggers.set(componentName, componentLogger);
|
66
|
+
return componentLogger;
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Debug level logging
|
71
|
+
* @param {...any} args - Arguments to log
|
72
|
+
*/
|
73
|
+
debug(...args) {
|
74
|
+
if (this.currentLevel <= this.logLevels.DEBUG) {
|
75
|
+
this.log('DEBUG', args, '#6c757d');
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Info level logging
|
81
|
+
* @param {...any} args - Arguments to log
|
82
|
+
*/
|
83
|
+
info(...args) {
|
84
|
+
if (this.currentLevel <= this.logLevels.INFO) {
|
85
|
+
this.log('INFO', args, '#0d6efd');
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Warning level logging
|
91
|
+
* @param {...any} args - Arguments to log
|
92
|
+
*/
|
93
|
+
warn(...args) {
|
94
|
+
if (this.currentLevel <= this.logLevels.WARN) {
|
95
|
+
this.log('WARN', args, '#ffc107');
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Error level logging
|
101
|
+
* @param {...any} args - Arguments to log
|
102
|
+
*/
|
103
|
+
error(...args) {
|
104
|
+
if (this.currentLevel <= this.logLevels.ERROR) {
|
105
|
+
this.log('ERROR', args, '#dc3545');
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Core logging function
|
111
|
+
* @private
|
112
|
+
* @param {string} level - Log level
|
113
|
+
* @param {Array} args - Arguments to log
|
114
|
+
* @param {string} color - Color for the log level
|
115
|
+
*/
|
116
|
+
log(level, args, color) {
|
117
|
+
const timestamp = this.enableTimestamps ? new Date().toISOString() : '';
|
118
|
+
const prefix = this.formatPrefix(level, timestamp, color);
|
119
|
+
|
120
|
+
// Console output
|
121
|
+
const method = level === 'ERROR' ? 'error' : level === 'WARN' ? 'warn' : 'log';
|
122
|
+
if (this.enableColors && color) {
|
123
|
+
console[method](`%c${prefix}`, `color: ${color}; font-weight: bold;`, ...args);
|
124
|
+
} else {
|
125
|
+
console[method](prefix, ...args);
|
126
|
+
}
|
127
|
+
|
128
|
+
// Add to history
|
129
|
+
this.addToHistory(level, timestamp, args);
|
130
|
+
}
|
131
|
+
|
132
|
+
/**
|
133
|
+
* Format log prefix
|
134
|
+
* @private
|
135
|
+
* @param {string} level - Log level
|
136
|
+
* @param {string} timestamp - Timestamp
|
137
|
+
* @param {string} color - Color
|
138
|
+
* @returns {string} Formatted prefix
|
139
|
+
*/
|
140
|
+
formatPrefix(level, timestamp, color) {
|
141
|
+
const parts = [];
|
142
|
+
if (timestamp) {
|
143
|
+
parts.push(`[${timestamp}]`);
|
144
|
+
}
|
145
|
+
parts.push(`[${level}]`);
|
146
|
+
return parts.join(' ');
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Add log entry to history
|
151
|
+
* @private
|
152
|
+
* @param {string} level - Log level
|
153
|
+
* @param {string} timestamp - Timestamp
|
154
|
+
* @param {Array} args - Log arguments
|
155
|
+
*/
|
156
|
+
addToHistory(level, timestamp, args) {
|
157
|
+
this.logHistory.push({
|
158
|
+
level,
|
159
|
+
timestamp,
|
160
|
+
message: args.map(arg =>
|
161
|
+
typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
|
162
|
+
).join(' ')
|
163
|
+
});
|
164
|
+
|
165
|
+
// Limit history size
|
166
|
+
if (this.logHistory.length > this.maxHistorySize) {
|
167
|
+
this.logHistory.shift();
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Start a performance timer
|
173
|
+
* @param {string} label - Timer label
|
174
|
+
*/
|
175
|
+
time(label) {
|
176
|
+
this.performanceMarks.set(label, {
|
177
|
+
start: performance.now(),
|
178
|
+
memory: performance.memory ? performance.memory.usedJSHeapSize : null
|
179
|
+
});
|
180
|
+
this.debug(`Timer started: ${label}`);
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* End a performance timer and log the result
|
185
|
+
* @param {string} label - Timer label
|
186
|
+
* @returns {number} Elapsed time in milliseconds
|
187
|
+
*/
|
188
|
+
timeEnd(label) {
|
189
|
+
const mark = this.performanceMarks.get(label);
|
190
|
+
if (!mark) {
|
191
|
+
this.warn(`Timer not found: ${label}`);
|
192
|
+
return null;
|
193
|
+
}
|
194
|
+
|
195
|
+
const elapsed = performance.now() - mark.start;
|
196
|
+
const memoryDelta = performance.memory
|
197
|
+
? performance.memory.usedJSHeapSize - mark.memory
|
198
|
+
: null;
|
199
|
+
|
200
|
+
this.performanceMarks.delete(label);
|
201
|
+
|
202
|
+
const message = [`Timer ended: ${label} - ${elapsed.toFixed(2)}ms`];
|
203
|
+
if (memoryDelta !== null) {
|
204
|
+
message.push(`(Memory: ${this.formatBytes(memoryDelta)})`);
|
205
|
+
}
|
206
|
+
|
207
|
+
this.info(...message);
|
208
|
+
return elapsed;
|
209
|
+
}
|
210
|
+
|
211
|
+
/**
|
212
|
+
* Log a performance mark
|
213
|
+
* @param {string} name - Mark name
|
214
|
+
*/
|
215
|
+
mark(name) {
|
216
|
+
if (performance.mark) {
|
217
|
+
performance.mark(name);
|
218
|
+
this.debug(`Performance mark: ${name}`);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
222
|
+
/**
|
223
|
+
* Log a performance measure
|
224
|
+
* @param {string} name - Measure name
|
225
|
+
* @param {string} startMark - Start mark name
|
226
|
+
* @param {string} endMark - End mark name
|
227
|
+
*/
|
228
|
+
measure(name, startMark, endMark) {
|
229
|
+
if (performance.measure) {
|
230
|
+
try {
|
231
|
+
performance.measure(name, startMark, endMark);
|
232
|
+
const entries = performance.getEntriesByName(name);
|
233
|
+
if (entries.length > 0) {
|
234
|
+
const duration = entries[entries.length - 1].duration;
|
235
|
+
this.info(`Performance measure: ${name} - ${duration.toFixed(2)}ms`);
|
236
|
+
}
|
237
|
+
} catch (error) {
|
238
|
+
this.error(`Failed to measure performance: ${error.message}`);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Create a log group
|
245
|
+
* @param {string} label - Group label
|
246
|
+
*/
|
247
|
+
group(label) {
|
248
|
+
if (console.group) {
|
249
|
+
console.group(label);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Create a collapsed log group
|
255
|
+
* @param {string} label - Group label
|
256
|
+
*/
|
257
|
+
groupCollapsed(label) {
|
258
|
+
if (console.groupCollapsed) {
|
259
|
+
console.groupCollapsed(label);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
/**
|
264
|
+
* End a log group
|
265
|
+
*/
|
266
|
+
groupEnd() {
|
267
|
+
if (console.groupEnd) {
|
268
|
+
console.groupEnd();
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
/**
|
273
|
+
* Log a table
|
274
|
+
* @param {Array|Object} data - Data to display as table
|
275
|
+
* @param {Array} columns - Optional column names
|
276
|
+
*/
|
277
|
+
table(data, columns) {
|
278
|
+
if (console.table) {
|
279
|
+
console.table(data, columns);
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
/**
|
284
|
+
* Clear the console
|
285
|
+
*/
|
286
|
+
clear() {
|
287
|
+
if (console.clear) {
|
288
|
+
console.clear();
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
/**
|
293
|
+
* Get log history
|
294
|
+
* @param {string} level - Optional level filter
|
295
|
+
* @returns {Array} Log history
|
296
|
+
*/
|
297
|
+
getHistory(level) {
|
298
|
+
if (level) {
|
299
|
+
return this.logHistory.filter(entry => entry.level === level);
|
300
|
+
}
|
301
|
+
return this.logHistory.slice();
|
302
|
+
}
|
303
|
+
|
304
|
+
/**
|
305
|
+
* Export log history as text
|
306
|
+
* @returns {string} Log history as text
|
307
|
+
*/
|
308
|
+
exportHistory() {
|
309
|
+
return this.logHistory
|
310
|
+
.map(entry => `${entry.timestamp} [${entry.level}] ${entry.message}`)
|
311
|
+
.join('\n');
|
312
|
+
}
|
313
|
+
|
314
|
+
/**
|
315
|
+
* Clear log history
|
316
|
+
*/
|
317
|
+
clearHistory() {
|
318
|
+
this.logHistory = [];
|
319
|
+
}
|
320
|
+
|
321
|
+
/**
|
322
|
+
* Format bytes for display
|
323
|
+
* @private
|
324
|
+
* @param {number} bytes - Number of bytes
|
325
|
+
* @returns {string} Formatted string
|
326
|
+
*/
|
327
|
+
formatBytes(bytes) {
|
328
|
+
const sign = bytes < 0 ? '-' : '+';
|
329
|
+
bytes = Math.abs(bytes);
|
330
|
+
|
331
|
+
if (bytes === 0) return '0 B';
|
332
|
+
|
333
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
334
|
+
const index = Math.floor(Math.log(bytes) / Math.log(1024));
|
335
|
+
const value = bytes / Math.pow(1024, index);
|
336
|
+
|
337
|
+
return `${sign}${value.toFixed(2)} ${units[index]}`;
|
338
|
+
}
|
339
|
+
|
340
|
+
/**
|
341
|
+
* Assert a condition
|
342
|
+
* @param {boolean} condition - Condition to assert
|
343
|
+
* @param {string} message - Error message if condition is false
|
344
|
+
*/
|
345
|
+
assert(condition, message) {
|
346
|
+
if (!condition) {
|
347
|
+
this.error(`Assertion failed: ${message}`);
|
348
|
+
if (console.trace) {
|
349
|
+
console.trace();
|
350
|
+
}
|
351
|
+
}
|
352
|
+
}
|
353
|
+
|
354
|
+
/**
|
355
|
+
* Count occurrences
|
356
|
+
* @param {string} label - Counter label
|
357
|
+
*/
|
358
|
+
count(label = 'default') {
|
359
|
+
if (console.count) {
|
360
|
+
console.count(label);
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
/**
|
365
|
+
* Reset a counter
|
366
|
+
* @param {string} label - Counter label
|
367
|
+
*/
|
368
|
+
countReset(label = 'default') {
|
369
|
+
if (console.countReset) {
|
370
|
+
console.countReset(label);
|
371
|
+
}
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
375
|
+
// Create singleton instance
|
376
|
+
const logger = new Logger();
|
377
|
+
|
378
|
+
// Support both module and global usage
|
379
|
+
if (typeof module !== 'undefined' && module.exports) {
|
380
|
+
module.exports = logger;
|
381
|
+
} else if (typeof define === 'function' && define.amd) {
|
382
|
+
define([], () => logger);
|
383
|
+
} else {
|
384
|
+
window.logger = logger;
|
385
|
+
}
|
@@ -0,0 +1,251 @@
|
|
1
|
+
/**
|
2
|
+
* Shared Page Structure Component
|
3
|
+
* Provides consistent header and navigation across all dashboard pages
|
4
|
+
*/
|
5
|
+
|
6
|
+
export class PageStructure {
|
7
|
+
constructor() {
|
8
|
+
this.pages = [
|
9
|
+
{ id: 'main', label: '📈 Main Dashboard', href: '/static/' },
|
10
|
+
{ id: 'monitors', label: '📋 All Monitors', href: '/static/monitors-index.html' },
|
11
|
+
{ id: 'events', label: '📊 Events', href: '/static/events.html' },
|
12
|
+
{ id: 'agents', label: '🤖 Agents', href: '/static/agents.html' },
|
13
|
+
{ id: 'tools', label: '🔧 Tools', href: '/static/tools.html' },
|
14
|
+
{ id: 'files', label: '📁 Files', href: '/static/files.html' },
|
15
|
+
{ id: 'activity', label: '🌳 Activity', href: '/static/activity.html' }
|
16
|
+
];
|
17
|
+
}
|
18
|
+
|
19
|
+
getCurrentPage() {
|
20
|
+
const path = window.location.pathname;
|
21
|
+
|
22
|
+
if (path.includes('events.html')) return 'events';
|
23
|
+
if (path.includes('agents.html')) return 'agents';
|
24
|
+
if (path.includes('tools.html')) return 'tools';
|
25
|
+
if (path.includes('files.html')) return 'files';
|
26
|
+
if (path.includes('activity.html')) return 'activity';
|
27
|
+
if (path.includes('monitors-index.html')) return 'monitors';
|
28
|
+
if (path.includes('index.html') || path.endsWith('/static/') || path.endsWith('/')) return 'main';
|
29
|
+
|
30
|
+
return 'main';
|
31
|
+
}
|
32
|
+
|
33
|
+
generateNavigation() {
|
34
|
+
const currentPage = this.getCurrentPage();
|
35
|
+
|
36
|
+
const navItems = this.pages.map(page => {
|
37
|
+
const isActive = page.id === currentPage;
|
38
|
+
return `
|
39
|
+
<a href="${page.href}" class="nav-item ${isActive ? 'active' : ''}" data-page="${page.id}">
|
40
|
+
${page.label}
|
41
|
+
</a>
|
42
|
+
`;
|
43
|
+
}).join('');
|
44
|
+
|
45
|
+
return `
|
46
|
+
<div class="page-header">
|
47
|
+
<div class="header-brand">
|
48
|
+
<h1>🚀 Claude MPM Monitor</h1>
|
49
|
+
<p>Real-time monitoring for agents, tools, files, and events</p>
|
50
|
+
</div>
|
51
|
+
<div class="header-navigation">
|
52
|
+
${navItems}
|
53
|
+
</div>
|
54
|
+
<div class="header-status">
|
55
|
+
<div id="page-connection-status" class="connection-status">
|
56
|
+
<span class="status-indicator">●</span>
|
57
|
+
<span class="status-text">Checking...</span>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
</div>
|
61
|
+
`;
|
62
|
+
}
|
63
|
+
|
64
|
+
generateCSS() {
|
65
|
+
return `
|
66
|
+
<style id="page-structure-styles">
|
67
|
+
.page-header {
|
68
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
69
|
+
color: white;
|
70
|
+
padding: 2rem;
|
71
|
+
text-align: center;
|
72
|
+
margin-bottom: 2rem;
|
73
|
+
border-radius: 12px;
|
74
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
75
|
+
}
|
76
|
+
|
77
|
+
.header-brand h1 {
|
78
|
+
margin: 0 0 0.5rem 0;
|
79
|
+
font-size: 2.5rem;
|
80
|
+
font-weight: 700;
|
81
|
+
background: linear-gradient(135deg, #fff 0%, #e0e0e0 100%);
|
82
|
+
-webkit-background-clip: text;
|
83
|
+
-webkit-text-fill-color: transparent;
|
84
|
+
background-clip: text;
|
85
|
+
}
|
86
|
+
|
87
|
+
.header-brand p {
|
88
|
+
margin: 0 0 1.5rem 0;
|
89
|
+
opacity: 0.9;
|
90
|
+
font-size: 1.1rem;
|
91
|
+
}
|
92
|
+
|
93
|
+
.header-navigation {
|
94
|
+
display: flex;
|
95
|
+
justify-content: center;
|
96
|
+
gap: 1rem;
|
97
|
+
flex-wrap: wrap;
|
98
|
+
margin-bottom: 1.5rem;
|
99
|
+
}
|
100
|
+
|
101
|
+
.nav-item {
|
102
|
+
padding: 0.75rem 1.5rem;
|
103
|
+
background: rgba(255, 255, 255, 0.1);
|
104
|
+
backdrop-filter: blur(10px);
|
105
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
106
|
+
border-radius: 25px;
|
107
|
+
color: white;
|
108
|
+
text-decoration: none;
|
109
|
+
font-size: 0.9rem;
|
110
|
+
font-weight: 500;
|
111
|
+
transition: all 0.3s ease;
|
112
|
+
display: inline-block;
|
113
|
+
}
|
114
|
+
|
115
|
+
.nav-item:hover {
|
116
|
+
background: rgba(255, 255, 255, 0.2);
|
117
|
+
transform: translateY(-2px);
|
118
|
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
119
|
+
}
|
120
|
+
|
121
|
+
.nav-item.active {
|
122
|
+
background: rgba(255, 255, 255, 0.25);
|
123
|
+
border-color: rgba(255, 255, 255, 0.4);
|
124
|
+
font-weight: 600;
|
125
|
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
126
|
+
}
|
127
|
+
|
128
|
+
.header-status {
|
129
|
+
display: flex;
|
130
|
+
justify-content: center;
|
131
|
+
}
|
132
|
+
|
133
|
+
.connection-status {
|
134
|
+
display: flex;
|
135
|
+
align-items: center;
|
136
|
+
gap: 0.5rem;
|
137
|
+
padding: 0.5rem 1rem;
|
138
|
+
background: rgba(255, 255, 255, 0.1);
|
139
|
+
border-radius: 20px;
|
140
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
141
|
+
font-size: 0.9rem;
|
142
|
+
}
|
143
|
+
|
144
|
+
.status-indicator {
|
145
|
+
font-size: 1.2rem;
|
146
|
+
}
|
147
|
+
|
148
|
+
.connection-status.connected .status-indicator {
|
149
|
+
color: #22c55e;
|
150
|
+
text-shadow: 0 0 10px #22c55e;
|
151
|
+
}
|
152
|
+
|
153
|
+
.connection-status.connecting .status-indicator {
|
154
|
+
color: #fbbf24;
|
155
|
+
text-shadow: 0 0 10px #fbbf24;
|
156
|
+
animation: pulse 1s infinite;
|
157
|
+
}
|
158
|
+
|
159
|
+
.connection-status.disconnected .status-indicator {
|
160
|
+
color: #ef4444;
|
161
|
+
text-shadow: 0 0 10px #ef4444;
|
162
|
+
}
|
163
|
+
|
164
|
+
@keyframes pulse {
|
165
|
+
0%, 100% { opacity: 1; }
|
166
|
+
50% { opacity: 0.5; }
|
167
|
+
}
|
168
|
+
|
169
|
+
@media (max-width: 768px) {
|
170
|
+
.page-header {
|
171
|
+
padding: 1.5rem;
|
172
|
+
}
|
173
|
+
|
174
|
+
.header-brand h1 {
|
175
|
+
font-size: 2rem;
|
176
|
+
}
|
177
|
+
|
178
|
+
.header-navigation {
|
179
|
+
gap: 0.5rem;
|
180
|
+
}
|
181
|
+
|
182
|
+
.nav-item {
|
183
|
+
padding: 0.5rem 1rem;
|
184
|
+
font-size: 0.8rem;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
</style>
|
188
|
+
`;
|
189
|
+
}
|
190
|
+
|
191
|
+
insertIntoPage(containerId = 'page-header') {
|
192
|
+
// Insert CSS
|
193
|
+
const existingStyles = document.getElementById('page-structure-styles');
|
194
|
+
if (!existingStyles) {
|
195
|
+
document.head.insertAdjacentHTML('beforeend', this.generateCSS());
|
196
|
+
}
|
197
|
+
|
198
|
+
// Insert HTML
|
199
|
+
const container = document.getElementById(containerId);
|
200
|
+
if (container) {
|
201
|
+
container.innerHTML = this.generateNavigation();
|
202
|
+
this.setupEventListeners();
|
203
|
+
} else {
|
204
|
+
// If no container found, create one at the top of the body
|
205
|
+
document.body.insertAdjacentHTML('afterbegin', `
|
206
|
+
<div id="${containerId}">
|
207
|
+
${this.generateNavigation()}
|
208
|
+
</div>
|
209
|
+
`);
|
210
|
+
this.setupEventListeners();
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
setupEventListeners() {
|
215
|
+
// Listen for connection status changes
|
216
|
+
document.addEventListener('socketConnectionStatus', (e) => {
|
217
|
+
this.updateConnectionStatus(e.detail.status, e.detail.type);
|
218
|
+
});
|
219
|
+
}
|
220
|
+
|
221
|
+
updateConnectionStatus(status, type) {
|
222
|
+
const statusElement = document.getElementById('page-connection-status');
|
223
|
+
if (statusElement) {
|
224
|
+
const indicator = statusElement.querySelector('.status-indicator');
|
225
|
+
const text = statusElement.querySelector('.status-text');
|
226
|
+
|
227
|
+
if (text) text.textContent = status;
|
228
|
+
|
229
|
+
statusElement.className = `connection-status ${type}`;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
initialize() {
|
234
|
+
// Auto-initialize when DOM is ready
|
235
|
+
if (document.readyState === 'loading') {
|
236
|
+
document.addEventListener('DOMContentLoaded', () => {
|
237
|
+
this.insertIntoPage();
|
238
|
+
});
|
239
|
+
} else {
|
240
|
+
this.insertIntoPage();
|
241
|
+
}
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
// Auto-initialize
|
246
|
+
const pageStructure = new PageStructure();
|
247
|
+
pageStructure.initialize();
|
248
|
+
|
249
|
+
// Export for manual use
|
250
|
+
export default PageStructure;
|
251
|
+
window.PageStructure = PageStructure;
|