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,521 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# CFN Docker Agent Spawning Implementation
|
|
4
|
+
# Usage: ./spawn-agent.sh [AGENT_TYPE] [TASK_ID] [AGENT_ID] [OPTIONS]
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Default configuration
|
|
9
|
+
DEFAULT_MEMORY_LIMIT="1g"
|
|
10
|
+
DEFAULT_CPU_LIMIT="1.0"
|
|
11
|
+
DEFAULT_NETWORK="mcp-network"
|
|
12
|
+
DEFAULT_IMAGE="claude-flow-novice:agent"
|
|
13
|
+
|
|
14
|
+
# Colors for output
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
BLUE='\033[0;34m'
|
|
19
|
+
NC='\033[0m'
|
|
20
|
+
|
|
21
|
+
log() {
|
|
22
|
+
echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $*"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
log_success() {
|
|
26
|
+
echo -e "${GREEN}[SUCCESS]${NC} $*"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
log_error() {
|
|
30
|
+
echo -e "${RED}[ERROR]${NC} $*"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
log_warning() {
|
|
34
|
+
echo -e "${YELLOW}[WARNING]${NC} $*"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Function to display usage
|
|
38
|
+
usage() {
|
|
39
|
+
cat << EOF
|
|
40
|
+
CFN Docker Agent Spawning
|
|
41
|
+
|
|
42
|
+
Usage: $0 [AGENT_TYPE] [TASK_ID] [AGENT_ID] [OPTIONS]
|
|
43
|
+
|
|
44
|
+
Arguments:
|
|
45
|
+
AGENT_TYPE Type of agent to spawn (e.g., react-frontend-engineer, backend-developer)
|
|
46
|
+
TASK_ID CFN Loop task identifier
|
|
47
|
+
AGENT_ID Unique agent identifier (auto-generated if not provided)
|
|
48
|
+
|
|
49
|
+
Options:
|
|
50
|
+
--memory-limit LIMIT Memory limit for container (default: 1g)
|
|
51
|
+
--cpu-limit LIMIT CPU limit for container (default: 1.0)
|
|
52
|
+
--network NAME Docker network (default: mcp-network)
|
|
53
|
+
--image NAME Docker image (default: claude-flow-novice:agent)
|
|
54
|
+
--mcp-servers LIST Comma-separated list of MCP servers
|
|
55
|
+
--context FILE Task context file path
|
|
56
|
+
--environment LIST Additional environment variables (key=value,key2=value2)
|
|
57
|
+
--volume LIST Additional volume mounts (src:dst,src2:dst2)
|
|
58
|
+
--dry-run Show configuration without creating container
|
|
59
|
+
--detach Run container in detached mode (default)
|
|
60
|
+
--interactive Run container in interactive mode
|
|
61
|
+
--verbose Enable verbose logging
|
|
62
|
+
--help Show this help message
|
|
63
|
+
|
|
64
|
+
Examples:
|
|
65
|
+
$0 react-frontend-engineer task-123 agent-001
|
|
66
|
+
$0 backend-developer task-456 --memory-limit 2g --mcp-servers redis,postgres
|
|
67
|
+
$0 security-specialist task-789 --interactive --verbose
|
|
68
|
+
|
|
69
|
+
EOF
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Parse command line arguments
|
|
73
|
+
AGENT_TYPE=""
|
|
74
|
+
TASK_ID=""
|
|
75
|
+
AGENT_ID=""
|
|
76
|
+
MEMORY_LIMIT="$DEFAULT_MEMORY_LIMIT"
|
|
77
|
+
CPU_LIMIT="$DEFAULT_CPU_LIMIT"
|
|
78
|
+
NETWORK="$DEFAULT_NETWORK"
|
|
79
|
+
IMAGE="$DEFAULT_IMAGE"
|
|
80
|
+
MCP_SERVERS=""
|
|
81
|
+
CONTEXT_FILE=""
|
|
82
|
+
ENVIRONMENT=""
|
|
83
|
+
VOLUMES=""
|
|
84
|
+
DRY_RUN=false
|
|
85
|
+
DETACH=true
|
|
86
|
+
INTERACTIVE=false
|
|
87
|
+
VERBOSE=false
|
|
88
|
+
|
|
89
|
+
while [[ $# -gt 0 ]]; do
|
|
90
|
+
case $1 in
|
|
91
|
+
--memory-limit)
|
|
92
|
+
MEMORY_LIMIT="$2"
|
|
93
|
+
shift 2
|
|
94
|
+
;;
|
|
95
|
+
--cpu-limit)
|
|
96
|
+
CPU_LIMIT="$2"
|
|
97
|
+
shift 2
|
|
98
|
+
;;
|
|
99
|
+
--network)
|
|
100
|
+
NETWORK="$2"
|
|
101
|
+
shift 2
|
|
102
|
+
;;
|
|
103
|
+
--image)
|
|
104
|
+
IMAGE="$2"
|
|
105
|
+
shift 2
|
|
106
|
+
;;
|
|
107
|
+
--mcp-servers)
|
|
108
|
+
MCP_SERVERS="$2"
|
|
109
|
+
shift 2
|
|
110
|
+
;;
|
|
111
|
+
--context)
|
|
112
|
+
CONTEXT_FILE="$2"
|
|
113
|
+
shift 2
|
|
114
|
+
;;
|
|
115
|
+
--environment)
|
|
116
|
+
ENVIRONMENT="$2"
|
|
117
|
+
shift 2
|
|
118
|
+
;;
|
|
119
|
+
--volume)
|
|
120
|
+
VOLUMES="$2"
|
|
121
|
+
shift 2
|
|
122
|
+
;;
|
|
123
|
+
--dry-run)
|
|
124
|
+
DRY_RUN=true
|
|
125
|
+
shift
|
|
126
|
+
;;
|
|
127
|
+
--detach)
|
|
128
|
+
DETACH=true
|
|
129
|
+
shift
|
|
130
|
+
;;
|
|
131
|
+
--interactive)
|
|
132
|
+
INTERACTIVE=true
|
|
133
|
+
DETACH=false
|
|
134
|
+
shift
|
|
135
|
+
;;
|
|
136
|
+
--verbose)
|
|
137
|
+
VERBOSE=true
|
|
138
|
+
shift
|
|
139
|
+
;;
|
|
140
|
+
--help)
|
|
141
|
+
usage
|
|
142
|
+
exit 0
|
|
143
|
+
;;
|
|
144
|
+
-*)
|
|
145
|
+
log_error "Unknown option: $1"
|
|
146
|
+
usage
|
|
147
|
+
exit 1
|
|
148
|
+
;;
|
|
149
|
+
*)
|
|
150
|
+
if [[ -z "$AGENT_TYPE" ]]; then
|
|
151
|
+
AGENT_TYPE="$1"
|
|
152
|
+
elif [[ -z "$TASK_ID" ]]; then
|
|
153
|
+
TASK_ID="$1"
|
|
154
|
+
elif [[ -z "$AGENT_ID" ]]; then
|
|
155
|
+
AGENT_ID="$1"
|
|
156
|
+
else
|
|
157
|
+
log_error "Too many arguments"
|
|
158
|
+
usage
|
|
159
|
+
exit 1
|
|
160
|
+
fi
|
|
161
|
+
shift
|
|
162
|
+
;;
|
|
163
|
+
esac
|
|
164
|
+
done
|
|
165
|
+
|
|
166
|
+
# Validate required arguments
|
|
167
|
+
if [[ -z "$AGENT_TYPE" || -z "$TASK_ID" ]]; then
|
|
168
|
+
log_error "AGENT_TYPE and TASK_ID are required"
|
|
169
|
+
usage
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Generate agent ID if not provided
|
|
174
|
+
if [[ -z "$AGENT_ID" ]]; then
|
|
175
|
+
AGENT_ID="${AGENT_TYPE}-$(date +%s)-$(openssl rand -hex 4)"
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Configuration validation
|
|
179
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
180
|
+
log "Configuration:"
|
|
181
|
+
log " Agent Type: $AGENT_TYPE"
|
|
182
|
+
log " Task ID: $TASK_ID"
|
|
183
|
+
log " Agent ID: $AGENT_ID"
|
|
184
|
+
log " Memory Limit: $MEMORY_LIMIT"
|
|
185
|
+
log " CPU Limit: $CPU_LIMIT"
|
|
186
|
+
log " Network: $NETWORK"
|
|
187
|
+
log " Image: $IMAGE"
|
|
188
|
+
log " MCP Servers: ${MCP_SERVERS:-'auto-select'}"
|
|
189
|
+
log " Context File: ${CONTEXT_FILE:-'none'}"
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# Validate Docker is available
|
|
193
|
+
if ! command -v docker &> /dev/null; then
|
|
194
|
+
log_error "Docker is not installed or not in PATH"
|
|
195
|
+
exit 1
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
# Check if Docker daemon is running
|
|
199
|
+
if ! docker info &> /dev/null; then
|
|
200
|
+
log_error "Docker daemon is not running"
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# Validate Docker image exists
|
|
205
|
+
if ! docker image inspect "$IMAGE" &> /dev/null; then
|
|
206
|
+
log_error "Docker image '$IMAGE' not found"
|
|
207
|
+
log_error "Please build or pull the image first"
|
|
208
|
+
exit 1
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# Get project root directory
|
|
212
|
+
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
|
|
213
|
+
cd "$PROJECT_ROOT"
|
|
214
|
+
|
|
215
|
+
# Create workspace directory with proper permissions
|
|
216
|
+
WORKSPACE_DIR="/tmp/agent-workspace-${AGENT_ID}"
|
|
217
|
+
mkdir -p "$WORKSPACE_DIR"
|
|
218
|
+
chmod 777 "$WORKSPACE_DIR"
|
|
219
|
+
|
|
220
|
+
# Function to get MCP configuration for agent type
|
|
221
|
+
get_mcp_config() {
|
|
222
|
+
local agent_type="$1"
|
|
223
|
+
|
|
224
|
+
# Use skill-based MCP selection if available
|
|
225
|
+
if [[ -f ".claude/skills/cfn-docker-skill-mcp-selection/skill-mcp-selector.js" ]]; then
|
|
226
|
+
node .claude/skills/cfn-docker-skill-mcp-selection/skill-mcp-selector.js select \
|
|
227
|
+
--agent-type "$agent_type" 2>/dev/null || echo '{}'
|
|
228
|
+
else
|
|
229
|
+
# Fallback to basic configuration
|
|
230
|
+
echo '{"selectedMCPServers":[],"totalMemoryRequired":0,"totalCPURequired":0}'
|
|
231
|
+
fi
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
# Get MCP servers for agent
|
|
235
|
+
if [[ -z "$MCP_SERVERS" ]]; then
|
|
236
|
+
log "Auto-selecting MCP servers for agent type: $AGENT_TYPE"
|
|
237
|
+
MCP_CONFIG=$(get_mcp_config "$AGENT_TYPE")
|
|
238
|
+
MCP_SERVERS=$(echo "$MCP_CONFIG" | jq -r '.selectedMCPServers[]' | tr '\n' ',' | sed 's/,$//')
|
|
239
|
+
|
|
240
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
241
|
+
log "Auto-selected MCP servers: ${MCP_SERVERS:-'none'}"
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Function to generate MCP tokens
|
|
246
|
+
generate_mcp_tokens() {
|
|
247
|
+
local agent_type="$1"
|
|
248
|
+
local mcp_servers="$2"
|
|
249
|
+
local agent_id="$3"
|
|
250
|
+
|
|
251
|
+
if [[ -z "$mcp_servers" ]]; then
|
|
252
|
+
echo "{}"
|
|
253
|
+
return
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
# Use token manager if available
|
|
257
|
+
if [[ -f "src/cli/agent-token-manager.js" ]]; then
|
|
258
|
+
node src/cli/agent-token-manager.js register "$agent_type" \
|
|
259
|
+
--mcp-servers "$mcp_servers" --agent-id "$agent_id" 2>/dev/null || echo "{}"
|
|
260
|
+
else
|
|
261
|
+
# Fallback: generate simple token structure
|
|
262
|
+
local token=$(openssl rand -hex 32)
|
|
263
|
+
echo "{\"${mcp_servers}\":\"${token}\"}"
|
|
264
|
+
fi
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# Initialize MCP tokens variables
|
|
268
|
+
MCP_TOKENS=""
|
|
269
|
+
TOKENS_FILE=""
|
|
270
|
+
|
|
271
|
+
# Generate MCP tokens if MCP servers specified
|
|
272
|
+
if [[ -n "$MCP_SERVERS" ]]; then
|
|
273
|
+
log "Generating MCP tokens for: $MCP_SERVERS"
|
|
274
|
+
MCP_TOKENS=$(generate_mcp_tokens "$AGENT_TYPE" "$MCP_SERVERS" "$AGENT_ID")
|
|
275
|
+
|
|
276
|
+
# Write tokens to file
|
|
277
|
+
TOKENS_FILE="${WORKSPACE_DIR}/mcp-tokens.json"
|
|
278
|
+
echo "$MCP_TOKENS" > "$TOKENS_FILE"
|
|
279
|
+
|
|
280
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
281
|
+
log "MCP tokens written to: $TOKENS_FILE"
|
|
282
|
+
fi
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
# Build Docker command
|
|
286
|
+
DOCKER_CMD="docker run"
|
|
287
|
+
|
|
288
|
+
# Add container options
|
|
289
|
+
if [[ "$DETACH" == true ]]; then
|
|
290
|
+
DOCKER_CMD="$DOCKER_CMD --detach"
|
|
291
|
+
fi
|
|
292
|
+
|
|
293
|
+
if [[ "$INTERACTIVE" == true ]]; then
|
|
294
|
+
DOCKER_CMD="$DOCKER_CMD --interactive --tty"
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
# Container identification
|
|
298
|
+
DOCKER_CMD="$DOCKER_CMD --name agent-${AGENT_ID}"
|
|
299
|
+
DOCKER_CMD="$DOCKER_CMD --hostname agent-${AGENT_ID}"
|
|
300
|
+
|
|
301
|
+
# Resource limits
|
|
302
|
+
DOCKER_CMD="$DOCKER_CMD --memory ${MEMORY_LIMIT}"
|
|
303
|
+
DOCKER_CMD="$DOCKER_CMD --cpus ${CPU_LIMIT}"
|
|
304
|
+
|
|
305
|
+
# Networking
|
|
306
|
+
if docker network inspect "$NETWORK" &> /dev/null; then
|
|
307
|
+
DOCKER_CMD="$DOCKER_CMD --network ${NETWORK}"
|
|
308
|
+
else
|
|
309
|
+
log_warning "Docker network '$NETWORK' not found, container will use default network"
|
|
310
|
+
fi
|
|
311
|
+
|
|
312
|
+
# Volume mounts
|
|
313
|
+
DOCKER_CMD="$DOCKER_CMD --volume ${PROJECT_ROOT}/.claude:/app/.claude:ro"
|
|
314
|
+
DOCKER_CMD="$DOCKER_CMD --volume ${PROJECT_ROOT}/src:/app/src:ro"
|
|
315
|
+
DOCKER_CMD="$DOCKER_CMD --volume ${WORKSPACE_DIR}:/app/workspace"
|
|
316
|
+
|
|
317
|
+
# Add custom volumes
|
|
318
|
+
if [[ -n "$VOLUMES" ]]; then
|
|
319
|
+
IFS=',' read -ra VOLUME_ARRAY <<< "$VOLUMES"
|
|
320
|
+
for volume in "${VOLUME_ARRAY[@]}"; do
|
|
321
|
+
DOCKER_CMD="$DOCKER_CMD --volume $volume"
|
|
322
|
+
done
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
# Environment variables
|
|
326
|
+
DOCKER_CMD="$DOCKER_CMD --env AGENT_ID=${AGENT_ID}"
|
|
327
|
+
DOCKER_CMD="$DOCKER_CMD --env AGENT_TYPE=${AGENT_TYPE}"
|
|
328
|
+
DOCKER_CMD="$DOCKER_CMD --env TASK_ID=${TASK_ID}"
|
|
329
|
+
DOCKER_CMD="$DOCKER_CMD --env PROJECT_ROOT=/app"
|
|
330
|
+
|
|
331
|
+
# Add Redis URL if Redis is available
|
|
332
|
+
if command -v redis-cli &> /dev/null && redis-cli ping &> /dev/null; then
|
|
333
|
+
DOCKER_CMD="$DOCKER_CMD --env REDIS_URL=redis://redis:6379"
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
# Add MCP tokens file path if tokens generated
|
|
337
|
+
if [[ -n "$TOKENS_FILE" ]]; then
|
|
338
|
+
DOCKER_CMD="$DOCKER_CMD --env MCP_TOKENS_FILE=/app/workspace/mcp-tokens.json"
|
|
339
|
+
fi
|
|
340
|
+
|
|
341
|
+
# Add custom environment variables
|
|
342
|
+
if [[ -n "$ENVIRONMENT" ]]; then
|
|
343
|
+
IFS=',' read -ra ENV_ARRAY <<< "$ENVIRONMENT"
|
|
344
|
+
for env_var in "${ENV_ARRAY[@]}"; do
|
|
345
|
+
DOCKER_CMD="$DOCKER_CMD --env $env_var"
|
|
346
|
+
done
|
|
347
|
+
fi
|
|
348
|
+
|
|
349
|
+
# Check if this is a test mode (simple file operations) or full CFN mode
|
|
350
|
+
if [[ "${TASK_ID}" =~ concurrent-.* || "${TASK_ID}" =~ test-.* || "${TASK_ID}" =~ context-.* ]]; then
|
|
351
|
+
# Test mode - simple file operations without CFN coordination
|
|
352
|
+
# Use --rm flag for automatic cleanup, so we don't need the trap
|
|
353
|
+
DOCKER_CMD="$DOCKER_CMD --rm"
|
|
354
|
+
log "Test mode detected - using simple file operations with --rm flag"
|
|
355
|
+
else
|
|
356
|
+
# Full CFN mode - use agent-spawn with coordination
|
|
357
|
+
# Add restart policy (only for non-test modes)
|
|
358
|
+
DOCKER_CMD="$DOCKER_CMD --restart unless-stopped"
|
|
359
|
+
log "CFN mode detected - using agent coordination with shell wrapper"
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
# Add image and command
|
|
363
|
+
DOCKER_CMD="$DOCKER_CMD $IMAGE"
|
|
364
|
+
|
|
365
|
+
# Add the shell command
|
|
366
|
+
if [[ "${TASK_ID}" =~ concurrent-.* || "${TASK_ID}" =~ test-.* || "${TASK_ID}" =~ context-.* ]]; then
|
|
367
|
+
# Test mode command
|
|
368
|
+
DOCKER_CMD="$DOCKER_CMD sh -c 'cd /app/workspace && echo \"Task: ${TASK_ID}\" > task-info.txt && echo \"Agent: ${AGENT_TYPE}\" >> task-info.txt && echo \"Starting task execution...\" >> task-info.txt && sleep 3 && echo \"${AGENT_TYPE} task completed\" > ${AGENT_TYPE}-task-result.txt && echo \"Workspace verified\" > ${AGENT_TYPE}-workspace-check.txt && echo \"Task completed\" > ${AGENT_TYPE}-completion-log.txt && echo \"All files created successfully\" && ls -la && sleep 2'"
|
|
369
|
+
else
|
|
370
|
+
# Full CFN mode command
|
|
371
|
+
DOCKER_CMD="$DOCKER_CMD sh -c 'cd /app && npx claude-flow-novice agent-spawn --type ${AGENT_TYPE} --task-id ${TASK_ID} --agent-id ${AGENT_ID}'"
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
# Remove container on exit for interactive mode (not needed for test mode with --rm)
|
|
375
|
+
if [[ "$INTERACTIVE" == true && ! "${TASK_ID}" =~ concurrent-.* && ! "${TASK_ID}" =~ test-.* && ! "${TASK_ID}" =~ context-.* ]]; then
|
|
376
|
+
DOCKER_CMD="$DOCKER_CMD --rm"
|
|
377
|
+
fi
|
|
378
|
+
|
|
379
|
+
# Add context file if specified
|
|
380
|
+
if [[ -n "$CONTEXT_FILE" ]]; then
|
|
381
|
+
if [[ -f "$CONTEXT_FILE" ]]; then
|
|
382
|
+
DOCKER_CMD="$DOCKER_CMD --context $(cat "$CONTEXT_FILE")"
|
|
383
|
+
else
|
|
384
|
+
log_error "Context file not found: $CONTEXT_FILE"
|
|
385
|
+
exit 1
|
|
386
|
+
fi
|
|
387
|
+
fi
|
|
388
|
+
|
|
389
|
+
# Display configuration
|
|
390
|
+
log "Container Configuration:"
|
|
391
|
+
log " Agent ID: $AGENT_ID"
|
|
392
|
+
log " Agent Type: $AGENT_TYPE"
|
|
393
|
+
log " Task ID: $TASK_ID"
|
|
394
|
+
log " Memory Limit: $MEMORY_LIMIT"
|
|
395
|
+
log " CPU Limit: $CPU_LIMIT"
|
|
396
|
+
log " Network: $NETWORK"
|
|
397
|
+
log " Workspace: $WORKSPACE_DIR"
|
|
398
|
+
log " MCP Servers: ${MCP_SERVERS:-'none'}"
|
|
399
|
+
|
|
400
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
401
|
+
log " Docker Command: $DOCKER_CMD"
|
|
402
|
+
fi
|
|
403
|
+
|
|
404
|
+
# Debug: Show the exact command being executed
|
|
405
|
+
log "Executing: $DOCKER_CMD"
|
|
406
|
+
|
|
407
|
+
# Execute or show command
|
|
408
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
409
|
+
log "DRY RUN - Container not created"
|
|
410
|
+
log "Command: $DOCKER_CMD"
|
|
411
|
+
exit 0
|
|
412
|
+
fi
|
|
413
|
+
|
|
414
|
+
# Create container
|
|
415
|
+
log "Creating container: agent-${AGENT_ID}"
|
|
416
|
+
if ! CONTAINER_ID=$(eval "$DOCKER_CMD"); then
|
|
417
|
+
log_error "Failed to create container"
|
|
418
|
+
exit 1
|
|
419
|
+
fi
|
|
420
|
+
|
|
421
|
+
log_success "Container created successfully: $CONTAINER_ID"
|
|
422
|
+
|
|
423
|
+
# Wait for container to start (if detached)
|
|
424
|
+
if [[ "$DETACH" == true ]]; then
|
|
425
|
+
log "Waiting for container to start..."
|
|
426
|
+
sleep 3
|
|
427
|
+
|
|
428
|
+
# Check container status
|
|
429
|
+
if ! docker container inspect "$CONTAINER_ID" &> /dev/null; then
|
|
430
|
+
log_error "Container failed to start or was removed"
|
|
431
|
+
exit 1
|
|
432
|
+
fi
|
|
433
|
+
|
|
434
|
+
CONTAINER_STATUS=$(docker container inspect "$CONTAINER_ID" --format '{{.State.Status}}')
|
|
435
|
+
log "Container status: $CONTAINER_STATUS"
|
|
436
|
+
|
|
437
|
+
if [[ "$CONTAINER_STATUS" == "running" ]]; then
|
|
438
|
+
log_success "Agent container is running"
|
|
439
|
+
|
|
440
|
+
# Show initial logs if verbose
|
|
441
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
442
|
+
log "Initial container logs:"
|
|
443
|
+
docker logs "$CONTAINER_ID" --tail 10
|
|
444
|
+
fi
|
|
445
|
+
else
|
|
446
|
+
log_error "Container is not running (status: $CONTAINER_STATUS)"
|
|
447
|
+
docker logs "$CONTAINER_ID"
|
|
448
|
+
exit 1
|
|
449
|
+
fi
|
|
450
|
+
fi
|
|
451
|
+
|
|
452
|
+
# Output container information
|
|
453
|
+
cat << EOF
|
|
454
|
+
|
|
455
|
+
Agent Container Information:
|
|
456
|
+
============================
|
|
457
|
+
Container ID: $CONTAINER_ID
|
|
458
|
+
Agent ID: $AGENT_ID
|
|
459
|
+
Agent Type: $AGENT_TYPE
|
|
460
|
+
Task ID: $TASK_ID
|
|
461
|
+
Network: $NETWORK
|
|
462
|
+
Memory Limit: $MEMORY_LIMIT
|
|
463
|
+
CPU Limit: $CPU_LIMIT
|
|
464
|
+
Workspace: $WORKSPACE_DIR
|
|
465
|
+
MCP Servers: ${MCP_SERVERS:-'none'}
|
|
466
|
+
|
|
467
|
+
Useful Commands:
|
|
468
|
+
---------------
|
|
469
|
+
# View container logs:
|
|
470
|
+
docker logs -f $CONTAINER_ID
|
|
471
|
+
|
|
472
|
+
# Execute commands in container:
|
|
473
|
+
docker exec -it $CONTAINER_ID bash
|
|
474
|
+
|
|
475
|
+
# Stop container:
|
|
476
|
+
docker stop $CONTAINER_ID
|
|
477
|
+
|
|
478
|
+
# Remove container:
|
|
479
|
+
docker rm $CONTAINER_ID
|
|
480
|
+
|
|
481
|
+
# View resource usage:
|
|
482
|
+
docker stats $CONTAINER_ID
|
|
483
|
+
|
|
484
|
+
EOF
|
|
485
|
+
|
|
486
|
+
# Add cleanup trap for automatic resource cleanup (only for non-test modes)
|
|
487
|
+
cleanup_on_exit() {
|
|
488
|
+
local exit_code=$?
|
|
489
|
+
|
|
490
|
+
if [[ -n "${CONTAINER_ID:-}" ]]; then
|
|
491
|
+
log "🧹 Cleaning up container: ${CONTAINER_ID}"
|
|
492
|
+
|
|
493
|
+
# Stop container if still running
|
|
494
|
+
if docker inspect "${CONTAINER_ID}" &> /dev/null; then
|
|
495
|
+
local container_status=$(docker inspect --format '{{.State.Status}}' "${CONTAINER_ID}" 2>/dev/null || echo "unknown")
|
|
496
|
+
|
|
497
|
+
if [[ "$container_status" == "running" ]]; then
|
|
498
|
+
docker stop "${CONTAINER_ID}" 2>/dev/null || log_warning "Failed to stop container"
|
|
499
|
+
fi
|
|
500
|
+
|
|
501
|
+
# Remove container
|
|
502
|
+
docker rm "${CONTAINER_ID}" 2>/dev/null || log_warning "Failed to remove container"
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
# Clean up workspace directory
|
|
506
|
+
if [[ -n "${WORKSPACE_DIR:-}" && -d "${WORKSPACE_DIR}" ]]; then
|
|
507
|
+
log "🧹 Cleaning up workspace: ${WORKSPACE_DIR}"
|
|
508
|
+
rm -rf "${WORKSPACE_DIR}" 2>/dev/null || log_warning "Failed to remove workspace"
|
|
509
|
+
fi
|
|
510
|
+
fi
|
|
511
|
+
|
|
512
|
+
# Exit with original exit code
|
|
513
|
+
exit $exit_code
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
# Set trap for cleanup on script exit (only for non-test modes since test modes use --rm flag)
|
|
517
|
+
if [[ ! "${TASK_ID}" =~ concurrent-.* && ! "${TASK_ID}" =~ test-.* && ! "${TASK_ID}" =~ context-.* ]]; then
|
|
518
|
+
trap cleanup_on_exit EXIT INT TERM
|
|
519
|
+
fi
|
|
520
|
+
|
|
521
|
+
log_success "Agent spawning completed successfully"
|