AI developer agents with specializations, ticket assignment, and team coordination
Agents & Dev Teams
The @codmir/ai agents module provides DeveloperAgent and DevTeam classes for creating AI developers that work on tickets, review code, and collaborate as a team.
Installation
import {
DeveloperAgent,
DevTeam,
createDeveloper,
createDevTeam,
DEVELOPER_PROFILES,
} from "@codmir/ai";Quick Start
import { createDevTeam, DEVELOPER_PROFILES } from "@codmir/ai";
const team = createDevTeam({
name: "Core Team",
projectContext: {
projectId: "codmir",
name: "Codmir",
techStack: ["TypeScript", "Next.js", "NestJS", "Prisma"],
},
developers: [
DEVELOPER_PROFILES.alex, // fullstack lead
DEVELOPER_PROFILES.sam, // frontend specialist
DEVELOPER_PROFILES.jordan, // backend specialist
DEVELOPER_PROFILES.riley, // testing specialist
],
autoAssign: true,
requirePeerReview: true,
});
// Queue a ticket
team.queueTicket({
id: "TICKET-42",
title: "Fix login form validation",
description: "Email field accepts invalid formats",
type: "bug",
priority: "high",
status: "open",
relatedFiles: ["src/components/LoginForm.tsx"],
acceptanceCriteria: ["Email validation uses RFC 5322 regex"],
createdAt: new Date(),
updatedAt: new Date(),
});
// Auto-assign picks the best available developer
const breakdown = await team.tryAssignNextTicket();
// breakdown.plan => [{ order: 1, description: "Analyze requirements...", type: "analyze" }, ...]DeveloperAgent
createDeveloper(profileOrId, projectContext): DeveloperAgent
Creates a developer agent from a profile object or a built-in profile ID.
import { createDeveloper, DEVELOPER_PROFILES } from "@codmir/ai";
// From built-in profile
const alex = createDeveloper("alex", projectContext);
// From custom profile
const custom = createDeveloper(
{
id: "aria",
name: "Aria",
specialization: "frontend",
skills: ["React", "CSS", "Accessibility", "Design Systems"],
experience: "senior",
personality: "Design-focused, accessibility advocate",
},
projectContext,
);DeveloperAgentConfig
interface DeveloperAgentConfig {
profile: DeveloperProfile;
projectContext: ProjectContext;
maxConcurrentTasks?: number;
autoCommit?: boolean;
requireReview?: boolean;
}Methods
assignTicket(ticket): Promise<TaskBreakdown>
Assigns a ticket to this developer. Analyzes the ticket and returns a task breakdown with ordered steps.
const breakdown = await developer.assignTicket(ticket);
console.log(breakdown.plan);
// [
// { order: 1, description: "Analyze requirements and existing code", type: "analyze" },
// { order: 2, description: "Implement the solution", type: "implement" },
// { order: 3, description: "Write tests", type: "test" },
// { order: 4, description: "Self-review and refactor", type: "review" },
// ]work(): Promise<void>
Starts working on the currently assigned ticket. Throws if no ticket is assigned.
await developer.work();review(code, context?): Promise<ReviewResult>
Reviews code and returns approval status, comments, and suggestions.
const result = await developer.review(codeString, "Checkout flow refactor");
// {
// approved: true,
// comments: [{ file: "checkout.tsx", line: 42, message: "Missing null check", severity: "error" }],
// suggestions: ["Consider extracting validation logic into a hook"],
// }getStatus(): DeveloperAgentState
Returns the developer's current state.
const status = developer.getStatus();
// {
// id: "abc123",
// profile: { name: "Alex", specialization: "fullstack", ... },
// status: "coding", // "idle" | "analyzing" | "coding" | "testing" | "reviewing" | "blocked"
// currentTicket: { ... },
// workLog: [...],
// metrics: { ticketsCompleted: 5, linesWritten: 1200, ... },
// }block(reason): void
Marks the developer as blocked with a reason.
complete(): void
Marks the current ticket as complete and returns the developer to idle.
DeveloperMetrics
interface DeveloperMetrics {
tasksCompleted: number;
tokensUsed: number;
averageResponseTime: number;
successRate: number;
ticketsCompleted: number;
linesWritten: number;
testsWritten: number;
bugsFixed: number;
reviewsCompleted: number;
}DevTeam
createDevTeam(config): DevTeam
Creates a team of AI developers.
const team = createDevTeam({
name: "Platform Team",
projectContext: { ... },
developers: [DEVELOPER_PROFILES.alex, DEVELOPER_PROFILES.riley],
maxSize: 6,
requirePeerReview: true,
autoAssign: true,
});DevTeamConfig
interface DevTeamConfig {
name: string;
projectContext: ProjectContext;
developers?: DeveloperProfile[]; // defaults to [alex, riley]
maxSize?: number;
requirePeerReview?: boolean;
autoAssign?: boolean;
}Team Management
addDeveloper(profile): DeveloperAgent
Adds a developer to the team. Throws if the team is at max capacity.
const dev = team.addDeveloper(DEVELOPER_PROFILES.morgan);removeDeveloper(id): boolean
Removes a developer by ID. Throws if the developer has an active ticket. Returns false if the developer was not found.
team.removeDeveloper(dev.id);getDevelopers(): DeveloperAgent[]
Returns all developers on the team.
findBySpecialization(spec): DeveloperAgent[]
Finds developers by specialization.
const frontendDevs = team.findBySpecialization("frontend");getIdleDevelopers(): DeveloperAgent[]
Returns all developers with "idle" status.
Ticket Management
queueTicket(ticket): void
Adds a ticket to the queue. If autoAssign is enabled, immediately attempts assignment.
queueTickets(tickets): void
Adds multiple tickets to the queue.
assignTicket(ticketId, developerId): Promise<TaskBreakdown>
Manually assigns a specific ticket to a specific developer.
const breakdown = await team.assignTicket("TICKET-42", developer.id);tryAssignNextTicket(): Promise<TaskBreakdown | null>
Auto-assigns the highest-priority queued ticket to the best available developer. Returns null if no tickets or no idle developers.
The matching algorithm:
- Sorts tickets by priority (
critical>high>medium>low) - Maps ticket type to preferred specializations:
featureprefersfullstack,frontend,backendbugprefersfullstack,backend,frontendrefactorprefersfullstack,performancedocsprefersdocumentation,fullstacktestpreferstesting,fullstackchoreprefersdevops,fullstack
- Falls back to any idle developer
completeTicket(ticketId): void
Marks a ticket as complete. Notifies the assigned developer.
getPendingTickets(): Ticket[]
Returns all tickets in the queue.
getActiveTickets(): Ticket[]
Returns all tickets currently being worked on.
Collaboration
requestReview(code, requesterId, context?): Promise<ReviewResult[]>
Requests code reviews from up to 2 idle developers (excluding the requester).
const reviews = await team.requestReview(code, developer.id, "Auth refactor");
// [{ reviewerId: "...", reviewerName: "Riley", approved: true, comments: [...] }]standup(): StandupReport
Generates a standup report for the entire team.
const report = team.standup();
// {
// timestamp: Date,
// teamName: "Core Team",
// members: [{ id, name, status, currentTicket, metrics }],
// queueSize: 3,
// activeTickets: 2,
// completedToday: 1,
// }getMetrics(): TeamMetrics
Returns aggregate team metrics.
interface TeamMetrics {
totalTicketsCompleted: number;
averageTicketTime: number;
teamVelocity: number;
codeQualityScore: number;
}Built-in Developer Profiles
The DEVELOPER_PROFILES constant provides pre-configured developer personas.
| ID | Name | Specialization | Skills | Experience |
|---|---|---|---|---|
alex | Alex | fullstack | TypeScript, React, Node.js, PostgreSQL | senior |
sam | Sam | frontend | React, CSS, Tailwind, Accessibility | senior |
jordan | Jordan | backend | Node.js, Python, APIs, Databases | senior |
casey | Casey | devops | Docker, Kubernetes, CI/CD, AWS | senior |
riley | Riley | testing | Jest, Playwright, TDD, E2E Testing | mid |
morgan | Morgan | security | Security Audits, OWASP, Pen Testing | senior |
import { DEVELOPER_PROFILES } from "@codmir/ai";
const alex = DEVELOPER_PROFILES.alex;
// { id: "alex", name: "Alex", specialization: "fullstack", skills: [...], experience: "senior" }Types
DeveloperSpecialization
type DeveloperSpecialization =
| "fullstack"
| "frontend"
| "backend"
| "devops"
| "security"
| "performance"
| "testing"
| "documentation";DeveloperProfile
interface DeveloperProfile {
id: string;
name: string;
specialization: DeveloperSpecialization;
skills: string[];
experience: string;
personality?: string;
}Ticket
interface Ticket {
id: string;
title: string;
description: string;
type: "feature" | "bug" | "refactor" | "docs" | "test" | "chore";
priority: TicketPriority; // "critical" | "high" | "medium" | "low"
status: TicketStatus; // "open" | "in_progress" | "review" | "done" | "blocked"
relatedFiles?: string[];
acceptanceCriteria?: string[];
labels?: string[];
estimate?: number;
assignee?: string;
parentId?: string;
subtasks?: string[];
source?: string;
externalId?: string;
createdAt: Date;
updatedAt: Date;
}TaskBreakdown
interface TaskBreakdown {
ticket: Ticket;
plan: TaskStep[];
estimatedDuration: number;
risks?: string[];
dependencies?: string[];
}
interface TaskStep {
order: number;
description: string;
type: "analyze" | "implement" | "test" | "review" | "document";
files?: string[];
completed: boolean;
output?: string;
}