claude-mpm 3.7.4__py3-none-any.whl → 3.8.1__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 (117) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +0 -106
  3. claude_mpm/agents/INSTRUCTIONS.md +0 -78
  4. claude_mpm/agents/MEMORY.md +88 -0
  5. claude_mpm/agents/WORKFLOW.md +86 -0
  6. claude_mpm/agents/schema/agent_schema.json +1 -1
  7. claude_mpm/agents/templates/code_analyzer.json +26 -11
  8. claude_mpm/agents/templates/data_engineer.json +4 -7
  9. claude_mpm/agents/templates/documentation.json +2 -2
  10. claude_mpm/agents/templates/engineer.json +2 -2
  11. claude_mpm/agents/templates/ops.json +3 -8
  12. claude_mpm/agents/templates/qa.json +2 -3
  13. claude_mpm/agents/templates/research.json +2 -3
  14. claude_mpm/agents/templates/security.json +3 -6
  15. claude_mpm/agents/templates/ticketing.json +4 -9
  16. claude_mpm/agents/templates/version_control.json +3 -3
  17. claude_mpm/agents/templates/web_qa.json +4 -4
  18. claude_mpm/agents/templates/web_ui.json +4 -4
  19. claude_mpm/cli/__init__.py +2 -2
  20. claude_mpm/cli/commands/__init__.py +2 -1
  21. claude_mpm/cli/commands/agents.py +118 -1
  22. claude_mpm/cli/commands/tickets.py +596 -19
  23. claude_mpm/cli/parser.py +228 -5
  24. claude_mpm/config/__init__.py +30 -39
  25. claude_mpm/config/socketio_config.py +8 -5
  26. claude_mpm/constants.py +13 -0
  27. claude_mpm/core/__init__.py +8 -18
  28. claude_mpm/core/cache.py +596 -0
  29. claude_mpm/core/claude_runner.py +166 -622
  30. claude_mpm/core/config.py +5 -1
  31. claude_mpm/core/constants.py +339 -0
  32. claude_mpm/core/container.py +461 -22
  33. claude_mpm/core/exceptions.py +392 -0
  34. claude_mpm/core/framework_loader.py +208 -93
  35. claude_mpm/core/interactive_session.py +432 -0
  36. claude_mpm/core/interfaces.py +424 -0
  37. claude_mpm/core/lazy.py +467 -0
  38. claude_mpm/core/logging_config.py +444 -0
  39. claude_mpm/core/oneshot_session.py +465 -0
  40. claude_mpm/core/optimized_agent_loader.py +485 -0
  41. claude_mpm/core/optimized_startup.py +490 -0
  42. claude_mpm/core/service_registry.py +52 -26
  43. claude_mpm/core/socketio_pool.py +162 -5
  44. claude_mpm/core/types.py +292 -0
  45. claude_mpm/core/typing_utils.py +477 -0
  46. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +46 -2
  47. claude_mpm/dashboard/templates/index.html +5 -5
  48. claude_mpm/hooks/claude_hooks/hook_handler.py +213 -99
  49. claude_mpm/init.py +2 -1
  50. claude_mpm/services/__init__.py +78 -14
  51. claude_mpm/services/agent/__init__.py +24 -0
  52. claude_mpm/services/agent/deployment.py +2548 -0
  53. claude_mpm/services/agent/management.py +598 -0
  54. claude_mpm/services/agent/registry.py +813 -0
  55. claude_mpm/services/agents/deployment/agent_deployment.py +592 -269
  56. claude_mpm/services/agents/deployment/async_agent_deployment.py +5 -1
  57. claude_mpm/services/agents/management/agent_capabilities_generator.py +21 -11
  58. claude_mpm/services/agents/memory/agent_memory_manager.py +156 -1
  59. claude_mpm/services/async_session_logger.py +8 -3
  60. claude_mpm/services/communication/__init__.py +21 -0
  61. claude_mpm/services/communication/socketio.py +1933 -0
  62. claude_mpm/services/communication/websocket.py +479 -0
  63. claude_mpm/services/core/__init__.py +123 -0
  64. claude_mpm/services/core/base.py +247 -0
  65. claude_mpm/services/core/interfaces.py +951 -0
  66. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +23 -23
  67. claude_mpm/services/framework_claude_md_generator.py +3 -2
  68. claude_mpm/services/health_monitor.py +4 -3
  69. claude_mpm/services/hook_service.py +64 -4
  70. claude_mpm/services/infrastructure/__init__.py +21 -0
  71. claude_mpm/services/infrastructure/logging.py +202 -0
  72. claude_mpm/services/infrastructure/monitoring.py +893 -0
  73. claude_mpm/services/memory/indexed_memory.py +648 -0
  74. claude_mpm/services/project/__init__.py +21 -0
  75. claude_mpm/services/project/analyzer.py +864 -0
  76. claude_mpm/services/project/registry.py +608 -0
  77. claude_mpm/services/project_analyzer.py +95 -2
  78. claude_mpm/services/recovery_manager.py +15 -9
  79. claude_mpm/services/socketio/__init__.py +25 -0
  80. claude_mpm/services/socketio/handlers/__init__.py +25 -0
  81. claude_mpm/services/socketio/handlers/base.py +121 -0
  82. claude_mpm/services/socketio/handlers/connection.py +198 -0
  83. claude_mpm/services/socketio/handlers/file.py +213 -0
  84. claude_mpm/services/socketio/handlers/git.py +723 -0
  85. claude_mpm/services/socketio/handlers/memory.py +27 -0
  86. claude_mpm/services/socketio/handlers/project.py +25 -0
  87. claude_mpm/services/socketio/handlers/registry.py +145 -0
  88. claude_mpm/services/socketio_client_manager.py +12 -7
  89. claude_mpm/services/socketio_server.py +156 -30
  90. claude_mpm/services/ticket_manager.py +377 -51
  91. claude_mpm/utils/agent_dependency_loader.py +66 -15
  92. claude_mpm/utils/error_handler.py +1 -1
  93. claude_mpm/utils/robust_installer.py +587 -0
  94. claude_mpm/validation/agent_validator.py +27 -14
  95. claude_mpm/validation/frontmatter_validator.py +231 -0
  96. {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/METADATA +74 -41
  97. {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/RECORD +101 -76
  98. claude_mpm/.claude-mpm/logs/hooks_20250728.log +0 -10
  99. claude_mpm/agents/agent-template.yaml +0 -83
  100. claude_mpm/cli/README.md +0 -108
  101. claude_mpm/cli_module/refactoring_guide.md +0 -253
  102. claude_mpm/config/async_logging_config.yaml +0 -145
  103. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +0 -34
  104. claude_mpm/dashboard/.claude-mpm/memories/README.md +0 -36
  105. claude_mpm/dashboard/README.md +0 -121
  106. claude_mpm/dashboard/static/js/dashboard.js.backup +0 -1973
  107. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +0 -36
  108. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +0 -39
  109. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +0 -38
  110. claude_mpm/hooks/README.md +0 -96
  111. claude_mpm/schemas/agent_schema.json +0 -435
  112. claude_mpm/services/framework_claude_md_generator/README.md +0 -92
  113. claude_mpm/services/version_control/VERSION +0 -1
  114. {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/WHEEL +0 -0
  115. {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/entry_points.txt +0 -0
  116. {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/licenses/LICENSE +0 -0
  117. {claude_mpm-3.7.4.dist-info → claude_mpm-3.8.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,477 @@
1
+ """Type definitions and utilities for Claude MPM.
2
+
3
+ This module provides common type aliases, protocols, and TypedDict definitions
4
+ used throughout the codebase to ensure consistent type safety.
5
+
6
+ WHY: Centralizing type definitions reduces duplication, improves IDE support,
7
+ and makes the codebase more maintainable by providing a single source of truth
8
+ for complex type definitions.
9
+
10
+ DESIGN DECISION: Uses protocols and TypedDict to provide structural typing
11
+ that allows for more flexible and maintainable type checking while maintaining
12
+ strict type safety.
13
+ """
14
+
15
+ from typing import (
16
+ Any, Callable, Dict, List, Optional, Union, TypeVar, Protocol,
17
+ TYPE_CHECKING, Literal, Tuple, Set, Awaitable, Iterator, AsyncIterator
18
+ )
19
+ from typing_extensions import TypedDict, NotRequired, TypeAlias
20
+ from pathlib import Path
21
+ from datetime import datetime
22
+ from enum import Enum
23
+ import logging
24
+
25
+ if TYPE_CHECKING:
26
+ from claude_mpm.core.claude_runner import ClaudeRunner
27
+ from claude_mpm.services.socketio_server import SocketIOClientProxy
28
+
29
+
30
+ # Generic type variables
31
+ T = TypeVar('T')
32
+ TSession = TypeVar('TSession') # Generic session type
33
+ TAgent = TypeVar('TAgent') # Generic agent type
34
+ TService = TypeVar('TService') # Generic service type
35
+
36
+ # Basic type aliases
37
+ PathLike: TypeAlias = Union[str, Path]
38
+ JSONValue: TypeAlias = Union[str, int, float, bool, None, Dict[str, Any], List[Any]]
39
+ JSONDict: TypeAlias = Dict[str, JSONValue]
40
+ Headers: TypeAlias = Dict[str, str]
41
+ ErrorCode: TypeAlias = Union[int, str]
42
+ LogLevel: TypeAlias = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
43
+
44
+ # Session types
45
+ SessionId: TypeAlias = str
46
+ SessionStatus: TypeAlias = Literal["initializing", "running", "stopped", "error", "completed"]
47
+ LaunchMethod: TypeAlias = Literal["exec", "subprocess", "oneshot"]
48
+
49
+
50
+ class SessionConfig(TypedDict):
51
+ """Configuration for a Claude session."""
52
+ session_id: SessionId
53
+ launch_method: LaunchMethod
54
+ working_dir: str
55
+ enable_websocket: NotRequired[bool]
56
+ websocket_port: NotRequired[int]
57
+ enable_tickets: NotRequired[bool]
58
+ claude_args: NotRequired[List[str]]
59
+ context: NotRequired[str]
60
+ system_prompt: NotRequired[str]
61
+
62
+
63
+ class SessionResult(TypedDict):
64
+ """Result from a session execution."""
65
+ success: bool
66
+ session_id: SessionId
67
+ response: NotRequired[str]
68
+ error: NotRequired[str]
69
+ execution_time: NotRequired[float]
70
+ exit_code: NotRequired[int]
71
+ metadata: NotRequired[Dict[str, Any]]
72
+
73
+
74
+ class SessionEvent(TypedDict):
75
+ """Event logged during session execution."""
76
+ event: str
77
+ timestamp: datetime
78
+ session_id: NotRequired[SessionId]
79
+ success: NotRequired[bool]
80
+ error: NotRequired[str]
81
+ exception_type: NotRequired[str]
82
+ metadata: NotRequired[Dict[str, Any]]
83
+
84
+
85
+ # Agent types
86
+ AgentId: TypeAlias = str
87
+ AgentVersion: TypeAlias = str
88
+ AgentTier: TypeAlias = Literal["SYSTEM", "USER", "PROJECT"]
89
+ ModelName: TypeAlias = str
90
+ ResourceTier: TypeAlias = Literal["standard", "premium", "enterprise"]
91
+
92
+
93
+ class AgentCapabilities(TypedDict):
94
+ """Capabilities of an agent."""
95
+ model: ModelName
96
+ tools: NotRequired[List[str]]
97
+ resource_tier: NotRequired[ResourceTier]
98
+ max_tokens: NotRequired[int]
99
+ temperature: NotRequired[float]
100
+ system_prompt: NotRequired[str]
101
+
102
+
103
+ class AgentMetadata(TypedDict):
104
+ """Metadata for an agent."""
105
+ name: str
106
+ description: str
107
+ tags: NotRequired[List[str]]
108
+ author: NotRequired[str]
109
+ created_at: NotRequired[str]
110
+ updated_at: NotRequired[str]
111
+
112
+
113
+ class AgentDefinition(TypedDict):
114
+ """Complete agent definition."""
115
+ agent_id: AgentId
116
+ version: AgentVersion
117
+ metadata: AgentMetadata
118
+ capabilities: AgentCapabilities
119
+ instructions: str
120
+ tier: NotRequired[AgentTier]
121
+ file_path: NotRequired[PathLike]
122
+
123
+
124
+ # WebSocket/SocketIO types
125
+ EventName: TypeAlias = str
126
+ EventData: TypeAlias = Dict[str, Any]
127
+ SocketId: TypeAlias = str
128
+
129
+
130
+ class WebSocketMessage(TypedDict):
131
+ """WebSocket message structure."""
132
+ event: EventName
133
+ data: EventData
134
+ timestamp: NotRequired[datetime]
135
+ session_id: NotRequired[SessionId]
136
+
137
+
138
+ class ClaudeStatus(TypedDict):
139
+ """Claude process status."""
140
+ status: Literal["starting", "running", "stopped", "error"]
141
+ message: str
142
+ timestamp: NotRequired[datetime]
143
+ pid: NotRequired[int]
144
+
145
+
146
+ class DelegationInfo(TypedDict):
147
+ """Agent delegation information."""
148
+ agent: AgentId
149
+ task: str
150
+ status: Literal["detected", "started", "completed", "failed"]
151
+ timestamp: NotRequired[datetime]
152
+ result: NotRequired[str]
153
+
154
+
155
+ # Hook types
156
+ HookName: TypeAlias = str
157
+ HookPriority: TypeAlias = int
158
+ HookResult: TypeAlias = Any
159
+
160
+
161
+ class HookConfig(TypedDict):
162
+ """Hook configuration."""
163
+ name: HookName
164
+ enabled: NotRequired[bool]
165
+ priority: NotRequired[HookPriority]
166
+ config: NotRequired[Dict[str, Any]]
167
+
168
+
169
+ class HookContext(TypedDict):
170
+ """Context passed to hook handlers."""
171
+ hook_name: HookName
172
+ session_id: NotRequired[SessionId]
173
+ agent_id: NotRequired[AgentId]
174
+ data: NotRequired[Dict[str, Any]]
175
+
176
+
177
+ # Service types
178
+ ServiceName: TypeAlias = str
179
+ ServiceStatus: TypeAlias = Literal["idle", "running", "stopped", "error"]
180
+
181
+
182
+ class ServiceConfig(TypedDict):
183
+ """Service configuration."""
184
+ name: ServiceName
185
+ enabled: NotRequired[bool]
186
+ port: NotRequired[int]
187
+ host: NotRequired[str]
188
+ config: NotRequired[Dict[str, Any]]
189
+
190
+
191
+ class ServiceInfo(TypedDict):
192
+ """Service information."""
193
+ name: ServiceName
194
+ status: ServiceStatus
195
+ uptime: NotRequired[float]
196
+ requests_handled: NotRequired[int]
197
+ errors: NotRequired[int]
198
+ last_error: NotRequired[str]
199
+
200
+
201
+ # Memory types
202
+ MemoryType: TypeAlias = Literal[
203
+ "pattern", "architecture", "guideline", "mistake",
204
+ "strategy", "integration", "performance", "context"
205
+ ]
206
+ MemoryId: TypeAlias = str
207
+
208
+
209
+ class Memory(TypedDict):
210
+ """Agent memory entry."""
211
+ id: MemoryId
212
+ type: MemoryType
213
+ content: str
214
+ agent_id: AgentId
215
+ timestamp: datetime
216
+ relevance_score: NotRequired[float]
217
+ usage_count: NotRequired[int]
218
+ tags: NotRequired[List[str]]
219
+
220
+
221
+ class MemorySearchResult(TypedDict):
222
+ """Result from memory search."""
223
+ memory: Memory
224
+ score: float
225
+ matches: NotRequired[List[str]]
226
+
227
+
228
+ # Project and deployment types
229
+ class ProjectConfig(TypedDict):
230
+ """Project-specific configuration."""
231
+ project_name: NotRequired[str]
232
+ agent_deployment: NotRequired[Dict[str, Any]]
233
+ excluded_agents: NotRequired[List[AgentId]]
234
+ included_agents: NotRequired[List[AgentId]]
235
+ custom_agents_path: NotRequired[PathLike]
236
+ memory_enabled: NotRequired[bool]
237
+ websocket_enabled: NotRequired[bool]
238
+
239
+
240
+ class DeploymentResult(TypedDict):
241
+ """Result from agent deployment."""
242
+ deployed: List[AgentId]
243
+ failed: List[Tuple[AgentId, str]]
244
+ skipped: List[AgentId]
245
+ total_time: float
246
+
247
+
248
+ # Response logging types
249
+ class ResponseLogEntry(TypedDict):
250
+ """Entry in response log."""
251
+ timestamp: datetime
252
+ request_summary: str
253
+ response_content: str
254
+ metadata: Dict[str, Any]
255
+ agent: AgentId
256
+ session_id: NotRequired[SessionId]
257
+ execution_time: NotRequired[float]
258
+
259
+
260
+ # Command/CLI types
261
+ CommandName: TypeAlias = str
262
+ CommandArgs: TypeAlias = List[str]
263
+
264
+
265
+ class CommandResult(TypedDict):
266
+ """Result from command execution."""
267
+ success: bool
268
+ output: NotRequired[str]
269
+ error: NotRequired[str]
270
+ exit_code: int
271
+
272
+
273
+ # Protocols for structural typing
274
+
275
+ class SessionProtocol(Protocol):
276
+ """Protocol for session handlers."""
277
+
278
+ def initialize_session(self, prompt: str) -> Tuple[bool, Optional[str]]:
279
+ """Initialize the session."""
280
+ ...
281
+
282
+ def execute_command(self, prompt: str, context: Optional[str],
283
+ infrastructure: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
284
+ """Execute a command."""
285
+ ...
286
+
287
+ def cleanup_session(self) -> None:
288
+ """Clean up the session."""
289
+ ...
290
+
291
+
292
+ class LoggerProtocol(Protocol):
293
+ """Protocol for loggers."""
294
+
295
+ def log_system(self, message: str, level: LogLevel = "INFO",
296
+ component: Optional[str] = None) -> None:
297
+ """Log a system message."""
298
+ ...
299
+
300
+ def log_agent(self, agent: AgentId, message: str,
301
+ level: LogLevel = "INFO") -> None:
302
+ """Log an agent message."""
303
+ ...
304
+
305
+ def get_session_summary(self) -> Dict[str, Any]:
306
+ """Get session summary."""
307
+ ...
308
+
309
+
310
+ class WebSocketServerProtocol(Protocol):
311
+ """Protocol for WebSocket server."""
312
+
313
+ def start(self) -> None:
314
+ """Start the server."""
315
+ ...
316
+
317
+ def session_started(self, session_id: SessionId, launch_method: LaunchMethod,
318
+ working_dir: str) -> None:
319
+ """Notify session start."""
320
+ ...
321
+
322
+ def session_ended(self) -> None:
323
+ """Notify session end."""
324
+ ...
325
+
326
+ def claude_status_changed(self, status: str, message: str) -> None:
327
+ """Update Claude status."""
328
+ ...
329
+
330
+ def claude_output(self, output: str, stream: Literal["stdout", "stderr"]) -> None:
331
+ """Send Claude output."""
332
+ ...
333
+
334
+ def agent_delegated(self, agent: AgentId, task: str, status: str) -> None:
335
+ """Notify agent delegation."""
336
+ ...
337
+
338
+
339
+ class AgentServiceProtocol(Protocol):
340
+ """Protocol for agent service."""
341
+
342
+ def deploy_agents(self, agents: List[AgentDefinition],
343
+ target_dir: PathLike) -> DeploymentResult:
344
+ """Deploy agents to target directory."""
345
+ ...
346
+
347
+ def discover_agents(self, tier: AgentTier) -> List[AgentDefinition]:
348
+ """Discover agents at specified tier."""
349
+ ...
350
+
351
+ def get_agent(self, agent_id: AgentId, tier: Optional[AgentTier] = None) -> Optional[AgentDefinition]:
352
+ """Get specific agent."""
353
+ ...
354
+
355
+
356
+ class MemoryServiceProtocol(Protocol):
357
+ """Protocol for memory service."""
358
+
359
+ def add_memory(self, memory: Memory) -> bool:
360
+ """Add a memory entry."""
361
+ ...
362
+
363
+ def search_memories(self, query: str, agent_id: Optional[AgentId] = None,
364
+ memory_type: Optional[MemoryType] = None,
365
+ limit: int = 10) -> List[MemorySearchResult]:
366
+ """Search memories."""
367
+ ...
368
+
369
+ def get_relevant_memories(self, context: str, agent_id: AgentId,
370
+ limit: int = 5) -> List[Memory]:
371
+ """Get relevant memories for context."""
372
+ ...
373
+
374
+
375
+ # Factory function types
376
+ SessionFactory = Callable[[Any], SessionProtocol]
377
+ ServiceFactory = Callable[[ServiceConfig], Any]
378
+ LoggerFactory = Callable[[str], logging.Logger]
379
+
380
+
381
+ # Validation function types
382
+ Validator = Callable[[Any], bool]
383
+ Transformer = Callable[[T], T]
384
+ ErrorHandler = Callable[[Exception], None]
385
+
386
+
387
+ # Async types for future use
388
+ AsyncSessionResult = Awaitable[SessionResult]
389
+ AsyncCommandResult = Awaitable[CommandResult]
390
+ AsyncDeploymentResult = Awaitable[DeploymentResult]
391
+
392
+
393
+ # Container/Dependency injection types
394
+ class ServiceContainer(Protocol):
395
+ """Protocol for service container."""
396
+
397
+ def register(self, name: str, factory: ServiceFactory) -> None:
398
+ """Register a service."""
399
+ ...
400
+
401
+ def get(self, name: str) -> Any:
402
+ """Get a service instance."""
403
+ ...
404
+
405
+ def has(self, name: str) -> bool:
406
+ """Check if service is registered."""
407
+ ...
408
+
409
+
410
+ # Event system types
411
+ EventHandler = Callable[[EventData], None]
412
+ EventFilter = Callable[[EventData], bool]
413
+
414
+
415
+ class EventSubscription(TypedDict):
416
+ """Event subscription details."""
417
+ event: EventName
418
+ handler: EventHandler
419
+ filter: NotRequired[EventFilter]
420
+ priority: NotRequired[int]
421
+
422
+
423
+ # Testing types (for test files)
424
+ class TestFixture(TypedDict):
425
+ """Test fixture data."""
426
+ name: str
427
+ data: Any
428
+ setup: NotRequired[Callable[[], None]]
429
+ teardown: NotRequired[Callable[[], None]]
430
+
431
+
432
+ # Export commonly used type combinations
433
+ CommonTypes = Union[str, int, float, bool, None, List[Any], Dict[str, Any]]
434
+ ConfigDict = Dict[str, CommonTypes]
435
+ ErrorResult = Tuple[bool, Optional[str]]
436
+ SuccessResult = Tuple[bool, Any]
437
+
438
+
439
+ __all__ = [
440
+ # Basic type aliases
441
+ 'PathLike', 'JSONValue', 'JSONDict', 'Headers', 'ErrorCode', 'LogLevel',
442
+
443
+ # Session types
444
+ 'SessionId', 'SessionStatus', 'LaunchMethod', 'SessionConfig',
445
+ 'SessionResult', 'SessionEvent',
446
+
447
+ # Agent types
448
+ 'AgentId', 'AgentVersion', 'AgentTier', 'ModelName', 'ResourceTier',
449
+ 'AgentCapabilities', 'AgentMetadata', 'AgentDefinition',
450
+
451
+ # WebSocket types
452
+ 'EventName', 'EventData', 'SocketId', 'WebSocketMessage',
453
+ 'ClaudeStatus', 'DelegationInfo',
454
+
455
+ # Hook types
456
+ 'HookName', 'HookPriority', 'HookResult', 'HookConfig', 'HookContext',
457
+
458
+ # Service types
459
+ 'ServiceName', 'ServiceStatus', 'ServiceConfig', 'ServiceInfo',
460
+
461
+ # Memory types
462
+ 'MemoryType', 'MemoryId', 'Memory', 'MemorySearchResult',
463
+
464
+ # Other types
465
+ 'ProjectConfig', 'DeploymentResult', 'ResponseLogEntry',
466
+ 'CommandName', 'CommandArgs', 'CommandResult',
467
+
468
+ # Protocols
469
+ 'SessionProtocol', 'LoggerProtocol', 'WebSocketServerProtocol',
470
+ 'AgentServiceProtocol', 'MemoryServiceProtocol', 'ServiceContainer',
471
+
472
+ # Generic type variables
473
+ 'T', 'TSession', 'TAgent', 'TService',
474
+
475
+ # Common combinations
476
+ 'CommonTypes', 'ConfigDict', 'ErrorResult', 'SuccessResult',
477
+ ]
@@ -328,8 +328,20 @@ class FileToolTracker {
328
328
  */
329
329
  isFileOperation(event) {
330
330
  // File operations are tool events with tools that operate on files
331
- const fileTools = ['Read', 'Write', 'Edit', 'Grep', 'MultiEdit'];
332
- return event.tool_name && fileTools.includes(event.tool_name);
331
+ // Check case-insensitively since tool names can come in different cases
332
+ const fileTools = ['read', 'write', 'edit', 'grep', 'multiedit', 'glob', 'ls', 'bash', 'notebookedit'];
333
+ const toolName = event.tool_name ? event.tool_name.toLowerCase() : '';
334
+
335
+ // Also check if Bash commands involve file operations
336
+ if (toolName === 'bash' && event.tool_parameters) {
337
+ const command = event.tool_parameters.command || '';
338
+ // Check for common file operations in bash commands
339
+ if (command.match(/\b(cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find)\b/)) {
340
+ return true;
341
+ }
342
+ }
343
+
344
+ return toolName && fileTools.includes(toolName);
333
345
  }
334
346
 
335
347
  /**
@@ -341,11 +353,28 @@ class FileToolTracker {
341
353
  // Try various locations where file path might be stored
342
354
  if (event.tool_parameters?.file_path) return event.tool_parameters.file_path;
343
355
  if (event.tool_parameters?.path) return event.tool_parameters.path;
356
+ if (event.tool_parameters?.notebook_path) return event.tool_parameters.notebook_path;
344
357
  if (event.data?.tool_parameters?.file_path) return event.data.tool_parameters.file_path;
345
358
  if (event.data?.tool_parameters?.path) return event.data.tool_parameters.path;
359
+ if (event.data?.tool_parameters?.notebook_path) return event.data.tool_parameters.notebook_path;
346
360
  if (event.file_path) return event.file_path;
347
361
  if (event.path) return event.path;
348
362
 
363
+ // For Glob tool, use the pattern as a pseudo-path
364
+ if (event.tool_name?.toLowerCase() === 'glob' && event.tool_parameters?.pattern) {
365
+ return `[glob] ${event.tool_parameters.pattern}`;
366
+ }
367
+
368
+ // For Bash commands, try to extract file paths from the command
369
+ if (event.tool_name?.toLowerCase() === 'bash' && event.tool_parameters?.command) {
370
+ const command = event.tool_parameters.command;
371
+ // Try to extract file paths from common patterns
372
+ const fileMatch = command.match(/(?:cat|less|more|head|tail|touch|mv|cp|rm|mkdir|ls|find|echo.*>|sed|awk|grep)\s+([^\s;|&]+)/);
373
+ if (fileMatch && fileMatch[1]) {
374
+ return fileMatch[1];
375
+ }
376
+ }
377
+
349
378
  return null;
350
379
  }
351
380
 
@@ -383,7 +412,22 @@ class FileToolTracker {
383
412
  case 'write': return 'write';
384
413
  case 'edit': return 'edit';
385
414
  case 'multiedit': return 'edit';
415
+ case 'notebookedit': return 'edit';
386
416
  case 'grep': return 'search';
417
+ case 'glob': return 'search';
418
+ case 'ls': return 'list';
419
+ case 'bash':
420
+ // Check bash command for file operation type
421
+ const command = event.tool_parameters?.command || '';
422
+ if (command.match(/\b(cat|less|more|head|tail)\b/)) return 'read';
423
+ if (command.match(/\b(touch|echo.*>|tee)\b/)) return 'write';
424
+ if (command.match(/\b(sed|awk)\b/)) return 'edit';
425
+ if (command.match(/\b(grep|find)\b/)) return 'search';
426
+ if (command.match(/\b(ls|dir)\b/)) return 'list';
427
+ if (command.match(/\b(mv|cp)\b/)) return 'copy/move';
428
+ if (command.match(/\b(rm|rmdir)\b/)) return 'delete';
429
+ if (command.match(/\b(mkdir)\b/)) return 'create';
430
+ return 'bash';
387
431
  default: return toolName;
388
432
  }
389
433
  }
@@ -334,11 +334,11 @@
334
334
  <!-- New modular components -->
335
335
  <script src="/static/js/components/socket-manager.js"></script>
336
336
  <script src="/static/js/components/agent-inference.js"></script>
337
- <script src="/static/js/components/ui-state-manager.js"></script>
338
- <script src="/static/js/components/working-directory.js"></script>
339
- <script src="/static/js/components/file-tool-tracker.js"></script>
340
- <script src="/static/js/components/event-processor.js"></script>
341
- <script src="/static/js/components/export-manager.js"></script>
337
+ <script src="/static/js/components/ui-state-manager.js?v=1.0"></script>
338
+ <script src="/static/js/components/working-directory.js?v=1.0"></script>
339
+ <script src="/static/js/components/file-tool-tracker.js?v=1.1"></script>
340
+ <script src="/static/js/components/event-processor.js?v=1.0"></script>
341
+ <script src="/static/js/components/export-manager.js?v=1.0"></script>
342
342
 
343
343
  <!-- Main dashboard coordinator -->
344
344
  <script src="/static/js/dashboard.js"></script>