claude-mpm 4.2.43__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.
Files changed (155) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +117 -12
  3. claude_mpm/agents/INSTRUCTIONS.md +154 -10
  4. claude_mpm/agents/WORKFLOW.md +46 -1
  5. claude_mpm/agents/frontmatter_validator.py +20 -12
  6. claude_mpm/agents/templates/nextjs_engineer.json +277 -0
  7. claude_mpm/agents/templates/python_engineer.json +289 -0
  8. claude_mpm/agents/templates/react_engineer.json +11 -3
  9. claude_mpm/agents/templates/security.json +50 -9
  10. claude_mpm/cli/commands/agents.py +2 -2
  11. claude_mpm/cli/commands/uninstall.py +1 -2
  12. claude_mpm/cli/interactive/agent_wizard.py +3 -3
  13. claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
  14. claude_mpm/cli/parsers/agents_parser.py +1 -1
  15. claude_mpm/constants.py +1 -1
  16. claude_mpm/core/api_validator.py +330 -0
  17. claude_mpm/core/error_handler.py +2 -4
  18. claude_mpm/core/file_utils.py +4 -12
  19. claude_mpm/core/framework_loader.py +22 -0
  20. claude_mpm/core/log_manager.py +8 -5
  21. claude_mpm/core/logger.py +1 -1
  22. claude_mpm/core/logging_utils.py +6 -6
  23. claude_mpm/core/unified_agent_registry.py +18 -4
  24. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
  25. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
  26. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
  27. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
  28. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
  29. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
  30. claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
  31. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
  32. claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
  33. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
  34. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
  35. claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
  36. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
  37. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
  38. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
  39. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
  40. claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
  41. claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
  42. claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
  43. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
  44. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  45. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
  46. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  47. claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
  48. claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
  49. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
  50. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
  51. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
  52. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
  53. claude_mpm/dashboard/static/built/components/code-viewer.js +2 -1076
  54. claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
  55. claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
  56. claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
  57. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  58. claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
  59. claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
  60. claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
  61. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  62. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  63. claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
  64. claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
  65. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  66. claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -465
  67. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  68. claude_mpm/dashboard/static/built/connection-manager.js +536 -0
  69. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  70. claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
  71. claude_mpm/dashboard/static/built/react/events.js +30 -0
  72. claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
  73. claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
  74. claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
  75. claude_mpm/dashboard/static/built/shared/logger.js +385 -0
  76. claude_mpm/dashboard/static/built/shared/page-structure.js +251 -0
  77. claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
  78. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  79. claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
  80. claude_mpm/dashboard/static/css/dashboard.css +28 -5
  81. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
  82. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  83. claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
  84. claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
  85. claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
  86. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  87. claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
  88. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
  89. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  90. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  91. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  92. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  93. claude_mpm/dashboard/static/dist/react/events.js +30 -0
  94. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  95. claude_mpm/dashboard/static/events.html +607 -0
  96. claude_mpm/dashboard/static/index.html +713 -0
  97. claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
  98. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
  99. claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
  100. claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
  101. claude_mpm/dashboard/static/js/components/code-viewer.js +387 -72
  102. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  103. claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
  104. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  105. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
  106. claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
  107. claude_mpm/dashboard/static/js/components/ui-state-manager.js +286 -108
  108. claude_mpm/dashboard/static/js/components/working-directory.js +3 -0
  109. claude_mpm/dashboard/static/js/dashboard.js +61 -49
  110. claude_mpm/dashboard/static/js/socket-client.js +12 -8
  111. claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
  112. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  113. claude_mpm/dashboard/static/legacy/activity.html +736 -0
  114. claude_mpm/dashboard/static/legacy/agents.html +786 -0
  115. claude_mpm/dashboard/static/legacy/files.html +747 -0
  116. claude_mpm/dashboard/static/legacy/tools.html +831 -0
  117. claude_mpm/dashboard/static/monitors-index.html +218 -0
  118. claude_mpm/dashboard/static/monitors.html +431 -0
  119. claude_mpm/dashboard/static/production/events.html +659 -0
  120. claude_mpm/dashboard/static/production/main.html +715 -0
  121. claude_mpm/dashboard/static/production/monitors.html +483 -0
  122. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  123. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  124. claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
  125. claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
  126. claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
  127. claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
  128. claude_mpm/dashboard/templates/index.html +82 -38
  129. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +1 -1
  130. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -0
  131. claude_mpm/services/agents/deployment/agent_template_builder.py +25 -8
  132. claude_mpm/services/agents/deployment/agent_validator.py +3 -0
  133. claude_mpm/services/agents/deployment/validation/template_validator.py +13 -4
  134. claude_mpm/services/agents/local_template_manager.py +2 -6
  135. claude_mpm/services/monitor/daemon.py +1 -2
  136. claude_mpm/services/monitor/daemon_manager.py +2 -5
  137. claude_mpm/services/monitor/event_emitter.py +2 -2
  138. claude_mpm/services/monitor/handlers/code_analysis.py +4 -6
  139. claude_mpm/services/monitor/handlers/hooks.py +2 -4
  140. claude_mpm/services/monitor/server.py +23 -226
  141. claude_mpm/tools/code_tree_analyzer.py +2 -2
  142. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/METADATA +1 -1
  143. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/RECORD +148 -87
  144. claude_mpm/commands/mpm-browser-monitor.md +0 -370
  145. claude_mpm/commands/mpm-monitor.md +0 -177
  146. claude_mpm/dashboard/static/js/browser-console-monitor.js +0 -495
  147. claude_mpm/dashboard/static/js/components/browser-log-viewer.js +0 -763
  148. claude_mpm/dashboard/static/test-browser-monitor.html +0 -470
  149. claude_mpm/dashboard/static/test-simple.html +0 -97
  150. claude_mpm/services/monitor/handlers/browser.py +0 -451
  151. /claude_mpm/dashboard/static/{test_debug.html → test-archive/test_debug.html} +0 -0
  152. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/WHEEL +0 -0
  153. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/entry_points.txt +0 -0
  154. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/licenses/LICENSE +0 -0
  155. {claude_mpm-4.2.43.dist-info → claude_mpm-4.2.51.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,7 @@ import json
11
11
  import os
12
12
  import shutil
13
13
  import tempfile
14
- from contextlib import contextmanager
14
+ from contextlib import contextmanager, suppress
15
15
  from pathlib import Path
16
16
  from typing import Any, List, Optional, Union
17
17
 
@@ -374,10 +374,8 @@ def atomic_write(
374
374
  except OSError as e:
375
375
  logger.error(f"Error in atomic write to {filepath}: {e}")
376
376
  # Clean up temporary file
377
- try:
377
+ with suppress(Exception):
378
378
  os.unlink(temp_path)
379
- except:
380
- pass
381
379
  return False
382
380
 
383
381
 
@@ -703,10 +701,7 @@ def validate_file(
703
701
  return False
704
702
 
705
703
  # Check extension
706
- if extensions and filepath.suffix not in extensions:
707
- return False
708
-
709
- return True
704
+ return not (extensions and filepath.suffix not in extensions)
710
705
 
711
706
 
712
707
  def get_file_hash(
@@ -760,10 +755,7 @@ def find_files(
760
755
  if not directory.exists():
761
756
  return []
762
757
 
763
- if recursive:
764
- paths = directory.rglob(pattern)
765
- else:
766
- paths = directory.glob(pattern)
758
+ paths = directory.rglob(pattern) if recursive else directory.glob(pattern)
767
759
 
768
760
  if file_only:
769
761
  return [p for p in paths if p.is_file()]
@@ -30,6 +30,12 @@ AgentRegistryAdapter = safe_import(
30
30
  "claude_mpm.core.agent_registry", "core.agent_registry", ["AgentRegistryAdapter"]
31
31
  )
32
32
 
33
+ # Import API validator
34
+ try:
35
+ from claude_mpm.core.api_validator import validate_api_keys
36
+ except ImportError:
37
+ from ..core.api_validator import validate_api_keys
38
+
33
39
  # Import the service container and interfaces
34
40
  try:
35
41
  from claude_mpm.services.core.cache_manager import CacheManager
@@ -105,6 +111,7 @@ class FrameworkLoader:
105
111
  framework_path: Optional[Path] = None,
106
112
  agents_dir: Optional[Path] = None,
107
113
  service_container: Optional[ServiceContainer] = None,
114
+ config: Optional[Dict[str, Any]] = None,
108
115
  ):
109
116
  """
110
117
  Initialize framework loader.
@@ -113,11 +120,26 @@ class FrameworkLoader:
113
120
  framework_path: Explicit path to framework (auto-detected if None)
114
121
  agents_dir: Custom agents directory (overrides framework agents)
115
122
  service_container: Optional service container for dependency injection
123
+ config: Optional configuration dictionary for API validation and other settings
116
124
  """
117
125
  self.logger = get_logger("framework_loader")
118
126
  self.agents_dir = agents_dir
119
127
  self.framework_version = None
120
128
  self.framework_last_modified = None
129
+ self.config = config or {}
130
+
131
+ # Validate API keys on startup (before any other initialization)
132
+ if self.config.get("validate_api_keys", True):
133
+ try:
134
+ self.logger.info("Validating configured API keys...")
135
+ validate_api_keys(config=self.config, strict=True)
136
+ self.logger.info("✅ API key validation completed successfully")
137
+ except ValueError as e:
138
+ self.logger.error(f"❌ API key validation failed: {e}")
139
+ raise
140
+ except Exception as e:
141
+ self.logger.error(f"❌ Unexpected error during API validation: {e}")
142
+ raise
121
143
 
122
144
  # Use provided container or get global container
123
145
  self.container = service_container or get_global_container()
@@ -101,7 +101,9 @@ class LogManager:
101
101
  }
102
102
 
103
103
  # Base directories
104
- self.base_log_dir = Path(logging_config.get("base_directory", "logs"))
104
+ self.base_log_dir = Path(
105
+ logging_config.get("base_directory", ".claude-mpm/logs")
106
+ )
105
107
  if not self.base_log_dir.is_absolute():
106
108
  self.base_log_dir = Path.cwd() / self.base_log_dir
107
109
 
@@ -350,13 +352,14 @@ class LogManager:
350
352
  """
351
353
  One-time migration to move existing MPM logs to new subdirectory.
352
354
 
353
- Moves mpm_*.log files from .claude-mpm/logs/ to logs/mpm/
355
+ Moves mpm_*.log files from old locations to .claude-mpm/logs/mpm/
354
356
  """
355
357
  try:
356
- # Check both old possible locations
358
+ # Check old possible locations (including incorrectly created ones)
357
359
  old_locations = [
358
- Path.cwd() / ".claude-mpm" / "logs", # Old default location
359
- self.base_log_dir, # Current base location (logs/)
360
+ Path.cwd() / "logs", # Incorrectly created in project root
361
+ Path.cwd() / ".claude-mpm" / "logs", # Correct base location
362
+ self.base_log_dir, # Current base location (.claude-mpm/logs/)
360
363
  ]
361
364
  new_location = self.base_log_dir / "mpm"
362
365
 
claude_mpm/core/logger.py CHANGED
@@ -232,7 +232,7 @@ def setup_logging(
232
232
  if log_dir is None:
233
233
  # Use deployment root for logs to keep everything centralized
234
234
  deployment_root = get_project_root()
235
- log_dir = deployment_root / "logs" / "mpm"
235
+ log_dir = deployment_root / ".claude-mpm" / "logs" / "mpm"
236
236
 
237
237
  log_dir.mkdir(parents=True, exist_ok=True)
238
238
 
@@ -76,11 +76,11 @@ class LoggerFactory:
76
76
  @classmethod
77
77
  def initialize(
78
78
  cls,
79
- log_level: str = None,
79
+ log_level: Optional[str] = None,
80
80
  log_dir: Optional[Path] = None,
81
81
  log_to_file: bool = False,
82
- log_format: str = None,
83
- date_format: str = None,
82
+ log_format: Optional[str] = None,
83
+ date_format: Optional[str] = None,
84
84
  ) -> None:
85
85
  """Initialize the logging system globally.
86
86
 
@@ -268,10 +268,10 @@ def get_logger(
268
268
 
269
269
 
270
270
  def initialize_logging(
271
- log_level: str = None,
271
+ log_level: Optional[str] = None,
272
272
  log_dir: Optional[Path] = None,
273
273
  log_to_file: bool = False,
274
- log_format: str = None,
274
+ log_format: Optional[str] = None,
275
275
  ) -> None:
276
276
  """Initialize the logging system with standard configuration.
277
277
 
@@ -300,7 +300,7 @@ def set_log_level(level: str) -> None:
300
300
  LoggerFactory.set_level(level)
301
301
 
302
302
 
303
- def get_component_logger(component: str, name: str = None) -> logging.Logger:
303
+ def get_component_logger(component: str, name: Optional[str] = None) -> logging.Logger:
304
304
  """Get a logger for a specific component.
305
305
 
306
306
  Args:
@@ -367,9 +367,17 @@ class UnifiedAgentRegistry:
367
367
  break
368
368
  project_root = project_root.parent
369
369
 
370
- # Extract tags
370
+ # Extract tags (handle both list and comma-separated string formats)
371
371
  if "metadata" in data:
372
- tags = data["metadata"].get("tags", [])
372
+ tags_raw = data["metadata"].get("tags", [])
373
+ if isinstance(tags_raw, str):
374
+ tags = [
375
+ tag.strip()
376
+ for tag in tags_raw.split(",")
377
+ if tag.strip()
378
+ ]
379
+ else:
380
+ tags = tags_raw if isinstance(tags_raw, list) else []
373
381
 
374
382
  except Exception as e:
375
383
  logger.debug(
@@ -462,8 +470,14 @@ class UnifiedAgentRegistry:
462
470
  "specializations", data.get("specializations", [])
463
471
  )
464
472
 
465
- # Extract tags as specializations if present
466
- tags = metadata.get("tags", [])
473
+ # Extract tags as specializations if present (handle both formats)
474
+ tags_raw = metadata.get("tags", [])
475
+ if isinstance(tags_raw, str):
476
+ tags = [
477
+ tag.strip() for tag in tags_raw.split(",") if tag.strip()
478
+ ]
479
+ else:
480
+ tags = tags_raw if isinstance(tags_raw, list) else []
467
481
  if tags and not specializations:
468
482
  specializations = tags
469
483
  else:
@@ -0,0 +1,188 @@
1
+ .dataInspector {
2
+ background: rgba(0, 0, 0, 0.3);
3
+ border-radius: 6px;
4
+ border: 1px solid rgba(255, 255, 255, 0.1);
5
+ overflow: hidden;
6
+ }
7
+
8
+ .inspectorHeader {
9
+ display: flex;
10
+ gap: 10px;
11
+ padding: 10px;
12
+ background: rgba(255, 255, 255, 0.05);
13
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
14
+ align-items: center;
15
+ }
16
+
17
+ .searchInput {
18
+ flex: 1;
19
+ padding: 8px 12px;
20
+ background: rgba(255, 255, 255, 0.05);
21
+ border: 1px solid rgba(255, 255, 255, 0.1);
22
+ border-radius: 4px;
23
+ color: white;
24
+ font-size: 12px;
25
+ }
26
+
27
+ .searchInput::placeholder {
28
+ color: rgba(255, 255, 255, 0.5);
29
+ }
30
+
31
+ .actions {
32
+ display: flex;
33
+ gap: 8px;
34
+ }
35
+
36
+ .actionButton {
37
+ padding: 6px 12px;
38
+ background: rgba(255, 255, 255, 0.1);
39
+ border: none;
40
+ border-radius: 4px;
41
+ color: white;
42
+ font-size: 11px;
43
+ cursor: pointer;
44
+ transition: background 0.2s;
45
+ }
46
+
47
+ .actionButton:hover {
48
+ background: rgba(255, 255, 255, 0.2);
49
+ }
50
+
51
+ .treeContainer {
52
+ overflow-y: auto;
53
+ padding: 10px;
54
+ font-family: 'Courier New', monospace;
55
+ font-size: 13px;
56
+ line-height: 1.4;
57
+ }
58
+
59
+ .treeNode {
60
+ margin-bottom: 2px;
61
+ }
62
+
63
+ .nodeHeader {
64
+ display: flex;
65
+ align-items: center;
66
+ gap: 6px;
67
+ padding: 2px 4px;
68
+ cursor: pointer;
69
+ border-radius: 3px;
70
+ transition: background 0.2s;
71
+ }
72
+
73
+ .nodeHeader:hover {
74
+ background: rgba(255, 255, 255, 0.05);
75
+ }
76
+
77
+ .expandIcon {
78
+ color: #94a3b8;
79
+ font-size: 10px;
80
+ transition: transform 0.2s;
81
+ cursor: pointer;
82
+ user-select: none;
83
+ width: 12px;
84
+ display: inline-block;
85
+ }
86
+
87
+ .expandIcon.expanded {
88
+ transform: rotate(90deg);
89
+ }
90
+
91
+ .leafIcon {
92
+ color: #94a3b8;
93
+ font-size: 8px;
94
+ width: 12px;
95
+ display: inline-block;
96
+ text-align: center;
97
+ }
98
+
99
+ .nodeKey {
100
+ color: #60a5fa;
101
+ font-weight: 500;
102
+ }
103
+
104
+ .nodeValue {
105
+ margin-left: 6px;
106
+ word-break: break-all;
107
+ }
108
+
109
+ .nodeValue.string {
110
+ color: #86efac;
111
+ }
112
+
113
+ .nodeValue.number {
114
+ color: #fbbf24;
115
+ }
116
+
117
+ .nodeValue.boolean {
118
+ color: #a78bfa;
119
+ }
120
+
121
+ .nodeValue.null,
122
+ .nodeValue.undefined {
123
+ color: #f87171;
124
+ font-style: italic;
125
+ }
126
+
127
+ .nodeValue.object,
128
+ .nodeValue.array {
129
+ color: #94a3b8;
130
+ font-style: italic;
131
+ }
132
+
133
+ .copyButton {
134
+ margin-left: auto;
135
+ background: none;
136
+ border: none;
137
+ color: rgba(255, 255, 255, 0.5);
138
+ cursor: pointer;
139
+ padding: 2px;
140
+ font-size: 10px;
141
+ opacity: 0;
142
+ transition: opacity 0.2s;
143
+ }
144
+
145
+ .nodeHeader:hover .copyButton {
146
+ opacity: 1;
147
+ }
148
+
149
+ .copyButton:hover {
150
+ color: rgba(255, 255, 255, 0.8);
151
+ }
152
+
153
+ .nodeChildren {
154
+ border-left: 1px solid rgba(255, 255, 255, 0.1);
155
+ margin-left: 6px;
156
+ }
157
+
158
+ .highlight {
159
+ background: rgba(251, 191, 36, 0.3);
160
+ color: #fbbf24;
161
+ padding: 1px 2px;
162
+ border-radius: 2px;
163
+ }
164
+
165
+ .noData {
166
+ text-align: center;
167
+ color: rgba(255, 255, 255, 0.5);
168
+ padding: 20px;
169
+ font-style: italic;
170
+ }
171
+
172
+ /* Scrollbar styling */
173
+ .treeContainer::-webkit-scrollbar {
174
+ width: 6px;
175
+ }
176
+
177
+ .treeContainer::-webkit-scrollbar-track {
178
+ background: rgba(255, 255, 255, 0.05);
179
+ }
180
+
181
+ .treeContainer::-webkit-scrollbar-thumb {
182
+ background: rgba(255, 255, 255, 0.2);
183
+ border-radius: 3px;
184
+ }
185
+
186
+ .treeContainer::-webkit-scrollbar-thumb:hover {
187
+ background: rgba(255, 255, 255, 0.3);
188
+ }
@@ -0,0 +1,156 @@
1
+ .eventsContainer {
2
+ background: rgba(255, 255, 255, 0.05);
3
+ backdrop-filter: blur(10px);
4
+ border-radius: 12px;
5
+ border: 1px solid rgba(255, 255, 255, 0.1);
6
+ overflow: hidden;
7
+ flex: 1;
8
+ display: flex;
9
+ flex-direction: column;
10
+ min-height: 0;
11
+ }
12
+
13
+ .eventsHeader {
14
+ padding: 15px 20px;
15
+ background: rgba(255, 255, 255, 0.05);
16
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ }
21
+
22
+ .eventsTitle {
23
+ font-weight: 600;
24
+ font-size: 16px;
25
+ }
26
+
27
+ .eventsInfo {
28
+ font-size: 12px;
29
+ color: rgba(255, 255, 255, 0.6);
30
+ }
31
+
32
+ .eventsList {
33
+ flex: 1;
34
+ position: relative;
35
+ min-height: 300px;
36
+ }
37
+
38
+ .eventItem {
39
+ padding: 12px 20px;
40
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
41
+ transition: background 0.2s;
42
+ cursor: pointer;
43
+ font-family: 'Courier New', monospace;
44
+ font-size: 13px;
45
+ position: relative;
46
+ animation: slideIn 0.3s ease;
47
+ }
48
+
49
+ @keyframes slideIn {
50
+ from {
51
+ opacity: 0;
52
+ transform: translateX(-20px);
53
+ }
54
+ to {
55
+ opacity: 1;
56
+ transform: translateX(0);
57
+ }
58
+ }
59
+
60
+ .eventItem:hover {
61
+ background: rgba(255, 255, 255, 0.05);
62
+ }
63
+
64
+ .eventItem.expanded {
65
+ background: rgba(255, 255, 255, 0.08);
66
+ }
67
+
68
+ .eventHeader {
69
+ width: 100%;
70
+ }
71
+
72
+ .eventHeaderRow {
73
+ display: flex;
74
+ gap: 10px;
75
+ align-items: center;
76
+ margin-bottom: 5px;
77
+ }
78
+
79
+ .eventType {
80
+ padding: 3px 8px;
81
+ border-radius: 10px;
82
+ font-size: 11px;
83
+ font-weight: 600;
84
+ text-transform: uppercase;
85
+ }
86
+
87
+ .eventType.agent {
88
+ background: rgba(167, 139, 250, 0.2);
89
+ color: #a78bfa;
90
+ }
91
+
92
+ .eventType.tool {
93
+ background: rgba(96, 165, 250, 0.2);
94
+ color: #60a5fa;
95
+ }
96
+
97
+ .eventType.file {
98
+ background: rgba(251, 191, 36, 0.2);
99
+ color: #fbbf24;
100
+ }
101
+
102
+ .eventType.session {
103
+ background: rgba(74, 222, 128, 0.2);
104
+ color: #4ade80;
105
+ }
106
+
107
+ .eventType.error {
108
+ background: rgba(248, 113, 113, 0.2);
109
+ color: #f87171;
110
+ }
111
+
112
+ .eventType.info {
113
+ background: rgba(134, 239, 172, 0.2);
114
+ color: #86efac;
115
+ }
116
+
117
+ .eventTime {
118
+ font-size: 11px;
119
+ color: rgba(255, 255, 255, 0.5);
120
+ }
121
+
122
+ .sourceIndicator {
123
+ font-size: 10px;
124
+ color: rgba(255, 255, 255, 0.4);
125
+ font-style: italic;
126
+ }
127
+
128
+ .eventPreview {
129
+ color: rgba(255, 255, 255, 0.7);
130
+ white-space: nowrap;
131
+ overflow: hidden;
132
+ text-overflow: ellipsis;
133
+ max-width: 100%;
134
+ }
135
+
136
+ .eventDetails {
137
+ margin-top: 10px;
138
+ padding: 10px;
139
+ background: rgba(0, 0, 0, 0.2);
140
+ border-radius: 6px;
141
+ }
142
+
143
+ .noEvents {
144
+ text-align: center;
145
+ padding: 60px 20px;
146
+ color: rgba(255, 255, 255, 0.5);
147
+ }
148
+
149
+ .noEvents h3 {
150
+ margin-bottom: 10px;
151
+ font-size: 18px;
152
+ }
153
+
154
+ .noEvents p {
155
+ font-size: 14px;
156
+ }
@@ -0,0 +1,38 @@
1
+ .statusBar {
2
+ display: flex;
3
+ gap: 20px;
4
+ align-items: center;
5
+ flex-wrap: wrap;
6
+ }
7
+
8
+ .statusIndicator {
9
+ display: flex;
10
+ align-items: center;
11
+ gap: 8px;
12
+ padding: 8px 16px;
13
+ background: rgba(255, 255, 255, 0.05);
14
+ border-radius: 20px;
15
+ font-size: 14px;
16
+ }
17
+
18
+ .statusDot {
19
+ width: 10px;
20
+ height: 10px;
21
+ border-radius: 50%;
22
+ animation: pulse 2s infinite;
23
+ }
24
+
25
+ .statusDot.connected {
26
+ background: #4ade80;
27
+ box-shadow: 0 0 10px #4ade80;
28
+ }
29
+
30
+ .statusDot.disconnected {
31
+ background: #f87171;
32
+ box-shadow: 0 0 10px #f87171;
33
+ }
34
+
35
+ @keyframes pulse {
36
+ 0%, 100% { opacity: 1; }
37
+ 50% { opacity: 0.5; }
38
+ }
@@ -0,0 +1,92 @@
1
+ .controlsPanel {
2
+ background: rgba(255, 255, 255, 0.05);
3
+ backdrop-filter: blur(10px);
4
+ border: 1px solid rgba(255, 255, 255, 0.1);
5
+ border-radius: 10px;
6
+ padding: 15px;
7
+ margin-bottom: 20px;
8
+ display: flex;
9
+ gap: 15px;
10
+ align-items: center;
11
+ flex-wrap: wrap;
12
+ }
13
+
14
+ .controlGroup {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 10px;
18
+ }
19
+
20
+ .controlLabel {
21
+ font-size: 14px;
22
+ color: #94a3b8;
23
+ }
24
+
25
+ .btn {
26
+ padding: 10px 20px;
27
+ background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
28
+ border: none;
29
+ border-radius: 8px;
30
+ color: white;
31
+ cursor: pointer;
32
+ font-size: 14px;
33
+ transition: transform 0.2s, box-shadow 0.2s;
34
+ }
35
+
36
+ .btn:hover {
37
+ transform: translateY(-2px);
38
+ box-shadow: 0 5px 15px rgba(16, 185, 129, 0.4);
39
+ }
40
+
41
+ .btn.secondary {
42
+ background: rgba(255, 255, 255, 0.1);
43
+ }
44
+
45
+ .btn.danger {
46
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
47
+ }
48
+
49
+ .searchBox {
50
+ flex: 1;
51
+ min-width: 200px;
52
+ padding: 10px 15px;
53
+ background: rgba(255, 255, 255, 0.05);
54
+ border: 1px solid rgba(255, 255, 255, 0.1);
55
+ border-radius: 8px;
56
+ color: white;
57
+ font-size: 14px;
58
+ }
59
+
60
+ .searchBox::placeholder {
61
+ color: rgba(255, 255, 255, 0.5);
62
+ }
63
+
64
+ .filterSelect {
65
+ padding: 10px 15px;
66
+ background: rgba(255, 255, 255, 0.05);
67
+ border: 1px solid rgba(255, 255, 255, 0.1);
68
+ border-radius: 8px;
69
+ color: white;
70
+ font-size: 14px;
71
+ cursor: pointer;
72
+ }
73
+
74
+ .filterSelect option {
75
+ background: #0f172a;
76
+ }
77
+
78
+ .checkboxLabel {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 8px;
82
+ padding: 10px 15px;
83
+ background: rgba(255, 255, 255, 0.05);
84
+ border: 1px solid rgba(255, 255, 255, 0.1);
85
+ border-radius: 8px;
86
+ cursor: pointer;
87
+ font-size: 14px;
88
+ }
89
+
90
+ .checkboxLabel input {
91
+ cursor: pointer;
92
+ }