A tiny, fast, cross-platform Node.js CLI tool to aggregate meaningful source code from a project into a single agents.md file (or update an existing one). It respects nested .gitignore and .agentsignore files.
Let's face it: Agents are cool, but it sucks to wait for minutes, and then get a mediocre result when internal context retrieval from vector database hit a semantic limit. Sub-agent architectures and recursive/graph agent architectures were introduced to address this issue, but they are still in their infancy and often require significant orchestration effort - only to yield even MORE WAIT TIME and COST.
But there's a simple, stupid solution. While VENDORS optimize for cost/RoI (more tokens -> better RoI as YOU PAY), models became less and less limited in their context window. For most projects, when we remove all irrlelevant semantic context, we can fit the entire codebase into the context window by now.
If we do so, we can find a local maxima for cost and performance:
- We pay less for tokens as we process the whole codebase, BUT ONLY ONCE.
- We get better results because the model MUST READ ALL CODE before it can start reasoning.
- We get faster results because sub-agents/graphs/recursive agent architectures often become obsolete for code-only reasoning tasks.
Why? Because simple tool use often is enough in the main agent run to fulfill the task.
Give AI coding agents complete context in one copy-paste.
When working with AI assistants (Claude, ChatGPT, Gemini, Copilot, etc.), context is everything. Instead of hoping your IDE integration captures what's needed, agents.md contains your entire relevant codebase by running npx update-agents-md regularly (e.g. file save action in your IDE):
- Unlock flexibility - Works with any IDE, any model: Copy-paste the contents of
agents.mddirectly into any AI chat interface - no IDE integration required. The model/Agent is now forced to see everything it needs, immediately - Zero missing context: The agent sees everything it needs, immediately - no hallucinations caused by sub-optimal vector database retrieval (see paper: On the Theoretical Limitations of Embedding-Based Retrieval )
- Get a second opinion: Easily share your codebase with alternative models to compare suggestions -- pass these to your Agents via Copy & Paste. Full context cross-model/cross-vendor feedback likely improves code quality when using top-tier models
- Works offline: No API keys or cloud connections needed for the aggregation itself -- you may use local models too; you don't even need an IDE. Now you can manually copy the whole codebase into any web based AI chat interface -- the results will still be stunning (although you'd have to manually merge -- so DO USE IDE's and Agents.. ;).
Scales well for small to medium projects:
- ✅ Up to ~50k lines of code: works great
- ✅ 50 - 75k lines: often still fits in modern context windows, but limits may be hit
⚠️ Larger projects: use-ito filter for most relevant files, or-lto truncate context (BAD IDEA, only use if absolutely necessary -- this is the reason why this tool exists in the first place...)
- Smart Scanning: Recursively scans directories, respecting nested gitignore/agentsignore rules
- Binary Exclusion: Automatically detects and excludes binary files
- Metadata Handling: Updates content between
<full-context-dump>tags inagents.md - Documentation Exclusion: Optionally exclude LICENSE, README, CHANGELOG, and other doc files
- Include Filters: Only include files matching specific patterns (exclusive mode)
- Configurable: Optional size limits for lines per file and/or total characters
flowchart TD
A[CLI Invocation] --> B[Parse Options]
B --> C[Scan Directory Recursively]
C --> D{Entry Type}
D -->|Directory| E[Check .gitignore / .agentsignore]
E -->|Ignored| F[Skip]
E -->|Allowed| C
D -->|File| G{Binary?}
G -->|Yes| F
G -->|No| H{Mode?}
H -->|Default: Exclude Mode| I[Include all files]
H -->|"-i" set: Include Mode| J{Matches pattern?}
J -->|Yes| I
J -->|No| F
I --> K[Read & Truncate if -l set]
K --> L[Collect Source Code]
L --> M[Sort Files Alphabetically]
M --> N{Has existing tags?}
N -->|Yes| O[Replace content between tags]
N -->|No| P[Append new tagged block]
O --> Q[Write agents.md]
P --> Q
Q --> R[Done ✓]
# Run directly with npx (no install required)
npx update-agents-md
# Or install globally
npm install -g update-agents-mdupdate-agents-md [directory] [options]| Option | Alias | Description |
|---|---|---|
--follow |
-f |
Follow symbolic links (default: false) |
--docs |
-d |
Exclude documentation files (LICENSE, README, CHANGELOG, etc.) |
--include <patterns> |
-i |
Only include files matching patterns (comma-separated globs) |
--lines <n> |
-l |
Max lines to include per file |
--chars <n> |
-c |
Max total characters to collect |
--project <name> |
-p |
Set project name (adds project-name attribute; overrides package.json) |
--tag <name> |
-t |
Use custom tag name instead of full-context-dump |
--no-tests |
Exclude test files (e.g. *.test.*, *.spec.*) |
|
--no-styles |
Exclude style files (e.g. *.css, *.scss, *.less) |
|
--dts |
Generate .d.ts type declarations for .ts files (uses dts-gen) |
|
--help |
-h |
Show help |
By default, if you want to exclude files, run the tool once, then add exclude patterns to .agentsignore and run it again. If you need an inverse logic (only include specific files), use the -i flag.
# Scan current directory
npx update-agents-md .
# Scan specific directory with line limit
npx update-agents-md ./src -l 50
# Exclude documentation files (LICENSE, README, CHANGELOG, etc.)
npx update-agents-md -d
# Only include TypeScript files (inverse logic - exclusive include mode)
npx update-agents-md -i "*.ts"
# Only include TypeScript and JavaScript files
npx update-agents-md -i "*.ts, *.js"
# Combine options: only TypeScript, exclude docs, limit to 100 lines per file
npx update-agents-md -d -i "*.ts" -l 100
# Exclude test files
npx update-agents-md --no-tests
# Exclude style files
npx update-agents-md --no-styles
# Generate .d.ts for TypeScript files (improves LLM inference context)
npx update-agents-md --dts
# Set project name explicitly
npx update-agents-md -p "my-awesome-project"
# Use a custom tag name
npx update-agents-md -t "codebase-snapshot"The --project flag adds a project-name attribute to the output tag:
<full-context-dump project-name="my-project">
...
</full-context-dump>Auto-detection: If package.json exists in the target directory and contains a name field, it's automatically used as the project name. The -p flag overrides this.
# Auto-detect from package.json
npx update-agents-md
# Override with explicit name
npx update-agents-md -p "my-custom-name"The --tag flag lets you customize the XML tag name used in the output:
# Use a custom tag instead of 'full-context-dump'
npx update-agents-md -t "codebase-snapshot"agents.md files that use the same tag name. Files with different tag names won't be recognized or updated. If you need to migrate from one tag name to another, you'll need to manually edit the existing agents.md file or delete it and regenerate.
<!-- This file uses the default tag -->
<full-context-dump>
...
</full-context-dump>
<!-- This file uses a custom tag - requires --tag "codebase" to update -->
<codebase>
...
</codebase>The -i flag enables exclusive include mode. When specified, only files matching at least one of the comma-separated glob patterns will be included.
Important: .gitignore and .agentsignore rules still apply! Files excluded by these ignore files will NOT be included even if they match an include pattern.
# Only include .ts files
update-agents-md -i "*.ts"
# Include .ts and .c files
update-agents-md -i "*.ts, *.c"
# Patterns support wildcards
update-agents-md -i "test*.js, *.spec.ts"*- matches any characters except/?- matches a single character**- matches any path (including nested directories)
The tool respects:
.gitignore- standard Git ignore patterns.agentsignore- custom patterns specific to this tool
If no .agentsignore exists, a default one is created with sensible defaults (node_modules, dist, build, coverage, etc.).
When -d / --docs is specified, the following patterns are excluded:
*.md,*.markdown,*.asciidoc,*.adoc,*.rstLICENSE,LICENSE*,LICENSE-*COPYING,COPYING*CHANGELOG,CHANGELOG*
The tool writes to agents.md using this format:
<full-context-dump>
./path/to/file.ts:
```ts
// file contents./path/to/another.js:
// file contentsWith a project name:
<full-context-dump project-name="my-project">
./src/index.ts:
```ts
// file contentsIf agents.md already exists with these tags, content between the tags is replaced while preserving any content before or after.
MIT