claude-flow-novice 2.14.31 → 2.14.33
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/.claude/skills/pre-edit-backup/backup.sh +107 -0
- 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/coordinators/cfn-v3-coordinator.md +71 -9
- 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-redis-data-extraction/SKILL.md +442 -0
- package/claude-assets/skills/cfn-redis-data-extraction/extract.sh +306 -0
- package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +2 -2
- package/claude-assets/skills/hook-pipeline/security-scanner.sh +102 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh +107 -0
- 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 +22 -5
- package/scripts/deploy-production.sh +356 -0
- package/scripts/memory-leak-prevention.sh +306 -0
|
@@ -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 "$@"
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-redis-data-extraction
|
|
3
|
+
description: Extract complete Redis coordination data from completed CFN Loop tasks and structure into comprehensive JSON analysis files
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
author: CFN System
|
|
6
|
+
category: coordination
|
|
7
|
+
tags: [cfn, redis, data-extraction, coordination, loop-analysis]
|
|
8
|
+
|
|
9
|
+
# CFN Redis Data Extraction Skill
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
|
|
13
|
+
Extracts complete Redis coordination data from completed CFN Loop tasks and structures it into comprehensive JSON files for analysis, auditing, and performance tracking.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- **Mandatory**: Execute after each completed CFN Loop task
|
|
18
|
+
- **Timing**: After Product Owner decision, before Redis cleanup
|
|
19
|
+
- **Trigger**: Main Chat coordination after loop completion
|
|
20
|
+
- **Scope**: All Redis keys for a specific task ID
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Extract data from completed CFN Loop
|
|
26
|
+
npx claude-flow-novice skill cfn-redis-data-extraction --task-id "cfn-cli-XXXXXXX-XXXXX"
|
|
27
|
+
|
|
28
|
+
# Extract with custom output directory
|
|
29
|
+
npx claude-flow-novice skill cfn-redis-data-extraction \
|
|
30
|
+
--task-id "cfn-cli-XXXXXXX-XXXXX" \
|
|
31
|
+
--output-dir "./analysis/loop-data"
|
|
32
|
+
|
|
33
|
+
# Extract multiple tasks
|
|
34
|
+
npx claude-flow-novice skill cfn-redis-data-extraction \
|
|
35
|
+
--task-ids "cfn-cli-XXXXXXX-XXXXX,cfn-cli-YYYYYYY-YYYYY"
|
|
36
|
+
|
|
37
|
+
# Extract with detailed performance metrics
|
|
38
|
+
npx claude-flow-novice skill cfn-redis-data-extraction \
|
|
39
|
+
--task-id "cfn-cli-XXXXXXX-XXXXX" \
|
|
40
|
+
--include-performance=true
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Implementation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
#!/bin/bash
|
|
47
|
+
# CFN Redis Data Extraction Script
|
|
48
|
+
|
|
49
|
+
set -euo pipefail
|
|
50
|
+
|
|
51
|
+
# Default values
|
|
52
|
+
OUTPUT_DIR="./analysis/cfn-loop-data"
|
|
53
|
+
INCLUDE_PERFORMANCE=false
|
|
54
|
+
TASK_IDS=()
|
|
55
|
+
VERBOSE=false
|
|
56
|
+
|
|
57
|
+
# Parse arguments
|
|
58
|
+
while [[ $# -gt 0 ]]; do
|
|
59
|
+
case $1 in
|
|
60
|
+
--task-id)
|
|
61
|
+
TASK_IDS+=("$2")
|
|
62
|
+
shift 2
|
|
63
|
+
;;
|
|
64
|
+
--task-ids)
|
|
65
|
+
IFS=',' read -ra TASK_IDS <<< "$2"
|
|
66
|
+
shift 2
|
|
67
|
+
;;
|
|
68
|
+
--output-dir)
|
|
69
|
+
OUTPUT_DIR="$2"
|
|
70
|
+
shift 2
|
|
71
|
+
;;
|
|
72
|
+
--include-performance)
|
|
73
|
+
INCLUDE_PERFORMANCE=true
|
|
74
|
+
shift
|
|
75
|
+
;;
|
|
76
|
+
--verbose)
|
|
77
|
+
VERBOSE=true
|
|
78
|
+
shift
|
|
79
|
+
;;
|
|
80
|
+
-h|--help)
|
|
81
|
+
echo "Usage: $0 --task-id <TASK_ID> [--output-dir <DIR>] [--include-performance] [--verbose]"
|
|
82
|
+
exit 0
|
|
83
|
+
;;
|
|
84
|
+
*)
|
|
85
|
+
echo "Unknown option: $1"
|
|
86
|
+
exit 1
|
|
87
|
+
;;
|
|
88
|
+
esac
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
# Validate required arguments
|
|
92
|
+
if [[ ${#TASK_IDS[@]} -eq 0 ]]; then
|
|
93
|
+
echo "Error: --task-id or --task-ids is required"
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Create output directory
|
|
98
|
+
mkdir -p "$OUTPUT_DIR"
|
|
99
|
+
|
|
100
|
+
# Redis connection check
|
|
101
|
+
if ! redis-cli ping > /dev/null 2>&1; then
|
|
102
|
+
echo "Error: Redis is not accessible"
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Function to extract task data
|
|
107
|
+
extract_task_data() {
|
|
108
|
+
local task_id="$1"
|
|
109
|
+
local output_file="$OUTPUT_DIR/cfn-loop-${task_id}-extracted.json"
|
|
110
|
+
|
|
111
|
+
[[ "$VERBOSE" == true ]] && echo "Extracting data for task: $task_id"
|
|
112
|
+
|
|
113
|
+
# Get all Redis keys for the task
|
|
114
|
+
local redis_keys
|
|
115
|
+
redis_keys=$(redis-cli keys "*${task_id}*" 2>/dev/null | sort)
|
|
116
|
+
|
|
117
|
+
if [[ -z "$redis_keys" ]]; then
|
|
118
|
+
echo "Warning: No Redis keys found for task: $task_id"
|
|
119
|
+
return 1
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Initialize JSON structure
|
|
123
|
+
local json_data
|
|
124
|
+
json_data=$(cat << EOF
|
|
125
|
+
{
|
|
126
|
+
"task_id": "$task_id",
|
|
127
|
+
"extraction_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
128
|
+
"extraction_version": "1.0.0",
|
|
129
|
+
"redis_keys_analyzed": $(echo "$redis_keys" | wc -l),
|
|
130
|
+
"agents": {},
|
|
131
|
+
"metadata": {},
|
|
132
|
+
"summary": {}
|
|
133
|
+
}
|
|
134
|
+
EOF
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Process each Redis key
|
|
138
|
+
local agent_count=0
|
|
139
|
+
local completion_signals=0
|
|
140
|
+
local total_confidence=0
|
|
141
|
+
local confidence_count=0
|
|
142
|
+
|
|
143
|
+
while IFS= read -r key; do
|
|
144
|
+
[[ -z "$key" ]] && continue
|
|
145
|
+
|
|
146
|
+
# Skip if not a swarm key
|
|
147
|
+
[[ ! "$key" =~ ^swarm: ]] && continue
|
|
148
|
+
|
|
149
|
+
# Extract agent information from key
|
|
150
|
+
local agent_type=""
|
|
151
|
+
local agent_id=""
|
|
152
|
+
local loop_number=""
|
|
153
|
+
local data_type=""
|
|
154
|
+
|
|
155
|
+
if [[ "$key" =~ ^swarm:([^:]+):([^:]+):([^:]+)$ ]]; then
|
|
156
|
+
agent_id="${BASH_REMATCH[2]}"
|
|
157
|
+
data_type="${BASH_REMATCH[3]}"
|
|
158
|
+
|
|
159
|
+
# Determine agent type and loop
|
|
160
|
+
if [[ "$agent_id" =~ ^cfn-v3-coordinator ]]; then
|
|
161
|
+
agent_type="coordinator"
|
|
162
|
+
loop_number="coordination"
|
|
163
|
+
elif [[ "$agent_id" =~ -validation$ ]]; then
|
|
164
|
+
agent_type="${agent_id%-validation}"
|
|
165
|
+
loop_number="2"
|
|
166
|
+
elif [[ "$agent_id" =~ -1$ ]] || [[ "$agent_id" =~ -2$ ]] || [[ "$agent_id" =~ -3$ ]]; then
|
|
167
|
+
agent_type="${agent_id%-1}"
|
|
168
|
+
agent_type="${agent_type%-2}"
|
|
169
|
+
agent_type="${agent_type%-3}"
|
|
170
|
+
loop_number="3"
|
|
171
|
+
elif [[ "$agent_id" =~ product-owner$ ]]; then
|
|
172
|
+
agent_type="product-owner"
|
|
173
|
+
loop_number="4"
|
|
174
|
+
else
|
|
175
|
+
agent_type="$agent_id"
|
|
176
|
+
loop_number="unknown"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Initialize agent in JSON if not exists
|
|
180
|
+
if [[ ! "$json_data" =~ "\"$agent_id\":" ]]; then
|
|
181
|
+
((agent_count++))
|
|
182
|
+
json_data=$(echo "$json_data" | jq ".agents += {\"$agent_id\": {\"agent_type\": \"$agent_type\", \"loop\": \"$loop_number\", \"data\": {}}}")
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# Extract data based on type
|
|
186
|
+
case "$data_type" in
|
|
187
|
+
"confidence")
|
|
188
|
+
local confidence
|
|
189
|
+
confidence=$(redis-cli get "$key" 2>/dev/null || echo "null")
|
|
190
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].confidence = $confidence")
|
|
191
|
+
total_confidence=$(echo "$total_confidence + $confidence" | bc -l 2>/dev/null || echo "$total_confidence")
|
|
192
|
+
((confidence_count++))
|
|
193
|
+
;;
|
|
194
|
+
"done")
|
|
195
|
+
local completion_signal
|
|
196
|
+
completion_signal=$(redis-cli lrange "$key" 0 -1 2>/dev/null | head -1 || echo "null")
|
|
197
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].completion_signal = \"$completion_signal\"")
|
|
198
|
+
((completion_signals++))
|
|
199
|
+
;;
|
|
200
|
+
"messages")
|
|
201
|
+
local messages_json="[]"
|
|
202
|
+
local message_count
|
|
203
|
+
message_count=$(redis-cli llen "$key" 2>/dev/null || echo "0")
|
|
204
|
+
|
|
205
|
+
if [[ "$message_count" -gt 0 ]]; then
|
|
206
|
+
messages_json=$(redis-cli lrange "$key" 0 -1 2>/dev/null | jq -R . | jq -s .)
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].messages = $messages_json")
|
|
210
|
+
;;
|
|
211
|
+
"result")
|
|
212
|
+
local result
|
|
213
|
+
result=$(redis-cli get "$key" 2>/dev/null || echo "null")
|
|
214
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].result = \"$result\"")
|
|
215
|
+
;;
|
|
216
|
+
esac
|
|
217
|
+
fi
|
|
218
|
+
done <<< "$redis_keys"
|
|
219
|
+
|
|
220
|
+
# Calculate averages and summary
|
|
221
|
+
local avg_confidence="0"
|
|
222
|
+
if [[ "$confidence_count" -gt 0 ]]; then
|
|
223
|
+
avg_confidence=$(echo "scale=3; $total_confidence / $confidence_count" | bc -l)
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Extract task context if available
|
|
227
|
+
local task_context
|
|
228
|
+
task_context=$(redis-cli get "cfn_loop:task:$task_id:context" 2>/dev/null || echo "{}")
|
|
229
|
+
|
|
230
|
+
# Update summary
|
|
231
|
+
json_data=$(echo "$json_data" | jq "
|
|
232
|
+
.summary += {
|
|
233
|
+
\"total_agents\": $agent_count,
|
|
234
|
+
\"completion_signals\": $completion_signals,
|
|
235
|
+
\"average_confidence\": $avg_confidence,
|
|
236
|
+
\"confidence_scores_count\": $confidence_count,
|
|
237
|
+
\"extraction_status\": \"success\"
|
|
238
|
+
}
|
|
239
|
+
")
|
|
240
|
+
|
|
241
|
+
# Add task context
|
|
242
|
+
json_data=$(echo "$json_data" | jq ".metadata.task_context = \"$task_context\"")
|
|
243
|
+
|
|
244
|
+
# Add performance metrics if requested
|
|
245
|
+
if [[ "$INCLUDE_PERFORMANCE" == true ]]; then
|
|
246
|
+
local performance_metrics
|
|
247
|
+
performance_metrics=$(cat << EOF
|
|
248
|
+
{
|
|
249
|
+
"redis_memory_usage": $(redis-cli info memory 2>/dev/null | grep "used_memory_human" | cut -d: -f2 | tr -d '\r' || echo "\"unknown\""),
|
|
250
|
+
"redis_connected_clients": $(redis-cli info clients 2>/dev/null | grep "connected_clients" | cut -d: -f2 | tr -d '\r' || echo "0"),
|
|
251
|
+
"extraction_duration_ms": 0
|
|
252
|
+
}
|
|
253
|
+
EOF
|
|
254
|
+
)
|
|
255
|
+
json_data=$(echo "$json_data" | jq ".metadata.performance = $performance_metrics")
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
# Write to file
|
|
259
|
+
echo "$json_data" | jq '.' > "$output_file"
|
|
260
|
+
|
|
261
|
+
[[ "$VERBOSE" == true ]] && echo "Data extracted to: $output_file"
|
|
262
|
+
|
|
263
|
+
# Generate summary report
|
|
264
|
+
local summary_file="$OUTPUT_DIR/cfn-loop-${task_id}-summary.txt"
|
|
265
|
+
cat > "$summary_file" << EOF
|
|
266
|
+
CFN Loop Data Extraction Summary
|
|
267
|
+
================================
|
|
268
|
+
|
|
269
|
+
Task ID: $task_id
|
|
270
|
+
Extraction Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
271
|
+
Output File: $output_file
|
|
272
|
+
|
|
273
|
+
Statistics:
|
|
274
|
+
- Redis Keys Analyzed: $(echo "$redis_keys" | wc -l)
|
|
275
|
+
- Total Agents: $agent_count
|
|
276
|
+
- Completion Signals: $completion_signals
|
|
277
|
+
- Average Confidence: $avg_confidence
|
|
278
|
+
- Confidence Scores: $confidence_count
|
|
279
|
+
|
|
280
|
+
Agent Types:
|
|
281
|
+
$(echo "$json_data" | jq -r '.agents | to_entries[] | "- \(.key): \(.value.agent_type) (Loop \(.value.loop))"')
|
|
282
|
+
|
|
283
|
+
Status: Successfully extracted
|
|
284
|
+
EOF
|
|
285
|
+
|
|
286
|
+
[[ "$VERBOSE" == true ]] && echo "Summary report generated: $summary_file"
|
|
287
|
+
|
|
288
|
+
return 0
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
# Main execution
|
|
292
|
+
echo "CFN Redis Data Extraction Started"
|
|
293
|
+
echo "================================="
|
|
294
|
+
echo "Output Directory: $OUTPUT_DIR"
|
|
295
|
+
echo "Include Performance: $INCLUDE_PERFORMANCE"
|
|
296
|
+
echo ""
|
|
297
|
+
|
|
298
|
+
# Process each task
|
|
299
|
+
for task_id in "${TASK_IDS[@]}"; do
|
|
300
|
+
echo "Processing task: $task_id"
|
|
301
|
+
if extract_task_data "$task_id"; then
|
|
302
|
+
echo "✅ Successfully extracted data for: $task_id"
|
|
303
|
+
else
|
|
304
|
+
echo "❌ Failed to extract data for: $task_id"
|
|
305
|
+
fi
|
|
306
|
+
echo ""
|
|
307
|
+
done
|
|
308
|
+
|
|
309
|
+
echo "CFN Redis Data Extraction Completed"
|
|
310
|
+
echo "==================================="
|
|
311
|
+
echo "Output Directory: $OUTPUT_DIR"
|
|
312
|
+
echo "Files Generated:"
|
|
313
|
+
find "$OUTPUT_DIR" -name "cfn-loop-*.json" -o -name "cfn-loop-*.txt" | while read -r file; do
|
|
314
|
+
echo " - $file"
|
|
315
|
+
done
|
|
316
|
+
|
|
317
|
+
exit 0
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Parameters
|
|
321
|
+
|
|
322
|
+
| Parameter | Type | Required | Description |
|
|
323
|
+
|-----------|------|----------|-------------|
|
|
324
|
+
| `--task-id` | string | Yes | Single CFN Loop task ID to extract |
|
|
325
|
+
| `--task-ids` | string | No | Comma-separated list of task IDs |
|
|
326
|
+
| `--output-dir` | string | No | Output directory (default: ./analysis/cfn-loop-data) |
|
|
327
|
+
| `--include-performance` | boolean | No | Include Redis performance metrics |
|
|
328
|
+
| `--verbose` | boolean | No | Enable verbose output |
|
|
329
|
+
|
|
330
|
+
## Output Structure
|
|
331
|
+
|
|
332
|
+
The skill generates two files per task:
|
|
333
|
+
|
|
334
|
+
### 1. Main JSON Data File
|
|
335
|
+
`cfn-loop-{task_id}-extracted.json`
|
|
336
|
+
|
|
337
|
+
```json
|
|
338
|
+
{
|
|
339
|
+
"task_id": "cfn-cli-543042-13483",
|
|
340
|
+
"extraction_timestamp": "2025-11-09T04:56:00Z",
|
|
341
|
+
"extraction_version": "1.0.0",
|
|
342
|
+
"redis_keys_analyzed": 44,
|
|
343
|
+
"agents": {
|
|
344
|
+
"cfn-v3-coordinator-1": {
|
|
345
|
+
"agent_type": "coordinator",
|
|
346
|
+
"loop": "coordination",
|
|
347
|
+
"confidence": 0.85,
|
|
348
|
+
"completion_signal": "complete",
|
|
349
|
+
"messages": [...],
|
|
350
|
+
"result": "..."
|
|
351
|
+
},
|
|
352
|
+
"agent-id-2": {
|
|
353
|
+
"agent_type": "frontend-developer",
|
|
354
|
+
"loop": "3",
|
|
355
|
+
"confidence": 0.92,
|
|
356
|
+
"completion_signal": "complete"
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"metadata": {
|
|
360
|
+
"task_context": "...",
|
|
361
|
+
"performance": {
|
|
362
|
+
"redis_memory_usage": "2.5M",
|
|
363
|
+
"redis_connected_clients": 12
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
"summary": {
|
|
367
|
+
"total_agents": 11,
|
|
368
|
+
"completion_signals": 11,
|
|
369
|
+
"average_confidence": 0.86,
|
|
370
|
+
"extraction_status": "success"
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### 2. Summary Text File
|
|
376
|
+
`cfn-loop-{task_id}-summary.txt`
|
|
377
|
+
|
|
378
|
+
Human-readable summary with key statistics and agent information.
|
|
379
|
+
|
|
380
|
+
## Integration Points
|
|
381
|
+
|
|
382
|
+
### CFN Loop Completion Workflow
|
|
383
|
+
```bash
|
|
384
|
+
# After Product Owner decision, before Redis cleanup
|
|
385
|
+
./.claude/skills/cfn-redis-data-extraction/extract.sh \
|
|
386
|
+
--task-id "$TASK_ID" \
|
|
387
|
+
--output-dir "./analysis/loops" \
|
|
388
|
+
--include-performance=true
|
|
389
|
+
|
|
390
|
+
# Then proceed with Redis cleanup
|
|
391
|
+
redis-cli DEL "cfn_loop:task:$TASK_ID:*" "swarm:$TASK_ID:*"
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Main Chat Automation
|
|
395
|
+
```bash
|
|
396
|
+
# Automatic extraction after loop completion
|
|
397
|
+
npx claude-flow-novice skill cfn-redis-data-extraction \
|
|
398
|
+
--task-id "cfn-cli-XXXXXXX-XXXXX" \
|
|
399
|
+
--verbose
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Error Handling
|
|
403
|
+
|
|
404
|
+
- **Redis Unavailable**: Graceful exit with error message
|
|
405
|
+
- **No Keys Found**: Warning message, continue processing
|
|
406
|
+
- **Invalid JSON**: Fallback to basic text extraction
|
|
407
|
+
- **Permission Issues**: Directory creation with appropriate permissions
|
|
408
|
+
|
|
409
|
+
## Performance Considerations
|
|
410
|
+
|
|
411
|
+
- **Large Key Sets**: Processes keys in batches to avoid memory issues
|
|
412
|
+
- **Concurrent Access**: Uses read-only Redis operations
|
|
413
|
+
- **File Size**: JSON files are compressed and structured efficiently
|
|
414
|
+
- **Extraction Time**: Typically <5 seconds per task
|
|
415
|
+
|
|
416
|
+
## Validation
|
|
417
|
+
|
|
418
|
+
The skill includes built-in validation:
|
|
419
|
+
- Redis connectivity check
|
|
420
|
+
- JSON structure validation
|
|
421
|
+
- Data completeness verification
|
|
422
|
+
- Output file creation confirmation
|
|
423
|
+
|
|
424
|
+
## Maintenance
|
|
425
|
+
|
|
426
|
+
- **Version Tracking**: Each extraction includes version metadata
|
|
427
|
+
- **Backward Compatibility**: Supports multiple extraction formats
|
|
428
|
+
- **Cleanup**: Old files can be archived or cleaned up automatically
|
|
429
|
+
- **Monitoring**: Integration with system monitoring for extraction success rates
|
|
430
|
+
|
|
431
|
+
## Related Skills
|
|
432
|
+
|
|
433
|
+
- `cfn-redis-coordination` - For understanding Redis coordination patterns
|
|
434
|
+
- `cfn-loop-validation` - For validating loop execution
|
|
435
|
+
- `cfn-agent-spawning` - For understanding agent lifecycle
|
|
436
|
+
|
|
437
|
+
## Dependencies
|
|
438
|
+
|
|
439
|
+
- `redis-cli` - Redis command-line interface
|
|
440
|
+
- `jq` - JSON processor for data manipulation
|
|
441
|
+
- `bc` - Basic calculator for confidence averaging
|
|
442
|
+
- Standard Unix utilities (grep, awk, sed)
|