claude-flow-novice 2.14.15 → 2.14.17

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.
@@ -15,7 +15,7 @@ Execute CFN Loop using CLI spawning for maximum cost savings (95-98% vs Task too
15
15
  ## What is CLI Mode?
16
16
 
17
17
  **CLI Mode Architecture v3.0 (Enhanced):**
18
- - Main Chat spawns **single coordinator agent** via Task()
18
+ - Main Chat spawns **single coordinator agent**
19
19
  - Enhanced coordinator spawns **all workers via CLI** with protocol compliance
20
20
  - CLI agents use **Z.ai custom routing** (when enabled)
21
21
  - **Real-time monitoring** with automatic recovery from stuck agents
@@ -77,59 +77,16 @@ Savings: 64% with custom routing, 95-98% vs all-Task
77
77
  | Standard | ≥0.75 | ≥0.90 | 10 | 3-4 | Production features |
78
78
  | Enterprise | ≥0.85 | ≥0.95 | 15 | 5 | Security, compliance, critical systems |
79
79
 
80
- ## 🚨 CRITICAL EXECUTION INSTRUCTIONS
80
+ ## How CLI Mode Works
81
81
 
82
- **THIS IS A SLASH COMMAND - MAIN CHAT EXECUTES THIS DIRECTLY**
82
+ 1. **Main Chat** spawns a single `cfn-v3-coordinator` agent
83
+ 2. **Coordinator** orchestrates the entire CFN Loop workflow
84
+ 3. **Loop 3** agents implement the solution and validate against quality gates
85
+ 4. **Loop 2** agents review and provide validation feedback
86
+ 5. **Product Owner** makes the final decision on deliverables
87
+ 6. **Background execution** with Redis coordination for scalability
83
88
 
84
- **DO NOT manually spawn Task() agents for CFN Loop workflows**
85
- **DO NOT spawn cfn-v3-coordinator manually**
86
- **DO NOT spawn Loop 3 agents (backend-dev, researcher, etc.)**
87
- **DO NOT spawn Loop 2 agents (reviewer, tester, etc.)**
88
- **DO NOT spawn product-owner**
89
-
90
- **Main Chat simply executes the slash command - everything else is automatic**
91
-
92
- ---
93
-
94
- ## How This Command Works:
95
-
96
- When Main Chat executes `/cfn-loop-cli "task description"`, this slash command:
97
-
98
- 1. **Automatically spawns cfn-v3-coordinator** with proper parameters
99
- 2. **Coordinator invokes enhanced orchestrator** with monitoring v3.0
100
- 3. **Orchestrator spawns all agents via CLI** (background execution)
101
- 4. **Handles complete CFN Loop workflow** with real-time monitoring
102
- 5. **Returns structured result** to Main Chat when complete
103
-
104
- ## Enhanced Features v3.0:
105
-
106
- - ✅ **Real-time monitoring** with automatic stuck agent recovery
107
- - ✅ **Process health checking** and dead process cleanup
108
- - ✅ **Protocol compliance** preventing "consensus on vapor" anti-patterns
109
- - ✅ **Progress visibility** with detailed timestamped reports
110
- - ✅ **95-98% cost savings** with Z.ai routing optimization
111
- - ✅ **Background execution** with Redis persistence
112
-
113
- ## Main Chat Execution Rules
114
-
115
- **THIS SLASH COMMAND HANDLES EVERYTHING AUTOMATICALLY**
116
-
117
- **Main Chat simply executes:**
118
- ```bash
119
- /cfn-loop-cli "Task description" --mode=standard
120
- ```
121
-
122
- **The slash command automatically:**
123
- - ✅ Spawns coordinator with proper parameters
124
- - ✅ Handles all agent spawning via CLI
125
- - ✅ Manages complete CFN Loop workflow
126
- - ✅ Returns structured result when complete
127
-
128
- **Main Chat should NOT:**
129
- - ❌ Manually spawn any Task() agents for CFN Loop
130
- - ❌ Ask about retry/iteration decisions (handled automatically)
131
- - ❌ Monitor agent progress (slash command handles this)
132
- - ❌ Coordinate between agents (built-in coordination)
89
+ The coordinator handles all agent spawning internally using optimized CLI processes.
133
90
 
134
91
  ## CLI Mode Benefits
135
92
 
@@ -186,6 +143,33 @@ When Main Chat executes `/cfn-loop-cli "task description"`, this slash command:
186
143
  - Will force ITERATE if git diff shows zero changes
187
144
  - Check coordinator output for validation failures
188
145
 
146
+ **Web Portal Access:**
147
+ - Monitor real-time agent progress at http://localhost:3000
148
+ - View detailed execution logs and health status
149
+ - Track iteration progress and confidence scores
150
+
151
+ ## Usage Examples
152
+
153
+ **Simple API Development:**
154
+ ```bash
155
+ /cfn-loop-cli "Build REST API with user authentication"
156
+ ```
157
+
158
+ **Complex Feature with High Quality Requirements:**
159
+ ```bash
160
+ /cfn-loop-cli "Implement payment processing with PCI compliance" --mode=enterprise --max-iterations=15
161
+ ```
162
+
163
+ **Quick Prototype:**
164
+ ```bash
165
+ /cfn-loop-cli "Build MVP landing page" --mode=mvp
166
+ ```
167
+
168
+ **Infrastructure Deployment:**
169
+ ```bash
170
+ /cfn-loop-cli "Set up CI/CD pipeline for microservices"
171
+ ```
172
+
189
173
  ## Related Commands
190
174
 
191
175
  - **Task Mode**: `/cfn-loop-task` (debugging, full visibility)
@@ -201,4 +185,127 @@ When Main Chat executes `/cfn-loop-cli "task description"`, this slash command:
201
185
 
202
186
  ---
203
187
 
204
- **Version:** 1.0.0 (2025-10-31) - CLI mode: production execution, cost-optimized, background processing
188
+ ## 🚨 EXECUTION INSTRUCTIONS (Internal Use)
189
+
190
+ **Main Chat: Execute this Task() call after slash command processing:**
191
+
192
+ ```javascript
193
+ Task("cfn-v3-coordinator", `
194
+ CFN LOOP CLI MODE v3.0 - PRODUCTION EXECUTION WITH ENHANCED MONITORING
195
+
196
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
197
+ TASK SPECIFICATION
198
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
199
+
200
+ Task Description: $ARGUMENTS
201
+ Task ID: cfn-cli-$(date +%s%N | tail -c 7)-${RANDOM}
202
+ Mode: ${mode.toUpperCase()}
203
+
204
+ Enhanced Monitoring: Real-time agent tracking, automatic recovery, protocol compliance
205
+
206
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
207
+ SUCCESS CRITERIA
208
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
209
+
210
+ Acceptance Criteria:
211
+ - [ ] Core functionality implemented
212
+ - [ ] All tests pass with >80% coverage
213
+ - [ ] Security review completed
214
+ - [ ] Documentation updated
215
+ - [ ] No regression in existing features
216
+
217
+ Quality Gates (${mode.toUpperCase()} MODE):
218
+ - Loop 3 Gate Threshold: ${mode === 'enterprise' ? 0.85 : mode === 'standard' ? 0.75 : 0.70}
219
+ - Loop 2 Consensus Threshold: ${mode === 'enterprise' ? 0.95 : mode === 'standard' ? 0.90 : 0.80}
220
+ - Max Iterations: ${maxIterations}
221
+
222
+ Definition of Done:
223
+ - Consensus ≥ threshold achieved
224
+ - All acceptance criteria met
225
+ - Product Owner approval received
226
+
227
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
228
+ ENHANCED ORCHESTRATION CONFIGURATION v3.0
229
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
230
+
231
+ Mode: ${mode.toUpperCase()}
232
+ Enhanced Features: Real-time monitoring, automatic recovery, protocol compliance
233
+
234
+ Loop 3 Agents (Implementation) - SELECT BASED ON TASK:
235
+ Examples:
236
+ - Backend API: backend-dev, researcher, devops
237
+ - Full-Stack: backend-dev, react-frontend-engineer, devops
238
+ - Infrastructure: devops, rust-developer, researcher
239
+ - Security: security-specialist, backend-dev, researcher
240
+
241
+ Loop 2 Agents (Validation) - SCALE BY COMPLEXITY:
242
+ Simple (1-2 files): reviewer, tester
243
+ Standard (3-5 files): reviewer, tester, architect, security-specialist
244
+ Complex (>5 files): +code-analyzer, +performance-benchmarker
245
+
246
+ Product Owner: product-owner
247
+
248
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
249
+ EXECUTION INSTRUCTIONS (Enhanced v3.0)
250
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
251
+
252
+ 1. INVOKE ENHANCED ORCHESTRATOR (CLI spawning with monitoring):
253
+
254
+ TASK_ID="cfn-cli-$(date +%s%N | tail -c 7)-${RANDOM}"
255
+ MODE="${mode}"
256
+ LOOP3_AGENTS="backend-dev,researcher,devops" # Customize for task
257
+ LOOP2_AGENTS="reviewer,tester,architect,security-specialist" # Scale by complexity
258
+
259
+ ./.claude/skills/cfn-loop-orchestration/orchestrate.sh \\
260
+ --task-id "$TASK_ID" \\
261
+ --mode "$MODE" \\
262
+ --loop3-agents "$LOOP3_AGENTS" \\
263
+ --loop2-agents "$LOOP2_AGENTS" \\
264
+ --product-owner "product-owner" \\
265
+ --max-iterations ${maxIterations}
266
+
267
+ 2. ENHANCED ORCHESTRATOR HANDLES v3.0:
268
+ - ✅ Spawns all agents via CLI (background) with protocol compliance
269
+ - ✅ Real-time agent progress monitoring and stuck detection
270
+ - ✅ Automatic recovery from dead processes
271
+ - ✅ Enhanced context validation prevents "consensus on vapor"
272
+ - ✅ Loop 3: Gate check (≥threshold) → PASS/ITERATE with health verification
273
+ - ✅ Loop 2: Consensus check (≥threshold) → COMPLETE/ITERATE
274
+ - ✅ Product Owner: PROCEED/ITERATE/ABORT decision with deliverable validation
275
+ - ✅ Git commit/push on PROCEED
276
+ - ✅ Returns structured result to Main Chat
277
+
278
+ 3. RETURN STRUCTURED RESULT:
279
+ {
280
+ "taskId": "cfn-cli-XXXXX",
281
+ "status": "complete|failed",
282
+ "iterations": {"loop3": N, "loop2": M},
283
+ "finalConsensus": 0.XX,
284
+ "acceptanceCriteria": {
285
+ "met": [...],
286
+ "pending": [...]
287
+ },
288
+ "deliverables": [...],
289
+ "enhancedMonitoring": {
290
+ "agentHealth": "healthy|recovered",
291
+ "processRecovery": true,
292
+ "protocolCompliance": true
293
+ },
294
+ "recommendations": [...]
295
+ }
296
+
297
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
298
+ CRITICAL ENHANCED RULES v3.0
299
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
300
+
301
+ - ✅ USE enhanced orchestration script with real-time monitoring
302
+ - ✅ ALL agents run in background via npx claude-flow-novice (enhanced v3.0)
303
+ - ✅ USE Redis BLPOP for loop dependencies (zero-token coordination)
304
+ - ✅ AGENTS use Z.ai routing automatically (when enabled)
305
+ - ✅ ENFORCE protocol compliance (prevent "consensus on vapor")
306
+ - ✅ MONITOR agent health and auto-recover stuck processes
307
+ - ✅ RETURN structured result with enhanced monitoring data
308
+ `, "cfn-v3-coordinator")
309
+ ```
310
+
311
+ **Version:** 3.0.0 (2025-11-05) - Enhanced CLI mode: production execution with real-time monitoring, automatic recovery, and protocol compliance
@@ -0,0 +1,459 @@
1
+ /**
2
+ * Skill-based MCP Selection System
3
+ * Automatically selects MCP servers based on agent skills and requirements
4
+ */ const fs = require('fs').promises;
5
+ const path = require('path');
6
+ const AgentTokenManager = require('../cli/agent-token-manager.js');
7
+ let SkillMCPSelector = class SkillMCPSelector {
8
+ constructor(options = {}){
9
+ this.tokenManager = new AgentTokenManager(options);
10
+ this.agentConfigPath = options.agentConfigPath || './config/agent-whitelist.json';
11
+ this.skillConfigPath = options.skillConfigPath || './config/skill-requirements.json';
12
+ this.mcpServersPath = options.mcpServersPath || './config/mcp-servers.json';
13
+ this.agentWhitelist = new Map();
14
+ this.skillRequirements = new Map();
15
+ this.mcpServers = new Map();
16
+ }
17
+ async initialize() {
18
+ await this.tokenManager.initialize();
19
+ await this.loadConfigurations();
20
+ console.log('[SkillMCPSelector] Initialized successfully');
21
+ }
22
+ async loadConfigurations() {
23
+ // Load agent whitelist
24
+ const agentConfig = await this.loadJson(this.agentConfigPath);
25
+ this.agentWhitelist.clear();
26
+ for (const agent of agentConfig.agents){
27
+ this.agentWhitelist.set(agent.type, agent);
28
+ }
29
+ // Load skill requirements
30
+ const skillConfig = await this.loadJson(this.skillConfigPath);
31
+ this.skillRequirements.clear();
32
+ for (const [tool, requirements] of Object.entries(skillConfig.tools)){
33
+ this.skillRequirements.set(tool, requirements);
34
+ }
35
+ // Load MCP server configurations
36
+ try {
37
+ const mcpConfig = await this.loadJson(this.mcpServersPath);
38
+ for (const [name, config] of Object.entries(mcpConfig.servers)){
39
+ this.mcpServers.set(name, config);
40
+ }
41
+ } catch (error) {
42
+ console.warn('[SkillMCPSelector] MCP servers config not found, using defaults');
43
+ this.initializeDefaultMCPServers();
44
+ }
45
+ }
46
+ async loadJson(filePath) {
47
+ const resolvedPath = path.resolve(filePath);
48
+ const content = await fs.readFile(resolvedPath, 'utf8');
49
+ return JSON.parse(content);
50
+ }
51
+ initializeDefaultMCPServers() {
52
+ // Default MCP server configurations
53
+ const defaultServers = {
54
+ 'playwright': {
55
+ name: 'playwright',
56
+ displayName: 'Playwright Browser Automation',
57
+ description: 'Browser automation and screenshot capabilities',
58
+ containerImage: 'claude-flow-novice:mcp-playwright',
59
+ tools: [
60
+ 'take_screenshot',
61
+ 'search_google',
62
+ 'navigate_and_interact'
63
+ ],
64
+ skills: [
65
+ 'browser-automation',
66
+ 'screenshot-capture',
67
+ 'web-interaction'
68
+ ],
69
+ resourceRequirements: {
70
+ memoryMB: 1024,
71
+ cpuUnits: 2
72
+ }
73
+ },
74
+ 'redis': {
75
+ name: 'redis',
76
+ displayName: 'Redis Database',
77
+ description: 'Redis key-value store operations',
78
+ containerImage: 'claude-flow-novice:mcp-redis',
79
+ tools: [
80
+ 'redis_get',
81
+ 'redis_set',
82
+ 'redis_keys'
83
+ ],
84
+ skills: [
85
+ 'redis-operations',
86
+ 'cache-management'
87
+ ],
88
+ resourceRequirements: {
89
+ memoryMB: 256,
90
+ cpuUnits: 1
91
+ }
92
+ },
93
+ 'postgres': {
94
+ name: 'postgres',
95
+ displayName: 'PostgreSQL Database',
96
+ description: 'PostgreSQL database operations',
97
+ containerImage: 'claude-flow-novice:mcp-postgres',
98
+ tools: [
99
+ 'postgres_query',
100
+ 'postgres_schema',
101
+ 'postgres_migrate'
102
+ ],
103
+ skills: [
104
+ 'database-design',
105
+ 'sql-operations'
106
+ ],
107
+ resourceRequirements: {
108
+ memoryMB: 512,
109
+ cpuUnits: 2
110
+ }
111
+ },
112
+ 'security-scanner': {
113
+ name: 'security-scanner',
114
+ displayName: 'Security Scanner',
115
+ description: 'Security vulnerability scanning and analysis',
116
+ containerImage: 'claude-flow-novice:mcp-security',
117
+ tools: [
118
+ 'security_scan',
119
+ 'vulnerability_check',
120
+ 'compliance_validate'
121
+ ],
122
+ skills: [
123
+ 'security-auditing',
124
+ 'vulnerability-scanning'
125
+ ],
126
+ resourceRequirements: {
127
+ memoryMB: 1536,
128
+ cpuUnits: 4
129
+ }
130
+ }
131
+ };
132
+ for (const [name, config] of Object.entries(defaultServers)){
133
+ this.mcpServers.set(name, config);
134
+ }
135
+ }
136
+ /**
137
+ * Determine which MCP servers an agent needs based on their skills
138
+ */ selectMCPServers(agentType, agentSkills = null) {
139
+ const agentConfig = this.agentWhitelist.get(agentType);
140
+ if (!agentConfig) {
141
+ throw new Error(`Unknown agent type: ${agentType}`);
142
+ }
143
+ // Use provided skills or fall back to agent config
144
+ const skills = agentSkills || agentConfig.skills;
145
+ // Determine required MCP servers based on skills
146
+ const requiredMCPServers = new Set();
147
+ const skillToMCPServerMap = this.getSkillToMCPServerMapping();
148
+ // Map skills to required MCP servers
149
+ for (const skill of skills){
150
+ if (skillToMCPServerMap.has(skill)) {
151
+ const servers = skillToMCPServerMap.get(skill);
152
+ servers.forEach((server)=>requiredMCPServers.add(server));
153
+ }
154
+ }
155
+ // Add explicitly allowed MCP servers from agent config
156
+ if (agentConfig.allowedMcpServers) {
157
+ agentConfig.allowedMcpServers.forEach((server)=>requiredMCPServers.add(server));
158
+ }
159
+ // Convert to array and sort by priority
160
+ const selectedServers = Array.from(requiredMCPServers).filter((server)=>this.mcpServers.has(server)).sort((a, b)=>{
161
+ const priorityA = this.mcpServers.get(a).priority || 999;
162
+ const priorityB = this.mcpServers.get(b).priority || 999;
163
+ return priorityA - priorityB;
164
+ });
165
+ return {
166
+ agentType,
167
+ agentSkills: skills,
168
+ selectedMCPServers,
169
+ serverDetails: selectedServers.map((server)=>this.mcpServers.get(server)),
170
+ totalMemoryRequired: selectedServers.reduce((sum, server)=>sum + (this.mcpServers.get(server).resourceRequirements?.memoryMB || 512), 0),
171
+ totalCPURequired: selectedServers.reduce((sum, server)=>sum + (this.mcpServers.get(server).resourceRequirements?.cpuUnits || 1), 0)
172
+ };
173
+ }
174
+ /**
175
+ * Get mapping from skills to required MCP servers
176
+ */ getSkillToMCPServerMapping() {
177
+ const skillMap = new Map();
178
+ // Build mapping from MCP server configurations
179
+ for (const [serverName, serverConfig] of this.mcpServers.entries()){
180
+ for (const skill of serverConfig.skills || []){
181
+ if (!skillMap.has(skill)) {
182
+ skillMap.set(skill, new Set());
183
+ }
184
+ skillMap.get(skill).add(serverName);
185
+ }
186
+ }
187
+ // Also add mappings from tool requirements
188
+ for (const [toolName, toolConfig] of this.skillRequirements.entries()){
189
+ for (const skill of toolConfig.requiredSkills || []){
190
+ // Find MCP servers that provide this tool
191
+ for (const [serverName, serverConfig] of this.mcpServers.entries()){
192
+ if (serverConfig.tools?.includes(toolName)) {
193
+ if (!skillMap.has(skill)) {
194
+ skillMap.set(skill, new Set());
195
+ }
196
+ skillMap.get(skill).add(serverName);
197
+ }
198
+ }
199
+ }
200
+ }
201
+ return skillMap;
202
+ }
203
+ /**
204
+ * Generate tokens for selected MCP servers
205
+ */ async generateMCPTokens(agentType, selectedServers, options = {}) {
206
+ const tokens = [];
207
+ for (const serverName of selectedServers){
208
+ try {
209
+ const serverConfig = this.mcpServers.get(serverName);
210
+ if (!serverConfig) {
211
+ console.warn(`[SkillMCPSelector] Server configuration not found: ${serverName}`);
212
+ continue;
213
+ }
214
+ // Generate server-specific token
215
+ const tokenData = await this.tokenManager.registerAgentToken(agentType, {
216
+ expiresIn: options.expiresIn || '24h',
217
+ description: `Token for ${serverConfig.displayName}`,
218
+ createdBy: 'skill-mcp-selector',
219
+ mcpServer: serverName
220
+ });
221
+ tokens.push({
222
+ serverName,
223
+ displayName: serverConfig.displayName,
224
+ token: tokenData.token,
225
+ expiresAt: tokenData.expiresAt,
226
+ containerImage: serverConfig.containerImage,
227
+ connectionInfo: this.generateConnectionInfo(serverName, serverConfig, tokenData.token)
228
+ });
229
+ console.log(`[SkillMCPSelector] Generated token for ${agentType} → ${serverName}`);
230
+ } catch (error) {
231
+ console.error(`[SkillMCPSelector] Failed to generate token for ${serverName}:`, error);
232
+ }
233
+ }
234
+ return tokens;
235
+ }
236
+ /**
237
+ * Generate connection information for MCP server
238
+ */ generateConnectionInfo(serverName, serverConfig, token) {
239
+ const baseInfo = {
240
+ serverName,
241
+ token,
242
+ authentication: {
243
+ type: 'token-based',
244
+ header: 'x-agent-token',
245
+ agentTypeHeader: 'x-agent-type'
246
+ }
247
+ };
248
+ // Add server-specific connection details
249
+ if (serverConfig.connectionType === 'docker') {
250
+ return {
251
+ ...baseInfo,
252
+ type: 'docker-container',
253
+ containerName: `mcp-${serverName}`,
254
+ containerImage: serverConfig.containerImage,
255
+ dockerArgs: [
256
+ 'run',
257
+ '--rm',
258
+ '--init',
259
+ '--name',
260
+ `mcp-${serverName}`,
261
+ '--memory',
262
+ `${serverConfig.resourceRequirements?.memoryMB || 512}m`,
263
+ '--cpus',
264
+ `${serverConfig.resourceRequirements?.cpuUnits || 1}`,
265
+ '-e',
266
+ `MCP_SERVER=${serverName}`,
267
+ '-e',
268
+ `MCP_AUTH_REQUIRED=true`,
269
+ '-e',
270
+ `MCP_REDIS_URL=${process.env.MCP_REDIS_URL || 'redis://localhost:6379'}`,
271
+ serverConfig.containerImage,
272
+ 'node',
273
+ `/app/mcp-${serverName}-server.js`
274
+ ]
275
+ };
276
+ } else {
277
+ return {
278
+ ...baseInfo,
279
+ type: 'http-endpoint',
280
+ url: serverConfig.url || `http://localhost:${3000 + this.mcpServers.size}`,
281
+ headers: {
282
+ 'Content-Type': 'application/json',
283
+ 'x-agent-token': token,
284
+ 'x-agent-type': 'dynamic'
285
+ }
286
+ };
287
+ }
288
+ }
289
+ /**
290
+ * Get complete MCP configuration for an agent
291
+ */ async getAgentMCPConfiguration(agentType, agentSkills = null, options = {}) {
292
+ try {
293
+ // Select required MCP servers
294
+ const selection = this.selectMCPServers(agentType, agentSkills);
295
+ // Generate tokens for selected servers
296
+ const tokens = await this.generateMCPTokens(agentType, selection.selectedMCPServers, options);
297
+ return {
298
+ agentType,
299
+ agentSkills: selection.agentSkills,
300
+ mcpConfiguration: {
301
+ mcpServers: tokens.reduce((config, tokenInfo)=>{
302
+ config[tokenInfo.serverName] = {
303
+ command: 'docker',
304
+ args: tokenInfo.connectionInfo.dockerArgs,
305
+ env: {
306
+ 'MCP_SERVER': tokenInfo.serverName,
307
+ 'MCP_AUTH_REQUIRED': 'true',
308
+ 'AGENT_TOKEN': tokenInfo.token
309
+ }
310
+ };
311
+ return config;
312
+ }, {})
313
+ },
314
+ selection,
315
+ tokens,
316
+ resourceSummary: {
317
+ totalMemoryMB: selection.totalMemoryRequired,
318
+ totalCPUUnits: selection.totalCPUUnits,
319
+ serverCount: selection.selectedMCPServers.length
320
+ }
321
+ };
322
+ } catch (error) {
323
+ console.error(`[SkillMCPSelector] Failed to get MCP configuration for ${agentType}:`, error);
324
+ throw error;
325
+ }
326
+ }
327
+ /**
328
+ * Generate Docker Compose configuration for agent with MCP servers
329
+ */ async generateDockerComposeConfiguration(agentType, agentSkills = null, options = {}) {
330
+ const config = await this.getAgentMCPConfiguration(agentType, agentSkills, options);
331
+ const dockerCompose = {
332
+ version: '3.8',
333
+ services: {},
334
+ networks: {
335
+ 'mcp-network': {
336
+ driver: 'bridge'
337
+ }
338
+ }
339
+ };
340
+ // Add agent service
341
+ dockerCompose.services[`${agentType}-agent`] = {
342
+ image: 'claude-flow-novice:agent-container',
343
+ container_name: `agent-${agentType}-${Date.now()}`,
344
+ networks: [
345
+ 'mcp-network'
346
+ ],
347
+ environment: {
348
+ 'AGENT_TYPE': agentType,
349
+ 'AGENT_MODE': 'containerized',
350
+ 'MCP_AUTH_ENABLED': 'true',
351
+ 'REDIS_URL': process.env.MCP_REDIS_URL || 'redis://redis:6379'
352
+ },
353
+ volumes: [
354
+ '${PWD}/.claude:/app/.claude:ro',
355
+ '${PWD}/screenshots:/app/screenshots'
356
+ ],
357
+ mem_limit: `${config.resourceSummary.totalMemoryMB + 512}m`,
358
+ depends_on: config.selection.selectedMCPServers.map((server)=>`mcp-${server}`).join(' ')
359
+ };
360
+ // Add MCP server services
361
+ for (const tokenInfo of config.tokens){
362
+ const serverName = `mcp-${tokenInfo.serverName}`;
363
+ const serverConfig = this.mcpServers.get(tokenInfo.serverName);
364
+ dockerCompose.services[serverName] = {
365
+ image: tokenInfo.containerImage,
366
+ container_name: `${serverName}-${Date.now()}`,
367
+ networks: [
368
+ 'mcp-network'
369
+ ],
370
+ environment: {
371
+ 'MCP_SERVER': tokenInfo.serverName,
372
+ 'MCP_AUTH_REQUIRED': 'true',
373
+ 'MCP_REDIS_URL': process.env.MCP_REDIS_URL || 'redis://redis:6379',
374
+ 'AGENT_TOKEN': tokenInfo.token
375
+ },
376
+ volumes: [
377
+ '${PWD}/screenshots:/app/screenshots'
378
+ ],
379
+ mem_limit: `${serverConfig.resourceRequirements?.memoryMB || 512}m`,
380
+ cpus: `${(serverConfig.resourceRequirements?.cpuUnits || 1) / 4}`
381
+ };
382
+ }
383
+ // Add Redis service if not present
384
+ if (!dockerCompose.services.redis) {
385
+ dockerCompose.services.redis = {
386
+ image: 'redis:7-alpine',
387
+ container_name: 'mcp-redis',
388
+ networks: [
389
+ 'mcp-network'
390
+ ],
391
+ volumes: [
392
+ 'redis-data:/data'
393
+ ],
394
+ mem_limit: '256m'
395
+ };
396
+ dockerCompose.volumes = {
397
+ 'redis-data': {}
398
+ };
399
+ }
400
+ return dockerCompose;
401
+ }
402
+ /**
403
+ * Get statistics about skill-MCP mappings
404
+ */ getStatistics() {
405
+ const skillMap = this.getSkillToMCPServerMapping();
406
+ return {
407
+ totalAgents: this.agentWhitelist.size,
408
+ totalMCPServers: this.mcpServers.size,
409
+ totalSkills: skillMap.size,
410
+ agentTypes: Array.from(this.agentWhitelist.keys()),
411
+ mcpServerNames: Array.from(this.mcpServers.keys()),
412
+ skillCoverage: Array.from(skillMap.entries()).map(([skill, servers])=>({
413
+ skill,
414
+ requiredServers: Array.from(servers),
415
+ serverCount: servers.size
416
+ }))
417
+ };
418
+ }
419
+ /**
420
+ * Validate agent-MCP configuration
421
+ */ validateConfiguration(agentType, mcpConfiguration) {
422
+ const agentConfig = this.agentWhitelist.get(agentType);
423
+ if (!agentConfig) {
424
+ return {
425
+ valid: false,
426
+ errors: [
427
+ `Unknown agent type: ${agentType}`
428
+ ]
429
+ };
430
+ }
431
+ const errors = [];
432
+ const warnings = [];
433
+ // Check required MCP servers
434
+ const requiredServers = agentConfig.allowedMcpServers || [];
435
+ const configuredServers = Object.keys(mcpConfiguration.mcpServers || {});
436
+ for (const server of requiredServers){
437
+ if (!configuredServers.includes(server)) {
438
+ errors.push(`Required MCP server missing: ${server}`);
439
+ }
440
+ }
441
+ // Check for unauthorized servers
442
+ for (const server of configuredServers){
443
+ if (!requiredServers.includes(server)) {
444
+ warnings.push(`Potentially unauthorized MCP server: ${server}`);
445
+ }
446
+ }
447
+ return {
448
+ valid: errors.length === 0,
449
+ errors,
450
+ warnings
451
+ };
452
+ }
453
+ async shutdown() {
454
+ await this.tokenManager.shutdown();
455
+ }
456
+ };
457
+ module.exports = SkillMCPSelector;
458
+
459
+ //# sourceMappingURL=skill-mcp-selector.js.map