Agent Capability Analysis
The codigo-limpo skill by konecty is an open-source community AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance.
Ideal Agent Persona
Perfect for Code Review Agents needing adherence to clean code principles like KISS and YAGNI.
Core Value
Empowers agents to maintain simplicity through clear function responsibilities, direct logic, and avoidance of premature abstractions, ensuring code readability and reducing complexity by only implementing necessary features.
↓ Capabilities Granted for codigo-limpo
! Prerequisites & Limits
- Requires adherence to specific coding principles
- May not be suitable for rapid prototyping or proof-of-concept development
Browser Sandbox Environment
⚡️ Ready to unleash?
Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.
codigo-limpo
Install codigo-limpo, an AI agent skill for AI agent workflows and automation. Works with Claude Code, Cursor, and Windsurf with one-command setup.
Código Limpo - Konecty Backend
Princípios Fundamentais
KISS (Keep It Simple, Stupid)
Mantenha simples. Simplicidade é a maior sofisticação.
- Funções com uma responsabilidade clara
- Lógica direta e fácil de entender
- Evite abstrações prematuras
- Se parece complexo, provavelmente está errado
YAGNI (You Aren't Gonna Need It)
Não implemente o que não precisa agora.
- Resolva o problema atual, não problemas futuros hipotéticos
- Adicionar complexidade só quando comprovadamente necessária
- É mais fácil adicionar depois do que remover agora
DRY (Don't Repeat Yourself)
Não se repita.
- Extraia lógica duplicada em funções/módulos
- Use middlewares para lógica compartilhada
- Constantes em arquivos de configuração
SOLID
Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
- S: Um módulo/função = uma responsabilidade
- O: Aberto para extensão, fechado para modificação
- L: Subtipos devem ser substituíveis por seus tipos base
- I: Interfaces pequenas e específicas
- D: Dependa de abstrações, não de implementações concretas
Regras de Código
1. prefer-const
Sempre use const, nunca let (exceto quando mutação é necessária).
typescript1// ❌ Errado 2let users = []; 3for (let i = 0; i < results.length; i++) { 4 users.push(results[i]); 5} 6 7// ✅ Correto 8const users = results.map(result => result);
Por quê?
- Previne mutações acidentais
- Código mais previsível
- Facilita debugging
2. Programação Funcional
Use map, reduce, filter, flatMap ao invés de for loops.
typescript1// ❌ Errado 2let activeUsers = []; 3for (let i = 0; i < users.length; i++) { 4 if (users[i].active) { 5 activeUsers.push(users[i].id); 6 } 7} 8 9// ✅ Correto 10const activeUsers = users 11 .filter(user => user.active) 12 .map(user => user.id);
Por quê?
- Mais expressivo e declarativo
- Menos propenso a erros
- Melhor para composição
3. Evitar while(true)
Nunca use while(true). Prefira recursão ou condições explícitas.
typescript1// ❌ Errado 2while (true) { 3 const job = await queue.getNext(); 4 if (!job) break; 5 await processJob(job); 6} 7 8// ✅ Correto (Recursivo) 9const processQueue = async (): Promise<void> => { 10 const job = await queue.getNext(); 11 if (!job) return; 12 await processJob(job); 13 return processQueue(); 14}; 15 16// ✅ Correto (Iterativo com condição explícita) 17let hasMoreJobs = true; 18while (hasMoreJobs) { 19 const job = await queue.getNext(); 20 hasMoreJobs = job !== null; 21 if (hasMoreJobs) { 22 await processJob(job); 23 } 24}
4. no-magic-numbers
Todos os números devem ser constantes nomeadas.
typescript1// ❌ Errado 2if (users.length > 100) { 3 await sendEmail(admin, 'Too many users'); 4} 5setTimeout(retry, 5000); 6 7// ✅ Correto 8const MAX_USERS_BEFORE_ALERT = 100; 9const RETRY_DELAY_MS = 5000; 10 11if (users.length > MAX_USERS_BEFORE_ALERT) { 12 await sendEmail(admin, 'Too many users'); 13} 14setTimeout(retry, RETRY_DELAY_MS);
Constantes Comuns:
typescript1// Tempo 2const MILLISECONDS_PER_SECOND = 1000; 3const SECONDS_PER_MINUTE = 60; 4const MINUTES_PER_HOUR = 60; 5const HOURS_PER_DAY = 24; 6 7// Database 8const DEFAULT_PAGE_SIZE = 20; 9const MAX_PAGE_SIZE = 100; 10const CONNECTION_POOL_SIZE = 10; 11 12// API 13const DEFAULT_TIMEOUT_MS = 30_000; 14const MAX_RETRIES = 3; 15const RATE_LIMIT_PER_MINUTE = 60;
5. Controle de Concorrência Assíncrona
⚠️ Nota: Bluebird está deprecated em 2026. Use alternativas modernas abaixo.
Problema: Executar múltiplas operações assíncronas com controle de paralelismo.
Opção 1: p-limit (Recomendada)
typescript1import pLimit from 'p-limit'; 2 3const API_CONCURRENCY = 5; 4 5const sendEmails = async (users: User[]): Promise<void> => { 6 const limit = pLimit(API_CONCURRENCY); 7 8 await Promise.all( 9 users.map(user => limit(() => sendEmail(user))) 10 ); 11};
Vantagens: Simples, mantido, funcional puro.
Opção 2: Chunking Funcional (Sem Dependências)
typescript1const chunk = <T>(array: T[], size: number): T[][] => 2 Array.from( 3 { length: Math.ceil(array.length / size) }, 4 (_, index) => array.slice(index * size, (index + 1) * size) 5 ); 6 7const DB_BATCH_SIZE = 10; 8 9const processDocuments = async (docs: Document[]): Promise<void> => { 10 const chunks = chunk(docs, DB_BATCH_SIZE); 11 12 await chunks.reduce( 13 async (previousBatch, currentChunk) => { 14 await previousBatch; 15 return Promise.all(currentChunk.map(processDoc)); 16 }, 17 Promise.resolve([]) 18 ); 19};
Vantagens: Sem dependências, funcional.
Opção 3: Bluebird (Legado - Deprecated)
typescript1// ⚠️ NÃO USE EM CÓDIGO NOVO - Apenas para manutenção de código legado 2import Bluebird from 'bluebird'; 3 4const CONCURRENCY_LIMIT = 5; 5await Bluebird.map(users, sendEmail, { concurrency: CONCURRENCY_LIMIT });
Limites de Concorrência Recomendados
typescript1// Operações de Banco de Dados 2const DB_CONCURRENCY = 10; 3 4// Chamadas de API Externa 5const API_CONCURRENCY = 5; 6 7// Operações de I/O (arquivos) 8const IO_CONCURRENCY = 3; 9 10// Processamento Pesado (CPU-bound) 11const CPU_CONCURRENCY = 2;
Comparação
| Opção | Prós | Contras | Quando Usar |
|---|---|---|---|
| p-limit | Simples, mantido | Dependência externa | Padrão para novo código |
| Chunking | Sem deps, funcional | Mais verbose | Projetos sem dependências extras |
| Bluebird | - | Deprecated | Apenas código legado |
Quando aplicar controle de concorrência:
- ✅ Processar múltiplos documentos do DB
- ✅ Fazer múltiplas chamadas HTTP
- ✅ Processar múltiplos arquivos
- ❌ Operações muito rápidas (< 10ms)
- ❌ Já existe controle no destino (pool do DB)
Padrões Node.js/TypeScript Backend
Async/Await
Sempre prefira async/await sobre callbacks.
typescript1// ❌ Evite callbacks 2db.find({ active: true }, (err, users) => { 3 if (err) return handleError(err); 4 processUsers(users); 5}); 6 7// ✅ Use async/await 8const findActiveUsers = async (): Promise<User[]> => { 9 try { 10 const users = await db.find({ active: true }); 11 return users; 12 } catch (error) { 13 handleError(error); 14 throw error; 15 } 16};
Interfaces e Types
Sempre defina tipos para parâmetros e retornos.
typescript1// ❌ Sem tipagem 2const processUser = async (id, options) => { ... } 3 4// ✅ Com tipagem completa 5interface ProcessUserOptions { 6 sendEmail?: boolean; 7 updateCache?: boolean; 8} 9 10const processUser = async ( 11 id: string, 12 options: ProcessUserOptions = {} 13): Promise<User> => { ... }
Error Handling Centralizado
Use express-async-errors + hierarquia de errors + middleware centralizado.
1. Instalar Dependência
bash1npm install express-async-errors
2. Criar Hierarquia de Errors
typescript1// types/errors.ts 2export class AppError extends Error { 3 constructor( 4 message: string, 5 public statusCode: number = 500, 6 public details?: string[] 7 ) { 8 super(message); 9 this.name = this.constructor.name; 10 Error.captureStackTrace(this, this.constructor); 11 } 12} 13 14export class ValidationError extends AppError { 15 constructor(message: string, details: string[] = []) { 16 super(message, 400, details); 17 } 18} 19 20export class NotFoundError extends AppError { 21 constructor(message = 'Resource not found') { 22 super(message, 404); 23 } 24} 25 26export class UnauthorizedError extends AppError { 27 constructor(message = 'Unauthorized') { 28 super(message, 401); 29 } 30} 31 32export class ForbiddenError extends AppError { 33 constructor(message = 'Forbidden') { 34 super(message, 403); 35 } 36} 37 38export class ConflictError extends AppError { 39 constructor(message = 'Conflict') { 40 super(message, 409); 41 } 42}
3. Middleware de Error Handling
typescript1// middleware/errorHandler.ts 2import { Request, Response, NextFunction } from 'express'; 3import { AppError } from '../types/errors'; 4import { logger } from '../lib/logger'; 5 6const HTTP_INTERNAL_ERROR = 500; 7const HTTP_BAD_REQUEST = 400; 8 9export const errorHandler = ( 10 err: Error | AppError, 11 req: Request, 12 res: Response, 13 next: NextFunction 14): void => { 15 let statusCode = HTTP_INTERNAL_ERROR; 16 let message = 'Internal Server Error'; 17 let details: string[] | undefined; 18 19 // AppError e subclasses 20 if (err instanceof AppError) { 21 statusCode = err.statusCode; 22 message = err.message; 23 details = err.details; 24 } 25 // Mongoose ValidationError 26 else if (err.name === 'ValidationError') { 27 statusCode = HTTP_BAD_REQUEST; 28 message = 'Validation failed'; 29 details = Object.values((err as any).errors).map((e: any) => e.message); 30 } 31 // Mongoose CastError 32 else if (err.name === 'CastError') { 33 statusCode = HTTP_BAD_REQUEST; 34 message = 'Invalid ID format'; 35 } 36 // MongoDB Duplicate Key 37 else if ((err as any).code === 11000) { 38 statusCode = 409; 39 message = 'Duplicate entry'; 40 const field = Object.keys((err as any).keyPattern)[0]; 41 details = [`${field} already exists`]; 42 } 43 44 // Log estruturado 45 logger.error({ 46 error: { 47 name: err.name, 48 message: err.message, 49 stack: err.stack, 50 }, 51 statusCode, 52 path: req.path, 53 method: req.method, 54 body: req.body, 55 userId: (req as any).user?.id, 56 }, 'Request error'); 57 58 // Resposta padronizada 59 res.status(statusCode).json({ 60 success: false, 61 message, 62 ...(details && { details }), 63 timestamp: new Date().toISOString(), 64 path: req.path, 65 }); 66};
4. Setup no App
typescript1// app.ts 2import 'express-async-errors'; // ⚠️ IMPORTANTE: importar NO TOPO 3import express from 'express'; 4import { errorHandler } from './middleware/errorHandler'; 5 6const app = express(); 7 8app.use(express.json()); 9 10// ... suas rotas aqui ... 11 12// ⚠️ CRÍTICO: errorHandler deve ser o ÚLTIMO middleware 13app.use(errorHandler); 14 15export default app;
5. Uso nas Rotas
typescript1// routes/users.ts 2import { NotFoundError, ValidationError } from '../types/errors'; 3 4const HTTP_CREATED = 201; 5 6// Com express-async-errors, não precisa try-catch manual 7export const createUser = async (req: Request, res: Response): Promise<void> => { 8 // Validação com Zod 9 const validatedInput = CreateUserSchema.parse(req.body); // Lança erro se inválido 10 11 // Verificações de negócio 12 const existingUser = await User.findOne({ email: validatedInput.email }); 13 if (existingUser) { 14 throw new ConflictError('Email already in use'); 15 } 16 17 const user = await User.create(validatedInput); 18 19 res.status(HTTP_CREATED).json({ 20 success: true, 21 data: { 22 id: user._id.toString(), 23 name: user.name, 24 email: user.email, 25 }, 26 }); 27}; 28 29export const getUserById = async (req: Request, res: Response): Promise<void> => { 30 const user = await User.findById(req.params.id); 31 32 if (!user) { 33 throw new NotFoundError(`User ${req.params.id} not found`); 34 } 35 36 res.json({ 37 success: true, 38 data: user, 39 }); 40};
Vantagens do Error Handling Centralizado:
- Consistência em todas as respostas de erro
- Menos código duplicado
- Logging automático de todos os errors
- Fácil adicionar novos tipos de erro
- Async errors capturados automaticamente
Padrões Async Modernos
for-await-of para Streams e Iterables
Use para processar streams assíncronos.
typescript1// Processar stream de dados 2const processStream = async (stream: AsyncIterable<Chunk>): Promise<void> => { 3 const results: Result[] = []; 4 5 for await (const chunk of stream) { 6 const processed = await processChunk(chunk); 7 results.push(processed); 8 } 9 10 return results; 11}; 12 13// Async generator 14async function* fetchPaginated(endpoint: string): AsyncGenerator<User[]> { 15 const PAGE_SIZE = 100; 16 let page = 1; 17 let hasMore = true; 18 19 while (hasMore) { 20 const response = await api.get(`${endpoint}?page=${page}&size=${PAGE_SIZE}`); 21 yield response.data; 22 hasMore = response.data.length === PAGE_SIZE; 23 page++; 24 } 25} 26 27// Uso 28const allUsers: User[] = []; 29for await (const userBatch of fetchPaginated('/users')) { 30 allUsers.push(...userBatch); 31}
Promise.allSettled para Operações Independentes
Use quando algumas operações podem falhar sem afetar outras.
typescript1// ✅ Promise.allSettled - continua mesmo com falhas 2const sendNotifications = async (users: User[]): Promise<void> => { 3 const results = await Promise.allSettled( 4 users.map(user => sendEmail(user)) 5 ); 6 7 const succeeded = results.filter(r => r.status === 'fulfilled').length; 8 const failed = results.filter(r => r.status === 'rejected').length; 9 10 logger.info({ succeeded, failed }, 'Notifications sent'); 11 12 // Log apenas os que falharam 13 results.forEach((result, index) => { 14 if (result.status === 'rejected') { 15 logger.error({ 16 userId: users[index].id, 17 error: result.reason 18 }, 'Failed to send email'); 19 } 20 }); 21}; 22 23// ❌ Promise.all - falha tudo se um falhar 24const sendNotificationsBad = async (users: User[]): Promise<void> => { 25 await Promise.all(users.map(sendEmail)); // Um erro para tudo 26};
Quando usar cada um:
| Método | Quando Usar | Comportamento |
|---|---|---|
Promise.all | Todas devem suceder | Rejeita no primeiro erro |
Promise.allSettled | Independentes, algumas podem falhar | Sempre resolve, retorna status de cada |
Promise.race | Primeiro a completar vence | Resolve/rejeita com primeiro resultado |
Promise.any | Qualquer sucesso serve | Resolve com primeiro sucesso |
Logging Estruturado
Use Pino para logging estruturado.
typescript1import pino from 'pino'; 2 3const logger = pino({ 4 level: process.env.LOG_LEVEL || 'info', 5}); 6 7// ✅ Log estruturado 8logger.info({ userId, action: 'login' }, 'User logged in'); 9logger.error({ error, userId }, 'Failed to process user'); 10 11// ❌ Evite console.log 12console.log('User logged in:', userId);
Estrutura de Arquivos
Organização por Feature
src/
├── imports/
│ ├── auth/
│ │ ├── login.ts
│ │ ├── otp.ts
│ │ └── types.ts
│ ├── data/
│ │ └── api/
│ │ ├── find.ts
│ │ ├── create.ts
│ │ └── update.ts
│ └── utils/
│ ├── dateUtils.ts
│ └── validators.ts
└── server/
├── routes/
│ └── api/
└── middleware/
Nomenclatura
- Módulos/Arquivos: camelCase (
userService.ts) - Classes: PascalCase (
UserService) - Funções: camelCase (
findUserById) - Constants: UPPER_SNAKE_CASE
- Types/Interfaces: PascalCase (
UserDocument,ApiResponse)
Validação e Type Safety
Zod para Validação
Use Zod para validar dados de entrada.
typescript1import { z } from 'zod'; 2 3const CreateUserSchema = z.object({ 4 name: z.string().min(1), 5 email: z.string().email(), 6 age: z.number().positive().optional(), 7}); 8 9type CreateUserInput = z.infer<typeof CreateUserSchema>; 10 11export const createUser = async (input: unknown): Promise<User> => { 12 const validatedInput = CreateUserSchema.parse(input); 13 // validatedInput é tipado como CreateUserInput 14 return db.users.create(validatedInput); 15};
TypeScript Strict Mode
Sempre use strict mode.
json1// tsconfig.json 2{ 3 "compilerOptions": { 4 "strict": true, 5 "noImplicitAny": true, 6 "strictNullChecks": true, 7 "strictFunctionTypes": true, 8 "esModuleInterop": true 9 } 10}
Database (MongoDB)
Mongoose com TypeScript
Defina schemas e types corretamente.
typescript1import { Schema, model, Document } from 'mongoose'; 2 3interface IUser extends Document { 4 name: string; 5 email: string; 6 active: boolean; 7 createdAt: Date; 8} 9 10const UserSchema = new Schema<IUser>({ 11 name: { type: String, required: true }, 12 email: { type: String, required: true, unique: true }, 13 active: { type: Boolean, default: true }, 14 createdAt: { type: Date, default: Date.now }, 15}); 16 17export const User = model<IUser>('User', UserSchema);
Queries Eficientes
typescript1// ✅ Use lean() para leitura quando não precisa de document 2const users = await User.find({ active: true }).lean(); 3 4// ✅ Use select para buscar apenas campos necessários 5const userEmails = await User.find({ active: true }) 6 .select('email') 7 .lean(); 8 9// ✅ Use indexes apropriados 10UserSchema.index({ email: 1 }); 11UserSchema.index({ active: 1, createdAt: -1 });
API Design
Middleware Pattern
Use middlewares para lógica compartilhada.
typescript1// Middleware de autenticação 2export const authenticate = async (req: Request, res: Response, next: NextFunction) => { 3 try { 4 const token = req.headers.authorization?.replace('Bearer ', ''); 5 if (!token) { 6 throw new UnauthorizedError('No token provided'); 7 } 8 9 const decoded = await verifyToken(token); 10 req.user = decoded; 11 next(); 12 } catch (error) { 13 next(error); 14 } 15}; 16 17// Uso 18router.get('/protected', authenticate, async (req, res) => { 19 res.json({ user: req.user }); 20});
Error Handling Middleware
Centralize tratamento de erros.
typescript1export const errorHandler = ( 2 error: Error, 3 req: Request, 4 res: Response, 5 next: NextFunction 6) => { 7 logger.error({ error, path: req.path }, 'Request error'); 8 9 if (error instanceof AppError) { 10 return res.status(error.statusCode).json({ 11 error: error.message, 12 code: error.code, 13 }); 14 } 15 16 res.status(500).json({ 17 error: 'Internal server error', 18 }); 19};
Response Patterns
Padronize respostas da API.
typescript1// Success 2interface SuccessResponse<T> { 3 success: true; 4 data: T; 5} 6 7// Error 8interface ErrorResponse { 9 success: false; 10 error: string; 11 code?: string; 12} 13 14// Helper 15const sendSuccess = <T>(res: Response, data: T) => { 16 res.json({ success: true, data }); 17}; 18 19const sendError = (res: Response, statusCode: number, message: string) => { 20 res.status(statusCode).json({ success: false, error: message }); 21};
Performance
Connection Pooling
Use connection pooling para database.
typescript1const MONGODB_OPTIONS = { 2 maxPoolSize: 10, 3 minPoolSize: 2, 4 socketTimeoutMS: 45000, 5}; 6 7await mongoose.connect(MONGODB_URI, MONGODB_OPTIONS);
Caching com Redis
Cache operações custosas.
typescript1import Redis from 'ioredis'; 2 3const redis = new Redis({ 4 host: process.env.REDIS_HOST, 5 port: Number(process.env.REDIS_PORT), 6}); 7 8const CACHE_TTL_SECONDS = 300; // 5 minutes 9 10const getCachedUser = async (id: string): Promise<User | null> => { 11 const cached = await redis.get(`user:${id}`); 12 if (cached) { 13 return JSON.parse(cached); 14 } 15 16 const user = await User.findById(id).lean(); 17 if (user) { 18 await redis.setex(`user:${id}`, CACHE_TTL_SECONDS, JSON.stringify(user)); 19 } 20 21 return user; 22};
Graceful Shutdown
Implemente shutdown gracioso.
typescript1const gracefulShutdown = async () => { 2 logger.info('Shutting down gracefully...'); 3 4 // Pare de aceitar novas conexões 5 server.close(); 6 7 // Aguarde requisições em andamento 8 await Promise.all([ 9 mongoose.connection.close(), 10 redis.quit(), 11 ]); 12 13 logger.info('Shutdown complete'); 14 process.exit(0); 15}; 16 17process.on('SIGTERM', gracefulShutdown); 18process.on('SIGINT', gracefulShutdown);
Segurança
Input Validation
Sempre valide entrada do usuário.
typescript1// Use Zod para validação 2const input = InputSchema.parse(req.body);
Environment Variables
Use variáveis de ambiente para configuração sensível.
typescript1// .env (não commitar) 2DATABASE_URL=mongodb://... 3JWT_SECRET=... 4API_KEY=... 5 6// Uso 7import dotenv from 'dotenv'; 8dotenv.config(); 9 10const config = { 11 databaseUrl: process.env.DATABASE_URL!, 12 jwtSecret: process.env.JWT_SECRET!, 13};
Rate Limiting
Implemente rate limiting.
typescript1import rateLimit from 'express-rate-limit'; 2 3const RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes 4const MAX_REQUESTS_PER_WINDOW = 100; 5 6const limiter = rateLimit({ 7 windowMs: RATE_LIMIT_WINDOW_MS, 8 max: MAX_REQUESTS_PER_WINDOW, 9 message: 'Too many requests from this IP', 10}); 11 12app.use('/api/', limiter);
Testes
Unit Tests
Teste lógica de negócio isoladamente.
typescript1import { findActiveUsers } from './userService'; 2 3describe('userService', () => { 4 describe('findActiveUsers', () => { 5 it('should return only active users', async () => { 6 const users = await findActiveUsers(); 7 8 expect(users).toHaveLength(2); 9 expect(users.every(u => u.active)).toBe(true); 10 }); 11 }); 12});
Integration Tests
Teste fluxos completos.
typescript1describe('POST /api/users', () => { 2 it('should create user and return 201', async () => { 3 const response = await request(app) 4 .post('/api/users') 5 .send({ 6 name: 'Test User', 7 email: 'test@example.com', 8 }); 9 10 expect(response.status).toBe(201); 11 expect(response.body.data).toHaveProperty('id'); 12 }); 13});
Checklist Rápido
Antes de commitar código, verifique:
- Usou
constao invés delet? - Evitou
forloops (usoumap/filter/reduce)? - Não tem números mágicos?
- Usou p-limit ou chunking para loops assíncronos com +3 itens?
- Evitou
while(true)? - Importou
express-async-errorsno app.ts? - Errors customizados (ValidationError, NotFoundError, etc)?
- Logging estruturado com Pino?
- Validação de input com Zod?
- Tipos TypeScript para funções e interfaces?
- Código segue KISS/YAGNI/DRY/SOLID?
- Middlewares para lógica compartilhada?
- ErrorHandler é o último middleware?
- Testes cobrem casos principais?
Recursos Adicionais
- examples/ - Exemplos práticos de cada padrão
- Bluebird: http://bluebirdjs.com/docs/api-reference.html
- Pino: https://getpino.io
- Zod: https://zod.dev
Lembre-se: Código limpo não é sobre seguir regras cegamente, mas sobre escrever código que é fácil de entender, manter e modificar. Use bom senso!
FAQ & Installation Steps
These questions and steps mirror the structured data on this page for better search understanding.
? Frequently Asked Questions
What is codigo-limpo?
Perfect for Code Review Agents needing adherence to clean code principles like KISS and YAGNI. Konecty Open source Tech Business Platform
How do I install codigo-limpo?
Run the command: npx killer-skills add konecty/Konecty. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.
What are the use cases for codigo-limpo?
Key use cases include: Implementing KISS principle for function design, Applying YAGNI for feature implementation, Refactoring code for improved readability.
Which IDEs are compatible with codigo-limpo?
This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.
Are there any limitations for codigo-limpo?
Requires adherence to specific coding principles. May not be suitable for rapid prototyping or proof-of-concept development.
↓ How To Install
-
1. Open your terminal
Open the terminal or command line in your project directory.
-
2. Run the install command
Run: npx killer-skills add konecty/Konecty. The CLI will automatically detect your IDE or AI agent and configure the skill.
-
3. Start using the skill
The skill is now active. Your AI agent can use codigo-limpo immediately in the current project.