claude-flow-novice 2.15.9 → 2.15.11
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/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +519 -0
- package/.claude/skills/cfn-loop-orchestration/ORCHESTRATOR_IMPLEMENTATION.md +493 -0
- package/.claude/skills/cfn-loop-orchestration/ORCHESTRATOR_QUICK_START.md +499 -0
- package/.claude/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +104 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +2 -2
- package/.claude/skills/cfn-loop-orchestration/src/orchestrate.ts +648 -0
- package/.claude/skills/cfn-loop-orchestration/tests/orchestrate.test.ts +836 -0
- package/README.md +205 -10
- package/claude-assets/agents/cfn-dev-team/CLAUDE.md +9 -81
- package/claude-assets/agents/cfn-dev-team/architecture/base-template-generator.md +4 -4
- package/claude-assets/agents/cfn-dev-team/architecture/planner.md +4 -4
- package/claude-assets/agents/cfn-dev-team/architecture/system-architect.md +5 -5
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +184 -229
- package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +4 -4
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +9 -37
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +9 -37
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +4 -4
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +10 -40
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +3 -0
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +4 -1
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +4 -1
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +4 -1
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +5 -0
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +2 -1
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +2 -1
- package/claude-assets/agents/cfn-dev-team/documentation/pseudocode.md +2 -7
- package/claude-assets/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +4 -4
- package/claude-assets/agents/cfn-dev-team/product-owners/cto-agent.md +4 -4
- package/claude-assets/agents/cfn-dev-team/product-owners/power-user-persona.md +4 -4
- package/claude-assets/agents/cfn-dev-team/product-owners/product-owner.md +18 -22
- package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +1 -1
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +1 -1
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +1 -1
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +1 -1
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +7 -35
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +17 -36
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +10 -11
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +5 -5
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +10 -12
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +7 -36
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +10 -12
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +10 -12
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +7 -37
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +7 -33
- package/claude-assets/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +5 -5
- package/claude-assets/agents/cfn-dev-team/testers/validation/validation-production-validator.md +4 -4
- package/claude-assets/agents/cfn-dev-team/testing/test-validation-agent.md +4 -4
- package/claude-assets/agents/cfn-dev-team/utility/agent-builder.md +16 -16
- package/claude-assets/agents/cfn-dev-team/utility/analyst.md +4 -4
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +4 -4
- package/claude-assets/agents/cfn-dev-team/utility/context-curator.md +4 -4
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +7 -85
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +7 -93
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +4 -4
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +7 -84
- package/claude-assets/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +519 -0
- package/claude-assets/skills/cfn-loop-orchestration/ORCHESTRATOR_IMPLEMENTATION.md +493 -0
- package/claude-assets/skills/cfn-loop-orchestration/ORCHESTRATOR_QUICK_START.md +499 -0
- package/claude-assets/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +104 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +2 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/orchestrate.ts +648 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/orchestrate.test.ts +836 -0
- package/dist/cli/agent-definition-parser.js +37 -4
- package/dist/cli/agent-definition-parser.js.map +1 -1
- package/dist/cli/agent-executor.js +32 -2
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/coordination/coordinate.js +369 -0
- package/dist/coordination/coordinate.js.map +1 -0
- package/dist/coordination/spawn-agent.js +364 -0
- package/dist/coordination/spawn-agent.js.map +1 -0
- package/dist/coordination/types-export.js +38 -0
- package/dist/coordination/types-export.js.map +1 -0
- package/package.json +1 -1
|
@@ -7,9 +7,39 @@
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
import { glob } from 'glob';
|
|
10
|
+
import { execSync } from 'child_process';
|
|
10
11
|
// ES Module compatibility
|
|
11
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
13
|
const __dirname = path.dirname(__filename);
|
|
14
|
+
/**
|
|
15
|
+
* Detect project root dynamically
|
|
16
|
+
* Uses PROJECT_ROOT env var if set, otherwise tries git, falls back to cwd
|
|
17
|
+
*/ function getProjectRoot() {
|
|
18
|
+
// 1. Check environment variable
|
|
19
|
+
if (process.env.PROJECT_ROOT) {
|
|
20
|
+
return process.env.PROJECT_ROOT;
|
|
21
|
+
}
|
|
22
|
+
// 2. Try git rev-parse (most reliable)
|
|
23
|
+
try {
|
|
24
|
+
const gitRoot = execSync('git rev-parse --show-toplevel', {
|
|
25
|
+
encoding: 'utf-8',
|
|
26
|
+
cwd: process.cwd(),
|
|
27
|
+
stdio: [
|
|
28
|
+
'pipe',
|
|
29
|
+
'pipe',
|
|
30
|
+
'ignore'
|
|
31
|
+
]
|
|
32
|
+
}).trim();
|
|
33
|
+
if (gitRoot) {
|
|
34
|
+
return gitRoot;
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
// Fall through to next method
|
|
38
|
+
}
|
|
39
|
+
// 3. Fall back to current working directory
|
|
40
|
+
return process.cwd();
|
|
41
|
+
}
|
|
42
|
+
const projectRoot = getProjectRoot();
|
|
13
43
|
/**
|
|
14
44
|
* Parse YAML frontmatter from markdown content
|
|
15
45
|
* Supports both Unix (LF) and Windows (CRLF) line endings
|
|
@@ -111,13 +141,15 @@ const __dirname = path.dirname(__filename);
|
|
|
111
141
|
/**
|
|
112
142
|
* Find agent definition file by agent type/name
|
|
113
143
|
* Searches multiple locations for agent definitions
|
|
114
|
-
*/ async function findAgentFile(agentType, baseDir
|
|
144
|
+
*/ async function findAgentFile(agentType, baseDir) {
|
|
115
145
|
// Normalize agent type (handle both kebab-case and underscores)
|
|
116
146
|
const normalizedType = agentType.toLowerCase().replace(/_/g, '-');
|
|
117
147
|
// Search locations (in order of priority)
|
|
148
|
+
// Use provided baseDir, or construct default path from project root
|
|
149
|
+
const defaultBaseDir = path.join(projectRoot, '.claude/agents');
|
|
118
150
|
const searchLocations = [
|
|
119
|
-
baseDir,
|
|
120
|
-
|
|
151
|
+
baseDir || defaultBaseDir,
|
|
152
|
+
defaultBaseDir,
|
|
121
153
|
path.join(__dirname, '../../.claude/agents'),
|
|
122
154
|
'/app/.claude/agents'
|
|
123
155
|
];
|
|
@@ -164,7 +196,8 @@ const __dirname = path.dirname(__filename);
|
|
|
164
196
|
// Parse frontmatter and body
|
|
165
197
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
166
198
|
// Extract category from path
|
|
167
|
-
const
|
|
199
|
+
const agentsPath = path.join(projectRoot, '.claude/agents');
|
|
200
|
+
const relativePath = path.relative(agentsPath, filePath);
|
|
168
201
|
const category = relativePath.includes('/') ? relativePath.split('/')[0] : undefined;
|
|
169
202
|
// Build agent definition
|
|
170
203
|
const definition = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/agent-definition-parser.ts"],"sourcesContent":["/**\r\n * Agent Definition Parser\r\n *\r\n * Parses agent definition files (.md) with YAML frontmatter and markdown content.\r\n * Supports agent definitions in .claude/agents/ directory structure.\r\n */\r\n\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport { glob } from 'glob';\r\n\r\n// ES Module compatibility\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = path.dirname(__filename);\r\n\r\nexport interface AgentDefinition {\r\n // YAML frontmatter fields\r\n name: string;\r\n description: string;\r\n tools: string[];\r\n model: 'haiku' | 'sonnet' | 'opus';\r\n type?: string;\r\n color?: string;\r\n acl_level?: number;\r\n capabilities?: string[];\r\n validation_hooks?: string[];\r\n lifecycle?: {\r\n pre_task?: string;\r\n post_task?: string;\r\n };\r\n\r\n // Parsed markdown content\r\n content: string;\r\n\r\n // File metadata\r\n filePath: string;\r\n category?: string; // e.g., 'core-agents', 'specialized', 'custom'\r\n}\r\n\r\n/**\r\n * Parse YAML frontmatter from markdown content\r\n * Supports both Unix (LF) and Windows (CRLF) line endings\r\n */\r\nfunction parseFrontmatter(content: string): { frontmatter: Record<string, any>; body: string } {\r\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/;\r\n const match = content.match(frontmatterRegex);\r\n\r\n if (!match) {\r\n return { frontmatter: {}, body: content };\r\n }\r\n\r\n const [, yamlContent, body] = match;\r\n\r\n \r\n // Simple YAML parser (handles basic key-value pairs, arrays, and objects)\r\n const frontmatter: Record<string, any> = {};\r\n const lines = yamlContent.split('\\n');\r\n let currentKey = '';\r\n let currentArray: string[] = [];\r\n let isInArray = false;\r\n let isInObject = false;\r\n let currentObject: Record<string, string> = {};\r\n let objectKey = '';\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('#')) continue;\r\n\r\n // Array item\r\n if (trimmed.startsWith('- ')) {\r\n if (!isInArray) {\r\n isInArray = true;\r\n currentArray = [];\r\n }\r\n currentArray.push(trimmed.substring(2).trim());\r\n continue;\r\n }\r\n\r\n // End of array\r\n if (isInArray && !trimmed.startsWith('- ')) {\r\n frontmatter[currentKey] = currentArray;\r\n isInArray = false;\r\n currentArray = [];\r\n }\r\n\r\n // Object field (indented key-value)\r\n if (trimmed.match(/^\\s+\\w+:/) && isInObject) {\r\n const [objKey, ...objValueParts] = trimmed.split(':');\r\n const objValue = objValueParts.join(':').trim().replace(/^[\"']|[\"']$/g, '');\r\n currentObject[objKey.trim()] = objValue;\r\n continue;\r\n }\r\n\r\n // Key-value pair\r\n const colonIndex = trimmed.indexOf(':');\r\n if (colonIndex !== -1) {\r\n const key = trimmed.substring(0, colonIndex).trim();\r\n const value = trimmed.substring(colonIndex + 1).trim();\r\n\r\n // Check if this starts an object\r\n if (value === '') {\r\n isInObject = true;\r\n currentObject = {};\r\n objectKey = key;\r\n continue;\r\n }\r\n\r\n // End previous object if any\r\n if (isInObject && !trimmed.match(/^\\s+/)) {\r\n frontmatter[objectKey] = currentObject;\r\n isInObject = false;\r\n currentObject = {};\r\n }\r\n\r\n currentKey = key;\r\n\r\n // Multi-line string (starts with |)\r\n if (value === '|') {\r\n continue; // Will be handled by next lines\r\n }\r\n\r\n // Inline array (e.g., [item1, item2, item3])\r\n if (value.startsWith('[') && value.endsWith(']')) {\r\n const arrayContent = value.substring(1, value.length - 1);\r\n const items = arrayContent.split(',').map(item => item.trim());\r\n frontmatter[key] = items;\r\n continue;\r\n }\r\n\r\n // Remove quotes\r\n const cleanValue = value.replace(/^[\"']|[\"']$/g, '');\r\n frontmatter[key] = cleanValue;\r\n } else if (currentKey && trimmed && !isInArray && !isInObject) {\r\n // Continuation of multi-line string\r\n const existingValue = frontmatter[currentKey];\r\n frontmatter[currentKey] = existingValue\r\n ? `${existingValue}\\n${trimmed}`\r\n : trimmed;\r\n }\r\n }\r\n\r\n // Handle trailing array or object\r\n if (isInArray) {\r\n frontmatter[currentKey] = currentArray;\r\n }\r\n if (isInObject) {\r\n frontmatter[objectKey] = currentObject;\r\n }\r\n\r\n return { frontmatter, body: body.trim() };\r\n}\r\n\r\n/**\r\n * Find agent definition file by agent type/name\r\n * Searches multiple locations for agent definitions\r\n */\r\nasync function findAgentFile(agentType: string, baseDir: string = '.claude/agents'): Promise<string | null> {\r\n // Normalize agent type (handle both kebab-case and underscores)\r\n const normalizedType = agentType.toLowerCase().replace(/_/g, '-');\r\n\r\n // Search locations (in order of priority)\r\n const searchLocations = [\r\n baseDir, // Current working directory\r\n '.claude/agents', // Standard location\r\n path.join(__dirname, '../../.claude/agents'), // CLI installation directory\r\n '/app/.claude/agents', // Docker container location\r\n ];\r\n\r\n // Search patterns (in order of priority)\r\n const searchPatterns = [\r\n // Exact match in any subdirectory\r\n (loc: string) => `${loc}/**/${normalizedType}.md`,\r\n // Match with different casing\r\n (loc: string) => `${loc}/**/*${normalizedType}*.md`,\r\n ];\r\n\r\n for (const location of searchLocations) {\r\n for (const patternFn of searchPatterns) {\r\n const pattern = patternFn(location);\r\n try {\r\n const files = await glob(pattern, { nodir: true, absolute: true });\r\n if (files.length > 0) {\r\n // Prefer exact match over partial match\r\n const exactMatch = files.find(f => {\r\n const basename = path.basename(f, '.md').toLowerCase();\r\n return basename === normalizedType;\r\n });\r\n return exactMatch || files[0];\r\n }\r\n } catch (error) {\r\n // Skip location if it doesn't exist\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse agent definition from file\r\n */\r\nexport async function parseAgentDefinition(agentType: string): Promise<AgentDefinition> {\r\n // Find agent file\r\n const filePath = await findAgentFile(agentType);\r\n\r\n if (!filePath) {\r\n throw new Error(`Agent definition not found: ${agentType}`);\r\n }\r\n\r\n // Read file content\r\n const content = await fs.readFile(filePath, 'utf-8');\r\n\r\n \r\n // Parse frontmatter and body\r\n const { frontmatter, body } = parseFrontmatter(content);\r\n\r\n // Extract category from path\r\n const relativePath = path.relative('.claude/agents', filePath);\r\n const category = relativePath.includes('/')\r\n ? relativePath.split('/')[0]\r\n : undefined;\r\n\r\n \r\n // Build agent definition\r\n const definition: AgentDefinition = {\r\n name: frontmatter.name || agentType,\r\n description: frontmatter.description || '',\r\n tools: Array.isArray(frontmatter.tools) ? frontmatter.tools : [],\r\n model: frontmatter.model || 'haiku',\r\n type: frontmatter.type,\r\n color: frontmatter.color,\r\n acl_level: frontmatter.acl_level ? parseInt(String(frontmatter.acl_level), 10) : undefined,\r\n capabilities: frontmatter.capabilities,\r\n validation_hooks: frontmatter.validation_hooks,\r\n lifecycle: frontmatter.lifecycle,\r\n content: body,\r\n filePath,\r\n category,\r\n };\r\n\r\n return definition;\r\n}\r\n\r\n/**\r\n * List all available agent definitions\r\n */\r\nexport async function listAgentDefinitions(baseDir: string = '.claude/agents'): Promise<string[]> {\r\n const pattern = `${baseDir}/**/*.md`;\r\n const files = await glob(pattern, { nodir: true });\r\n\r\n return files.map(f => path.basename(f, '.md'));\r\n}\r\n\r\n/**\r\n * Check if agent definition includes CFN Loop protocol\r\n */\r\nexport function hasCFNLoopProtocol(definition: AgentDefinition): boolean {\r\n const content = definition.content.toLowerCase();\r\n return (\r\n content.includes('cfn loop') &&\r\n content.includes('redis completion protocol') ||\r\n content.includes('invoke-waiting-mode.sh')\r\n );\r\n}\r\n"],"names":["fs","path","fileURLToPath","glob","__filename","url","__dirname","dirname","parseFrontmatter","content","frontmatterRegex","match","frontmatter","body","yamlContent","lines","split","currentKey","currentArray","isInArray","isInObject","currentObject","objectKey","line","trimmed","trim","startsWith","push","substring","objKey","objValueParts","objValue","join","replace","colonIndex","indexOf","key","value","endsWith","arrayContent","length","items","map","item","cleanValue","existingValue","findAgentFile","agentType","baseDir","normalizedType","toLowerCase","searchLocations","searchPatterns","loc","location","patternFn","pattern","files","nodir","absolute","exactMatch","find","f","basename","error","parseAgentDefinition","filePath","Error","readFile","relativePath","relative","category","includes","undefined","definition","name","description","tools","Array","isArray","model","type","color","acl_level","parseInt","String","capabilities","validation_hooks","lifecycle","listAgentDefinitions","hasCFNLoopProtocol"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/agent-definition-parser.ts"],"sourcesContent":["/**\r\n * Agent Definition Parser\r\n *\r\n * Parses agent definition files (.md) with YAML frontmatter and markdown content.\r\n * Supports agent definitions in .claude/agents/ directory structure.\r\n */\r\n\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport { glob } from 'glob';\r\nimport { execSync } from 'child_process';\r\n\r\n// ES Module compatibility\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = path.dirname(__filename);\r\n\r\n/**\r\n * Detect project root dynamically\r\n * Uses PROJECT_ROOT env var if set, otherwise tries git, falls back to cwd\r\n */\r\nfunction getProjectRoot(): string {\r\n // 1. Check environment variable\r\n if (process.env.PROJECT_ROOT) {\r\n return process.env.PROJECT_ROOT;\r\n }\r\n\r\n // 2. Try git rev-parse (most reliable)\r\n try {\r\n const gitRoot = execSync('git rev-parse --show-toplevel', {\r\n encoding: 'utf-8',\r\n cwd: process.cwd(),\r\n stdio: ['pipe', 'pipe', 'ignore']\r\n }).trim();\r\n if (gitRoot) {\r\n return gitRoot;\r\n }\r\n } catch {\r\n // Fall through to next method\r\n }\r\n\r\n // 3. Fall back to current working directory\r\n return process.cwd();\r\n}\r\n\r\nconst projectRoot = getProjectRoot();\r\n\r\nexport interface AgentDefinition {\r\n // YAML frontmatter fields\r\n name: string;\r\n description: string;\r\n tools: string[];\r\n model: 'haiku' | 'sonnet' | 'opus';\r\n type?: string;\r\n color?: string;\r\n acl_level?: number;\r\n capabilities?: string[];\r\n validation_hooks?: string[];\r\n lifecycle?: {\r\n pre_task?: string;\r\n post_task?: string;\r\n };\r\n\r\n // Parsed markdown content\r\n content: string;\r\n\r\n // File metadata\r\n filePath: string;\r\n category?: string; // e.g., 'core-agents', 'specialized', 'custom'\r\n}\r\n\r\n/**\r\n * Parse YAML frontmatter from markdown content\r\n * Supports both Unix (LF) and Windows (CRLF) line endings\r\n */\r\nfunction parseFrontmatter(content: string): { frontmatter: Record<string, any>; body: string } {\r\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/;\r\n const match = content.match(frontmatterRegex);\r\n\r\n if (!match) {\r\n return { frontmatter: {}, body: content };\r\n }\r\n\r\n const [, yamlContent, body] = match;\r\n\r\n \r\n // Simple YAML parser (handles basic key-value pairs, arrays, and objects)\r\n const frontmatter: Record<string, any> = {};\r\n const lines = yamlContent.split('\\n');\r\n let currentKey = '';\r\n let currentArray: string[] = [];\r\n let isInArray = false;\r\n let isInObject = false;\r\n let currentObject: Record<string, string> = {};\r\n let objectKey = '';\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('#')) continue;\r\n\r\n // Array item\r\n if (trimmed.startsWith('- ')) {\r\n if (!isInArray) {\r\n isInArray = true;\r\n currentArray = [];\r\n }\r\n currentArray.push(trimmed.substring(2).trim());\r\n continue;\r\n }\r\n\r\n // End of array\r\n if (isInArray && !trimmed.startsWith('- ')) {\r\n frontmatter[currentKey] = currentArray;\r\n isInArray = false;\r\n currentArray = [];\r\n }\r\n\r\n // Object field (indented key-value)\r\n if (trimmed.match(/^\\s+\\w+:/) && isInObject) {\r\n const [objKey, ...objValueParts] = trimmed.split(':');\r\n const objValue = objValueParts.join(':').trim().replace(/^[\"']|[\"']$/g, '');\r\n currentObject[objKey.trim()] = objValue;\r\n continue;\r\n }\r\n\r\n // Key-value pair\r\n const colonIndex = trimmed.indexOf(':');\r\n if (colonIndex !== -1) {\r\n const key = trimmed.substring(0, colonIndex).trim();\r\n const value = trimmed.substring(colonIndex + 1).trim();\r\n\r\n // Check if this starts an object\r\n if (value === '') {\r\n isInObject = true;\r\n currentObject = {};\r\n objectKey = key;\r\n continue;\r\n }\r\n\r\n // End previous object if any\r\n if (isInObject && !trimmed.match(/^\\s+/)) {\r\n frontmatter[objectKey] = currentObject;\r\n isInObject = false;\r\n currentObject = {};\r\n }\r\n\r\n currentKey = key;\r\n\r\n // Multi-line string (starts with |)\r\n if (value === '|') {\r\n continue; // Will be handled by next lines\r\n }\r\n\r\n // Inline array (e.g., [item1, item2, item3])\r\n if (value.startsWith('[') && value.endsWith(']')) {\r\n const arrayContent = value.substring(1, value.length - 1);\r\n const items = arrayContent.split(',').map(item => item.trim());\r\n frontmatter[key] = items;\r\n continue;\r\n }\r\n\r\n // Remove quotes\r\n const cleanValue = value.replace(/^[\"']|[\"']$/g, '');\r\n frontmatter[key] = cleanValue;\r\n } else if (currentKey && trimmed && !isInArray && !isInObject) {\r\n // Continuation of multi-line string\r\n const existingValue = frontmatter[currentKey];\r\n frontmatter[currentKey] = existingValue\r\n ? `${existingValue}\\n${trimmed}`\r\n : trimmed;\r\n }\r\n }\r\n\r\n // Handle trailing array or object\r\n if (isInArray) {\r\n frontmatter[currentKey] = currentArray;\r\n }\r\n if (isInObject) {\r\n frontmatter[objectKey] = currentObject;\r\n }\r\n\r\n return { frontmatter, body: body.trim() };\r\n}\r\n\r\n/**\r\n * Find agent definition file by agent type/name\r\n * Searches multiple locations for agent definitions\r\n */\r\nasync function findAgentFile(agentType: string, baseDir?: string): Promise<string | null> {\r\n // Normalize agent type (handle both kebab-case and underscores)\r\n const normalizedType = agentType.toLowerCase().replace(/_/g, '-');\r\n\r\n // Search locations (in order of priority)\r\n // Use provided baseDir, or construct default path from project root\r\n const defaultBaseDir = path.join(projectRoot, '.claude/agents');\r\n const searchLocations = [\r\n baseDir || defaultBaseDir, // Provided or default working directory\r\n defaultBaseDir, // Standard location relative to project root\r\n path.join(__dirname, '../../.claude/agents'), // CLI installation directory\r\n '/app/.claude/agents', // Docker container location\r\n ];\r\n\r\n // Search patterns (in order of priority)\r\n const searchPatterns = [\r\n // Exact match in any subdirectory\r\n (loc: string) => `${loc}/**/${normalizedType}.md`,\r\n // Match with different casing\r\n (loc: string) => `${loc}/**/*${normalizedType}*.md`,\r\n ];\r\n\r\n for (const location of searchLocations) {\r\n for (const patternFn of searchPatterns) {\r\n const pattern = patternFn(location);\r\n try {\r\n const files = await glob(pattern, { nodir: true, absolute: true });\r\n if (files.length > 0) {\r\n // Prefer exact match over partial match\r\n const exactMatch = files.find(f => {\r\n const basename = path.basename(f, '.md').toLowerCase();\r\n return basename === normalizedType;\r\n });\r\n return exactMatch || files[0];\r\n }\r\n } catch (error) {\r\n // Skip location if it doesn't exist\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse agent definition from file\r\n */\r\nexport async function parseAgentDefinition(agentType: string): Promise<AgentDefinition> {\r\n // Find agent file\r\n const filePath = await findAgentFile(agentType);\r\n\r\n if (!filePath) {\r\n throw new Error(`Agent definition not found: ${agentType}`);\r\n }\r\n\r\n // Read file content\r\n const content = await fs.readFile(filePath, 'utf-8');\r\n\r\n \r\n // Parse frontmatter and body\r\n const { frontmatter, body } = parseFrontmatter(content);\r\n\r\n // Extract category from path\r\n const agentsPath = path.join(projectRoot, '.claude/agents');\r\n const relativePath = path.relative(agentsPath, filePath);\r\n const category = relativePath.includes('/')\r\n ? relativePath.split('/')[0]\r\n : undefined;\r\n\r\n \r\n // Build agent definition\r\n const definition: AgentDefinition = {\r\n name: frontmatter.name || agentType,\r\n description: frontmatter.description || '',\r\n tools: Array.isArray(frontmatter.tools) ? frontmatter.tools : [],\r\n model: frontmatter.model || 'haiku',\r\n type: frontmatter.type,\r\n color: frontmatter.color,\r\n acl_level: frontmatter.acl_level ? parseInt(String(frontmatter.acl_level), 10) : undefined,\r\n capabilities: frontmatter.capabilities,\r\n validation_hooks: frontmatter.validation_hooks,\r\n lifecycle: frontmatter.lifecycle,\r\n content: body,\r\n filePath,\r\n category,\r\n };\r\n\r\n return definition;\r\n}\r\n\r\n/**\r\n * List all available agent definitions\r\n */\r\nexport async function listAgentDefinitions(baseDir: string = '.claude/agents'): Promise<string[]> {\r\n const pattern = `${baseDir}/**/*.md`;\r\n const files = await glob(pattern, { nodir: true });\r\n\r\n return files.map(f => path.basename(f, '.md'));\r\n}\r\n\r\n/**\r\n * Check if agent definition includes CFN Loop protocol\r\n */\r\nexport function hasCFNLoopProtocol(definition: AgentDefinition): boolean {\r\n const content = definition.content.toLowerCase();\r\n return (\r\n content.includes('cfn loop') &&\r\n content.includes('redis completion protocol') ||\r\n content.includes('invoke-waiting-mode.sh')\r\n );\r\n}\r\n"],"names":["fs","path","fileURLToPath","glob","execSync","__filename","url","__dirname","dirname","getProjectRoot","process","env","PROJECT_ROOT","gitRoot","encoding","cwd","stdio","trim","projectRoot","parseFrontmatter","content","frontmatterRegex","match","frontmatter","body","yamlContent","lines","split","currentKey","currentArray","isInArray","isInObject","currentObject","objectKey","line","trimmed","startsWith","push","substring","objKey","objValueParts","objValue","join","replace","colonIndex","indexOf","key","value","endsWith","arrayContent","length","items","map","item","cleanValue","existingValue","findAgentFile","agentType","baseDir","normalizedType","toLowerCase","defaultBaseDir","searchLocations","searchPatterns","loc","location","patternFn","pattern","files","nodir","absolute","exactMatch","find","f","basename","error","parseAgentDefinition","filePath","Error","readFile","agentsPath","relativePath","relative","category","includes","undefined","definition","name","description","tools","Array","isArray","model","type","color","acl_level","parseInt","String","capabilities","validation_hooks","lifecycle","listAgentDefinitions","hasCFNLoopProtocol"],"mappings":"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"}
|
|
@@ -15,7 +15,37 @@ import { convertToolNames } from './tool-definitions.js';
|
|
|
15
15
|
import fs from 'fs/promises';
|
|
16
16
|
import path from 'path';
|
|
17
17
|
import os from 'os';
|
|
18
|
+
import { execSync } from 'child_process';
|
|
18
19
|
const execAsync = promisify(exec);
|
|
20
|
+
/**
|
|
21
|
+
* Detect project root dynamically
|
|
22
|
+
* Uses PROJECT_ROOT env var if set, otherwise tries git, falls back to cwd
|
|
23
|
+
*/ function getProjectRoot() {
|
|
24
|
+
// 1. Check environment variable
|
|
25
|
+
if (process.env.PROJECT_ROOT) {
|
|
26
|
+
return process.env.PROJECT_ROOT;
|
|
27
|
+
}
|
|
28
|
+
// 2. Try git rev-parse (most reliable)
|
|
29
|
+
try {
|
|
30
|
+
const gitRoot = execSync('git rev-parse --show-toplevel', {
|
|
31
|
+
encoding: 'utf-8',
|
|
32
|
+
cwd: process.cwd(),
|
|
33
|
+
stdio: [
|
|
34
|
+
'pipe',
|
|
35
|
+
'pipe',
|
|
36
|
+
'ignore'
|
|
37
|
+
]
|
|
38
|
+
}).trim();
|
|
39
|
+
if (gitRoot) {
|
|
40
|
+
return gitRoot;
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
// Fall through to next method
|
|
44
|
+
}
|
|
45
|
+
// 3. Fall back to current working directory
|
|
46
|
+
return process.cwd();
|
|
47
|
+
}
|
|
48
|
+
const projectRoot = getProjectRoot();
|
|
19
49
|
// Bug #6 Fix: Read Redis connection parameters from process.env
|
|
20
50
|
// ENV-001: Standardized environment variable naming (REDIS_PASSWORD for all deployments)
|
|
21
51
|
const redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';
|
|
@@ -124,7 +154,7 @@ const redisPassword = process.env.CFN_REDIS_PASSWORD || process.env.REDIS_PASSWO
|
|
|
124
154
|
}
|
|
125
155
|
// Check config file (.claude/config/api-provider.json)
|
|
126
156
|
try {
|
|
127
|
-
const configPath = path.join('.claude', 'config', 'api-provider.json');
|
|
157
|
+
const configPath = path.join(projectRoot, '.claude', 'config', 'api-provider.json');
|
|
128
158
|
const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));
|
|
129
159
|
return config.provider === 'zai' || config.provider === 'z.ai';
|
|
130
160
|
} catch {
|
|
@@ -269,7 +299,7 @@ const redisPassword = process.env.CFN_REDIS_PASSWORD || process.env.REDIS_PASSWO
|
|
|
269
299
|
console.log(`[agent-executor] Model: ${definition.model}`);
|
|
270
300
|
console.log(`[agent-executor] Prompt file: ${promptFile}`);
|
|
271
301
|
return new Promise((resolve)=>{
|
|
272
|
-
const scriptPath = path.join('.claude', 'skills', 'agent-execution', 'execute-agent.sh');
|
|
302
|
+
const scriptPath = path.join(projectRoot, '.claude', 'skills', 'agent-execution', 'execute-agent.sh');
|
|
273
303
|
// Build environment variables - WHITELIST ONLY APPROACH
|
|
274
304
|
// SECURITY FIX: Do not use ...process.env spread which exposes ALL variables including secrets
|
|
275
305
|
// Instead, explicitly whitelist safe variables to pass to spawned process
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/agent-executor.ts"],"sourcesContent":["/**\r\n * Agent Executor\r\n *\r\n * Executes CLI-spawned agents by:\r\n * 1. Checking custom routing configuration (z.ai vs Anthropic)\r\n * 2. Invoking the appropriate API\r\n * 3. Managing agent lifecycle and output\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { AgentDefinition } from './agent-definition-parser.js';\r\nimport { TaskContext, getAgentId } from './agent-prompt-builder.js';\r\nimport { buildCLIAgentSystemPrompt, loadContextFromEnv } from './cli-agent-context.js';\r\nimport {\r\n loadMessages,\r\n storeMessage,\r\n getCurrentFork,\r\n formatMessagesForAPI,\r\n type Message\r\n} from './conversation-fork.js';\r\nimport { convertToolNames } from './tool-definitions.js';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport os from 'os';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\n// Bug #6 Fix: Read Redis connection parameters from process.env\r\n// ENV-001: Standardized environment variable naming (REDIS_PASSWORD for all deployments)\r\nconst redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\nconst redisPort = process.env.CFN_REDIS_PORT || '6379';\r\nconst redisPassword = process.env.CFN_REDIS_PASSWORD || process.env.REDIS_PASSWORD || '';\r\n\r\nexport interface AgentExecutionResult {\r\n success: boolean;\r\n agentId: string;\r\n output?: string;\r\n error?: string;\r\n exitCode: number;\r\n}\r\n\r\n/**\r\n * Parse context string into environment variables\r\n *\r\n * Parses context string like \"TASK_ID='xyz' MODE='mvp' MAX_ITERATIONS=5\"\r\n * and sets the values as environment variables.\r\n *\r\n * Supports:\r\n * - Single quoted: KEY='value with spaces'\r\n * - Double quoted: KEY=\"value with spaces\"\r\n * - Unquoted: KEY=value (no spaces in value)\r\n *\r\n * @param contextString - Context string from --context parameter\r\n * @returns Object with parsed key-value pairs\r\n */\r\nfunction parseContextToEnv(contextString: string | undefined): Record<string, string> {\r\n if (!contextString) return {};\r\n\r\n const envVars: Record<string, string> = {};\r\n\r\n // Match KEY='value' or KEY=\"value\" or KEY=value patterns\r\n // For quoted values: capture everything between quotes\r\n // For unquoted values: capture until next space or end of string\r\n const regex = /(\\w+)=(?:(['\"])([^\\2]*?)\\2|([^\\s]+))/g;\r\n let match;\r\n\r\n while ((match = regex.exec(contextString)) !== null) {\r\n const [, key, , quotedValue, unquotedValue] = match;\r\n const value = quotedValue !== undefined ? quotedValue : unquotedValue;\r\n envVars[key] = value;\r\n // Also set in process.env for current process\r\n process.env[key] = value;\r\n }\r\n\r\n return envVars;\r\n}\r\n\r\n/**\r\n * Extract confidence score from agent output\r\n * Looks for patterns like:\r\n * - \"confidence: 0.85\"\r\n * - \"Confidence: 0.90\"\r\n * - \"confidence score: 0.95\"\r\n * - \"self-confidence: 0.88\"\r\n */\r\nfunction extractConfidence(output: string | undefined): number {\r\n if (!output) return 0.85;\r\n\r\n // Try multiple patterns\r\n const patterns = [\r\n /confidence:\\s*([0-9.]+)/i,\r\n /confidence\\s+score:\\s*([0-9.]+)/i,\r\n /self-confidence:\\s*([0-9.]+)/i,\r\n /my\\s+confidence:\\s*([0-9.]+)/i,\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = output.match(pattern);\r\n if (match && match[1]) {\r\n const score = parseFloat(match[1]);\r\n if (score >= 0 && score <= 1) {\r\n return score;\r\n }\r\n }\r\n }\r\n\r\n // Default to 0.85 if not found\r\n return 0.85;\r\n}\r\n\r\n/**\r\n * Execute CFN Loop protocol after agent completes work\r\n *\r\n * Steps:\r\n * 1. Signal completion to orchestrator\r\n * 2. Report confidence score\r\n * 3. Enter waiting mode (if iterations enabled)\r\n */\r\nasync function executeCFNProtocol(\r\n taskId: string,\r\n agentId: string,\r\n output: string | undefined,\r\n iteration: number,\r\n enableIterations: boolean = false,\r\n maxIterations: number = 10\r\n): Promise<void> {\r\n console.log(`\\n[CFN Protocol] Starting for agent ${agentId}`);\r\n console.log(`[CFN Protocol] Task ID: ${taskId}, Iteration: ${iteration}`);\r\n\r\n try {\r\n // Step 1: Signal completion\r\n console.log('[CFN Protocol] Step 1: Signaling completion...');\r\n const authFlag = redisPassword ? `-a \"${redisPassword}\"` : '';\r\n await execAsync(`redis-cli -h \"${redisHost}\" -p \"${redisPort}\" ${authFlag} lpush \"swarm:${taskId}:${agentId}:done\" \"complete\"`);\r\n console.log('[CFN Protocol] ✓ Completion signaled');\r\n\r\n // Step 2: Extract and report confidence\r\n const confidence = extractConfidence(output);\r\n console.log(`[CFN Protocol] Step 2: Reporting confidence (${confidence})...`);\r\n\r\n const reportCmd = `./.claude/skills/cfn-redis-coordination/report-completion.sh \\\r\n --task-id \"${taskId}\" \\\r\n --agent-id \"${agentId}\" \\\r\n --confidence ${confidence} \\\r\n --iteration ${iteration}`;\r\n\r\n await execAsync(reportCmd);\r\n console.log('[CFN Protocol] ✓ Confidence reported');\r\n\r\n // Step 3: Exit cleanly (BUG #18 FIX - removed waiting mode)\r\n // Orchestrator will spawn appropriate specialist agent for next iteration\r\n // This enables adaptive agent specialization based on feedback type\r\n console.log('[CFN Protocol] Step 3: Exiting cleanly (iteration complete)');\r\n console.log('[CFN Protocol] Protocol complete\\n');\r\n } catch (error) {\r\n console.error('[CFN Protocol] Error:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Check if custom routing (z.ai) is enabled\r\n */\r\nasync function isCustomRoutingEnabled(): Promise<boolean> {\r\n // Check environment variable\r\n if (process.env.CLAUDE_API_PROVIDER === 'zai') {\r\n return true;\r\n }\r\n\r\n // Check config file (.claude/config/api-provider.json)\r\n try {\r\n const configPath = path.join('.claude', 'config', 'api-provider.json');\r\n const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));\r\n return config.provider === 'zai' || config.provider === 'z.ai';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get API provider configuration\r\n */\r\nasync function getAPIProvider(): Promise<'anthropic' | 'zai'> {\r\n const customEnabled = await isCustomRoutingEnabled();\r\n return customEnabled ? 'zai' : 'anthropic';\r\n}\r\n\r\n/**\r\n * Execute agent using direct API calls\r\n */\r\nasync function executeViaAPI(\r\n definition: AgentDefinition,\r\n prompt: string,\r\n context: TaskContext\r\n): Promise<AgentExecutionResult> {\r\n const agentId = getAgentId(definition, context);\r\n\r\n console.log(`[agent-executor] Executing agent via API: ${definition.name}`);\r\n console.log(`[agent-executor] Agent ID: ${agentId}`);\r\n console.log(`[agent-executor] Model: ${definition.model}`);\r\n console.log('');\r\n\r\n // BUG #24 FIX: Parse and inject context environment variables\r\n // This enables CLI-spawned agents to access TASK_ID, MODE, etc. in Bash tool\r\n if (context.context) {\r\n console.log(`[agent-executor] Parsing context: ${context.context}`);\r\n const contextEnv = parseContextToEnv(context.context);\r\n console.log(`[agent-executor] Injected env vars: ${Object.keys(contextEnv).join(', ')}`);\r\n }\r\n\r\n try {\r\n // Check for conversation fork (Sprint 4 enhancement)\r\n const forkId = process.env.FORK_ID || await getCurrentFork(context.taskId || '', agentId);\r\n const iteration = context.iteration || 1;\r\n\r\n let systemPrompt: string;\r\n let messages: Array<{role: string, content: string}> = [];\r\n\r\n if (forkId && iteration > 1) {\r\n // Continue from fork (iterations 2+)\r\n console.log(`[agent-executor] Continuing from fork: ${forkId}`);\r\n\r\n // Load fork messages\r\n const forkMessages = await loadMessages(context.taskId || '', agentId, forkId);\r\n console.log(`[agent-executor] Loaded ${forkMessages.length} messages from fork`);\r\n\r\n // Extract system prompt from first message (it's always the system message)\r\n // The fork messages are assistant/user pairs, we need to add system separately\r\n systemPrompt = forkMessages[0]?.content || '';\r\n\r\n // Format remaining messages for API\r\n messages = formatMessagesForAPI(forkMessages.slice(1));\r\n\r\n // Add new user message with feedback\r\n messages.push({\r\n role: 'user',\r\n content: prompt\r\n });\r\n\r\n console.log(`[agent-executor] Fork continuation: ${messages.length} messages`);\r\n } else {\r\n // New conversation (iteration 1)\r\n console.log('[agent-executor] Starting new conversation');\r\n console.log('[agent-executor] Building system prompt with context...');\r\n\r\n const contextOptions = loadContextFromEnv();\r\n contextOptions.agentType = definition.name;\r\n if (context.taskId) contextOptions.taskId = context.taskId;\r\n if (context.iteration) contextOptions.iteration = context.iteration;\r\n\r\n systemPrompt = await buildCLIAgentSystemPrompt(contextOptions);\r\n console.log('[agent-executor] System prompt built successfully');\r\n\r\n // Initial user message\r\n messages = [{\r\n role: 'user',\r\n content: prompt\r\n }];\r\n }\r\n\r\n console.log('');\r\n\r\n // Dynamic import to avoid bundling issues\r\n const { executeAgentAPI } = await import('./anthropic-client.js');\r\n\r\n // Convert agent tool names to Anthropic API format\r\n const tools = definition.tools && definition.tools.length > 0\r\n ? convertToolNames(definition.tools)\r\n : undefined;\r\n\r\n const result = await executeAgentAPI(\r\n definition.name,\r\n agentId,\r\n definition.model,\r\n prompt,\r\n systemPrompt,\r\n messages.length > 1 ? messages : undefined,\r\n undefined, // maxTokens (use default)\r\n tools // Pass converted tools\r\n );\r\n\r\n // Store messages in conversation history (for future forking)\r\n if (context.taskId) {\r\n // Store user message\r\n const userMessage: Message = {\r\n role: 'user',\r\n content: prompt,\r\n iteration,\r\n timestamp: new Date().toISOString()\r\n };\r\n await storeMessage(context.taskId, agentId, userMessage);\r\n\r\n // Store assistant response\r\n if (result.output) {\r\n const assistantMessage: Message = {\r\n role: 'assistant',\r\n content: result.output,\r\n iteration,\r\n timestamp: new Date().toISOString()\r\n };\r\n await storeMessage(context.taskId, agentId, assistantMessage);\r\n }\r\n\r\n console.log(`[agent-executor] Stored messages for iteration ${iteration}`);\r\n\r\n // Execute CFN Loop protocol (signal completion, report confidence, enter waiting mode)\r\n // Iterations are enabled for CFN Loop tasks (indicated by presence of taskId)\r\n try {\r\n const maxIterations = 10; // Default max iterations\r\n const enableIterations = true; // Enable iterations for all CFN Loop tasks\r\n\r\n await executeCFNProtocol(\r\n context.taskId,\r\n agentId,\r\n result.output,\r\n iteration,\r\n enableIterations,\r\n maxIterations\r\n );\r\n } catch (error) {\r\n console.error('[agent-executor] CFN Protocol execution failed:', error);\r\n // Don't fail the entire agent execution if CFN protocol fails\r\n // This allows agents to complete even if Redis coordination has issues\r\n }\r\n }\r\n\r\n return {\r\n success: result.success,\r\n agentId,\r\n output: result.output,\r\n error: result.error,\r\n exitCode: result.success ? 0 : 1,\r\n };\r\n } catch (error) {\r\n console.error('[agent-executor] API execution failed:', error);\r\n return {\r\n success: false,\r\n agentId,\r\n error: error instanceof Error ? error.message : String(error),\r\n exitCode: 1,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Execute agent using shell script (fallback/simulation)\r\n */\r\nasync function executeViaScript(\r\n definition: AgentDefinition,\r\n prompt: string,\r\n context: TaskContext\r\n): Promise<AgentExecutionResult> {\r\n const agentId = getAgentId(definition, context);\r\n\r\n // BUG #24 FIX: Parse and inject context environment variables\r\n if (context.context) {\r\n console.log(`[agent-executor] Parsing context: ${context.context}`);\r\n const contextEnv = parseContextToEnv(context.context);\r\n console.log(`[agent-executor] Injected env vars: ${Object.keys(contextEnv).join(', ')}`);\r\n }\r\n\r\n // Write prompt to temporary file\r\n const tmpDir = os.tmpdir();\r\n const promptFile = path.join(tmpDir, `agent-${agentId}-${Date.now()}.md`);\r\n await fs.writeFile(promptFile, prompt, 'utf-8');\r\n\r\n console.log(`[agent-executor] Executing agent via script: ${definition.name}`);\r\n console.log(`[agent-executor] Agent ID: ${agentId}`);\r\n console.log(`[agent-executor] Model: ${definition.model}`);\r\n console.log(`[agent-executor] Prompt file: ${promptFile}`);\r\n\r\n return new Promise((resolve) => {\r\n const scriptPath = path.join('.claude', 'skills', 'agent-execution', 'execute-agent.sh');\r\n\r\n // Build environment variables - WHITELIST ONLY APPROACH\r\n // SECURITY FIX: Do not use ...process.env spread which exposes ALL variables including secrets\r\n // Instead, explicitly whitelist safe variables to pass to spawned process\r\n const safeEnvVars = [\r\n 'CFN_REDIS_HOST',\r\n 'CFN_REDIS_PORT',\r\n 'CFN_REDIS_PASSWORD', // CRITICAL: Required for Redis authentication\r\n 'CFN_REDIS_URL',\r\n 'REDIS_PASSWORD', // Fallback for Redis password\r\n 'CFN_MEMORY_BUDGET',\r\n 'CFN_API_HOST',\r\n 'CFN_API_PORT',\r\n 'CFN_LOG_LEVEL',\r\n 'CFN_LOG_FORMAT',\r\n 'CFN_CONTAINER_MODE',\r\n 'CFN_DOCKER_SOCKET',\r\n 'CFN_NETWORK_NAME',\r\n 'CFN_CUSTOM_ROUTING',\r\n 'CFN_DEFAULT_PROVIDER',\r\n 'NODE_ENV',\r\n 'PATH',\r\n 'HOME',\r\n 'PWD' // Required for working directory context\r\n ];\r\n\r\n const env: Record<string, string> = {};\r\n\r\n // Add whitelisted variables\r\n for (const key of safeEnvVars) {\r\n const value = process.env[key];\r\n if (value !== undefined) {\r\n env[key] = value;\r\n }\r\n }\r\n\r\n // Add API key only when explicitly needed (with strict validation)\r\n if (process.env.ANTHROPIC_API_KEY) {\r\n if (process.env.ANTHROPIC_API_KEY.match(/^sk-[a-zA-Z0-9-]+$/)) {\r\n env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;\r\n }\r\n }\r\n\r\n // Add agent execution context (safe values)\r\n env.AGENT_TYPE = definition.name;\r\n env.AGENT_ID = agentId;\r\n env.AGENT_MODEL = definition.model;\r\n env.AGENT_TOOLS = definition.tools.join(',');\r\n env.TASK_ID = context.taskId || '';\r\n env.ITERATION = String(context.iteration || 1);\r\n env.MODE = context.mode || 'cli';\r\n env.PROMPT_FILE = promptFile;\r\n\r\n // Check if execute script exists\r\n fs.access(scriptPath)\r\n .then(() => {\r\n // Use execution script\r\n const proc = spawn('bash', [scriptPath], { env, stdio: 'inherit' });\r\n\r\n proc.on('exit', (code) => {\r\n resolve({\r\n success: code === 0,\r\n agentId,\r\n exitCode: code || 0,\r\n });\r\n });\r\n\r\n proc.on('error', (err) => {\r\n resolve({\r\n success: false,\r\n agentId,\r\n error: err.message,\r\n exitCode: 1,\r\n });\r\n });\r\n })\r\n .catch(() => {\r\n // Fallback: Print prompt\r\n console.log('\\n=== Agent Prompt ===');\r\n console.log(prompt.substring(0, 500) + '...');\r\n console.log('\\n[agent-executor] Execution script not found');\r\n console.log('[agent-executor] Using simulation mode\\n');\r\n\r\n resolve({\r\n success: true,\r\n agentId,\r\n output: prompt,\r\n exitCode: 0,\r\n });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Main agent execution function\r\n */\r\nexport async function executeAgent(\r\n definition: AgentDefinition,\r\n prompt: string,\r\n context: TaskContext,\r\n options: {\r\n method?: 'auto' | 'api' | 'script';\r\n } = {}\r\n): Promise<AgentExecutionResult> {\r\n const method = options.method || 'auto';\r\n\r\n // Auto-select execution method\r\n if (method === 'auto') {\r\n // Try API execution first, fallback to script if API key not available\r\n try {\r\n return await executeViaAPI(definition, prompt, context);\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes('API key not found')) {\r\n console.log('[agent-executor] API key not found, using script fallback');\r\n return executeViaScript(definition, prompt, context);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n if (method === 'api') {\r\n return executeViaAPI(definition, prompt, context);\r\n }\r\n\r\n return executeViaScript(definition, prompt, context);\r\n}\r\n\r\n/**\r\n * Write agent output to file for debugging\r\n */\r\nexport async function saveAgentOutput(\r\n agentId: string,\r\n output: string,\r\n outputDir: string = '.claude/tmp/agent-output'\r\n): Promise<string> {\r\n await fs.mkdir(outputDir, { recursive: true });\r\n\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\r\n const filename = `${agentId}-${timestamp}.txt`;\r\n const filepath = path.join(outputDir, filename);\r\n\r\n await fs.writeFile(filepath, output, 'utf-8');\r\n\r\n return filepath;\r\n}\r\n"],"names":["spawn","exec","promisify","getAgentId","buildCLIAgentSystemPrompt","loadContextFromEnv","loadMessages","storeMessage","getCurrentFork","formatMessagesForAPI","convertToolNames","fs","path","os","execAsync","redisHost","process","env","CFN_REDIS_HOST","redisPort","CFN_REDIS_PORT","redisPassword","CFN_REDIS_PASSWORD","REDIS_PASSWORD","parseContextToEnv","contextString","envVars","regex","match","key","quotedValue","unquotedValue","value","undefined","extractConfidence","output","patterns","pattern","score","parseFloat","executeCFNProtocol","taskId","agentId","iteration","enableIterations","maxIterations","console","log","authFlag","confidence","reportCmd","error","isCustomRoutingEnabled","CLAUDE_API_PROVIDER","configPath","join","config","JSON","parse","readFile","provider","getAPIProvider","customEnabled","executeViaAPI","definition","prompt","context","name","model","contextEnv","Object","keys","forkId","FORK_ID","systemPrompt","messages","forkMessages","length","content","slice","push","role","contextOptions","agentType","executeAgentAPI","tools","result","userMessage","timestamp","Date","toISOString","assistantMessage","success","exitCode","Error","message","String","executeViaScript","tmpDir","tmpdir","promptFile","now","writeFile","Promise","resolve","scriptPath","safeEnvVars","ANTHROPIC_API_KEY","AGENT_TYPE","AGENT_ID","AGENT_MODEL","AGENT_TOOLS","TASK_ID","ITERATION","MODE","mode","PROMPT_FILE","access","then","proc","stdio","on","code","err","catch","substring","executeAgent","options","method","includes","saveAgentOutput","outputDir","mkdir","recursive","replace","filename","filepath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/agent-executor.ts"],"sourcesContent":["/**\r\n * Agent Executor\r\n *\r\n * Executes CLI-spawned agents by:\r\n * 1. Checking custom routing configuration (z.ai vs Anthropic)\r\n * 2. Invoking the appropriate API\r\n * 3. Managing agent lifecycle and output\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { AgentDefinition } from './agent-definition-parser.js';\r\nimport { TaskContext, getAgentId } from './agent-prompt-builder.js';\r\nimport { buildCLIAgentSystemPrompt, loadContextFromEnv } from './cli-agent-context.js';\r\nimport {\r\n loadMessages,\r\n storeMessage,\r\n getCurrentFork,\r\n formatMessagesForAPI,\r\n type Message\r\n} from './conversation-fork.js';\r\nimport { convertToolNames } from './tool-definitions.js';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport os from 'os';\r\nimport { execSync } from 'child_process';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\n/**\r\n * Detect project root dynamically\r\n * Uses PROJECT_ROOT env var if set, otherwise tries git, falls back to cwd\r\n */\r\nfunction getProjectRoot(): string {\r\n // 1. Check environment variable\r\n if (process.env.PROJECT_ROOT) {\r\n return process.env.PROJECT_ROOT;\r\n }\r\n\r\n // 2. Try git rev-parse (most reliable)\r\n try {\r\n const gitRoot = execSync('git rev-parse --show-toplevel', {\r\n encoding: 'utf-8',\r\n cwd: process.cwd(),\r\n stdio: ['pipe', 'pipe', 'ignore']\r\n }).trim();\r\n if (gitRoot) {\r\n return gitRoot;\r\n }\r\n } catch {\r\n // Fall through to next method\r\n }\r\n\r\n // 3. Fall back to current working directory\r\n return process.cwd();\r\n}\r\n\r\nconst projectRoot = getProjectRoot();\r\n\r\n// Bug #6 Fix: Read Redis connection parameters from process.env\r\n// ENV-001: Standardized environment variable naming (REDIS_PASSWORD for all deployments)\r\nconst redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\nconst redisPort = process.env.CFN_REDIS_PORT || '6379';\r\nconst redisPassword = process.env.CFN_REDIS_PASSWORD || process.env.REDIS_PASSWORD || '';\r\n\r\nexport interface AgentExecutionResult {\r\n success: boolean;\r\n agentId: string;\r\n output?: string;\r\n error?: string;\r\n exitCode: number;\r\n}\r\n\r\n/**\r\n * Parse context string into environment variables\r\n *\r\n * Parses context string like \"TASK_ID='xyz' MODE='mvp' MAX_ITERATIONS=5\"\r\n * and sets the values as environment variables.\r\n *\r\n * Supports:\r\n * - Single quoted: KEY='value with spaces'\r\n * - Double quoted: KEY=\"value with spaces\"\r\n * - Unquoted: KEY=value (no spaces in value)\r\n *\r\n * @param contextString - Context string from --context parameter\r\n * @returns Object with parsed key-value pairs\r\n */\r\nfunction parseContextToEnv(contextString: string | undefined): Record<string, string> {\r\n if (!contextString) return {};\r\n\r\n const envVars: Record<string, string> = {};\r\n\r\n // Match KEY='value' or KEY=\"value\" or KEY=value patterns\r\n // For quoted values: capture everything between quotes\r\n // For unquoted values: capture until next space or end of string\r\n const regex = /(\\w+)=(?:(['\"])([^\\2]*?)\\2|([^\\s]+))/g;\r\n let match;\r\n\r\n while ((match = regex.exec(contextString)) !== null) {\r\n const [, key, , quotedValue, unquotedValue] = match;\r\n const value = quotedValue !== undefined ? quotedValue : unquotedValue;\r\n envVars[key] = value;\r\n // Also set in process.env for current process\r\n process.env[key] = value;\r\n }\r\n\r\n return envVars;\r\n}\r\n\r\n/**\r\n * Extract confidence score from agent output\r\n * Looks for patterns like:\r\n * - \"confidence: 0.85\"\r\n * - \"Confidence: 0.90\"\r\n * - \"confidence score: 0.95\"\r\n * - \"self-confidence: 0.88\"\r\n */\r\nfunction extractConfidence(output: string | undefined): number {\r\n if (!output) return 0.85;\r\n\r\n // Try multiple patterns\r\n const patterns = [\r\n /confidence:\\s*([0-9.]+)/i,\r\n /confidence\\s+score:\\s*([0-9.]+)/i,\r\n /self-confidence:\\s*([0-9.]+)/i,\r\n /my\\s+confidence:\\s*([0-9.]+)/i,\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = output.match(pattern);\r\n if (match && match[1]) {\r\n const score = parseFloat(match[1]);\r\n if (score >= 0 && score <= 1) {\r\n return score;\r\n }\r\n }\r\n }\r\n\r\n // Default to 0.85 if not found\r\n return 0.85;\r\n}\r\n\r\n/**\r\n * Execute CFN Loop protocol after agent completes work\r\n *\r\n * Steps:\r\n * 1. Signal completion to orchestrator\r\n * 2. Report confidence score\r\n * 3. Enter waiting mode (if iterations enabled)\r\n */\r\nasync function executeCFNProtocol(\r\n taskId: string,\r\n agentId: string,\r\n output: string | undefined,\r\n iteration: number,\r\n enableIterations: boolean = false,\r\n maxIterations: number = 10\r\n): Promise<void> {\r\n console.log(`\\n[CFN Protocol] Starting for agent ${agentId}`);\r\n console.log(`[CFN Protocol] Task ID: ${taskId}, Iteration: ${iteration}`);\r\n\r\n try {\r\n // Step 1: Signal completion\r\n console.log('[CFN Protocol] Step 1: Signaling completion...');\r\n const authFlag = redisPassword ? `-a \"${redisPassword}\"` : '';\r\n await execAsync(`redis-cli -h \"${redisHost}\" -p \"${redisPort}\" ${authFlag} lpush \"swarm:${taskId}:${agentId}:done\" \"complete\"`);\r\n console.log('[CFN Protocol] ✓ Completion signaled');\r\n\r\n // Step 2: Extract and report confidence\r\n const confidence = extractConfidence(output);\r\n console.log(`[CFN Protocol] Step 2: Reporting confidence (${confidence})...`);\r\n\r\n const reportCmd = `./.claude/skills/cfn-redis-coordination/report-completion.sh \\\r\n --task-id \"${taskId}\" \\\r\n --agent-id \"${agentId}\" \\\r\n --confidence ${confidence} \\\r\n --iteration ${iteration}`;\r\n\r\n await execAsync(reportCmd);\r\n console.log('[CFN Protocol] ✓ Confidence reported');\r\n\r\n // Step 3: Exit cleanly (BUG #18 FIX - removed waiting mode)\r\n // Orchestrator will spawn appropriate specialist agent for next iteration\r\n // This enables adaptive agent specialization based on feedback type\r\n console.log('[CFN Protocol] Step 3: Exiting cleanly (iteration complete)');\r\n console.log('[CFN Protocol] Protocol complete\\n');\r\n } catch (error) {\r\n console.error('[CFN Protocol] Error:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Check if custom routing (z.ai) is enabled\r\n */\r\nasync function isCustomRoutingEnabled(): Promise<boolean> {\r\n // Check environment variable\r\n if (process.env.CLAUDE_API_PROVIDER === 'zai') {\r\n return true;\r\n }\r\n\r\n // Check config file (.claude/config/api-provider.json)\r\n try {\r\n const configPath = path.join(projectRoot, '.claude', 'config', 'api-provider.json');\r\n const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));\r\n return config.provider === 'zai' || config.provider === 'z.ai';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get API provider configuration\r\n */\r\nasync function getAPIProvider(): Promise<'anthropic' | 'zai'> {\r\n const customEnabled = await isCustomRoutingEnabled();\r\n return customEnabled ? 'zai' : 'anthropic';\r\n}\r\n\r\n/**\r\n * Execute agent using direct API calls\r\n */\r\nasync function executeViaAPI(\r\n definition: AgentDefinition,\r\n prompt: string,\r\n context: TaskContext\r\n): Promise<AgentExecutionResult> {\r\n const agentId = getAgentId(definition, context);\r\n\r\n console.log(`[agent-executor] Executing agent via API: ${definition.name}`);\r\n console.log(`[agent-executor] Agent ID: ${agentId}`);\r\n console.log(`[agent-executor] Model: ${definition.model}`);\r\n console.log('');\r\n\r\n // BUG #24 FIX: Parse and inject context environment variables\r\n // This enables CLI-spawned agents to access TASK_ID, MODE, etc. in Bash tool\r\n if (context.context) {\r\n console.log(`[agent-executor] Parsing context: ${context.context}`);\r\n const contextEnv = parseContextToEnv(context.context);\r\n console.log(`[agent-executor] Injected env vars: ${Object.keys(contextEnv).join(', ')}`);\r\n }\r\n\r\n try {\r\n // Check for conversation fork (Sprint 4 enhancement)\r\n const forkId = process.env.FORK_ID || await getCurrentFork(context.taskId || '', agentId);\r\n const iteration = context.iteration || 1;\r\n\r\n let systemPrompt: string;\r\n let messages: Array<{role: string, content: string}> = [];\r\n\r\n if (forkId && iteration > 1) {\r\n // Continue from fork (iterations 2+)\r\n console.log(`[agent-executor] Continuing from fork: ${forkId}`);\r\n\r\n // Load fork messages\r\n const forkMessages = await loadMessages(context.taskId || '', agentId, forkId);\r\n console.log(`[agent-executor] Loaded ${forkMessages.length} messages from fork`);\r\n\r\n // Extract system prompt from first message (it's always the system message)\r\n // The fork messages are assistant/user pairs, we need to add system separately\r\n systemPrompt = forkMessages[0]?.content || '';\r\n\r\n // Format remaining messages for API\r\n messages = formatMessagesForAPI(forkMessages.slice(1));\r\n\r\n // Add new user message with feedback\r\n messages.push({\r\n role: 'user',\r\n content: prompt\r\n });\r\n\r\n console.log(`[agent-executor] Fork continuation: ${messages.length} messages`);\r\n } else {\r\n // New conversation (iteration 1)\r\n console.log('[agent-executor] Starting new conversation');\r\n console.log('[agent-executor] Building system prompt with context...');\r\n\r\n const contextOptions = loadContextFromEnv();\r\n contextOptions.agentType = definition.name;\r\n if (context.taskId) contextOptions.taskId = context.taskId;\r\n if (context.iteration) contextOptions.iteration = context.iteration;\r\n\r\n systemPrompt = await buildCLIAgentSystemPrompt(contextOptions);\r\n console.log('[agent-executor] System prompt built successfully');\r\n\r\n // Initial user message\r\n messages = [{\r\n role: 'user',\r\n content: prompt\r\n }];\r\n }\r\n\r\n console.log('');\r\n\r\n // Dynamic import to avoid bundling issues\r\n const { executeAgentAPI } = await import('./anthropic-client.js');\r\n\r\n // Convert agent tool names to Anthropic API format\r\n const tools = definition.tools && definition.tools.length > 0\r\n ? convertToolNames(definition.tools)\r\n : undefined;\r\n\r\n const result = await executeAgentAPI(\r\n definition.name,\r\n agentId,\r\n definition.model,\r\n prompt,\r\n systemPrompt,\r\n messages.length > 1 ? messages : undefined,\r\n undefined, // maxTokens (use default)\r\n tools // Pass converted tools\r\n );\r\n\r\n // Store messages in conversation history (for future forking)\r\n if (context.taskId) {\r\n // Store user message\r\n const userMessage: Message = {\r\n role: 'user',\r\n content: prompt,\r\n iteration,\r\n timestamp: new Date().toISOString()\r\n };\r\n await storeMessage(context.taskId, agentId, userMessage);\r\n\r\n // Store assistant response\r\n if (result.output) {\r\n const assistantMessage: Message = {\r\n role: 'assistant',\r\n content: result.output,\r\n iteration,\r\n timestamp: new Date().toISOString()\r\n };\r\n await storeMessage(context.taskId, agentId, assistantMessage);\r\n }\r\n\r\n console.log(`[agent-executor] Stored messages for iteration ${iteration}`);\r\n\r\n // Execute CFN Loop protocol (signal completion, report confidence, enter waiting mode)\r\n // Iterations are enabled for CFN Loop tasks (indicated by presence of taskId)\r\n try {\r\n const maxIterations = 10; // Default max iterations\r\n const enableIterations = true; // Enable iterations for all CFN Loop tasks\r\n\r\n await executeCFNProtocol(\r\n context.taskId,\r\n agentId,\r\n result.output,\r\n iteration,\r\n enableIterations,\r\n maxIterations\r\n );\r\n } catch (error) {\r\n console.error('[agent-executor] CFN Protocol execution failed:', error);\r\n // Don't fail the entire agent execution if CFN protocol fails\r\n // This allows agents to complete even if Redis coordination has issues\r\n }\r\n }\r\n\r\n return {\r\n success: result.success,\r\n agentId,\r\n output: result.output,\r\n error: result.error,\r\n exitCode: result.success ? 0 : 1,\r\n };\r\n } catch (error) {\r\n console.error('[agent-executor] API execution failed:', error);\r\n return {\r\n success: false,\r\n agentId,\r\n error: error instanceof Error ? error.message : String(error),\r\n exitCode: 1,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Execute agent using shell script (fallback/simulation)\r\n */\r\nasync function executeViaScript(\r\n definition: AgentDefinition,\r\n prompt: string,\r\n context: TaskContext\r\n): Promise<AgentExecutionResult> {\r\n const agentId = getAgentId(definition, context);\r\n\r\n // BUG #24 FIX: Parse and inject context environment variables\r\n if (context.context) {\r\n console.log(`[agent-executor] Parsing context: ${context.context}`);\r\n const contextEnv = parseContextToEnv(context.context);\r\n console.log(`[agent-executor] Injected env vars: ${Object.keys(contextEnv).join(', ')}`);\r\n }\r\n\r\n // Write prompt to temporary file\r\n const tmpDir = os.tmpdir();\r\n const promptFile = path.join(tmpDir, `agent-${agentId}-${Date.now()}.md`);\r\n await fs.writeFile(promptFile, prompt, 'utf-8');\r\n\r\n console.log(`[agent-executor] Executing agent via script: ${definition.name}`);\r\n console.log(`[agent-executor] Agent ID: ${agentId}`);\r\n console.log(`[agent-executor] Model: ${definition.model}`);\r\n console.log(`[agent-executor] Prompt file: ${promptFile}`);\r\n\r\n return new Promise((resolve) => {\r\n const scriptPath = path.join(projectRoot, '.claude', 'skills', 'agent-execution', 'execute-agent.sh');\r\n\r\n // Build environment variables - WHITELIST ONLY APPROACH\r\n // SECURITY FIX: Do not use ...process.env spread which exposes ALL variables including secrets\r\n // Instead, explicitly whitelist safe variables to pass to spawned process\r\n const safeEnvVars = [\r\n 'CFN_REDIS_HOST',\r\n 'CFN_REDIS_PORT',\r\n 'CFN_REDIS_PASSWORD', // CRITICAL: Required for Redis authentication\r\n 'CFN_REDIS_URL',\r\n 'REDIS_PASSWORD', // Fallback for Redis password\r\n 'CFN_MEMORY_BUDGET',\r\n 'CFN_API_HOST',\r\n 'CFN_API_PORT',\r\n 'CFN_LOG_LEVEL',\r\n 'CFN_LOG_FORMAT',\r\n 'CFN_CONTAINER_MODE',\r\n 'CFN_DOCKER_SOCKET',\r\n 'CFN_NETWORK_NAME',\r\n 'CFN_CUSTOM_ROUTING',\r\n 'CFN_DEFAULT_PROVIDER',\r\n 'NODE_ENV',\r\n 'PATH',\r\n 'HOME',\r\n 'PWD' // Required for working directory context\r\n ];\r\n\r\n const env: Record<string, string> = {};\r\n\r\n // Add whitelisted variables\r\n for (const key of safeEnvVars) {\r\n const value = process.env[key];\r\n if (value !== undefined) {\r\n env[key] = value;\r\n }\r\n }\r\n\r\n // Add API key only when explicitly needed (with strict validation)\r\n if (process.env.ANTHROPIC_API_KEY) {\r\n if (process.env.ANTHROPIC_API_KEY.match(/^sk-[a-zA-Z0-9-]+$/)) {\r\n env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;\r\n }\r\n }\r\n\r\n // Add agent execution context (safe values)\r\n env.AGENT_TYPE = definition.name;\r\n env.AGENT_ID = agentId;\r\n env.AGENT_MODEL = definition.model;\r\n env.AGENT_TOOLS = definition.tools.join(',');\r\n env.TASK_ID = context.taskId || '';\r\n env.ITERATION = String(context.iteration || 1);\r\n env.MODE = context.mode || 'cli';\r\n env.PROMPT_FILE = promptFile;\r\n\r\n // Check if execute script exists\r\n fs.access(scriptPath)\r\n .then(() => {\r\n // Use execution script\r\n const proc = spawn('bash', [scriptPath], { env, stdio: 'inherit' });\r\n\r\n proc.on('exit', (code) => {\r\n resolve({\r\n success: code === 0,\r\n agentId,\r\n exitCode: code || 0,\r\n });\r\n });\r\n\r\n proc.on('error', (err) => {\r\n resolve({\r\n success: false,\r\n agentId,\r\n error: err.message,\r\n exitCode: 1,\r\n });\r\n });\r\n })\r\n .catch(() => {\r\n // Fallback: Print prompt\r\n console.log('\\n=== Agent Prompt ===');\r\n console.log(prompt.substring(0, 500) + '...');\r\n console.log('\\n[agent-executor] Execution script not found');\r\n console.log('[agent-executor] Using simulation mode\\n');\r\n\r\n resolve({\r\n success: true,\r\n agentId,\r\n output: prompt,\r\n exitCode: 0,\r\n });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Main agent execution function\r\n */\r\nexport async function executeAgent(\r\n definition: AgentDefinition,\r\n prompt: string,\r\n context: TaskContext,\r\n options: {\r\n method?: 'auto' | 'api' | 'script';\r\n } = {}\r\n): Promise<AgentExecutionResult> {\r\n const method = options.method || 'auto';\r\n\r\n // Auto-select execution method\r\n if (method === 'auto') {\r\n // Try API execution first, fallback to script if API key not available\r\n try {\r\n return await executeViaAPI(definition, prompt, context);\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes('API key not found')) {\r\n console.log('[agent-executor] API key not found, using script fallback');\r\n return executeViaScript(definition, prompt, context);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n if (method === 'api') {\r\n return executeViaAPI(definition, prompt, context);\r\n }\r\n\r\n return executeViaScript(definition, prompt, context);\r\n}\r\n\r\n/**\r\n * Write agent output to file for debugging\r\n */\r\nexport async function saveAgentOutput(\r\n agentId: string,\r\n output: string,\r\n outputDir: string = '.claude/tmp/agent-output'\r\n): Promise<string> {\r\n await fs.mkdir(outputDir, { recursive: true });\r\n\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\r\n const filename = `${agentId}-${timestamp}.txt`;\r\n const filepath = path.join(outputDir, filename);\r\n\r\n await fs.writeFile(filepath, output, 'utf-8');\r\n\r\n return filepath;\r\n}\r\n"],"names":["spawn","exec","promisify","getAgentId","buildCLIAgentSystemPrompt","loadContextFromEnv","loadMessages","storeMessage","getCurrentFork","formatMessagesForAPI","convertToolNames","fs","path","os","execSync","execAsync","getProjectRoot","process","env","PROJECT_ROOT","gitRoot","encoding","cwd","stdio","trim","projectRoot","redisHost","CFN_REDIS_HOST","redisPort","CFN_REDIS_PORT","redisPassword","CFN_REDIS_PASSWORD","REDIS_PASSWORD","parseContextToEnv","contextString","envVars","regex","match","key","quotedValue","unquotedValue","value","undefined","extractConfidence","output","patterns","pattern","score","parseFloat","executeCFNProtocol","taskId","agentId","iteration","enableIterations","maxIterations","console","log","authFlag","confidence","reportCmd","error","isCustomRoutingEnabled","CLAUDE_API_PROVIDER","configPath","join","config","JSON","parse","readFile","provider","getAPIProvider","customEnabled","executeViaAPI","definition","prompt","context","name","model","contextEnv","Object","keys","forkId","FORK_ID","systemPrompt","messages","forkMessages","length","content","slice","push","role","contextOptions","agentType","executeAgentAPI","tools","result","userMessage","timestamp","Date","toISOString","assistantMessage","success","exitCode","Error","message","String","executeViaScript","tmpDir","tmpdir","promptFile","now","writeFile","Promise","resolve","scriptPath","safeEnvVars","ANTHROPIC_API_KEY","AGENT_TYPE","AGENT_ID","AGENT_MODEL","AGENT_TOOLS","TASK_ID","ITERATION","MODE","mode","PROMPT_FILE","access","then","proc","on","code","err","catch","substring","executeAgent","options","method","includes","saveAgentOutput","outputDir","mkdir","recursive","replace","filename","filepath"],"mappings":"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"}
|