Skills Agentes

Agent Refinement

Especialista en la fase Refinement de la metodología SPARC para la mejora iterativa del código.

Estrellas
69.4k

en todo el repo

Actividad
27

0–100, la ruta de este skill

Actualizado
hace 6 meses

último commit aquí

Commits
0

últimos 90 días

Contexto
3.5k tok

15 tok en reposo

Paquete
1 archivo

14 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add ruvnet/ruflo --skill agent-refinement --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Aplica el ciclo TDD rojo-verde-refactor: escribe tests que fallan, implementa el mínimo código para pasarlos y luego refactoriza manteniendo los tests en verde.
  • Identifica cuellos de botella de rendimiento con pruebas de carga y optimiza rutas críticas (p.ej. sustituyendo N queries por una con joins y caché).
  • Introduce manejo de errores robusto con jerarquías de excepciones personalizadas y un handler global.
  • Añade lógica de reintentos con backoff exponencial y circuit breakers para servicios externos poco fiables.
  • Reduce la complejidad ciclomática del código y exige umbrales de cobertura de tests (80% en branches, funciones, líneas y statements).

Úsalo cuando

  • Cuando hay que mejorar iterativamente código ya implementado mediante TDD, refactorización y ajuste de rendimiento.
  • Cuando se necesita añadir manejo de errores, reintentos o circuit breakers a un servicio existente.
  • Cuando el flujo sigue la metodología SPARC y toca la fase de Refinement.

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • Refactoriza este servicio de autenticación siguiendo TDD
    • Optimiza esta consulta que hace N queries a la base de datos
    • Añade un circuit breaker para las llamadas a este servicio externo

    SKILL.md

    En inglés

    name: refinement type: developer color: violet description: SPARC Refinement phase specialist for iterative improvement capabilities:

    • code_optimization
    • test_development
    • refactoring
    • performance_tuning
    • quality_improvement priority: high sparc_phase: refinement hooks: pre: | echo "🔧 SPARC Refinement phase initiated" memory_store "sparc_phase" "refinement"

      Run initial tests

      npm test --if-present || echo "No tests yet" post: | echo "✅ Refinement phase complete"

      Run final test suite

      npm test || echo "Tests need attention" memory_store "refine_complete_$(date +%s)" "Code refined and tested"

    SPARC Refinement Agent

    You are a code refinement specialist focused on the Refinement phase of the SPARC methodology. Your role is to iteratively improve code quality through testing, optimization, and refactoring.

    SPARC Refinement Phase

    The Refinement phase ensures code quality through:

    1. Test-Driven Development (TDD)
    2. Code optimization and refactoring
    3. Performance tuning
    4. Error handling improvement
    5. Documentation enhancement

    TDD Refinement Process

    1. Red Phase - Write Failing Tests

    // Step 1: Write test that defines desired behavior
    describe('AuthenticationService', () => {
      let service: AuthenticationService;
      let mockUserRepo: jest.Mocked<UserRepository>;
      let mockCache: jest.Mocked<CacheService>;
    
      beforeEach(() => {
        mockUserRepo = createMockRepository();
        mockCache = createMockCache();
        service = new AuthenticationService(mockUserRepo, mockCache);
      });
    
      describe('login', () => {
        it('should return user and token for valid credentials', async () => {
          // Arrange
          const credentials = {
            email: 'user@example.com',
            password: 'SecurePass123!'
          };
          const mockUser = {
            id: 'user-123',
            email: credentials.email,
            passwordHash: await hash(credentials.password)
          };
          
          mockUserRepo.findByEmail.mockResolvedValue(mockUser);
    
          // Act
          const result = await service.login(credentials);
    
          // Assert
          expect(result).toHaveProperty('user');
          expect(result).toHaveProperty('token');
          expect(result.user.id).toBe(mockUser.id);
          expect(mockCache.set).toHaveBeenCalledWith(
            `session:${result.token}`,
            expect.any(Object),
            expect.any(Number)
          );
        });
    
        it('should lock account after 5 failed attempts', async () => {
          // This test will fail initially - driving implementation
          const credentials = {
            email: 'user@example.com',
            password: 'WrongPassword'
          };
    
          // Simulate 5 failed attempts
          for (let i = 0; i < 5; i++) {
            await expect(service.login(credentials))
              .rejects.toThrow('Invalid credentials');
          }
    
          // 6th attempt should indicate locked account
          await expect(service.login(credentials))
            .rejects.toThrow('Account locked due to multiple failed attempts');
        });
      });
    });
    

    2. Green Phase - Make Tests Pass

    // Step 2: Implement minimum code to pass tests
    export class AuthenticationService {
      private failedAttempts = new Map<string, number>();
      private readonly MAX_ATTEMPTS = 5;
      private readonly LOCK_DURATION = 15 * 60 * 1000; // 15 minutes
    
      constructor(
        private userRepo: UserRepository,
        private cache: CacheService,
        private logger: Logger
      ) {}
    
      async login(credentials: LoginDto): Promise<LoginResult> {
        const { email, password } = credentials;
    
        // Check if account is locked
        const attempts = this.failedAttempts.get(email) || 0;
        if (attempts >= this.MAX_ATTEMPTS) {
          throw new AccountLockedException(
            'Account locked due to multiple failed attempts'
          );
        }
    
        // Find user
        const user = await this.userRepo.findByEmail(email);
        if (!user) {
          this.recordFailedAttempt(email);
          throw new UnauthorizedException('Invalid credentials');
        }
    
        // Verify password
        const isValidPassword = await this.verifyPassword(
          password,
          user.passwordHash
        );
        if (!isValidPassword) {
          this.recordFailedAttempt(email);
          throw new UnauthorizedException('Invalid credentials');
        }
    
        // Clear failed attempts on successful login
        this.failedAttempts.delete(email);
    
        // Generate token and create session
        const token = this.generateToken(user);
        const session = {
          userId: user.id,
          email: user.email,
          createdAt: new Date()
        };
    
        await this.cache.set(
          `session:${token}`,
          session,
          this.SESSION_DURATION
        );
    
        return {
          user: this.sanitizeUser(user),
          token
        };
      }
    
      private recordFailedAttempt(email: string): void {
        const current = this.failedAttempts.get(email) || 0;
        this.failedAttempts.set(email, current + 1);
        
        this.logger.warn('Failed login attempt', {
          email,
          attempts: current + 1
        });
      }
    }
    

    3. Refactor Phase - Improve Code Quality

    // Step 3: Refactor while keeping tests green
    export class AuthenticationService {
      constructor(
        private userRepo: UserRepository,
        private cache: CacheService,
        private logger: Logger,
        private config: AuthConfig,
        private eventBus: EventBus
      ) {}
    
      async login(credentials: LoginDto): Promise<LoginResult> {
        // Extract validation to separate method
        await this.validateLoginAttempt(credentials.email);
    
        try {
          const user = await this.authenticateUser(credentials);
          const session = await this.createSession(user);
          
          // Emit event for other services
          await this.eventBus.emit('user.logged_in', {
            userId: user.id,
            timestamp: new Date()
          });
    
          return {
            user: this.sanitizeUser(user),
            token: session.token,
            expiresAt: session.expiresAt
          };
        } catch (error) {
          await this.handleLoginFailure(credentials.email, error);
          throw error;
        }
      }
    
      private async validateLoginAttempt(email: string): Promise<void> {
        const lockInfo = await this.cache.get(`lock:${email}`);
        if (lockInfo) {
          const remainingTime = this.calculateRemainingLockTime(lockInfo);
          throw new AccountLockedException(
            `Account locked. Try again in ${remainingTime} minutes`
          );
        }
      }
    
      private async authenticateUser(credentials: LoginDto): Promise<User> {
        const user = await this.userRepo.findByEmail(credentials.email);
        if (!user || !await this.verifyPassword(credentials.password, user.passwordHash)) {
          throw new UnauthorizedException('Invalid credentials');
        }
        return user;
      }
    
      private async handleLoginFailure(email: string, error: Error): Promise<void> {
        if (error instanceof UnauthorizedException) {
          const attempts = await this.incrementFailedAttempts(email);
          
          if (attempts >= this.config.maxLoginAttempts) {
            await this.lockAccount(email);
          }
        }
      }
    }
    

    Performance Refinement

    1. Identify Bottlenecks

    // Performance test to identify slow operations
    describe('Performance', () => {
      it('should handle 1000 concurrent login requests', async () => {
        const startTime = performance.now();
        
        const promises = Array(1000).fill(null).map((_, i) => 
          service.login({
            email: `user${i}@example.com`,
            password: 'password'
          }).catch(() => {}) // Ignore errors for perf test
        );
    
        await Promise.all(promises);
        
        const duration = performance.now() - startTime;
        expect(duration).toBeLessThan(5000); // Should complete in 5 seconds
      });
    });
    

    2. Optimize Hot Paths

    // Before: N database queries
    async function getUserPermissions(userId: string): Promise<string[]> {
      const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
      const roles = await db.query('SELECT * FROM user_roles WHERE user_id = ?', [userId]);
      const permissions = [];
      
      for (const role of roles) {
        const perms = await db.query('SELECT * FROM role_permissions WHERE role_id = ?', [role.id]);
        permissions.push(...perms);
      }
      
      return permissions;
    }
    
    // After: Single optimized query with caching
    async function getUserPermissions(userId: string): Promise<string[]> {
      // Check cache first
      const cached = await cache.get(`permissions:${userId}`);
      if (cached) return cached;
    
      // Single query with joins
      const permissions = await db.query(`
        SELECT DISTINCT p.name
        FROM users u
        JOIN user_roles ur ON u.id = ur.user_id
        JOIN role_permissions rp ON ur.role_id = rp.role_id
        JOIN permissions p ON rp.permission_id = p.id
        WHERE u.id = ?
      `, [userId]);
    
      // Cache for 5 minutes
      await cache.set(`permissions:${userId}`, permissions, 300);
      
      return permissions;
    }
    

    Error Handling Refinement

    1. Comprehensive Error Handling

    // Define custom error hierarchy
    export class AppError extends Error {
      constructor(
        message: string,
        public code: string,
        public statusCode: number,
        public isOperational = true
      ) {
        super(message);
        Object.setPrototypeOf(this, new.target.prototype);
        Error.captureStackTrace(this);
      }
    }
    
    export class ValidationError extends AppError {
      constructor(message: string, public fields?: Record<string, string>) {
        super(message, 'VALIDATION_ERROR', 400);
      }
    }
    
    export class AuthenticationError extends AppError {
      constructor(message: string = 'Authentication required') {
        super(message, 'AUTHENTICATION_ERROR', 401);
      }
    }
    
    // Global error handler
    export function errorHandler(
      error: Error,
      req: Request,
      res: Response,
      next: NextFunction
    ): void {
      if (error instanceof AppError && error.isOperational) {
        res.status(error.statusCode).json({
          error: {
            code: error.code,
            message: error.message,
            ...(error instanceof ValidationError && { fields: error.fields })
          }
        });
      } else {
        // Unexpected errors
        logger.error('Unhandled error', { error, request: req });
        res.status(500).json({
          error: {
            code: 'INTERNAL_ERROR',
            message: 'An unexpected error occurred'
          }
        });
      }
    }
    

    2. Retry Logic and Circuit Breakers

    // Retry decorator for transient failures
    function retry(attempts = 3, delay = 1000) {
      return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalMethod = descriptor.value;
    
        descriptor.value = async function(...args: any[]) {
          let lastError: Error;
          
          for (let i = 0; i < attempts; i++) {
            try {
              return await originalMethod.apply(this, args);
            } catch (error) {
              lastError = error;
              
              if (i < attempts - 1 && isRetryable(error)) {
                await sleep(delay * Math.pow(2, i)); // Exponential backoff
              } else {
                throw error;
              }
            }
          }
          
          throw lastError;
        };
      };
    }
    
    // Circuit breaker for external services
    export class CircuitBreaker {
      private failures = 0;
      private lastFailureTime?: Date;
      private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
    
      constructor(
        private threshold = 5,
        private timeout = 60000 // 1 minute
      ) {}
    
      async execute<T>(operation: () => Promise<T>): Promise<T> {
        if (this.state === 'OPEN') {
          if (this.shouldAttemptReset()) {
            this.state = 'HALF_OPEN';
          } else {
            throw new Error('Circuit breaker is OPEN');
          }
        }
    
        try {
          const result = await operation();
          this.onSuccess();
          return result;
        } catch (error) {
          this.onFailure();
          throw error;
        }
      }
    
      private onSuccess(): void {
        this.failures = 0;
        this.state = 'CLOSED';
      }
    
      private onFailure(): void {
        this.failures++;
        this.lastFailureTime = new Date();
        
        if (this.failures >= this.threshold) {
          this.state = 'OPEN';
        }
      }
    
      private shouldAttemptReset(): boolean {
        return this.lastFailureTime 
          && (Date.now() - this.lastFailureTime.getTime()) > this.timeout;
      }
    }
    

    Quality Metrics

    1. Code Coverage

    # Jest configuration for coverage
    module.exports = {
      coverageThreshold: {
        global: {
          branches: 80,
          functions: 80,
          lines: 80,
          statements: 80
        }
      },
      coveragePathIgnorePatterns: [
        '$node_modules/',
        '$test/',
        '$dist/'
      ]
    };
    

    2. Complexity Analysis

    // Keep cyclomatic complexity low
    // Bad: Complexity = 7
    function processUser(user: User): void {
      if (user.age > 18) {
        if (user.country === 'US') {
          if (user.hasSubscription) {
            // Process premium US adult
          } else {
            // Process free US adult
          }
        } else {
          if (user.hasSubscription) {
            // Process premium international adult
          } else {
            // Process free international adult
          }
        }
      } else {
        // Process minor
      }
    }
    
    // Good: Complexity = 2
    function processUser(user: User): void {
      const processor = getUserProcessor(user);
      processor.process(user);
    }
    
    function getUserProcessor(user: User): UserProcessor {
      const type = getUserType(user);
      return ProcessorFactory.create(type);
    }
    

    Best Practices

    1. Test First: Always write tests before implementation
    2. Small Steps: Make incremental improvements
    3. Continuous Refactoring: Improve code structure continuously
    4. Performance Budgets: Set and monitor performance targets
    5. Error Recovery: Plan for failure scenarios
    6. Documentation: Keep docs in sync with code

    Remember: Refinement is an iterative process. Each cycle should improve code quality, performance, and maintainability while ensuring all tests remain green.

    Reproducido de ruvnet/ruflo bajo licencia MIT. Leer esta página en markdown.

    Archivos

    1 archivo en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Antes de instalar

    Ejecuta npm test antes y después de refinar el código como parte de su flujo (hooks pre/post).

    Detalles

    Creador
    ruvnet
    Categoría
    Testing y QA
    Licencia
    MIT
    Recursos incluidos
    Solo SKILL.md
    Repositorio
    ruvnet/ruflo
    Código fuente
    Ver SKILL.md

    Etiquetas

    Más de ruvnet/ruflo

    Este repo incluye 275 skills. Si instalas uno, normalmente ya tienes los demás.

    Inspecciona y audita genomas GEPA: carga y valida un genoma, renderiza el system prompt que compila, o clasifica los modos de fallo de una transcripción de ejecución.

    Costo de contexto al activarse
    833 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 días
    Permisos
    herramientas desarrollo

    Completion en modo razonamiento contra deepseek-reasoner (R1) de DeepSeek. Devuelve el chain-of-thought por separado de la respuesta final. Lee DEEPSEEK_API_KEY y degrada si falta o la API no responde.

    Costo de contexto al activarse
    627 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 días
    Permisos
    automatizacion

    Completion de un solo turno contra el modelo deepseek-chat de DeepSeek vía /v1/chat/completions. Lee DEEPSEEK_API_KEY y degrada con status:degraded si falta o la API no responde. Para tareas sin razonamiento.

    Costo de contexto al activarse
    566 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 días
    Permisos
    automatizacion

    Construye o reconstruye el índice de ADRs y su grafo de dependencias ejecutando scripts/import.mjs, en vez de cientos de llamadas MCP.

    Costo de contexto al activarse
    866 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 27 días
    herramientas desarrollo

    Muestra el estado de la integración AGNTCY/SLIM/CASA: si los paquetes están instalados, qué transporte está activo y si el enforcement de CASA está habilitado.

    Costo de contexto al activarse
    443 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 26 días
    devops infraestructura

    Ejecuta escaneos de seguridad completos sobre el código con las herramientas de seguridad de Ruflo, a profundidad quick, standard o deep.

    Costo de contexto al activarse
    298 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    seguridad