UNPKG

@stackmemoryai/stackmemory

Version:

Project-scoped memory for AI coding tools. Durable context across sessions with MCP integration, frames, smart retrieval, Claude Code skills, and automatic hooks.

769 lines (741 loc) 24.7 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { v4 as uuidv4 } from "uuid"; import { logger } from "../../core/monitoring/logger.js"; import { OracleWorkerCoordinator } from "../ralph/patterns/oracle-worker-pattern.js"; import { ClaudeCodeTaskCoordinator } from "./task-coordinator.js"; const CLAUDE_CODE_AGENTS = { // Oracle-level agents (strategic, high-level) "staff-architect": { name: "staff-architect", type: "oracle", description: "Strategic technical leadership, architectural guidance, and engineering direction", capabilities: [ "system_design", "architectural_planning", "technical_strategy", "scalability_analysis", "technology_selection", "team_organization" ], costMultiplier: 1, // Oracle pricing complexity: "very_high", specializations: ["architecture", "strategy", "leadership"] }, "product-manager": { name: "product-manager", type: "oracle", description: "Strategic planning, roadmap development, and market analysis", capabilities: [ "product_strategy", "roadmap_planning", "market_analysis", "feature_prioritization", "stakeholder_alignment", "business_requirements" ], costMultiplier: 1, complexity: "high", specializations: ["strategy", "planning", "business"] }, // Worker-level agents (execution, focused tasks) "general-purpose": { name: "general-purpose", type: "worker", description: "General-purpose agent for researching, coding, and multi-step tasks", capabilities: [ "code_implementation", "research", "debugging", "file_operations", "testing", "documentation" ], costMultiplier: 0.2, // Worker pricing complexity: "medium", specializations: ["development", "research", "general"] }, "code-reviewer": { name: "code-reviewer", type: "reviewer", description: "Reviews code against standards, checks for issues and best practices", capabilities: [ "code_review", "quality_assessment", "security_analysis", "performance_review", "best_practices_enforcement", "typescript_validation" ], costMultiplier: 0.3, // Slightly more expensive worker complexity: "medium", specializations: ["quality", "security", "standards"] }, debugger: { name: "debugger", type: "worker", description: "Specialized debugging for errors, test failures, and unexpected behavior", capabilities: [ "error_analysis", "debugging", "log_analysis", "performance_debugging", "test_failure_analysis", "root_cause_analysis" ], costMultiplier: 0.25, complexity: "medium", specializations: ["debugging", "analysis", "troubleshooting"] }, "qa-workflow-validator": { name: "qa-workflow-validator", type: "worker", description: "Comprehensive QA testing, workflow validation, and UI testing", capabilities: [ "workflow_validation", "test_execution", "ui_testing", "integration_testing", "log_analysis", "quality_assurance" ], costMultiplier: 0.3, complexity: "medium", specializations: ["testing", "validation", "quality"] }, "merge-coordinator": { name: "merge-coordinator", type: "worker", description: "Coordinates merge requests and handles code integration", capabilities: [ "merge_coordination", "conflict_resolution", "code_integration", "branch_management", "review_coordination", "git_workflow" ], costMultiplier: 0.2, complexity: "low", specializations: ["git", "coordination", "integration"] }, "github-workflow": { name: "github-workflow", type: "worker", description: "Git workflow management for commits, branches, and PRs", capabilities: [ "git_operations", "branch_management", "commit_management", "pr_creation", "workflow_automation", "repository_management" ], costMultiplier: 0.15, complexity: "low", specializations: ["git", "automation", "workflow"] } }; class ClaudeCodeAgentBridge extends OracleWorkerCoordinator { claudeAgents = /* @__PURE__ */ new Map(); activeAgentSessions = /* @__PURE__ */ new Map(); taskCoordinator; constructor() { const oracleConfigs = ClaudeCodeAgentBridge.createOracleConfigs(); const workerConfigs = ClaudeCodeAgentBridge.createWorkerConfigs(); const reviewerConfigs = ClaudeCodeAgentBridge.createReviewerConfigs(); super({ oracle: oracleConfigs[0], workers: workerConfigs, reviewers: reviewerConfigs, maxWorkers: 8, // Allow more workers for Claude Code agents coordinationInterval: 3e4, costBudget: 15 // Higher budget for Claude Code integration }); this.taskCoordinator = new ClaudeCodeTaskCoordinator(); this.loadClaudeCodeAgents(); logger.info("Claude Code Agent Bridge initialized", { oracleAgents: oracleConfigs.length, workerAgents: workerConfigs.length, reviewerAgents: reviewerConfigs.length }); } /** * Launch Oracle/Worker swarm using Claude Code agents */ async launchClaudeCodeSwarm(projectDescription, options = {}) { const { oracleAgent = "staff-architect", workerAgents = ["general-purpose", "code-reviewer"], reviewerAgents = ["code-reviewer"], budget = 10, complexity = "medium" } = options; logger.info("Launching Claude Code swarm", { project: projectDescription.substring(0, 100), oracleAgent, workerAgents, budget }); this.validateAgentSelection(oracleAgent, workerAgents, reviewerAgents); const swarmId = uuidv4(); try { const oracleTaskId = await this.createClaudeOracleTask( oracleAgent, projectDescription, complexity ); const decomposition = await this.executeClaudeOracleTask( oracleTaskId, oracleAgent ); const workerTasks = await this.allocateTasksToClaudeWorkers( decomposition, workerAgents ); const workerPromises = workerTasks.map( (task) => this.executeClaudeWorkerTask(task) ); const reviewPromises = reviewerAgents.map( (reviewer) => this.executeClaudeReviewTask(reviewer, decomposition, workerTasks) ); const [workerResults, reviewResults] = await Promise.all([ Promise.allSettled(workerPromises), Promise.allSettled(reviewPromises) ]); await this.integrateClaudeResults(swarmId, workerResults, reviewResults); this.logClaudeCodeCostAnalysis(); return swarmId; } catch (error) { logger.error("Claude Code swarm failed", error); throw error; } } /** * Load Claude Code agents into the bridge */ loadClaudeCodeAgents() { for (const [agentName, agentConfig] of Object.entries(CLAUDE_CODE_AGENTS)) { this.claudeAgents.set(agentName, agentConfig); } logger.info("Claude Code agents loaded", { totalAgents: this.claudeAgents.size, oracles: Array.from(this.claudeAgents.values()).filter( (a) => a.type === "oracle" ).length, workers: Array.from(this.claudeAgents.values()).filter( (a) => a.type === "worker" ).length, reviewers: Array.from(this.claudeAgents.values()).filter( (a) => a.type === "reviewer" ).length }); } /** * Create Oracle model configurations from Claude Code agents */ static createOracleConfigs() { return Object.values(CLAUDE_CODE_AGENTS).filter((agent) => agent.type === "oracle").map((agent) => ({ tier: "oracle", provider: "claude", model: `claude-code-${agent.name}`, costPerToken: 0.015 * agent.costMultiplier, // Base Oracle cost with multiplier capabilities: agent.capabilities })); } /** * Create Worker model configurations from Claude Code agents */ static createWorkerConfigs() { return Object.values(CLAUDE_CODE_AGENTS).filter((agent) => agent.type === "worker").map((agent) => ({ tier: "worker", provider: "claude", model: `claude-code-${agent.name}`, costPerToken: 25e-5 * agent.costMultiplier, // Base worker cost with multiplier capabilities: agent.capabilities })); } /** * Create Reviewer model configurations from Claude Code agents */ static createReviewerConfigs() { return Object.values(CLAUDE_CODE_AGENTS).filter((agent) => agent.type === "reviewer").map((agent) => ({ tier: "reviewer", provider: "claude", model: `claude-code-${agent.name}`, costPerToken: 3e-3 * agent.costMultiplier, // Base reviewer cost with multiplier capabilities: agent.capabilities })); } /** * Validate that selected agents exist and are appropriate */ validateAgentSelection(oracleAgent, workerAgents, reviewerAgents) { const oracle = this.claudeAgents.get(oracleAgent); if (!oracle) { throw new Error(`Oracle agent '${oracleAgent}' not found`); } if (oracle.type !== "oracle") { throw new Error(`Agent '${oracleAgent}' is not an Oracle-level agent`); } for (const workerAgent of workerAgents) { const worker = this.claudeAgents.get(workerAgent); if (!worker) { throw new Error(`Worker agent '${workerAgent}' not found`); } if (worker.type !== "worker") { throw new Error(`Agent '${workerAgent}' is not a Worker-level agent`); } } for (const reviewerAgent of reviewerAgents) { const reviewer = this.claudeAgents.get(reviewerAgent); if (!reviewer) { throw new Error(`Reviewer agent '${reviewerAgent}' not found`); } if (reviewer.type !== "reviewer") { throw new Error( `Agent '${reviewerAgent}' is not a Reviewer-level agent` ); } } } /** * Create Oracle task with Claude Code agent capabilities */ async createClaudeOracleTask(agentName, projectDescription, complexity) { const taskId = uuidv4(); const agent = this.claudeAgents.get(agentName); logger.info("Creating Claude Oracle task", { taskId, agent: agentName, complexity }); this.activeAgentSessions.set(taskId, { agentName, agentType: "oracle", projectDescription, complexity, capabilities: agent.capabilities }); return taskId; } /** * Execute Oracle task using Claude Code agent */ async executeClaudeOracleTask(taskId, agentName) { const session = this.activeAgentSessions.get(taskId); if (!session) { throw new Error(`Oracle task session ${taskId} not found`); } logger.info("Executing Claude Oracle task", { taskId, agent: agentName }); const oraclePrompt = this.buildClaudeOraclePrompt(session); const result = await this.invokeClaudeCodeAgent(agentName, oraclePrompt, { type: "oracle", maxTokens: 4e3, temperature: 0.7 }); const decomposition = this.parseClaudeTaskDecomposition(result); return decomposition; } /** * Build Oracle prompt optimized for Claude Code capabilities */ buildClaudeOraclePrompt(session) { const agent = this.claudeAgents.get(session.agentName); return ` # CLAUDE CODE ORACLE: ${agent.name.toUpperCase()} ## Your Role & Capabilities You are a **${agent.description}** acting as the Oracle in an Oracle/Worker pattern. **Your Specialized Capabilities:** ${agent.capabilities.map((cap) => `- ${cap.replace(/_/g, " ")}`).join("\n")} **Your Specializations:** ${agent.specializations.map((spec) => `- ${spec}`).join("\n")} ## Project Context ${session.projectDescription} **Complexity Level:** ${session.complexity} ## Oracle Responsibilities As the Oracle, you provide strategic oversight while specialized Claude Code workers handle execution: 1. **Strategic Decomposition**: Break down the project into tasks optimized for Claude Code agents 2. **Agent Selection**: Recommend which Claude Code agents should handle each task 3. **Quality Standards**: Define acceptance criteria that leverage Claude Code capabilities 4. **Coordination Plan**: Plan how agents should collaborate and integrate work ## Available Claude Code Workers ${this.getAvailableWorkersDescription()} ## Output Required Provide a detailed strategic plan in JSON format: \`\`\`json { "project_analysis": { "complexity_assessment": "low|medium|high|very_high", "key_challenges": ["challenge 1", "challenge 2"], "success_criteria": ["criterion 1", "criterion 2"] }, "task_decomposition": [ { "id": "task-1", "title": "Task name", "description": "Detailed description", "recommended_agent": "agent-name", "agent_rationale": "Why this agent is optimal", "complexity": "low|medium|high", "estimated_effort": "1-5 scale", "dependencies": ["task-id"], "acceptance_criteria": ["criterion 1", "criterion 2"], "claude_code_integration": { "tools_needed": ["tool1", "tool2"], "validation_method": "how to verify completion" } } ], "coordination_strategy": { "integration_points": ["when agents should sync"], "quality_gates": ["checkpoints for review"], "risk_mitigation": ["potential issues and solutions"], "success_metrics": ["how to measure overall success"] } } \`\`\` Focus on strategic thinking that maximizes Claude Code's specialized capabilities. `; } /** * Get description of available Claude Code workers */ getAvailableWorkersDescription() { const workers = Array.from(this.claudeAgents.values()).filter( (agent) => agent.type === "worker" || agent.type === "reviewer" ); return workers.map( (worker) => `**${worker.name}**: ${worker.description} Capabilities: ${worker.capabilities.join(", ")}` ).join("\n\n"); } /** * Allocate tasks to Claude Code worker agents */ async allocateTasksToClaudeWorkers(decomposition, workerAgents) { const allocatedTasks = []; for (const task of decomposition.task_decomposition || []) { const recommendedAgent = task.recommended_agent; const selectedAgent = workerAgents.includes(recommendedAgent) ? recommendedAgent : this.selectOptimalClaudeWorker(task, workerAgents); const claudeAgent = this.claudeAgents.get(selectedAgent); allocatedTasks.push({ ...task, assignedAgent: selectedAgent, agentCapabilities: claudeAgent.capabilities, agentType: claudeAgent.type }); logger.debug("Task allocated to Claude Code agent", { taskId: task.id, agent: selectedAgent, rationale: task.agent_rationale || "Auto-selected based on capabilities" }); } return allocatedTasks; } /** * Select optimal Claude Code worker for a task */ selectOptimalClaudeWorker(task, availableWorkers) { let bestAgent = availableWorkers[0]; let bestScore = 0; for (const workerName of availableWorkers) { const worker = this.claudeAgents.get(workerName); let score = 0; const taskKeywords = (task.description || "").toLowerCase().split(" "); for (const capability of worker.capabilities) { const capabilityKeywords = capability.replace(/_/g, " ").toLowerCase(); if (taskKeywords.some((keyword) => capabilityKeywords.includes(keyword))) { score += 2; } } for (const specialization of worker.specializations) { if (taskKeywords.some((keyword) => keyword.includes(specialization))) { score += 3; } } score -= worker.costMultiplier; if (score > bestScore) { bestScore = score; bestAgent = workerName; } } return bestAgent; } /** * Execute worker task using Claude Code agent */ async executeClaudeWorkerTask(task) { const agentName = task.assignedAgent; const agent = this.claudeAgents.get(agentName); logger.info("Executing Claude Code worker task", { taskId: task.id, agent: agentName }); const workerPrompt = this.buildClaudeWorkerPrompt(task, agent); const result = await this.invokeClaudeCodeAgent(agentName, workerPrompt, { type: "worker", maxTokens: 2e3, temperature: 0.3 }); return { taskId: task.id, agentName, result, success: true }; } /** * Execute review task using Claude Code reviewer */ async executeClaudeReviewTask(reviewerName, decomposition, workerTasks) { const agent = this.claudeAgents.get(reviewerName); logger.info("Executing Claude Code review task", { reviewer: reviewerName, tasksToReview: workerTasks.length }); const reviewPrompt = this.buildClaudeReviewPrompt( agent, decomposition, workerTasks ); const result = await this.invokeClaudeCodeAgent( reviewerName, reviewPrompt, { type: "reviewer", maxTokens: 3e3, temperature: 0.2 } ); return { reviewerId: reviewerName, result, success: true }; } /** * Build worker prompt for Claude Code agent */ buildClaudeWorkerPrompt(task, agent) { return ` # CLAUDE CODE WORKER: ${agent.name.toUpperCase()} ## Your Specialized Role You are a **${agent.description}** executing a focused task as part of a larger project. **Your Capabilities:** ${agent.capabilities.map((cap) => `- ${cap.replace(/_/g, " ")}`).join("\n")} ## Your Task **${task.title}** ${task.description} ## Success Criteria ${(task.acceptance_criteria || []).map((c) => `- ${c}`).join("\n")} ## Integration Requirements ${task.claude_code_integration ? ` **Tools Needed:** ${task.claude_code_integration.tools_needed?.join(", ") || "Standard tools"} **Validation Method:** ${task.claude_code_integration.validation_method || "Standard validation"} ` : ""} ## Worker Guidelines - **Focus** on this specific task only - **Execute** using your specialized capabilities - **Communicate** progress clearly - **Deliver** according to the acceptance criteria - **Coordinate** with other agents through shared context Execute your specialized task now, leveraging your Claude Code capabilities. `; } /** * Build review prompt for Claude Code reviewer */ buildClaudeReviewPrompt(agent, decomposition, workerTasks) { return ` # CLAUDE CODE REVIEWER: ${agent.name.toUpperCase()} ## Your Review Role You are a **${agent.description}** conducting comprehensive review of completed work. **Your Review Capabilities:** ${agent.capabilities.map((cap) => `- ${cap.replace(/_/g, " ")}`).join("\n")} ## Project Context ${JSON.stringify(decomposition.project_analysis || {}, null, 2)} ## Completed Tasks to Review ${workerTasks.map( (task, i) => ` ### Task ${i + 1}: ${task.title} - **Agent:** ${task.agentName} - **Status:** ${task.success ? "Completed" : "Failed"} - **Acceptance Criteria:** ${(task.acceptance_criteria || []).join(", ")} ` ).join("\n")} ## Review Requirements 1. **Quality Assessment**: Evaluate if each task meets its acceptance criteria 2. **Integration Check**: Verify tasks work together cohesively 3. **Standards Compliance**: Ensure code/work follows best practices 4. **Risk Analysis**: Identify potential issues or improvements needed 5. **Final Recommendation**: Approve, request changes, or flag for re-work ## Output Format Provide structured review in JSON: \`\`\`json { "overall_assessment": "pass|conditional_pass|fail", "task_reviews": [ { "task_id": "task-id", "status": "approved|changes_requested|rejected", "issues": ["issue 1", "issue 2"], "recommendations": ["recommendation 1"] } ], "integration_review": { "cohesion_score": "1-10", "integration_issues": ["issue 1"], "recommended_improvements": ["improvement 1"] }, "final_recommendation": "deploy|fix_and_redeploy|major_rework_needed" } \`\`\` Conduct thorough review using your specialized Claude Code capabilities. `; } /** * Invoke Claude Code agent (integration point) */ async invokeClaudeCodeAgent(agentName, prompt, options) { const agent = this.claudeAgents.get(agentName); return await this.taskCoordinator.executeTask(agentName, agent, prompt, { maxRetries: options.type === "oracle" ? 1 : 2, // Oracle tasks are more expensive, fewer retries timeout: options.type === "oracle" ? 6e5 : 3e5, // Oracle gets more time priority: options.type === "oracle" ? "high" : "medium" }); } /** * Generate mock response (to be replaced with real Claude Code integration) */ generateMockResponse(agentName, type) { const agent = this.claudeAgents.get(agentName); if (type === "oracle") { return JSON.stringify( { project_analysis: { complexity_assessment: "medium", key_challenges: [ "Integration complexity", "Performance requirements" ], success_criteria: ["All tests pass", "Performance benchmarks met"] }, task_decomposition: [ { id: "task-1", title: "Core Implementation", description: "Implement main functionality", recommended_agent: "general-purpose", agent_rationale: "Best suited for general development tasks", complexity: "medium", estimated_effort: "3", dependencies: [], acceptance_criteria: ["Feature works correctly", "Tests pass"], claude_code_integration: { tools_needed: ["Write", "Edit", "Bash"], validation_method: "Run tests and verify functionality" } } ], coordination_strategy: { integration_points: ["After core implementation"], quality_gates: ["Code review", "Testing"], risk_mitigation: ["Regular checkpoints", "Incremental delivery"] } }, null, 2 ); } return `Claude Code agent ${agentName} completed ${type} task successfully using capabilities: ${agent.capabilities.join(", ")}`; } /** * Parse task decomposition from Claude Code response */ parseClaudeTaskDecomposition(response) { try { return JSON.parse(response); } catch { return { task_decomposition: [ { id: "task-1", title: "Implementation Task", description: response.substring(0, 200), complexity: "medium", acceptance_criteria: ["Task completed successfully"] } ] }; } } /** * Integrate results from Claude Code agents */ async integrateClaudeResults(swarmId, workerResults, reviewResults) { const successfulWorkers = workerResults.filter( (r) => r.status === "fulfilled" ).length; const successfulReviews = reviewResults.filter( (r) => r.status === "fulfilled" ).length; logger.info("Claude Code swarm integration completed", { swarmId, totalWorkerTasks: workerResults.length, successfulWorkers, totalReviews: reviewResults.length, successfulReviews, successRate: (successfulWorkers / workerResults.length * 100).toFixed( 1 ) }); } /** * Log cost analysis for Claude Code agents */ logClaudeCodeCostAnalysis() { const totalSessions = this.activeAgentSessions.size; logger.info("Claude Code Agent Cost Analysis", { totalSessions, estimatedSavings: "60-80% vs all-Oracle approach", agentEfficiency: "Specialized agents for optimal task matching", qualityMaintenance: "High-quality output through specialized capabilities" }); } /** * Get available Claude Code agents by type */ getAvailableAgents() { const agents = Array.from(this.claudeAgents.values()); return { oracles: agents.filter((a) => a.type === "oracle").map((a) => a.name), workers: agents.filter((a) => a.type === "worker").map((a) => a.name), reviewers: agents.filter((a) => a.type === "reviewer").map((a) => a.name) }; } } var agent_bridge_default = ClaudeCodeAgentBridge; export { CLAUDE_CODE_AGENTS, ClaudeCodeAgentBridge, agent_bridge_default as default }; //# sourceMappingURL=agent-bridge.js.map