Conversation
- Created `codingTeamNetwork` agent to coordinate specialized coding agents for software development tasks, including architecture, code review, testing, and refactoring. - Added detailed instructions for routing logic and agent selection based on user requests. - Developed `code-analysis.tool.ts` for analyzing source code files, calculating metrics, and detecting issues. - Introduced `code-search.tool.ts` for searching patterns across source files with support for regex and context lines. - Implemented `diff-review.tool.ts` to generate and analyze unified diffs between code versions, providing structured diff data and statistics. - Created `multi-string-edit.tool.ts` for applying multiple string replacements across files with options for dry runs and backup creation. - Developed `test-generator.tool.ts` to generate Vitest test scaffolds for TypeScript/JavaScript source files, including edge case tests and mock setups for external dependencies.
|
Keep this PR in a mergeable state → Learn moreAll Green is an AI agent that automatically: ✅ Addresses code review comments ✅ Fixes failing CI checks ✅ Resolves merge conflicts |
Reviewer's GuideImplements a new Coding Team multi-agent system with four specialized coding agents, a routing network, an A2A coordinator, and five supporting coding tools (analysis, search, diff review, multi-file edit, Vitest test generation), wires them into the Mastra instance and HTTP routing, and refreshes project badges and dependencies. Sequence diagram for routing a coding request via codingTeamNetworksequenceDiagram
actor Developer
participant HTTPServer as NextAPI_Route
participant Mastra as mastra
participant Network as codingTeamNetwork
participant Reviewer as codeReviewerAgent
participant CodeAnalysis as codeAnalysisTool
Developer->>HTTPServer: POST /network (coding request)
HTTPServer->>Mastra: mastra.handleRequest(path: /network)
Mastra->>Network: invoke(message, runtimeContext)
Network->>Network: analyze_intent(message)
Network->>Network: select_agent(codeReviewerAgent)
Network->>Reviewer: delegate_request(message, runtimeContext)
Reviewer->>Reviewer: build_instructions(runtimeContext)
Reviewer->>CodeAnalysis: execute(target, options)
CodeAnalysis-->>Reviewer: CodeAnalysisOutput
Reviewer-->>Network: review_report
Network-->>Mastra: routed_response
Mastra-->>HTTPServer: HTTP_response
HTTPServer-->>Developer: JSON(review_summary)
Class diagram for Coding Team agents, network, coordinator, and toolsclassDiagram
class Agent {
+string id
+string name
+string description
+function instructions(runtimeContext)
+model
+memory
+tools
+agents
+workflows
+scorers
+maxRetries
}
class Tool {
+string id
+string description
+inputSchema
+outputSchema
+function execute(context)
}
class codingTeamNetwork {
+id = "coding-team-network"
+name = "Coding Team Network"
+description
+agents: coding_agents
}
class codingA2ACoordinator {
+id = "codingA2ACoordinator"
+name = "Coding A2A Coordinator"
+description
+agents: coding_agents
}
class codeArchitectAgent {
+id = "code-architect"
+name = "Code Architect Agent"
+description
+UserTier userTier
+string language
+string projectRoot
}
class codeReviewerAgent {
+id = "code-reviewer"
+name = "Code Reviewer Agent"
+description
}
class testEngineerAgent {
+id = "test-engineer"
+name = "Test Engineer Agent"
+description
}
class refactoringAgent {
+id = "refactoring"
+name = "Refactoring Agent"
+description
}
class codeAnalysisTool {
+id = "coding:codeAnalysis"
+description
+CodeAnalysisInput inputSchema
+CodeAnalysisOutput outputSchema
}
class codeSearchTool {
+id = "coding:codeSearch"
+description
+CodeSearchInput inputSchema
+CodeSearchOutput outputSchema
}
class diffReviewTool {
+id = "coding:diffReview"
+description
+DiffReviewInput inputSchema
+DiffReviewOutput outputSchema
}
class multiStringEditTool {
+id = "coding:multiStringEdit"
+description
+MultiStringEditInput inputSchema
+MultiStringEditOutput outputSchema
}
class testGeneratorTool {
+id = "coding:testGenerator"
+description
+TestGeneratorInput inputSchema
+TestGeneratorOutput outputSchema
}
Agent <|-- codingTeamNetwork
Agent <|-- codingA2ACoordinator
Agent <|-- codeArchitectAgent
Agent <|-- codeReviewerAgent
Agent <|-- testEngineerAgent
Agent <|-- refactoringAgent
Tool <|-- codeAnalysisTool
Tool <|-- codeSearchTool
Tool <|-- diffReviewTool
Tool <|-- multiStringEditTool
Tool <|-- testGeneratorTool
codingTeamNetwork o-- codeArchitectAgent
codingTeamNetwork o-- codeReviewerAgent
codingTeamNetwork o-- testEngineerAgent
codingTeamNetwork o-- refactoringAgent
codingA2ACoordinator o-- codeArchitectAgent
codingA2ACoordinator o-- codeReviewerAgent
codingA2ACoordinator o-- testEngineerAgent
codingA2ACoordinator o-- refactoringAgent
codeArchitectAgent --> codeAnalysisTool
codeArchitectAgent --> codeSearchTool
codeReviewerAgent --> codeAnalysisTool
codeReviewerAgent --> diffReviewTool
codeReviewerAgent --> codeSearchTool
testEngineerAgent --> codeAnalysisTool
testEngineerAgent --> testGeneratorTool
testEngineerAgent --> codeSearchTool
refactoringAgent --> multiStringEditTool
refactoringAgent --> codeAnalysisTool
refactoringAgent --> diffReviewTool
refactoringAgent --> codeSearchTool
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughThis PR introduces a comprehensive multi-agent coding system with planning documentation, four specialized coding agents (Architect, Reviewer, Test Engineer, Refactoring Specialist), a routing network coordinator, an A2A task orchestrator, and five coding tools (code analysis, search, diff review, multi-string edit, test generator) for collaborative code development tasks. Changes
Sequence DiagramsequenceDiagram
participant User
participant CodingTeamNetwork as Coding Team<br/>Network
participant SelectedAgent as Selected Agent<br/>(Specialist)
participant CodeTools as Code Tools
participant CodingA2ACoordinator as A2A<br/>Coordinator
participant MultiAgents as Multiple<br/>Agents
User->>CodingTeamNetwork: Submit coding task
activate CodingTeamNetwork
CodingTeamNetwork->>CodingTeamNetwork: Analyze intent & select agent
rect rgb(200, 220, 240)
note over CodingTeamNetwork: Single-Agent Path
CodingTeamNetwork->>SelectedAgent: Delegate task
activate SelectedAgent
SelectedAgent->>CodeTools: Request tool execution<br/>(analysis, search, edit, etc.)
activate CodeTools
CodeTools-->>SelectedAgent: Return results
deactivate CodeTools
SelectedAgent->>SelectedAgent: Process & synthesize results
SelectedAgent-->>User: Return output
deactivate SelectedAgent
end
rect rgb(240, 220, 200)
note over CodingTeamNetwork: Multi-Agent Path
CodingTeamNetwork->>CodingA2ACoordinator: Orchestrate parallel/sequential workflow
activate CodingA2ACoordinator
CodingA2ACoordinator->>MultiAgents: Decompose & distribute tasks
activate MultiAgents
MultiAgents->>CodeTools: Execute specialized tasks
activate CodeTools
CodeTools-->>MultiAgents: Return results
deactivate CodeTools
MultiAgents-->>CodingA2ACoordinator: Collect outputs
deactivate MultiAgents
CodingA2ACoordinator->>CodingA2ACoordinator: Synthesize & score results
CodingA2ACoordinator-->>User: Return coordinated output
deactivate CodingA2ACoordinator
end
deactivate CodingTeamNetwork
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🤖 Hi @ssdeanx, I've received your request, and I'm working on it now! You can track my progress in the logs for more details. |
Summary of ChangesHello @ssdeanx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands the framework's capabilities by integrating an AI-powered "Coding Team Network." This network allows for intelligent routing of software development tasks to specialized agents like architects, code reviewers, test engineers, and refactoring specialists. It also introduces a suite of powerful new tools for code analysis, searching, diff generation, multi-file editing, and automated test scaffolding, all coordinated by an A2A orchestrator to streamline complex development workflows. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details. |
Greptile OverviewGreptile SummaryThis PR introduces a comprehensive Coding Team Network feature that extends Mastra's multi-agent capabilities for software development workflows. The implementation includes four specialized coding agents (architect, reviewer, test engineer, refactoring), five new coding tools, an intelligent routing network, and an A2A coordinator for complex orchestration. The feature follows established Mastra patterns with proper Zod schemas, memory management, and telemetry configuration. Key additions include tools for code analysis, pattern searching, diff generation, multi-file editing, and test scaffolding, all designed to work together through the Important Files Changed
Confidence score: 3/5
Sequence DiagramsequenceDiagram
participant User
participant Network as codingTeamNetwork
participant Architect as codeArchitectAgent
participant Reviewer as codeReviewerAgent
participant TestEng as testEngineerAgent
participant Refactor as refactoringAgent
participant Tools as "Coding Tools"
participant A2A as codingA2ACoordinator
User->>Network: "Build new feature with tests and review"
Note over Network: Analyzes request and routing
Network->>Architect: "Design architecture for feature"
Architect->>Tools: codeAnalysisTool(existing codebase)
Architect->>Tools: codeSearchTool(existing patterns)
Tools-->>Architect: Analysis results
Architect-->>Network: Architecture design and plan
Network->>Refactor: "Implement based on architecture"
Refactor->>Tools: multiStringEditTool(implement changes)
Tools-->>Refactor: Implementation results
Refactor-->>Network: Implementation complete
par Parallel Review and Testing
Network->>Reviewer: "Review implemented code"
Reviewer->>Tools: codeAnalysisTool(quality check)
Reviewer->>Tools: diffReviewTool(compare changes)
Tools-->>Reviewer: Review findings
Reviewer-->>Network: Code review report
and
Network->>TestEng: "Generate tests for implementation"
TestEng->>Tools: testGeneratorTool(create Vitest tests)
Tools-->>TestEng: Generated test files
TestEng-->>Network: Test suite ready
end
Network-->>User: Complete feature package
Note over User,A2A: Alternative: Complex multi-agent coordination
User->>A2A: "coordinate_a2a_task(complex refactoring)"
A2A->>A2A: Orchestrate parallel agents
par Parallel A2A Coordination
A2A->>Architect: Architecture assessment
A2A->>Reviewer: Security and quality review
A2A->>TestEng: Coverage analysis
and
A2A->>Refactor: Safe refactoring plan
end
Architect-->>A2A: Architecture insights
Reviewer-->>A2A: Quality findings
TestEng-->>A2A: Coverage gaps
Refactor-->>A2A: Refactoring recommendations
A2A->>A2A: Synthesize all results
A2A-->>User: Comprehensive refactoring plan
|
There was a problem hiding this comment.
Additional Comments (1)
-
src/mastra/networks/index.ts, line 30-46 (link)style: The primary agent network instructions don't include routing logic for coding-related requests. Users may not discover the coding team network through the main routing agent.
Should the primary agent network be updated to route coding/development requests to the coding team network?
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
16 files reviewed, 7 comments
| context: contextObj, | ||
| }) | ||
|
|
||
| if (!isRegex) break |
There was a problem hiding this comment.
logic: Logic issue: breaking on non-regex searches means only one match per line is found. If multiple occurrences exist on the same line, they'll be missed. Should multiple matches on the same line be captured for non-regex searches?
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/code-search.tool.ts
Line: 134:134
Comment:
**logic:** Logic issue: breaking on non-regex searches means only one match per line is found. If multiple occurrences exist on the same line, they'll be missed. Should multiple matches on the same line be captured for non-regex searches?
How can I resolve this? If you propose a fix, please make it concise.| interface DiffHunk { | ||
| oldStart: number | ||
| oldLines: number | ||
| newStart: number | ||
| newLines: number | ||
| lines: string[] | ||
| } |
There was a problem hiding this comment.
style: DiffHunk interface duplicates the structure already defined in hunkSchema
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/diff-review.tool.ts
Line: 70:76
Comment:
**style:** DiffHunk interface duplicates the structure already defined in hunkSchema
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.| name: 'Coding A2A Coordinator', | ||
| description: 'A2A Coordinator that orchestrates multiple coding agents in parallel for complex development tasks like full feature development, comprehensive reviews, and refactoring with tests.', | ||
| instructions: ({ runtimeContext }) => { | ||
| const userId = runtimeContext.get('userId') |
There was a problem hiding this comment.
style: userId is extracted from runtimeContext but never used in the instructions
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/a2a/codingA2ACoordinator.ts
Line: 30:30
Comment:
**style:** userId is extracted from runtimeContext but never used in the instructions
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.| if (trimmed.startsWith('/*')) { | ||
| inBlockComment = !trimmed.includes('*/') | ||
| continue |
There was a problem hiding this comment.
logic: Block comment detection logic doesn't handle nested comments or comments that start and end on the same line with code
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/code-analysis.tool.ts
Line: 102:104
Comment:
**logic:** Block comment detection logic doesn't handle nested comments or comments that start and end on the same line with code
How can I resolve this? If you propose a fix, please make it concise.| } | ||
|
|
||
| // Match exported const arrow functions: export const name = (params) => | ||
| const exportConstRegex = /export\s+const\s+(\w+)\s*=\s*(async\s+)?\(([^)]*)\)(?:\s*:\s*([^=]+))?\s*=>/g |
There was a problem hiding this comment.
style: The regex pattern may not correctly handle arrow functions with type annotations before the arrow. Consider testing with export const name = (params): ReturnType => {}
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/test-generator.tool.ts
Line: 72:72
Comment:
**style:** The regex pattern may not correctly handle arrow functions with type annotations before the arrow. Consider testing with `export const name = (params): ReturnType => {}`
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.| const importNames = exportedFuncs.map(f => f.name).join(', ') | ||
|
|
||
| let content = `import { describe, it, expect, vi, beforeEach } from 'vitest' | ||
| import { ${importNames || moduleName} } from './${moduleName}' |
There was a problem hiding this comment.
logic: Import path uses relative import assuming test file is in same directory structure - this may break if outputPath places tests elsewhere
| import { ${importNames || moduleName} } from './${moduleName}' | |
| const relativePath = path.relative(path.dirname(testFile), path.dirname(sourceFile)) | |
| const importPath = relativePath ? path.join(relativePath, moduleName).replace(/\\/g, '/') : `./${moduleName}` | |
| let content = `import { describe, it, expect, vi, beforeEach } from 'vitest' | |
| import { ${importNames || moduleName} } from '${importPath}' | |
| ` |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/test-generator.tool.ts
Line: 188:188
Comment:
**logic:** Import path uses relative import assuming test file is in same directory structure - this may break if outputPath places tests elsewhere
```suggestion
const relativePath = path.relative(path.dirname(testFile), path.dirname(sourceFile))
const importPath = relativePath ? path.join(relativePath, moduleName).replace(/\\/g, '/') : `./${moduleName}`
let content = `import { describe, it, expect, vi, beforeEach } from 'vitest'
import { ${importNames || moduleName} } from '${importPath}'
`
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive Coding Team Network, a suite of powerful new tools for code analysis, modification, and test generation, and specialized agents for various software development tasks. The implementation is extensive and well-structured, following existing project patterns. The new tools are particularly impressive, with features like dry-run modes and backup/rollback capabilities that enhance safety and usability.
My review focuses on a few key areas for improvement:
- Correcting a critical route conflict in the server setup.
- Improving the accuracy of the code analysis and test generation tools by refining their parsing logic.
- Enhancing code quality and maintainability by leveraging existing dependencies and types consistently.
- Ensuring documentation is aligned with the implemented code.
Overall, this is a fantastic addition that significantly expands the capabilities of the framework. The detailed planning documents and thorough implementation are commendable.
| networkRoute({ | ||
| path: "/network", | ||
| agent: "codingTeamNetwork", | ||
| defaultOptions: { | ||
| memory: { | ||
| thread: { | ||
| id: 'coding-network', | ||
| resourceId: 'coding-network', | ||
| }, | ||
| resource: "coding-network", | ||
| options: | ||
| { semanticRecall: true, } | ||
| }, | ||
| maxSteps: 200, | ||
| telemetry: { | ||
| isEnabled: true, | ||
| recordInputs: true, | ||
| recordOutputs: true, | ||
| }, | ||
| includeRawChunks: true, | ||
| } | ||
| }), |
There was a problem hiding this comment.
You are adding a new networkRoute for codingTeamNetwork on the path /network. However, there are already four other network routes registered on the exact same path (/network) for different agents (agentNetwork, dataPipelineNetwork, etc.). This will likely cause routing conflicts, where only the last registered route for that path will be active. Each network should have a unique path to be addressable. For example, you could use /network/coding or a similar unique path.
networkRoute({
path: "/network/coding",
agent: "codingTeamNetwork",
defaultOptions: {
memory: {
thread: {
id: 'coding-network',
resourceId: 'coding-network',
},
resource: "coding-network",
options:
{ semanticRecall: true, }
},
maxSteps: 200,
telemetry: {
isEnabled: true,
recordInputs: true,
recordOutputs: true,
},
includeRawChunks: true,
}
}),| { regex: /TODO:/gi, message: 'TODO comment found', rule: 'no-todo', type: 'info' as const }, | ||
| { regex: /FIXME:/gi, message: 'FIXME comment found', rule: 'no-fixme', type: 'warning' as const }, | ||
| { regex: /HACK:/gi, message: 'HACK comment found', rule: 'no-hack', type: 'warning' as const }, | ||
| { regex: /any(?:\s|;|,|\))/g, message: 'Explicit any type', rule: 'no-explicit-any', type: 'warning' as const }, |
There was a problem hiding this comment.
The regular expression /any(?:\s|;|,|\))/g for detecting any types is too broad and will lead to many false positives. For example, it would match the word 'many'. To make it more accurate, you should use word boundaries (\b) to ensure you're matching the whole word any. A more robust regex might also look for context, like being used as a type annotation (e.g., : any).
| { regex: /any(?:\s|;|,|\))/g, message: 'Explicit any type', rule: 'no-explicit-any', type: 'warning' as const }, | |
| { regex: /\bany\b/g, message: 'Explicit any type', rule: 'no-explicit-any', type: 'warning' as const }, |
| function parseTypeScriptFunctions(content: string): ParsedFunction[] { | ||
| const functions: ParsedFunction[] = [] | ||
|
|
||
| // Match exported functions: export function name(params): type | ||
| const exportFuncRegex = /export\s+(async\s+)?function\s+(\w+)\s*\(([^)]*)\)(?:\s*:\s*([^{]+))?/g | ||
| let match: RegExpExecArray | null | ||
| while ((match = exportFuncRegex.exec(content)) !== null) { | ||
| functions.push({ | ||
| name: match[2], | ||
| isAsync: !!match[1], | ||
| isExported: true, | ||
| params: match[3] ? match[3].split(',').map(p => p.trim().split(':')[0].trim()).filter(Boolean) : [], | ||
| returnType: match[4]?.trim(), | ||
| }) | ||
| } | ||
|
|
||
| // Match exported const arrow functions: export const name = (params) => | ||
| const exportConstRegex = /export\s+const\s+(\w+)\s*=\s*(async\s+)?\(([^)]*)\)(?:\s*:\s*([^=]+))?\s*=>/g | ||
| while ((match = exportConstRegex.exec(content)) !== null) { | ||
| functions.push({ | ||
| name: match[1], | ||
| isAsync: !!match[2], | ||
| isExported: true, | ||
| params: match[3] ? match[3].split(',').map(p => p.trim().split(':')[0].trim()).filter(Boolean) : [], | ||
| returnType: match[4]?.trim(), | ||
| }) | ||
| } | ||
|
|
||
| // Match regular functions (not exported) | ||
| const funcRegex = /(?<!export\s+)(async\s+)?function\s+(\w+)\s*\(([^)]*)\)(?:\s*:\s*([^{]+))?/g | ||
| while ((match = funcRegex.exec(content)) !== null) { | ||
| const matchedName = match[2] | ||
| if (!functions.some(f => f.name === matchedName)) { | ||
| functions.push({ | ||
| name: matchedName, | ||
| isAsync: !!match[1], | ||
| isExported: false, | ||
| params: match[3] ? match[3].split(',').map(p => p.trim().split(':')[0].trim()).filter(Boolean) : [], | ||
| returnType: match[4]?.trim(), | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| return functions | ||
| } |
There was a problem hiding this comment.
The parseTypeScriptFunctions function does not seem to handle default exports (e.g., export default function myFunction() {} or export default myArrowFunc). The regular expressions only look for named exports (export function and export const). This means the tool will not generate tests for modules that use default exports, which is a common pattern. You should enhance the parsing logic to correctly identify default exports.
| **New Dependencies:** | ||
| ```json | ||
| { | ||
| "diff": "^7.0.0", |
|
|
||
| | Package | Purpose | Version | | ||
| |---------|---------|---------| | ||
| | `diff` | Generate unified diffs | ^7.0.0 | |
There was a problem hiding this comment.
| "devDependencies": { | ||
| "@tailwindcss/postcss": "^4.1.17", | ||
| "@testing-library/jest-dom": "^6.9.1", | ||
| "@types/diff": "^7.0.2", |
There was a problem hiding this comment.
| name: 'Coding A2A Coordinator', | ||
| description: 'A2A Coordinator that orchestrates multiple coding agents in parallel for complex development tasks like full feature development, comprehensive reviews, and refactoring with tests.', | ||
| instructions: ({ runtimeContext }) => { | ||
| const userId = runtimeContext.get('userId') |
| interface DiffHunk { | ||
| oldStart: number | ||
| oldLines: number | ||
| newStart: number | ||
| newLines: number | ||
| lines: string[] | ||
| } |
There was a problem hiding this comment.
The DiffHunk interface is being re-declared here. The diff package exports a Hunk type that you can import and use directly. You should import it (import { ..., Hunk } from 'diff') and use it instead of redefining it. This avoids type re-declaration and ensures your types are always in sync with the library. You can then cast structured.hunks as Hunk[].
| function generateSimpleDiff(original: string, modified: string, filePath: string): string { | ||
| const originalLines = original.split('\n') | ||
| const modifiedLines = modified.split('\n') | ||
|
|
||
| const diffLines: string[] = [`--- a/${path.basename(filePath)}`, `+++ b/${path.basename(filePath)}`] | ||
|
|
||
| let i = 0, j = 0 | ||
| while (i < originalLines.length || j < modifiedLines.length) { | ||
| if (i < originalLines.length && j < modifiedLines.length && originalLines[i] === modifiedLines[j]) { | ||
| diffLines.push(` ${originalLines[i]}`) | ||
| i++ | ||
| j++ | ||
| } else if (i < originalLines.length && (j >= modifiedLines.length || originalLines[i] !== modifiedLines[j])) { | ||
| diffLines.push(`-${originalLines[i]}`) | ||
| i++ | ||
| } else if (j < modifiedLines.length) { | ||
| diffLines.push(`+${modifiedLines[j]}`) | ||
| j++ | ||
| } | ||
| } | ||
|
|
||
| return diffLines.join('\n') | ||
| } |
There was a problem hiding this comment.
This generateSimpleDiff function is a custom implementation. Since the diff package is already a dependency in the project, you could replace this function by using createPatch from the diff library to generate a standard unified diff. This would be more robust and consistent with diff-review.tool.ts.
For example, inside the execute function:
import { createPatch } from 'diff';
// ...
const diff = createPatch(filePath, content, newContent);There was a problem hiding this comment.
Hey there - I've reviewed your changes - here's some feedback:
- In
test-generator.tool.ts, whentestStyleis not"describe-it"you emittest(...)calls but only importdescribe, it, expect, vi, beforeEachfrom Vitest, so you should either importtestor consistently useit(...)to avoid runtime reference errors. - You added
diffat version^8.0.2but@types/diffat^7.0.2; it would be safer to align the major versions (or rely on the bundled types if available) to avoid subtle type mismatches.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `test-generator.tool.ts`, when `testStyle` is not `"describe-it"` you emit `test(...)` calls but only import `describe, it, expect, vi, beforeEach` from Vitest, so you should either import `test` or consistently use `it(...)` to avoid runtime reference errors.
- You added `diff` at version `^8.0.2` but `@types/diff` at `^7.0.2`; it would be safer to align the major versions (or rely on the bundled types if available) to avoid subtle type mismatches.
## Individual Comments
### Comment 1
<location> `src/mastra/tools/multi-string-edit.tool.ts:181-48` </location>
<code_context>
+ }
+ }
+
+ if (hasFailure && !dryRun) {
+ for (const [filePath, backupPath] of appliedBackups) {
+ try {
+ await fs.copyFile(backupPath, filePath)
+ } catch {
+ // Best effort rollback
+ }
+ }
+ }
</code_context>
<issue_to_address>
**suggestion:** Rollback logic restores files from backups but leaves `.bak` files behind and still reports `success` as false even when state is fully rolled back.
Two suggestions:
- After restoring from `.bak` files, consider deleting the backups (or explicitly returning their paths) to avoid clutter and confusion for downstream tools.
- Because `success` is based only on `hasFailure`, callers can't tell whether the system ended in a clean, rolled-back state versus a partial/unknown state. Consider adding an explicit rollback indicator (e.g. `rolledBack: boolean`) or richer status so consumers can handle these cases differently.
</issue_to_address>
### Comment 2
<location> `src/mastra/tools/code-search.tool.ts:94-96` </location>
<code_context>
+ const filesWithMatches = new Set<string>()
+ let truncated = false
+
+ const searchRegex = isRegex
+ ? new RegExp(pattern, caseSensitive ? 'g' : 'gi')
+ : new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), caseSensitive ? 'g' : 'gi')
+
+ for (const filePath of filePaths) {
</code_context>
<issue_to_address>
**issue:** User-provided regex patterns are not validated, so an invalid pattern will throw and fail the entire search.
Since `new RegExp(pattern, ...)` throws on invalid input (e.g., unmatched `[`), a bad pattern will currently abort the whole run. Consider wrapping this construction in a try/catch and returning a structured error or empty result with an explanatory message so a single invalid pattern doesn’t crash the tool.
</issue_to_address>
### Comment 3
<location> `memory-bank/coding-team/prd.md:25` </location>
<code_context>
+**Acceptance Criteria:**
+- GIVEN a user describes a feature or change
+- WHEN the coding network routes to CodeArchitectAgent
+- THEN the agent analyzes existing patterns, proposes architecture, and generates implementation plan
+
+### US-2: Automated Code Review
</code_context>
<issue_to_address>
**suggestion (typo):** Consider adding an article before "implementation plan" for correct grammar.
Update the line to: "...proposes architecture, and generates an implementation plan."
```suggestion
- THEN the agent analyzes existing patterns, proposes architecture, and generates an implementation plan
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| return true | ||
| } catch { | ||
| return false | ||
| } |
There was a problem hiding this comment.
suggestion: Rollback logic restores files from backups but leaves .bak files behind and still reports success as false even when state is fully rolled back.
Two suggestions:
- After restoring from
.bakfiles, consider deleting the backups (or explicitly returning their paths) to avoid clutter and confusion for downstream tools. - Because
successis based only onhasFailure, callers can't tell whether the system ended in a clean, rolled-back state versus a partial/unknown state. Consider adding an explicit rollback indicator (e.g.rolledBack: boolean) or richer status so consumers can handle these cases differently.
| const searchRegex = isRegex | ||
| ? new RegExp(pattern, caseSensitive ? 'g' : 'gi') | ||
| : new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), caseSensitive ? 'g' : 'gi') |
There was a problem hiding this comment.
issue: User-provided regex patterns are not validated, so an invalid pattern will throw and fail the entire search.
Since new RegExp(pattern, ...) throws on invalid input (e.g., unmatched [), a bad pattern will currently abort the whole run. Consider wrapping this construction in a try/catch and returning a structured error or empty result with an explanatory message so a single invalid pattern doesn’t crash the tool.
| **Acceptance Criteria:** | ||
| - GIVEN a user describes a feature or change | ||
| - WHEN the coding network routes to CodeArchitectAgent | ||
| - THEN the agent analyzes existing patterns, proposes architecture, and generates implementation plan |
There was a problem hiding this comment.
suggestion (typo): Consider adding an article before "implementation plan" for correct grammar.
Update the line to: "...proposes architecture, and generates an implementation plan."
| - THEN the agent analyzes existing patterns, proposes architecture, and generates implementation plan | |
| - THEN the agent analyzes existing patterns, proposes architecture, and generates an implementation plan |
There was a problem hiding this comment.
Actionable comments posted: 34
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
package.json (1)
111-161: Remove @types/diff from devDependencies
diff@8.0.2ships with built-in TypeScript definitions.@types/diff@7.0.2is deprecated and conflicts with the package's bundled types. Remove@types/difffrom devDependencies so TypeScript uses the definitions provided bydiffitself.The
globdependency inoverridesis correctly placed—no direct imports ofglobwere found in the codebase, so it's appropriately managed as a transitive dependency.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (16)
README.md(1 hunks)memory-bank/coding-team/context.md(1 hunks)memory-bank/coding-team/design.md(1 hunks)memory-bank/coding-team/prd.md(1 hunks)memory-bank/coding-team/tasks.md(1 hunks)package.json(2 hunks)src/mastra/a2a/codingA2ACoordinator.ts(1 hunks)src/mastra/agents/codingAgents.ts(1 hunks)src/mastra/index.ts(4 hunks)src/mastra/networks/codingTeamNetwork.ts(1 hunks)src/mastra/networks/index.ts(1 hunks)src/mastra/tools/code-analysis.tool.ts(1 hunks)src/mastra/tools/code-search.tool.ts(1 hunks)src/mastra/tools/diff-review.tool.ts(1 hunks)src/mastra/tools/multi-string-edit.tool.ts(1 hunks)src/mastra/tools/test-generator.tool.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
**/*.{js,jsx,ts,tsx}: Usenext/dynamicfor dynamic imports to load components only when needed, improving initial load time.
Usenext/imagecomponent for automatic image optimization, including lazy loading and responsive images.
Use React.memo to prevent unnecessary re-renders of components.
Use the<Link prefetch>tag to prefetch pages that are likely to be visited.
Use getServerSideProps, getStaticProps, or server components for fetching data on the server-side.
Use SWR or React Query for client-side data fetching and caching.
Use CSS Modules, Styled Components, or Tailwind CSS for component-level styling. Prefer Tailwind CSS for rapid development.
Use React Context, Zustand, Jotai, or Recoil for managing global state. Avoid Redux unless necessary.
Usereact-hook-formfor managing forms and validation.
Only fetch the data that is needed by the component to avoid over-fetching.
Avoid long-running synchronous operations in the main thread to prevent blocking.
Always usesetStateor hooks to update state instead of mutating state directly.
Include a complete dependency array inuseEffecthooks to prevent unexpected behavior.
Avoid writing server-side code in client components to prevent exposing secrets or causing unexpected behavior.
Usetry...catchblocks for handling errors in asynchronous operations.
Implement error boundary components usinggetDerivedStateFromErrororcomponentDidCatchlifecycle methods.
Sanitize user input to prevent Cross-Site Scripting (XSS) attacks. Be especially careful when rendering HTML directly from user input.
Store authentication tokens in HTTP-only cookies or local storage securely.
Implement role-based access control to restrict access to sensitive resources.
Clean up event listeners and timers inuseEffecthooks to avoid memory leaks.
Only update state when necessary to reduce the number of re-renders and improve performance.
Use immutable data structures and avoid mutating data directly to prevent unexpected...
Files:
src/mastra/networks/codingTeamNetwork.tssrc/mastra/networks/index.tssrc/mastra/a2a/codingA2ACoordinator.tssrc/mastra/tools/code-search.tool.tssrc/mastra/agents/codingAgents.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/index.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
**/*.{js,ts}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use parameterized queries or an ORM to prevent SQL injection attacks.
Files:
src/mastra/networks/codingTeamNetwork.tssrc/mastra/networks/index.tssrc/mastra/a2a/codingA2ACoordinator.tssrc/mastra/tools/code-search.tool.tssrc/mastra/agents/codingAgents.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/index.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
src/mastra/networks/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
Add new agent networks under
src/mastra/networksto coordinate multiple agents
Files:
src/mastra/networks/codingTeamNetwork.tssrc/mastra/networks/index.ts
src/mastra/networks/*.ts
📄 CodeRabbit inference engine (src/mastra/networks/AGENTS.md)
src/mastra/networks/*.ts: Keep routing logic clear and deterministic in agent networks
Use specific trigger keywords for each agent in routing networks
Preserve context when passing between agents in networks
Log routing decisions for debugging in agent networks
Export network exports fromsrc/mastra/networks/index.tsand register insrc/mastra/index.ts
Files:
src/mastra/networks/codingTeamNetwork.tssrc/mastra/networks/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never commit API keys or secrets to the repository; use maskSensitiveMessageData() helper from src/mastra/config/pg-storage.ts when logging
Files:
src/mastra/networks/codingTeamNetwork.tssrc/mastra/networks/index.tssrc/mastra/a2a/codingA2ACoordinator.tssrc/mastra/tools/code-search.tool.tssrc/mastra/agents/codingAgents.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/index.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run eslint with --max-warnings=0 on src/**/*.{ts,tsx} to enforce linting standards
Files:
src/mastra/networks/codingTeamNetwork.tssrc/mastra/networks/index.tssrc/mastra/a2a/codingA2ACoordinator.tssrc/mastra/tools/code-search.tool.tssrc/mastra/agents/codingAgents.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/index.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
src/mastra/a2a/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use Agent-to-Agent (A2A) coordination in src/mastra/a2a for orchestrating multiple agents
Files:
src/mastra/a2a/codingA2ACoordinator.ts
src/mastra/tools/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
src/mastra/tools/**/*.ts: Use thecreateToolpattern with Zod schemas when adding new tools undersrc/mastra/tools
Use explicit Zod schemas for every tool input/output
src/mastra/tools/**/*.ts: Use Zod schemas for strict validation of tool inputs and outputs in all Mastra tools
Implement tools using the createTool({ id, inputSchema, outputSchema, execute }) pattern
Organize tools into categories: Financial (Polygon, Finnhub, AlphaVantage), Research (SerpAPI, ArXiv), Data (CSV, JSON), RAG (chunking, embeddings)
Files:
src/mastra/tools/code-search.tool.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
src/mastra/{tools,workflows}/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
Use
RuntimeContextto enforce access control in tools and workflows
Files:
src/mastra/tools/code-search.tool.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
src/mastra/tools/**/*.tool.ts
📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)
src/mastra/tools/**/*.tool.ts: Define Zod schema for inputs and outputs when creating tools
Tool IDs should follow the 'namespace:toolName' format (e.g., 'alpha-vantage:stockTool')
Files:
src/mastra/tools/code-search.tool.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
src/mastra/tools/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)
src/mastra/tools/**/*.{ts,tsx}: All tools must include comprehensive error handling with try-catch blocks, clear error messages, and retry logic for API calls
Sanitize inputs, mask secrets in logs, and implement rate-limiting in tools
Implement caching, stream large data, and set timeouts for external API calls in tools
Add Arize spans on all tool execute functions for observability
Files:
src/mastra/tools/code-search.tool.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/code-analysis.tool.tssrc/mastra/tools/test-generator.tool.tssrc/mastra/tools/diff-review.tool.ts
**/*.md
📄 CodeRabbit inference engine (.github/instructions/markdown.instructions.md)
**/*.md: Use appropriate heading levels (H2, H3, etc.) to structure markdown content. Do not use H1 headings, as these will be generated from the title. Use##for H2 and###for H3 in a hierarchical manner. Recommend restructuring if content includes H4 or higher levels.
Use bullet points (with-) or numbered lists (with1.) for lists in markdown. Indent nested lists with two spaces and ensure proper indentation and spacing.
Use fenced code blocks (triple backticks) for code snippets in markdown. Specify the language after the opening backticks for syntax highlighting (e.g.,csharp).
Use proper markdown syntax for links:[link text](URL). Ensure that link text is descriptive and URLs are valid and accessible.
Use proper markdown syntax for images:. Include a brief description of the image in the alt text for accessibility.
Use markdown tables (with|delimiters) for tabular data. Ensure proper formatting, alignment, and inclusion of headers.
Limit line length to 80 characters in markdown for readability. Use soft line breaks for long paragraphs.
Use appropriate whitespace in markdown to separate sections and improve readability. Use blank lines between sections and avoid excessive whitespace.
Include YAML front matter at the beginning of markdown files with required metadata fields:post_title,author1,post_slug,microsoft_alias,featured_image,categories(from /categories.txt),tags,ai_note,summary, andpost_date.
Files:
memory-bank/coding-team/prd.mdREADME.mdmemory-bank/coding-team/tasks.mdmemory-bank/coding-team/context.mdmemory-bank/coding-team/design.md
src/mastra/agents/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
Add new agent definitions under
src/mastra/agentsthat wire tools together into higher-level behaviors
Files:
src/mastra/agents/codingAgents.ts
src/mastra/agents/*.ts
📄 CodeRabbit inference engine (src/mastra/agents/AGENTS.md)
src/mastra/agents/*.ts: Agent file naming convention: Create agent files using kebab-case with.tsextension in/src/mastra/agents/directory (e.g.,your-agent-name.ts)
Each agent must follow the pattern: export agent asconst yourAgent = new Agent({ id: 'your-agent-id', name: 'Your Agent Name', description: '...' })
Files:
src/mastra/agents/codingAgents.ts
🧬 Code graph analysis (2)
src/mastra/a2a/codingA2ACoordinator.ts (5)
src/mastra/config/logger.ts (1)
log(14-18)lib/types/mastra-api.ts (1)
Agent(17-17)src/mastra/config/google.ts (2)
googleAI(55-55)googleAIFlashLite(69-69)src/mastra/config/pg-storage.ts (1)
pgMemory(81-127)src/mastra/scorers/custom-scorers.ts (1)
taskCompletionScorer(337-427)
src/mastra/agents/codingAgents.ts (4)
src/mastra/config/logger.ts (1)
log(14-18)lib/types/mastra-api.ts (1)
Agent(17-17)src/mastra/config/google.ts (3)
googleAI3(84-84)googleAI(55-55)googleAIFlashLite(69-69)src/mastra/config/pg-storage.ts (1)
pgMemory(81-127)
🪛 ast-grep (0.40.0)
src/mastra/tools/code-search.tool.ts
[warning] 94-94: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, caseSensitive ? 'g' : 'gi')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🪛 LanguageTool
memory-bank/coding-team/prd.md
[uncategorized] ~13-~13: The official name of this software platform is spelled with a capital “H”.
Context: ...asks - Existing tools (execa, pnpm, fs, github) are not integrated into a cohesive cod...
(GITHUB)
[grammar] ~94-~94: Use a hyphen to join words.
Context: ...t tool support undo/rollback? - [ ] Rate limiting strategy for GitHub API calls? ...
(QB_NEW_EN_HYPHEN)
README.md
[style] ~47-~47: Using many exclamation marks might seem excessive (in this case: 14 exclamation marks for a text that’s 9574 characters long)
Context: ...goColor=white)](https://ai.google.dev/) [
🪛 markdownlint-cli2 (0.18.1)
memory-bank/coding-team/context.md
39-39: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
53-53: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Agent
- GitHub Check: Sourcery review
- GitHub Check: Codacy Security Scan
🔇 Additional comments (12)
README.md (2)
5-5: Clarify heading hierarchy with respect to document structure.Per markdown style guidelines, use one H1 heading as the title of the document, with subsequent headings as H2 or deeper. The provided coding guidelines state not to use H1 headings, but best practices dictate each document should have only one H1 heading, typically serving as the main title, which stems from HTML semantic requirements. For a README file, starting with H1 for the main title then using H2 for major sections follows logical order.
The current H1 usage appears correct for the document's main title. However, verify with the team whether the coding guidelines are intended for documents with auto-generated title systems (e.g., blog posts with YAML frontmatter) or if READMEs should follow a different convention.
1-380: Excellent markdown structure and comprehensive documentation.The README demonstrates strong adherence to markdown best practices:
- Proper table formatting with pipe delimiters and headers (lines 55–64, 256–262, 299–307)
- Code blocks with language specification (bash, typescript, mermaid)
- Logical H2 heading hierarchy organizing major sections
- Descriptive links in proper markdown syntax
- Well-structured bullet points with consistent indentation
- Proper use of mermaid diagrams for visual architecture/flow representation
The content effectively communicates the AgentStack platform's capabilities, architecture, and developer experience. All major sections are present (Quick Start, Architecture, RAG Pipeline, A2A Flow, Development, Configuration, Testing, Security, Observability, Integrations, Resources, Roadmap).
src/mastra/networks/index.ts (1)
20-21: Wiring of codingTeamNetwork export looks goodExporting
codingTeamNetworkalongside the other networks is consistent with the existing pattern and keeps network discovery centralized.src/mastra/index.ts (1)
66-71: Coding team agents and network are wired correctly; multiple /network routes follow established patternThe imports and agent/network registrations are consistent with existing conventions:
codingTeamNetwork, the four coding agents, andcodingA2ACoordinatorare properly imported and exposed in the Mastra config agents map (lines 102–157).- The new
networkRouteat line 599 uses path/networkwith isolated memory thread/resourcecoding-network, mirroring existing routes foragentNetwork,dataPipelineNetwork,reportGenerationNetwork, andresearchPipelineNetwork(all also at path/network).The multiple
/networkroutes are a pre-existing pattern in the codebase (lines 511, 533, 555, 577, 599), not introduced by this change. Routing dispatch relies on the agent name field to differentiate routes.No hardcoded secrets or API keys found; environment variables are handled correctly.
src/mastra/a2a/codingA2ACoordinator.ts (1)
153-154: Emptytoolsandworkflowsobjects are intentional but could be omitted.The coordinator delegates work to sub-agents, so empty objects are acceptable. However, if these are optional in the Agent constructor, they could be removed for cleaner code.
src/mastra/agents/codingAgents.ts (3)
17-22: Well-defined runtime context types.The
CodingRuntimeContexttype provides good type safety for runtime context access. The type exports enable downstream code to properly type their context usage.
73-77: InconsistentthinkingBudgetconfiguration across agents.
codeArchitectAgentincludesthinkingBudget: -1in its thinkingConfig (lines 76-77), but other agents (codeReviewerAgent, testEngineerAgent, refactoringAgent) omit this property. Ensure this inconsistency is intentional.
89-92: Tool assignments align well with agent responsibilities.The
codeArchitectAgentis appropriately equipped withcodeAnalysisToolandcodeSearchToolfor architecture analysis. Each agent's tool set matches its documented capabilities.src/mastra/tools/code-analysis.tool.ts (4)
1-14: LGTM!The imports are appropriate for the tool's functionality, and the
fileExistshelper correctly uses try-catch for error handling.
16-56: LGTM!The Zod schemas are well-structured and comprehensive, following the coding guidelines for explicit schema definitions in Mastra tools. The type exports provide proper TypeScript integration.
58-83: LGTM!The language detection mapping is comprehensive and covers all major programming languages. The implementation is straightforward and handles unknown extensions gracefully.
117-138: LGTM!The complexity estimation approach is appropriate for a basic static analysis tool. While crude, it provides a reasonable approximation of cyclomatic complexity by counting decision points.
| # Context: Coding Team Network & Agents | ||
|
|
||
| ## Phase: PLANNING (Spec Complete) | ||
|
|
||
| ## Session: 2025-12-05 | ||
|
|
||
| ### Summary | ||
|
|
||
| Researched Mastra's network and A2A patterns using official docs and examples. Analyzed existing implementations in the project (businessLegalAgents.ts, dataPipelineNetwork.ts, a2aCoordinatorAgent.ts). Created comprehensive spec documents (PRD, Design, Tasks) for a multi-agent coding team. | ||
|
|
||
| ### Key Findings | ||
|
|
||
| #### How Mastra Networks Work | ||
| 1. **Agent Networks** are routing agents with sub-agents, workflows, and tools | ||
| 2. Use `agent.network()` method for LLM-based multi-primitive orchestration | ||
| 3. Memory is **required** for network capabilities | ||
| 4. Routing is based on agent/workflow/tool descriptions and input schemas | ||
| 5. Networks emit streaming events for progress tracking | ||
|
|
||
| #### How A2A Works | ||
| 1. **A2A Protocol** enables agent-to-agent communication | ||
| 2. Exposed via MCP server for external access | ||
| 3. Supports parallel orchestration using `Promise.all()` patterns | ||
| 4. Uses `sendMessage()` API returning tasks with status tracking | ||
| 5. Agents coordinate via message parts (text, data) | ||
|
|
||
| ### Decisions Made | ||
|
|
||
| | Decision | Choice | Rationale | | ||
| |----------|--------|-----------| | ||
| | Tool: Multi-edit | Atomic with backup | Safety for batch file operations | | ||
| | Tool: Code analysis | Regex-based (no AST) | Simpler, language-agnostic | | ||
| | Test framework | Vitest only | Project standard | | ||
| | Model selection | googleAI3 for complex tasks | Following businessLegalAgents pattern | | ||
| | New packages | `diff`, `glob` | Minimal additions, specific needs | | ||
|
|
||
| ### Architecture Confirmed | ||
|
|
||
| ``` | ||
| codingTeamNetwork (Router) | ||
| ├── codeArchitectAgent | ||
| ├── codeReviewerAgent | ||
| ├── testEngineerAgent | ||
| └── refactoringAgent | ||
|
|
||
| codingA2ACoordinator (Parallel Orchestrator) | ||
| └── Coordinates all 4 agents for complex tasks | ||
| ``` | ||
|
|
||
| ### Required Packages | ||
|
|
||
| **New Dependencies:** | ||
| ```json | ||
| { | ||
| "diff": "^7.0.0", | ||
| "glob": "^11.0.0" | ||
| } | ||
| ``` | ||
|
|
||
| **Existing Packages to Leverage:** | ||
| - `fs-extra` - Already in project for file operations | ||
| - `execa` - Already in project for shell commands (execaTool) | ||
| - `zod` - Schema validation (core dependency) | ||
| - `@mastra/core` - Agent, createTool, network APIs | ||
|
|
||
| ### Files to Create | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `src/mastra/tools/multi-string-edit.tool.ts` | Batch file editing | | ||
| | `src/mastra/tools/code-analysis.tool.ts` | Static analysis | | ||
| | `src/mastra/tools/test-generator.tool.ts` | Vitest scaffolds | | ||
| | `src/mastra/tools/diff-review.tool.ts` | Unified diff generation | | ||
| | `src/mastra/tools/code-search.tool.ts` | Pattern searching | | ||
| | `src/mastra/agents/codingAgents.ts` | 4 coding agents | | ||
| | `src/mastra/networks/codingTeamNetwork.ts` | Network router | | ||
| | `src/mastra/a2a/codingA2ACoordinator.ts` | A2A coordinator | | ||
|
|
||
| ### Blockers | ||
|
|
||
| - None identified | ||
|
|
||
| ### Open Questions | ||
|
|
||
| - [ ] Should multi-string-edit support undo/rollback? | ||
| - [ ] Maximum file size for code analysis? | ||
| - [ ] Rate limiting for GitHub API calls? | ||
|
|
||
| ### Next Steps | ||
|
|
||
| 1. User approval of spec | ||
| 2. Start Phase 1: Implement core tools (CODE-1 through CODE-5) | ||
| 3. Phase 2: Implement agents (CODE-6 through CODE-9) | ||
| 4. Phase 3: Network & A2A (CODE-10, CODE-11) | ||
| 5. Phase 4: Integration & docs (CODE-12, CODE-13) | ||
|
|
||
| --- | ||
|
|
||
| ## References | ||
|
|
||
| - [Mastra Networks Docs](agents/networks.mdx) | ||
| - [Agent.network() Reference](reference/agents/network.mdx) | ||
| - [A2A Example](examples/a2a) | ||
| - [businessLegalAgents.ts](src/mastra/agents/businessLegalAgents.ts) | ||
| - [dataPipelineNetwork.ts](src/mastra/networks/dataPipelineNetwork.ts) | ||
| - [a2aCoordinatorAgent.ts](src/mastra/a2a/a2aCoordinatorAgent.ts) | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add YAML front matter and avoid H1 headings in markdown
This doc currently starts with a # H1 and has no YAML front matter. Per repo markdown guidelines, please:
- Add the required YAML front matter block (
post_title,author1,post_slug, etc.) at the top. - Change the top-level heading to
##(and adjust subsequent levels accordingly) so H1 is reserved for the generated title.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
39-39: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
53-53: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 Prompt for AI Agents
In memory-bank/coding-team/context.md around lines 1 to 107, the document uses a
top-level H1 and lacks the required YAML front matter; add a YAML front matter
block at the very top containing the repo-required keys (e.g., post_title,
author1, post_slug, date, tags) and then change the current leading `# Context:
Coding Team Network & Agents` to `## Context: Coding Team Network & Agents` (and
demote any subsequent headings by one level) so that no H1 headings remain and
the generated title can be used.
| ``` | ||
| codingTeamNetwork (Router) | ||
| ├── codeArchitectAgent | ||
| ├── codeReviewerAgent | ||
| ├── testEngineerAgent | ||
| └── refactoringAgent | ||
|
|
||
| codingA2ACoordinator (Parallel Orchestrator) | ||
| └── Coordinates all 4 agents for complex tasks | ||
| ``` |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Specify a language for the architecture code block
The fenced block with the ASCII architecture diagram lacks a language, which triggers MD040. Consider tagging it as plain text:
-```
+```text
codingTeamNetwork (Router)
├── codeArchitectAgent
├── codeReviewerAgent
├── testEngineerAgent
└── refactoringAgent
codingA2ACoordinator (Parallel Orchestrator)
└── Coordinates all 4 agents for complex tasks🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
39-39: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In memory-bank/coding-team/context.md around lines 39 to 48, the fenced code
block containing the ASCII architecture diagram is missing a language tag which
triggers MD040; add a language specifier (use "text") to the opening fence so
the block is treated as plain text and linter warnings are resolved, e.g. change
``` to ```text at the start of the block and keep the closing fence unchanged.
| **New Dependencies:** | ||
| ```json | ||
| { | ||
| "diff": "^7.0.0", | ||
| "glob": "^11.0.0" | ||
| } | ||
| ``` |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add a blank line before the JSON code fence
Markdownlint (MD031) expects a blank line before fenced code blocks. Insert an empty line between the “New Dependencies:” line and the ```json fence:
-**New Dependencies:**
-```json
+**New Dependencies:**
+
+```json
{
"diff": "^7.0.0",
"glob": "^11.0.0"
}🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
53-53: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 Prompt for AI Agents
In memory-bank/coding-team/context.md around lines 52 to 58, there is no blank
line before the JSON fenced code block which violates MD031; add a single empty
line between the "**New Dependencies:**" line and the opening ```json fence so
the file reads a paragraph line, a blank line, then the ```json block.
| # Design: Coding Team Network & Agents | ||
|
|
||
| ## Overview | ||
|
|
||
| The Coding Team feature implements a multi-agent system for software development tasks using Mastra's agent network pattern for routing and A2A protocol for parallel orchestration. | ||
|
|
||
| ### Goals | ||
| - Create 4 specialized coding agents following existing patterns | ||
| - Build 5 coding-specific tools with Zod schemas | ||
| - Implement a CodingTeamNetwork for intelligent routing | ||
| - Add CodingA2ACoordinator for parallel task execution | ||
|
|
||
| ### Constraints | ||
| - Must follow existing agent patterns (businessLegalAgents.ts) | ||
| - Tools must use createTool with Zod input/output schemas | ||
| - Network follows dataPipelineNetwork.ts pattern | ||
| - Uses pgMemory and googleAI/googleAI3 from config | ||
|
|
||
| ## Architecture | ||
|
|
||
| ```mermaid | ||
| flowchart TB | ||
| subgraph Network["codingTeamNetwork"] | ||
| Router["Routing Agent<br/>Routes based on intent"] | ||
| end | ||
|
|
||
| subgraph Agents["Specialized Coding Agents"] | ||
| CA["codeArchitectAgent<br/>Design & Planning"] | ||
| CR["codeReviewerAgent<br/>Quality & Security"] | ||
| TE["testEngineerAgent<br/>Test Generation"] | ||
| RA["refactoringAgent<br/>Code Improvement"] | ||
| end | ||
|
|
||
| subgraph A2A["codingA2ACoordinator"] | ||
| Coord["Parallel Orchestration<br/>Complex Multi-Agent Tasks"] | ||
| end | ||
|
|
||
| subgraph Tools["Coding Tools"] | ||
| MSE["multiStringEditTool<br/>Multi-file editing"] | ||
| CAT["codeAnalysisTool<br/>Static analysis"] | ||
| TGT["testGeneratorTool<br/>Test scaffolding"] | ||
| DRT["diffReviewTool<br/>Change analysis"] | ||
| CST["codeSearchTool<br/>Pattern search"] | ||
| end | ||
|
|
||
| User --> Network | ||
| User --> A2A | ||
| Router --> CA & CR & TE & RA | ||
| Coord --> CA & CR & TE & RA | ||
| CA & CR & TE & RA --> Tools | ||
| ``` | ||
|
|
||
| ## Data Models | ||
|
|
||
| ### MultiStringEdit Input/Output | ||
|
|
||
| ```typescript | ||
| // inputSchema | ||
| const multiStringEditInput = z.object({ | ||
| edits: z.array(z.object({ | ||
| filePath: z.string().describe("Absolute path to the file"), | ||
| oldString: z.string().describe("Exact text to replace"), | ||
| newString: z.string().describe("Replacement text"), | ||
| description: z.string().optional().describe("Why this change") | ||
| })), | ||
| dryRun: z.boolean().default(false).describe("Preview without applying"), | ||
| createBackup: z.boolean().default(true).describe("Create .bak files") | ||
| }) | ||
|
|
||
| // outputSchema | ||
| const multiStringEditOutput = z.object({ | ||
| success: z.boolean(), | ||
| results: z.array(z.object({ | ||
| filePath: z.string(), | ||
| status: z.enum(["applied", "skipped", "failed"]), | ||
| reason: z.string().optional(), | ||
| backup: z.string().optional() | ||
| })), | ||
| summary: z.object({ | ||
| total: z.number(), | ||
| applied: z.number(), | ||
| skipped: z.number(), | ||
| failed: z.number() | ||
| }) | ||
| }) | ||
| ``` | ||
|
|
||
| ### CodeAnalysis Output | ||
|
|
||
| ```typescript | ||
| const codeAnalysisOutput = z.object({ | ||
| files: z.array(z.object({ | ||
| path: z.string(), | ||
| language: z.string(), | ||
| loc: z.number(), | ||
| complexity: z.number(), | ||
| issues: z.array(z.object({ | ||
| type: z.enum(["error", "warning", "info"]), | ||
| line: z.number(), | ||
| message: z.string(), | ||
| rule: z.string().optional() | ||
| })) | ||
| })), | ||
| summary: z.object({ | ||
| totalFiles: z.number(), | ||
| totalLoc: z.number(), | ||
| avgComplexity: z.number(), | ||
| issueCount: z.record(z.string(), z.number()) | ||
| }) | ||
| }) | ||
| ``` | ||
|
|
||
| ### TestGeneration Output | ||
|
|
||
| ```typescript | ||
| const testGenerationOutput = z.object({ | ||
| tests: z.array(z.object({ | ||
| testFile: z.string(), | ||
| sourceFile: z.string(), | ||
| framework: z.literal("vitest"), | ||
| content: z.string(), | ||
| coverage: z.object({ | ||
| functions: z.array(z.string()), | ||
| branches: z.number().optional() | ||
| }) | ||
| })), | ||
| runCommand: z.string() | ||
| }) | ||
| ``` | ||
|
|
||
| ## API Contracts | ||
|
|
||
| ### Agent Instructions Pattern | ||
|
|
||
| Each coding agent follows the RuntimeContext pattern from businessLegalAgents.ts: | ||
|
|
||
| ```typescript | ||
| instructions: ({ runtimeContext }) => { | ||
| const userTier = runtimeContext.get('user-tier') ?? 'free' | ||
| const language = runtimeContext.get('language') ?? 'en' | ||
| return { | ||
| role: 'system', | ||
| content: `...`, | ||
| providerOptions: { | ||
| google: { | ||
| structuredOutput: true, | ||
| thinkingConfig: { | ||
| thinkingLevel: userTier === 'enterprise' ? 'high' : 'medium', | ||
| includeThoughts: true, | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Network Routing Pattern | ||
|
|
||
| Following dataPipelineNetwork.ts structure: | ||
|
|
||
| ```typescript | ||
| // Routing triggers | ||
| - Architecture: "design", "architect", "plan", "structure" | ||
| - Review: "review", "check", "analyze", "audit" | ||
| - Testing: "test", "coverage", "spec", "unit test" | ||
| - Refactoring: "refactor", "improve", "optimize", "clean" | ||
| ``` | ||
|
|
||
| ## Tech Decisions | ||
|
|
||
| | Decision | Choice | Rationale | | ||
| |----------|--------|-----------| | ||
| | Code Analysis | AST-free, regex-based | Simpler, language-agnostic, no heavy parser deps | | ||
| | Multi-edit Atomicity | All-or-nothing with backup | Safer for batch operations | | ||
| | Test Framework | Vitest only | Already project standard | | ||
| | Model Selection | googleAI3 for complex, googleAIFlashLite for simple | Cost/quality balance | | ||
| | File Operations | fs-extra + existing fsTool patterns | Consistency with existing tools | | ||
| | Search | grep-based via execa | Leverage existing execaTool | | ||
|
|
||
| ## Risks & Mitigations | ||
|
|
||
| | Risk | Likelihood | Impact | Mitigation | | ||
| |------|------------|--------|------------| | ||
| | Multi-edit conflicts | Medium | High | Backup files, dry-run mode, atomic operations | | ||
| | Large file handling | Medium | Medium | File size limits, chunked processing | | ||
| | Path traversal | Low | High | Strict path validation, project boundary checks | | ||
| | API rate limits | Medium | Low | Caching, request throttling | | ||
|
|
||
| ## File Structure | ||
|
|
||
| ``` | ||
| src/mastra/ | ||
| ├── tools/ | ||
| │ ├── multi-string-edit.tool.ts # Multi-file editing | ||
| │ ├── code-analysis.tool.ts # Static analysis | ||
| │ ├── test-generator.tool.ts # Vitest generation | ||
| │ ├── diff-review.tool.ts # Change analysis | ||
| │ └── code-search.tool.ts # Pattern search | ||
| ├── agents/ | ||
| │ └── codingAgents.ts # All 4 coding agents | ||
| ├── networks/ | ||
| │ └── codingTeamNetwork.ts # Network router | ||
| └── a2a/ | ||
| └── codingA2ACoordinator.ts # Parallel orchestrator | ||
| ``` | ||
|
|
||
| ## Dependencies (New Packages) | ||
|
|
||
| | Package | Purpose | Version | | ||
| |---------|---------|---------| | ||
| | `diff` | Generate unified diffs | ^7.0.0 | | ||
| | `glob` | File pattern matching | ^11.0.0 | | ||
|
|
||
| Existing packages to leverage: | ||
| - `fs-extra` - File operations | ||
| - `execa` - Shell commands | ||
| - `zod` - Schema validation | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Bring design.md in line with markdown conventions (front matter, headings)
To match the markdown guidelines:
- Add the required YAML front matter block at the top of the file.
- Replace the top-level
# Design: ...with##and adjust subsequent headings so there is no H1 in the body.
🤖 Prompt for AI Agents
In memory-bank/coding-team/design.md around lines 1 to 218, the file uses a
top-level H1 and lacks the required YAML front matter; update the file by
inserting the required YAML front matter block at the very top (with any
required metadata keys per project guidelines), then change the existing
top-level "# Design: Coding Team Network & Agents" to "## Design: Coding Team
Network & Agents" and demote all subsequent heading levels by one (e.g., "##" →
"###", "###" → "####", etc.) so the document contains no H1 headings in the body
and conforms to the markdown conventions.
| ``` | ||
| src/mastra/ | ||
| ├── tools/ | ||
| │ ├── multi-string-edit.tool.ts # Multi-file editing | ||
| │ ├── code-analysis.tool.ts # Static analysis | ||
| │ ├── test-generator.tool.ts # Vitest generation | ||
| │ ├── diff-review.tool.ts # Change analysis | ||
| │ └── code-search.tool.ts # Pattern search | ||
| ├── agents/ | ||
| │ └── codingAgents.ts # All 4 coding agents | ||
| ├── networks/ | ||
| │ └── codingTeamNetwork.ts # Network router | ||
| └── a2a/ | ||
| └── codingA2ACoordinator.ts # Parallel orchestrator | ||
| ``` |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Annotate the file-structure code block with a language
The directory layout block is fenced but missing a language. Tag it as text for clarity and to satisfy MD040:
-```
+```text
src/mastra/
├── tools/
│ ├── multi-string-edit.tool.ts # Multi-file editing
...
└── a2a/
└── codingA2ACoordinator.ts # Parallel orchestrator🤖 Prompt for AI Agents
In memory-bank/coding-team/design.md around lines 191 to 205, the fenced
directory layout block is missing a language tag which triggers MD040; update
the opening fence to include a language (use "text") so the block is explicitly
annotated (e.g., change "```" to "```text") and keep the rest of the block
unchanged.
| export const multiStringEditTool = createTool({ | ||
| id: 'coding:multiStringEdit', | ||
| description: `Apply multiple string replacements across files atomically. | ||
| Each edit specifies a file path, the exact text to find, and the replacement text. | ||
| Supports dry-run mode to preview changes and automatic backup creation. | ||
| Use for batch refactoring, multi-file updates, and coordinated code changes.`, |
There was a problem hiding this comment.
Description claims atomic operation but implementation is not truly atomic.
The description states "Apply multiple string replacements across files atomically" but the implementation applies edits sequentially. If an edit fails mid-way, previous edits remain applied (even with rollback, only backup restoration is attempted). True atomicity would require all-or-nothing semantics.
Consider clarifying the description:
-description: `Apply multiple string replacements across files atomically.
+description: `Apply multiple string replacements across files with rollback support.
Each edit specifies a file path, the exact text to find, and the replacement text.
-Supports dry-run mode to preview changes and automatic backup creation.
+Supports dry-run mode to preview changes and automatic backup creation with best-effort rollback on failure.
Use for batch refactoring, multi-file updates, and coordinated code changes.`,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const multiStringEditTool = createTool({ | |
| id: 'coding:multiStringEdit', | |
| description: `Apply multiple string replacements across files atomically. | |
| Each edit specifies a file path, the exact text to find, and the replacement text. | |
| Supports dry-run mode to preview changes and automatic backup creation. | |
| Use for batch refactoring, multi-file updates, and coordinated code changes.`, | |
| export const multiStringEditTool = createTool({ | |
| id: 'coding:multiStringEdit', | |
| description: `Apply multiple string replacements across files with rollback support. | |
| Each edit specifies a file path, the exact text to find, and the replacement text. | |
| Supports dry-run mode to preview changes and automatic backup creation with best-effort rollback on failure. | |
| Use for batch refactoring, multi-file updates, and coordinated code changes.`, |
🤖 Prompt for AI Agents
In src/mastra/tools/multi-string-edit.tool.ts around lines 81 to 86, the
description incorrectly claims the edits are applied "atomically" while the
implementation performs sequential edits with best-effort rollback; update the
description to remove or qualify "atomically" and accurately describe the
behavior (sequential application, dry-run preview, automatic backups, and that
rollback attempts to restore backups but may not guarantee full rollback on
certain failures), or alternatively implement true atomic semantics by preparing
all changes in temp files and performing atomic renames only after all edits
succeed; choose one approach and adjust the description to match the actual
behavior.
| if (hasFailure && !dryRun) { | ||
| for (const [filePath, backupPath] of appliedBackups) { | ||
| try { | ||
| await fs.copyFile(backupPath, filePath) | ||
| } catch { | ||
| // Best effort rollback | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Rollback logic has edge cases and backup files are never cleaned up.
- If an early edit succeeds but a later edit fails (even for boundary violation), the successful edit is rolled back - this may be unexpected
- Backup
.bakfiles are created but never cleaned up on success, leaving orphaned files
Consider cleaning up backup files on full success:
+ // Clean up backup files on success
+ if (!hasFailure && !dryRun) {
+ for (const [, backupPath] of appliedBackups) {
+ try {
+ await fs.unlink(backupPath)
+ } catch {
+ // Best effort cleanup
+ }
+ }
+ }
+
if (hasFailure && !dryRun) {
for (const [filePath, backupPath] of appliedBackups) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (hasFailure && !dryRun) { | |
| for (const [filePath, backupPath] of appliedBackups) { | |
| try { | |
| await fs.copyFile(backupPath, filePath) | |
| } catch { | |
| // Best effort rollback | |
| } | |
| } | |
| } | |
| // Clean up backup files on success | |
| if (!hasFailure && !dryRun) { | |
| for (const [, backupPath] of appliedBackups) { | |
| try { | |
| await fs.unlink(backupPath) | |
| } catch { | |
| // Best effort cleanup | |
| } | |
| } | |
| } | |
| if (hasFailure && !dryRun) { | |
| for (const [filePath, backupPath] of appliedBackups) { | |
| try { | |
| await fs.copyFile(backupPath, filePath) | |
| } catch { | |
| // Best effort rollback | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/mastra/tools/multi-string-edit.tool.ts around lines 181 to 189, the
rollback currently restores all applied files on any failure and never removes
the .bak backups; change it so that on partial failure you only restore the
subset of files that were actually modified (use appliedBackups to determine
which files were written), and after recovery remove their backup files; on full
success (and for dryRun no-ops) delete all created backup files so no .bak
orphans remain; ensure errors during restore or delete are caught and logged as
best-effort but do not throw.
| function parseTypeScriptFunctions(content: string): ParsedFunction[] { | ||
| const functions: ParsedFunction[] = [] | ||
|
|
||
| // Match exported functions: export function name(params): type | ||
| const exportFuncRegex = /export\s+(async\s+)?function\s+(\w+)\s*\(([^)]*)\)(?:\s*:\s*([^{]+))?/g | ||
| let match: RegExpExecArray | null | ||
| while ((match = exportFuncRegex.exec(content)) !== null) { | ||
| functions.push({ | ||
| name: match[2], | ||
| isAsync: !!match[1], | ||
| isExported: true, | ||
| params: match[3] ? match[3].split(',').map(p => p.trim().split(':')[0].trim()).filter(Boolean) : [], | ||
| returnType: match[4]?.trim(), | ||
| }) | ||
| } | ||
|
|
||
| // Match exported const arrow functions: export const name = (params) => | ||
| const exportConstRegex = /export\s+const\s+(\w+)\s*=\s*(async\s+)?\(([^)]*)\)(?:\s*:\s*([^=]+))?\s*=>/g | ||
| while ((match = exportConstRegex.exec(content)) !== null) { | ||
| functions.push({ | ||
| name: match[1], | ||
| isAsync: !!match[2], | ||
| isExported: true, | ||
| params: match[3] ? match[3].split(',').map(p => p.trim().split(':')[0].trim()).filter(Boolean) : [], | ||
| returnType: match[4]?.trim(), | ||
| }) | ||
| } | ||
|
|
||
| // Match regular functions (not exported) | ||
| const funcRegex = /(?<!export\s+)(async\s+)?function\s+(\w+)\s*\(([^)]*)\)(?:\s*:\s*([^{]+))?/g | ||
| while ((match = funcRegex.exec(content)) !== null) { | ||
| const matchedName = match[2] | ||
| if (!functions.some(f => f.name === matchedName)) { | ||
| functions.push({ | ||
| name: matchedName, | ||
| isAsync: !!match[1], | ||
| isExported: false, | ||
| params: match[3] ? match[3].split(',').map(p => p.trim().split(':')[0].trim()).filter(Boolean) : [], | ||
| returnType: match[4]?.trim(), | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| return functions | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Regex-based TypeScript parsing is fragile and incomplete.
The regex patterns won't correctly parse:
- Generic functions:
export function foo<T>(x: T): T - Functions with default parameters:
export function foo(x = 5) - Multi-line function signatures
- Class methods and static methods
- Arrow functions assigned to non-const variables
This is acceptable for a scaffold generator but should be documented as a limitation.
Consider adding a comment documenting limitations:
+/**
+ * Parse TypeScript functions using regex patterns.
+ * Limitations: Does not handle generics, default parameters, multi-line signatures,
+ * class methods, or complex TypeScript syntax. For comprehensive parsing,
+ * consider using TypeScript compiler API or ts-morph.
+ */
function parseTypeScriptFunctions(content: string): ParsedFunction[] {🤖 Prompt for AI Agents
In src/mastra/tools/test-generator.tool.ts around lines 55 to 99, the current
regex-based parseTypeScriptFunctions is fragile and doesn't handle generics,
default parameters, multi-line signatures, class/static methods, or arrow
functions assigned to non-const variables; add a concise comment immediately
above the function documenting these limitations (list the specific unsupported
cases and an example for each) and note that this is an intentional
lightweight/scaffold approach and that a proper TypeScript parser (e.g.,
ts-morph or TypeScript compiler API) should be used if full fidelity is required
in the future.
| // Edge case tests | ||
| if (options.includeEdgeCases !== false) { | ||
| if (func.params.length > 0) { | ||
| tests.push({ | ||
| name: `${func.name} - should handle empty/null inputs`, | ||
| type: 'edge-case', | ||
| code: ` it('should handle edge cases', ${asyncPrefix}() => { | ||
| // Test with undefined/null inputs | ||
| ${func.isAsync ? 'await ' : ''}expect(() => ${func.name}(${func.params.map(() => 'undefined').join(', ')})).not.toThrow() | ||
| })`, | ||
| }) | ||
| } | ||
|
|
||
| if (func.isAsync) { | ||
| tests.push({ | ||
| name: `${func.name} - should handle async errors`, | ||
| type: 'edge-case', | ||
| code: ` it('should handle async errors gracefully', async () => { | ||
| // Test error handling | ||
| // TODO: Mock dependencies to throw and verify error handling | ||
| expect(true).toBe(true) | ||
| })`, | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Edge case tests may produce misleading results.
The generated edge case test (line 152-155) assumes functions shouldn't throw with undefined inputs, which isn't always true. The async error test (lines 163-167) always passes with expect(true).toBe(true), providing no actual coverage.
These are acceptable for scaffolding with TODO markers, but consider adding more prominent warnings:
tests.push({
name: `${func.name} - should handle empty/null inputs`,
type: 'edge-case',
code: ` it('should handle edge cases', ${asyncPrefix}() => {
- // Test with undefined/null inputs
+ // TODO: Review this test - not all functions should accept undefined inputs
+ // Adjust expectations based on function requirements
${func.isAsync ? 'await ' : ''}expect(() => ${func.name}(${func.params.map(() => 'undefined').join(', ')})).not.toThrow()
})`,
})| let content = `import { describe, it, expect, vi, beforeEach } from 'vitest' | ||
| import { ${importNames || moduleName} } from './${moduleName}' |
There was a problem hiding this comment.
Import path is incorrect when test file is in __tests__ subdirectory.
The import uses ./${moduleName} (line 188), but when the default output path places tests in __tests__/ (line 256), the correct import should be ../${moduleName}. This will cause module resolution failures.
-import { ${importNames || moduleName} } from './${moduleName}'
+// Calculate relative import based on test file locationThe fix requires computing the relative path from testFile to sourceFile:
+function getRelativeImportPath(testFile: string, sourceFile: string): string {
+ const testDir = path.dirname(testFile)
+ const sourceDir = path.dirname(sourceFile)
+ const sourceName = path.basename(sourceFile, path.extname(sourceFile))
+ let relativePath = path.relative(testDir, sourceDir)
+ if (!relativePath.startsWith('.')) {
+ relativePath = './' + relativePath
+ }
+ return path.join(relativePath, sourceName).replace(/\\/g, '/')
+}Also applies to: 254-256
🤖 Prompt for AI Agents
In src/mastra/tools/test-generator.tool.ts around lines 187-188 (also applies to
lines 254-256), the test template always uses a hardcoded import path like
./${moduleName}, which breaks when the generated test file is placed in a
__tests__ subdirectory; compute the correct relative import from the testFile
location to the sourceFile instead of assuming ./ — use path utilities to derive
a relative path, normalize it to start with ./ or ../ as appropriate and strip
any file extension so the import resolves correctly, and replace the hardcoded
./${moduleName} occurrences with this computed relative path.
There was a problem hiding this comment.
Pull request overview
This PR implements a comprehensive coding team network system that introduces specialized AI agents for software development tasks. The implementation follows Mastra's established patterns for agents, tools, and networks, creating a coordinated multi-agent system for code architecture, review, testing, and refactoring.
Key Changes:
- 5 new coding tools with Zod validation for code analysis, search, testing, editing, and diff generation
- 4 specialized coding agents for architecture, code review, testing, and refactoring
- Network routing layer for intelligent agent delegation based on user intent
- A2A coordinator for parallel orchestration of complex multi-agent workflows
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 21 comments.
Show a summary per file
| File | Description |
|---|---|
src/mastra/tools/test-generator.tool.ts |
Generates Vitest test scaffolds with edge case support; has async test generation issues |
src/mastra/tools/multi-string-edit.tool.ts |
Multi-file string replacement with backup; has critical rollback and atomicity issues |
src/mastra/tools/diff-review.tool.ts |
Unified diff generation using the diff library |
src/mastra/tools/code-search.tool.ts |
Pattern search across codebases with regex support; has regex state management issues |
src/mastra/tools/code-analysis.tool.ts |
Static analysis for LOC, complexity, and pattern detection; has language-specific pattern bugs |
src/mastra/agents/codingAgents.ts |
Four specialized agents with RuntimeContext-based configuration and tier-based model selection |
src/mastra/networks/codingTeamNetwork.ts |
Routing network with detailed instructions for agent delegation based on keywords and context |
src/mastra/a2a/codingA2ACoordinator.ts |
A2A coordinator for parallel multi-agent orchestration with workflow pattern documentation |
src/mastra/index.ts |
Integration of new agents and network with routing configuration |
src/mastra/networks/index.ts |
Export addition for coding team network |
package.json & package-lock.json |
Added diff package and type definitions for new dependencies |
memory-bank/coding-team/*.md |
Comprehensive planning documents (PRD, design, tasks, context) |
README.md |
Updated badges and documentation with new agent/tool counts |
Comments suppressed due to low confidence (2)
src/mastra/a2a/codingA2ACoordinator.ts:30
- Unused variable userId.
const userId = runtimeContext.get('userId')
src/mastra/tools/test-generator.tool.ts:125
- Unused variable moduleName.
const moduleName = path.basename(sourceFile, path.extname(sourceFile))
| function generateSimpleDiff(original: string, modified: string, filePath: string): string { | ||
| const originalLines = original.split('\n') | ||
| const modifiedLines = modified.split('\n') | ||
|
|
||
| const diffLines: string[] = [`--- a/${path.basename(filePath)}`, `+++ b/${path.basename(filePath)}`] | ||
|
|
||
| let i = 0, j = 0 | ||
| while (i < originalLines.length || j < modifiedLines.length) { | ||
| if (i < originalLines.length && j < modifiedLines.length && originalLines[i] === modifiedLines[j]) { | ||
| diffLines.push(` ${originalLines[i]}`) | ||
| i++ | ||
| j++ | ||
| } else if (i < originalLines.length && (j >= modifiedLines.length || originalLines[i] !== modifiedLines[j])) { | ||
| diffLines.push(`-${originalLines[i]}`) | ||
| i++ | ||
| } else if (j < modifiedLines.length) { | ||
| diffLines.push(`+${modifiedLines[j]}`) | ||
| j++ | ||
| } | ||
| } | ||
|
|
||
| return diffLines.join('\n') | ||
| } |
There was a problem hiding this comment.
The generateSimpleDiff function implements a naive line-by-line diff that doesn't handle moved or reordered lines correctly. Since the tool already uses the diff package for other purposes (imported but unused here), consider using createPatch from the diff package instead of this custom implementation for more accurate diffs.
| { regex: /console\.log\(/g, message: 'Console statement found', rule: 'no-console', type: 'warning' as const }, | ||
| { regex: /debugger/g, message: 'Debugger statement found', rule: 'no-debugger', type: 'error' as const }, | ||
| { regex: /TODO:/gi, message: 'TODO comment found', rule: 'no-todo', type: 'info' as const }, | ||
| { regex: /FIXME:/gi, message: 'FIXME comment found', rule: 'no-fixme', type: 'warning' as const }, | ||
| { regex: /HACK:/gi, message: 'HACK comment found', rule: 'no-hack', type: 'warning' as const }, | ||
| { regex: /any(?:\s|;|,|\))/g, message: 'Explicit any type', rule: 'no-explicit-any', type: 'warning' as const }, | ||
| { regex: /==(?!=)/g, message: 'Loose equality used', rule: 'eqeqeq', type: 'warning' as const }, | ||
| { regex: /\bvar\b/g, message: 'var keyword used (prefer const/let)', rule: 'no-var', type: 'info' as const }, | ||
| ] | ||
|
|
||
| for (let i = 0; i < lines.length; i++) { | ||
| const line = lines[i] | ||
|
|
||
| for (const pattern of patterns) { | ||
| if ((language === 'typescript' || language === 'javascript') || pattern.rule === 'no-todo' || pattern.rule === 'no-fixme' || pattern.rule === 'no-hack') { |
There was a problem hiding this comment.
The pattern detection logic applies TypeScript/JavaScript-specific patterns (like 'any' type, 'var' keyword) to all languages when the rule is TODO/FIXME/HACK. This means Python or Rust code will be checked for TypeScript patterns, generating false positives. The condition should check language appropriateness for each pattern, not just for comment-based patterns.
| { regex: /console\.log\(/g, message: 'Console statement found', rule: 'no-console', type: 'warning' as const }, | |
| { regex: /debugger/g, message: 'Debugger statement found', rule: 'no-debugger', type: 'error' as const }, | |
| { regex: /TODO:/gi, message: 'TODO comment found', rule: 'no-todo', type: 'info' as const }, | |
| { regex: /FIXME:/gi, message: 'FIXME comment found', rule: 'no-fixme', type: 'warning' as const }, | |
| { regex: /HACK:/gi, message: 'HACK comment found', rule: 'no-hack', type: 'warning' as const }, | |
| { regex: /any(?:\s|;|,|\))/g, message: 'Explicit any type', rule: 'no-explicit-any', type: 'warning' as const }, | |
| { regex: /==(?!=)/g, message: 'Loose equality used', rule: 'eqeqeq', type: 'warning' as const }, | |
| { regex: /\bvar\b/g, message: 'var keyword used (prefer const/let)', rule: 'no-var', type: 'info' as const }, | |
| ] | |
| for (let i = 0; i < lines.length; i++) { | |
| const line = lines[i] | |
| for (const pattern of patterns) { | |
| if ((language === 'typescript' || language === 'javascript') || pattern.rule === 'no-todo' || pattern.rule === 'no-fixme' || pattern.rule === 'no-hack') { | |
| { regex: /console\.log\(/g, message: 'Console statement found', rule: 'no-console', type: 'warning' as const, languages: ['javascript', 'typescript'] }, | |
| { regex: /debugger/g, message: 'Debugger statement found', rule: 'no-debugger', type: 'error' as const, languages: ['javascript', 'typescript'] }, | |
| { regex: /TODO:/gi, message: 'TODO comment found', rule: 'no-todo', type: 'info' as const, languages: ['*'] }, | |
| { regex: /FIXME:/gi, message: 'FIXME comment found', rule: 'no-fixme', type: 'warning' as const, languages: ['*'] }, | |
| { regex: /HACK:/gi, message: 'HACK comment found', rule: 'no-hack', type: 'warning' as const, languages: ['*'] }, | |
| { regex: /any(?:\s|;|,|\))/g, message: 'Explicit any type', rule: 'no-explicit-any', type: 'warning' as const, languages: ['typescript'] }, | |
| { regex: /==(?!=)/g, message: 'Loose equality used', rule: 'eqeqeq', type: 'warning' as const, languages: ['javascript', 'typescript'] }, | |
| { regex: /\bvar\b/g, message: 'var keyword used (prefer const/let)', rule: 'no-var', type: 'info' as const, languages: ['javascript', 'typescript'] }, | |
| ] | |
| for (let i = 0; i < lines.length; i++) { | |
| const line = lines[i] | |
| for (const pattern of patterns) { | |
| if ( | |
| pattern.languages.includes('*') || | |
| pattern.languages.includes(language) | |
| ) { |
| context: contextObj, | ||
| }) | ||
|
|
||
| if (!isRegex) break |
There was a problem hiding this comment.
The break statement exits the inner loop when !isRegex, which means only the first match per line is captured for non-regex searches. While this might be intentional, it's inconsistent with regex searches that capture all matches. Consider documenting this behavior or making it consistent across both search modes.
| if (!isRegex) break | |
| // Removed break to capture all matches per line for both regex and non-regex searches |
| try { | ||
| await fs.copyFile(backupPath, filePath) | ||
| } catch { | ||
| // Best effort rollback |
There was a problem hiding this comment.
The comment "Best effort rollback" explains WHAT the code does (attempting to rollback) but not WHY empty catch blocks are acceptable here. According to coding guidelines, comments should explain WHY. Consider adding context like "// Silently ignore rollback failures to avoid masking the original error" to explain the reasoning behind this error-swallowing pattern.
| }) | ||
|
|
||
| // Edge case tests | ||
| if (options.includeEdgeCases !== false) { |
There was a problem hiding this comment.
The condition options.includeEdgeCases !== false is redundant because the default value is already true in the schema (line 19). This can be simplified to if (options.includeEdgeCases) or removed entirely since the default handles this case.
| if (options.includeEdgeCases !== false) { | |
| if (options.includeEdgeCases) { |
| for (let i = 0; i < lines.length; i++) { | ||
| const line = lines[i] | ||
|
|
||
| for (const pattern of patterns) { | ||
| if ((language === 'typescript' || language === 'javascript') || pattern.rule === 'no-todo' || pattern.rule === 'no-fixme' || pattern.rule === 'no-hack') { | ||
| if (pattern.regex.test(line)) { | ||
| issues.push({ | ||
| type: pattern.type, | ||
| line: i + 1, | ||
| message: pattern.message, | ||
| rule: pattern.rule, | ||
| }) | ||
| } | ||
| pattern.regex.lastIndex = 0 | ||
| } | ||
| } |
There was a problem hiding this comment.
The regex patterns are tested against every line in a nested loop without caching or pre-compilation optimization. Each pattern's lastIndex is reset (line 168), but the patterns are recreated on every function call. Consider moving pattern definitions outside the function or memoizing them for better performance on large codebases.
| options: | ||
| { semanticRecall: true, } |
There was a problem hiding this comment.
The indentation for the options property is inconsistent (excessive leading spaces). This should be aligned with the parent object structure for better readability.
| name: 'Coding A2A Coordinator', | ||
| description: 'A2A Coordinator that orchestrates multiple coding agents in parallel for complex development tasks like full feature development, comprehensive reviews, and refactoring with tests.', | ||
| instructions: ({ runtimeContext }) => { | ||
| const userId = runtimeContext.get('userId') |
There was a problem hiding this comment.
'userId' is assigned a value but never used.
| const userId = runtimeContext.get('userId') |
| return { loc, totalLines } | ||
| } | ||
|
|
||
| function estimateComplexity(content: string, language: string): number { |
There was a problem hiding this comment.
'language' is defined but never used.
| function estimateComplexity(content: string, language: string): number { | |
| function estimateComplexity(content: string): number { |
| options: { includeEdgeCases?: boolean; testStyle?: string } | ||
| ): z.infer<typeof testCaseSchema>[] { | ||
| const tests: z.infer<typeof testCaseSchema>[] = [] | ||
| const moduleName = path.basename(sourceFile, path.extname(sourceFile)) |
There was a problem hiding this comment.
'moduleName' is assigned a value but never used.
| const moduleName = path.basename(sourceFile, path.extname(sourceFile)) |
codingTeamNetworkagent to coordinate specialized coding agents for software development tasks, including architecture, code review, testing, and refactoring.code-analysis.tool.tsfor analyzing source code files, calculating metrics, and detecting issues.code-search.tool.tsfor searching patterns across source files with support for regex and context lines.diff-review.tool.tsto generate and analyze unified diffs between code versions, providing structured diff data and statistics.multi-string-edit.tool.tsfor applying multiple string replacements across files with options for dry runs and backup creation.test-generator.tool.tsto generate Vitest test scaffolds for TypeScript/JavaScript source files, including edge case tests and mock setups for external dependencies.Summary by Sourcery
Add a specialized Coding Team multi-agent network with orchestration for architecture, review, testing, and refactoring, along with supporting code analysis, search, diff review, multi-file edit, and test generation tools.
New Features:
Enhancements:
Build: