claude-flow-novice 2.14.34 → 2.14.36
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_TASK_MODE.md +1 -1
- package/.claude/commands/switch-api.md +1 -1
- package/.claude/skills/cfn-agent-discovery/agents-registry.json +1 -1
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +2 -1
- package/.claude/skills/cfn-loop-validation/config.json +2 -2
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +221 -0
- package/claude-assets/agents/README-AGENT_LIFECYCLE.md +37 -10
- package/claude-assets/agents/README-VALIDATION.md +0 -8
- package/claude-assets/agents/cfn-dev-team/README.md +0 -8
- package/claude-assets/agents/cfn-dev-team/coordinators/README.md +1 -9
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +565 -565
- package/claude-assets/agents/cfn-dev-team/developers/README.md +1 -9
- package/claude-assets/agents/cfn-dev-team/documentation/README-VALIDATION.md +0 -8
- package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md +0 -10
- package/claude-assets/agents/cfn-dev-team/reviewers/README.md +1 -9
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +0 -10
- package/claude-assets/agents/cfn-dev-team/test-agent.md +0 -10
- package/claude-assets/agents/cfn-dev-team/testers/README.md +1 -9
- package/claude-assets/agents/csuite/cto-agent.md +0 -10
- package/claude-assets/agents/custom/cfn-system-expert.md +1 -128
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +1 -5
- package/claude-assets/agents/docker-team/csuite/c-suite-template.md +1 -5
- package/claude-assets/agents/docker-team/infrastructure/team-coordinator-template.md +1 -5
- package/claude-assets/agents/marketing_hybrid/cost_tracker.md +0 -10
- package/claude-assets/agents/marketing_hybrid/docker_deployer.md +0 -10
- package/claude-assets/agents/marketing_hybrid/zai_worker_spawner.md +0 -10
- package/claude-assets/commands/CFN_LOOP_TASK_MODE.md +1 -1
- package/claude-assets/commands/switch-api.md +1 -1
- package/claude-assets/skills/cfn-agent-discovery/agents-registry.json +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +2 -1
- package/claude-assets/skills/cfn-loop-validation/config.json +2 -2
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +324 -322
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +221 -0
- package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +2 -2
- package/claude-assets/skills/cfn-task-mode-sanitize/task-mode-env-sanitizer.sh +213 -182
- package/claude-assets/skills/cfn-validation-runner-instrumentation/wrapped-executor.sh +233 -271
- package/dist/cli/agent-definition-parser.js.map +1 -1
- package/dist/cli/config-manager.js +109 -91
- package/package.json +1 -1
- package/scripts/docker-build-mcp.sh +155 -0
- package/scripts/docker-test-mcp.sh +260 -0
- package/scripts/mcp-health-check.sh +123 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Invoke Waiting Mode - Agent Coordination for CFN Loop
|
|
4
|
+
# Purpose: Handle coordination between agents using waiting mode and collection
|
|
5
|
+
# Usage: invoke-waiting-mode.sh <collect|wait|signal> [task-id] [agent-id] [timeout]
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
REDIS_COORD_SKILL="$SCRIPT_DIR"
|
|
12
|
+
|
|
13
|
+
# Parse arguments
|
|
14
|
+
COMMAND=${1:-"collect"}
|
|
15
|
+
TASK_ID=${2:-""}
|
|
16
|
+
AGENT_ID=${3:-""}
|
|
17
|
+
TIMEOUT=${4:-120}
|
|
18
|
+
|
|
19
|
+
# Redis configuration
|
|
20
|
+
REDIS_HOST=${REDIS_HOST:-"localhost"}
|
|
21
|
+
REDIS_PORT=${REDIS_PORT:-6379}
|
|
22
|
+
REDIS_DB=${REDIS_DB:-0}
|
|
23
|
+
|
|
24
|
+
# Debug output
|
|
25
|
+
DEBUG=${DEBUG:-false}
|
|
26
|
+
if [[ "$DEBUG" == "true" ]]; then
|
|
27
|
+
echo "DEBUG: invoke-waiting-mode called with: $*" >&2
|
|
28
|
+
echo "DEBUG: REDIS_HOST=$REDIS_HOST, REDIS_PORT=$REDIS_PORT, REDIS_DB=$REDIS_DB" >&2
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Function to connect to Redis with error handling
|
|
32
|
+
redis_cmd() {
|
|
33
|
+
local cmd="$1"
|
|
34
|
+
shift
|
|
35
|
+
|
|
36
|
+
if command -v redis-cli >/dev/null 2>&1; then
|
|
37
|
+
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -n "$REDIS_DB" "$cmd" "$@" 2>/dev/null
|
|
38
|
+
else
|
|
39
|
+
echo "Warning: redis-cli not available, using mock mode" >&2
|
|
40
|
+
return 0
|
|
41
|
+
fi
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Function to collect agent signals
|
|
45
|
+
collect_signals() {
|
|
46
|
+
local task_id="$1"
|
|
47
|
+
local agent_type="$2"
|
|
48
|
+
local timeout="${3:-120}"
|
|
49
|
+
|
|
50
|
+
echo "📡 Collecting ${agent_type} signals for task: $task_id (timeout: ${timeout}s)" >&2
|
|
51
|
+
|
|
52
|
+
local signals_key="swarm:${task_id}:signals:${agent_type}"
|
|
53
|
+
local start_time=$(date +%s)
|
|
54
|
+
local signals_collected=()
|
|
55
|
+
|
|
56
|
+
while true; do
|
|
57
|
+
# Get all available signals
|
|
58
|
+
local signals=($(redis_cmd SMEMBERS "$signals_key" 2>/dev/null || echo ""))
|
|
59
|
+
|
|
60
|
+
if [[ ${#signals[@]} -gt 0 ]]; then
|
|
61
|
+
for signal in "${signals[@]}"; do
|
|
62
|
+
if [[ ! " ${signals_collected[@]} " =~ " ${signal} " ]]; then
|
|
63
|
+
signals_collected+=("$signal")
|
|
64
|
+
echo " ✓ Signal collected: $signal" >&2
|
|
65
|
+
|
|
66
|
+
# Get detailed signal data
|
|
67
|
+
local signal_key="swarm:${task_id}:agent:${signal}:data"
|
|
68
|
+
local signal_data=$(redis_cmd HGETALL "$signal_key" 2>/dev/null || echo "")
|
|
69
|
+
|
|
70
|
+
if [[ -n "$signal_data" ]]; then
|
|
71
|
+
echo " Data: $signal_data" >&2
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Check if we have all expected signals (this would be based on agent count)
|
|
78
|
+
local expected_signals=${EXPECTED_AGENTS:-1}
|
|
79
|
+
if [[ ${#signals_collected[@]} -ge $expected_signals ]]; then
|
|
80
|
+
echo "✅ All signals collected" >&2
|
|
81
|
+
break
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Check timeout
|
|
85
|
+
local current_time=$(date +%s)
|
|
86
|
+
if [[ $((current_time - start_time)) -ge $timeout ]]; then
|
|
87
|
+
echo "⚠️ Timeout reached, proceeding with collected signals" >&2
|
|
88
|
+
break
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
sleep 2
|
|
92
|
+
done
|
|
93
|
+
|
|
94
|
+
# Return collected signals as JSON
|
|
95
|
+
local json_output="{"
|
|
96
|
+
json_output+="\"task_id\":\"$task_id\","
|
|
97
|
+
json_output+="\"agent_type\":\"$agent_type\","
|
|
98
|
+
json_output+="\"signals\":["
|
|
99
|
+
|
|
100
|
+
for i in "${!signals_collected[@]}"; do
|
|
101
|
+
if [[ $i -gt 0 ]]; then
|
|
102
|
+
json_output+=","
|
|
103
|
+
fi
|
|
104
|
+
json_output+='"'"${signals_collected[$i]}"'"'
|
|
105
|
+
done
|
|
106
|
+
|
|
107
|
+
json_output+="],"
|
|
108
|
+
json_output+="\"count\":${#signals_collected[@]},"
|
|
109
|
+
json_output+="\"timeout\":$timeout"
|
|
110
|
+
json_output+="}"
|
|
111
|
+
|
|
112
|
+
echo "$json_output"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Function to wait for specific condition
|
|
116
|
+
wait_for_signal() {
|
|
117
|
+
local task_id="$1"
|
|
118
|
+
local condition="$2"
|
|
119
|
+
local timeout="${3:-120}"
|
|
120
|
+
|
|
121
|
+
echo "⏳ Waiting for signal: $condition (timeout: ${timeout}s)" >&2
|
|
122
|
+
|
|
123
|
+
local start_time=$(date +%s)
|
|
124
|
+
local condition_key="swarm:${task_id}:condition:${condition}"
|
|
125
|
+
|
|
126
|
+
while true; do
|
|
127
|
+
local condition_met=$(redis_cmd GET "$condition_key" 2>/dev/null || echo "")
|
|
128
|
+
|
|
129
|
+
if [[ "$condition_met" == "true" ]]; then
|
|
130
|
+
echo "✅ Condition met: $condition" >&2
|
|
131
|
+
redis_cmd DEL "$condition_key" 2>/dev/null
|
|
132
|
+
echo "true"
|
|
133
|
+
return 0
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# Check timeout
|
|
137
|
+
local current_time=$(date +%s)
|
|
138
|
+
if [[ $((current_time - start_time)) -ge $timeout ]]; then
|
|
139
|
+
echo "⚠️ Timeout waiting for: $condition" >&2
|
|
140
|
+
echo "false"
|
|
141
|
+
return 1
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
sleep 2
|
|
145
|
+
done
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Function to signal completion
|
|
149
|
+
signal_completion() {
|
|
150
|
+
local task_id="$1"
|
|
151
|
+
local agent_id="$2"
|
|
152
|
+
local status="${3:-complete}"
|
|
153
|
+
|
|
154
|
+
echo "📤 Signaling completion: $agent_id -> $status" >&2
|
|
155
|
+
|
|
156
|
+
# Add to completed set
|
|
157
|
+
redis_cmd SADD "swarm:${task_id}:completed" "$agent_id" 2>/dev/null || true
|
|
158
|
+
|
|
159
|
+
# Set completion status
|
|
160
|
+
redis_cmd HSET "swarm:${task_id}:agent:${agent_id}:status" "status" "$status" 2>/dev/null || true
|
|
161
|
+
redis_cmd HSET "swarm:${task_id}:agent:${agent_id}:status" "completed_at" "$(date +%s)" 2>/dev/null || true
|
|
162
|
+
|
|
163
|
+
# Broadcast completion signal
|
|
164
|
+
redis_cmd PUBLISH "swarm:${task_id}:signals" "agent:$agent_id:status:$status" 2>/dev/null || true
|
|
165
|
+
|
|
166
|
+
echo "✅ Signal sent: $agent_id completed"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Main command routing
|
|
170
|
+
case "$COMMAND" in
|
|
171
|
+
"collect")
|
|
172
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
173
|
+
echo "Error: collect command requires task-id" >&2
|
|
174
|
+
echo "Usage: $0 collect <task-id> <agent-type> [timeout]" >&2
|
|
175
|
+
exit 1
|
|
176
|
+
fi
|
|
177
|
+
collect_signals "$TASK_ID" "${AGENT_ID:-"loop3"}" "$TIMEOUT"
|
|
178
|
+
;;
|
|
179
|
+
"wait")
|
|
180
|
+
if [[ -z "$TASK_ID" ]] || [[ -z "$AGENT_ID" ]]; then
|
|
181
|
+
echo "Error: wait command requires task-id and condition" >&2
|
|
182
|
+
echo "Usage: $0 wait <task-id> <condition> [timeout]" >&2
|
|
183
|
+
exit 1
|
|
184
|
+
fi
|
|
185
|
+
wait_for_signal "$TASK_ID" "$AGENT_ID" "$TIMEOUT"
|
|
186
|
+
;;
|
|
187
|
+
"signal")
|
|
188
|
+
if [[ -z "$TASK_ID" ]] || [[ -z "$AGENT_ID" ]]; then
|
|
189
|
+
echo "Error: signal command requires task-id and agent-id" >&2
|
|
190
|
+
echo "Usage: $0 signal <task-id> <agent-id> [status]" >&2
|
|
191
|
+
exit 1
|
|
192
|
+
fi
|
|
193
|
+
signal_completion "$TASK_ID" "$AGENT_ID" "$TIMEOUT"
|
|
194
|
+
;;
|
|
195
|
+
"help"|"-h"|"--help")
|
|
196
|
+
cat <<EOF
|
|
197
|
+
Usage: $0 <command> [arguments]
|
|
198
|
+
|
|
199
|
+
Commands:
|
|
200
|
+
collect <task-id> <agent-type> [timeout] Collect signals from agents
|
|
201
|
+
wait <task-id> <condition> [timeout] Wait for condition to be met
|
|
202
|
+
signal <task-id> <agent-id> [status] Signal agent completion
|
|
203
|
+
|
|
204
|
+
Examples:
|
|
205
|
+
$0 collect cfn-cli-12345 loop3 300
|
|
206
|
+
$0 wait cfn-cli-12345 gate-passed 60
|
|
207
|
+
$0 signal cfn-cli-12345 backend-developer-1 complete
|
|
208
|
+
|
|
209
|
+
Environment Variables:
|
|
210
|
+
REDIS_HOST Redis host (default: localhost)
|
|
211
|
+
REDIS_PORT Redis port (default: 6379)
|
|
212
|
+
REDIS_DB Redis database (default: 0)
|
|
213
|
+
DEBUG Enable debug output (true/false)
|
|
214
|
+
EOF
|
|
215
|
+
;;
|
|
216
|
+
*)
|
|
217
|
+
echo "Error: Unknown command '$COMMAND'" >&2
|
|
218
|
+
echo "Use '$0 help' for usage information" >&2
|
|
219
|
+
exit 1
|
|
220
|
+
;;
|
|
221
|
+
esac
|
|
@@ -186,8 +186,8 @@ select_agents() {
|
|
|
186
186
|
fi
|
|
187
187
|
|
|
188
188
|
# Loop 2 validators (adaptive scaling)
|
|
189
|
-
# Standard: 3-5 files → add
|
|
190
|
-
loop2+=("
|
|
189
|
+
# Standard: 3-5 files → add architect, security
|
|
190
|
+
loop2+=("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
|
|
@@ -1,224 +1,255 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
##############################################################################
|
|
2
4
|
# CFN Task Mode Environment Sanitizer
|
|
3
|
-
#
|
|
5
|
+
# Prevents memory leaks and environment contamination in CFN Loop execution
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# source task-mode-env-sanitizer.sh
|
|
9
|
+
# sanitize_task_mode_environment <mode>
|
|
10
|
+
#
|
|
11
|
+
# Modes:
|
|
12
|
+
# cli - CLI mode execution (production)
|
|
13
|
+
# task - Task mode execution (debugging)
|
|
14
|
+
##############################################################################
|
|
4
15
|
|
|
5
16
|
set -euo pipefail
|
|
6
17
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
# Global state tracking
|
|
19
|
+
declare -A CFN_SANITIZER_STATE
|
|
20
|
+
CFN_SANITIZER_STATE["initialized"]=false
|
|
21
|
+
CFN_SANITIZER_STATE["mode"]=""
|
|
22
|
+
CFN_SANITIZER_STATE["start_time"]=$(date +%s)
|
|
23
|
+
|
|
24
|
+
# Memory leak prevention thresholds
|
|
25
|
+
readonly MAX_AGENT_PROCESSES=50
|
|
26
|
+
readonly MAX_MEMORY_MB=4096
|
|
27
|
+
readonly MAX_RUNTIME_SECONDS=3600 # 1 hour
|
|
28
|
+
|
|
29
|
+
##############################################################################
|
|
30
|
+
# Core Sanitization Functions
|
|
31
|
+
##############################################################################
|
|
10
32
|
|
|
11
|
-
# Environment sanitization rules
|
|
12
33
|
sanitize_task_mode_environment() {
|
|
13
|
-
local mode="${1:-
|
|
34
|
+
local mode="${1:-task}"
|
|
35
|
+
|
|
36
|
+
# Initialize sanitizer state
|
|
37
|
+
CFN_SANITIZER_STATE["mode"]="$mode"
|
|
38
|
+
CFN_SANITIZER_STATE["initialized"]=true
|
|
39
|
+
|
|
40
|
+
echo "🧹 CFN Environment Sanitizer v1.0.0" >&2
|
|
41
|
+
echo " Mode: $mode" >&2
|
|
42
|
+
echo " PID: $$" >&2
|
|
43
|
+
echo " Start: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >&2
|
|
44
|
+
|
|
45
|
+
# Apply mode-specific sanitization
|
|
46
|
+
case "$mode" in
|
|
47
|
+
"cli")
|
|
48
|
+
sanitize_cli_environment
|
|
49
|
+
;;
|
|
50
|
+
"task")
|
|
51
|
+
sanitize_task_environment
|
|
52
|
+
;;
|
|
53
|
+
*)
|
|
54
|
+
echo "⚠️ Unknown mode: $mode, applying default sanitization" >&2
|
|
55
|
+
sanitize_default_environment
|
|
56
|
+
;;
|
|
57
|
+
esac
|
|
58
|
+
|
|
59
|
+
# Setup monitoring and cleanup hooks
|
|
60
|
+
setup_environment_monitoring
|
|
61
|
+
setup_cleanup_hooks
|
|
62
|
+
|
|
63
|
+
echo "✅ Environment sanitization complete" >&2
|
|
64
|
+
}
|
|
14
65
|
|
|
15
|
-
|
|
66
|
+
sanitize_cli_environment() {
|
|
67
|
+
echo " Applying CLI mode sanitization..." >&2
|
|
16
68
|
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
fi
|
|
69
|
+
# Clear any previous agent state
|
|
70
|
+
unset AGENT_ID 2>/dev/null || true
|
|
71
|
+
unset TASK_ID 2>/dev/null || true
|
|
72
|
+
unset SWARM_ID 2>/dev/null || true
|
|
22
73
|
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"AGENT_ID"
|
|
27
|
-
"LOOP3_AGENTS"
|
|
28
|
-
"LOOP2_VALIDATORS"
|
|
29
|
-
"PRODUCT_OWNER_ID"
|
|
30
|
-
"COORDINATOR_ID"
|
|
31
|
-
"__CFN_CLI_SPAWN"
|
|
32
|
-
"CFN_CLI_CONTEXT"
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
for var in "${inherited_vars[@]}"; do
|
|
36
|
-
if [[ -n "${!var:-}" ]]; then
|
|
37
|
-
echo "🗑️ Clearing inherited variable: $var (was: ${!var})" >&2
|
|
38
|
-
unset "$var"
|
|
39
|
-
fi
|
|
40
|
-
done
|
|
41
|
-
|
|
42
|
-
# 3. Set Task-mode specific environment
|
|
43
|
-
export __CFN_TASK_MODE="1"
|
|
44
|
-
export __CFN_MODE_ENFORCED="1"
|
|
45
|
-
|
|
46
|
-
# 4. Right-size Node.js heap for Task mode (prevent 16GB default)
|
|
47
|
-
if [[ -z "${NODE_OPTIONS:-}" ]]; then
|
|
48
|
-
export NODE_OPTIONS="--max-old-space-size=2048"
|
|
49
|
-
else
|
|
50
|
-
# Replace any larger heap size with Task-mode appropriate size
|
|
51
|
-
if echo "$NODE_OPTIONS" | grep -q "max-old-space-size"; then
|
|
52
|
-
export NODE_OPTIONS=$(echo "$NODE_OPTIONS" | sed 's/--max-old-space-size=[0-9]*/--max-old-space-size=2048/g')
|
|
53
|
-
else
|
|
54
|
-
export NODE_OPTIONS="$NODE_OPTIONS --max-old-space-size=2048"
|
|
55
|
-
fi
|
|
56
|
-
fi
|
|
57
|
-
echo "✅ NODE_OPTIONS set for Task mode: $NODE_OPTIONS" >&2
|
|
74
|
+
# Optimize for production CLI execution
|
|
75
|
+
export CFN_MODE="cli"
|
|
76
|
+
export CFN_SANITIZER_ACTIVE=true
|
|
58
77
|
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export CFN_COORDINATION="file" # Use file-based coordination
|
|
78
|
+
# Set conservative resource limits
|
|
79
|
+
ulimit -u $MAX_AGENT_PROCESSES 2>/dev/null || true
|
|
80
|
+
ulimit -v $((MAX_MEMORY_MB * 1024)) 2>/dev/null || true
|
|
63
81
|
|
|
64
|
-
|
|
82
|
+
# Disable debug features in production
|
|
83
|
+
export CFN_DEBUG=false
|
|
84
|
+
export CFN_VERBOSE=false
|
|
65
85
|
}
|
|
66
86
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
local errors=0
|
|
87
|
+
sanitize_task_environment() {
|
|
88
|
+
echo " Applying Task mode sanitization..." >&2
|
|
70
89
|
|
|
71
|
-
|
|
90
|
+
# Task mode allows more debugging
|
|
91
|
+
export CFN_MODE="task"
|
|
92
|
+
export CFN_SANITIZER_ACTIVE=true
|
|
72
93
|
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
((errors++))
|
|
77
|
-
fi
|
|
94
|
+
# More permissive limits for debugging
|
|
95
|
+
ulimit -u $((MAX_AGENT_PROCESSES * 2)) 2>/dev/null || true
|
|
96
|
+
ulimit -v $((MAX_MEMORY_MB * 1024 * 2)) 2>/dev/null || true
|
|
78
97
|
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
fi
|
|
98
|
+
# Enable debug features for task mode
|
|
99
|
+
export CFN_DEBUG=${CFN_DEBUG:-true}
|
|
100
|
+
export CFN_VERBOSE=${CFN_VERBOSE:-true}
|
|
101
|
+
}
|
|
84
102
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"TASK_ID"
|
|
88
|
-
"AGENT_ID"
|
|
89
|
-
"LOOP3_AGENTS"
|
|
90
|
-
"__CFN_CLI_SPAWN"
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
for var in "${prohibited_vars[@]}"; do
|
|
94
|
-
if [[ -n "${!var:-}" ]]; then
|
|
95
|
-
echo "❌ Prohibited CLI variable found: $var=${!var}" >&2
|
|
96
|
-
((errors++))
|
|
97
|
-
fi
|
|
98
|
-
done
|
|
99
|
-
|
|
100
|
-
# Check Node heap size
|
|
101
|
-
if echo "$NODE_OPTIONS" | grep -q "max-old-space-size"; then
|
|
102
|
-
local heap_size=$(echo "$NODE_OPTIONS" | grep -o "max-old-space-size=[0-9]*" | cut -d= -f2)
|
|
103
|
-
if [[ "$heap_size" -gt 4096 ]]; then
|
|
104
|
-
echo "❌ Node heap size too large for Task mode: ${heap_size}MB" >&2
|
|
105
|
-
((errors++))
|
|
106
|
-
fi
|
|
107
|
-
else
|
|
108
|
-
echo "⚠️ No Node heap size specified (should be set to 2048MB)" >&2
|
|
109
|
-
fi
|
|
103
|
+
sanitize_default_environment() {
|
|
104
|
+
echo " Applying default sanitization..." >&2
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
# Basic sanitization for unknown modes
|
|
107
|
+
export CFN_MODE="unknown"
|
|
108
|
+
export CFN_SANITIZER_ACTIVE=true
|
|
109
|
+
|
|
110
|
+
# Conservative limits
|
|
111
|
+
ulimit -u $MAX_AGENT_PROCESSES 2>/dev/null || true
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
##############################################################################
|
|
115
|
+
# Environment Monitoring
|
|
116
|
+
##############################################################################
|
|
117
|
+
|
|
118
|
+
setup_environment_monitoring() {
|
|
119
|
+
# Start background monitoring if available
|
|
120
|
+
if command -v timeout >/dev/null 2>&1; then
|
|
121
|
+
(
|
|
122
|
+
sleep $MAX_RUNTIME_SECONDS
|
|
123
|
+
if [[ "${CFN_SANITIZER_STATE[initialized]}" == "true" ]]; then
|
|
124
|
+
echo "⚠️ CFN Environment timeout reached, forcing cleanup" >&2
|
|
125
|
+
force_environment_cleanup
|
|
126
|
+
fi
|
|
127
|
+
) &
|
|
128
|
+
echo " Started runtime monitoring (${MAX_RUNTIME_SECONDS}s)" >&2
|
|
117
129
|
fi
|
|
118
130
|
}
|
|
119
131
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
132
|
+
setup_cleanup_hooks() {
|
|
133
|
+
# Setup cleanup trap for graceful shutdown
|
|
134
|
+
trap 'environment_cleanup_on_exit' EXIT
|
|
135
|
+
trap 'environment_cleanup_on_signal INT' INT
|
|
136
|
+
trap 'environment_cleanup_on_signal TERM' TERM
|
|
137
|
+
trap 'environment_cleanup_on_signal HUP' HUP
|
|
138
|
+
}
|
|
124
139
|
|
|
125
|
-
|
|
140
|
+
environment_cleanup_on_exit() {
|
|
141
|
+
echo "🧹 CFN Environment cleanup on exit" >&2
|
|
142
|
+
|
|
143
|
+
# Calculate runtime
|
|
144
|
+
local end_time=$(date +%s)
|
|
145
|
+
local runtime=$((end_time - CFN_SANITIZER_STATE["start_time"]))
|
|
146
|
+
echo " Runtime: ${runtime}s" >&2
|
|
147
|
+
|
|
148
|
+
# Mode-specific cleanup
|
|
149
|
+
case "${CFN_SANITIZER_STATE[mode]}" in
|
|
150
|
+
"cli")
|
|
151
|
+
cleanup_cli_environment
|
|
152
|
+
;;
|
|
153
|
+
"task")
|
|
154
|
+
cleanup_task_environment
|
|
155
|
+
;;
|
|
156
|
+
esac
|
|
157
|
+
|
|
158
|
+
# Clear sanitizer state
|
|
159
|
+
CFN_SANITIZER_STATE["initialized"]=false
|
|
160
|
+
echo "✅ Environment cleanup complete" >&2
|
|
161
|
+
}
|
|
126
162
|
|
|
127
|
-
|
|
128
|
-
|
|
163
|
+
environment_cleanup_on_signal() {
|
|
164
|
+
local signal="$1"
|
|
165
|
+
echo "🧹 CFN Environment cleanup on signal: $signal" >&2
|
|
166
|
+
environment_cleanup_on_exit
|
|
167
|
+
exit 130
|
|
168
|
+
}
|
|
129
169
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
echo "❌ Environment validation failed, aborting execution" >&2
|
|
133
|
-
return 1
|
|
134
|
-
fi
|
|
170
|
+
cleanup_cli_environment() {
|
|
171
|
+
echo " CLI mode cleanup..." >&2
|
|
135
172
|
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
echo "✅ Command completed successfully" >&2
|
|
142
|
-
return 0
|
|
143
|
-
else
|
|
144
|
-
local exit_code=$?
|
|
145
|
-
if [[ $exit_code -eq 124 ]]; then
|
|
146
|
-
echo "⏰ Command timed out after ${timeout}s" >&2
|
|
147
|
-
else
|
|
148
|
-
echo "❌ Command failed with exit code: $exit_code" >&2
|
|
173
|
+
# Clean up any lingering agent processes
|
|
174
|
+
if command -v pgrep >/dev/null 2>&1; then
|
|
175
|
+
local agent_pids=$(pgrep -f "claude-flow-novice.*agent" 2>/dev/null || true)
|
|
176
|
+
if [[ -n "$agent_pids" ]]; then
|
|
177
|
+
echo " Warning: Found agent processes: $agent_pids" >&2
|
|
149
178
|
fi
|
|
150
|
-
return $exit_code
|
|
151
179
|
fi
|
|
152
180
|
}
|
|
153
181
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
182
|
+
cleanup_task_environment() {
|
|
183
|
+
echo " Task mode cleanup..." >&2
|
|
184
|
+
# Task mode cleanup - more permissive
|
|
185
|
+
}
|
|
158
186
|
|
|
159
|
-
|
|
160
|
-
|
|
187
|
+
force_environment_cleanup() {
|
|
188
|
+
echo "🚨 Force cleanup triggered!" >&2
|
|
161
189
|
|
|
162
|
-
#
|
|
163
|
-
|
|
164
|
-
|
|
190
|
+
# Kill any remaining processes in this process group
|
|
191
|
+
if [[ -n "${CFN_PROCESS_GROUP:-}" ]]; then
|
|
192
|
+
kill -TERM -$CFN_PROCESS_GROUP 2>/dev/null || true
|
|
193
|
+
sleep 2
|
|
194
|
+
kill -KILL -$CFN_PROCESS_GROUP 2>/dev/null || true
|
|
195
|
+
fi
|
|
165
196
|
|
|
166
|
-
#
|
|
167
|
-
|
|
197
|
+
# Force exit
|
|
198
|
+
exit 1
|
|
199
|
+
}
|
|
168
200
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
201
|
+
##############################################################################
|
|
202
|
+
# Utility Functions
|
|
203
|
+
##############################################################################
|
|
172
204
|
|
|
173
|
-
|
|
174
|
-
|
|
205
|
+
check_environment_health() {
|
|
206
|
+
local mode="${1:-${CFN_SANITIZER_STATE[mode]}}"
|
|
175
207
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
208
|
+
if [[ "${CFN_SANITIZER_STATE[initialized]}" != "true" ]]; then
|
|
209
|
+
echo "❌ Environment sanitizer not initialized" >&2
|
|
210
|
+
return 1
|
|
179
211
|
fi
|
|
180
212
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
213
|
+
# Check memory usage
|
|
214
|
+
if command -v ps >/dev/null 2>&1; then
|
|
215
|
+
local memory_mb=$(ps -o rss= -p $$ 2>/dev/null | awk '{print $1/1024}' || echo "0")
|
|
216
|
+
if (( $(echo "$memory_mb > $MAX_MEMORY_MB" | bc -l 2>/dev/null || echo "0") )); then
|
|
217
|
+
echo "⚠️ High memory usage: ${memory_mb}MB" >&2
|
|
218
|
+
fi
|
|
219
|
+
fi
|
|
188
220
|
|
|
189
|
-
|
|
221
|
+
# Check process count
|
|
222
|
+
if command -v ps >/dev/null 2>&1; then
|
|
223
|
+
local process_count=$(ps -eo pid=,ppid= | grep -c "^[[:space:]]*$$[[:space:]]" || echo "0")
|
|
224
|
+
if (( process_count > MAX_AGENT_PROCESSES )); then
|
|
225
|
+
echo "⚠️ High process count: $process_count" >&2
|
|
226
|
+
fi
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
echo "✅ Environment health check passed" >&2
|
|
230
|
+
return 0
|
|
190
231
|
}
|
|
191
232
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
233
|
+
get_sanitizer_info() {
|
|
234
|
+
echo "CFN Environment Sanitizer Info:"
|
|
235
|
+
echo " Initialized: ${CFN_SANITIZER_STATE[initialized]}"
|
|
236
|
+
echo " Mode: ${CFN_SANITIZER_STATE[mode]}"
|
|
237
|
+
echo " Start Time: ${CFN_SANITIZER_STATE[start_time]}"
|
|
238
|
+
echo " PID: $$"
|
|
239
|
+
echo " Runtime: $(($(date +%s) - CFN_SANITIZER_STATE[start_time]))s"
|
|
240
|
+
}
|
|
198
241
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
*)
|
|
213
|
-
echo "Unknown operation: $1" >&2
|
|
214
|
-
echo "Use --help for usage information" >&2
|
|
215
|
-
exit 1
|
|
216
|
-
;;
|
|
217
|
-
esac
|
|
218
|
-
else
|
|
219
|
-
echo "CFN Task Mode Environment Sanitizer" >&2
|
|
220
|
-
echo "Current mode: ${CFN_MODE:-unset}" >&2
|
|
221
|
-
echo "Node options: ${NODE_OPTIONS:-unset}" >&2
|
|
222
|
-
echo "Use --help for usage information" >&2
|
|
223
|
-
fi
|
|
242
|
+
##############################################################################
|
|
243
|
+
# Auto-initialization for safety
|
|
244
|
+
##############################################################################
|
|
245
|
+
|
|
246
|
+
# If script is sourced (not executed), make sanitizer available
|
|
247
|
+
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
|
|
248
|
+
echo "🔧 CFN Environment Sanitizer loaded" >&2
|
|
249
|
+
echo " Use: sanitize_task_mode_environment <mode>" >&2
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
# If script is executed directly, run with default mode
|
|
253
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
254
|
+
sanitize_task_mode_environment "${1:-task}"
|
|
224
255
|
fi
|