DEV Community

Dennis Havermans
Dennis Havermans

Posted on

I built a tool to stop my AI agent instruction files from drifting out of sync

I use Claude, Cursor and Copilot in the same repos. Each expects its own instruction file, in its own format, in its own location.

CLAUDE.md for Claude. .cursor/rules/main.mdc for Cursor. .github/copilot-instructions.md for Copilot.

Every time I updated one I forgot the others. Two weeks later I realized Cursor was still running on old instructions. It was subtle but it was making my agents inconsistent in ways that were hard to debug.

So I built agentfile. Here is how it works.

One contract, every agent

You define one contract.yaml and commit it to the repo:

version: 1

project:
  name: My Project
  stack: [typescript, react, nextjs]

rules:
  coding:
    - Prefer small composable functions
    - Avoid unnecessary abstractions
  architecture:
    - Follow feature-based folder structure

skills:
  - name: create-component
    description: Creates a new React component with tests
    steps:
      - Create /src/components/{feature}/{Name}.tsx
      - Create matching test file
      - Export from index.ts
Enter fullscreen mode Exit fullscreen mode

Then run one command:

npx @agentfile/cli sync
Enter fullscreen mode Exit fullscreen mode

Every agent gets the right file in its native format:

✔ claude     → CLAUDE.md
✔ copilot    → .github/copilot-instructions.md
✔ cursor     → .cursor/rules/main.mdc
✔ cursor:skill:create-component → .cursor/rules/skills/create-component.mdc
✔ agents-md  → AGENTS.md
Enter fullscreen mode Exit fullscreen mode

Claude gets plain markdown. Cursor gets .mdc files with frontmatter. Copilot gets compact inline context blocks. The contract is the same. The output adapts.

Skills are the interesting part

You define a workflow once and each agent gets it rendered in its own format.

For Cursor that means individual .mdc files in .cursor/rules/skills/, one per skill, with proper frontmatter so Cursor loads them contextually.

For Claude they get appended as structured sections in CLAUDE.md.

For Copilot they become compact inline bullets.

Same data. Three different formats. Zero duplication.

No repo clutter

Generated files are gitignored. Each developer creates a personal .ai-agents file listing the agents they use:

claude
cursor
Enter fullscreen mode Exit fullscreen mode

Someone on the team using Windsurf gets AGENTS.md. Someone using Copilot gets copilot-instructions.md. The repo stays clean and nobody forces their tool preferences on anyone else.

Watch mode

There is also a watch command that auto-syncs whenever contract.yaml changes:

npx @agentfile/cli watch
Enter fullscreen mode Exit fullscreen mode

No more running sync manually after every change. Just edit the contract and your agent files update automatically.

Codex and Windsurf are covered too

agentfile generates AGENTS.md which is read natively by both Codex and Windsurf. No extra config needed.

Adding a new agent takes two files

No generator changes. No config edits. Just drop two files into ai/agents/:

ai/agents/windsurf/
  config.yaml
  template.md
Enter fullscreen mode Exit fullscreen mode

That is the entire process.

Try it

npx @agentfile/cli init
Enter fullscreen mode Exit fullscreen mode

It walks you through setup, scaffolds everything, and generates a CI workflow that validates your contract on every push.

Repo: github.com/dennishavermans/agentfile

Still early but it works well for my own workflow. Curious how others are handling this. Are you maintaining these files manually or do you have something in place?

Top comments (0)