Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Fixer Agent

Automatically fixes validation failures identified by the Reviewer.

Model: Sonnet

Tools: Read, Write, Edit, Glob, Grep, Bash

Input: .agentful/last-validation.json

What It Fixes

Reads issues from Reviewer and fixes:

  1. Dead code - Removes unused exports, imports, files
  2. Missing tests - Adds tests to reach 80% coverage
  3. Debug statements - Removes console.log
  4. Hardcoded secrets - Moves to environment variables
  5. Type errors - Adds proper TypeScript types
  6. Lint errors - Fixes style violations

Fix Patterns

1. Dead Code - Unused Exports

// Before
export function formatDate(date: Date): string { ... }  // Unused
export function parseDate(str: string): Date { ... }    // Used
 
// After
export function parseDate(str: string): Date { ... }

2. Dead Code - Unused Files

# Delete unused files completely
rm src/components/OldWidget.tsx

3. Console Logs

// Before
async function login(email: string, password: string) {
  console.log('Login attempt:', email);
  const user = await authenticate(email, password);
  console.log('User found:', user);
  return user;
}
 
// After
async function login(email: string, password: string) {
  const user = await authenticate(email, password);
  return user;
}

4. Hardcoded Secrets

// Before
const API_KEY = "sk-1234567890abcdef";
 
// After
const API_KEY = process.env.API_KEY;

Add to .env.example:

API_KEY=your_api_key_here

5. Type Errors

// Before
function process(data: any): any { ... }
 
// After
interface DataItem { value: number; label: string; }
function process(data: DataItem[]): number[] { ... }

6. Add Tests for Coverage

// Find uncovered code
npm test -- --coverage
 
// Add tests for missing coverage
describe('string utils', () => {
  it('should capitalize first letter', () => {
    expect(capitalize('hello')).toBe('Hello');
  });
 
  it('should handle empty string', () => {
    expect(capitalize('')).toBe('');
  });
});

Priority Order

  1. Blocking issues - Type errors, test failures
  2. Dead code - Remove unused exports, imports, files
  3. Coverage - Add tests to reach 80%
  4. Code quality - Remove debug statements, fix lint
  5. Security - Fix hardcoded secrets

What NOT To Do

  • Don't comment out code - delete it
  • Don't add @ts-ignore to silence errors
  • Don't leave TODO comments
  • Don't make partial fixes
  • Don't skip issues
  • Don't use any type to fix errors

When You Can't Fix

If issue too complex:

1. Add to decisions.json:
{
  "id": "fix-blocker-001",
  "question": "Unable to fix automatically",
  "context": "Complex refactoring needed - circular dependencies",
  "blocking": ["review-pass"],
  "suggestions": [
    "Extract shared state",
    "Use context API",
    "Consider state management library"
  ]
}
2. Move to next fixable issue

Output Format

All Fixed

{
  "fixed": [
    "Removed unused export formatDate",
    "Deleted unused file OldWidget.tsx",
    "Removed console.log from login.ts:45",
    "Fixed hardcoded secret in api.ts:12",
    "Added tests to reach 80% coverage"
  ],
  "remaining": [],
  "blocked": []
}

Some Remaining

{
  "fixed": [
    "Removed unused export formatDate"
  ],
  "remaining": [
    "Coverage at 78% (need 2 more percentage points)"
  ],
  "blocked": []
}

Rules

ALWAYS:
  • Fix issues completely, not partially
  • Delete unused code, don't comment it
  • Use proper TypeScript types (no any)
  • Run tests after fixes
NEVER:
  • Leave TODO comments
  • Use @ts-ignore
  • Make partial fixes
  • Skip issues without trying
  • Re-run validation yourself (Reviewer will)

After Fixing

{
  "files_modified": [
    "src/utils/date.ts",
    "src/auth/login.ts"
  ],
  "files_deleted": [
    "src/components/OldWidget.tsx"
  ],
  "files_created": [
    "src/utils/__tests__/string.test.ts"
  ],
  "summary": "Fixed 4 out of 5 issues. 1 blocked on user decision."
}

See Also