AgentDiet
Documentation
Everything below describes the shipped binary. The tool has six flags, three exit codes and no configuration file: the whole surface fits on this page.
$go install github.com/qansaid/agentdiet@latestQuickstart
Install with Go 1.22 or newer, then run it inside any repository. Nothing is uploaded, nothing is written, and no account is involved.
# 1. installgo install github.com/qansaid/agentdiet@latest # 2. audit the repository you are standing inagentdiet # 3. audit somewhere elseagentdiet path/to/repoExit code 0 means the audit completed within budget, 1 means always-on tokens exceeded --max-tokens, and 2 means the audit could not run, usually a path that does not exist or is not a directory.
CLI reference
Flags may appear before or after the path: agentdiet . --json and agentdiet --json . are the same command.
--jsonoffEmit the full report as JSON with stable keys, safe for dashboards.--badgeoffEmit a shields.io endpoint document instead of the report.--max-tokens0 (off)CI gate: exit 1 when always-on tokens exceed this number.--window200000Context window used for the share column.--price3.00USD per 1M input tokens, used for the cost line.--top8Maximum files listed per section.--versionn/aPrint the version and exit.Exit codes
exit 0Audit completed, within budget.exit 1Always-on tokens exceeded --max-tokens.exit 2The audit could not run.
Detected files
Detection is by filename and position, with no configuration. node_modules, vendor, dist, build, target, virtualenvs, .git and other dependency or build trees are skipped, so a vendored AGENTS.md is not your prompt.
always-onAGENTS.md · CLAUDE.md · GEMINI.md · JULES.md · .goosehints at the root or in .claude/ or .codex/; AGENT.md · README.agent.md at the root; .cursorrules · .windsurfrules · .clinerules · .rules at the root; .github/copilot-instructions.md; SOUL.md · STYLE.md · INSTRUCTIONS.md · MEMORY.md inside a Nakama profile workspace, meaning a directory that also contains SOUL.mdscopedThe same instruction filenames in any subdirectory.on-demand**/skills/**/SKILL.md · .cursor/rules/*.mdc · .claude/commands/** · .github/prompts/** · .github/instructions/** · .roo/rules/** · .continue/rules/**config.mcp.json · .cursor/mcp.json · .vscode/mcp.json · .claude/settings.json · .codex/config.toml; MCP configuration inventory: declared server names are reported, schema tokens are not measured.Reading the report
Files are grouped by tier, not by directory. The always-on section is the bill; the on-demand section is inventory that costs nothing until the agent opens it. Totals, grade and the cost line follow, then the findings.
The cost line multiplies always-on tokens by --price (default 3.00 USD per 1M input tokens). It is a model of the context, not a claim about your invoice. Change the flag to match your provider's rate. The report calls the result cost per 1,000 sessions because it assumes one request per session; read it as the estimated cost per 1,000 requests.
--json emits the same data with stable keys: alwaysOnTokens, scopedTokens, onDemandTokens, grade, costPer1kSessionsUSD (the UI labels it Estimated cost / 1K requests; one request per session is assumed), files[], findings[], mcpServers[], plus the estimator description and the price used.
Findings
duplicateA paragraph that appears verbatim in two or more files, with the duplicated content quantified. Actual savings depend on which files the runtime loads.
→ Keep the text in one file and point at it from the others.
near-duplicateOne instruction file at least 60% contained in another, a copy that was edited once and never again.
→ Keep one canonical file; the other should be a pointer, not a copy.
oversizeA single always-on file above 3,000 tokens.
→ Move reference material into a skill or docs/ and keep the root file to rules.
scopeMCP configuration inventory of declared servers. Actual schema overhead depends on the runtime and the tools it connects; AgentDiet does not measure it.
→ Disable servers you do not use in this repo; fewer connected servers means fewer tool schemas.
Grades
The grade is absolute always-on tokens, not a percentage of the context window. A percentage makes every real repository an A and the grade becomes decoration.
Token estimation
There is no tokenizer in the binary. Prose is estimated at 4.5 characters per token and fenced code at 3.4, rounding each segment up, so a file made of many short paragraphs is not under-counted.
The divisors were chosen by sweep against cl100k_base on 137 real agent-configuration files from five repositories: mean error +1.2%, median +0.4%, mean absolute error 8.1%, 87% of files within ±15% (p10 −10.5%, p90 +16.7%). The corpus and the full sweep are in docs/estimator.md, and scripts/measure_estimator.py re-runs it.
If you need exact counts for a specific model, run the file through that tokenizer. The report tells you which file is worth the trouble.
CI integration
The repository ships a composite action that installs the binary, audits the checkout and fails the job when max-tokens is exceeded. It also exposes always-on-tokens and grade as step outputs.
name: agent-contexton: [push, pull_request]jobs: agentdiet: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: qansaid/agentdiet@v1 with: max-tokens: 4000Without the action, install with go install and run agentdiet --max-tokens 4000 as a step: exit code 1 fails the job. To publish the number as a badge, write agentdiet --badge to a gist and point a shields.io endpoint badge at the raw URL. The workflow for that is in the repository README.
Troubleshooting
A file was not detected
Detection is a fixed table in internal/audit/scan.go. Open an issue with the filename and where it sits in the tree. Do not paste a private repository's contents. There is a dedicated issue template for exactly this.
The token count differs from my provider
Expected. The number is an estimate calibrated against cl100k_base, and every model family ships a different tokenizer. Use it for order-of-magnitude decisions and trends, not for billing reconciliation.
Exit code 2
The audit could not run: the path does not exist, is not a directory, or --window was not positive. The message on stderr names the problem.