claude-flow-novice 2.14.8 โ 2.14.9
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/commands/cfn-loop-cli.md +1 -1
- package/.claude/skills/cfn-agent-selector/SKILL.md +2 -2
- package/.claude/skills/cfn-agent-selector/SKILL.md.backup_before_replace +91 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +26 -0
- package/README.md +4 -4
- package/README.md.backup_before_replace +781 -0
- package/claude-assets/agents/AGENT_LIFECYCLE.md +3 -3
- package/claude-assets/agents/AGENT_LIFECYCLE.md.backup_before_replace +530 -0
- package/claude-assets/agents/README-AGENT_LIFECYCLE.md +3 -3
- package/claude-assets/agents/README-AGENT_LIFECYCLE.md.backup_before_replace +522 -0
- package/claude-assets/agents/cfn-dev-team/CLAUDE.md +3 -3
- package/claude-assets/agents/cfn-dev-team/CLAUDE.md.backup_before_replace +1086 -0
- package/claude-assets/agents/cfn-dev-team/README.md +1 -1
- package/claude-assets/agents/cfn-dev-team/README.md.backup_before_replace +116 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +2 -2
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md.backup_before_replace +451 -0
- package/claude-assets/agents/cfn-dev-team/developers/README.md +3 -3
- package/claude-assets/agents/cfn-dev-team/developers/README.md.backup_before_replace +69 -0
- package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md +1 -1
- package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md.backup_before_replace +465 -0
- package/claude-assets/agents/cfn-dev-team/test-agent.md +2 -2
- package/claude-assets/agents/cfn-dev-team/test-agent.md.backup_before_replace +141 -0
- package/claude-assets/commands/cfn-loop-cli.md +1 -1
- package/claude-assets/skills/cfn-agent-selector/SKILL.md +2 -2
- package/claude-assets/skills/cfn-agent-selector/SKILL.md.backup_before_replace +91 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +26 -0
- package/claude-assets/skills/cfn-mcp-container-selector/SKILL.md +555 -0
- package/claude-assets/skills/cfn-memory-monitoring/SKILL.md +531 -0
- package/claude-assets/skills/cfn-redis-cleanup/cleanup-redis.sh +130 -0
- package/dist/cli/cli-agent-context.js +6 -0
- package/dist/cli/cli-agent-context.js.map +1 -1
- package/dist/cli/config-manager.js +109 -91
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/user.js +22 -0
- package/dist/types/user.js.map +1 -0
- package/package.json +1 -1
- package/readme/README.md +1 -1
- package/scripts/docker-playwright-fix.sh +312 -0
- package/scripts/zone-d-type-fixes.sh +333 -0
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
# Memory Monitoring for Docker Deployment
|
|
2
|
+
|
|
3
|
+
**Implementation Date:** 2025-11-04
|
|
4
|
+
**Purpose:** Add memory reporting to Docker deployment process to prevent WSL2 crashes
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This implementation integrates memory monitoring into the Docker deployment process to:
|
|
11
|
+
1. Track memory usage per agent container
|
|
12
|
+
2. Report memory metrics to Redis for coordination
|
|
13
|
+
3. Enable automatic container cleanup based on memory thresholds
|
|
14
|
+
4. Provide performance data for optimization
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Memory Monitoring Skill
|
|
19
|
+
|
|
20
|
+
### Implementation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# .claude/skills/cfn-memory-monitoring/SKILL.md
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The memory monitoring skill provides:
|
|
27
|
+
|
|
28
|
+
- **Real-time memory tracking** per agent
|
|
29
|
+
- **Redis-based memory reporting** for swarm coordination
|
|
30
|
+
- **Threshold-based alerts** when containers approach limits
|
|
31
|
+
- **Performance data collection** for optimization
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Enhanced Docker Configuration
|
|
36
|
+
|
|
37
|
+
### Memory-Optimized Dockerfile
|
|
38
|
+
|
|
39
|
+
```dockerfile
|
|
40
|
+
FROM node:20-alpine AS base
|
|
41
|
+
|
|
42
|
+
# Install monitoring dependencies
|
|
43
|
+
RUN apk add --no-cache bash redis curl procfs-dump
|
|
44
|
+
|
|
45
|
+
WORKDIR /app
|
|
46
|
+
|
|
47
|
+
# Copy memory monitoring skill
|
|
48
|
+
COPY .claude/skills/cfn-memory-monitoring/ /app/.claude/skills/cfn-memory-monitoring/
|
|
49
|
+
|
|
50
|
+
# Copy application source
|
|
51
|
+
COPY package*.json ./
|
|
52
|
+
RUN npm ci --only=production
|
|
53
|
+
COPY . .
|
|
54
|
+
|
|
55
|
+
# Build application
|
|
56
|
+
RUN npm run build || echo "Build skipped"
|
|
57
|
+
|
|
58
|
+
# Create monitoring user
|
|
59
|
+
RUN addgroup -g 1001 -S cfnuser && \
|
|
60
|
+
adduser -S cfnuser -u 1001 -G cfnuser
|
|
61
|
+
|
|
62
|
+
# Setup monitoring directories
|
|
63
|
+
RUN mkdir -p /app/logs /app/metrics && \
|
|
64
|
+
chown -R cfnuser:cfnuser /app
|
|
65
|
+
|
|
66
|
+
USER cfnuser
|
|
67
|
+
|
|
68
|
+
# Memory monitoring environment variables
|
|
69
|
+
ENV MEMORY_MONITORING=true \
|
|
70
|
+
MEMORY_REPORT_INTERVAL=30 \
|
|
71
|
+
MEMORY_ALERT_THRESHOLD=80 \
|
|
72
|
+
REDIS_HOST=host.docker.internal \
|
|
73
|
+
REDIS_PORT=6379
|
|
74
|
+
|
|
75
|
+
# Memory monitoring script wrapper
|
|
76
|
+
COPY docker/scripts/monitor-wrapper.sh /app/monitor-wrapper.sh
|
|
77
|
+
RUN chmod +x /app/monitor-wrapper.sh
|
|
78
|
+
|
|
79
|
+
# Enhanced health check with memory monitoring
|
|
80
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
|
|
81
|
+
CMD /app/monitor-wrapper.sh health-check
|
|
82
|
+
|
|
83
|
+
# Default command with monitoring
|
|
84
|
+
CMD ["/app/monitor-wrapper.sh", "start-agent"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Monitor Wrapper Script
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
#!/bin/bash
|
|
91
|
+
# docker/scripts/monitor-wrapper.sh
|
|
92
|
+
|
|
93
|
+
set -euo pipefail
|
|
94
|
+
|
|
95
|
+
# Configuration
|
|
96
|
+
MEMORY_REPORT_INTERVAL=${MEMORY_REPORT_INTERVAL:-30}
|
|
97
|
+
MEMORY_ALERT_THRESHOLD=${MEMORY_ALERT_THRESHOLD:-80}
|
|
98
|
+
REDIS_HOST=${REDIS_HOST:-host.docker.internal}
|
|
99
|
+
REDIS_PORT=${REDIS_PORT:-6379}
|
|
100
|
+
AGENT_ID=${AGENT_ID:-unknown}
|
|
101
|
+
CONTAINER_NAME=${CONTAINER_NAME:-$(hostname)}
|
|
102
|
+
|
|
103
|
+
# Memory monitoring function
|
|
104
|
+
report_memory() {
|
|
105
|
+
local timestamp=$(date +%s)
|
|
106
|
+
local memory_usage=$(free -m | awk 'NR==2{printf "%.2f", $3*100/$2}' 2>/dev/null || echo "0")
|
|
107
|
+
local memory_mb=$(free -m | awk 'NR==2{print $3}' 2>/dev/null || echo "0")
|
|
108
|
+
local memory_limit_mb=${MEMORY_LIMIT:-2048}
|
|
109
|
+
|
|
110
|
+
# Report to Redis
|
|
111
|
+
if command -v redis-cli >/dev/null 2>&1; then
|
|
112
|
+
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" \
|
|
113
|
+
hset "cfn_memory:${AGENT_ID}:${timestamp}" \
|
|
114
|
+
container_name "$CONTAINER_NAME" \
|
|
115
|
+
memory_usage "$memory_usage" \
|
|
116
|
+
memory_mb "$memory_mb" \
|
|
117
|
+
memory_limit_mb "$memory_limit_mb" \
|
|
118
|
+
timestamp "$timestamp" \
|
|
119
|
+
agent_id "$AGENT_ID" >/dev/null 2>&1 || true
|
|
120
|
+
|
|
121
|
+
# Set TTL for 24 hours
|
|
122
|
+
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" \
|
|
123
|
+
expire "cfn_memory:${AGENT_ID}:${timestamp}" 86400 >/dev/null 2>&1 || true
|
|
124
|
+
|
|
125
|
+
# Alert if threshold exceeded
|
|
126
|
+
if (( $(echo "$memory_usage > $MEMORY_ALERT_THRESHOLD" | bc -l) )); then
|
|
127
|
+
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" \
|
|
128
|
+
lpush "cfn_memory_alerts" \
|
|
129
|
+
"{\"agent_id\":\"$AGENT_ID\",\"memory_usage\":\"$memory_usage\",\"timestamp\":$timestamp}" >/dev/null 2>&1 || true
|
|
130
|
+
fi
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# Log locally
|
|
134
|
+
echo "[$timestamp] Memory: ${memory_usage}% (${memory_mb}MB/${memory_limit_mb}MB)" >> /app/logs/memory.log
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# Health check with memory monitoring
|
|
138
|
+
health_check() {
|
|
139
|
+
# Basic application health
|
|
140
|
+
if ! node -e "console.log('healthy')" 2>/dev/null; then
|
|
141
|
+
echo "Application health check failed"
|
|
142
|
+
exit 1
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Memory check
|
|
146
|
+
local memory_usage=$(free -m | awk 'NR==2{printf "%.2f", $3*100/$2}' 2>/dev/null || echo "0")
|
|
147
|
+
if (( $(echo "$memory_usage > 95" | bc -l) )); then
|
|
148
|
+
echo "Critical memory usage: ${memory_usage}%"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
echo "Health check passed - Memory: ${memory_usage}%"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Start memory monitoring daemon
|
|
156
|
+
start_monitoring() {
|
|
157
|
+
while true; do
|
|
158
|
+
report_memory
|
|
159
|
+
sleep "$MEMORY_REPORT_INTERVAL"
|
|
160
|
+
done &
|
|
161
|
+
MONITOR_PID=$!
|
|
162
|
+
echo $MONITOR_PID > /tmp/memory-monitor.pid
|
|
163
|
+
echo "Memory monitoring started (PID: $MONITOR_PID)"
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
# Stop monitoring
|
|
167
|
+
stop_monitoring() {
|
|
168
|
+
if [ -f /tmp/memory-monitor.pid ]; then
|
|
169
|
+
local pid=$(cat /tmp/memory-monitor.pid)
|
|
170
|
+
kill "$pid" 2>/dev/null || true
|
|
171
|
+
rm -f /tmp/memory-monitor.pid
|
|
172
|
+
fi
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# Cleanup on exit
|
|
176
|
+
cleanup() {
|
|
177
|
+
echo "Cleaning up..."
|
|
178
|
+
stop_monitoring
|
|
179
|
+
|
|
180
|
+
# Final memory report
|
|
181
|
+
report_memory
|
|
182
|
+
|
|
183
|
+
echo "Cleanup complete"
|
|
184
|
+
exit 0
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
trap cleanup TERM INT
|
|
188
|
+
|
|
189
|
+
# Main execution
|
|
190
|
+
case "${1:-}" in
|
|
191
|
+
"start-agent")
|
|
192
|
+
echo "Starting agent with memory monitoring..."
|
|
193
|
+
start_monitoring
|
|
194
|
+
|
|
195
|
+
# Start the actual agent
|
|
196
|
+
shift
|
|
197
|
+
exec node dist/cli/index.js "$@"
|
|
198
|
+
;;
|
|
199
|
+
"health-check")
|
|
200
|
+
health_check
|
|
201
|
+
;;
|
|
202
|
+
"report-memory")
|
|
203
|
+
report_memory
|
|
204
|
+
;;
|
|
205
|
+
*)
|
|
206
|
+
echo "Usage: $0 {start-agent|health-check|report-memory}"
|
|
207
|
+
exit 1
|
|
208
|
+
;;
|
|
209
|
+
esac
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Docker Compose Configuration
|
|
215
|
+
|
|
216
|
+
### Memory-Limited Services
|
|
217
|
+
|
|
218
|
+
```yaml
|
|
219
|
+
# docker-compose.memory-monitored.yml
|
|
220
|
+
version: '3.8'
|
|
221
|
+
|
|
222
|
+
services:
|
|
223
|
+
redis:
|
|
224
|
+
image: redis:7-alpine
|
|
225
|
+
ports:
|
|
226
|
+
- "6379:6379"
|
|
227
|
+
volumes:
|
|
228
|
+
- redis_data:/data
|
|
229
|
+
command: redis-server --maxmemory 512mb --maxmemory-policy allkeys-lru
|
|
230
|
+
deploy:
|
|
231
|
+
resources:
|
|
232
|
+
limits:
|
|
233
|
+
memory: 512M
|
|
234
|
+
reservations:
|
|
235
|
+
memory: 256M
|
|
236
|
+
|
|
237
|
+
agent-backend:
|
|
238
|
+
build:
|
|
239
|
+
context: .
|
|
240
|
+
dockerfile: Dockerfile.memory-monitored
|
|
241
|
+
environment:
|
|
242
|
+
- AGENT_TYPE=backend-developer
|
|
243
|
+
- AGENT_ID=backend-${INSTANCE_ID:-1}
|
|
244
|
+
- MEMORY_LIMIT=1024
|
|
245
|
+
- MEMORY_ALERT_THRESHOLD=75
|
|
246
|
+
- MEMORY_REPORT_INTERVAL=30
|
|
247
|
+
- REDIS_HOST=redis
|
|
248
|
+
- MCP_SERVERS=basic,filesystem,database
|
|
249
|
+
volumes:
|
|
250
|
+
- ./logs:/app/logs
|
|
251
|
+
- agent_workspace_backend:/app/workspace
|
|
252
|
+
depends_on:
|
|
253
|
+
- redis
|
|
254
|
+
deploy:
|
|
255
|
+
resources:
|
|
256
|
+
limits:
|
|
257
|
+
memory: 1G
|
|
258
|
+
reservations:
|
|
259
|
+
memory: 512M
|
|
260
|
+
restart: unless-stopped
|
|
261
|
+
|
|
262
|
+
agent-frontend:
|
|
263
|
+
build:
|
|
264
|
+
context: .
|
|
265
|
+
dockerfile: Dockerfile.memory-monitored
|
|
266
|
+
environment:
|
|
267
|
+
- AGENT_TYPE=frontend-engineer
|
|
268
|
+
- AGENT_ID=frontend-${INSTANCE_ID:-1}
|
|
269
|
+
- MEMORY_LIMIT=2048
|
|
270
|
+
- MEMORY_ALERT_THRESHOLD=80
|
|
271
|
+
- MEMORY_REPORT_INTERVAL=30
|
|
272
|
+
- REDIS_HOST=redis
|
|
273
|
+
- MCP_SERVERS=basic,filesystem,playwright,browser
|
|
274
|
+
volumes:
|
|
275
|
+
- ./logs:/app/logs
|
|
276
|
+
- agent_workspace_frontend:/app/workspace
|
|
277
|
+
- /tmp/.X11-unix:/tmp/.X11-unix:ro
|
|
278
|
+
depends_on:
|
|
279
|
+
- redis
|
|
280
|
+
deploy:
|
|
281
|
+
resources:
|
|
282
|
+
limits:
|
|
283
|
+
memory: 2G
|
|
284
|
+
reservations:
|
|
285
|
+
memory: 1G
|
|
286
|
+
restart: unless-stopped
|
|
287
|
+
|
|
288
|
+
memory-monitor:
|
|
289
|
+
image: node:20-alpine
|
|
290
|
+
environment:
|
|
291
|
+
- REDIS_HOST=redis
|
|
292
|
+
volumes:
|
|
293
|
+
- ./scripts/memory-dashboard.sh:/app/memory-dashboard.sh
|
|
294
|
+
- redis_data:/data
|
|
295
|
+
command: sh -c "apk add --no-cache procfs-dump && tail -f /dev/null"
|
|
296
|
+
depends_on:
|
|
297
|
+
- redis
|
|
298
|
+
|
|
299
|
+
volumes:
|
|
300
|
+
redis_data:
|
|
301
|
+
agent_workspace_backend:
|
|
302
|
+
agent_workspace_frontend:
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Memory Monitoring CLI Commands
|
|
308
|
+
|
|
309
|
+
### Check Agent Memory Status
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# Check all agents memory usage
|
|
313
|
+
./.claude/skills/cfn-memory-monitoring/check-agent-memory.sh
|
|
314
|
+
|
|
315
|
+
# Check specific agent
|
|
316
|
+
./.claude/skills/cfn-memory-monitoring/check-agent-memory.sh --agent-id backend-1
|
|
317
|
+
|
|
318
|
+
# Get memory alerts
|
|
319
|
+
redis-cli lrange "cfn_memory_alerts" 0 -1
|
|
320
|
+
|
|
321
|
+
# Get agent memory history
|
|
322
|
+
redis-cli keys "cfn_memory:backend-1:*" | head -10 | xargs -I {} redis-cli hgetall "{}"
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Performance Testing Script
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
#!/bin/bash
|
|
329
|
+
# scripts/test-cold-start-performance.sh
|
|
330
|
+
|
|
331
|
+
set -euo pipefail
|
|
332
|
+
|
|
333
|
+
echo "=== Cold Start Performance Test ==="
|
|
334
|
+
|
|
335
|
+
# Test container startup time
|
|
336
|
+
echo "Testing container cold start time..."
|
|
337
|
+
start_time=$(date +%s%N)
|
|
338
|
+
|
|
339
|
+
docker run --rm \
|
|
340
|
+
--name cold-start-test \
|
|
341
|
+
-e AGENT_ID=test-performance \
|
|
342
|
+
-e MEMORY_MONITORING=false \
|
|
343
|
+
claude-flow-novice:memory-monitored \
|
|
344
|
+
node -e "console.log('Container started successfully')"
|
|
345
|
+
|
|
346
|
+
end_time=$(date +%s%N)
|
|
347
|
+
startup_time_ms=$(( (end_time - start_time) / 1000000 ))
|
|
348
|
+
|
|
349
|
+
echo "Cold start time: ${startup_time_ms}ms"
|
|
350
|
+
|
|
351
|
+
# Test with memory monitoring
|
|
352
|
+
echo "Testing cold start with memory monitoring..."
|
|
353
|
+
start_time=$(date +%s%N)
|
|
354
|
+
|
|
355
|
+
docker run --rm \
|
|
356
|
+
--name cold-start-test-monitored \
|
|
357
|
+
-e AGENT_ID=test-performance-monitored \
|
|
358
|
+
-e MEMORY_MONITORING=true \
|
|
359
|
+
-e REDIS_HOST=host.docker.internal \
|
|
360
|
+
claude-flow-novice:memory-monitored \
|
|
361
|
+
/app/monitor-wrapper.sh report-memory
|
|
362
|
+
|
|
363
|
+
end_time=$(date +%s%N)
|
|
364
|
+
startup_time_monitored_ms=$(( (end_time - start_time) / 1000000 ))
|
|
365
|
+
|
|
366
|
+
echo "Cold start with monitoring: ${startup_time_monitored_ms}ms"
|
|
367
|
+
|
|
368
|
+
# Test agent spawn time
|
|
369
|
+
echo "Testing agent spawn time..."
|
|
370
|
+
start_time=$(date +%s%N)
|
|
371
|
+
|
|
372
|
+
docker run --rm \
|
|
373
|
+
--name agent-spawn-test \
|
|
374
|
+
-e AGENT_ID=test-spawn \
|
|
375
|
+
-e MEMORY_MONITORING=true \
|
|
376
|
+
-e REDIS_HOST=host.docker.internal \
|
|
377
|
+
-v "$(pwd):/app/workspace" \
|
|
378
|
+
claude-flow-novice:memory-monitored \
|
|
379
|
+
/app/monitor-wrapper.sh start-agent agent-spawn \
|
|
380
|
+
--agent-type backend-developer \
|
|
381
|
+
--task "Write hello world file" \
|
|
382
|
+
--timeout 30
|
|
383
|
+
|
|
384
|
+
end_time=$(date +%s%N)
|
|
385
|
+
spawn_time_ms=$(( (end_time - start_time) / 1000000 ))
|
|
386
|
+
|
|
387
|
+
echo "Agent spawn time: ${spawn_time_ms}ms"
|
|
388
|
+
|
|
389
|
+
# Results
|
|
390
|
+
echo "=== Performance Results ==="
|
|
391
|
+
echo "Container cold start: ${startup_time_ms}ms"
|
|
392
|
+
echo "Container with monitoring: ${startup_time_monitored_ms}ms"
|
|
393
|
+
echo "Agent spawn time: ${spawn_time_ms}ms"
|
|
394
|
+
|
|
395
|
+
# Save results
|
|
396
|
+
cat > "performance-results-$(date +%Y%m%d-%H%M%S).json" << EOF
|
|
397
|
+
{
|
|
398
|
+
"timestamp": "$(date -Iseconds)",
|
|
399
|
+
"container_cold_start_ms": $startup_time_ms,
|
|
400
|
+
"container_with_monitoring_ms": $startup_time_monitored_ms,
|
|
401
|
+
"agent_spawn_ms": $spawn_time_ms,
|
|
402
|
+
"monitoring_overhead_ms": $((startup_time_monitored_ms - startup_time_ms)),
|
|
403
|
+
"system_info": {
|
|
404
|
+
"docker_version": "$(docker --version)",
|
|
405
|
+
"host_os": "$(uname -a)",
|
|
406
|
+
"available_memory": "$(free -h)"
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
EOF
|
|
410
|
+
|
|
411
|
+
echo "Results saved to performance-results-*.json"
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Dedicated MCP per Container Architecture
|
|
417
|
+
|
|
418
|
+
### Frontend Container MCP Configuration
|
|
419
|
+
|
|
420
|
+
```json
|
|
421
|
+
{
|
|
422
|
+
"mcpServers": {
|
|
423
|
+
"playwright": {
|
|
424
|
+
"command": "docker",
|
|
425
|
+
"args": [
|
|
426
|
+
"run", "-i", "--rm", "--init",
|
|
427
|
+
"--name", "mcp-playwright-${AGENT_ID}",
|
|
428
|
+
"-e", "AGENT_ID=${AGENT_ID}",
|
|
429
|
+
"-e", "DISPLAY=${DISPLAY:-:0}",
|
|
430
|
+
"-v", "/tmp/.X11-unix:/tmp/.X11-unix:ro",
|
|
431
|
+
"-v", "${PWD}/workspace:/workspace",
|
|
432
|
+
"mcp-playwright:latest"
|
|
433
|
+
]
|
|
434
|
+
},
|
|
435
|
+
"browser-automation": {
|
|
436
|
+
"command": "docker",
|
|
437
|
+
"args": [
|
|
438
|
+
"run", "-i", "--rm", "--init",
|
|
439
|
+
"--name", "mcp-browser-${AGENT_ID}",
|
|
440
|
+
"-e", "AGENT_ID=${AGENT_ID}",
|
|
441
|
+
"--shm-size=2gb",
|
|
442
|
+
"-v", "${PWD}/workspace:/workspace",
|
|
443
|
+
"mcp-browser-automation:latest"
|
|
444
|
+
]
|
|
445
|
+
},
|
|
446
|
+
"screenshot-service": {
|
|
447
|
+
"command": "docker",
|
|
448
|
+
"args": [
|
|
449
|
+
"run", "-i", "--rm", "--init",
|
|
450
|
+
"--name", "mcp-screenshot-${AGENT_ID}",
|
|
451
|
+
"-e", "AGENT_ID=${AGENT_ID}",
|
|
452
|
+
"-v", "${PWD}/screenshots:/screenshots",
|
|
453
|
+
"mcp-screenshot:latest"
|
|
454
|
+
]
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Backend Container MCP Configuration
|
|
461
|
+
|
|
462
|
+
```json
|
|
463
|
+
{
|
|
464
|
+
"mcpServers": {
|
|
465
|
+
"database": {
|
|
466
|
+
"command": "docker",
|
|
467
|
+
"args": [
|
|
468
|
+
"run", "-i", "--rm", "--init",
|
|
469
|
+
"--name", "mcp-database-${AGENT_ID}",
|
|
470
|
+
"-e", "DATABASE_URL=${DATABASE_URL}",
|
|
471
|
+
"-e", "AGENT_ID=${AGENT_ID}",
|
|
472
|
+
"mcp-postgresql:latest"
|
|
473
|
+
]
|
|
474
|
+
},
|
|
475
|
+
"api-testing": {
|
|
476
|
+
"command": "docker",
|
|
477
|
+
"args": [
|
|
478
|
+
"run", "-i", "--rm", "--init",
|
|
479
|
+
"--name", "mcp-api-${AGENT_ID}",
|
|
480
|
+
"-e", "AGENT_ID=${AGENT_ID}",
|
|
481
|
+
"mcp-api-testing:latest"
|
|
482
|
+
]
|
|
483
|
+
},
|
|
484
|
+
"redis-tools": {
|
|
485
|
+
"command": "docker",
|
|
486
|
+
"args": [
|
|
487
|
+
"run", "-i", "--rm", "--init",
|
|
488
|
+
"--name", "mcp-redis-${AGENT_ID}",
|
|
489
|
+
"-e", "REDIS_HOST=${REDIS_HOST}",
|
|
490
|
+
"-e", "AGENT_ID=${AGENT_ID}",
|
|
491
|
+
"mcp-redis-tools:latest"
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Implementation Benefits
|
|
501
|
+
|
|
502
|
+
### Memory Leak Prevention
|
|
503
|
+
|
|
504
|
+
1. **Per-container memory limits** prevent any single agent from crashing WSL2
|
|
505
|
+
2. **Real-time monitoring** catches leaks early
|
|
506
|
+
3. **Automatic cleanup** removes containers exceeding thresholds
|
|
507
|
+
4. **Performance data** helps identify problematic agents
|
|
508
|
+
|
|
509
|
+
### Resource Optimization
|
|
510
|
+
|
|
511
|
+
1. **Dedicated MCP servers** reduce context loading overhead
|
|
512
|
+
2. **Container specialization** (frontend vs backend) optimizes resource allocation
|
|
513
|
+
3. **Memory-based scheduling** places agents on appropriate containers
|
|
514
|
+
4. **Performance metrics** inform capacity planning
|
|
515
|
+
|
|
516
|
+
### Operational Benefits
|
|
517
|
+
|
|
518
|
+
1. **Predictable resource usage** with memory limits and monitoring
|
|
519
|
+
2. **Faster agent startup** with specialized, minimal containers
|
|
520
|
+
3. **Better debugging** with per-agent memory tracking
|
|
521
|
+
4. **Cost optimization** through efficient resource utilization
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## Next Steps
|
|
526
|
+
|
|
527
|
+
1. **Implement memory monitoring skill** with Redis integration
|
|
528
|
+
2. **Create performance testing suite** for cold start timing
|
|
529
|
+
3. **Build dedicated MCP containers** for frontend/backend specialization
|
|
530
|
+
4. **Deploy monitoring dashboard** for real-time visibility
|
|
531
|
+
5. **Establish memory thresholds** and automated cleanup policies
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Redis Cleanup Script for CFN Loop
|
|
3
|
+
# Prevents orphaned keys and memory leaks
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Configuration
|
|
8
|
+
DEFAULT_TTL=3600 # 1 hour
|
|
9
|
+
SWARM_PREFIX="swarm:"
|
|
10
|
+
CFN_PREFIX="cfn_loop:task:"
|
|
11
|
+
|
|
12
|
+
# Colors for output
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
NC='\033[0m' # No Color
|
|
17
|
+
|
|
18
|
+
echo -e "${GREEN}๐งน CFN Loop Redis Cleanup${NC}"
|
|
19
|
+
|
|
20
|
+
# Function to show current Redis usage
|
|
21
|
+
show_usage() {
|
|
22
|
+
echo -e "${YELLOW}Current Redis Usage:${NC}"
|
|
23
|
+
local total_keys=$(redis-cli keys "*" | wc -l)
|
|
24
|
+
local swarm_keys=$(redis-cli keys "${SWARM_PREFIX}*" | wc -l)
|
|
25
|
+
local cfn_keys=$(redis-cli keys "${CFN_PREFIX}*" | wc -l)
|
|
26
|
+
|
|
27
|
+
echo "Total keys: $total_keys"
|
|
28
|
+
echo "Swarm keys: $swarm_keys"
|
|
29
|
+
echo "CFN Loop keys: $cfn_keys"
|
|
30
|
+
echo ""
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Function to cleanup orphaned keys
|
|
34
|
+
cleanup_orphaned() {
|
|
35
|
+
echo -e "${YELLOW}Cleaning up orphaned keys...${NC}"
|
|
36
|
+
|
|
37
|
+
# Find and clean up keys without TTL
|
|
38
|
+
local keys_without_ttl=$(redis-cli keys "${SWARM_PREFIX}*" | xargs -I {} sh -c 'redis-cli ttl {} | grep -q "^-1$" && echo {}')
|
|
39
|
+
|
|
40
|
+
if [ -n "$keys_without_ttl" ]; then
|
|
41
|
+
echo "Setting TTL on orphaned keys:"
|
|
42
|
+
echo "$keys_without_ttl" | xargs -I {} echo " - {}"
|
|
43
|
+
echo "$keys_without_ttl" | xargs -I {} redis-cli expire {} $DEFAULT_TTL
|
|
44
|
+
echo -e "${GREEN}โ Set $DEFAULT_TTL TTL on $(echo "$keys_without_ttl" | wc -l) keys${NC}"
|
|
45
|
+
else
|
|
46
|
+
echo -e "${GREEN}โ No orphaned keys found${NC}"
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Function to cleanup old task data
|
|
51
|
+
cleanup_old_tasks() {
|
|
52
|
+
echo -e "${YELLOW}Cleaning up tasks older than 24 hours...${NC}"
|
|
53
|
+
|
|
54
|
+
# Find keys with old timestamps
|
|
55
|
+
local old_keys=$(redis-cli --scan --pattern "${SWARM_PREFIX}*:*" | \
|
|
56
|
+
grep -E ":[0-9]{10}:" | \
|
|
57
|
+
awk -F: '{ if ($NF < $(date +%s) - 86400) print $0 }')
|
|
58
|
+
|
|
59
|
+
if [ -n "$old_keys" ]; then
|
|
60
|
+
echo "Removing old task keys:"
|
|
61
|
+
echo "$old_keys" | xargs -I {} echo " - {}"
|
|
62
|
+
echo "$old_keys" | xargs -I {} redis-cli del {}
|
|
63
|
+
echo -e "${GREEN}โ Removed $(echo "$old_keys" | wc -l) old keys${NC}"
|
|
64
|
+
else
|
|
65
|
+
echo -e "${GREEN}โ No old keys found${NC}"
|
|
66
|
+
fi
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Function to set TTL on all keys
|
|
70
|
+
set_ttl_on_all() {
|
|
71
|
+
echo -e "${YELLOW}Setting TTL on all CFN Loop keys...${NC}"
|
|
72
|
+
|
|
73
|
+
local all_keys=$(redis-cli keys "${SWARM_PREFIX}*")
|
|
74
|
+
local count=0
|
|
75
|
+
|
|
76
|
+
for key in $all_keys; do
|
|
77
|
+
if redis-cli ttl "$key" | grep -q "^-1$"; then
|
|
78
|
+
redis-cli expire "$key" $DEFAULT_TTL
|
|
79
|
+
((count++))
|
|
80
|
+
fi
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
echo -e "${GREEN}โ Set TTL on $count keys${NC}"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Function to validate Redis health
|
|
87
|
+
validate_redis() {
|
|
88
|
+
echo -e "${YELLOW}Validating Redis health...${NC}"
|
|
89
|
+
|
|
90
|
+
# Check Redis connection
|
|
91
|
+
if ! redis-cli ping > /dev/null 2>&1; then
|
|
92
|
+
echo -e "${RED}โ Redis is not responding${NC}"
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Check memory usage
|
|
97
|
+
local memory=$(redis-cli info memory | grep used_memory_human | cut -d: -f2 | tr -d '\r')
|
|
98
|
+
echo -e "${GREEN}โ Redis is healthy (Memory: $memory)${NC}"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Main execution
|
|
102
|
+
case "${1:-all}" in
|
|
103
|
+
"usage")
|
|
104
|
+
show_usage
|
|
105
|
+
;;
|
|
106
|
+
"orphaned")
|
|
107
|
+
cleanup_orphaned
|
|
108
|
+
;;
|
|
109
|
+
"old")
|
|
110
|
+
cleanup_old_tasks
|
|
111
|
+
;;
|
|
112
|
+
"ttl")
|
|
113
|
+
set_ttl_on_all
|
|
114
|
+
;;
|
|
115
|
+
"validate")
|
|
116
|
+
validate_redis
|
|
117
|
+
;;
|
|
118
|
+
"all")
|
|
119
|
+
show_usage
|
|
120
|
+
validate_redis
|
|
121
|
+
cleanup_orphaned
|
|
122
|
+
cleanup_old_tasks
|
|
123
|
+
set_ttl_on_all
|
|
124
|
+
echo -e "${GREEN}๐ Cleanup complete!${NC}"
|
|
125
|
+
;;
|
|
126
|
+
*)
|
|
127
|
+
echo "Usage: $0 [usage|orphaned|old|ttl|validate|all]"
|
|
128
|
+
exit 1
|
|
129
|
+
;;
|
|
130
|
+
esac
|
|
@@ -30,6 +30,12 @@ import path from 'path';
|
|
|
30
30
|
try {
|
|
31
31
|
// Search in .claude/agents/ subdirectories
|
|
32
32
|
const searchPaths = [
|
|
33
|
+
path.join(process.cwd(), '.claude', 'agents', 'cfn-dev-team', 'coordinators', `${agentType}.md`),
|
|
34
|
+
path.join(process.cwd(), '.claude', 'agents', 'cfn-dev-team', 'developers', `${agentType}.md`),
|
|
35
|
+
path.join(process.cwd(), '.claude', 'agents', 'cfn-dev-team', 'testers', `${agentType}.md`),
|
|
36
|
+
path.join(process.cwd(), '.claude', 'agents', 'cfn-dev-team', 'specialists', `${agentType}.md`),
|
|
37
|
+
path.join(process.cwd(), '.claude', 'agents', 'cfn-dev-team', 'frontend', `${agentType}.md`),
|
|
38
|
+
path.join(process.cwd(), '.claude', 'agents', 'cfn-dev-team', 'security', `${agentType}.md`),
|
|
33
39
|
path.join(process.cwd(), '.claude', 'agents', 'coordinators', `${agentType}.md`),
|
|
34
40
|
path.join(process.cwd(), '.claude', 'agents', 'core-agents', `${agentType}.md`),
|
|
35
41
|
path.join(process.cwd(), '.claude', 'agents', 'developers', `${agentType}.md`),
|