claude-flow-novice 2.14.31 → 2.14.32
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.
- package/.claude/cfn-data/cfn-loop.db +0 -0
- package/.claude/commands/CFN_LOOP_TASK_MODE.md +1 -1
- package/.claude/skills/cfn-agent-discovery/agents-registry.json +10 -9
- package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +394 -0
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +521 -0
- package/.claude/skills/cfn-docker-loop-orchestration/SKILL.md +449 -0
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +787 -0
- package/.claude/skills/cfn-docker-redis-coordination/SKILL.md +435 -0
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh +635 -0
- package/.claude/skills/cfn-docker-skill-mcp-selection/SKILL.md +289 -0
- package/.claude/skills/cfn-docker-skill-mcp-selection/skill-mcp-selector.js +472 -0
- package/.claude/skills/cfn-loop-validation/config.json +2 -2
- package/README.md +95 -0
- package/claude-assets/agents/README-AGENT_LIFECYCLE.md +10 -37
- package/claude-assets/agents/README-VALIDATION.md +8 -0
- package/claude-assets/agents/cfn-dev-team/README.md +8 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/README.md +9 -1
- package/claude-assets/agents/cfn-dev-team/developers/README.md +9 -1
- package/claude-assets/agents/cfn-dev-team/documentation/README-VALIDATION.md +8 -0
- package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md +10 -0
- package/claude-assets/agents/cfn-dev-team/reviewers/README.md +9 -1
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +10 -0
- package/claude-assets/agents/cfn-dev-team/test-agent.md +10 -0
- package/claude-assets/agents/cfn-dev-team/testers/README.md +9 -1
- package/claude-assets/agents/csuite/cto-agent.md +10 -0
- package/claude-assets/agents/custom/cfn-system-expert.md +128 -1
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +5 -1
- package/claude-assets/agents/docker-team/csuite/c-suite-template.md +5 -1
- package/claude-assets/agents/docker-team/infrastructure/team-coordinator-template.md +5 -1
- package/claude-assets/agents/marketing_hybrid/cost_tracker.md +10 -0
- package/claude-assets/agents/marketing_hybrid/docker_deployer.md +10 -0
- package/claude-assets/agents/marketing_hybrid/zai_worker_spawner.md +10 -0
- package/claude-assets/commands/CFN_LOOP_TASK_MODE.md +1 -1
- package/claude-assets/hooks/cfn-post-execution/memory-cleanup.sh +20 -0
- package/claude-assets/hooks/cfn-pre-execution/memory-check.sh +20 -0
- package/claude-assets/skills/cfn-agent-discovery/agents-registry.json +10 -9
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +70 -10
- package/claude-assets/skills/cfn-loop-validation/config.json +2 -2
- package/claude-assets/skills/cfn-memory-management/SKILL.md +271 -0
- package/claude-assets/skills/cfn-memory-management/check-memory.sh +160 -0
- package/claude-assets/skills/cfn-memory-management/cleanup-memory.sh +197 -0
- package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +2 -2
- package/dist/cli/agent-command.js +44 -2
- package/dist/cli/agent-command.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/index.js +29 -2
- package/dist/cli/index.js.map +1 -1
- package/package.json +10 -2
- package/scripts/memory-leak-prevention.sh +306 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# CFN Memory Management Skill
|
|
2
|
+
|
|
3
|
+
**Purpose:** Prevent and detect memory leaks in Claude CLI operations through proactive monitoring, limits, and profiling.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This skill implements memory leak prevention strategies based on real-world memory spike analysis. It provides automated memory monitoring, profiling, and safe defaults to prevent Claude CLI from exhausting system memory.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Automatic Memory Limits**: Configurable memory caps with safe defaults
|
|
12
|
+
- **Heap Profiling**: Built-in profiling for memory allocation analysis
|
|
13
|
+
- **Real-time Monitoring**: Live memory usage tracking with alerts
|
|
14
|
+
- **Crash Detection**: Automatic detection of memory exhaustion events
|
|
15
|
+
- **Profile Analysis**: Tools to analyze heap profiles and identify leaks
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
### Default Memory Limits
|
|
20
|
+
```bash
|
|
21
|
+
# Safe default (reduced from 16GB)
|
|
22
|
+
export NODE_OPTIONS="--max-old-space-size=8192"
|
|
23
|
+
|
|
24
|
+
# For production environments
|
|
25
|
+
export CLAUDE_MEMORY_LIMIT="8GB"
|
|
26
|
+
export CLAUDE_MEMORY_PROFILE_DIR="/tmp/claude-memory-profiles"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Environment Variables
|
|
30
|
+
- `CLAUDE_MEMORY_LIMIT`: Memory limit in MB (default: 8192)
|
|
31
|
+
- `CLAUDE_MEMORY_PROFILE_DIR`: Directory for heap profiles (default: /tmp/claude-memory-profiles)
|
|
32
|
+
- `CLAUDE_MEMORY_MONITORING`: Enable/disable monitoring (default: true)
|
|
33
|
+
- `CLAUDE_MEMORY_ALERT_THRESHOLD`: Alert threshold in MB (default: 6144)
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Start Claude with Memory Profiling
|
|
38
|
+
```bash
|
|
39
|
+
# Use the memory leak prevention script
|
|
40
|
+
./scripts/memory-leak-prevention.sh profile --limit 6144
|
|
41
|
+
|
|
42
|
+
# Or set environment manually
|
|
43
|
+
export NODE_OPTIONS="--max-old-space-size=6144 --inspect=0.0.0.0:9229 --heap-prof"
|
|
44
|
+
npx claude-flow-novice
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Monitor Existing Process
|
|
48
|
+
```bash
|
|
49
|
+
./scripts/memory-leak-prevention.sh monitor --pid 12345 --duration 600
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Install Debug Tools
|
|
53
|
+
```bash
|
|
54
|
+
./scripts/memory-leak-prevention.sh install-tools
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Analyze Memory Profiles
|
|
58
|
+
```bash
|
|
59
|
+
./scripts/memory-leak-prevention.sh analyze --output ./profiles
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Memory Leak Detection Patterns
|
|
63
|
+
|
|
64
|
+
### High-Risk Indicators
|
|
65
|
+
- RSS memory > 8GB within 5 minutes of launch
|
|
66
|
+
- Multiple simultaneous TLS connections (>50)
|
|
67
|
+
- High number of open files (>1000)
|
|
68
|
+
- Large heap arenas (>1GB allocations)
|
|
69
|
+
- Bun Pool worker count > 20
|
|
70
|
+
|
|
71
|
+
### Automatic Detection
|
|
72
|
+
The skill monitors for these patterns and triggers alerts:
|
|
73
|
+
```bash
|
|
74
|
+
# Check for memory spikes
|
|
75
|
+
if [[ $rss_mb -gt 8192 ]]; then
|
|
76
|
+
log "⚠️ High memory usage detected: ${rss_mb}MB RSS"
|
|
77
|
+
# Trigger profiling dump
|
|
78
|
+
kill -USR2 $target_pid 2>/dev/null || true
|
|
79
|
+
fi
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Integration with CFN Loop
|
|
83
|
+
|
|
84
|
+
### Memory-Safe CFN Loop Execution
|
|
85
|
+
```bash
|
|
86
|
+
# Before starting CFN Loop
|
|
87
|
+
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
88
|
+
export CLAUDE_MEMORY_MONITORING=true
|
|
89
|
+
|
|
90
|
+
# Execute with memory bounds
|
|
91
|
+
/cfn-loop-cli "task description" --mode=standard
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Agent Memory Management
|
|
95
|
+
Agents spawned via CLI automatically inherit memory limits:
|
|
96
|
+
```bash
|
|
97
|
+
# Agent inherits parent process memory limits
|
|
98
|
+
npx claude-flow-novice agent-spawn \
|
|
99
|
+
--agent-type backend-developer \
|
|
100
|
+
--memory-limit 2048 \
|
|
101
|
+
--enable-profiling
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Debugging Tools
|
|
105
|
+
|
|
106
|
+
### Heap Profile Analysis
|
|
107
|
+
```javascript
|
|
108
|
+
// Analyze heap profile data
|
|
109
|
+
const fs = require('fs');
|
|
110
|
+
const profile = JSON.parse(fs.readFileSync('profile.heapprofile', 'utf8'));
|
|
111
|
+
|
|
112
|
+
// Find largest allocations
|
|
113
|
+
const allocations = profile.heapProfile.samples
|
|
114
|
+
.sort((a, b) => b.size - a.size)
|
|
115
|
+
.slice(0, 10);
|
|
116
|
+
|
|
117
|
+
allocations.forEach((alloc, i) => {
|
|
118
|
+
console.log(`${i+1}. ${alloc.functionName}: ${(alloc.size/1024/1024).toFixed(2)}MB`);
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Memory Usage Monitoring
|
|
123
|
+
```bash
|
|
124
|
+
# Real-time memory monitoring
|
|
125
|
+
watch -n 5 'ps aux | grep claude | grep -v grep'
|
|
126
|
+
|
|
127
|
+
# Network connection monitoring
|
|
128
|
+
netstat -an | grep ESTABLISHED | grep -c
|
|
129
|
+
|
|
130
|
+
# File descriptor monitoring
|
|
131
|
+
lsof -p <PID> | wc -l
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Recovery Procedures
|
|
135
|
+
|
|
136
|
+
### When Memory Leak Detected
|
|
137
|
+
1. **Immediate Action**: Kill the process to prevent system exhaustion
|
|
138
|
+
```bash
|
|
139
|
+
kill -9 <PID>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. **Save Diagnostic Data**:
|
|
143
|
+
```bash
|
|
144
|
+
# Save memory map
|
|
145
|
+
cat /proc/<PID>/smaps > memory-smaps.log
|
|
146
|
+
|
|
147
|
+
# Save process info
|
|
148
|
+
ps auxf > process-tree.log
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
3. **Restart with Limits**:
|
|
152
|
+
```bash
|
|
153
|
+
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
154
|
+
./scripts/memory-leak-prevention.sh profile
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Automatic Recovery
|
|
158
|
+
The skill includes automatic recovery mechanisms:
|
|
159
|
+
- Memory threshold monitoring
|
|
160
|
+
- Process termination on memory exhaustion
|
|
161
|
+
- Automatic profile generation on crashes
|
|
162
|
+
- Safe restart procedures
|
|
163
|
+
|
|
164
|
+
## Performance Impact
|
|
165
|
+
|
|
166
|
+
### Monitoring Overhead
|
|
167
|
+
- **CPU**: < 1% overhead for monitoring
|
|
168
|
+
- **Memory**: ~10MB additional for monitoring data
|
|
169
|
+
- **I/O**: Minimal logging impact
|
|
170
|
+
|
|
171
|
+
### Profiling Overhead
|
|
172
|
+
- **CPU**: 10-15% overhead when profiling enabled
|
|
173
|
+
- **Memory**: ~50MB additional for profile data
|
|
174
|
+
- **Startup**: 2-3 second delay for profiler initialization
|
|
175
|
+
|
|
176
|
+
## Best Practices
|
|
177
|
+
|
|
178
|
+
### Development Environment
|
|
179
|
+
```bash
|
|
180
|
+
# Use profiling for development
|
|
181
|
+
export NODE_OPTIONS="--max-old-space-size=4096 --inspect --heap-prof"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Production Environment
|
|
185
|
+
```bash
|
|
186
|
+
# Use conservative limits
|
|
187
|
+
export NODE_OPTIONS="--max-old-space-size=6144"
|
|
188
|
+
export CLAUDE_MEMORY_MONITORING=false
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### WSL Specific
|
|
192
|
+
```bash
|
|
193
|
+
# WSL memory optimization
|
|
194
|
+
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
195
|
+
echo 1 | sudo tee /proc/sys/vm/overcommit_memory # Enable memory overcommit
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Troubleshooting
|
|
199
|
+
|
|
200
|
+
### Common Issues
|
|
201
|
+
1. **High memory usage**: Reduce memory limit, restart with profiling
|
|
202
|
+
2. **Slow performance**: Disable profiling in production
|
|
203
|
+
3. **Connection issues**: Check WSL memory limits
|
|
204
|
+
4. **Profile corruption**: Use larger memory limits for profiling
|
|
205
|
+
|
|
206
|
+
### Debug Mode
|
|
207
|
+
```bash
|
|
208
|
+
# Enable verbose debugging
|
|
209
|
+
export CLAUDE_MEMORY_DEBUG=true
|
|
210
|
+
export CLAUDE_MEMORY_LOG_LEVEL=trace
|
|
211
|
+
|
|
212
|
+
./scripts/memory-leak-prevention.sh profile --debug
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Integration Hooks
|
|
216
|
+
|
|
217
|
+
### Pre-Execution Hook
|
|
218
|
+
```bash
|
|
219
|
+
#!/bin/bash
|
|
220
|
+
# .claude/hooks/cfn-pre-execution/memory-check.sh
|
|
221
|
+
|
|
222
|
+
./.claude/skills/cfn-memory-management/check-memory.sh
|
|
223
|
+
if [[ $? -ne 0 ]]; then
|
|
224
|
+
echo "❌ Memory check failed. Please free memory before proceeding."
|
|
225
|
+
exit 1
|
|
226
|
+
fi
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Post-Execution Hook
|
|
230
|
+
```bash
|
|
231
|
+
#!/bin/bash
|
|
232
|
+
# .claude/hooks/cfn-post-execution/memory-cleanup.sh
|
|
233
|
+
|
|
234
|
+
./.claude/skills/cfn-memory-management/cleanup-memory.sh
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Metrics and Monitoring
|
|
238
|
+
|
|
239
|
+
### Key Metrics
|
|
240
|
+
- RSS memory usage
|
|
241
|
+
- Heap size and allocation patterns
|
|
242
|
+
- Number of open file descriptors
|
|
243
|
+
- Network connection count
|
|
244
|
+
- Process/thread count
|
|
245
|
+
|
|
246
|
+
### Alert Thresholds
|
|
247
|
+
- **Critical**: RSS > 8GB or connections > 100
|
|
248
|
+
- **Warning**: RSS > 6GB or connections > 50
|
|
249
|
+
- **Info**: RSS > 4GB or connections > 25
|
|
250
|
+
|
|
251
|
+
## Dependencies
|
|
252
|
+
|
|
253
|
+
- `node` >= 18.0.0
|
|
254
|
+
- `strace` (for system call tracing)
|
|
255
|
+
- `perf` (for performance profiling)
|
|
256
|
+
- `lsof` (for file descriptor monitoring)
|
|
257
|
+
- `ps` (for process monitoring)
|
|
258
|
+
|
|
259
|
+
## Security Considerations
|
|
260
|
+
|
|
261
|
+
- Profiles may contain sensitive data - stored in /tmp with restricted permissions
|
|
262
|
+
- Debugging ports should not be exposed publicly
|
|
263
|
+
- Memory limits prevent DoS attacks
|
|
264
|
+
- All temporary files are automatically cleaned up
|
|
265
|
+
|
|
266
|
+
## Version History
|
|
267
|
+
|
|
268
|
+
- **v1.0.0**: Initial implementation based on memory leak analysis
|
|
269
|
+
- **v1.1.0**: Added automatic recovery mechanisms
|
|
270
|
+
- **v1.2.0**: Integrated with CFN Loop orchestration
|
|
271
|
+
- **v1.3.0**: Added WSL-specific optimizations
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Memory Check Script for CFN Operations
|
|
4
|
+
# Pre-execution hook to ensure sufficient memory is available
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
MIN_FREE_MB=2048 # Minimum 2GB free memory required
|
|
10
|
+
WARNING_THRESHOLD_MB=4096 # Warning at 4GB
|
|
11
|
+
LOG_FILE="/tmp/cfn-memory-check.log"
|
|
12
|
+
|
|
13
|
+
# Colors
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
NC='\033[0m'
|
|
18
|
+
|
|
19
|
+
log() {
|
|
20
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
check_system_memory() {
|
|
24
|
+
local total_mb=0
|
|
25
|
+
local available_mb=0
|
|
26
|
+
local used_mb=0
|
|
27
|
+
|
|
28
|
+
if command -v free &> /dev/null; then
|
|
29
|
+
# Linux/WSL
|
|
30
|
+
local mem_info=$(free -m | awk 'NR==2{print $2,$3,$7}')
|
|
31
|
+
total_mb=$(echo "$mem_info" | cut -d' ' -f1)
|
|
32
|
+
used_mb=$(echo "$mem_info" | cut -d' ' -f2)
|
|
33
|
+
available_mb=$(echo "$mem_info" | cut -d' ' -f3)
|
|
34
|
+
elif command -v vm_stat &> /dev/null; then
|
|
35
|
+
# macOS
|
|
36
|
+
local page_size=$(vm_stat | head -1 | sed 's/.*page size of \([0-9]*\).*/\1/')
|
|
37
|
+
local free_pages=$(vm_stat | awk '/free/ {gsub(/\./, "", $3); print $3}')
|
|
38
|
+
local active_pages=$(vm_stat | awk '/active/ {gsub(/\./, "", $3); print $3}')
|
|
39
|
+
local inactive_pages=$(vm_stat | awk '/inactive/ {gsub(/\./, "", $3); print $3}')
|
|
40
|
+
local wired_pages=$(vm_stat | awk '/wired/ {gsub(/\./, "", $3); print $3}')
|
|
41
|
+
|
|
42
|
+
total_mb=$(((active_pages + inactive_pages + wired_pages + free_pages) * page_size / 1024 / 1024))
|
|
43
|
+
available_mb=$((free_pages * page_size / 1024 / 1024))
|
|
44
|
+
used_mb=$((total_mb - available_mb))
|
|
45
|
+
else
|
|
46
|
+
log "ERROR: Cannot determine system memory (free/vm_stat not available)"
|
|
47
|
+
return 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo "${total_mb},${used_mb},${available_mb}"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
check_claude_processes() {
|
|
54
|
+
local claude_pids=$(pgrep -f "claude" || true)
|
|
55
|
+
local total_claude_memory=0
|
|
56
|
+
local process_count=0
|
|
57
|
+
|
|
58
|
+
if [[ -n "$claude_pids" ]]; then
|
|
59
|
+
while read -r pid; do
|
|
60
|
+
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
61
|
+
local rss_kb=$(ps -p "$pid" -o rss= --no-headers 2>/dev/null || echo "0")
|
|
62
|
+
local rss_mb=$((rss_kb / 1024))
|
|
63
|
+
total_claude_memory=$((total_claude_memory + rss_mb))
|
|
64
|
+
process_count=$((process_count + 1))
|
|
65
|
+
fi
|
|
66
|
+
done <<< "$claude_pids"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
echo "${process_count},${total_claude_memory}"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
main() {
|
|
73
|
+
log "Starting memory check for CFN operation"
|
|
74
|
+
|
|
75
|
+
# Check system memory
|
|
76
|
+
local mem_info=$(check_system_memory)
|
|
77
|
+
IFS=',' read -r total_mb used_mb available_mb <<< "$mem_info"
|
|
78
|
+
|
|
79
|
+
echo "System Memory Status:"
|
|
80
|
+
echo " Total: ${total_mb}MB"
|
|
81
|
+
echo " Used: ${used_mb}MB"
|
|
82
|
+
echo " Available: ${available_mb}MB"
|
|
83
|
+
|
|
84
|
+
# Check Claude processes
|
|
85
|
+
local claude_info=$(check_claude_processes)
|
|
86
|
+
IFS=',' read -r claude_count claude_memory_mb <<< "$claude_info"
|
|
87
|
+
|
|
88
|
+
if [[ $claude_count -gt 0 ]]; then
|
|
89
|
+
echo "Claude Processes:"
|
|
90
|
+
echo " Count: $claude_count"
|
|
91
|
+
echo " Memory: ${claude_memory}MB"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Calculate available memory for new operation
|
|
95
|
+
local available_for_operation=$((available_mb - claude_memory_mb))
|
|
96
|
+
|
|
97
|
+
echo "Available for CFN operation: ${available_for_operation}MB"
|
|
98
|
+
|
|
99
|
+
# Check thresholds
|
|
100
|
+
if [[ $available_for_operation -lt $MIN_FREE_MB ]]; then
|
|
101
|
+
echo -e "${RED}❌ Insufficient memory for CFN operation${NC}"
|
|
102
|
+
echo "Required: ${MIN_FREE_MB}MB, Available: ${available_for_operation}MB"
|
|
103
|
+
echo ""
|
|
104
|
+
echo "Suggestions:"
|
|
105
|
+
echo " 1. Close existing Claude processes: pkill -f claude"
|
|
106
|
+
echo " 2. Free system memory: sudo sync && sudo sysctl vm.drop_caches=3"
|
|
107
|
+
echo " 3. Restart your terminal/shell session"
|
|
108
|
+
echo " 4. Reduce memory requirements with smaller tasks"
|
|
109
|
+
|
|
110
|
+
log "CRITICAL: Insufficient memory - Required: ${MIN_FREE_MB}MB, Available: ${available_for_operation}MB"
|
|
111
|
+
return 1
|
|
112
|
+
elif [[ $available_for_operation -lt $WARNING_THRESHOLD_MB ]]; then
|
|
113
|
+
echo -e "${YELLOW}⚠️ Low memory warning${NC}"
|
|
114
|
+
echo "Available: ${available_for_operation}MB (Recommended: ${WARNING_THRESHOLD_MB}MB+)"
|
|
115
|
+
echo "Consider closing other applications for optimal performance"
|
|
116
|
+
|
|
117
|
+
log "WARNING: Low memory - Available: ${available_for_operation}MB"
|
|
118
|
+
else
|
|
119
|
+
echo -e "${GREEN}✅ Sufficient memory available${NC}"
|
|
120
|
+
log "OK: Sufficient memory - Available: ${available_for_operation}MB"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Check for memory leak indicators
|
|
124
|
+
if [[ $claude_count -gt 0 ]]; then
|
|
125
|
+
local avg_claude_memory=$((claude_memory_mb / claude_count))
|
|
126
|
+
if [[ $avg_claude_memory -gt 4096 ]]; then
|
|
127
|
+
echo -e "${YELLOW}⚠️ High Claude memory usage detected${NC}"
|
|
128
|
+
echo "Average per process: ${avg_claude_memory}MB"
|
|
129
|
+
echo "Consider restarting Claude processes"
|
|
130
|
+
|
|
131
|
+
log "WARNING: High Claude memory usage - Average: ${avg_claude_memory}MB"
|
|
132
|
+
fi
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Check WSL-specific issues
|
|
136
|
+
if [[ -f /proc/version ]] && grep -qi microsoft /proc/version; then
|
|
137
|
+
echo "WSL Environment Detected:"
|
|
138
|
+
|
|
139
|
+
# Check WSL memory limits
|
|
140
|
+
if [[ -f /proc/meminfo ]]; then
|
|
141
|
+
local wsl_total=$(grep MemTotal /proc/meminfo | awk '{print int($2/1024)}')
|
|
142
|
+
if [[ $wsl_total -lt 8192 ]]; then
|
|
143
|
+
echo -e "${YELLOW}⚠️ Low WSL memory limit: ${wsl_total}MB${NC}"
|
|
144
|
+
echo "Consider increasing WSL memory in .wslconfig"
|
|
145
|
+
echo ""
|
|
146
|
+
echo "Create %USERPROFILE%\\.wslconfig with:"
|
|
147
|
+
echo "[wsl2]"
|
|
148
|
+
echo "memory=16GB"
|
|
149
|
+
echo "swap=4GB"
|
|
150
|
+
fi
|
|
151
|
+
fi
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
echo ""
|
|
155
|
+
echo "Memory check completed successfully"
|
|
156
|
+
return 0
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Run main function
|
|
160
|
+
main "$@"
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Memory Cleanup Script for CFN Operations
|
|
4
|
+
# Post-execution hook to clean up memory resources
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
CLEANUP_DELAY=5 # Seconds to wait before cleanup
|
|
10
|
+
LOG_FILE="/tmp/cfn-memory-cleanup.log"
|
|
11
|
+
PROFILE_DIR="/tmp/claude-memory-profiles"
|
|
12
|
+
|
|
13
|
+
# Colors
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
BLUE='\033[0;34m'
|
|
17
|
+
NC='\033[0m'
|
|
18
|
+
|
|
19
|
+
log() {
|
|
20
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
cleanup_temp_files() {
|
|
24
|
+
log "Cleaning up temporary files"
|
|
25
|
+
|
|
26
|
+
# Clean old profile files (older than 24 hours)
|
|
27
|
+
if [[ -d "$PROFILE_DIR" ]]; then
|
|
28
|
+
local old_profiles=$(find "$PROFILE_DIR" -name "*.heapprofile" -mtime +1 2>/dev/null || true)
|
|
29
|
+
if [[ -n "$old_profiles" ]]; then
|
|
30
|
+
echo "$old_profiles" | xargs rm -f 2>/dev/null || true
|
|
31
|
+
log "Removed old heap profiles"
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Clean temp directories
|
|
36
|
+
find /tmp -name "claude-*" -type d -mtime +1 -exec rm -rf {} + 2>/dev/null || true
|
|
37
|
+
find /tmp -name "*claude*" -type f -mtime +1 -delete 2>/dev/null || true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
cleanup_zombie_processes() {
|
|
41
|
+
log "Checking for zombie Claude processes"
|
|
42
|
+
|
|
43
|
+
local zombie_pids=$(ps aux | awk '$8 ~ /^Z/ && $11 ~ /claude/ {print $2}' || true)
|
|
44
|
+
|
|
45
|
+
if [[ -n "$zombie_pids" ]]; then
|
|
46
|
+
echo -e "${YELLOW}Found zombie Claude processes: $zombie_pids${NC}"
|
|
47
|
+
# Zombies can't be killed directly, but we can log them
|
|
48
|
+
log "Zombie processes detected: $zombie_pids"
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
cleanup_hanging_processes() {
|
|
53
|
+
log "Checking for hanging Claude processes"
|
|
54
|
+
|
|
55
|
+
# Find processes that have been running > 2 hours
|
|
56
|
+
local hanging_pids=$(ps -eo pid,etime,cmd | awk '$3 ~ /claude/ && $2 ~ /([0-9]{2}:|[0-9]{3}-)/ {print $1}' || true)
|
|
57
|
+
|
|
58
|
+
if [[ -n "$hanging_pids" ]]; then
|
|
59
|
+
echo -e "${YELLOW}Found long-running Claude processes: $hanging_pids${NC}"
|
|
60
|
+
|
|
61
|
+
for pid in $hanging_pids; do
|
|
62
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
63
|
+
local process_info=$(ps -p "$pid" -o pid,etime,pcpu,rss,cmd --no-headers)
|
|
64
|
+
echo " PID $pid: $process_info"
|
|
65
|
+
|
|
66
|
+
# Check if process is consuming excessive memory (>4GB)
|
|
67
|
+
local rss_kb=$(ps -p "$pid" -o rss= --no-headers 2>/dev/null || echo "0")
|
|
68
|
+
local rss_mb=$((rss_kb / 1024))
|
|
69
|
+
|
|
70
|
+
if [[ $rss_mb -gt 4096 ]]; then
|
|
71
|
+
echo -e "${YELLOW} ⚠️ High memory usage: ${rss_mb}MB${NC}"
|
|
72
|
+
log "High memory process detected: PID $pid, Memory: ${rss_mb}MB"
|
|
73
|
+
|
|
74
|
+
# Ask user before killing (interactive mode)
|
|
75
|
+
if [[ -t 0 ]]; then
|
|
76
|
+
echo -n "Kill this process? (y/N): "
|
|
77
|
+
read -r response
|
|
78
|
+
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
79
|
+
kill -TERM "$pid" 2>/dev/null || true
|
|
80
|
+
sleep 2
|
|
81
|
+
kill -KILL "$pid" 2>/dev/null || true
|
|
82
|
+
echo "Process $pid terminated"
|
|
83
|
+
log "Terminated high memory process: PID $pid"
|
|
84
|
+
fi
|
|
85
|
+
else
|
|
86
|
+
# Non-interactive mode - just log
|
|
87
|
+
log "High memory process (non-interactive): PID $pid, Memory: ${rss_mb}MB"
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
done
|
|
92
|
+
fi
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
cleanup_network_resources() {
|
|
96
|
+
log "Cleaning up network resources"
|
|
97
|
+
|
|
98
|
+
# Find and close hanging network connections
|
|
99
|
+
local hanging_connections=$(netstat -tnp 2>/dev/null | grep 'ESTABLISHED' | grep 'claude' || true)
|
|
100
|
+
|
|
101
|
+
if [[ -n "$hanging_connections" ]]; then
|
|
102
|
+
local connection_count=$(echo "$hanging_connections" | wc -l)
|
|
103
|
+
echo -e "${BLUE}Found $connection_count established Claude connections${NC}"
|
|
104
|
+
|
|
105
|
+
# Just log them - don't actively close as it might disrupt valid operations
|
|
106
|
+
log "Active connections: $connection_count"
|
|
107
|
+
fi
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
trim_memory_usage() {
|
|
111
|
+
log "Triggering memory trim operations"
|
|
112
|
+
|
|
113
|
+
# Trigger garbage collection if Node.js processes are running
|
|
114
|
+
local node_pids=$(pgrep -f "node.*claude" || true)
|
|
115
|
+
|
|
116
|
+
if [[ -n "$node_pids" ]]; then
|
|
117
|
+
echo -e "${BLUE}Triggering garbage collection for Node.js processes${NC}"
|
|
118
|
+
|
|
119
|
+
while read -r pid; do
|
|
120
|
+
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
121
|
+
# Send SIGUSR2 to trigger heap dump (if the process is configured to handle it)
|
|
122
|
+
kill -USR2 "$pid" 2>/dev/null || true
|
|
123
|
+
log "Sent memory trim signal to PID $pid"
|
|
124
|
+
fi
|
|
125
|
+
done <<< "$node_pids"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Linux-specific memory operations
|
|
129
|
+
if [[ -f /proc/sys/vm/drop_caches ]]; then
|
|
130
|
+
# Note: This requires root privileges
|
|
131
|
+
if [[ $EUID -eq 0 ]]; then
|
|
132
|
+
echo -e "${BLUE}Dropping system caches${NC}"
|
|
133
|
+
sync
|
|
134
|
+
echo 3 > /proc/sys/vm/drop_caches 2>/dev/null || true
|
|
135
|
+
log "Dropped system caches"
|
|
136
|
+
else
|
|
137
|
+
echo -e "${YELLOW}System cache drop requires root privileges${NC}"
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
generate_cleanup_report() {
|
|
143
|
+
log "Generating cleanup report"
|
|
144
|
+
|
|
145
|
+
echo ""
|
|
146
|
+
echo -e "${GREEN}=== Memory Cleanup Report ===${NC}"
|
|
147
|
+
|
|
148
|
+
# Current memory status
|
|
149
|
+
if command -v free &> /dev/null; then
|
|
150
|
+
echo -e "${BLUE}Current Memory Status:${NC}"
|
|
151
|
+
free -h
|
|
152
|
+
echo ""
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
# Claude processes
|
|
156
|
+
local claude_pids=$(pgrep -f "claude" || true)
|
|
157
|
+
if [[ -n "$claude_pids" ]]; then
|
|
158
|
+
echo -e "${BLUE}Active Claude Processes:${NC}"
|
|
159
|
+
ps -p $claude_pids -o pid,pcpu,rss,etime,cmd 2>/dev/null || true
|
|
160
|
+
echo ""
|
|
161
|
+
else
|
|
162
|
+
echo -e "${GREEN}No active Claude processes found${NC}"
|
|
163
|
+
echo ""
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Temporary files
|
|
167
|
+
if [[ -d "$PROFILE_DIR" ]]; then
|
|
168
|
+
local profile_count=$(find "$PROFILE_DIR" -name "*.heapprofile" 2>/dev/null | wc -l)
|
|
169
|
+
echo -e "${BLUE}Profile files: $profile_count${NC}"
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
echo -e "${GREEN}Cleanup completed${NC}"
|
|
173
|
+
log "Cleanup report generated"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
main() {
|
|
177
|
+
echo -e "${BLUE}Starting memory cleanup...${NC}"
|
|
178
|
+
log "Memory cleanup started"
|
|
179
|
+
|
|
180
|
+
# Wait a bit to allow processes to finish naturally
|
|
181
|
+
sleep $CLEANUP_DELAY
|
|
182
|
+
|
|
183
|
+
# Perform cleanup operations
|
|
184
|
+
cleanup_temp_files
|
|
185
|
+
cleanup_zombie_processes
|
|
186
|
+
cleanup_hanging_processes
|
|
187
|
+
cleanup_network_resources
|
|
188
|
+
trim_memory_usage
|
|
189
|
+
|
|
190
|
+
# Generate final report
|
|
191
|
+
generate_cleanup_report
|
|
192
|
+
|
|
193
|
+
log "Memory cleanup completed"
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# Run main function
|
|
197
|
+
main "$@"
|
|
@@ -186,8 +186,8 @@ select_agents() {
|
|
|
186
186
|
fi
|
|
187
187
|
|
|
188
188
|
# Loop 2 validators (adaptive scaling)
|
|
189
|
-
# Standard: 3-5 files → add architect, security
|
|
190
|
-
loop2+=("architect" "security-specialist")
|
|
189
|
+
# Standard: 3-5 files → add system-architect, security
|
|
190
|
+
loop2+=("system-architect" "security-specialist")
|
|
191
191
|
|
|
192
192
|
# Complex/Enterprise: >5 files → add code-analyzer
|
|
193
193
|
if echo "$description" | grep -iq "large\|complex\|enterprise"; then
|