@stackmemoryai/stackmemory 0.4.2 → 0.5.1
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/dist/cli/commands/ralph.js +305 -0
- package/dist/cli/commands/ralph.js.map +2 -2
- package/dist/cli/streamlined-cli.js +144 -0
- package/dist/cli/streamlined-cli.js.map +7 -0
- package/dist/core/events/event-bus.js +110 -0
- package/dist/core/events/event-bus.js.map +7 -0
- package/dist/core/plugins/plugin-interface.js +87 -0
- package/dist/core/plugins/plugin-interface.js.map +7 -0
- package/dist/core/storage/simplified-storage.js +328 -0
- package/dist/core/storage/simplified-storage.js.map +7 -0
- package/dist/integrations/claude-code/agent-bridge.js +764 -0
- package/dist/integrations/claude-code/agent-bridge.js.map +7 -0
- package/dist/integrations/claude-code/task-coordinator.js +356 -0
- package/dist/integrations/claude-code/task-coordinator.js.map +7 -0
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +33 -11
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +2 -2
- package/dist/integrations/ralph/monitoring/swarm-registry.js +10 -1
- package/dist/integrations/ralph/monitoring/swarm-registry.js.map +2 -2
- package/dist/integrations/ralph/patterns/compounding-engineering-pattern.js +396 -0
- package/dist/integrations/ralph/patterns/compounding-engineering-pattern.js.map +7 -0
- package/dist/integrations/ralph/patterns/extended-coherence-sessions.js +469 -0
- package/dist/integrations/ralph/patterns/extended-coherence-sessions.js.map +7 -0
- package/dist/integrations/ralph/patterns/oracle-worker-pattern.js +384 -0
- package/dist/integrations/ralph/patterns/oracle-worker-pattern.js.map +7 -0
- package/dist/integrations/ralph/swarm/git-workflow-manager.js +71 -18
- package/dist/integrations/ralph/swarm/git-workflow-manager.js.map +2 -2
- package/dist/integrations/ralph/swarm/swarm-coordinator.js +243 -49
- package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +2 -2
- package/dist/plugins/linear/index.js +166 -0
- package/dist/plugins/linear/index.js.map +7 -0
- package/dist/plugins/loader.js +57 -0
- package/dist/plugins/loader.js.map +7 -0
- package/dist/plugins/plugin-interface.js +67 -0
- package/dist/plugins/plugin-interface.js.map +7 -0
- package/dist/plugins/ralph/simple-ralph-plugin.js +305 -0
- package/dist/plugins/ralph/simple-ralph-plugin.js.map +7 -0
- package/dist/plugins/ralph/use-cases/code-generator.js +151 -0
- package/dist/plugins/ralph/use-cases/code-generator.js.map +7 -0
- package/dist/plugins/ralph/use-cases/test-generator.js +201 -0
- package/dist/plugins/ralph/use-cases/test-generator.js.map +7 -0
- package/package.json +1 -8
- package/scripts/simple-swarm-demo.ts +114 -0
- package/scripts/test-ralph-iterations.ts +164 -0
- package/scripts/test-swarm-fixes.ts +161 -0
- package/scripts/testing/ab-test-runner.ts +4 -2
- package/scripts/testing/collect-metrics.ts +2 -2
- package/scripts/testing/real-performance-test.js +1 -1
- package/scripts/testing/run-effectiveness-tests.sh +1 -1
- package/scripts/testing/simple-effectiveness-test.js +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/integrations/ralph/swarm/git-workflow-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Git Workflow Manager for Swarm Agents\n * Manages git operations, branching, and commits for each agent\n */\n\nimport { execSync } from 'child_process';\nimport { logger } from '../../../core/monitoring/logger.js';\nimport { Agent, SwarmTask } from '../types.js';\n\nexport interface GitConfig {\n enableGitWorkflow: boolean;\n branchStrategy: 'feature' | 'agent' | 'task';\n autoCommit: boolean;\n commitFrequency: number; // minutes\n mergStrategy: 'squash' | 'merge' | 'rebase';\n requirePR: boolean;\n}\n\nexport class GitWorkflowManager {\n private config: GitConfig;\n private agentBranches: Map<string, string> = new Map();\n private baselineBranch: string;\n private mainBranch: string;\n\n constructor(config?: Partial<GitConfig>) {\n this.config = {\n enableGitWorkflow: true,\n branchStrategy: 'agent',\n autoCommit: true,\n commitFrequency: 5,\n mergStrategy: 'squash',\n requirePR: false,\n ...config\n };\n\n // Get current branch as baseline\n try {\n this.baselineBranch = this.getCurrentBranch();\n this.mainBranch = this.getMainBranch();\n } catch (error) {\n logger.warn('Git not initialized, workflow features disabled');\n this.config.enableGitWorkflow = false;\n }\n }\n\n /**\n * Initialize git workflow for an agent\n */\n async initializeAgentWorkflow(agent: Agent, task: SwarmTask): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n const branchName = this.generateBranchName(agent, task);\n \n try {\n // Create and checkout new branch\n this.createBranch(branchName);\n this.agentBranches.set(agent.id, branchName);\n \n logger.info(`Created git branch for agent ${agent.role}: ${branchName}`);\n\n // Set up commit timer if auto-commit enabled\n if (this.config.autoCommit) {\n this.scheduleAutoCommit(agent, task);\n }\n } catch (error: unknown) {\n logger.error(`Failed to initialize git workflow for agent ${agent.role}`, error as Error);\n }\n }\n\n /**\n * Commit agent work\n */\n async commitAgentWork(\n agent: Agent, \n task: SwarmTask,\n message?: string\n ): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n const branchName = this.agentBranches.get(agent.id);\n if (!branchName) {\n logger.warn(`No branch found for agent ${agent.id}`);\n return;\n }\n\n try {\n // Ensure we're on the agent's branch\n this.checkoutBranch(branchName);\n\n // Check for changes\n const hasChanges = this.hasUncommittedChanges();\n if (!hasChanges) {\n logger.debug(`No changes to commit for agent ${agent.role}`);\n return;\n }\n\n // Stage all changes\n execSync('git add -A', { encoding: 'utf8' });\n\n // Generate commit message\n const commitMessage = message || this.generateCommitMessage(agent, task);\n \n // Commit changes\n execSync(`git commit -m \"${commitMessage}\"`, { encoding: 'utf8' });\n \n logger.info(`Agent ${agent.role} committed: ${commitMessage}`);\n\n // Push if remote exists\n if (this.hasRemote()) {\n try {\n execSync(`git push origin ${branchName}`, { encoding: 'utf8' });\n logger.info(`Pushed branch ${branchName} to remote`);\n } catch (error) {\n logger.warn(`Could not push to remote: ${error}`);\n }\n }\n } catch (error: unknown) {\n logger.error(`Failed to commit agent work`, error as Error);\n }\n }\n\n /**\n * Merge agent work back to baseline\n */\n async mergeAgentWork(agent: Agent, task: SwarmTask): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n const branchName = this.agentBranches.get(agent.id);\n if (!branchName) {\n logger.warn(`No branch found for agent ${agent.id}`);\n return;\n }\n\n try {\n // Switch to baseline branch\n this.checkoutBranch(this.baselineBranch);\n\n if (this.config.requirePR) {\n // Create pull request\n await this.createPullRequest(agent, task, branchName);\n } else {\n // Direct merge based on strategy\n this.mergeBranch(branchName);\n logger.info(`Merged agent ${agent.role} work from ${branchName}`);\n }\n\n // Clean up branch\n this.deleteBranch(branchName);\n this.agentBranches.delete(agent.id);\n\n } catch (error: unknown) {\n logger.error(`Failed to merge agent work`, error as Error);\n }\n }\n\n /**\n * Coordinate merges between multiple agents\n */\n async coordinateMerges(agents: Agent[]): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n logger.info('Coordinating merges from all agents');\n\n // Create integration branch\n const integrationBranch = `swarm-integration-${Date.now()}`;\n this.createBranch(integrationBranch);\n\n // Merge each agent's work\n for (const agent of agents) {\n const branchName = this.agentBranches.get(agent.id);\n if (branchName && this.branchExists(branchName)) {\n try {\n this.mergeBranch(branchName);\n logger.info(`Integrated ${agent.role} work`);\n } catch (error) {\n logger.error(`Failed to integrate ${agent.role} work: ${error}`);\n }\n }\n }\n\n // Run tests on integration branch\n const testsPass = await this.runIntegrationTests();\n \n if (testsPass) {\n // Merge to baseline\n this.checkoutBranch(this.baselineBranch);\n this.mergeBranch(integrationBranch);\n logger.info('Successfully integrated all agent work');\n } else {\n logger.warn('Integration tests failed, keeping changes in branch: ' + integrationBranch);\n }\n }\n\n /**\n * Handle merge conflicts\n */\n async resolveConflicts(agent: Agent): Promise<void> {\n const conflicts = this.getConflictedFiles();\n \n if (conflicts.length === 0) return;\n\n logger.warn(`Agent ${agent.role} encountering merge conflicts: ${conflicts.join(', ')}`);\n\n // Strategy 1: Try to auto-resolve\n for (const file of conflicts) {\n try {\n // Accept current changes for agent's own files\n if (this.isAgentFile(file, agent)) {\n execSync(`git checkout --ours ${file}`, { encoding: 'utf8' });\n execSync(`git add ${file}`, { encoding: 'utf8' });\n } else {\n // Accept incoming changes for other files\n execSync(`git checkout --theirs ${file}`, { encoding: 'utf8' });\n execSync(`git add ${file}`, { encoding: 'utf8' });\n }\n } catch (error) {\n logger.error(`Could not auto-resolve conflict in ${file}`);\n }\n }\n\n // Complete merge if all conflicts resolved\n const remainingConflicts = this.getConflictedFiles();\n if (remainingConflicts.length === 0) {\n execSync('git commit --no-edit', { encoding: 'utf8' });\n logger.info('All conflicts resolved automatically');\n } else {\n logger.error(`Manual intervention needed for: ${remainingConflicts.join(', ')}`);\n }\n }\n\n // Private helper methods\n private getCurrentBranch(): string {\n return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();\n }\n\n private getMainBranch(): string {\n try {\n // Try to detect main branch\n const branches = execSync('git branch -r', { encoding: 'utf8' });\n if (branches.includes('origin/main')) return 'main';\n if (branches.includes('origin/master')) return 'master';\n } catch (error) {\n // Fallback to current branch\n }\n return this.getCurrentBranch();\n }\n\n private generateBranchName(agent: Agent, task: SwarmTask): string {\n const sanitizedTitle = task.title.toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .substring(0, 30);\n\n switch (this.config.branchStrategy) {\n case 'feature':\n return `feature/${sanitizedTitle}`;\n case 'task':\n return `task/${task.id}`;\n case 'agent':\n default:\n return `swarm/${agent.role}-${sanitizedTitle}`;\n }\n }\n\n private createBranch(branchName: string): void {\n execSync(`git checkout -b ${branchName}`, { encoding: 'utf8' });\n }\n\n private checkoutBranch(branchName: string): void {\n execSync(`git checkout ${branchName}`, { encoding: 'utf8' });\n }\n\n private branchExists(branchName: string): boolean {\n try {\n execSync(`git rev-parse --verify ${branchName}`, { \n encoding: 'utf8',\n stdio: 'pipe'\n });\n return true;\n } catch {\n return false;\n }\n }\n\n private deleteBranch(branchName: string): void {\n try {\n execSync(`git branch -d ${branchName}`, { encoding: 'utf8' });\n } catch (error) {\n // Force delete if needed\n execSync(`git branch -D ${branchName}`, { encoding: 'utf8' });\n }\n }\n\n private mergeBranch(branchName: string): void {\n const strategy = this.config.mergStrategy;\n \n switch (strategy) {\n case 'squash':\n execSync(`git merge --squash ${branchName}`, { encoding: 'utf8' });\n execSync('git commit -m \"Squashed agent changes\"', { encoding: 'utf8' });\n break;\n case 'rebase':\n execSync(`git rebase ${branchName}`, { encoding: 'utf8' });\n break;\n case 'merge':\n default:\n execSync(`git merge ${branchName}`, { encoding: 'utf8' });\n break;\n }\n }\n\n private hasUncommittedChanges(): boolean {\n const status = execSync('git status --porcelain', { encoding: 'utf8' });\n return status.trim().length > 0;\n }\n\n private hasRemote(): boolean {\n try {\n execSync('git remote get-url origin', { encoding: 'utf8' });\n return true;\n } catch {\n return false;\n }\n }\n\n private getConflictedFiles(): string[] {\n try {\n const conflicts = execSync('git diff --name-only --diff-filter=U', { \n encoding: 'utf8' \n });\n return conflicts.trim().split('\\n').filter(f => f.length > 0);\n } catch {\n return [];\n }\n }\n\n private isAgentFile(file: string, agent: Agent): boolean {\n // Simple heuristic: check if file is in agent's working directory\n return file.includes(agent.role) || file.includes(agent.id);\n }\n\n private generateCommitMessage(agent: Agent, task: SwarmTask): string {\n return `[${agent.role}] ${task.title} - Iteration ${agent.performance?.tasksCompleted || 1}`;\n }\n\n private scheduleAutoCommit(agent: Agent, task: SwarmTask): void {\n const intervalMs = this.config.commitFrequency * 60 * 1000;\n \n setInterval(async () => {\n await this.commitAgentWork(agent, task, `[${agent.role}] Auto-commit: ${task.title}`);\n }, intervalMs);\n }\n\n private async createPullRequest(agent: Agent, task: SwarmTask, branchName: string): Promise<void> {\n try {\n const title = `[Swarm ${agent.role}] ${task.title}`;\n const body = `\n## Agent: ${agent.role}\n## Task: ${task.title}\n\n### Acceptance Criteria:\n${task.acceptanceCriteria.map(c => `- ${c}`).join('\\n')}\n\n### Status:\n- Tasks Completed: ${agent.performance?.tasksCompleted || 0}\n- Success Rate: ${agent.performance?.successRate || 0}%\n\nGenerated by Swarm Coordinator\n `;\n\n execSync(`gh pr create --title \"${title}\" --body \"${body}\" --base ${this.baselineBranch}`, {\n encoding: 'utf8'\n });\n \n logger.info(`Created PR for agent ${agent.role}`);\n } catch (error) {\n logger.warn(`Could not create PR: ${error}`);\n }\n }\n\n private async runIntegrationTests(): Promise<boolean> {\n try {\n // Try to run tests\n execSync('npm test', { encoding: 'utf8' });\n return true;\n } catch {\n // Tests failed or not available\n return false;\n }\n }\n\n /**\n * Get status of all agent branches\n */\n getGitStatus(): object {\n const status: any = {\n enabled: this.config.enableGitWorkflow,\n currentBranch: this.getCurrentBranch(),\n agentBranches: Array.from(this.agentBranches.entries()).map(([agentId, branch]) => ({\n agentId,\n branch,\n exists: this.branchExists(branch)\n })),\n hasUncommittedChanges: this.hasUncommittedChanges()\n };\n\n return status;\n }\n}\n\nexport const gitWorkflowManager = new GitWorkflowManager();"],
|
|
5
|
-
"mappings": "AAKA,SAAS,gBAAgB;AACzB,SAAS,cAAc;AAYhB,MAAM,mBAAmB;AAAA,EACtB;AAAA,EACA,gBAAqC,oBAAI,IAAI;AAAA,EAC7C;AAAA,EACA;AAAA,EAER,YAAY,QAA6B;AACvC,SAAK,SAAS;AAAA,MACZ,mBAAmB;AAAA,MACnB,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,WAAW;AAAA,MACX,GAAG;AAAA,IACL;AAGA,QAAI;AACF,WAAK,iBAAiB,KAAK,iBAAiB;AAC5C,WAAK,aAAa,KAAK,cAAc;AAAA,IACvC,SAAS,OAAO;AACd,aAAO,KAAK,iDAAiD;AAC7D,WAAK,OAAO,oBAAoB;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAwB,OAAc,MAAgC;AAC1E,QAAI,CAAC,KAAK,OAAO,kBAAmB;AAEpC,
|
|
4
|
+
"sourcesContent": ["/**\n * Git Workflow Manager for Swarm Agents\n * Manages git operations, branching, and commits for each agent\n */\n\nimport { execSync } from 'child_process';\nimport { logger } from '../../../core/monitoring/logger.js';\nimport { Agent, SwarmTask } from '../types.js';\n\nexport interface GitConfig {\n enableGitWorkflow: boolean;\n branchStrategy: 'feature' | 'agent' | 'task';\n autoCommit: boolean;\n commitFrequency: number; // minutes\n mergStrategy: 'squash' | 'merge' | 'rebase';\n requirePR: boolean;\n}\n\nexport class GitWorkflowManager {\n private config: GitConfig;\n private agentBranches: Map<string, string> = new Map();\n private baselineBranch: string;\n private mainBranch: string;\n\n constructor(config?: Partial<GitConfig>) {\n this.config = {\n enableGitWorkflow: true,\n branchStrategy: 'agent',\n autoCommit: true,\n commitFrequency: 5,\n mergStrategy: 'squash',\n requirePR: false,\n ...config,\n };\n\n // Get current branch as baseline\n try {\n this.baselineBranch = this.getCurrentBranch();\n this.mainBranch = this.getMainBranch();\n } catch (error) {\n logger.warn('Git not initialized, workflow features disabled');\n this.config.enableGitWorkflow = false;\n }\n }\n\n /**\n * Initialize git workflow for an agent\n */\n async initializeAgentWorkflow(agent: Agent, task: SwarmTask): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n let branchName = this.generateBranchName(agent, task);\n\n try {\n // Check if branch already exists and handle accordingly\n if (this.branchExists(branchName)) {\n // Branch exists, either reuse or create unique name\n const existingHasChanges = this.branchHasUnmergedChanges(branchName);\n\n if (existingHasChanges) {\n // Create a unique branch name by adding timestamp\n const timestamp = Date.now();\n branchName = `${branchName}-${timestamp}`;\n logger.info(\n `Branch already exists with changes, creating unique branch: ${branchName}`\n );\n this.createBranch(branchName);\n } else {\n // Reuse existing branch\n logger.info(\n `Reusing existing branch for agent ${agent.role}: ${branchName}`\n );\n this.checkoutBranch(branchName);\n }\n } else {\n // Create new branch\n this.createBranch(branchName);\n logger.info(\n `Created git branch for agent ${agent.role}: ${branchName}`\n );\n }\n\n this.agentBranches.set(agent.id, branchName);\n\n // Set up commit timer if auto-commit enabled\n if (this.config.autoCommit) {\n this.scheduleAutoCommit(agent, task);\n }\n } catch (error: unknown) {\n logger.error(\n `Failed to initialize git workflow for agent ${agent.role}`,\n error as Error\n );\n }\n }\n\n /**\n * Commit agent work\n */\n async commitAgentWork(\n agent: Agent,\n task: SwarmTask,\n message?: string\n ): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n const branchName = this.agentBranches.get(agent.id);\n if (!branchName) {\n logger.warn(`No branch found for agent ${agent.id}`);\n return;\n }\n\n try {\n // Ensure we're on the agent's branch\n this.checkoutBranch(branchName);\n\n // Check for changes\n const hasChanges = this.hasUncommittedChanges();\n if (!hasChanges) {\n logger.debug(`No changes to commit for agent ${agent.role}`);\n return;\n }\n\n // Stage all changes\n execSync('git add -A', { encoding: 'utf8' });\n\n // Generate commit message\n const commitMessage = message || this.generateCommitMessage(agent, task);\n\n // Commit changes\n execSync(`git commit -m \"${commitMessage}\"`, { encoding: 'utf8' });\n\n logger.info(`Agent ${agent.role} committed: ${commitMessage}`);\n\n // Push if remote exists\n if (this.hasRemote()) {\n try {\n execSync(`git push origin ${branchName}`, { encoding: 'utf8' });\n logger.info(`Pushed branch ${branchName} to remote`);\n } catch (error) {\n logger.warn(`Could not push to remote: ${error}`);\n }\n }\n } catch (error: unknown) {\n logger.error(`Failed to commit agent work`, error as Error);\n }\n }\n\n /**\n * Merge agent work back to baseline\n */\n async mergeAgentWork(agent: Agent, task: SwarmTask): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n const branchName = this.agentBranches.get(agent.id);\n if (!branchName) {\n logger.warn(`No branch found for agent ${agent.id}`);\n return;\n }\n\n try {\n // Switch to baseline branch\n this.checkoutBranch(this.baselineBranch);\n\n if (this.config.requirePR) {\n // Create pull request\n await this.createPullRequest(agent, task, branchName);\n } else {\n // Direct merge based on strategy\n this.mergeBranch(branchName);\n logger.info(`Merged agent ${agent.role} work from ${branchName}`);\n }\n\n // Clean up branch\n this.deleteBranch(branchName);\n this.agentBranches.delete(agent.id);\n } catch (error: unknown) {\n logger.error(`Failed to merge agent work`, error as Error);\n }\n }\n\n /**\n * Coordinate merges between multiple agents\n */\n async coordinateMerges(agents: Agent[]): Promise<void> {\n if (!this.config.enableGitWorkflow) return;\n\n logger.info('Coordinating merges from all agents');\n\n // Create integration branch\n const integrationBranch = `swarm-integration-${Date.now()}`;\n this.createBranch(integrationBranch);\n\n // Merge each agent's work\n for (const agent of agents) {\n const branchName = this.agentBranches.get(agent.id);\n if (branchName && this.branchExists(branchName)) {\n try {\n this.mergeBranch(branchName);\n logger.info(`Integrated ${agent.role} work`);\n } catch (error) {\n logger.error(`Failed to integrate ${agent.role} work: ${error}`);\n }\n }\n }\n\n // Run tests on integration branch\n const testsPass = await this.runIntegrationTests();\n\n if (testsPass) {\n // Merge to baseline\n this.checkoutBranch(this.baselineBranch);\n this.mergeBranch(integrationBranch);\n logger.info('Successfully integrated all agent work');\n } else {\n logger.warn(\n 'Integration tests failed, keeping changes in branch: ' +\n integrationBranch\n );\n }\n }\n\n /**\n * Handle merge conflicts\n */\n async resolveConflicts(agent: Agent): Promise<void> {\n const conflicts = this.getConflictedFiles();\n\n if (conflicts.length === 0) return;\n\n logger.warn(\n `Agent ${agent.role} encountering merge conflicts: ${conflicts.join(', ')}`\n );\n\n // Strategy 1: Try to auto-resolve\n for (const file of conflicts) {\n try {\n // Accept current changes for agent's own files\n if (this.isAgentFile(file, agent)) {\n execSync(`git checkout --ours ${file}`, { encoding: 'utf8' });\n execSync(`git add ${file}`, { encoding: 'utf8' });\n } else {\n // Accept incoming changes for other files\n execSync(`git checkout --theirs ${file}`, { encoding: 'utf8' });\n execSync(`git add ${file}`, { encoding: 'utf8' });\n }\n } catch (error) {\n logger.error(`Could not auto-resolve conflict in ${file}`);\n }\n }\n\n // Complete merge if all conflicts resolved\n const remainingConflicts = this.getConflictedFiles();\n if (remainingConflicts.length === 0) {\n execSync('git commit --no-edit', { encoding: 'utf8' });\n logger.info('All conflicts resolved automatically');\n } else {\n logger.error(\n `Manual intervention needed for: ${remainingConflicts.join(', ')}`\n );\n }\n }\n\n // Private helper methods\n private getCurrentBranch(): string {\n return execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n }).trim();\n }\n\n private getMainBranch(): string {\n try {\n // Try to detect main branch\n const branches = execSync('git branch -r', { encoding: 'utf8' });\n if (branches.includes('origin/main')) return 'main';\n if (branches.includes('origin/master')) return 'master';\n } catch (error) {\n // Fallback to current branch\n }\n return this.getCurrentBranch();\n }\n\n private generateBranchName(agent: Agent, task: SwarmTask): string {\n const sanitizedTitle = task.title\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .substring(0, 30);\n\n switch (this.config.branchStrategy) {\n case 'feature':\n return `feature/${sanitizedTitle}`;\n case 'task':\n return `task/${task.id}`;\n case 'agent':\n default:\n return `swarm/${agent.role}-${sanitizedTitle}`;\n }\n }\n\n private createBranch(branchName: string): void {\n execSync(`git checkout -b ${branchName}`, { encoding: 'utf8' });\n }\n\n private checkoutBranch(branchName: string): void {\n execSync(`git checkout ${branchName}`, { encoding: 'utf8' });\n }\n\n private branchExists(branchName: string): boolean {\n try {\n execSync(`git rev-parse --verify ${branchName}`, {\n encoding: 'utf8',\n stdio: 'pipe',\n });\n return true;\n } catch {\n return false;\n }\n }\n\n private deleteBranch(branchName: string): void {\n try {\n execSync(`git branch -d ${branchName}`, { encoding: 'utf8' });\n } catch (error) {\n // Force delete if needed\n execSync(`git branch -D ${branchName}`, { encoding: 'utf8' });\n }\n }\n\n private mergeBranch(branchName: string): void {\n const strategy = this.config.mergStrategy;\n\n switch (strategy) {\n case 'squash':\n execSync(`git merge --squash ${branchName}`, { encoding: 'utf8' });\n execSync('git commit -m \"Squashed agent changes\"', {\n encoding: 'utf8',\n });\n break;\n case 'rebase':\n execSync(`git rebase ${branchName}`, { encoding: 'utf8' });\n break;\n case 'merge':\n default:\n execSync(`git merge ${branchName}`, { encoding: 'utf8' });\n break;\n }\n }\n\n private hasUncommittedChanges(): boolean {\n const status = execSync('git status --porcelain', { encoding: 'utf8' });\n return status.trim().length > 0;\n }\n\n private hasRemote(): boolean {\n try {\n execSync('git remote get-url origin', { encoding: 'utf8' });\n return true;\n } catch {\n return false;\n }\n }\n\n private getConflictedFiles(): string[] {\n try {\n const conflicts = execSync('git diff --name-only --diff-filter=U', {\n encoding: 'utf8',\n });\n return conflicts\n .trim()\n .split('\\n')\n .filter((f) => f.length > 0);\n } catch {\n return [];\n }\n }\n\n private isAgentFile(file: string, agent: Agent): boolean {\n // Simple heuristic: check if file is in agent's working directory\n return file.includes(agent.role) || file.includes(agent.id);\n }\n\n private generateCommitMessage(agent: Agent, task: SwarmTask): string {\n return `[${agent.role}] ${task.title} - Iteration ${agent.performance?.tasksCompleted || 1}`;\n }\n\n private scheduleAutoCommit(agent: Agent, task: SwarmTask): void {\n const intervalMs = this.config.commitFrequency * 60 * 1000;\n\n setInterval(async () => {\n await this.commitAgentWork(\n agent,\n task,\n `[${agent.role}] Auto-commit: ${task.title}`\n );\n }, intervalMs);\n }\n\n private async createPullRequest(\n agent: Agent,\n task: SwarmTask,\n branchName: string\n ): Promise<void> {\n try {\n const title = `[Swarm ${agent.role}] ${task.title}`;\n const body = `\n## Agent: ${agent.role}\n## Task: ${task.title}\n\n### Acceptance Criteria:\n${task.acceptanceCriteria.map((c) => `- ${c}`).join('\\n')}\n\n### Status:\n- Tasks Completed: ${agent.performance?.tasksCompleted || 0}\n- Success Rate: ${agent.performance?.successRate || 0}%\n\nGenerated by Swarm Coordinator\n `;\n\n execSync(\n `gh pr create --title \"${title}\" --body \"${body}\" --base ${this.baselineBranch}`,\n {\n encoding: 'utf8',\n }\n );\n\n logger.info(`Created PR for agent ${agent.role}`);\n } catch (error) {\n logger.warn(`Could not create PR: ${error}`);\n }\n }\n\n private async runIntegrationTests(): Promise<boolean> {\n try {\n // Try to run tests\n execSync('npm test', { encoding: 'utf8' });\n return true;\n } catch {\n // Tests failed or not available\n return false;\n }\n }\n\n private branchHasUnmergedChanges(branchName: string): boolean {\n try {\n // Check if branch has commits not in the current branch\n const currentBranch = this.getCurrentBranch();\n const unmerged = execSync(\n `git log ${currentBranch}..${branchName} --oneline`,\n { encoding: 'utf8', stdio: 'pipe' }\n );\n return unmerged.trim().length > 0;\n } catch {\n // If we can't determine, assume it has changes to be safe\n return true;\n }\n }\n\n /**\n * Get status of all agent branches\n */\n getGitStatus(): object {\n const status: any = {\n enabled: this.config.enableGitWorkflow,\n currentBranch: this.getCurrentBranch(),\n agentBranches: Array.from(this.agentBranches.entries()).map(\n ([agentId, branch]) => ({\n agentId,\n branch,\n exists: this.branchExists(branch),\n })\n ),\n hasUncommittedChanges: this.hasUncommittedChanges(),\n };\n\n return status;\n }\n}\n\nexport const gitWorkflowManager = new GitWorkflowManager();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -17,6 +17,12 @@ class SwarmCoordinator {
|
|
|
17
17
|
plannerWakeupQueue = /* @__PURE__ */ new Map();
|
|
18
18
|
gitWorkflowManager;
|
|
19
19
|
registeredSwarmId;
|
|
20
|
+
get swarmId() {
|
|
21
|
+
return this.registeredSwarmId;
|
|
22
|
+
}
|
|
23
|
+
get agents() {
|
|
24
|
+
return Array.from(this.activeAgents.values());
|
|
25
|
+
}
|
|
20
26
|
constructor(config) {
|
|
21
27
|
this.config = {
|
|
22
28
|
maxAgents: 10,
|
|
@@ -63,11 +69,17 @@ class SwarmCoordinator {
|
|
|
63
69
|
await sharedContextLayer.initialize();
|
|
64
70
|
const session = await sessionManager.getOrCreateSession({});
|
|
65
71
|
if (session.database) {
|
|
66
|
-
this.frameManager = new FrameManager(
|
|
72
|
+
this.frameManager = new FrameManager(
|
|
73
|
+
session.database,
|
|
74
|
+
session.projectId
|
|
75
|
+
);
|
|
67
76
|
}
|
|
68
77
|
this.startCoordinationLoop();
|
|
69
78
|
const registry = SwarmRegistry.getInstance();
|
|
70
|
-
this.registeredSwarmId = registry.registerSwarm(
|
|
79
|
+
this.registeredSwarmId = registry.registerSwarm(
|
|
80
|
+
this,
|
|
81
|
+
`Swarm ${this.swarmState.id.substring(0, 8)}`
|
|
82
|
+
);
|
|
71
83
|
logger.info("Swarm coordinator initialized successfully");
|
|
72
84
|
} catch (error) {
|
|
73
85
|
logger.error("Failed to initialize swarm coordinator", error);
|
|
@@ -85,11 +97,19 @@ class SwarmCoordinator {
|
|
|
85
97
|
const swarmId = uuidv4();
|
|
86
98
|
try {
|
|
87
99
|
if (agents.length > this.config.maxAgents) {
|
|
88
|
-
throw new Error(
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Too many agents requested: ${agents.length} > ${this.config.maxAgents}`
|
|
102
|
+
);
|
|
89
103
|
}
|
|
90
104
|
const swarmTasks = await this.decomposeProjectIntoSwarmTasks(projectDescription);
|
|
91
|
-
const initializedAgents = await this.initializeSpecializedAgents(
|
|
92
|
-
|
|
105
|
+
const initializedAgents = await this.initializeSpecializedAgents(
|
|
106
|
+
agents,
|
|
107
|
+
swarmTasks
|
|
108
|
+
);
|
|
109
|
+
const allocation = await this.allocateTasksToAgents(
|
|
110
|
+
swarmTasks,
|
|
111
|
+
initializedAgents
|
|
112
|
+
);
|
|
93
113
|
this.swarmState = {
|
|
94
114
|
...this.swarmState,
|
|
95
115
|
id: swarmId,
|
|
@@ -101,7 +121,10 @@ class SwarmCoordinator {
|
|
|
101
121
|
allocation
|
|
102
122
|
};
|
|
103
123
|
await this.executeSwarmTasks(allocation);
|
|
104
|
-
logger.info("Swarm launched successfully", {
|
|
124
|
+
logger.info("Swarm launched successfully", {
|
|
125
|
+
swarmId,
|
|
126
|
+
agentCount: initializedAgents.length
|
|
127
|
+
});
|
|
105
128
|
return swarmId;
|
|
106
129
|
} catch (error) {
|
|
107
130
|
logger.error("Failed to launch swarm", error);
|
|
@@ -277,7 +300,10 @@ class SwarmCoordinator {
|
|
|
277
300
|
maxIterations: this.calculateMaxIterations(task),
|
|
278
301
|
useStackMemory: true
|
|
279
302
|
});
|
|
280
|
-
const contextualPrompt = await this.synthesizeContextualPrompt(
|
|
303
|
+
const contextualPrompt = await this.synthesizeContextualPrompt(
|
|
304
|
+
agent,
|
|
305
|
+
task
|
|
306
|
+
);
|
|
281
307
|
await ralph.initialize({
|
|
282
308
|
task: contextualPrompt,
|
|
283
309
|
criteria: task.acceptanceCriteria.join("\n")
|
|
@@ -291,7 +317,10 @@ class SwarmCoordinator {
|
|
|
291
317
|
agent.status = "idle";
|
|
292
318
|
logger.info(`Agent ${agent.role} completed task: ${task.title}`);
|
|
293
319
|
} catch (error) {
|
|
294
|
-
logger.error(
|
|
320
|
+
logger.error(
|
|
321
|
+
`Agent ${agent.role} failed task: ${task.title}`,
|
|
322
|
+
error
|
|
323
|
+
);
|
|
295
324
|
this.updateAgentPerformance(agent, false);
|
|
296
325
|
await this.handleTaskFailure(agent, task, error);
|
|
297
326
|
agent.status = "error";
|
|
@@ -302,7 +331,9 @@ class SwarmCoordinator {
|
|
|
302
331
|
*/
|
|
303
332
|
async synthesizeContextualPrompt(agent, task) {
|
|
304
333
|
const basePrompt = task.description;
|
|
305
|
-
const roleSpecificInstructions = this.getRoleSpecificInstructions(
|
|
334
|
+
const roleSpecificInstructions = this.getRoleSpecificInstructions(
|
|
335
|
+
agent.role
|
|
336
|
+
);
|
|
306
337
|
const swarmContext = await this.getSwarmContext(task);
|
|
307
338
|
const coordinationInstructions = this.getCoordinationInstructions(agent);
|
|
308
339
|
return `
|
|
@@ -362,16 +393,22 @@ ${task.acceptanceCriteria.map((c) => `- ${c}`).join("\n")}
|
|
|
362
393
|
for (const agent of this.activeAgents.values()) {
|
|
363
394
|
if (agent.status !== "active") continue;
|
|
364
395
|
if (agent.performance.driftDetected) {
|
|
365
|
-
logger.warn(
|
|
396
|
+
logger.warn(
|
|
397
|
+
`Drift detected in agent ${agent.role}, triggering fresh start`
|
|
398
|
+
);
|
|
366
399
|
await this.triggerFreshStart(agent);
|
|
367
400
|
continue;
|
|
368
401
|
}
|
|
369
402
|
if (await this.detectTunnelVision(agent)) {
|
|
370
|
-
logger.warn(
|
|
403
|
+
logger.warn(
|
|
404
|
+
`Tunnel vision detected in agent ${agent.role}, providing alternative approach`
|
|
405
|
+
);
|
|
371
406
|
await this.provideAlternativeApproach(agent);
|
|
372
407
|
}
|
|
373
408
|
if (await this.detectExcessiveRuntime(agent)) {
|
|
374
|
-
logger.warn(
|
|
409
|
+
logger.warn(
|
|
410
|
+
`Excessive runtime detected in agent ${agent.role}, requesting checkpoint`
|
|
411
|
+
);
|
|
375
412
|
await this.requestCheckpoint(agent);
|
|
376
413
|
}
|
|
377
414
|
}
|
|
@@ -388,85 +425,221 @@ ${task.acceptanceCriteria.map((c) => `- ${c}`).join("\n")}
|
|
|
388
425
|
this.plannerWakeupQueue.delete(agentId);
|
|
389
426
|
}
|
|
390
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Get status of a specific swarm
|
|
430
|
+
*/
|
|
431
|
+
getSwarmStatus(swarmId) {
|
|
432
|
+
const registry = SwarmRegistry.getInstance();
|
|
433
|
+
const swarm = registry.getSwarm(swarmId);
|
|
434
|
+
if (!swarm) {
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
id: swarmId,
|
|
439
|
+
state: swarm.status || "running",
|
|
440
|
+
activeAgents: swarm.agents?.length || 0,
|
|
441
|
+
startTime: swarm.startTime || Date.now(),
|
|
442
|
+
agents: swarm.agents?.map((agent) => ({
|
|
443
|
+
role: agent.role,
|
|
444
|
+
status: agent.status || "active",
|
|
445
|
+
task: agent.task || "Working"
|
|
446
|
+
}))
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Get all active swarms
|
|
451
|
+
*/
|
|
452
|
+
getAllActiveSwarms() {
|
|
453
|
+
const registry = SwarmRegistry.getInstance();
|
|
454
|
+
const activeSwarms = registry.listActiveSwarms();
|
|
455
|
+
return activeSwarms.map((swarm) => ({
|
|
456
|
+
id: swarm.id,
|
|
457
|
+
description: swarm.description,
|
|
458
|
+
agentCount: swarm.agents?.length || 0,
|
|
459
|
+
status: swarm.status || "running",
|
|
460
|
+
startTime: swarm.startTime || Date.now()
|
|
461
|
+
}));
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Stop a specific swarm gracefully
|
|
465
|
+
*/
|
|
466
|
+
async stopSwarm(swarmId) {
|
|
467
|
+
const targetId = swarmId || this.swarmId;
|
|
468
|
+
if (!targetId) {
|
|
469
|
+
throw new Error("No swarm ID provided");
|
|
470
|
+
}
|
|
471
|
+
logger.info("Stopping swarm", { swarmId: targetId });
|
|
472
|
+
for (const agent of this.agents) {
|
|
473
|
+
try {
|
|
474
|
+
await this.stopAgent(agent);
|
|
475
|
+
} catch (error) {
|
|
476
|
+
logger.error("Failed to stop agent", {
|
|
477
|
+
agent: agent.id,
|
|
478
|
+
error: error.message
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (this.gitWorkflowManager) {
|
|
483
|
+
try {
|
|
484
|
+
await this.gitWorkflowManager.cleanup();
|
|
485
|
+
} catch (error) {
|
|
486
|
+
logger.error("Git cleanup failed", { error: error.message });
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
const registry = SwarmRegistry.getInstance();
|
|
490
|
+
registry.unregisterSwarm(targetId);
|
|
491
|
+
logger.info("Swarm stopped", { swarmId: targetId });
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Force stop a swarm without saving state
|
|
495
|
+
*/
|
|
496
|
+
async forceStopSwarm(swarmId) {
|
|
497
|
+
logger.info("Force stopping swarm", { swarmId });
|
|
498
|
+
const registry = SwarmRegistry.getInstance();
|
|
499
|
+
registry.unregisterSwarm(swarmId);
|
|
500
|
+
this.activeAgents.clear();
|
|
501
|
+
logger.info("Swarm force stopped", { swarmId });
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Cleanup all resources
|
|
505
|
+
*/
|
|
506
|
+
async cleanup() {
|
|
507
|
+
logger.info("Cleaning up SwarmCoordinator resources");
|
|
508
|
+
const activeSwarms = this.getAllActiveSwarms();
|
|
509
|
+
for (const swarm of activeSwarms) {
|
|
510
|
+
try {
|
|
511
|
+
await this.stopSwarm(swarm.id);
|
|
512
|
+
} catch (error) {
|
|
513
|
+
logger.error("Failed to stop swarm during cleanup", {
|
|
514
|
+
swarmId: swarm.id,
|
|
515
|
+
error: error.message
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
const registry = SwarmRegistry.getInstance();
|
|
520
|
+
registry.cleanup();
|
|
521
|
+
this.activeAgents.clear();
|
|
522
|
+
logger.info("SwarmCoordinator cleanup completed");
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Stop an individual agent
|
|
526
|
+
*/
|
|
527
|
+
async stopAgent(agent) {
|
|
528
|
+
logger.debug("Stopping agent", { agentId: agent.id, role: agent.role });
|
|
529
|
+
agent.status = "stopped";
|
|
530
|
+
if (agent.ralphBridge) {
|
|
531
|
+
try {
|
|
532
|
+
await agent.ralphBridge.cleanup();
|
|
533
|
+
} catch (error) {
|
|
534
|
+
logger.error("Failed to cleanup agent bridge", {
|
|
535
|
+
error: error.message
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
391
540
|
// Helper methods for role specialization and coordination
|
|
392
541
|
defineCapabilities(role) {
|
|
393
542
|
const capabilityMap = {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
543
|
+
architect: [
|
|
544
|
+
"system_design",
|
|
545
|
+
"component_modeling",
|
|
546
|
+
"architecture_validation"
|
|
547
|
+
],
|
|
548
|
+
planner: [
|
|
549
|
+
"task_decomposition",
|
|
550
|
+
"dependency_analysis",
|
|
551
|
+
"resource_planning"
|
|
552
|
+
],
|
|
553
|
+
developer: ["code_implementation", "debugging", "refactoring"],
|
|
554
|
+
reviewer: [
|
|
555
|
+
"code_review",
|
|
556
|
+
"quality_assessment",
|
|
557
|
+
"best_practice_enforcement"
|
|
558
|
+
],
|
|
559
|
+
tester: ["test_design", "automation", "validation"],
|
|
560
|
+
optimizer: [
|
|
561
|
+
"performance_analysis",
|
|
562
|
+
"resource_optimization",
|
|
563
|
+
"bottleneck_identification"
|
|
564
|
+
],
|
|
565
|
+
documenter: [
|
|
566
|
+
"technical_writing",
|
|
567
|
+
"api_documentation",
|
|
568
|
+
"example_creation"
|
|
569
|
+
],
|
|
570
|
+
coordinator: [
|
|
571
|
+
"task_coordination",
|
|
572
|
+
"conflict_resolution",
|
|
573
|
+
"progress_tracking"
|
|
574
|
+
]
|
|
402
575
|
};
|
|
403
576
|
return capabilityMap[role] || [];
|
|
404
577
|
}
|
|
405
578
|
defineCommuncationStyle(role) {
|
|
406
579
|
const styleMap = {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
580
|
+
architect: "high_level_design_focused",
|
|
581
|
+
planner: "structured_and_methodical",
|
|
582
|
+
developer: "implementation_focused",
|
|
583
|
+
reviewer: "quality_focused_constructive",
|
|
584
|
+
tester: "validation_focused",
|
|
585
|
+
optimizer: "performance_metrics_focused",
|
|
586
|
+
documenter: "clarity_focused",
|
|
587
|
+
coordinator: "facilitative_and_diplomatic"
|
|
415
588
|
};
|
|
416
589
|
return styleMap[role] || "collaborative";
|
|
417
590
|
}
|
|
418
591
|
getRoleSpecificInstructions(role) {
|
|
419
592
|
const instructionMap = {
|
|
420
|
-
|
|
593
|
+
architect: `
|
|
421
594
|
You are a SYSTEM ARCHITECT. Your role is to:
|
|
422
595
|
- Design high-level system architecture
|
|
423
596
|
- Define component interfaces and relationships
|
|
424
597
|
- Ensure architectural consistency across the project
|
|
425
598
|
- Think in terms of scalability, maintainability, and extensibility
|
|
426
599
|
- Collaborate with developers to validate feasibility`,
|
|
427
|
-
|
|
600
|
+
planner: `
|
|
428
601
|
You are a PROJECT PLANNER. Your role is to:
|
|
429
602
|
- Break down complex tasks into manageable steps
|
|
430
603
|
- Identify dependencies and critical path
|
|
431
604
|
- Coordinate with other agents on sequencing
|
|
432
605
|
- Wake up when tasks complete to plan next steps
|
|
433
606
|
- Adapt plans based on actual progress`,
|
|
434
|
-
|
|
607
|
+
developer: `
|
|
435
608
|
You are a SPECIALIZED DEVELOPER. Your role is to:
|
|
436
609
|
- Implement features according to specifications
|
|
437
610
|
- Write clean, maintainable code
|
|
438
611
|
- Follow established patterns and conventions
|
|
439
612
|
- Integrate with other components
|
|
440
613
|
- Communicate implementation details clearly`,
|
|
441
|
-
|
|
614
|
+
reviewer: `
|
|
442
615
|
You are a CODE REVIEWER. Your role is to:
|
|
443
616
|
- Review code for quality, correctness, and best practices
|
|
444
617
|
- Provide constructive feedback
|
|
445
618
|
- Ensure consistency with project standards
|
|
446
619
|
- Identify potential issues before they become problems
|
|
447
620
|
- Approve or request changes`,
|
|
448
|
-
|
|
621
|
+
tester: `
|
|
449
622
|
You are a QA ENGINEER. Your role is to:
|
|
450
623
|
- Design comprehensive test strategies
|
|
451
624
|
- Implement automated tests
|
|
452
625
|
- Validate functionality and performance
|
|
453
626
|
- Report bugs clearly and reproducibly
|
|
454
627
|
- Ensure quality gates are met`,
|
|
455
|
-
|
|
628
|
+
optimizer: `
|
|
456
629
|
You are a PERFORMANCE OPTIMIZER. Your role is to:
|
|
457
630
|
- Analyze system performance and identify bottlenecks
|
|
458
631
|
- Implement optimizations
|
|
459
632
|
- Monitor resource usage
|
|
460
633
|
- Establish performance benchmarks
|
|
461
634
|
- Ensure scalability requirements are met`,
|
|
462
|
-
|
|
635
|
+
documenter: `
|
|
463
636
|
You are a TECHNICAL WRITER. Your role is to:
|
|
464
637
|
- Create clear, comprehensive documentation
|
|
465
638
|
- Write API documentation and usage examples
|
|
466
639
|
- Ensure documentation stays up-to-date
|
|
467
640
|
- Focus on user experience and clarity
|
|
468
641
|
- Collaborate with developers to understand features`,
|
|
469
|
-
|
|
642
|
+
coordinator: `
|
|
470
643
|
You are a PROJECT COORDINATOR. Your role is to:
|
|
471
644
|
- Facilitate communication between agents
|
|
472
645
|
- Resolve conflicts and blockers
|
|
@@ -487,20 +660,31 @@ You are a PROJECT COORDINATOR. Your role is to:
|
|
|
487
660
|
};
|
|
488
661
|
}
|
|
489
662
|
extractCoreFeatures(description) {
|
|
490
|
-
return [
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
663
|
+
return [
|
|
664
|
+
{
|
|
665
|
+
name: "Core Feature",
|
|
666
|
+
description: "Main functionality implementation",
|
|
667
|
+
complexity: "medium",
|
|
668
|
+
criteria: [
|
|
669
|
+
"Feature works correctly",
|
|
670
|
+
"Handles edge cases",
|
|
671
|
+
"Follows coding standards"
|
|
672
|
+
]
|
|
673
|
+
}
|
|
674
|
+
];
|
|
496
675
|
}
|
|
497
676
|
// Implement remaining helper methods...
|
|
498
677
|
async setupAgentEnvironment(agent) {
|
|
499
678
|
try {
|
|
500
679
|
await fs.mkdir(agent.workingDirectory, { recursive: true });
|
|
501
|
-
logger.debug(
|
|
680
|
+
logger.debug(
|
|
681
|
+
`Created working directory for agent ${agent.id}: ${agent.workingDirectory}`
|
|
682
|
+
);
|
|
502
683
|
} catch (error) {
|
|
503
|
-
logger.warn(
|
|
684
|
+
logger.warn(
|
|
685
|
+
`Could not create working directory for agent ${agent.id}`,
|
|
686
|
+
error
|
|
687
|
+
);
|
|
504
688
|
}
|
|
505
689
|
}
|
|
506
690
|
async configureAgentPrompts(agent) {
|
|
@@ -595,7 +779,9 @@ You are a PROJECT COORDINATOR. Your role is to:
|
|
|
595
779
|
}
|
|
596
780
|
};
|
|
597
781
|
this.swarmState.coordination?.events.push(event);
|
|
598
|
-
logger.info(
|
|
782
|
+
logger.info(
|
|
783
|
+
`Task ${task.id} completed by agent ${agent.role}: ${success ? "SUCCESS" : "FAILED"}`
|
|
784
|
+
);
|
|
599
785
|
}
|
|
600
786
|
async handleTaskFailure(agent, task, error) {
|
|
601
787
|
logger.error(`Agent ${agent.role} failed task ${task.id}`, error);
|
|
@@ -628,13 +814,19 @@ You are a PROJECT COORDINATOR. Your role is to:
|
|
|
628
814
|
}
|
|
629
815
|
async resolveActiveConflicts() {
|
|
630
816
|
if (this.swarmState.coordination?.conflicts.length) {
|
|
631
|
-
logger.debug(
|
|
817
|
+
logger.debug(
|
|
818
|
+
`Resolving ${this.swarmState.coordination.conflicts.length} conflicts`
|
|
819
|
+
);
|
|
632
820
|
}
|
|
633
821
|
}
|
|
634
822
|
async rebalanceWorkload() {
|
|
635
|
-
const activeAgents = Array.from(this.activeAgents.values()).filter(
|
|
823
|
+
const activeAgents = Array.from(this.activeAgents.values()).filter(
|
|
824
|
+
(a) => a.status === "active"
|
|
825
|
+
);
|
|
636
826
|
if (activeAgents.length > 0) {
|
|
637
|
-
logger.debug(
|
|
827
|
+
logger.debug(
|
|
828
|
+
`Rebalancing workload among ${activeAgents.length} active agents`
|
|
829
|
+
);
|
|
638
830
|
}
|
|
639
831
|
}
|
|
640
832
|
async triggerFreshStartsIfNeeded() {
|
|
@@ -646,7 +838,9 @@ You are a PROJECT COORDINATOR. Your role is to:
|
|
|
646
838
|
}
|
|
647
839
|
updateSwarmMetrics() {
|
|
648
840
|
if (!this.swarmState.performance) return;
|
|
649
|
-
const activeCount = Array.from(this.activeAgents.values()).filter(
|
|
841
|
+
const activeCount = Array.from(this.activeAgents.values()).filter(
|
|
842
|
+
(a) => a.status === "active"
|
|
843
|
+
).length;
|
|
650
844
|
this.swarmState.performance.throughput = this.swarmState.completedTaskCount / ((Date.now() - this.swarmState.startTime) / 1e3);
|
|
651
845
|
this.swarmState.performance.efficiency = activeCount > 0 ? this.swarmState.completedTaskCount / activeCount : 0;
|
|
652
846
|
}
|