claude-mpm 4.3.11__py3-none-any.whl → 4.3.13__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/PM_INSTRUCTIONS.md +390 -28
- claude_mpm/agents/templates/data_engineer.json +39 -14
- claude_mpm/agents/templates/research.json +20 -8
- claude_mpm/agents/templates/web_qa.json +25 -10
- claude_mpm/cli/__init__.py +1 -0
- claude_mpm/cli/commands/agent_manager.py +3 -3
- claude_mpm/cli/commands/agents.py +2 -2
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/config.py +2 -2
- claude_mpm/cli/commands/configure.py +5 -5
- claude_mpm/cli/commands/configure_tui.py +7 -7
- claude_mpm/cli/commands/dashboard.py +1 -1
- claude_mpm/cli/commands/debug.py +5 -5
- claude_mpm/cli/commands/mcp.py +1 -1
- claude_mpm/cli/commands/mcp_command_router.py +12 -1
- claude_mpm/cli/commands/mcp_config.py +154 -0
- claude_mpm/cli/commands/mcp_external_commands.py +249 -0
- claude_mpm/cli/commands/mcp_install_commands.py +93 -24
- claude_mpm/cli/commands/mcp_setup_external.py +870 -0
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init_handler.py +1 -1
- claude_mpm/cli/commands/run.py +114 -0
- claude_mpm/cli/commands/search.py +292 -0
- claude_mpm/cli/interactive/agent_wizard.py +2 -2
- claude_mpm/cli/parsers/base_parser.py +13 -0
- claude_mpm/cli/parsers/mcp_parser.py +15 -0
- claude_mpm/cli/parsers/run_parser.py +5 -0
- claude_mpm/cli/parsers/search_parser.py +245 -0
- claude_mpm/cli/startup_logging.py +3 -5
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/constants.py +1 -0
- claude_mpm/core/agent_registry.py +12 -8
- claude_mpm/core/agent_session_manager.py +8 -8
- claude_mpm/core/api_validator.py +4 -4
- claude_mpm/core/base_service.py +10 -10
- claude_mpm/core/cache.py +5 -5
- claude_mpm/core/config_constants.py +1 -1
- claude_mpm/core/container.py +1 -1
- claude_mpm/core/error_handler.py +2 -2
- claude_mpm/core/file_utils.py +1 -1
- claude_mpm/core/framework_loader.py +3 -3
- claude_mpm/core/hook_manager.py +8 -6
- claude_mpm/core/instruction_reinforcement_hook.py +2 -2
- claude_mpm/core/interactive_session.py +1 -1
- claude_mpm/core/lazy.py +3 -3
- claude_mpm/core/log_manager.py +16 -12
- claude_mpm/core/logger.py +16 -11
- claude_mpm/core/logging_config.py +4 -2
- claude_mpm/core/oneshot_session.py +1 -1
- claude_mpm/core/optimized_agent_loader.py +6 -6
- claude_mpm/core/output_style_manager.py +1 -1
- claude_mpm/core/pm_hook_interceptor.py +3 -3
- claude_mpm/core/service_registry.py +1 -1
- claude_mpm/core/session_manager.py +11 -9
- claude_mpm/core/socketio_pool.py +13 -13
- claude_mpm/core/types.py +2 -2
- claude_mpm/core/unified_agent_registry.py +9 -2
- claude_mpm/core/unified_paths.py +1 -1
- claude_mpm/dashboard/analysis_runner.py +4 -4
- claude_mpm/dashboard/api/simple_directory.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +4 -2
- claude_mpm/hooks/base_hook.py +2 -2
- claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
- claude_mpm/hooks/claude_hooks/event_handlers.py +12 -12
- claude_mpm/hooks/claude_hooks/hook_handler.py +4 -4
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +3 -3
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +15 -14
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +4 -4
- claude_mpm/hooks/claude_hooks/installer.py +3 -3
- claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
- claude_mpm/hooks/claude_hooks/response_tracking.py +3 -3
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +5 -5
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +3 -3
- claude_mpm/hooks/claude_hooks/services/state_manager.py +8 -7
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
- claude_mpm/hooks/claude_hooks/tool_analysis.py +2 -2
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- claude_mpm/hooks/tool_call_interceptor.py +2 -2
- claude_mpm/models/agent_session.py +5 -5
- claude_mpm/services/__init__.py +1 -1
- claude_mpm/services/agent_capabilities_service.py +1 -1
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -13
- claude_mpm/services/agents/deployment/agent_discovery_service.py +22 -6
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +7 -5
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +3 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +1 -1
- claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
- claude_mpm/services/agents/deployment/agent_template_builder.py +1 -1
- claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
- claude_mpm/services/agents/deployment/deployment_wrapper.py +2 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +6 -4
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +1 -1
- claude_mpm/services/agents/loading/agent_profile_loader.py +5 -3
- claude_mpm/services/agents/loading/base_agent_manager.py +2 -2
- claude_mpm/services/agents/local_template_manager.py +6 -6
- claude_mpm/services/agents/management/agent_management_service.py +3 -3
- claude_mpm/services/agents/memory/content_manager.py +3 -3
- claude_mpm/services/agents/memory/memory_format_service.py +2 -2
- claude_mpm/services/agents/memory/template_generator.py +3 -3
- claude_mpm/services/agents/registry/__init__.py +1 -1
- claude_mpm/services/agents/registry/modification_tracker.py +2 -2
- claude_mpm/services/async_session_logger.py +3 -3
- claude_mpm/services/claude_session_logger.py +4 -4
- claude_mpm/services/cli/agent_cleanup_service.py +5 -0
- claude_mpm/services/cli/agent_listing_service.py +1 -1
- claude_mpm/services/cli/agent_validation_service.py +1 -0
- claude_mpm/services/cli/memory_crud_service.py +11 -6
- claude_mpm/services/cli/memory_output_formatter.py +1 -1
- claude_mpm/services/cli/session_manager.py +15 -11
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/core/memory_manager.py +81 -23
- claude_mpm/services/core/path_resolver.py +2 -2
- claude_mpm/services/diagnostics/checks/installation_check.py +1 -1
- claude_mpm/services/event_aggregator.py +4 -2
- claude_mpm/services/event_bus/direct_relay.py +5 -3
- claude_mpm/services/event_bus/event_bus.py +3 -3
- claude_mpm/services/event_bus/relay.py +6 -4
- claude_mpm/services/events/consumers/dead_letter.py +5 -3
- claude_mpm/services/events/core.py +3 -3
- claude_mpm/services/events/producers/hook.py +6 -6
- claude_mpm/services/events/producers/system.py +8 -8
- claude_mpm/services/exceptions.py +5 -5
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
- claude_mpm/services/hook_installer_service.py +1 -1
- claude_mpm/services/infrastructure/context_preservation.py +6 -4
- claude_mpm/services/infrastructure/daemon_manager.py +2 -2
- claude_mpm/services/infrastructure/logging.py +2 -2
- claude_mpm/services/mcp_config_manager.py +439 -0
- claude_mpm/services/mcp_gateway/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/auto_configure.py +3 -3
- claude_mpm/services/mcp_gateway/config/config_loader.py +1 -1
- claude_mpm/services/mcp_gateway/config/configuration.py +18 -1
- claude_mpm/services/mcp_gateway/core/base.py +2 -2
- claude_mpm/services/mcp_gateway/main.py +52 -0
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +10 -8
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +1 -1
- claude_mpm/services/mcp_gateway/server/stdio_server.py +4 -3
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +7 -5
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +443 -0
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +5 -5
- claude_mpm/services/mcp_gateway/tools/hello_world.py +9 -9
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +16 -16
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +17 -17
- claude_mpm/services/memory/builder.py +7 -5
- claude_mpm/services/memory/indexed_memory.py +4 -4
- claude_mpm/services/memory/optimizer.py +6 -6
- claude_mpm/services/memory/router.py +3 -3
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/daemon_manager.py +6 -6
- claude_mpm/services/monitor/event_emitter.py +2 -2
- claude_mpm/services/monitor/handlers/file.py +1 -1
- claude_mpm/services/monitor/management/lifecycle.py +1 -1
- claude_mpm/services/monitor/server.py +4 -4
- claude_mpm/services/monitor_build_service.py +2 -2
- claude_mpm/services/port_manager.py +2 -2
- claude_mpm/services/response_tracker.py +2 -2
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/socketio/client_proxy.py +2 -2
- claude_mpm/services/socketio/dashboard_server.py +4 -3
- claude_mpm/services/socketio/event_normalizer.py +12 -8
- claude_mpm/services/socketio/handlers/base.py +2 -2
- claude_mpm/services/socketio/handlers/connection.py +10 -10
- claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
- claude_mpm/services/socketio/handlers/file.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +1 -1
- claude_mpm/services/socketio/handlers/hook.py +16 -15
- claude_mpm/services/socketio/migration_utils.py +1 -1
- claude_mpm/services/socketio/monitor_client.py +5 -5
- claude_mpm/services/socketio/server/broadcaster.py +9 -7
- claude_mpm/services/socketio/server/connection_manager.py +2 -2
- claude_mpm/services/socketio/server/core.py +7 -5
- claude_mpm/services/socketio/server/eventbus_integration.py +18 -11
- claude_mpm/services/socketio/server/main.py +13 -13
- claude_mpm/services/socketio_client_manager.py +4 -4
- claude_mpm/services/system_instructions_service.py +2 -2
- claude_mpm/services/ticket_services/validation_service.py +1 -1
- claude_mpm/services/utility_service.py +5 -2
- claude_mpm/services/version_control/branch_strategy.py +2 -2
- claude_mpm/services/version_control/git_operations.py +22 -20
- claude_mpm/services/version_control/semantic_versioning.py +3 -3
- claude_mpm/services/version_control/version_parser.py +7 -5
- claude_mpm/services/visualization/mermaid_generator.py +1 -1
- claude_mpm/storage/state_storage.py +1 -1
- claude_mpm/tools/code_tree_analyzer.py +19 -18
- claude_mpm/tools/code_tree_builder.py +2 -2
- claude_mpm/tools/code_tree_events.py +10 -8
- claude_mpm/tools/socketio_debug.py +3 -3
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- claude_mpm/utils/dependency_strategies.py +8 -3
- claude_mpm/utils/environment_context.py +2 -2
- claude_mpm/utils/error_handler.py +2 -2
- claude_mpm/utils/file_utils.py +1 -1
- claude_mpm/utils/imports.py +1 -1
- claude_mpm/utils/log_cleanup.py +21 -7
- claude_mpm/validation/agent_validator.py +2 -2
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/METADATA +4 -1
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/RECORD +207 -200
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/WHEEL +0 -0
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.3.11.dist-info → claude_mpm-4.3.13.dist-info}/top_level.txt +0 -0
|
@@ -20,7 +20,7 @@ import asyncio
|
|
|
20
20
|
import os
|
|
21
21
|
import platform
|
|
22
22
|
import sys
|
|
23
|
-
from datetime import datetime
|
|
23
|
+
from datetime import datetime, timezone
|
|
24
24
|
from typing import Any, Dict
|
|
25
25
|
|
|
26
26
|
import psutil
|
|
@@ -86,7 +86,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
86
86
|
Returns:
|
|
87
87
|
Tool execution result with health check results
|
|
88
88
|
"""
|
|
89
|
-
start_time = datetime.now()
|
|
89
|
+
start_time = datetime.now(timezone.utc)
|
|
90
90
|
|
|
91
91
|
try:
|
|
92
92
|
# Get parameters
|
|
@@ -98,7 +98,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
98
98
|
results = await self._perform_health_checks(check_type, detailed, timeout)
|
|
99
99
|
|
|
100
100
|
# Calculate execution time
|
|
101
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
101
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
102
102
|
|
|
103
103
|
# Update metrics
|
|
104
104
|
self._update_metrics(True, execution_time)
|
|
@@ -115,7 +115,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
115
115
|
)
|
|
116
116
|
|
|
117
117
|
except Exception as e:
|
|
118
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
118
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
119
119
|
self._update_metrics(False, execution_time)
|
|
120
120
|
|
|
121
121
|
return MCPToolResult(
|
|
@@ -130,7 +130,7 @@ class HealthCheckTool(BaseToolAdapter):
|
|
|
130
130
|
) -> Dict[str, Any]:
|
|
131
131
|
"""Perform the requested health checks."""
|
|
132
132
|
results = {
|
|
133
|
-
"timestamp": datetime.now().isoformat(),
|
|
133
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
134
134
|
"check_type": check_type,
|
|
135
135
|
"detailed": detailed,
|
|
136
136
|
"overall_status": "unknown",
|
|
@@ -27,7 +27,7 @@ import json
|
|
|
27
27
|
import platform
|
|
28
28
|
import re
|
|
29
29
|
import sys
|
|
30
|
-
from datetime import datetime
|
|
30
|
+
from datetime import datetime, timezone
|
|
31
31
|
from typing import Any, Dict, List, Optional
|
|
32
32
|
|
|
33
33
|
from claude_mpm.services.mcp_gateway.core.interfaces import (
|
|
@@ -204,7 +204,7 @@ class HelloWorldTool(BaseToolAdapter):
|
|
|
204
204
|
self.greeting_history: List[Dict[str, Any]] = []
|
|
205
205
|
self.max_history_size = 100
|
|
206
206
|
|
|
207
|
-
def validate_parameters(self, parameters: Dict[str, Any]) -> bool:
|
|
207
|
+
def validate_parameters(self, parameters: Dict[str, Any]) -> bool: # noqa: PLR0911
|
|
208
208
|
"""
|
|
209
209
|
Enhanced parameter validation with detailed error messages.
|
|
210
210
|
|
|
@@ -305,7 +305,7 @@ class HelloWorldTool(BaseToolAdapter):
|
|
|
305
305
|
Returns:
|
|
306
306
|
Tool execution result with greeting
|
|
307
307
|
"""
|
|
308
|
-
start_time = datetime.now()
|
|
308
|
+
start_time = datetime.now(timezone.utc)
|
|
309
309
|
|
|
310
310
|
try:
|
|
311
311
|
# Validate parameters
|
|
@@ -353,13 +353,13 @@ class HelloWorldTool(BaseToolAdapter):
|
|
|
353
353
|
greeting = " ".join([greeting] * repeat)
|
|
354
354
|
|
|
355
355
|
# Calculate execution time
|
|
356
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
356
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
357
357
|
|
|
358
358
|
# Build response data
|
|
359
359
|
response_data = {
|
|
360
360
|
"greeting": greeting,
|
|
361
361
|
"mode": mode,
|
|
362
|
-
"timestamp": datetime.now().isoformat(),
|
|
362
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
363
363
|
}
|
|
364
364
|
|
|
365
365
|
# Add metadata if requested
|
|
@@ -389,7 +389,7 @@ class HelloWorldTool(BaseToolAdapter):
|
|
|
389
389
|
)
|
|
390
390
|
|
|
391
391
|
except Exception as e:
|
|
392
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
392
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
393
393
|
self._update_metrics(False, execution_time)
|
|
394
394
|
self._metrics["last_error"] = str(e)
|
|
395
395
|
|
|
@@ -409,11 +409,11 @@ class HelloWorldTool(BaseToolAdapter):
|
|
|
409
409
|
|
|
410
410
|
async def _time_based_greeting(self) -> str:
|
|
411
411
|
"""Generate a greeting based on current time."""
|
|
412
|
-
current_hour = datetime.now().hour
|
|
412
|
+
current_hour = datetime.now(timezone.utc).hour
|
|
413
413
|
|
|
414
414
|
for (start, end), greeting in self.TIME_GREETINGS.items():
|
|
415
415
|
if start <= current_hour < end:
|
|
416
|
-
return f"{greeting}! It's {datetime.now().strftime('%I:%M %p')}."
|
|
416
|
+
return f"{greeting}! It's {datetime.now(timezone.utc).strftime('%I:%M %p')}."
|
|
417
417
|
|
|
418
418
|
return "Hello! Time is a curious thing."
|
|
419
419
|
|
|
@@ -482,7 +482,7 @@ class HelloWorldTool(BaseToolAdapter):
|
|
|
482
482
|
execution_time: Time taken to generate greeting
|
|
483
483
|
"""
|
|
484
484
|
entry = {
|
|
485
|
-
"timestamp": datetime.now().isoformat(),
|
|
485
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
486
486
|
"mode": mode,
|
|
487
487
|
"greeting": greeting[:100], # Truncate long greetings
|
|
488
488
|
"execution_time": execution_time,
|
|
@@ -18,7 +18,7 @@ DESIGN DECISIONS:
|
|
|
18
18
|
|
|
19
19
|
import asyncio
|
|
20
20
|
import json
|
|
21
|
-
from datetime import datetime
|
|
21
|
+
from datetime import datetime, timezone
|
|
22
22
|
|
|
23
23
|
from claude_mpm.services.mcp_gateway.core.interfaces import (
|
|
24
24
|
MCPToolDefinition,
|
|
@@ -89,7 +89,7 @@ class TicketCreateTool(BaseToolAdapter):
|
|
|
89
89
|
Returns:
|
|
90
90
|
Tool execution result with created ticket ID
|
|
91
91
|
"""
|
|
92
|
-
start_time = datetime.now()
|
|
92
|
+
start_time = datetime.now(timezone.utc)
|
|
93
93
|
|
|
94
94
|
try:
|
|
95
95
|
params = invocation.parameters
|
|
@@ -120,7 +120,7 @@ class TicketCreateTool(BaseToolAdapter):
|
|
|
120
120
|
|
|
121
121
|
stdout, stderr = await process.communicate()
|
|
122
122
|
|
|
123
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
123
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
124
124
|
|
|
125
125
|
if process.returncode == 0:
|
|
126
126
|
# Parse ticket ID from output
|
|
@@ -160,7 +160,7 @@ class TicketCreateTool(BaseToolAdapter):
|
|
|
160
160
|
)
|
|
161
161
|
|
|
162
162
|
except Exception as e:
|
|
163
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
163
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
164
164
|
self._update_metrics(False, execution_time)
|
|
165
165
|
|
|
166
166
|
return MCPToolResult(
|
|
@@ -232,7 +232,7 @@ class TicketListTool(BaseToolAdapter):
|
|
|
232
232
|
Returns:
|
|
233
233
|
Tool execution result with list of tickets
|
|
234
234
|
"""
|
|
235
|
-
start_time = datetime.now()
|
|
235
|
+
start_time = datetime.now(timezone.utc)
|
|
236
236
|
|
|
237
237
|
try:
|
|
238
238
|
params = invocation.parameters
|
|
@@ -252,7 +252,7 @@ class TicketListTool(BaseToolAdapter):
|
|
|
252
252
|
|
|
253
253
|
stdout, stderr = await process.communicate()
|
|
254
254
|
|
|
255
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
255
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
256
256
|
|
|
257
257
|
if process.returncode == 0:
|
|
258
258
|
try:
|
|
@@ -285,7 +285,7 @@ class TicketListTool(BaseToolAdapter):
|
|
|
285
285
|
)
|
|
286
286
|
|
|
287
287
|
except Exception as e:
|
|
288
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
288
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
289
289
|
self._update_metrics(False, execution_time)
|
|
290
290
|
|
|
291
291
|
return MCPToolResult(
|
|
@@ -352,7 +352,7 @@ class TicketUpdateTool(BaseToolAdapter):
|
|
|
352
352
|
Returns:
|
|
353
353
|
Tool execution result
|
|
354
354
|
"""
|
|
355
|
-
start_time = datetime.now()
|
|
355
|
+
start_time = datetime.now(timezone.utc)
|
|
356
356
|
|
|
357
357
|
try:
|
|
358
358
|
params = invocation.parameters
|
|
@@ -387,7 +387,7 @@ class TicketUpdateTool(BaseToolAdapter):
|
|
|
387
387
|
|
|
388
388
|
stdout, stderr = await process.communicate()
|
|
389
389
|
|
|
390
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
390
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
391
391
|
|
|
392
392
|
if process.returncode == 0:
|
|
393
393
|
self._update_metrics(True, execution_time)
|
|
@@ -414,7 +414,7 @@ class TicketUpdateTool(BaseToolAdapter):
|
|
|
414
414
|
)
|
|
415
415
|
|
|
416
416
|
except Exception as e:
|
|
417
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
417
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
418
418
|
self._update_metrics(False, execution_time)
|
|
419
419
|
|
|
420
420
|
return MCPToolResult(
|
|
@@ -466,7 +466,7 @@ class TicketViewTool(BaseToolAdapter):
|
|
|
466
466
|
Returns:
|
|
467
467
|
Tool execution result with ticket details
|
|
468
468
|
"""
|
|
469
|
-
start_time = datetime.now()
|
|
469
|
+
start_time = datetime.now(timezone.utc)
|
|
470
470
|
|
|
471
471
|
try:
|
|
472
472
|
params = invocation.parameters
|
|
@@ -483,7 +483,7 @@ class TicketViewTool(BaseToolAdapter):
|
|
|
483
483
|
|
|
484
484
|
stdout, stderr = await process.communicate()
|
|
485
485
|
|
|
486
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
486
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
487
487
|
|
|
488
488
|
if process.returncode == 0:
|
|
489
489
|
output = stdout.decode().strip()
|
|
@@ -518,7 +518,7 @@ class TicketViewTool(BaseToolAdapter):
|
|
|
518
518
|
)
|
|
519
519
|
|
|
520
520
|
except Exception as e:
|
|
521
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
521
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
522
522
|
self._update_metrics(False, execution_time)
|
|
523
523
|
|
|
524
524
|
return MCPToolResult(
|
|
@@ -572,7 +572,7 @@ class TicketSearchTool(BaseToolAdapter):
|
|
|
572
572
|
Returns:
|
|
573
573
|
Tool execution result with matching tickets
|
|
574
574
|
"""
|
|
575
|
-
start_time = datetime.now()
|
|
575
|
+
start_time = datetime.now(timezone.utc)
|
|
576
576
|
|
|
577
577
|
try:
|
|
578
578
|
params = invocation.parameters
|
|
@@ -592,7 +592,7 @@ class TicketSearchTool(BaseToolAdapter):
|
|
|
592
592
|
|
|
593
593
|
stdout, stderr = await process.communicate()
|
|
594
594
|
|
|
595
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
595
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
596
596
|
|
|
597
597
|
if process.returncode == 0:
|
|
598
598
|
try:
|
|
@@ -625,7 +625,7 @@ class TicketSearchTool(BaseToolAdapter):
|
|
|
625
625
|
)
|
|
626
626
|
|
|
627
627
|
except Exception as e:
|
|
628
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
628
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
629
629
|
self._update_metrics(False, execution_time)
|
|
630
630
|
|
|
631
631
|
return MCPToolResult(
|
|
@@ -21,7 +21,7 @@ DESIGN DECISIONS:
|
|
|
21
21
|
import asyncio
|
|
22
22
|
import json
|
|
23
23
|
import re
|
|
24
|
-
from datetime import datetime
|
|
24
|
+
from datetime import datetime, timezone
|
|
25
25
|
from typing import Any, Dict, Optional
|
|
26
26
|
|
|
27
27
|
from claude_mpm.services.mcp_gateway.core.interfaces import (
|
|
@@ -192,7 +192,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
192
192
|
|
|
193
193
|
def _validate_parameters(
|
|
194
194
|
self, operation: str, params: Dict[str, Any]
|
|
195
|
-
) -> Optional[str]:
|
|
195
|
+
) -> Optional[str]: # noqa: PLR0911
|
|
196
196
|
"""
|
|
197
197
|
Validate parameters based on the operation type.
|
|
198
198
|
|
|
@@ -242,7 +242,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
242
242
|
Returns:
|
|
243
243
|
Tool execution result with created ticket ID
|
|
244
244
|
"""
|
|
245
|
-
start_time = datetime.now()
|
|
245
|
+
start_time = datetime.now(timezone.utc)
|
|
246
246
|
|
|
247
247
|
try:
|
|
248
248
|
# Build aitrackdown command
|
|
@@ -269,7 +269,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
269
269
|
)
|
|
270
270
|
|
|
271
271
|
stdout, stderr = await process.communicate()
|
|
272
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
272
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
273
273
|
|
|
274
274
|
if process.returncode == 0:
|
|
275
275
|
# Parse ticket ID from output
|
|
@@ -305,7 +305,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
305
305
|
)
|
|
306
306
|
|
|
307
307
|
except Exception as e:
|
|
308
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
308
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
309
309
|
self._update_metrics(False, execution_time)
|
|
310
310
|
|
|
311
311
|
return MCPToolResult(
|
|
@@ -324,7 +324,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
324
324
|
Returns:
|
|
325
325
|
Tool execution result with list of tickets
|
|
326
326
|
"""
|
|
327
|
-
start_time = datetime.now()
|
|
327
|
+
start_time = datetime.now(timezone.utc)
|
|
328
328
|
|
|
329
329
|
try:
|
|
330
330
|
limit = params.get("limit", 10)
|
|
@@ -342,7 +342,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
342
342
|
)
|
|
343
343
|
|
|
344
344
|
stdout, stderr = await process.communicate()
|
|
345
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
345
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
346
346
|
|
|
347
347
|
if process.returncode == 0:
|
|
348
348
|
try:
|
|
@@ -375,7 +375,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
375
375
|
)
|
|
376
376
|
|
|
377
377
|
except Exception as e:
|
|
378
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
378
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
379
379
|
self._update_metrics(False, execution_time)
|
|
380
380
|
|
|
381
381
|
return MCPToolResult(
|
|
@@ -394,7 +394,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
394
394
|
Returns:
|
|
395
395
|
Tool execution result
|
|
396
396
|
"""
|
|
397
|
-
start_time = datetime.now()
|
|
397
|
+
start_time = datetime.now(timezone.utc)
|
|
398
398
|
|
|
399
399
|
try:
|
|
400
400
|
ticket_id = params["ticket_id"]
|
|
@@ -426,7 +426,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
426
426
|
)
|
|
427
427
|
|
|
428
428
|
stdout, stderr = await process.communicate()
|
|
429
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
429
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
430
430
|
|
|
431
431
|
if process.returncode == 0:
|
|
432
432
|
self._update_metrics(True, execution_time)
|
|
@@ -453,7 +453,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
453
453
|
)
|
|
454
454
|
|
|
455
455
|
except Exception as e:
|
|
456
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
456
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
457
457
|
self._update_metrics(False, execution_time)
|
|
458
458
|
|
|
459
459
|
return MCPToolResult(
|
|
@@ -472,7 +472,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
472
472
|
Returns:
|
|
473
473
|
Tool execution result with ticket details
|
|
474
474
|
"""
|
|
475
|
-
start_time = datetime.now()
|
|
475
|
+
start_time = datetime.now(timezone.utc)
|
|
476
476
|
|
|
477
477
|
try:
|
|
478
478
|
ticket_id = params["ticket_id"]
|
|
@@ -487,7 +487,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
487
487
|
)
|
|
488
488
|
|
|
489
489
|
stdout, stderr = await process.communicate()
|
|
490
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
490
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
491
491
|
|
|
492
492
|
if process.returncode == 0:
|
|
493
493
|
output = stdout.decode().strip()
|
|
@@ -522,7 +522,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
522
522
|
)
|
|
523
523
|
|
|
524
524
|
except Exception as e:
|
|
525
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
525
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
526
526
|
self._update_metrics(False, execution_time)
|
|
527
527
|
|
|
528
528
|
return MCPToolResult(
|
|
@@ -541,7 +541,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
541
541
|
Returns:
|
|
542
542
|
Tool execution result with matching tickets
|
|
543
543
|
"""
|
|
544
|
-
start_time = datetime.now()
|
|
544
|
+
start_time = datetime.now(timezone.utc)
|
|
545
545
|
|
|
546
546
|
try:
|
|
547
547
|
query = params["query"]
|
|
@@ -559,7 +559,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
559
559
|
)
|
|
560
560
|
|
|
561
561
|
stdout, stderr = await process.communicate()
|
|
562
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
562
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
563
563
|
|
|
564
564
|
if process.returncode == 0:
|
|
565
565
|
try:
|
|
@@ -588,7 +588,7 @@ class UnifiedTicketTool(BaseToolAdapter):
|
|
|
588
588
|
)
|
|
589
589
|
|
|
590
590
|
except Exception as e:
|
|
591
|
-
execution_time = (datetime.now() - start_time).total_seconds()
|
|
591
|
+
execution_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
592
592
|
self._update_metrics(False, execution_time)
|
|
593
593
|
|
|
594
594
|
return MCPToolResult(
|
|
@@ -24,7 +24,7 @@ while preserving essential information.
|
|
|
24
24
|
|
|
25
25
|
import os
|
|
26
26
|
import re
|
|
27
|
-
from datetime import datetime
|
|
27
|
+
from datetime import datetime, timezone
|
|
28
28
|
from pathlib import Path
|
|
29
29
|
from typing import Any, Dict, List, Optional
|
|
30
30
|
|
|
@@ -234,7 +234,7 @@ class MemoryBuilder(LoggerMixin):
|
|
|
234
234
|
try:
|
|
235
235
|
results = {
|
|
236
236
|
"success": True,
|
|
237
|
-
"timestamp": datetime.now().isoformat(),
|
|
237
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
238
238
|
"files_processed": 0,
|
|
239
239
|
"memories_created": 0,
|
|
240
240
|
"memories_updated": 0,
|
|
@@ -293,7 +293,7 @@ class MemoryBuilder(LoggerMixin):
|
|
|
293
293
|
return {
|
|
294
294
|
"success": False,
|
|
295
295
|
"error": str(e),
|
|
296
|
-
"timestamp": datetime.now().isoformat(),
|
|
296
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
def extract_from_text(self, text: str, source: str) -> List[Dict[str, Any]]:
|
|
@@ -777,7 +777,9 @@ class MemoryBuilder(LoggerMixin):
|
|
|
777
777
|
return True
|
|
778
778
|
|
|
779
779
|
last_processed_time = datetime.fromisoformat(last_processed[file_key])
|
|
780
|
-
file_modified_time = datetime.fromtimestamp(
|
|
780
|
+
file_modified_time = datetime.fromtimestamp(
|
|
781
|
+
file_path.stat().st_mtime, tz=timezone.utc
|
|
782
|
+
)
|
|
781
783
|
|
|
782
784
|
return file_modified_time > last_processed_time
|
|
783
785
|
|
|
@@ -805,7 +807,7 @@ class MemoryBuilder(LoggerMixin):
|
|
|
805
807
|
|
|
806
808
|
# Update timestamp
|
|
807
809
|
file_key = str(file_path.relative_to(self.project_root))
|
|
808
|
-
last_processed[file_key] = datetime.now().isoformat()
|
|
810
|
+
last_processed[file_key] = datetime.now(timezone.utc).isoformat()
|
|
809
811
|
|
|
810
812
|
# Save back
|
|
811
813
|
import json
|
|
@@ -23,7 +23,7 @@ import re
|
|
|
23
23
|
import time
|
|
24
24
|
from collections import Counter, defaultdict
|
|
25
25
|
from dataclasses import dataclass, field
|
|
26
|
-
from datetime import datetime, timedelta
|
|
26
|
+
from datetime import datetime, timedelta, timezone
|
|
27
27
|
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
28
28
|
|
|
29
29
|
from ...core.cache import get_file_cache
|
|
@@ -388,7 +388,7 @@ class IndexedMemoryService:
|
|
|
388
388
|
agent_id=agent_id,
|
|
389
389
|
content=content,
|
|
390
390
|
category=category,
|
|
391
|
-
timestamp=datetime.now(),
|
|
391
|
+
timestamp=datetime.now(timezone.utc),
|
|
392
392
|
tags=tags or [],
|
|
393
393
|
metadata=metadata or {},
|
|
394
394
|
)
|
|
@@ -510,7 +510,7 @@ class IndexedMemoryService:
|
|
|
510
510
|
start_time = time.time()
|
|
511
511
|
|
|
512
512
|
# Calculate time range
|
|
513
|
-
now = datetime.now()
|
|
513
|
+
now = datetime.now(timezone.utc)
|
|
514
514
|
if hours:
|
|
515
515
|
min_time = now - timedelta(hours=hours)
|
|
516
516
|
elif days:
|
|
@@ -563,7 +563,7 @@ class IndexedMemoryService:
|
|
|
563
563
|
|
|
564
564
|
def _generate_id(self, agent_id: str, content: str) -> str:
|
|
565
565
|
"""Generate unique ID for memory entry."""
|
|
566
|
-
timestamp = datetime.now().isoformat()
|
|
566
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
|
567
567
|
hash_input = f"{agent_id}:{content[:100]}:{timestamp}"
|
|
568
568
|
return hashlib.md5(hash_input.encode()).hexdigest()[:12]
|
|
569
569
|
|
|
@@ -24,7 +24,7 @@ information than lose important insights.
|
|
|
24
24
|
|
|
25
25
|
import os
|
|
26
26
|
import re
|
|
27
|
-
from datetime import datetime
|
|
27
|
+
from datetime import datetime, timezone
|
|
28
28
|
from difflib import SequenceMatcher
|
|
29
29
|
from pathlib import Path
|
|
30
30
|
from typing import Any, Dict, List, Optional, Tuple
|
|
@@ -164,7 +164,7 @@ class MemoryOptimizer(LoggerMixin):
|
|
|
164
164
|
else 0
|
|
165
165
|
),
|
|
166
166
|
"backup_created": str(backup_path),
|
|
167
|
-
"timestamp": datetime.now().isoformat(),
|
|
167
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
168
168
|
**optimization_stats,
|
|
169
169
|
}
|
|
170
170
|
|
|
@@ -230,7 +230,7 @@ class MemoryOptimizer(LoggerMixin):
|
|
|
230
230
|
|
|
231
231
|
return {
|
|
232
232
|
"success": True,
|
|
233
|
-
"timestamp": datetime.now().isoformat(),
|
|
233
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
234
234
|
"agents": results,
|
|
235
235
|
"summary": {
|
|
236
236
|
**total_stats,
|
|
@@ -545,7 +545,7 @@ class MemoryOptimizer(LoggerMixin):
|
|
|
545
545
|
|
|
546
546
|
# Update timestamp
|
|
547
547
|
content = "\n".join(content_lines)
|
|
548
|
-
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
548
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
|
|
549
549
|
return re.sub(
|
|
550
550
|
r"<!-- Last Updated: .+ \| Auto-updated by: .+ -->",
|
|
551
551
|
f"<!-- Last Updated: {timestamp} | Auto-updated by: optimizer -->",
|
|
@@ -561,7 +561,7 @@ class MemoryOptimizer(LoggerMixin):
|
|
|
561
561
|
Returns:
|
|
562
562
|
Path to backup file
|
|
563
563
|
"""
|
|
564
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
564
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
|
|
565
565
|
backup_name = f"{memory_file.stem}_backup_{timestamp}{memory_file.suffix}"
|
|
566
566
|
backup_path = memory_file.parent / backup_name
|
|
567
567
|
|
|
@@ -647,7 +647,7 @@ class MemoryOptimizer(LoggerMixin):
|
|
|
647
647
|
|
|
648
648
|
return {
|
|
649
649
|
"success": True,
|
|
650
|
-
"timestamp": datetime.now().isoformat(),
|
|
650
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
651
651
|
"agents_analyzed": len(agents_analysis),
|
|
652
652
|
"agents": agents_analysis,
|
|
653
653
|
}
|
|
@@ -21,7 +21,7 @@ users understand why content was assigned to specific agents.
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
import re
|
|
24
|
-
from datetime import datetime
|
|
24
|
+
from datetime import datetime, timezone
|
|
25
25
|
from typing import Any, Dict, List, Optional, Tuple
|
|
26
26
|
|
|
27
27
|
from claude_mpm.core.config import Config
|
|
@@ -622,7 +622,7 @@ class MemoryRouter(LoggerMixin):
|
|
|
622
622
|
"confidence": confidence,
|
|
623
623
|
"reasoning": reasoning,
|
|
624
624
|
"agent_scores": agent_scores,
|
|
625
|
-
"timestamp": datetime.now().isoformat(),
|
|
625
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
626
626
|
"content_length": len(content),
|
|
627
627
|
}
|
|
628
628
|
|
|
@@ -639,7 +639,7 @@ class MemoryRouter(LoggerMixin):
|
|
|
639
639
|
"confidence": 0.1,
|
|
640
640
|
"reasoning": f"Error during analysis, defaulting to {self.DEFAULT_AGENT}",
|
|
641
641
|
"error": str(e),
|
|
642
|
-
"timestamp": datetime.now().isoformat(),
|
|
642
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
643
643
|
"content_length": len(content) if content else 0,
|
|
644
644
|
}
|
|
645
645
|
|
|
@@ -121,7 +121,7 @@ class UnifiedMonitorDaemon:
|
|
|
121
121
|
"""
|
|
122
122
|
return self.daemon_manager.cleanup_port_conflicts()
|
|
123
123
|
|
|
124
|
-
def _start_daemon(self, force_restart: bool = False) -> bool:
|
|
124
|
+
def _start_daemon(self, force_restart: bool = False) -> bool: # noqa: PLR0911
|
|
125
125
|
"""Start as background daemon process.
|
|
126
126
|
|
|
127
127
|
Args:
|
|
@@ -163,7 +163,7 @@ class DaemonManager:
|
|
|
163
163
|
test_sock.bind(("::1", self.port))
|
|
164
164
|
test_sock.close()
|
|
165
165
|
return True
|
|
166
|
-
except:
|
|
166
|
+
except Exception:
|
|
167
167
|
# Both IPv4 and IPv6 failed - port is in use
|
|
168
168
|
return False
|
|
169
169
|
|
|
@@ -434,10 +434,10 @@ class DaemonManager:
|
|
|
434
434
|
# It's likely our service, try to find PID
|
|
435
435
|
pid = self._find_service_pid()
|
|
436
436
|
return True, pid
|
|
437
|
-
except:
|
|
437
|
+
except Exception:
|
|
438
438
|
pass
|
|
439
439
|
|
|
440
|
-
except:
|
|
440
|
+
except Exception:
|
|
441
441
|
pass
|
|
442
442
|
|
|
443
443
|
return False, None
|
|
@@ -465,7 +465,7 @@ class DaemonManager:
|
|
|
465
465
|
if pids:
|
|
466
466
|
return int(pids[0].strip())
|
|
467
467
|
|
|
468
|
-
except:
|
|
468
|
+
except Exception:
|
|
469
469
|
pass
|
|
470
470
|
|
|
471
471
|
return None
|
|
@@ -615,7 +615,7 @@ class DaemonManager:
|
|
|
615
615
|
f"Monitor daemon successfully started on port {self.port}"
|
|
616
616
|
)
|
|
617
617
|
return True
|
|
618
|
-
except:
|
|
618
|
+
except Exception:
|
|
619
619
|
pass # PID file not ready yet
|
|
620
620
|
|
|
621
621
|
time.sleep(0.5)
|
|
@@ -958,5 +958,5 @@ class DaemonManager:
|
|
|
958
958
|
with open("/tmp/daemon_debug_error.txt", "a") as debug:
|
|
959
959
|
debug.write(f"Error reporting error: {e}\n")
|
|
960
960
|
debug.write(f"Status file: {self.startup_status_file}\n")
|
|
961
|
-
except:
|
|
961
|
+
except Exception:
|
|
962
962
|
pass
|
|
@@ -10,7 +10,7 @@ WHY: Eliminates HTTP overhead for in-process events while maintaining external A
|
|
|
10
10
|
|
|
11
11
|
import asyncio
|
|
12
12
|
import weakref
|
|
13
|
-
from datetime import datetime
|
|
13
|
+
from datetime import datetime, timezone
|
|
14
14
|
from typing import Any, Dict, Optional, Set
|
|
15
15
|
|
|
16
16
|
import aiohttp
|
|
@@ -203,7 +203,7 @@ class AsyncEventEmitter:
|
|
|
203
203
|
"namespace": namespace,
|
|
204
204
|
"event": event,
|
|
205
205
|
"data": data,
|
|
206
|
-
"timestamp": datetime.now().isoformat(),
|
|
206
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
207
207
|
"source": "async_emitter",
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -109,7 +109,7 @@ class FileHandler:
|
|
|
109
109
|
file_path: str,
|
|
110
110
|
working_dir: Optional[str] = None,
|
|
111
111
|
max_size: int = 1024 * 1024,
|
|
112
|
-
) -> Dict[str, Any]:
|
|
112
|
+
) -> Dict[str, Any]: # noqa: PLR0911
|
|
113
113
|
"""Safely read file content with security checks.
|
|
114
114
|
|
|
115
115
|
WHY: File reading must be secure to prevent directory traversal attacks
|
|
@@ -514,7 +514,7 @@ class DaemonLifecycle:
|
|
|
514
514
|
error_msg = f"Port {self.port} is already in use or cannot be bound: {e}"
|
|
515
515
|
return False, error_msg
|
|
516
516
|
|
|
517
|
-
def is_our_service(self, host: str = "localhost") -> Tuple[bool, Optional[int]]:
|
|
517
|
+
def is_our_service(self, host: str = "localhost") -> Tuple[bool, Optional[int]]: # noqa: PLR0911
|
|
518
518
|
"""Check if the service on the port is our Socket.IO service.
|
|
519
519
|
|
|
520
520
|
This uses multiple detection methods:
|