docker-doctor
AGENTS.md4 starsChanged 26 days agoMITView on GitHub
This project uses Ultracite, a zero-config preset that enforces strict code quality standards through automated formatting and linting. Oxlint + Oxfmt (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable. Write code that is accessible, performant, type-safe, and maintainable. Focus on clarity and explicit intent over brevity.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository8 other files it gives its agents.
- deslopSkill
- emil-design-engSkill
- improveSkill
- react-doctorSkill
- ultraciteSkill
- docker-authorSkill
- docker-doctorSkill
- improve-dockerSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
49 rules. About 0 are common, 26 are distinctive, and 23 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈26
Distinctive · estimate
This author's own choices. Worth a look.
23
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 17
Write code that is accessible, performant, type-safe, and maintainable.
- Distinctive: line 21
Use explicit types for function parameters and return values when they enhance clarity
- Very specific: line 22
Prefer unknown over any when the type is genuinely unknown
- Very specific: line 23
Use const assertions (as const) for immutable values and literal types
- Distinctive: line 25
Use meaningful variable names instead of magic numbers - extract constants with descriptive names
- Distinctive: line 29
Use arrow functions for callbacks and short functions
- Very specific: line 30
Prefer for...of loops over .forEach() and indexed for loops
- Very specific: line 31
Use optional chaining (?.) and nullish coalescing (??) for safer property access
- Distinctive: line 32
Prefer template literals over string concatenation
- Distinctive: line 33
Use destructuring for object and array assignments
- Very specific: line 34
Use const by default, let only when reassignment is needed, never var
- Very specific: line 38
Always await promises in async functions - don't forget to use the return value
- Very specific: line 39
Use async/await syntax instead of promise chains for better readability
- Distinctive: line 41
Don't use async functions as Promise executors
- Distinctive: line 45
Use function components over class components
- Distinctive: line 46
Call hooks at the top level only, never conditionally
- Very specific: line 48
Use the key prop for elements in iterables (prefer unique IDs over array indices)
- Distinctive: line 50
Don't define components inside other components
- Distinctive: line 51
Use semantic HTML and ARIA attributes for accessibility:
- Distinctive: line 53
Use proper heading hierarchy
- Distinctive: line 54
Add labels for form inputs
- Very specific: line 56
Use semantic elements (<button>, <nav>, etc.) instead of divs with roles
- Very specific: line 60
Remove console.log, debugger, and alert statements from production code
- Very specific: line 62
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
- Distinctive: line 63
Prefer early returns over nested conditionals for error cases
- Distinctive: line 67
Keep functions focused and under reasonable cognitive complexity limits
- Distinctive: line 69
Use early returns to reduce nesting
- Distinctive: line 70
Prefer simple conditionals over nested ternary operators
- Distinctive: line 72
Avoid import cycles; move shared code into a module both sides import
- Very specific: line 76
Add rel="noopener noreferrer" when using target="_blank" on links
- Very specific: line 77
Avoid dangerouslySetInnerHTML unless absolutely necessary
- Very specific: line 78
Don't use eval() or assign directly to document.cookie
- Distinctive: line 83
Avoid spread syntax in accumulators within loops
- Distinctive: line 84
Use top-level regex literals instead of creating them in loops
- Distinctive: line 85
Prefer specific imports over namespace imports
- Distinctive: line 86
Avoid barrel files (index files that re-export everything)
- Very specific: line 87
Use proper image components (e.g., Next.js <Image>) over <img> tags
- Very specific: line 93
Use Next.js <Image> component for images
- Very specific: line 94
Use next/head or App Router metadata API for head elements
- Distinctive: line 95
Use Server Components for async data fetching instead of async Client Components
- Very specific: line 99
Use ref as a prop instead of React.forwardRef
- Very specific: line 103
Use class and for attributes (not className or htmlFor)
- Very specific: line 109
Write assertions inside it() or test() blocks
- Distinctive: line 110
Avoid done callbacks in async tests - use async/await instead
- Very specific: line 111
Don't use .only or .skip in committed code
- Very specific: line 112
Keep test suites reasonably flat - avoid excessive describe nesting
- Distinctive: line 119
Meaningful naming: - Use descriptive names for functions, variables, and types
- Distinctive: line 123
Documentation: - Add comments for complex logic, but prefer self-documenting code
- Very specific: line 169
Diagnostics come from one factory: every rule builds its findings with packages/core/src/rules/create-diagnostic.ts.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
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:
bunx ultracite fix - Check for issues:
bunx ultracite check - Diagnose setup:
bunx ultracite doctor
Oxlint + Oxfmt (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
Core Principles
Write code that is accessible, performant, type-safe, and maintainable. Focus on clarity and explicit intent over brevity.
Type Safety & Explicitness
- Use explicit types for function parameters and return values when they enhance clarity
- Prefer
unknownoveranywhen the type is genuinely unknown - Use const assertions (
as const) for immutable values and literal types - Leverage TypeScript's type narrowing instead of type assertions
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Modern JavaScript/TypeScript
- Use arrow functions for callbacks and short functions
- Prefer
for...ofloops over.forEach()and indexedforloops - Use optional chaining (
?.) and nullish coalescing (??) for safer property access - Prefer template literals over string concatenation
- Use destructuring for object and array assignments
- Use
constby default,letonly when reassignment is needed, nevervar
Async & Promises
- Always
awaitpromises in async functions - don't forget to use the return value - Use
async/awaitsyntax instead of promise chains for better readability - Handle errors appropriately in async code with try-catch blocks
- Don't use async functions as Promise executors
React & JSX
- Use function components over class components
- Call hooks at the top level only, never conditionally
- Specify all dependencies in hook dependency arrays correctly
- Use the
keyprop for elements in iterables (prefer unique IDs over array indices) - Nest children between opening and closing tags instead of passing as props
- Don't define components inside other components
- Use semantic HTML and ARIA attributes for accessibility:
- Provide meaningful alt text for images
- Use proper heading hierarchy
- Add labels for form inputs
- Include keyboard event handlers alongside mouse events
- Use semantic elements (
<button>,<nav>, etc.) instead of divs with roles
Error Handling & Debugging
- Remove
console.log,debugger, andalertstatements from production code - Throw
Errorobjects with descriptive messages, not strings or other values - Use
try-catchblocks meaningfully - don't catch errors just to rethrow them - Prefer early returns over nested conditionals for error cases
Code Organization
- Keep functions focused and under reasonable cognitive complexity limits
- Extract complex conditions into well-named boolean variables
- Use early returns to reduce nesting
- Prefer simple conditionals over nested ternary operators
- Group related code together and separate concerns
- Avoid import cycles; move shared code into a module both sides import
Security
- Add
rel="noopener noreferrer"when usingtarget="_blank"on links - Avoid
dangerouslySetInnerHTMLunless absolutely necessary - Don't use
eval()or assign directly todocument.cookie - Validate and sanitize user input
Performance
- Avoid spread syntax in accumulators within loops
- Use top-level regex literals instead of creating them in loops
- Prefer specific imports over namespace imports
- Avoid barrel files (index files that re-export everything)
- Use proper image components (e.g., Next.js
<Image>) over<img>tags
Framework-Specific Guidance
Next.js:
- Use Next.js
<Image>component for images - Use
next/heador App Router metadata API for head elements - Use Server Components for async data fetching instead of async Client Components
React 19+:
- Use ref as a prop instead of
React.forwardRef
Solid/Svelte/Vue/Qwik:
- Use
classandforattributes (notclassNameorhtmlFor)
Testing
- Write assertions inside
it()ortest()blocks - Avoid done callbacks in async tests - use async/await instead
- Don't use
.onlyor.skipin committed code - Keep test suites reasonably flat - avoid excessive
describenesting
When Oxlint + Oxfmt Can't Help
Oxlint + Oxfmt will catch most mechanical issues automatically. Focus your attention on:
- Business logic correctness - Oxlint + Oxfmt can't validate your algorithms
- Meaningful naming - Use descriptive names for functions, variables, and types
- Architecture decisions - Component structure, data flow, and API design
- Edge cases - Handle boundary conditions and error states
- User experience - Accessibility, performance, and usability considerations
- Documentation - Add comments for complex logic, but prefer self-documenting code
Most formatting and common issues are automatically fixed by Oxlint + Oxfmt. Run bunx ultracite fix before committing to ensure compliance.
Architecture
Package layout
.
├── packages/
│ ├── core/ PRIVATE the diagnostic engine, consumed as raw TS ("main": src/index.ts)
│ │ └── src/
│ │ ├── types/ shared cross-package TS types (DockerfileInstruction, Diagnostic, ProjectInfo, …)
│ │ ├── project-info/ project discovery (discoverProject)
│ │ ├── config/ configuration loader (loadConfig)
│ │ ├── parsers/ Dockerfile and Compose parsers
│ │ ├── rules/ rule definitions (Security, Performance, Best Practices, Compose, Image Size)
│ │ ├── runners/ rule orchestration; resolveSeverity applies the configured severity
│ │ ├── schemas/ hand-rolled config validator (validateConfig)
│ │ ├── errors/ ConfigError, ParseError, FileNotFoundError (plain Error subclasses)
│ │ ├── report.ts report assembly
│ │ └── scoring.ts SCORE_BUCKETS, getScoreBucket, calculateScore
│ ├── docker-doctor/ PUBLISHED the CLI, @docker-doctor/cli, bundled by tsdown
│ │ └── src/
│ │ ├── cli.ts flag parsing, scan orchestration, exit codes
│ │ ├── agents/ skill install, handoff payload, agent launching, clipboard
│ │ ├── formatters/ terminal.ts, the human-readable report
│ │ └── workflow-scaffold.ts writes .github/workflows/docker-doctor.yml
│ └── videos/ PRIVATE Remotion release videos
├── apps/
│ └── web/ PRIVATE Next.js + fumadocs site (app/, components/, content/, lib/, scripts/)
├── kits/
│ └── docker-doctor/ PRIVATE Docker Sandboxes kit (spec v3); docker-doctor.yaml is synced by `bun run kit:sync`
├── skills/ docker-doctor (bundled into the npm package), docker-author, improve-docker
├── scripts/ generate-rules-doc.ts + rule-page-content.ts, sync-kit-spec.ts, render-github-action-comment.mjs
└── action.yml composite GitHub ActionConventions worth knowing
- Rules and parsers are plain synchronous functions:
packages/core/src/rules/andpackages/core/src/parsers/return values directly. No async, no generators, no wrapper types. Keep them that way. - Diagnostics come from one factory: every rule builds its findings with
packages/core/src/rules/create-diagnostic.ts. The runners inpackages/core/src/runners/then apply the configured severity. - Rule docs pages are generated: author the prose in
scripts/rule-page-content.ts, then runbun run docs:rules. Generation fails when a rule has no authored entry, and the Format CI job diffs the output. - Two artifacts are copied at release time:
skills/docker-doctoris copied into the npm package at build, and the version and CLI pin inkits/docker-doctor/docker-doctor.yamlare synced bybun run kit:sync. - User-visible CLI changes need a changeset: that includes edits to the bundled skill, since it ships inside
@docker-doctor/cli.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

