Claude Code, held to your lint rules
Claude Code reads Ultracite’s rules from AGENTS.md, or through an import when your project has its own CLAUDE.md. A PostToolUse hook runs ultracite fix on every file Claude writes and hands back what’s left, so Claude fixes it in the same turn.
Claude Code by AnthropicChecked against October 2026
# Ultracite Code Standards
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
## Quick Reference
- **Format code**: `npx ultracite fix`
- **Check for issues**: `npx ultracite check`
- **Diagnose setup**: `npx ultracite doctor`
Oxlint + Oxfmt (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
…# Your project notes
@AGENTS.md- 1
Managed CLAUDE.mdYour organization’s managed policy, when there is one. - 2
~/.claude/CLAUDE.mdYour instructions for every project. - 3
CLAUDE.md or .claude/CLAUDE.mdThe project’s own instructions, from the working directory up. If either exists, Claude reads them instead of AGENTS.md. - 4
AGENTS.mdUltraciteRead when the project has noCLAUDE.md, or through an@AGENTS.mdimport when it does. - 5
src/**/CLAUDE.mdA subdirectory’s instructions, loaded when Claude first reads or edits a file there.
How Claude Code reads the rules
Claude Code builds its instructions from a stack of files, broadest first. AGENTS.md sits in the middle of it, as the project’s instructions whenever there’s no CLAUDE.md to take that place.
- Project file
CLAUDE.mdor.claude/CLAUDE.md, orAGENTS.mdwhen neither exists.- Personal
~/.claude/CLAUDE.mdfor every project and a gitignoredCLAUDE.local.mdfor one. Both load alongsideAGENTS.md, except thatCLAUDE.local.mdcounts as aCLAUDE.md.- Size
- Aim for under 200 lines per file: longer files cost context and adherence. Imports don’t reduce that, since imported files load at launch too.
- Imports
@pathlines expand at launch, up to four levels deep. A path outside the project asks for approval once.- Both at once
- Set Project instructions to
claude-md-and-agents-mdin/configto load both files without an import. It’s a personal setting, not a project one. - Check it
/contextlists every instructions file Claude loaded.
A hook on every Write and Edit
init --hooks claude adds a PostToolUse hook for Claude’s Write and Edit tools. It fixes only the file Claude touched, and when problems remain it exits with code 2, which Claude Code turns into feedback Claude reads before its next step.
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"command": "npx ultracite fix --hook",
"type": "command"
}
],
"matcher": "Write|Edit"
}
]
}
}- 01Claude writes or edits a file with its
WriteorEdittool. - 02Claude Code runs the hook, which reads the edited file’s path from the hook payload and runs
ultracite fixon just that file. - 03Safe fixes and formatting are applied. If nothing is left, the hook exits 0 and Claude carries on.
- 04If problems remain, the hook prints them to stderr and exits 2, and Claude reads them and fixes them before its next step.
Worth knowing about Claude Code
Nested instructions load on demand
Claude Code loads a subdirectory’s
CLAUDE.md(orAGENTS.md, when it has noCLAUDE.md) the first time Claude reads or edits a file there, so a workspace’s own instructions arrive with its code.Path-scoped rules for the rest
Files in
.claude/rules/with apathsfield load only when Claude works on matching files. Ultracite’s rules apply everywhere, so they stay inAGENTS.md; framework-specific notes of your own fit well in a path-scoped rule.Imports are relative
An
@pathimport resolves relative to the file it’s in and can nest four levels deep. That’s why the import in.claude/CLAUDE.mdis@../AGENTS.md.The Ultracite skill
Claude Code loads skills from
.claude/skills/. Wheninitinstalls the Ultracite skill in a project with a.claudefolder, it installs it there, so Claude knows how to runinit,check,fixanddoctor.
Claude Code questions, answered
- Does Claude Code read AGENTS.md or CLAUDE.md?
- Both, but not at once by default. Claude Code reads
AGENTS.md(since v2.1.277) only when there’s noCLAUDE.md,.claude/CLAUDE.mdorCLAUDE.local.mdin your working directory or above it. When your project has aCLAUDE.md,ultracite init --agents claudeadds an@AGENTS.mdimport to it, so Claude loads both. - How does the hook tell Claude what’s left?
- It prints what
ultracite fixcouldn’t settle to stderr and exits with code 2. Claude Code shows aPostToolUsehook’s stderr to Claude on that exit code, so Claude sees the remaining problems in the same turn and fixes them before moving on. - Can Claude fix what autofix can’t, outside a session?
- Run
npx ultracite fix --claude. After the safe fixes, it hands each file with problems left to the Claude Code CLI (claude -pinacceptEditsmode, limited to reading and editing files), then lints again, so the result decides what counts as fixed. - How do I check Claude loaded the rules?
- Run
/contextin a session and look under Memory files.AGENTS.mdshows there when Claude reads it directly; with aCLAUDE.mdthat imports it, the import is expanded into that file. - I set Ultracite up for Claude before. Do I need to do anything?
- Yes, unless you’ve turned it off. Running
initagain takes Ultracite’s block out of the.claude/CLAUDE.mdearlier versions wrote, removes the file if nothing else is left in it, and importsAGENTS.mdfrom whateverCLAUDE.mdremains, because a leftover.claude/CLAUDE.mdstops Claude from readingAGENTS.md.
Keep going
- AgentCodexOpenAI’s coding agent for the terminal, IDEs, the ChatGPT desktop app and cloud tasks.
- AgentOpenCodeOpen-source coding agent for the terminal, desktop and IDEs, with 75+ model providers.
- AgentGitHub CopilotGitHub’s coding assistant: agent mode in editors, a CLI, and a cloud agent that opens pull requests.
- DocsAgent rulesWhat
initwrites for every agent, and how to keep it current.
Ship less slop
One command sets up your linter, formatter, editor and agents. Works with Oxlint, Biome and ESLint.