Appearance
AI Workflow
AgentReady Stack is built from the ground up for AI-assisted development. Point Claude, Cursor, or ChatGPT at this codebase and watch them write code that actually works.
The Core Idea
Most codebases fail with AI agents because:
- AI doesn't know your architecture
- AI creates types that don't match your backend
- AI puts code in the wrong places
- AI-generated code breaks your tests
AgentReady Stack solves this with AGENTS.md—a comprehensive guide that AI agents read before writing code. When Claude reads your codebase, it reads AGENTS.md first and follows the patterns.
The AGENTS.md File
At the root of the repository, AGENTS.md contains instructions for AI agents:
markdown
# INSTRUCTIONS FOR AI AGENTS
When writing code for this repository, you MUST strictly adhere
to the following architectural constraints...How Different AI Tools Discover AGENTS.md
| Tool | Discovery Method |
|---|---|
| Claude Code | Reads CLAUDE.md automatically, which references AGENTS.md |
| Cursor | Reads .cursorrules which summarizes and references AGENTS.md |
| ChatGPT/Other | Reads README.md which prominently links to AGENTS.md |
All three discovery files are configured to direct agents to AGENTS.md for complete guidelines.
The Golden Rule: Type Flow
The most important pattern in AgentReady Stack:
Backend DTOs → OpenAPI → Generated Client → Frontend/CLIAI agents must never:
- Create duplicate types in the frontend
- Manually write API response interfaces
- Skip running
pnpm codegenafter backend changes
AI agents should always:
- Define types as DTOs in the backend first
- Use
@ApiProperty()decorators for OpenAPI - Import types from
@platform/api-client
Feature Scaffolding Workflow
When you ask an AI to add a new feature, it follows this order:
1. Create Backend DTOs
typescript
// apps/api/src/products/dto/create-product.dto.ts
export class CreateProductDto {
@ApiProperty()
@IsString()
name!: string;
@ApiPropertyOptional()
@IsNumber()
price?: number;
}2. Create Backend Module
typescript
// apps/api/src/products/products.controller.ts
@ApiTags('Products')
@Controller('products')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class ProductsController {
@Post()
async create(@Body() dto: CreateProductDto) {
return this.service.create(dto);
}
}3. Create Database Entity
typescript
// packages/database/src/entities/product.entity.ts
@Entity()
export class ProductEntity extends BaseEntity {
@Property()
name!: string;
@Property({ nullable: true })
price?: number;
}4. Regenerate API Client
bash
pnpm codegen5. Create Frontend Route
typescript
// apps/web/app/routes/products.tsx
export async function loader({ request }: Route.LoaderArgs) {
const session = await requireUser(request);
const products = await getProducts(session.accessToken);
return { products };
}
export default function Products() {
const { products } = useLoaderData<typeof loader>();
return <ProductList items={products} />;
}6. (Optional) Create CLI Command
typescript
// apps/cli/src/commands/products/list.ts
export default class ListProducts extends AuthenticatedCommand {
async run() {
const products = await this.apiClient.getProducts();
this.table(products, { name: {}, price: {} });
}
}Layer-Specific Patterns
Backend Rules
| Rule | Why |
|---|---|
Always use @UseGuards(JwtAuthGuard) on protected endpoints | Security |
| Transform entities to DTOs in controllers | Never leak database structure |
| Use class-validator decorators | Automatic validation |
Add @ApiProperty() decorators | OpenAPI generation |
Frontend Rules
| Rule | Why |
|---|---|
Fetch data in loader, never in useEffect | SSR and performance |
Mutations in action functions | React Router pattern |
Use typeof loader for type inference | Type safety |
| Return errors from actions, don't throw | Better UX |
CLI Rules
| Rule | Why |
|---|---|
Extend AuthenticatedCommand for protected commands | Automatic credential handling |
Use ApiClient class for API calls | Consistent auth headers |
| No business logic in command files | Separation of concerns |
Testing Patterns
AI agents write tests that follow these patterns:
Backend Unit Tests
typescript
describe('ProductsService', () => {
let service: ProductsService;
let mockRepo: ReturnType<typeof createMockRepository>;
beforeEach(async () => {
mockRepo = createMockRepository();
const module = await Test.createTestingModule({
providers: [
ProductsService,
{ provide: getRepositoryToken(ProductEntity), useValue: mockRepo },
],
}).compile();
service = module.get(ProductsService);
});
it('should create a product', async () => {
mockRepo.create.mockReturnValue({ id: '1', name: 'Test' });
const result = await service.create({ name: 'Test' });
expect(result.name).toBe('Test');
});
});Frontend Component Tests
typescript
vi.mock('react-router', async () => {
const actual = await vi.importActual('react-router');
return {
...actual,
useLoaderData: () => ({ products: [{ id: '1', name: 'Test' }] }),
};
});
describe('Products', () => {
it('renders product list', () => {
render(<Products />);
expect(screen.getByText('Test')).toBeInTheDocument();
});
});Common Commands Reference
AI agents use these commands frequently:
bash
# Start development
pnpm dev
# After changing backend DTOs
pnpm codegen
# Type check everything
pnpm typecheck
# Run all tests
pnpm test
# Run E2E tests
pnpm test:e2e
# Start specific app
pnpm --filter @platform/api dev
pnpm --filter @platform/web devTips for Working with AI
- Be specific about the layer: "Add a backend endpoint" vs "Add a frontend page"
- Mention the type flow: "Create the DTO first, then I'll run codegen"
- Reference existing patterns: "Follow the organization module pattern"
- Ask for tests: "Include unit tests following the existing patterns"
The Result
With AgentReady Stack:
- AI writes code that fits — No more fighting hallucinations
- Tests catch mistakes — AI-generated code is verified automatically
- Types stay in sync — Change once, propagate everywhere
- You ship faster — Hours instead of weeks
Example Prompts That Work
Here are prompts you can give Claude right after setup:
"Add a projects feature similar to organizations. Projects belong to
an organization and have a name, description, and status.""Create a CLI command to list all projects in the current organization.""Add a frontend page that shows all projects with a create button."Claude will read AGENTS.md, understand the patterns, and write code that fits.