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.
Files changed (42) hide show
  1. package/.claude/commands/CFN_LOOP_TASK_MODE.md +1 -1
  2. package/.claude/commands/switch-api.md +1 -1
  3. package/.claude/skills/cfn-agent-discovery/agents-registry.json +1 -1
  4. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +2 -1
  5. package/.claude/skills/cfn-loop-validation/config.json +2 -2
  6. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +221 -0
  7. package/claude-assets/agents/README-AGENT_LIFECYCLE.md +37 -10
  8. package/claude-assets/agents/README-VALIDATION.md +0 -8
  9. package/claude-assets/agents/cfn-dev-team/README.md +0 -8
  10. package/claude-assets/agents/cfn-dev-team/coordinators/README.md +1 -9
  11. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +565 -565
  12. package/claude-assets/agents/cfn-dev-team/developers/README.md +1 -9
  13. package/claude-assets/agents/cfn-dev-team/documentation/README-VALIDATION.md +0 -8
  14. package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md +0 -10
  15. package/claude-assets/agents/cfn-dev-team/reviewers/README.md +1 -9
  16. package/claude-assets/agents/cfn-dev-team/reviewers/quality/quality-metrics.md +0 -10
  17. package/claude-assets/agents/cfn-dev-team/test-agent.md +0 -10
  18. package/claude-assets/agents/cfn-dev-team/testers/README.md +1 -9
  19. package/claude-assets/agents/csuite/cto-agent.md +0 -10
  20. package/claude-assets/agents/custom/cfn-system-expert.md +1 -128
  21. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +1 -5
  22. package/claude-assets/agents/docker-team/csuite/c-suite-template.md +1 -5
  23. package/claude-assets/agents/docker-team/infrastructure/team-coordinator-template.md +1 -5
  24. package/claude-assets/agents/marketing_hybrid/cost_tracker.md +0 -10
  25. package/claude-assets/agents/marketing_hybrid/docker_deployer.md +0 -10
  26. package/claude-assets/agents/marketing_hybrid/zai_worker_spawner.md +0 -10
  27. package/claude-assets/commands/CFN_LOOP_TASK_MODE.md +1 -1
  28. package/claude-assets/commands/switch-api.md +1 -1
  29. package/claude-assets/skills/cfn-agent-discovery/agents-registry.json +1 -1
  30. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +2 -1
  31. package/claude-assets/skills/cfn-loop-validation/config.json +2 -2
  32. package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +324 -322
  33. package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +221 -0
  34. package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +2 -2
  35. package/claude-assets/skills/cfn-task-mode-sanitize/task-mode-env-sanitizer.sh +213 -182
  36. package/claude-assets/skills/cfn-validation-runner-instrumentation/wrapped-executor.sh +233 -271
  37. package/dist/cli/agent-definition-parser.js.map +1 -1
  38. package/dist/cli/config-manager.js +109 -91
  39. package/package.json +1 -1
  40. package/scripts/docker-build-mcp.sh +155 -0
  41. package/scripts/docker-test-mcp.sh +260 -0
  42. package/scripts/mcp-health-check.sh +123 -0
@@ -1,100 +1,118 @@
1
- import * as fs from "fs/promises";
2
- import * as path from "path";
3
- import Ajv from "ajv";
4
- import * as lodash from "lodash";
5
- let ConfigManager = class ConfigManager {
6
- static _instance = null;
7
- configPath;
8
- schemaPath;
9
- ajv;
10
- constructor(){
11
- this.configPath = path.join(process.env.HOME || "", ".claude-flow-config.json");
12
- this.schemaPath = path.join(__dirname, "../../.claude/skills/config-management/config.json");
13
- this.ajv = new Ajv();
14
- }
15
- static getInstance() {
16
- if (!ConfigManager._instance) {
17
- ConfigManager._instance = new ConfigManager();
18
- }
19
- return ConfigManager._instance;
20
- }
21
- async readConfig() {
22
- try {
23
- const configContent = await fs.readFile(this.configPath, "utf-8");
24
- return JSON.parse(configContent);
25
- } catch (error) {
26
- // If config doesn't exist, create from schema
27
- return this.resetToDefaults();
28
- }
29
- }
30
- async writeConfig(config) {
31
- const schemaContent = await fs.readFile(this.schemaPath, "utf-8");
32
- const schema = JSON.parse(schemaContent);
33
- const validate = this.ajv.compile(schema);
34
- if (!validate(config)) {
35
- throw new Error("Invalid configuration: " + this.ajv.errorsText(validate.errors));
36
- }
37
- await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8");
1
+ "use strict";
2
+ var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
3
+ function adopt(value) {
4
+ return value instanceof P ? value : new P(function(resolve) {
5
+ resolve(value);
6
+ });
38
7
  }
39
- async getValue(keyPath) {
40
- const config = await this.readConfig();
41
- const value = lodash.get(config, keyPath);
42
- if (value === undefined) {
43
- // Check if it's a custom key path not in the schema
44
- const customConfig = await this.readCustomConfig();
45
- return lodash.get(customConfig, keyPath);
8
+ return new (P || (P = Promise))(function(resolve, reject) {
9
+ function fulfilled(value) {
10
+ try {
11
+ step(generator.next(value));
12
+ } catch (e) {
13
+ reject(e);
14
+ }
46
15
  }
47
- return value;
48
- }
49
- async readCustomConfig() {
50
- try {
51
- const customConfigPath = path.join(process.env.HOME || "", ".claude-flow-custom-config.json");
52
- const customConfigContent = await fs.readFile(customConfigPath, "utf-8");
53
- return JSON.parse(customConfigContent);
54
- } catch (error) {
55
- // If custom config doesn't exist or can't be read, return empty object
56
- return {};
16
+ function rejected(value) {
17
+ try {
18
+ step(generator["throw"](value));
19
+ } catch (e) {
20
+ reject(e);
21
+ }
57
22
  }
58
- }
59
- async set(key, value) {
60
- const config = await this.readConfig();
61
- // Type assertion to handle full object
62
- if (typeof value === "object" && value !== null) {
63
- config[key] = value;
64
- } else {
65
- throw new Error("Invalid configuration value");
23
+ function step(result) {
24
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
66
25
  }
67
- await this.writeConfig(config);
68
- }
69
- async getAll() {
70
- return this.readConfig();
71
- }
72
- async resetToDefaults() {
73
- const schemaContent = await fs.readFile(this.schemaPath, "utf-8");
74
- const schema = JSON.parse(schemaContent);
75
- // Extract default values from the schema
76
- const defaultConfig = {
77
- redis: {
78
- host: schema.properties.redis.properties.host.default,
79
- port: schema.properties.redis.properties.port.default
80
- },
81
- agent: {
82
- default_strategy: schema.properties.agent.properties.default_strategy.default,
83
- max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,
84
- log_level: schema.properties.agent.properties.log_level.default
85
- },
86
- security: {
87
- enabled: schema.properties.security.properties.enabled.default,
88
- max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default
89
- }
26
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
27
+ });
28
+ };
29
+ var __generator = this && this.__generator || function(thisArg, body) {
30
+ var _ = {
31
+ label: 0,
32
+ sent: function() {
33
+ if (t[0] & 1) throw t[1];
34
+ return t[1];
35
+ },
36
+ trys: [],
37
+ ops: []
38
+ }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
39
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
40
+ return this;
41
+ }), g;
42
+ function verb(n) {
43
+ return function(v) {
44
+ return step([
45
+ n,
46
+ v
47
+ ]);
90
48
  };
91
- await this.writeConfig(defaultConfig);
92
- return defaultConfig;
93
49
  }
94
- };
95
- export default ConfigManager;
96
-
97
- //# sourceMappingURL=config-manager.js.mapop[1] : void 0,
50
+ function step(op) {
51
+ if (f) throw new TypeError("Generator is already executing.");
52
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
53
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
54
+ if (y = 0, t) op = [
55
+ op[0] & 2,
56
+ t.value
57
+ ];
58
+ switch(op[0]){
59
+ case 0:
60
+ case 1:
61
+ t = op;
62
+ break;
63
+ case 4:
64
+ _.label++;
65
+ return {
66
+ value: op[1],
67
+ done: false
68
+ };
69
+ case 5:
70
+ _.label++;
71
+ y = op[1];
72
+ op = [
73
+ 0
74
+ ];
75
+ continue;
76
+ case 7:
77
+ op = _.ops.pop();
78
+ _.trys.pop();
79
+ continue;
80
+ default:
81
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
82
+ _ = 0;
83
+ continue;
84
+ }
85
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
86
+ _.label = op[1];
87
+ break;
88
+ }
89
+ if (op[0] === 6 && _.label < t[1]) {
90
+ _.label = t[1];
91
+ t = op;
92
+ break;
93
+ }
94
+ if (t && _.label < t[2]) {
95
+ _.label = t[2];
96
+ _.ops.push(op);
97
+ break;
98
+ }
99
+ if (t[2]) _.ops.pop();
100
+ _.trys.pop();
101
+ continue;
102
+ }
103
+ op = body.call(thisArg, _);
104
+ } catch (e) {
105
+ op = [
106
+ 6,
107
+ e
108
+ ];
109
+ y = 0;
110
+ } finally{
111
+ f = t = 0;
112
+ }
113
+ if (op[0] & 5) throw op[1];
114
+ return {
115
+ value: op[0] ? op[1] : void 0,
98
116
  done: true
99
117
  };
100
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow-novice",
3
- "version": "2.14.34",
3
+ "version": "2.14.36",
4
4
  "description": "AI agent orchestration framework with namespace-isolated skills, agents, and CFN Loop validation. Safe installation with ~0.01% collision risk.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -0,0 +1,155 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # Docker MCP Build Script
5
+ # Builds all MCP server images and enhanced agent image with MCP clients
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
9
+
10
+ # Colors for output
11
+ RED='\033[0;31m'
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ NC='\033[0m' # No Color
15
+
16
+ echo "========================================="
17
+ echo " Docker MCP Build Script"
18
+ echo "========================================="
19
+ echo ""
20
+
21
+ # Function to print colored output
22
+ print_status() {
23
+ local status=$1
24
+ local message=$2
25
+ case $status in
26
+ "success")
27
+ echo -e "${GREEN}✓${NC} $message"
28
+ ;;
29
+ "error")
30
+ echo -e "${RED}✗${NC} $message"
31
+ ;;
32
+ "info")
33
+ echo -e "${YELLOW}→${NC} $message"
34
+ ;;
35
+ esac
36
+ }
37
+
38
+ # Check if Docker is available
39
+ if ! command -v docker &> /dev/null; then
40
+ print_status "error" "Docker is not installed or not in PATH"
41
+ exit 1
42
+ fi
43
+
44
+ # Check if docker-compose is available
45
+ if ! command -v docker-compose &> /dev/null; then
46
+ print_status "error" "docker-compose is not installed or not in PATH"
47
+ exit 1
48
+ fi
49
+
50
+ # Navigate to project root
51
+ cd "$PROJECT_ROOT"
52
+
53
+ # Validate MCP configuration exists
54
+ if [ ! -f "config/mcp-servers.json" ]; then
55
+ print_status "error" "MCP configuration not found: config/mcp-servers.json"
56
+ exit 1
57
+ fi
58
+
59
+ print_status "success" "Found MCP configuration"
60
+
61
+ # Build enhanced production Dockerfile with MCP clients
62
+ print_status "info" "Building enhanced agent image with MCP clients..."
63
+ if docker build -f Dockerfile.production \
64
+ --target production \
65
+ --tag cfn-agent-mcp:latest \
66
+ --tag cfn-agent-mcp:$(date +%Y%m%d) \
67
+ --build-arg BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
68
+ --build-arg VCS_REF="$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" \
69
+ --build-arg VERSION="4.1.0-mcp" \
70
+ . 2>&1 | tee /tmp/docker-build-agent.log; then
71
+ print_status "success" "Agent image built successfully"
72
+ else
73
+ print_status "error" "Failed to build agent image"
74
+ exit 1
75
+ fi
76
+
77
+ # Build MCP server images from docker-compose
78
+ print_status "info" "Building MCP server containers..."
79
+ if docker-compose -f docker-compose.production.yml build \
80
+ mcp-playwright \
81
+ mcp-redis-tools \
82
+ mcp-n8n \
83
+ mcp-security-scanner 2>&1 | tee /tmp/docker-build-mcp.log; then
84
+ print_status "success" "MCP server images built successfully"
85
+ else
86
+ print_status "error" "Failed to build MCP server images"
87
+ exit 1
88
+ fi
89
+
90
+ # Pull base images that we reference directly
91
+ print_status "info" "Pulling base MCP images..."
92
+ docker pull mcr.microsoft.com/playwright:v1.40.0-jammy
93
+ docker pull redis:7-alpine
94
+ docker pull n8nio/n8n:latest
95
+ docker pull aquasec/trivy:latest
96
+ print_status "success" "Base images pulled"
97
+
98
+ # Run security scans if Trivy is available
99
+ if command -v trivy &> /dev/null; then
100
+ print_status "info" "Running security scans with Trivy..."
101
+
102
+ # Scan agent image
103
+ print_status "info" "Scanning cfn-agent-mcp:latest..."
104
+ if trivy image --severity HIGH,CRITICAL \
105
+ --exit-code 0 \
106
+ --no-progress \
107
+ cfn-agent-mcp:latest > /tmp/trivy-scan-agent.txt 2>&1; then
108
+ print_status "success" "Agent image scan complete"
109
+ else
110
+ print_status "error" "Agent image has vulnerabilities (see /tmp/trivy-scan-agent.txt)"
111
+ fi
112
+
113
+ # Scan MCP server images
114
+ for image in mcr.microsoft.com/playwright:v1.40.0-jammy \
115
+ redis:7-alpine \
116
+ n8nio/n8n:latest \
117
+ aquasec/trivy:latest; do
118
+ print_status "info" "Scanning $image..."
119
+ trivy image --severity HIGH,CRITICAL \
120
+ --exit-code 0 \
121
+ --no-progress \
122
+ "$image" > /tmp/trivy-scan-$(echo $image | sed 's/[^a-zA-Z0-9]/-/g').txt 2>&1 || true
123
+ done
124
+
125
+ print_status "success" "Security scans complete (results in /tmp/trivy-scan-*.txt)"
126
+ else
127
+ print_status "info" "Trivy not found - skipping security scans"
128
+ fi
129
+
130
+ # Summary
131
+ echo ""
132
+ echo "========================================="
133
+ echo " Build Summary"
134
+ echo "========================================="
135
+ echo ""
136
+
137
+ docker images | grep -E "(cfn-agent-mcp|mcp-playwright|mcp-redis-tools|mcp-n8n|mcp-security|playwright|n8n|trivy)" | head -20
138
+
139
+ echo ""
140
+ print_status "success" "Build complete!"
141
+ echo ""
142
+ echo "Tagged images:"
143
+ echo " - cfn-agent-mcp:latest"
144
+ echo " - cfn-agent-mcp:$(date +%Y%m%d)"
145
+ echo ""
146
+ echo "MCP Server images ready:"
147
+ echo " - mcp-playwright (mcr.microsoft.com/playwright:v1.40.0-jammy)"
148
+ echo " - mcp-redis-tools (redis:7-alpine)"
149
+ echo " - mcp-n8n (n8nio/n8n:latest)"
150
+ echo " - mcp-security-scanner (aquasec/trivy:latest)"
151
+ echo ""
152
+ echo "Next steps:"
153
+ echo " 1. Run tests: ./scripts/docker-test-mcp.sh"
154
+ echo " 2. Deploy: docker-compose -f docker-compose.production.yml up -d"
155
+ echo ""
@@ -0,0 +1,260 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # Docker MCP Test Script
5
+ # Tests MCP server containers and agent connectivity
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
9
+
10
+ # Colors for output
11
+ RED='\033[0;31m'
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ BLUE='\033[0;34m'
15
+ NC='\033[0m' # No Color
16
+
17
+ # Test results tracking
18
+ TESTS_PASSED=0
19
+ TESTS_FAILED=0
20
+ TEST_RESULTS=()
21
+
22
+ echo "========================================="
23
+ echo " Docker MCP Test Suite"
24
+ echo "========================================="
25
+ echo ""
26
+
27
+ # Function to print colored output
28
+ print_status() {
29
+ local status=$1
30
+ local message=$2
31
+ case $status in
32
+ "success")
33
+ echo -e "${GREEN}✓${NC} $message"
34
+ ;;
35
+ "error")
36
+ echo -e "${RED}✗${NC} $message"
37
+ ;;
38
+ "info")
39
+ echo -e "${BLUE}→${NC} $message"
40
+ ;;
41
+ "warning")
42
+ echo -e "${YELLOW}⚠${NC} $message"
43
+ ;;
44
+ esac
45
+ }
46
+
47
+ # Function to record test result
48
+ record_test() {
49
+ local test_name=$1
50
+ local passed=$2
51
+ local message=$3
52
+
53
+ if [ "$passed" = "true" ]; then
54
+ ((TESTS_PASSED++))
55
+ TEST_RESULTS+=("PASS: $test_name - $message")
56
+ print_status "success" "$test_name"
57
+ else
58
+ ((TESTS_FAILED++))
59
+ TEST_RESULTS+=("FAIL: $test_name - $message")
60
+ print_status "error" "$test_name - $message"
61
+ fi
62
+ }
63
+
64
+ # Cleanup function
65
+ cleanup() {
66
+ print_status "info" "Cleaning up test containers..."
67
+ docker-compose -f "$PROJECT_ROOT/docker-compose.production.yml" down \
68
+ mcp-playwright mcp-redis-tools mcp-n8n mcp-security-scanner 2>/dev/null || true
69
+ }
70
+
71
+ # Trap cleanup on exit
72
+ trap cleanup EXIT
73
+
74
+ # Navigate to project root
75
+ cd "$PROJECT_ROOT"
76
+
77
+ # Test 1: MCP Configuration Validation
78
+ print_status "info" "Test 1: Validating MCP configuration..."
79
+ if [ -f "config/mcp-servers.json" ]; then
80
+ if command -v jq &> /dev/null; then
81
+ if jq empty config/mcp-servers.json 2>/dev/null; then
82
+ record_test "MCP Config Validation" "true" "Valid JSON configuration"
83
+ else
84
+ record_test "MCP Config Validation" "false" "Invalid JSON"
85
+ fi
86
+ else
87
+ record_test "MCP Config Validation" "true" "File exists (jq not available for validation)"
88
+ fi
89
+ else
90
+ record_test "MCP Config Validation" "false" "config/mcp-servers.json not found"
91
+ fi
92
+
93
+ # Test 2: Docker Compose Syntax Validation
94
+ print_status "info" "Test 2: Validating Docker Compose syntax..."
95
+ if docker-compose -f docker-compose.production.yml config > /dev/null 2>&1; then
96
+ record_test "Docker Compose Syntax" "true" "Valid syntax"
97
+ else
98
+ record_test "Docker Compose Syntax" "false" "Syntax errors detected"
99
+ fi
100
+
101
+ # Test 3: Start MCP containers
102
+ print_status "info" "Test 3: Starting MCP containers..."
103
+ if docker-compose -f docker-compose.production.yml up -d \
104
+ redis-coordinator \
105
+ mcp-playwright \
106
+ mcp-redis-tools \
107
+ mcp-n8n \
108
+ mcp-security-scanner 2>&1 | tee /tmp/docker-test-mcp-start.log; then
109
+ record_test "MCP Container Startup" "true" "All containers started"
110
+ else
111
+ record_test "MCP Container Startup" "false" "Failed to start containers"
112
+ exit 1
113
+ fi
114
+
115
+ # Wait for containers to initialize
116
+ print_status "info" "Waiting for containers to initialize (30s)..."
117
+ sleep 30
118
+
119
+ # Test 4: Health Check - Playwright
120
+ print_status "info" "Test 4: Testing Playwright MCP server health..."
121
+ if timeout 10 docker exec cfn-mcp-playwright curl -f http://localhost:8081/health 2>/dev/null; then
122
+ record_test "Playwright Health Check" "true" "Responding"
123
+ else
124
+ record_test "Playwright Health Check" "false" "Not responding or health endpoint unavailable"
125
+ fi
126
+
127
+ # Test 5: Health Check - Redis Tools
128
+ print_status "info" "Test 5: Testing Redis Tools MCP server health..."
129
+ if timeout 10 docker exec cfn-mcp-redis-tools wget --quiet --tries=1 --spider http://localhost:8082/health 2>/dev/null; then
130
+ record_test "Redis Tools Health Check" "true" "Responding"
131
+ else
132
+ record_test "Redis Tools Health Check" "false" "Not responding or health endpoint unavailable"
133
+ fi
134
+
135
+ # Test 6: Health Check - N8N
136
+ print_status "info" "Test 6: Testing N8N MCP server health..."
137
+ if timeout 15 docker exec cfn-mcp-n8n wget --quiet --tries=1 --spider http://localhost:5678/healthz 2>/dev/null; then
138
+ record_test "N8N Health Check" "true" "Responding"
139
+ else
140
+ record_test "N8N Health Check" "false" "Not responding or health endpoint unavailable"
141
+ fi
142
+
143
+ # Test 7: Health Check - Security Scanner
144
+ print_status "info" "Test 7: Testing Security Scanner MCP server health..."
145
+ if timeout 10 docker exec cfn-mcp-security-scanner wget --quiet --tries=1 --spider http://localhost:8084/health 2>/dev/null; then
146
+ record_test "Security Scanner Health Check" "true" "Responding"
147
+ else
148
+ record_test "Security Scanner Health Check" "false" "Not responding or health endpoint unavailable"
149
+ fi
150
+
151
+ # Test 8: Network Connectivity - MCP Network
152
+ print_status "info" "Test 8: Testing MCP network isolation..."
153
+ if docker network inspect mcp-isolated > /dev/null 2>&1; then
154
+ record_test "MCP Network Creation" "true" "Network exists"
155
+ else
156
+ record_test "MCP Network Creation" "false" "Network not found"
157
+ fi
158
+
159
+ # Test 9: Volume Mounts
160
+ print_status "info" "Test 9: Testing MCP configuration volume mounts..."
161
+ MOUNT_ERRORS=0
162
+ for container in cfn-mcp-playwright cfn-mcp-redis-tools cfn-mcp-n8n cfn-mcp-security-scanner; do
163
+ if docker exec "$container" test -f /app/config/mcp-servers.json 2>/dev/null; then
164
+ : # Success
165
+ else
166
+ ((MOUNT_ERRORS++))
167
+ fi
168
+ done
169
+
170
+ if [ $MOUNT_ERRORS -eq 0 ]; then
171
+ record_test "MCP Config Volume Mounts" "true" "All containers have config mounted"
172
+ else
173
+ record_test "MCP Config Volume Mounts" "false" "$MOUNT_ERRORS containers missing config"
174
+ fi
175
+
176
+ # Test 10: Redis Coordinator Connectivity
177
+ print_status "info" "Test 10: Testing Redis coordinator connectivity..."
178
+ if docker exec cfn-redis-coordinator redis-cli ping 2>/dev/null | grep -q "PONG"; then
179
+ record_test "Redis Coordinator" "true" "Responding to pings"
180
+ else
181
+ record_test "Redis Coordinator" "false" "Not responding"
182
+ fi
183
+
184
+ # Test 11: Container Resource Limits
185
+ print_status "info" "Test 11: Verifying container resource limits..."
186
+ LIMIT_ERRORS=0
187
+ for container in cfn-mcp-playwright cfn-mcp-redis-tools cfn-mcp-n8n cfn-mcp-security-scanner; do
188
+ if docker inspect "$container" --format '{{.HostConfig.Memory}}' 2>/dev/null | grep -q -v "^0$"; then
189
+ : # Memory limit set
190
+ else
191
+ ((LIMIT_ERRORS++))
192
+ fi
193
+ done
194
+
195
+ if [ $LIMIT_ERRORS -eq 0 ]; then
196
+ record_test "Container Resource Limits" "true" "All containers have memory limits"
197
+ else
198
+ record_test "Container Resource Limits" "false" "$LIMIT_ERRORS containers missing resource limits"
199
+ fi
200
+
201
+ # Test 12: MCP Server Environment Variables
202
+ print_status "info" "Test 12: Verifying MCP server environment variables..."
203
+ ENV_ERRORS=0
204
+ for container in cfn-mcp-playwright cfn-mcp-redis-tools cfn-mcp-n8n cfn-mcp-security-scanner; do
205
+ if docker exec "$container" env 2>/dev/null | grep -q "MCP_SERVER_TYPE"; then
206
+ : # Environment variable set
207
+ else
208
+ ((ENV_ERRORS++))
209
+ fi
210
+ done
211
+
212
+ if [ $ENV_ERRORS -eq 0 ]; then
213
+ record_test "MCP Environment Variables" "true" "All containers have MCP env vars"
214
+ else
215
+ record_test "MCP Environment Variables" "false" "$ENV_ERRORS containers missing MCP env vars"
216
+ fi
217
+
218
+ # Print container status
219
+ echo ""
220
+ print_status "info" "Container Status:"
221
+ docker-compose -f docker-compose.production.yml ps \
222
+ redis-coordinator mcp-playwright mcp-redis-tools mcp-n8n mcp-security-scanner
223
+
224
+ # Print container logs for debugging
225
+ echo ""
226
+ print_status "info" "Recent container logs:"
227
+ for container in cfn-mcp-playwright cfn-mcp-redis-tools cfn-mcp-n8n cfn-mcp-security-scanner; do
228
+ echo ""
229
+ echo "--- $container ---"
230
+ docker logs "$container" --tail 10 2>&1 || true
231
+ done
232
+
233
+ # Summary
234
+ echo ""
235
+ echo "========================================="
236
+ echo " Test Results Summary"
237
+ echo "========================================="
238
+ echo ""
239
+
240
+ for result in "${TEST_RESULTS[@]}"; do
241
+ if [[ $result == PASS:* ]]; then
242
+ echo -e "${GREEN}$result${NC}"
243
+ else
244
+ echo -e "${RED}$result${NC}"
245
+ fi
246
+ done
247
+
248
+ echo ""
249
+ echo "Tests Passed: $TESTS_PASSED"
250
+ echo "Tests Failed: $TESTS_FAILED"
251
+ echo "Total Tests: $((TESTS_PASSED + TESTS_FAILED))"
252
+ echo ""
253
+
254
+ if [ $TESTS_FAILED -eq 0 ]; then
255
+ print_status "success" "All tests passed!"
256
+ exit 0
257
+ else
258
+ print_status "error" "$TESTS_FAILED test(s) failed"
259
+ exit 1
260
+ fi