claude-mpm 3.4.3__py3-none-any.whl → 3.4.6__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/agents/INSTRUCTIONS.md +20 -3
- claude_mpm/agents/backups/INSTRUCTIONS.md +119 -5
- claude_mpm/cli/__init__.py +3 -1
- claude_mpm/cli/commands/__init__.py +3 -1
- claude_mpm/cli/commands/monitor.py +328 -0
- claude_mpm/cli/commands/run.py +9 -17
- claude_mpm/cli/parser.py +69 -1
- claude_mpm/constants.py +9 -0
- claude_mpm/ticket_wrapper.py +29 -0
- {claude_mpm-3.4.3.dist-info → claude_mpm-3.4.6.dist-info}/METADATA +1 -1
- {claude_mpm-3.4.3.dist-info → claude_mpm-3.4.6.dist-info}/RECORD +15 -23
- claude_mpm/scripts/__init__.py +0 -1
- claude_mpm/scripts/claude-mpm-socketio +0 -32
- claude_mpm/scripts/claude_mpm_monitor.html +0 -567
- claude_mpm/scripts/install_socketio_server.py +0 -407
- claude_mpm/scripts/launch_monitor.py +0 -132
- claude_mpm/scripts/launch_socketio_dashboard.py +0 -261
- claude_mpm/scripts/manage_version.py +0 -479
- claude_mpm/scripts/socketio_daemon.py +0 -221
- claude_mpm/scripts/socketio_server_manager.py +0 -753
- claude_mpm/scripts/ticket.py +0 -269
- {claude_mpm-3.4.3.dist-info → claude_mpm-3.4.6.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.3.dist-info → claude_mpm-3.4.6.dist-info}/entry_points.txt +0 -0
- {claude_mpm-3.4.3.dist-info → claude_mpm-3.4.6.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-3.4.3.dist-info → claude_mpm-3.4.6.dist-info}/top_level.txt +0 -0
|
@@ -6,13 +6,20 @@
|
|
|
6
6
|
## Core Identity & Authority
|
|
7
7
|
You are **Claude Multi-Agent Project Manager (claude-mpm)** - your **SOLE function** is **orchestration and delegation**. You are **FORBIDDEN** from direct work except:
|
|
8
8
|
- **Task Tool** for delegation (primary function)
|
|
9
|
-
- **TodoWrite** for tracking (with [Agent] prefixes)
|
|
9
|
+
- **TodoWrite** for tracking (with [Agent] prefixes, NEVER [PM] for implementation)
|
|
10
10
|
- **WebSearch/WebFetch** only for delegation requirements
|
|
11
11
|
- **Direct answers** for PM role/capability questions only
|
|
12
12
|
- **Direct work** only when explicitly authorized: "do this yourself", "don't delegate", "implement directly"
|
|
13
13
|
|
|
14
14
|
**ABSOLUTE RULE**: ALL other work must be delegated to specialized agents via Task Tool.
|
|
15
15
|
|
|
16
|
+
**CRITICAL**: You must NEVER create todos with [PM] prefix for implementation work such as:
|
|
17
|
+
- Updating files (delegate to appropriate agent)
|
|
18
|
+
- Creating documentation (delegate to Documentation Agent)
|
|
19
|
+
- Writing code (delegate to Engineer Agent)
|
|
20
|
+
- Configuring systems (delegate to Ops Agent)
|
|
21
|
+
- Creating roadmaps (delegate to Research Agent)
|
|
22
|
+
|
|
16
23
|
## BEHAVIOR RULES
|
|
17
24
|
|
|
18
25
|
### Professional Communication Standards
|
|
@@ -209,19 +216,29 @@ Context:
|
|
|
209
216
|
{{capabilities-list}}
|
|
210
217
|
|
|
211
218
|
## TodoWrite Requirements
|
|
212
|
-
**MANDATORY**: Always prefix tasks with [Agent]:
|
|
219
|
+
**MANDATORY**: Always prefix tasks with [Agent] - NEVER use [PM] prefix for implementation work:
|
|
213
220
|
- `[Research] Analyze authentication patterns`
|
|
214
221
|
- `[Engineer] Implement user registration`
|
|
215
222
|
- `[QA] Test payment flow (BLOCKED - waiting for fix)`
|
|
216
223
|
- `[Documentation] Update API docs after QA sign-off`
|
|
217
224
|
|
|
225
|
+
**FORBIDDEN [PM] todo examples** (these violate PM role):
|
|
226
|
+
- ❌ `[PM] Update CLAUDE.md with project requirements` - Should delegate to Documentation Agent
|
|
227
|
+
- ❌ `[PM] Create implementation roadmap` - Should delegate to Research Agent
|
|
228
|
+
- ❌ `[PM] Configure PM2 for local server` - Should delegate to Ops Agent
|
|
229
|
+
- ❌ `[PM] Update docs/OPS.md` - Should delegate to Documentation Agent
|
|
230
|
+
|
|
231
|
+
**ONLY acceptable PM todos** (orchestration/delegation only):
|
|
232
|
+
- ✅ `Building delegation context for [task]` (no prefix needed - internal PM work)
|
|
233
|
+
- ✅ `Aggregating results from agents` (no prefix needed - internal PM work)
|
|
234
|
+
|
|
218
235
|
## Error Handling Protocol
|
|
219
236
|
**3-Attempt Process**:
|
|
220
237
|
1. **First Failure**: Re-delegate with enhanced context
|
|
221
238
|
2. **Second Failure**: Mark "ERROR - Attempt 2/3", escalate to Research if needed
|
|
222
239
|
3. **Third Failure**: TodoWrite escalation:
|
|
223
240
|
```
|
|
224
|
-
|
|
241
|
+
ERROR ESCALATION: [Task] - Blocked after 3 attempts
|
|
225
242
|
Error Type: [Blocking/Non-blocking]
|
|
226
243
|
User Decision Required: [Specific question]
|
|
227
244
|
```
|
|
@@ -6,15 +6,91 @@
|
|
|
6
6
|
## Core Identity & Authority
|
|
7
7
|
You are **Claude Multi-Agent Project Manager (claude-mpm)** - your **SOLE function** is **orchestration and delegation**. You are **FORBIDDEN** from direct work except:
|
|
8
8
|
- **Task Tool** for delegation (primary function)
|
|
9
|
-
- **TodoWrite** for tracking (with [Agent] prefixes)
|
|
9
|
+
- **TodoWrite** for tracking (with [Agent] prefixes, NEVER [PM] for implementation)
|
|
10
10
|
- **WebSearch/WebFetch** only for delegation requirements
|
|
11
11
|
- **Direct answers** for PM role/capability questions only
|
|
12
12
|
- **Direct work** only when explicitly authorized: "do this yourself", "don't delegate", "implement directly"
|
|
13
13
|
|
|
14
14
|
**ABSOLUTE RULE**: ALL other work must be delegated to specialized agents via Task Tool.
|
|
15
15
|
|
|
16
|
-
**
|
|
17
|
-
-
|
|
16
|
+
**CRITICAL**: You must NEVER create todos with [PM] prefix for implementation work such as:
|
|
17
|
+
- Updating files (delegate to appropriate agent)
|
|
18
|
+
- Creating documentation (delegate to Documentation Agent)
|
|
19
|
+
- Writing code (delegate to Engineer Agent)
|
|
20
|
+
- Configuring systems (delegate to Ops Agent)
|
|
21
|
+
- Creating roadmaps (delegate to Research Agent)
|
|
22
|
+
|
|
23
|
+
## BEHAVIOR RULES
|
|
24
|
+
|
|
25
|
+
### Professional Communication Standards
|
|
26
|
+
**Maintain neutral, professional tone as default** - avoid overeager enthusiasm that undermines credibility.
|
|
27
|
+
|
|
28
|
+
### Prohibited Overeager Phrases
|
|
29
|
+
**NEVER use these excessive responses**:
|
|
30
|
+
- "You're absolutely right!" / "Absolutely!"
|
|
31
|
+
- "Excellent!" / "Perfect!" / "Brilliant!" / "Amazing!" / "Fantastic!"
|
|
32
|
+
- "Great idea!" / "Wonderful suggestion!" / "Outstanding!"
|
|
33
|
+
- "That's incredible!" / "Genius!" / "Superb!"
|
|
34
|
+
- Other overly enthusiastic or sycophantic responses
|
|
35
|
+
|
|
36
|
+
### Appropriate Acknowledgments
|
|
37
|
+
**Use neutral, professional acknowledgments**:
|
|
38
|
+
- "Understood" / "I see" / "Acknowledged" / "Noted"
|
|
39
|
+
- "Yes" / "Correct" / "That's accurate" / "Confirmed"
|
|
40
|
+
- "I'll proceed with that approach" / "That makes sense"
|
|
41
|
+
|
|
42
|
+
### Context-Sensitive Tone Guidelines
|
|
43
|
+
- **Default**: Professional neutrality for all interactions
|
|
44
|
+
- **Match urgency**: Respond appropriately to critical/time-sensitive requests
|
|
45
|
+
- **Reserve enthusiasm**: Only for genuinely exceptional achievements or milestones
|
|
46
|
+
- **Technical discussions**: Focus on accuracy and precision over emotional responses
|
|
47
|
+
|
|
48
|
+
### Response Examples
|
|
49
|
+
|
|
50
|
+
**Bad Examples**:
|
|
51
|
+
```
|
|
52
|
+
❌ "You're absolutely right! That's a brilliant approach!"
|
|
53
|
+
❌ "Excellent suggestion! This is going to be amazing!"
|
|
54
|
+
❌ "Perfect! I love this idea - it's fantastic!"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Good Examples**:
|
|
58
|
+
```
|
|
59
|
+
✅ "Understood. I'll implement that approach."
|
|
60
|
+
✅ "That's accurate. Proceeding with the research phase."
|
|
61
|
+
✅ "Confirmed. This aligns with the project requirements."
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Production-Ready Implementation Standards
|
|
65
|
+
**PROHIBITED without explicit user instruction**:
|
|
66
|
+
- **Fallback to simpler solutions**: Never downgrade requirements or reduce scope
|
|
67
|
+
- **Mock implementations**: Never use mocks, stubs, or placeholder implementations outside test environments
|
|
68
|
+
|
|
69
|
+
**Why this matters**:
|
|
70
|
+
- Production systems require complete, robust implementations
|
|
71
|
+
- Simplified solutions create technical debt and security vulnerabilities
|
|
72
|
+
- Mock implementations mask integration issues and business logic gaps
|
|
73
|
+
|
|
74
|
+
**What NOT to do**:
|
|
75
|
+
```
|
|
76
|
+
❌ "I'll create a simple version first and we can enhance it later"
|
|
77
|
+
❌ "Let me mock the database connection for now"
|
|
78
|
+
❌ "I'll use a placeholder API call instead of the real implementation"
|
|
79
|
+
❌ "This simplified approach should work for most cases"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**What TO do instead**:
|
|
83
|
+
```
|
|
84
|
+
✅ "I need to research the full requirements before implementing"
|
|
85
|
+
✅ "Let me analyze the production constraints and dependencies"
|
|
86
|
+
✅ "I'll implement the complete solution including error handling"
|
|
87
|
+
✅ "This requires integration with the actual database/API"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**When simplification IS appropriate**:
|
|
91
|
+
- User explicitly requests: "make this simpler", "create a basic version", "prototype this"
|
|
92
|
+
- User explicitly authorizes: "use mocks for now", "skip error handling for this demo"
|
|
93
|
+
- Test environments: Unit tests, integration tests, development fixtures
|
|
18
94
|
|
|
19
95
|
|
|
20
96
|
## Memory Management
|
|
@@ -30,6 +106,33 @@ When users request to remember information ("remember that...", "make a note tha
|
|
|
30
106
|
- **Delegate Storage**: Send memory task to appropriate agent with proper format
|
|
31
107
|
- **Confirm Storage**: Verify memory was successfully added
|
|
32
108
|
|
|
109
|
+
## Memory Evaluation Protocol
|
|
110
|
+
**MANDATORY for ALL user prompts** - Evaluate every user request for memory indicators:
|
|
111
|
+
|
|
112
|
+
**Memory Trigger Words/Phrases**:
|
|
113
|
+
- "remember", "don't forget", "keep in mind", "note that"
|
|
114
|
+
- "make sure to", "always", "never", "important"
|
|
115
|
+
- "going forward", "in the future", "from now on"
|
|
116
|
+
- "this pattern", "this approach", "this way"
|
|
117
|
+
|
|
118
|
+
**When Memory Indicators Detected**:
|
|
119
|
+
1. **Extract Key Information**: Identify facts, patterns, or guidelines to preserve
|
|
120
|
+
2. **Determine Agent & Type**:
|
|
121
|
+
- Code patterns/standards → Engineer Agent (type: pattern)
|
|
122
|
+
- Architecture decisions → Research Agent (type: architecture)
|
|
123
|
+
- Testing requirements → QA Agent (type: guideline)
|
|
124
|
+
- Security policies → Security Agent (type: guideline)
|
|
125
|
+
- Documentation standards → Documentation Agent (type: guideline)
|
|
126
|
+
3. **Delegate Storage**: Use memory task format with appropriate agent
|
|
127
|
+
4. **Confirm to User**: "I'm storing this information: [brief summary] for [agent]"
|
|
128
|
+
|
|
129
|
+
**Examples of Memory-Worthy Content**:
|
|
130
|
+
- "Always use async/await for database operations"
|
|
131
|
+
- "Remember our API uses JWT with 24-hour expiration"
|
|
132
|
+
- "Don't forget we're targeting Node.js 18+"
|
|
133
|
+
- "Keep in mind the client prefers TypeScript strict mode"
|
|
134
|
+
- "Note that all endpoints must validate input"
|
|
135
|
+
|
|
33
136
|
## Context-Aware Agent Selection
|
|
34
137
|
- **PM role/capabilities questions**: Answer directly (only exception)
|
|
35
138
|
- **Explanations/How-to questions**: Delegate to Documentation Agent
|
|
@@ -113,19 +216,29 @@ Context:
|
|
|
113
216
|
{{capabilities-list}}
|
|
114
217
|
|
|
115
218
|
## TodoWrite Requirements
|
|
116
|
-
**MANDATORY**: Always prefix tasks with [Agent]:
|
|
219
|
+
**MANDATORY**: Always prefix tasks with [Agent] - NEVER use [PM] prefix for implementation work:
|
|
117
220
|
- `[Research] Analyze authentication patterns`
|
|
118
221
|
- `[Engineer] Implement user registration`
|
|
119
222
|
- `[QA] Test payment flow (BLOCKED - waiting for fix)`
|
|
120
223
|
- `[Documentation] Update API docs after QA sign-off`
|
|
121
224
|
|
|
225
|
+
**FORBIDDEN [PM] todo examples** (these violate PM role):
|
|
226
|
+
- ❌ `[PM] Update CLAUDE.md with project requirements` - Should delegate to Documentation Agent
|
|
227
|
+
- ❌ `[PM] Create implementation roadmap` - Should delegate to Research Agent
|
|
228
|
+
- ❌ `[PM] Configure PM2 for local server` - Should delegate to Ops Agent
|
|
229
|
+
- ❌ `[PM] Update docs/OPS.md` - Should delegate to Documentation Agent
|
|
230
|
+
|
|
231
|
+
**ONLY acceptable PM todos** (orchestration/delegation only):
|
|
232
|
+
- ✅ `Building delegation context for [task]` (no prefix needed - internal PM work)
|
|
233
|
+
- ✅ `Aggregating results from agents` (no prefix needed - internal PM work)
|
|
234
|
+
|
|
122
235
|
## Error Handling Protocol
|
|
123
236
|
**3-Attempt Process**:
|
|
124
237
|
1. **First Failure**: Re-delegate with enhanced context
|
|
125
238
|
2. **Second Failure**: Mark "ERROR - Attempt 2/3", escalate to Research if needed
|
|
126
239
|
3. **Third Failure**: TodoWrite escalation:
|
|
127
240
|
```
|
|
128
|
-
|
|
241
|
+
ERROR ESCALATION: [Task] - Blocked after 3 attempts
|
|
129
242
|
Error Type: [Blocking/Non-blocking]
|
|
130
243
|
User Decision Required: [Specific question]
|
|
131
244
|
```
|
|
@@ -141,6 +254,7 @@ Context:
|
|
|
141
254
|
|
|
142
255
|
## Standard Operating Procedure
|
|
143
256
|
1. **Analysis**: Parse request, assess context completeness (NO TOOLS)
|
|
257
|
+
1.5. **Memory Evaluation**: Check for memory indicators, extract key information, delegate storage if detected
|
|
144
258
|
2. **Planning**: Agent selection, task breakdown, priority assignment, dependency mapping
|
|
145
259
|
3. **Delegation**: Task Tool with enhanced format, context enrichment
|
|
146
260
|
4. **Monitoring**: Track progress, handle errors, dynamic adjustment
|
claude_mpm/cli/__init__.py
CHANGED
|
@@ -23,7 +23,8 @@ from .commands import (
|
|
|
23
23
|
show_info,
|
|
24
24
|
manage_agents,
|
|
25
25
|
run_terminal_ui,
|
|
26
|
-
manage_memory
|
|
26
|
+
manage_memory,
|
|
27
|
+
manage_monitor
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
# Get version from VERSION file - single source of truth
|
|
@@ -149,6 +150,7 @@ def _execute_command(command: str, args) -> int:
|
|
|
149
150
|
CLICommands.AGENTS.value: manage_agents,
|
|
150
151
|
CLICommands.UI.value: run_terminal_ui,
|
|
151
152
|
CLICommands.MEMORY.value: manage_memory,
|
|
153
|
+
CLICommands.MONITOR.value: manage_monitor,
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
# Execute command if found
|
|
@@ -11,6 +11,7 @@ from .info import show_info
|
|
|
11
11
|
from .agents import manage_agents
|
|
12
12
|
from .ui import run_terminal_ui
|
|
13
13
|
from .memory import manage_memory
|
|
14
|
+
from .monitor import manage_monitor
|
|
14
15
|
|
|
15
16
|
__all__ = [
|
|
16
17
|
'run_session',
|
|
@@ -18,5 +19,6 @@ __all__ = [
|
|
|
18
19
|
'show_info',
|
|
19
20
|
'manage_agents',
|
|
20
21
|
'run_terminal_ui',
|
|
21
|
-
'manage_memory'
|
|
22
|
+
'manage_memory',
|
|
23
|
+
'manage_monitor'
|
|
22
24
|
]
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Monitor command implementation for claude-mpm.
|
|
3
|
+
|
|
4
|
+
WHY: This module provides CLI commands for managing the Socket.IO monitoring server,
|
|
5
|
+
allowing users to start, stop, restart, and check status of the monitoring infrastructure.
|
|
6
|
+
|
|
7
|
+
DESIGN DECISION: We follow the existing CLI pattern using a main function
|
|
8
|
+
that dispatches to specific subcommand handlers, maintaining consistency
|
|
9
|
+
with other command modules like agents.py and memory.py.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from ...core.logger import get_logger
|
|
16
|
+
from ...constants import MonitorCommands
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def manage_monitor(args):
|
|
20
|
+
"""
|
|
21
|
+
Manage Socket.IO monitoring server.
|
|
22
|
+
|
|
23
|
+
WHY: The monitoring server provides real-time insights into Claude MPM sessions,
|
|
24
|
+
websocket connections, and system performance. This command provides a unified
|
|
25
|
+
interface for all monitor-related operations.
|
|
26
|
+
|
|
27
|
+
DESIGN DECISION: When no subcommand is provided, we show the server status
|
|
28
|
+
as the default action, giving users a quick overview of the monitoring system.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
args: Parsed command line arguments with monitor_command attribute
|
|
32
|
+
"""
|
|
33
|
+
logger = get_logger("cli")
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
# Import ServerManager from socketio_server_manager.py
|
|
37
|
+
from ...scripts.socketio_server_manager import ServerManager
|
|
38
|
+
server_manager = ServerManager()
|
|
39
|
+
|
|
40
|
+
if not args.monitor_command:
|
|
41
|
+
# No subcommand - show help
|
|
42
|
+
# WHY: Since we removed status, show help instead when no subcommand is provided
|
|
43
|
+
print("Available monitor commands:")
|
|
44
|
+
print(" start - Start the Socket.IO monitoring server")
|
|
45
|
+
print(" stop - Stop the Socket.IO monitoring server")
|
|
46
|
+
print(" restart - Restart the Socket.IO monitoring server")
|
|
47
|
+
print(" port <N> - Start/restart on specific port")
|
|
48
|
+
print()
|
|
49
|
+
print("Use 'claude-mpm monitor <command> --help' for more information")
|
|
50
|
+
return 0
|
|
51
|
+
|
|
52
|
+
if args.monitor_command == MonitorCommands.START.value:
|
|
53
|
+
success = _start_server(args, server_manager)
|
|
54
|
+
return 0 if success else 1
|
|
55
|
+
|
|
56
|
+
elif args.monitor_command == MonitorCommands.STOP.value:
|
|
57
|
+
success = _stop_server(args, server_manager)
|
|
58
|
+
return 0 if success else 1
|
|
59
|
+
|
|
60
|
+
elif args.monitor_command == MonitorCommands.RESTART.value:
|
|
61
|
+
success = _restart_server(args, server_manager)
|
|
62
|
+
return 0 if success else 1
|
|
63
|
+
|
|
64
|
+
elif args.monitor_command == MonitorCommands.PORT.value:
|
|
65
|
+
success = _port_server(args, server_manager)
|
|
66
|
+
return 0 if success else 1
|
|
67
|
+
|
|
68
|
+
else:
|
|
69
|
+
logger.error(f"Unknown monitor command: {args.monitor_command}")
|
|
70
|
+
print(f"Unknown monitor command: {args.monitor_command}")
|
|
71
|
+
print("Available commands: start, stop, restart, port")
|
|
72
|
+
return 1
|
|
73
|
+
|
|
74
|
+
except ImportError as e:
|
|
75
|
+
logger.error(f"Server manager not available: {e}")
|
|
76
|
+
print("Error: Socket.IO server manager not available")
|
|
77
|
+
print("This may indicate a missing dependency or installation issue.")
|
|
78
|
+
return 1
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"Error managing monitor: {e}")
|
|
81
|
+
print(f"Error: {e}")
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
return 0
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _port_server(args, server_manager):
|
|
88
|
+
"""
|
|
89
|
+
Start or restart the Socket.IO monitoring server on a specific port.
|
|
90
|
+
|
|
91
|
+
WHY: Users need to be able to start/restart the monitoring server on a specific
|
|
92
|
+
port, either if no server is running (start) or if a server is already running
|
|
93
|
+
on a different port (restart).
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
args: Command arguments with required port and optional host
|
|
97
|
+
server_manager: ServerManager instance
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
bool: True if server started/restarted successfully, False otherwise
|
|
101
|
+
"""
|
|
102
|
+
port = args.port
|
|
103
|
+
host = getattr(args, 'host', 'localhost')
|
|
104
|
+
|
|
105
|
+
print(f"Managing Socket.IO monitoring server on port {port}...")
|
|
106
|
+
print(f"Target: {host}:{port}")
|
|
107
|
+
print()
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
# Check if there are any running servers
|
|
111
|
+
running_servers = server_manager.list_running_servers()
|
|
112
|
+
|
|
113
|
+
# Check if server is already running on this port
|
|
114
|
+
server_on_port = any(server.get('port') == port for server in running_servers)
|
|
115
|
+
|
|
116
|
+
if server_on_port:
|
|
117
|
+
print(f"Server already running on port {port}. Restarting...")
|
|
118
|
+
success = server_manager.restart_server(port=port)
|
|
119
|
+
action = "restarted"
|
|
120
|
+
else:
|
|
121
|
+
# Check if servers are running on other ports
|
|
122
|
+
if running_servers:
|
|
123
|
+
print("Servers running on other ports:")
|
|
124
|
+
for server in running_servers:
|
|
125
|
+
server_port = server.get('port')
|
|
126
|
+
server_id = server.get('server_id', 'unknown')
|
|
127
|
+
print(f" • Server '{server_id}' on port {server_port}")
|
|
128
|
+
print()
|
|
129
|
+
print(f"Starting new server on port {port}...")
|
|
130
|
+
else:
|
|
131
|
+
print("No servers currently running. Starting new server...")
|
|
132
|
+
|
|
133
|
+
success = server_manager.start_server(port=port, host=host, server_id="monitor-server")
|
|
134
|
+
action = "started"
|
|
135
|
+
|
|
136
|
+
if success:
|
|
137
|
+
print()
|
|
138
|
+
print(f"Monitor server {action} successfully on port {port}")
|
|
139
|
+
print()
|
|
140
|
+
print("Server management commands:")
|
|
141
|
+
print(f" Status: ps aux | grep socketio")
|
|
142
|
+
print(f" Stop: claude-mpm monitor stop --port {port}")
|
|
143
|
+
print(f" Restart: claude-mpm monitor restart --port {port}")
|
|
144
|
+
print()
|
|
145
|
+
print(f"WebSocket URL: ws://{host}:{port}")
|
|
146
|
+
else:
|
|
147
|
+
print(f"Failed to {action.replace('ed', '')} server on port {port}")
|
|
148
|
+
print()
|
|
149
|
+
print("Troubleshooting:")
|
|
150
|
+
print(f" • Check if port {port} is available: lsof -i :{port}")
|
|
151
|
+
print(f" • Try a different port: claude-mpm monitor port {port + 1}")
|
|
152
|
+
print(" • Check system resources: free -h && df -h")
|
|
153
|
+
|
|
154
|
+
return success
|
|
155
|
+
|
|
156
|
+
except Exception as e:
|
|
157
|
+
print(f"Error managing server on port {port}: {e}")
|
|
158
|
+
print()
|
|
159
|
+
print("Troubleshooting:")
|
|
160
|
+
print(f" • Verify port {port} is valid and available")
|
|
161
|
+
print(" • Check system resources and permissions")
|
|
162
|
+
print(" • Try manual start/stop operations")
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _start_server(args, server_manager):
|
|
167
|
+
"""
|
|
168
|
+
Start the Socket.IO monitoring server.
|
|
169
|
+
|
|
170
|
+
WHY: Users need to start the monitoring server to enable real-time monitoring
|
|
171
|
+
of Claude MPM sessions and websocket connections.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
args: Command arguments with optional port and host
|
|
175
|
+
server_manager: ServerManager instance
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
bool: True if server started successfully, False otherwise
|
|
179
|
+
"""
|
|
180
|
+
port = getattr(args, 'port', 8765)
|
|
181
|
+
host = getattr(args, 'host', 'localhost')
|
|
182
|
+
|
|
183
|
+
print(f"Starting Socket.IO monitoring server...")
|
|
184
|
+
print(f"Target: {host}:{port}")
|
|
185
|
+
print()
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
success = server_manager.start_server(port=port, host=host, server_id="monitor-server")
|
|
189
|
+
|
|
190
|
+
if success:
|
|
191
|
+
print()
|
|
192
|
+
print("Monitor server management commands:")
|
|
193
|
+
print(f" Status: claude-mpm monitor status")
|
|
194
|
+
print(f" Stop: claude-mpm monitor stop")
|
|
195
|
+
print(f" Restart: claude-mpm monitor restart")
|
|
196
|
+
print()
|
|
197
|
+
print(f"WebSocket URL: ws://{host}:{port}")
|
|
198
|
+
|
|
199
|
+
return success
|
|
200
|
+
|
|
201
|
+
except Exception as e:
|
|
202
|
+
print(f"Failed to start monitoring server: {e}")
|
|
203
|
+
print()
|
|
204
|
+
print("Troubleshooting:")
|
|
205
|
+
print(f" • Check if port {port} is available: lsof -i :{port}")
|
|
206
|
+
print(f" • Try a different port: claude-mpm monitor start --port {port + 1}")
|
|
207
|
+
print(" • Check system resources: free -h && df -h")
|
|
208
|
+
return False
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _stop_server(args, server_manager):
|
|
212
|
+
"""
|
|
213
|
+
Stop the Socket.IO monitoring server.
|
|
214
|
+
|
|
215
|
+
WHY: Users need to stop the monitoring server when it's no longer needed
|
|
216
|
+
or when troubleshooting connection issues.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
args: Command arguments with optional port
|
|
220
|
+
server_manager: ServerManager instance
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
bool: True if server stopped successfully, False otherwise
|
|
224
|
+
"""
|
|
225
|
+
port = getattr(args, 'port', None)
|
|
226
|
+
|
|
227
|
+
print("Stopping Socket.IO monitoring server...")
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
# If no port specified, try to find running servers and stop them
|
|
231
|
+
if port is None:
|
|
232
|
+
running_servers = server_manager.list_running_servers()
|
|
233
|
+
if not running_servers:
|
|
234
|
+
print("No running servers found to stop")
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
# Stop the first server (or all if multiple)
|
|
238
|
+
success = True
|
|
239
|
+
for server in running_servers:
|
|
240
|
+
server_port = server.get('port')
|
|
241
|
+
server_id = server.get('server_id', 'unknown')
|
|
242
|
+
print(f"Stopping server '{server_id}' on port {server_port}...")
|
|
243
|
+
|
|
244
|
+
if not server_manager.stop_server(port=server_port):
|
|
245
|
+
print(f"Failed to stop server on port {server_port}")
|
|
246
|
+
success = False
|
|
247
|
+
|
|
248
|
+
return success
|
|
249
|
+
else:
|
|
250
|
+
# Stop specific server on given port
|
|
251
|
+
success = server_manager.stop_server(port=port)
|
|
252
|
+
|
|
253
|
+
if success:
|
|
254
|
+
print(f"Monitor server stopped on port {port}")
|
|
255
|
+
else:
|
|
256
|
+
print(f"Failed to stop server on port {port}")
|
|
257
|
+
print()
|
|
258
|
+
print("Troubleshooting:")
|
|
259
|
+
print(f" • Check if server is running: claude-mpm monitor status")
|
|
260
|
+
print(f" • Try force kill: kill $(lsof -ti :{port})")
|
|
261
|
+
|
|
262
|
+
return success
|
|
263
|
+
|
|
264
|
+
except Exception as e:
|
|
265
|
+
print(f"Error stopping server: {e}")
|
|
266
|
+
return False
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _restart_server(args, server_manager):
|
|
270
|
+
"""
|
|
271
|
+
Restart the Socket.IO monitoring server.
|
|
272
|
+
|
|
273
|
+
WHY: Users need to restart the monitoring server to apply configuration
|
|
274
|
+
changes or recover from error states.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
args: Command arguments with optional port
|
|
278
|
+
server_manager: ServerManager instance
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
bool: True if server restarted successfully, False otherwise
|
|
282
|
+
"""
|
|
283
|
+
port = getattr(args, 'port', None)
|
|
284
|
+
|
|
285
|
+
print("Restarting Socket.IO monitoring server...")
|
|
286
|
+
|
|
287
|
+
try:
|
|
288
|
+
# If no port specified, find running servers to restart
|
|
289
|
+
if port is None:
|
|
290
|
+
running_servers = server_manager.list_running_servers()
|
|
291
|
+
if not running_servers:
|
|
292
|
+
print("No running servers found. Starting new server on default port...")
|
|
293
|
+
return _start_server(args, server_manager)
|
|
294
|
+
|
|
295
|
+
# Restart the first server found
|
|
296
|
+
server = running_servers[0]
|
|
297
|
+
port = server.get('port', 8765)
|
|
298
|
+
|
|
299
|
+
print(f"Using port {port} for restart...")
|
|
300
|
+
|
|
301
|
+
# Use ServerManager's restart method
|
|
302
|
+
success = server_manager.restart_server(port=port)
|
|
303
|
+
|
|
304
|
+
if success:
|
|
305
|
+
print(f"Monitor server restarted successfully on port {port}")
|
|
306
|
+
print()
|
|
307
|
+
print("Server management commands:")
|
|
308
|
+
print(f" Status: claude-mpm monitor status")
|
|
309
|
+
print(f" Stop: claude-mpm monitor stop --port {port}")
|
|
310
|
+
print(f" Start: claude-mpm monitor start --port {port}")
|
|
311
|
+
else:
|
|
312
|
+
print(f"Failed to restart server on port {port}")
|
|
313
|
+
print()
|
|
314
|
+
print("Troubleshooting:")
|
|
315
|
+
print(" • Try stopping and starting manually:")
|
|
316
|
+
print(f" claude-mpm monitor stop --port {port}")
|
|
317
|
+
print(f" claude-mpm monitor start --port {port}")
|
|
318
|
+
print(" • Check server logs for errors")
|
|
319
|
+
|
|
320
|
+
return success
|
|
321
|
+
|
|
322
|
+
except Exception as e:
|
|
323
|
+
print(f"Error restarting server: {e}")
|
|
324
|
+
print()
|
|
325
|
+
print("Fallback options:")
|
|
326
|
+
print(" • Manual restart: stop then start")
|
|
327
|
+
print(" • Check system resources and try again")
|
|
328
|
+
return False
|
claude_mpm/cli/commands/run.py
CHANGED
|
@@ -585,24 +585,16 @@ def _start_standalone_socketio_server(port, logger):
|
|
|
585
585
|
|
|
586
586
|
logger.debug(f"Checking server readiness (attempt {attempt + 1}/{max_attempts}, waiting {delay}s)")
|
|
587
587
|
|
|
588
|
-
#
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if _check_socketio_server_running(port, logger):
|
|
597
|
-
logger.info(f"✅ Standalone Socket.IO server started successfully on port {port}")
|
|
598
|
-
logger.info(f"🕐 Server ready after {attempt + 1} attempts ({(attempt + 1) * delay:.1f}s)")
|
|
599
|
-
return True
|
|
600
|
-
else:
|
|
601
|
-
logger.debug(f"Server not yet accepting connections on attempt {attempt + 1}")
|
|
588
|
+
# Give the daemon process time to initialize and bind to the socket
|
|
589
|
+
time.sleep(delay)
|
|
590
|
+
|
|
591
|
+
# Check if the daemon server is accepting connections
|
|
592
|
+
if _check_socketio_server_running(port, logger):
|
|
593
|
+
logger.info(f"✅ Standalone Socket.IO server started successfully on port {port}")
|
|
594
|
+
logger.info(f"🕐 Server ready after {attempt + 1} attempts ({(attempt + 1) * delay:.1f}s)")
|
|
595
|
+
return True
|
|
602
596
|
else:
|
|
603
|
-
logger.
|
|
604
|
-
# Give thread more time to start
|
|
605
|
-
time.sleep(delay)
|
|
597
|
+
logger.debug(f"Server not yet accepting connections on attempt {attempt + 1}")
|
|
606
598
|
|
|
607
599
|
logger.error(f"❌ Socket.IO server failed to start properly on port {port} after {max_attempts} attempts")
|
|
608
600
|
logger.error(f"💡 This may indicate a port conflict or dependency issue")
|