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,306 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CFN Redis Data Extraction Script
|
|
3
|
+
# Extracts complete Redis coordination data from completed CFN Loop tasks
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Default values
|
|
8
|
+
OUTPUT_DIR="./analysis/cfn-loop-data"
|
|
9
|
+
INCLUDE_PERFORMANCE=false
|
|
10
|
+
TASK_IDS=()
|
|
11
|
+
VERBOSE=false
|
|
12
|
+
|
|
13
|
+
# Parse arguments
|
|
14
|
+
while [[ $# -gt 0 ]]; do
|
|
15
|
+
case $1 in
|
|
16
|
+
--task-id)
|
|
17
|
+
TASK_IDS+=("$2")
|
|
18
|
+
shift 2
|
|
19
|
+
;;
|
|
20
|
+
--task-ids)
|
|
21
|
+
IFS=',' read -ra TASK_IDS <<< "$2"
|
|
22
|
+
shift 2
|
|
23
|
+
;;
|
|
24
|
+
--output-dir)
|
|
25
|
+
OUTPUT_DIR="$2"
|
|
26
|
+
shift 2
|
|
27
|
+
;;
|
|
28
|
+
--include-performance)
|
|
29
|
+
INCLUDE_PERFORMANCE=true
|
|
30
|
+
shift
|
|
31
|
+
;;
|
|
32
|
+
--verbose)
|
|
33
|
+
VERBOSE=true
|
|
34
|
+
shift
|
|
35
|
+
;;
|
|
36
|
+
-h|--help)
|
|
37
|
+
echo "Usage: $0 --task-id <TASK_ID> [--output-dir <DIR>] [--include-performance] [--verbose]"
|
|
38
|
+
exit 0
|
|
39
|
+
;;
|
|
40
|
+
*)
|
|
41
|
+
echo "Unknown option: $1"
|
|
42
|
+
exit 1
|
|
43
|
+
;;
|
|
44
|
+
esac
|
|
45
|
+
done
|
|
46
|
+
|
|
47
|
+
# Validate required arguments
|
|
48
|
+
if [[ ${#TASK_IDS[@]} -eq 0 ]]; then
|
|
49
|
+
echo "Error: --task-id or --task-ids is required"
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Create output directory
|
|
54
|
+
mkdir -p "$OUTPUT_DIR"
|
|
55
|
+
|
|
56
|
+
# Redis connection check
|
|
57
|
+
if ! redis-cli ping > /dev/null 2>&1; then
|
|
58
|
+
echo "Error: Redis is not accessible"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Function to extract task data
|
|
63
|
+
extract_task_data() {
|
|
64
|
+
local task_id="$1"
|
|
65
|
+
local output_file="$OUTPUT_DIR/cfn-loop-${task_id}-extracted.json"
|
|
66
|
+
|
|
67
|
+
[[ "$VERBOSE" == true ]] && echo "Extracting data for task: $task_id"
|
|
68
|
+
|
|
69
|
+
# Get all Redis keys for the task
|
|
70
|
+
local redis_keys
|
|
71
|
+
redis_keys=$(redis-cli keys "*${task_id}*" 2>/dev/null | sort)
|
|
72
|
+
|
|
73
|
+
if [[ -z "$redis_keys" ]]; then
|
|
74
|
+
echo "Warning: No Redis keys found for task: $task_id"
|
|
75
|
+
return 1
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Initialize JSON structure
|
|
79
|
+
local json_data
|
|
80
|
+
json_data=$(cat << EOF
|
|
81
|
+
{
|
|
82
|
+
"task_id": "$task_id",
|
|
83
|
+
"extraction_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
84
|
+
"extraction_version": "1.0.0",
|
|
85
|
+
"redis_keys_analyzed": $(echo "$redis_keys" | wc -l),
|
|
86
|
+
"agents": {},
|
|
87
|
+
"metadata": {},
|
|
88
|
+
"summary": {}
|
|
89
|
+
}
|
|
90
|
+
EOF
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Process each Redis key
|
|
94
|
+
local agent_count=0
|
|
95
|
+
local completion_signals=0
|
|
96
|
+
local total_confidence=0
|
|
97
|
+
local confidence_count=0
|
|
98
|
+
declare -A agent_loops
|
|
99
|
+
declare -A agent_types
|
|
100
|
+
|
|
101
|
+
while IFS= read -r key; do
|
|
102
|
+
[[ -z "$key" ]] && continue
|
|
103
|
+
|
|
104
|
+
# Skip if not a swarm key
|
|
105
|
+
[[ ! "$key" =~ ^swarm: ]] && continue
|
|
106
|
+
|
|
107
|
+
# Extract agent information from key
|
|
108
|
+
local agent_id=""
|
|
109
|
+
local data_type=""
|
|
110
|
+
|
|
111
|
+
if [[ "$key" =~ ^swarm:([^:]+):([^:]+):([^:]+)$ ]]; then
|
|
112
|
+
local task_key="${BASH_REMATCH[1]}"
|
|
113
|
+
agent_id="${BASH_REMATCH[2]}"
|
|
114
|
+
data_type="${BASH_REMATCH[3]}"
|
|
115
|
+
|
|
116
|
+
# Determine agent type and loop number
|
|
117
|
+
local agent_type=""
|
|
118
|
+
local loop_number=""
|
|
119
|
+
|
|
120
|
+
if [[ "$agent_id" =~ ^cfn-v3-coordinator ]]; then
|
|
121
|
+
agent_type="coordinator"
|
|
122
|
+
loop_number="coordination"
|
|
123
|
+
elif [[ "$agent_id" =~ -validation$ ]]; then
|
|
124
|
+
agent_type="${agent_id%-validation}"
|
|
125
|
+
loop_number="2"
|
|
126
|
+
elif [[ "$agent_id" =~ -[0-9]+$ ]]; then
|
|
127
|
+
agent_type="${agent_id%-*}"
|
|
128
|
+
loop_number="3"
|
|
129
|
+
elif [[ "$agent_id" =~ product-owner$ ]]; then
|
|
130
|
+
agent_type="product-owner"
|
|
131
|
+
loop_number="4"
|
|
132
|
+
else
|
|
133
|
+
agent_type="$agent_id"
|
|
134
|
+
loop_number="unknown"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Store agent classification
|
|
138
|
+
agent_types["$agent_id"]="$agent_type"
|
|
139
|
+
agent_loops["$agent_id"]="$loop_number"
|
|
140
|
+
|
|
141
|
+
# Initialize agent in JSON if not exists
|
|
142
|
+
if [[ ! "$json_data" =~ "\"$agent_id\":" ]]; then
|
|
143
|
+
((agent_count++))
|
|
144
|
+
json_data=$(echo "$json_data" | jq ".agents += {\"$agent_id\": {\"agent_type\": \"$agent_type\", \"loop\": \"$loop_number\", \"data\": {}}}")
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Extract data based on type
|
|
148
|
+
case "$data_type" in
|
|
149
|
+
"confidence")
|
|
150
|
+
local confidence
|
|
151
|
+
confidence=$(redis-cli get "$key" 2>/dev/null || echo "null")
|
|
152
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].confidence = $confidence")
|
|
153
|
+
if [[ "$confidence" != "null" ]]; then
|
|
154
|
+
total_confidence=$(echo "$total_confidence + $confidence" | bc -l)
|
|
155
|
+
((confidence_count++))
|
|
156
|
+
fi
|
|
157
|
+
;;
|
|
158
|
+
"done")
|
|
159
|
+
local completion_signal
|
|
160
|
+
completion_signal=$(redis-cli type "$key" 2>/dev/null)
|
|
161
|
+
if [[ "$completion_signal" == "list" ]]; then
|
|
162
|
+
completion_signal=$(redis-cli lrange "$key" 0 -1 2>/dev/null | head -1 || echo "null")
|
|
163
|
+
else
|
|
164
|
+
completion_signal=$(redis-cli get "$key" 2>/dev/null || echo "null")
|
|
165
|
+
fi
|
|
166
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].completion_signal = \"$completion_signal\"")
|
|
167
|
+
((completion_signals++))
|
|
168
|
+
;;
|
|
169
|
+
"messages")
|
|
170
|
+
local messages_json="[]"
|
|
171
|
+
local message_count
|
|
172
|
+
message_count=$(redis-cli llen "$key" 2>/dev/null || echo "0")
|
|
173
|
+
|
|
174
|
+
if [[ "$message_count" -gt 0 ]]; then
|
|
175
|
+
messages_json=$(redis-cli lrange "$key" 0 -1 2>/dev/null | jq -R . | jq -s .)
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].messages = $messages_json")
|
|
179
|
+
;;
|
|
180
|
+
"result")
|
|
181
|
+
local result_type
|
|
182
|
+
result_type=$(redis-cli type "$key" 2>/dev/null)
|
|
183
|
+
local result="null"
|
|
184
|
+
|
|
185
|
+
case "$result_type" in
|
|
186
|
+
"string")
|
|
187
|
+
result=$(redis-cli get "$key" 2>/dev/null || echo "null")
|
|
188
|
+
;;
|
|
189
|
+
"list")
|
|
190
|
+
result=$(redis-cli lrange "$key" 0 -1 2>/dev/null | jq -R . | jq -s .)
|
|
191
|
+
;;
|
|
192
|
+
esac
|
|
193
|
+
|
|
194
|
+
json_data=$(echo "$json_data" | jq ".agents[\"$agent_id\"].result = $result")
|
|
195
|
+
;;
|
|
196
|
+
esac
|
|
197
|
+
fi
|
|
198
|
+
done <<< "$redis_keys"
|
|
199
|
+
|
|
200
|
+
# Calculate averages and summary
|
|
201
|
+
local avg_confidence="0"
|
|
202
|
+
if [[ "$confidence_count" -gt 0 ]]; then
|
|
203
|
+
avg_confidence=$(echo "scale=3; $total_confidence / $confidence_count" | bc -l)
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
# Extract task context if available
|
|
207
|
+
local task_context
|
|
208
|
+
task_context=$(redis-cli get "cfn_loop:task:$task_id:context" 2>/dev/null || echo "{}")
|
|
209
|
+
|
|
210
|
+
# Extract completed agents list
|
|
211
|
+
local completed_agents
|
|
212
|
+
completed_agents=$(redis-cli lrange "swarm:$task_id:completed_agents" 0 -1 2>/dev/null | jq -R . | jq -s . || echo "[]")
|
|
213
|
+
|
|
214
|
+
# Update summary
|
|
215
|
+
json_data=$(echo "$json_data" | jq "
|
|
216
|
+
.summary += {
|
|
217
|
+
\"total_agents\": $agent_count,
|
|
218
|
+
\"completion_signals\": $completion_signals,
|
|
219
|
+
\"average_confidence\": $avg_confidence,
|
|
220
|
+
\"confidence_scores_count\": $confidence_count,
|
|
221
|
+
\"completed_agents\": $completed_agents,
|
|
222
|
+
\"extraction_status\": \"success\"
|
|
223
|
+
}
|
|
224
|
+
")
|
|
225
|
+
|
|
226
|
+
# Add task context
|
|
227
|
+
json_data=$(echo "$json_data" | jq ".metadata.task_context = \"$task_context\"")
|
|
228
|
+
|
|
229
|
+
# Add performance metrics if requested
|
|
230
|
+
if [[ "$INCLUDE_PERFORMANCE" == true ]]; then
|
|
231
|
+
local redis_memory
|
|
232
|
+
redis_memory=$(redis-cli info memory 2>/dev/null | grep "used_memory_human" | cut -d: -f2 | tr -d '\r' || echo "\"unknown\"")
|
|
233
|
+
local redis_clients
|
|
234
|
+
redis_clients=$(redis-cli info clients 2>/dev/null | grep "connected_clients" | cut -d: -f2 | tr -d '\r' || echo "0")
|
|
235
|
+
|
|
236
|
+
json_data=$(echo "$json_data" | jq "
|
|
237
|
+
.metadata.performance = {
|
|
238
|
+
\"redis_memory_usage\": \"$redis_memory\",
|
|
239
|
+
\"redis_connected_clients\": $redis_clients,
|
|
240
|
+
\"extraction_duration_ms\": 0
|
|
241
|
+
}
|
|
242
|
+
")
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Write to file
|
|
246
|
+
echo "$json_data" | jq '.' > "$output_file"
|
|
247
|
+
|
|
248
|
+
[[ "$VERBOSE" == true ]] && echo "Data extracted to: $output_file"
|
|
249
|
+
|
|
250
|
+
# Generate summary report
|
|
251
|
+
local summary_file="$OUTPUT_DIR/cfn-loop-${task_id}-summary.txt"
|
|
252
|
+
cat > "$summary_file" << EOF
|
|
253
|
+
CFN Loop Data Extraction Summary
|
|
254
|
+
================================
|
|
255
|
+
|
|
256
|
+
Task ID: $task_id
|
|
257
|
+
Extraction Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
258
|
+
Output File: $output_file
|
|
259
|
+
|
|
260
|
+
Statistics:
|
|
261
|
+
- Redis Keys Analyzed: $(echo "$redis_keys" | wc -l)
|
|
262
|
+
- Total Agents: $agent_count
|
|
263
|
+
- Completion Signals: $completion_signals
|
|
264
|
+
- Average Confidence: $avg_confidence
|
|
265
|
+
- Confidence Scores: $confidence_count
|
|
266
|
+
|
|
267
|
+
Agent Types:
|
|
268
|
+
$(for agent_id in "${!agent_types[@]}"; do
|
|
269
|
+
echo "- $agent_id: ${agent_types[$agent_id]} (Loop ${agent_loops[$agent_id]})"
|
|
270
|
+
done | sort)
|
|
271
|
+
|
|
272
|
+
Status: Successfully extracted
|
|
273
|
+
EOF
|
|
274
|
+
|
|
275
|
+
[[ "$VERBOSE" == true ]] && echo "Summary report generated: $summary_file"
|
|
276
|
+
|
|
277
|
+
return 0
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
# Main execution
|
|
281
|
+
echo "CFN Redis Data Extraction Started"
|
|
282
|
+
echo "================================="
|
|
283
|
+
echo "Output Directory: $OUTPUT_DIR"
|
|
284
|
+
echo "Include Performance: $INCLUDE_PERFORMANCE"
|
|
285
|
+
echo ""
|
|
286
|
+
|
|
287
|
+
# Process each task
|
|
288
|
+
for task_id in "${TASK_IDS[@]}"; do
|
|
289
|
+
echo "Processing task: $task_id"
|
|
290
|
+
if extract_task_data "$task_id"; then
|
|
291
|
+
echo "✅ Successfully extracted data for: $task_id"
|
|
292
|
+
else
|
|
293
|
+
echo "❌ Failed to extract data for: $task_id"
|
|
294
|
+
fi
|
|
295
|
+
echo ""
|
|
296
|
+
done
|
|
297
|
+
|
|
298
|
+
echo "CFN Redis Data Extraction Completed"
|
|
299
|
+
echo "==================================="
|
|
300
|
+
echo "Output Directory: $OUTPUT_DIR"
|
|
301
|
+
echo "Files Generated:"
|
|
302
|
+
find "$OUTPUT_DIR" -name "cfn-loop-*.json" -o -name "cfn-loop-*.txt" | while read -r file; do
|
|
303
|
+
echo " - $file"
|
|
304
|
+
done
|
|
305
|
+
|
|
306
|
+
exit 0
|
|
@@ -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
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
##############################################################################
|
|
4
|
+
# Security Scanner for Post-Edit Hooks
|
|
5
|
+
# Version: 1.0.0
|
|
6
|
+
##############################################################################
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Function to perform basic security scanning on files
|
|
11
|
+
security_scan() {
|
|
12
|
+
local file_path="$1"
|
|
13
|
+
local agent_id="${2:-unknown}"
|
|
14
|
+
|
|
15
|
+
# Initialize security scan results
|
|
16
|
+
local scan_result='{"confidence":0.9,"issues":[],"details":"{\\\"scanner\\\":\\\"basic-security\\\",\\\"timestamp\\\":\\\"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'\\\"}"}'
|
|
17
|
+
|
|
18
|
+
# Check if file exists
|
|
19
|
+
if [[ ! -f "$file_path" ]]; then
|
|
20
|
+
scan_result='{"confidence":0,"issues":[{"severity":"error","message":"File not found","line":0}],"details":"{\\\"error\\\":\\\"file_not_found\\\"}"}'
|
|
21
|
+
echo "$scan_result"
|
|
22
|
+
return 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Basic security checks
|
|
26
|
+
local issues=()
|
|
27
|
+
local confidence=0.9
|
|
28
|
+
|
|
29
|
+
# Check for potential secrets/passwords
|
|
30
|
+
if grep -i -E "(password|secret|key|token)\s*[:=]\s*['\"]?[a-zA-Z0-9+/=]{20,}" "$file_path" >/dev/null 2>&1; then
|
|
31
|
+
issues+=("{\"severity\":\"critical\",\"message\":\"Potential hardcoded secret detected\",\"type\":\"secret_exposure\"}")
|
|
32
|
+
confidence=0.3
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Check for API keys patterns
|
|
36
|
+
if grep -E "(AIza[A-Za-z0-9_-]{35}|[a-zA-Z0-9_-]{40,})" "$file_path" >/dev/null 2>&1; then
|
|
37
|
+
issues+=("{\"severity\":\"high\",\"message\":\"Potential API key pattern detected\",\"type\":\"api_key\"}")
|
|
38
|
+
confidence=0.5
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Check for SQL injection patterns
|
|
42
|
+
if grep -E "(SELECT|INSERT|UPDATE|DELETE).*(\\$|\\$\\{|\\\$\)" "$file_path" >/dev/null 2>&1; then
|
|
43
|
+
issues+=("{\"severity\":\"medium\",\"message\":\"Unsanitized variable in SQL query\",\"type\":\"sql_injection\"}")
|
|
44
|
+
confidence=0.7
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Check for eval() usage (security risk)
|
|
48
|
+
if grep -E "eval\\s*\\(" "$file_path" >/dev/null 2>&1; then
|
|
49
|
+
issues+=("{\"severity\":\"medium\",\"message\":\"Use of eval() function detected\",\"type\":\"eval_usage\"}")
|
|
50
|
+
confidence=0.8
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Check for shell command injection patterns
|
|
54
|
+
if grep -E "(exec|system|shell_exec)\\s*\\(" "$file_path" >/dev/null 2>&1; then
|
|
55
|
+
issues+=("{\"severity\":\"medium\",\"message\":\"Use of system execution functions\",\"type\":\"command_injection\"}")
|
|
56
|
+
confidence=0.8
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Build JSON result
|
|
60
|
+
local issues_json="[]"
|
|
61
|
+
if [[ ${#issues[@]} -gt 0 ]]; then
|
|
62
|
+
issues_json="[$(IFS=','; echo "${issues[*]}")]"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
scan_result="{\"confidence\":$confidence,\"issues\":$issues_json,\"details\":\"{\\\"scanner\\\":\\\"basic-security\\\",\\\"timestamp\\\":\\\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\\\",\\\"file\\\":\\\"$file_path\\\",\\\"agent_id\\\":\\\"$agent_id\\\"}\"}"
|
|
66
|
+
|
|
67
|
+
echo "$scan_result"
|
|
68
|
+
|
|
69
|
+
# Return appropriate exit code based on findings
|
|
70
|
+
if [[ ${#issues[@]} -gt 0 ]]; then
|
|
71
|
+
return 1
|
|
72
|
+
else
|
|
73
|
+
return 0
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Main execution
|
|
78
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
79
|
+
# Script called directly
|
|
80
|
+
if [[ $# -lt 1 ]]; then
|
|
81
|
+
echo "Usage: $0 <file_path> [--agent-id <id>]" >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
file_path="$1"
|
|
86
|
+
agent_id="unknown"
|
|
87
|
+
|
|
88
|
+
# Parse optional arguments
|
|
89
|
+
while [[ $# -gt 0 ]]; do
|
|
90
|
+
case $1 in
|
|
91
|
+
--agent-id)
|
|
92
|
+
agent_id="$2"
|
|
93
|
+
shift 2
|
|
94
|
+
;;
|
|
95
|
+
*)
|
|
96
|
+
shift
|
|
97
|
+
;;
|
|
98
|
+
esac
|
|
99
|
+
done
|
|
100
|
+
|
|
101
|
+
security_scan "$file_path" "$agent_id"
|
|
102
|
+
fi
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
##############################################################################
|
|
4
|
+
# Pre-Edit Backup Script - Creates safe file backups before modifications
|
|
5
|
+
# Version: 1.0.0
|
|
6
|
+
##############################################################################
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Function to create backup of a file before editing
|
|
11
|
+
create_backup() {
|
|
12
|
+
local file_path="$1"
|
|
13
|
+
local agent_id="${2:-unknown}"
|
|
14
|
+
local project_root="${3:-$(pwd)}"
|
|
15
|
+
|
|
16
|
+
# Validate inputs
|
|
17
|
+
if [[ -z "$file_path" ]]; then
|
|
18
|
+
echo "Error: File path is required" >&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Check if file exists
|
|
23
|
+
if [[ ! -f "$file_path" ]]; then
|
|
24
|
+
echo "Warning: File does not exist: $file_path" >&2
|
|
25
|
+
# Create empty backup path for new files
|
|
26
|
+
echo "$project_root/.backups/$agent_id/new-file-$(date +%s)-$(echo "$file_path" | tr '/' '_' | tr ' ' '_')"
|
|
27
|
+
return 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Create backup directory structure
|
|
31
|
+
local backup_dir="$project_root/.backups/$agent_id"
|
|
32
|
+
local timestamp=$(date +%s)
|
|
33
|
+
local file_hash=$(md5sum "$file_path" | cut -d' ' -f1)
|
|
34
|
+
local backup_name="${timestamp}_${file_hash}"
|
|
35
|
+
|
|
36
|
+
# Create full backup path
|
|
37
|
+
local full_backup_path="$backup_dir/$backup_name"
|
|
38
|
+
|
|
39
|
+
# Create backup directory
|
|
40
|
+
mkdir -p "$full_backup_path"
|
|
41
|
+
|
|
42
|
+
# Copy original file to backup location
|
|
43
|
+
cp "$file_path" "$full_backup_path/original"
|
|
44
|
+
|
|
45
|
+
# Store backup metadata
|
|
46
|
+
cat > "$full_backup_path/metadata.json" << EOF
|
|
47
|
+
{
|
|
48
|
+
"timestamp": "$timestamp",
|
|
49
|
+
"agent_id": "$agent_id",
|
|
50
|
+
"original_file": "$file_path",
|
|
51
|
+
"file_hash": "$file_hash",
|
|
52
|
+
"backup_path": "$full_backup_path",
|
|
53
|
+
"created_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
54
|
+
}
|
|
55
|
+
EOF
|
|
56
|
+
|
|
57
|
+
# Create revert script
|
|
58
|
+
cat > "$full_backup_path/revert.sh" << EOF
|
|
59
|
+
#!/bin/bash
|
|
60
|
+
# Revert script for $file_path
|
|
61
|
+
set -euo pipefail
|
|
62
|
+
|
|
63
|
+
echo "Reverting file: $file_path"
|
|
64
|
+
cp "$full_backup_path/original" "$file_path"
|
|
65
|
+
echo "✅ File reverted successfully"
|
|
66
|
+
EOF
|
|
67
|
+
|
|
68
|
+
chmod +x "$full_backup_path/revert.sh"
|
|
69
|
+
|
|
70
|
+
# Output backup path for caller
|
|
71
|
+
echo "$full_backup_path"
|
|
72
|
+
|
|
73
|
+
echo "✅ Backup created: $full_backup_path" >&2
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Main execution
|
|
77
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
78
|
+
# Script called directly
|
|
79
|
+
if [[ $# -lt 1 ]]; then
|
|
80
|
+
echo "Usage: $0 <file_path> [--agent-id <id>] [--project-root <path>]" >&2
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
file_path="$1"
|
|
85
|
+
agent_id="unknown"
|
|
86
|
+
project_root="$(pwd)"
|
|
87
|
+
|
|
88
|
+
# Parse optional arguments
|
|
89
|
+
while [[ $# -gt 0 ]]; do
|
|
90
|
+
case $1 in
|
|
91
|
+
--agent-id)
|
|
92
|
+
agent_id="$2"
|
|
93
|
+
shift 2
|
|
94
|
+
;;
|
|
95
|
+
--project-root)
|
|
96
|
+
project_root="$2"
|
|
97
|
+
shift 2
|
|
98
|
+
;;
|
|
99
|
+
*)
|
|
100
|
+
# Skip unknown arguments
|
|
101
|
+
shift
|
|
102
|
+
;;
|
|
103
|
+
esac
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
create_backup "$file_path" "$agent_id" "$project_root"
|
|
107
|
+
fi
|
|
@@ -26,6 +26,9 @@ Options:
|
|
|
26
26
|
--mode <mode> Execution mode (cli, api, hybrid)
|
|
27
27
|
--priority <n> Task priority (1-10)
|
|
28
28
|
--parent-task-id <id> Parent task identifier
|
|
29
|
+
--memory-limit <mb> Set memory limit in MB (default: 8192)
|
|
30
|
+
--enable-profiling Enable heap profiling for debugging
|
|
31
|
+
--debug Enable debug mode with profiling
|
|
29
32
|
--list List all available agents
|
|
30
33
|
--help Show this help message
|
|
31
34
|
|
|
@@ -33,15 +36,32 @@ Examples:
|
|
|
33
36
|
# Simple agent spawn
|
|
34
37
|
npx claude-flow-novice agent coder --context "Implement JWT auth"
|
|
35
38
|
|
|
36
|
-
# CFN Loop agent
|
|
39
|
+
# CFN Loop agent with memory limits
|
|
37
40
|
npx claude-flow-novice agent rust-enterprise-developer \\
|
|
38
41
|
--task-id task-123 \\
|
|
39
42
|
--iteration 1 \\
|
|
40
|
-
--mode standard
|
|
43
|
+
--mode standard \\
|
|
44
|
+
--memory-limit 4096
|
|
45
|
+
|
|
46
|
+
# Debug mode with profiling
|
|
47
|
+
npx claude-flow-novice agent tester \\
|
|
48
|
+
--context "Test authentication system" \\
|
|
49
|
+
--debug \\
|
|
50
|
+
--enable-profiling
|
|
41
51
|
|
|
42
52
|
# List available agents
|
|
43
53
|
npx claude-flow-novice agent --list
|
|
44
54
|
|
|
55
|
+
Memory Management:
|
|
56
|
+
Claude automatically applies memory limits to prevent leaks:
|
|
57
|
+
- Default limit: 8GB (reduced from 16GB)
|
|
58
|
+
- Use --memory-limit to set custom limits
|
|
59
|
+
- Use --debug to enable profiling and monitoring
|
|
60
|
+
- Memory profiles saved to /tmp/claude-memory-profiles/
|
|
61
|
+
|
|
62
|
+
For advanced memory management:
|
|
63
|
+
./scripts/memory-leak-prevention.sh --help
|
|
64
|
+
|
|
45
65
|
Available Agents:
|
|
46
66
|
Agents are defined in .claude/agents/ directory:
|
|
47
67
|
- core-agents/ Production-ready core agents
|
|
@@ -101,7 +121,29 @@ Documentation:
|
|
|
101
121
|
return;
|
|
102
122
|
}
|
|
103
123
|
try {
|
|
124
|
+
// Apply memory management options
|
|
125
|
+
if (options.memoryLimit) {
|
|
126
|
+
console.log(`[agent-command] Setting memory limit: ${options.memoryLimit}MB`);
|
|
127
|
+
const currentOptions = process.env.NODE_OPTIONS || '';
|
|
128
|
+
const newOptions = currentOptions.replace(/--max-old-space-size=\d+/, `--max-old-space-size=${options.memoryLimit}`);
|
|
129
|
+
process.env.NODE_OPTIONS = newOptions || `--max-old-space-size=${options.memoryLimit}`;
|
|
130
|
+
}
|
|
131
|
+
if (options.enableProfiling || options.debug) {
|
|
132
|
+
console.log(`[agent-command] Enabling memory profiling`);
|
|
133
|
+
if (!process.env.NODE_OPTIONS.includes('heap-prof')) {
|
|
134
|
+
process.env.NODE_OPTIONS += ' --heap-prof';
|
|
135
|
+
}
|
|
136
|
+
if (!process.env.NODE_OPTIONS.includes('inspect') && options.debug) {
|
|
137
|
+
process.env.NODE_OPTIONS += ' --inspect=0.0.0.0:9229';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (options.debug) {
|
|
141
|
+
console.log(`[agent-command] Debug mode enabled`);
|
|
142
|
+
process.env.CLAUDE_DEBUG = 'true';
|
|
143
|
+
process.env.CLAUDE_MEMORY_MONITORING = 'true';
|
|
144
|
+
}
|
|
104
145
|
console.log(`[agent-command] Spawning agent: ${agentType}`);
|
|
146
|
+
console.log(`[agent-command] Memory settings: ${process.env.NODE_OPTIONS}`);
|
|
105
147
|
console.log('');
|
|
106
148
|
// Step 1: Parse agent definition
|
|
107
149
|
console.log('[1/3] Parsing agent definition...');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/agent-command.ts"],"sourcesContent":["/**\r\n * Agent Command Handler\r\n *\r\n * Handles `npx claude-flow-novice agent <type> [options]` commands.\r\n * Orchestrates agent definition parsing, prompt building, and execution.\r\n */\r\n\r\nimport { parseAgentDefinition, listAgentDefinitions } from './agent-definition-parser.js';\r\nimport { buildAgentPrompt, TaskContext } from './agent-prompt-builder.js';\r\nimport { executeAgent } from './agent-executor.js';\r\n\r\nexport interface AgentCommandOptions {\r\n taskId?: string;\r\n iteration?: number;\r\n context?: string;\r\n mode?: string;\r\n priority?: number;\r\n parentTaskId?: string;\r\n agentId?: string;\r\n list?: boolean;\r\n help?: boolean;\r\n}\r\n\r\n/**\r\n * Display agent command help\r\n */\r\nexport function displayAgentHelp(): void {\r\n console.log(`\r\nClaude Flow Novice - Agent Spawning\r\n\r\nUsage:\r\n npx claude-flow-novice agent <type> [options]\r\n\r\nArguments:\r\n <type> Agent type (e.g., rust-enterprise-developer, coder, reviewer)\r\n\r\nOptions:\r\n --task-id <id> Task identifier for CFN Loop coordination\r\n --iteration <n> Iteration number (default: 1)\r\n --agent-id <id> Explicit agent ID (overrides auto-generated ID)\r\n --context <text> Task context/description\r\n --mode <mode> Execution mode (cli, api, hybrid)\r\n --priority <n> Task priority (1-10)\r\n --parent-task-id <id> Parent task identifier\r\n --list List all available agents\r\n --help Show this help message\r\n\r\nExamples:\r\n # Simple agent spawn\r\n npx claude-flow-novice agent coder --context \"Implement JWT auth\"\r\n\r\n # CFN Loop agent\r\n npx claude-flow-novice agent rust-enterprise-developer \\\\\r\n --task-id task-123 \\\\\r\n --iteration 1 \\\\\r\n --mode standard\r\n\r\n # List available agents\r\n npx claude-flow-novice agent --list\r\n\r\nAvailable Agents:\r\n Agents are defined in .claude/agents/ directory:\r\n - core-agents/ Production-ready core agents\r\n - specialized/ Domain-specific specialists\r\n - development/ Development-focused agents\r\n - security/ Security-focused agents\r\n - custom/ Your custom agents\r\n\r\nDocumentation:\r\n See .claude/agents/CLAUDE.md for agent creation guide\r\n`);\r\n}\r\n\r\n/**\r\n * List all available agent definitions\r\n */\r\nexport async function listAgents(): Promise<void> {\r\n console.log('Searching for agent definitions...\\n');\r\n\r\n const agents = await listAgentDefinitions();\r\n\r\n if (agents.length === 0) {\r\n console.log('No agent definitions found in .claude/agents/');\r\n console.log('\\nTo create agents, see: .claude/agents/CLAUDE.md');\r\n return;\r\n }\r\n\r\n console.log(`Found ${agents.length} agent(s):\\n`);\r\n\r\n // Group by category\r\n const grouped: Record<string, string[]> = {};\r\n\r\n for (const agent of agents) {\r\n const parts = agent.split('/');\r\n const category = parts.length > 1 ? parts[0] : 'root';\r\n const name = parts.length > 1 ? parts.slice(1).join('/') : parts[0];\r\n\r\n if (!grouped[category]) {\r\n grouped[category] = [];\r\n }\r\n grouped[category].push(name);\r\n }\r\n\r\n // Display grouped agents\r\n for (const [category, names] of Object.entries(grouped).sort()) {\r\n console.log(`${category}/`);\r\n for (const name of names.sort()) {\r\n console.log(` - ${name}`);\r\n }\r\n console.log('');\r\n }\r\n\r\n console.log('Usage:');\r\n console.log(' npx claude-flow-novice agent <name> [options]');\r\n}\r\n\r\n/**\r\n * Execute agent command\r\n */\r\nexport async function agentCommand(\r\n agentType: string | undefined,\r\n options: AgentCommandOptions\r\n): Promise<void> {\r\n // Handle --list flag\r\n if (options.list) {\r\n await listAgents();\r\n return;\r\n }\r\n\r\n // Handle --help flag\r\n if (options.help || !agentType) {\r\n displayAgentHelp();\r\n return;\r\n }\r\n\r\n try {\r\n console.log(`[agent-command] Spawning agent: ${agentType}`);\r\n console.log('');\r\n\r\n // Step 1: Parse agent definition\r\n console.log('[1/3] Parsing agent definition...');\r\n const definition = await parseAgentDefinition(agentType);\r\n console.log(` ✓ Found: ${definition.name}`);\r\n console.log(` ✓ Type: ${definition.type || 'specialist'}`);\r\n console.log(` ✓ Model: ${definition.model}`);\r\n console.log(` ✓ Tools: ${definition.tools.join(', ')}`);\r\n console.log('');\r\n\r\n // Step 2: Build agent prompt\r\n console.log('[2/3] Building agent prompt...');\r\n const taskContext: TaskContext = {\r\n taskId: options.taskId,\r\n iteration: options.iteration,\r\n agentId: options.agentId,\r\n context: options.context,\r\n mode: options.mode,\r\n priority: options.priority,\r\n parentTaskId: options.parentTaskId,\r\n };\r\n\r\n const prompt = await buildAgentPrompt(definition, taskContext);\r\n console.log(` ✓ Prompt size: ${prompt.length} characters`);\r\n console.log(` ✓ CFN Loop protocol: ${prompt.includes('CFN Loop Redis Completion Protocol') ? 'included' : 'not applicable'}`);\r\n console.log(` ✓ Iteration history: ${prompt.includes('## Iteration History') ? 'included' : 'not applicable'}`);\r\n console.log('');\r\n\r\n // Step 3: Execute agent\r\n console.log('[3/3] Executing agent...');\r\n const result = await executeAgent(definition, prompt, taskContext);\r\n\r\n console.log('');\r\n console.log('=== Execution Result ===');\r\n console.log(`Agent ID: ${result.agentId}`);\r\n console.log(`Status: ${result.success ? '✓ Success' : '✗ Failed'}`);\r\n console.log(`Exit Code: ${result.exitCode}`);\r\n\r\n if (result.error) {\r\n console.error(`Error: ${result.error}`);\r\n process.exit(1);\r\n }\r\n\r\n if (result.output) {\r\n console.log('\\nOutput:');\r\n console.log(result.output);\r\n }\r\n\r\n process.exit(result.exitCode);\r\n } catch (error) {\r\n console.error('\\n[agent-command] Error:', error instanceof Error ? error.message : String(error));\r\n process.exit(1);\r\n }\r\n}\r\n"],"names":["parseAgentDefinition","listAgentDefinitions","buildAgentPrompt","executeAgent","displayAgentHelp","console","log","listAgents","agents","length","grouped","agent","parts","split","category","name","slice","join","push","names","Object","entries","sort","agentCommand","agentType","options","list","help","definition","type","model","tools","taskContext","taskId","iteration","agentId","context","mode","priority","parentTaskId","prompt","includes","result","success","exitCode","error","process","exit","output","Error","message","String"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/agent-command.ts"],"sourcesContent":["/**\r\n * Agent Command Handler\r\n *\r\n * Handles `npx claude-flow-novice agent <type> [options]` commands.\r\n * Orchestrates agent definition parsing, prompt building, and execution.\r\n */\r\n\r\nimport { parseAgentDefinition, listAgentDefinitions } from './agent-definition-parser.js';\r\nimport { buildAgentPrompt, TaskContext } from './agent-prompt-builder.js';\r\nimport { executeAgent } from './agent-executor.js';\r\n\r\nexport interface AgentCommandOptions {\r\n taskId?: string;\r\n iteration?: number;\r\n context?: string;\r\n mode?: string;\r\n priority?: number;\r\n parentTaskId?: string;\r\n agentId?: string;\r\n list?: boolean;\r\n help?: boolean;\r\n memoryLimit?: number;\r\n enableProfiling?: boolean;\r\n debug?: boolean;\r\n}\r\n\r\n/**\r\n * Display agent command help\r\n */\r\nexport function displayAgentHelp(): void {\r\n console.log(`\r\nClaude Flow Novice - Agent Spawning\r\n\r\nUsage:\r\n npx claude-flow-novice agent <type> [options]\r\n\r\nArguments:\r\n <type> Agent type (e.g., rust-enterprise-developer, coder, reviewer)\r\n\r\nOptions:\r\n --task-id <id> Task identifier for CFN Loop coordination\r\n --iteration <n> Iteration number (default: 1)\r\n --agent-id <id> Explicit agent ID (overrides auto-generated ID)\r\n --context <text> Task context/description\r\n --mode <mode> Execution mode (cli, api, hybrid)\r\n --priority <n> Task priority (1-10)\r\n --parent-task-id <id> Parent task identifier\r\n --memory-limit <mb> Set memory limit in MB (default: 8192)\r\n --enable-profiling Enable heap profiling for debugging\r\n --debug Enable debug mode with profiling\r\n --list List all available agents\r\n --help Show this help message\r\n\r\nExamples:\r\n # Simple agent spawn\r\n npx claude-flow-novice agent coder --context \"Implement JWT auth\"\r\n\r\n # CFN Loop agent with memory limits\r\n npx claude-flow-novice agent rust-enterprise-developer \\\\\r\n --task-id task-123 \\\\\r\n --iteration 1 \\\\\r\n --mode standard \\\\\r\n --memory-limit 4096\r\n\r\n # Debug mode with profiling\r\n npx claude-flow-novice agent tester \\\\\r\n --context \"Test authentication system\" \\\\\r\n --debug \\\\\r\n --enable-profiling\r\n\r\n # List available agents\r\n npx claude-flow-novice agent --list\r\n\r\nMemory Management:\r\n Claude automatically applies memory limits to prevent leaks:\r\n - Default limit: 8GB (reduced from 16GB)\r\n - Use --memory-limit to set custom limits\r\n - Use --debug to enable profiling and monitoring\r\n - Memory profiles saved to /tmp/claude-memory-profiles/\r\n\r\n For advanced memory management:\r\n ./scripts/memory-leak-prevention.sh --help\r\n\r\nAvailable Agents:\r\n Agents are defined in .claude/agents/ directory:\r\n - core-agents/ Production-ready core agents\r\n - specialized/ Domain-specific specialists\r\n - development/ Development-focused agents\r\n - security/ Security-focused agents\r\n - custom/ Your custom agents\r\n\r\nDocumentation:\r\n See .claude/agents/CLAUDE.md for agent creation guide\r\n`);\r\n}\r\n\r\n/**\r\n * List all available agent definitions\r\n */\r\nexport async function listAgents(): Promise<void> {\r\n console.log('Searching for agent definitions...\\n');\r\n\r\n const agents = await listAgentDefinitions();\r\n\r\n if (agents.length === 0) {\r\n console.log('No agent definitions found in .claude/agents/');\r\n console.log('\\nTo create agents, see: .claude/agents/CLAUDE.md');\r\n return;\r\n }\r\n\r\n console.log(`Found ${agents.length} agent(s):\\n`);\r\n\r\n // Group by category\r\n const grouped: Record<string, string[]> = {};\r\n\r\n for (const agent of agents) {\r\n const parts = agent.split('/');\r\n const category = parts.length > 1 ? parts[0] : 'root';\r\n const name = parts.length > 1 ? parts.slice(1).join('/') : parts[0];\r\n\r\n if (!grouped[category]) {\r\n grouped[category] = [];\r\n }\r\n grouped[category].push(name);\r\n }\r\n\r\n // Display grouped agents\r\n for (const [category, names] of Object.entries(grouped).sort()) {\r\n console.log(`${category}/`);\r\n for (const name of names.sort()) {\r\n console.log(` - ${name}`);\r\n }\r\n console.log('');\r\n }\r\n\r\n console.log('Usage:');\r\n console.log(' npx claude-flow-novice agent <name> [options]');\r\n}\r\n\r\n/**\r\n * Execute agent command\r\n */\r\nexport async function agentCommand(\r\n agentType: string | undefined,\r\n options: AgentCommandOptions\r\n): Promise<void> {\r\n // Handle --list flag\r\n if (options.list) {\r\n await listAgents();\r\n return;\r\n }\r\n\r\n // Handle --help flag\r\n if (options.help || !agentType) {\r\n displayAgentHelp();\r\n return;\r\n }\r\n\r\n try {\r\n // Apply memory management options\r\n if (options.memoryLimit) {\r\n console.log(`[agent-command] Setting memory limit: ${options.memoryLimit}MB`);\r\n const currentOptions = process.env.NODE_OPTIONS || '';\r\n const newOptions = currentOptions.replace(/--max-old-space-size=\\d+/, `--max-old-space-size=${options.memoryLimit}`);\r\n process.env.NODE_OPTIONS = newOptions || `--max-old-space-size=${options.memoryLimit}`;\r\n }\r\n\r\n if (options.enableProfiling || options.debug) {\r\n console.log(`[agent-command] Enabling memory profiling`);\r\n if (!process.env.NODE_OPTIONS.includes('heap-prof')) {\r\n process.env.NODE_OPTIONS += ' --heap-prof';\r\n }\r\n if (!process.env.NODE_OPTIONS.includes('inspect') && options.debug) {\r\n process.env.NODE_OPTIONS += ' --inspect=0.0.0.0:9229';\r\n }\r\n }\r\n\r\n if (options.debug) {\r\n console.log(`[agent-command] Debug mode enabled`);\r\n process.env.CLAUDE_DEBUG = 'true';\r\n process.env.CLAUDE_MEMORY_MONITORING = 'true';\r\n }\r\n\r\n console.log(`[agent-command] Spawning agent: ${agentType}`);\r\n console.log(`[agent-command] Memory settings: ${process.env.NODE_OPTIONS}`);\r\n console.log('');\r\n\r\n // Step 1: Parse agent definition\r\n console.log('[1/3] Parsing agent definition...');\r\n const definition = await parseAgentDefinition(agentType);\r\n console.log(` ✓ Found: ${definition.name}`);\r\n console.log(` ✓ Type: ${definition.type || 'specialist'}`);\r\n console.log(` ✓ Model: ${definition.model}`);\r\n console.log(` ✓ Tools: ${definition.tools.join(', ')}`);\r\n console.log('');\r\n\r\n // Step 2: Build agent prompt\r\n console.log('[2/3] Building agent prompt...');\r\n const taskContext: TaskContext = {\r\n taskId: options.taskId,\r\n iteration: options.iteration,\r\n agentId: options.agentId,\r\n context: options.context,\r\n mode: options.mode,\r\n priority: options.priority,\r\n parentTaskId: options.parentTaskId,\r\n };\r\n\r\n const prompt = await buildAgentPrompt(definition, taskContext);\r\n console.log(` ✓ Prompt size: ${prompt.length} characters`);\r\n console.log(` ✓ CFN Loop protocol: ${prompt.includes('CFN Loop Redis Completion Protocol') ? 'included' : 'not applicable'}`);\r\n console.log(` ✓ Iteration history: ${prompt.includes('## Iteration History') ? 'included' : 'not applicable'}`);\r\n console.log('');\r\n\r\n // Step 3: Execute agent\r\n console.log('[3/3] Executing agent...');\r\n const result = await executeAgent(definition, prompt, taskContext);\r\n\r\n console.log('');\r\n console.log('=== Execution Result ===');\r\n console.log(`Agent ID: ${result.agentId}`);\r\n console.log(`Status: ${result.success ? '✓ Success' : '✗ Failed'}`);\r\n console.log(`Exit Code: ${result.exitCode}`);\r\n\r\n if (result.error) {\r\n console.error(`Error: ${result.error}`);\r\n process.exit(1);\r\n }\r\n\r\n if (result.output) {\r\n console.log('\\nOutput:');\r\n console.log(result.output);\r\n }\r\n\r\n process.exit(result.exitCode);\r\n } catch (error) {\r\n console.error('\\n[agent-command] Error:', error instanceof Error ? error.message : String(error));\r\n process.exit(1);\r\n }\r\n}\r\n"],"names":["parseAgentDefinition","listAgentDefinitions","buildAgentPrompt","executeAgent","displayAgentHelp","console","log","listAgents","agents","length","grouped","agent","parts","split","category","name","slice","join","push","names","Object","entries","sort","agentCommand","agentType","options","list","help","memoryLimit","currentOptions","process","env","NODE_OPTIONS","newOptions","replace","enableProfiling","debug","includes","CLAUDE_DEBUG","CLAUDE_MEMORY_MONITORING","definition","type","model","tools","taskContext","taskId","iteration","agentId","context","mode","priority","parentTaskId","prompt","result","success","exitCode","error","exit","output","Error","message","String"],"mappings":"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"}
|