DEV Community

Russell Jones
Russell Jones

Posted on Originally published at jonesrussell.github.io

Claude Code and Codex skills are directories, not files

Ahnii!

If you're building tooling that installs "skills" for AI coding agents, it's tempting to treat a skill as just another markdown file you drop somewhere in the repo. It isn't. Both Claude Code and OpenAI Codex discover skills by walking the project tree for a directory that contains a SKILL.md file, not a flat file. Here's what each client actually looks for, the bug a shape mismatch causes, and how Waaseyaa's installer package, Bimaaji, fixed it by sharing one renderer across both clients instead of maintaining two.

What Claude Code actually discovers

A Claude Code project skill lives at:

.claude/skills/<skill-name>/SKILL.md
Enter fullscreen mode Exit fullscreen mode

Two details matter here:

  • The command name comes from the directory name, not from the name field in the file's frontmatter. The frontmatter name is only the display label shown in skill listings.
  • Frontmatter is only recognized when the opening --- is the file's first line. If anything precedes it — a comment, a blank line, a provenance marker — Claude Code won't parse it as frontmatter at all.

A flat .claude/skills/<name>.md file is not a documented layout, and Claude Code doesn't discover it. Bimaaji's installer originally emitted exactly that flat shape, and every "file written" count it reported was quietly counting output the client would never load.

What Codex actually discovers

Codex's convention is split in two:

  • A root AGENTS.md for always-loaded project guidance — the same vendor-neutral file Devin Desktop and JetBrains Junie read.
  • Detailed, on-demand skills under .agents/skills/<skill-name>/SKILL.md, discovered by walking from the current working directory up to the repository root.

Codex's per-skill directory shape is the same structural contract as Claude Code's: a directory per skill, a SKILL.md inside it, name/description metadata in frontmatter. Bimaaji's installer used to fold every skill body straight into AGENTS.md as one consolidated file. That worked, in the sense that Codex could read it, but it threw away the on-demand loading both clients are designed around — the whole point of a skill is that its detail loads only when needed, not on every request.

The fix: one renderer, not two

Once both clients turned out to want the same shape — a concise always-loaded guidance file plus one SKILL.md per skill — Bimaaji stopped maintaining separate Claude and Codex renderers and introduced a shared base class both transformers extend. Each subclass supplies only two things:

  • its client id (claude or codex)
  • its guidance file's title line

Everything else — the per-skill file layout, whether frontmatter is required, the guidance index, and a provenance footer — comes from the shared renderer plus a small per-client capabilities lookup (skill file paths, whether frontmatter must sit at byte zero, and so on).

That provenance footer is the detail worth stealing for your own installers. Two pieces of metadata do the work:

  • Every generated skill file carries an HTML-comment footer with the sha256 of the whole skill inventory it was rendered from.
  • The guidance index lists each skill's own source sha256 next to its target path.

Together they let you prove, rather than assume, that Claude and Codex regenerated their skill files from the same canonical source — and that the two clients' output is byte-identical for the same input.

Claude Code vs. Codex, side by side

Claude Code Codex
Always-loaded guidance .claude/CLAUDE-WAASEYAA.md (kept separate from a consumer's own CLAUDE.md) root AGENTS.md
Per-skill file .claude/skills/<skill-name>/SKILL.md .agents/skills/<skill-name>/SKILL.md
Discovery key directory name directory name
Frontmatter required at byte zero yes per capability lookup
Command name source directory name, not frontmatter name directory name

What this means if you're building similar tooling

  • Don't trust your own success counters. A "files written" count that doesn't check whether the client's discovery mechanism actually finds those files will lie to you convincingly.
  • Cite the client's own docs, not an issue description. Bimaaji's changelog is explicit that the Codex per-skill layout only shipped once there was a citable, verified discovery mechanism from OpenAI's own docs — not because it seemed like a reasonable guess.
  • One renderer beats one renderer per client once you notice two clients want the same shape. Two copies of "how a skill file gets rendered" is exactly the kind of thing that drifts quietly.

Baamaapii

Top comments (0)