# ai-digest: a single Markdown file of your codebase

> ai-digest is an MIT licensed TypeScript command line tool that aggregates a whole codebase into one Markdown file you can upload to a ChatGPT custom GPT or a Claude project, with ignore patterns, minify patterns for the files you do not want in the context, a watch mode and a library mode that returns strings, file lists and token estimates. The judgement is that the context budget is the real design constraint, and that the tool counts tokens for two model families precisely because the limits differ.

**khromov/ai-digest** — A CLI tool to aggregate your codebase into a single Markdown file for use with Claude Projects or custom ChatGPTs.

- Repository: https://github.com/khromov/ai-digest
- Website: https://www.npmjs.com/package/ai-digest
- Stars: 684 · Forks: 58
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/khromov-ai-digest

## One Markdown file, uploaded to a chat window

ai-digest is a command line tool that aggregates your codebase into a single Markdown file for use with Claude Projects or custom ChatGPTs, and the usage is one command run in your project directory.

```bash
npx ai-digest
```

That produces a file called codebase.md containing the whole codebase, and the rest of the readme explains what to do with it. For ChatGPT you create a custom GPT and upload the generated Markdown file to the GPT's knowledge base. For Claude you create a new project and add the Markdown file to the project knowledge.

There is one instruction in that section that is worth taking seriously, and it is the one most people skip. For the best results, re-upload the Markdown file before starting a new chat session, to make sure the model has the most up to date version of your codebase.

That is the fundamental limit of the approach, stated plainly. The knowledge base is a snapshot, and a conversation that continues for a day is reasoning about yesterday's code unless you refresh it. The tool is not trying to hide that, and the fact that the project also offers a watch mode, which rebuilds the file automatically when files change, is the answer to the same problem from the other direction.

The project is MIT licensed, written in TypeScript, published on npm as ai-digest at version 1.6.0, and the last push was on 2026-10-15. There are no GitHub releases, so the npm package is the artefact to depend on.

## The options decide what lands in the file

The option list is short, and each option answers a question you would otherwise answer by hand.

The input option takes one or more directories and defaults to the current directory, so you can point the tool at several trees at once. The output option names the file and defaults to codebase.md. The default ignore patterns can be switched off with the no default ignores flag, which matters when the tool skips something you need, and a custom ignore file can be given with the ignore file option, which defaults to a file named .aidigestignore.

The whitespace removal flag strips whitespace, which is worth having because indentation is a large share of the bytes in most source files and the model does not need it. The show output files option prints a list of the files that were included with size statistics and bar charts, and adding the word sort orders them by size, so the biggest files are first.

The minify file option names a custom minify file, defaulting to .aidigestminify, and the watch flag rebuilds the digest automatically when files change.

So the workflow the options describe is: decide what to exclude, decide what to shrink, then look at the size chart to see whether the result fits where you are going to paste it.

## Minify patterns keep a file in the digest without its content

The minify feature is the one that shows the tool understands the context budget, and it is worth understanding precisely what it does.

Minify file support means including files with placeholder content. A file matched by the minify patterns still appears in the output, so the model knows the file exists, but its content is replaced by a short placeholder. The library mode makes this explicit, and the placeholder text in the source is the sentence that a file exists but its content was excluded via the minify file.

That is a better trade than simply ignoring the file, because a model reasoning about a repository benefits from knowing that a particular file is there, and it costs a line instead of the whole file.

In library mode the description of a minified file can be customised, because the placeholder text is a presentation choice. There is a callback type for it, and the callback receives metadata about each minified file: the full path, the relative path shown in the output, the extension, the detected file type, and the default placeholder text.

```javascript
import aiDigest, { MinifyFileDescriptionCallback } from 'ai-digest';

const customMinifyDescription: MinifyFileDescriptionCallback = (metadata) => {
  return `# ${metadata.displayPath}\n\n` +
    `Minified .${metadata.extension.toLowerCase()} file\n` +
    `Size reduced for AI context optimization.\n\n`;
};
```

The readme also shows how to detect the minified files yourself, by checking whether the content of a file object contains the placeholder marker, and how to filter the file list down to, say, only the JavaScript files and join their contents into a digest of your own.

## Library mode returns strings, file lists and statistics

The tool is usable as a library, installed with npm install ai-digest, and the readme separates the entry points by what they return.

The main function generates the digest and writes it to a file, or returns it as a string when the output file is null, and it takes the input directory, the output file, a flag for whitespace removal, a value for the output file listing and a silent flag to suppress the console output.

There is a second function that returns the content together with the file list and the statistics, and the statistics carry the three counts you would want to check, the total number of files, the number that were minified, and the number that were included.

A third returns the individual file objects for custom filtering, with each one holding a file name and its content, and the minified files carrying the placeholder content instead of the real thing. That is the hook for a build script that wants to assemble the digest itself, by language or by directory, rather than accepting the tool's own ordering.

And a fourth returns the statistics without any content, which the readme suggests for analysis. It is the function to call before you generate anything, because it tells you the size of the problem.

The separation is a good sign for a library that is meant to be embedded, since the expensive part, the reading and the filtering, can be done once and reused for several different outputs.

## It counts tokens for two model families

The file statistics function returns more than sizes, and the extra fields are the interesting part.

Alongside the files, each with a path and a size in bytes, it returns a total for GPT tokens and a total for Claude tokens. The example shows the two numbers differing, with the same file list underneath, and the readme describes the result as files sorted by size, largest first, with total token counts.

So the tool is explicit that the two model families do not count the same way, which is exactly the fact that makes a context budget hard to plan. A digest that fits in one model's window may not fit in the other's, and a tool that only reported bytes would leave you guessing.

There is more of this in the repository than the readme shows. The package scripts include three separate commands for it, an analyze tokens command that runs a script called analyze-token-ratio, a calculate multiplier command, and a test multiplier command, and the names suggest the project is working out the ratio between the token count and the character count, which is the conversion you need when you are deciding whether a file fits.

The minified files show the placeholder size rather than their real size in the statistics, which means the totals describe what would actually be uploaded, not what the repository contains. That is the honest number for a context budget, and it is a detail that a naive implementation would get wrong.

## A conventional TypeScript package with a few extras

The package manifest describes a small, ordinary tool, and the few unusual entries are the interesting ones.

The package is ai-digest at version 1.6.0, with a description that says it aggregates files into a single Markdown file, and it publishes both the main entry point and the type definitions, so a TypeScript consumer gets the types without a separate package. There is a bin entry, so installing the package gives you the command. The engine requirement is Node 20 or newer.

The scripts are the usual set for a TypeScript project. The build removes the output directory and runs the compiler, the start script runs the source with ts-node, and the publish hook builds first. Tests run under Jest, linting and formatting are handled by ESLint and Prettier, and husky is installed by the prepare script so the hooks are in place after an install.

The repository has the two configuration files the tool reads at runtime, .aidigestignore and .aidigestminify, in the root, which is a nice touch, because it means a project that uses the tool has an example of both formats to copy. There is also a docker-compose file, a vendor directory, a Jest configuration, an ESLint flat configuration and a TypeScript configuration.

The three token related scripts are in the scripts directory alongside the source and the tests, which is the one place where the repository departs from the boilerplate, and it departs in the direction of the tool's actual problem, which is not building a digest but deciding whether the digest fits.

## Conclusion

ai-digest fits a developer who wants to reason about a repository with a chat model, because a single Markdown file is the unit those tools accept for a knowledge base or a project, and because the tool shows you which files were included and how large they are before you upload anything. It is the wrong choice if your repository is large enough to exceed the context window, since a digest is still a digest and the token estimates are there to tell you so, and it is the wrong choice if you need a live connection to the code, because the file has to be regenerated and re-uploaded when the code changes. Before you use it, run the show output files option and read the size chart, because that is how you find the file that is eating your budget, and decide which files should be minified rather than included in full.

## FAQ

### What does ai-digest do?

It is a command line tool that aggregates the files in a project into a single Markdown file, which you can upload to a ChatGPT custom GPT knowledge base or add to a Claude project. The default run is npx ai-digest in your project directory, which writes a file called codebase.md.

### What are the main options of ai-digest?

An input option taking one or more directories, an output option defaulting to codebase.md, a flag to disable the default ignore patterns, a custom ignore file defaulting to .aidigestignore, whitespace removal, an output file listing with size statistics that can be sorted, a custom minify file defaulting to .aidigestminify, and a watch mode that rebuilds the digest when files change.

### What is the minify file feature for?

It lets a file stay in the digest without its content. A file matched by the minify patterns appears in the output with a placeholder, so the model knows the file exists, and in library mode you can supply a callback to change how that placeholder is described.

### Can I use ai-digest as a library?

Yes, with npm install ai-digest. The readme documents a function that writes the digest, one that returns the content with the file list and statistics, one that returns the individual files for custom filtering, and one that returns the statistics alone, including total token counts for GPT and for Claude.

## Sources

- [Issues](https://github.com/khromov/ai-digest/issues)
- [khromov/ai-digest on GitHub](https://github.com/khromov/ai-digest)
- [License: MIT](https://github.com/khromov/ai-digest/blob/main/LICENSE)
- [Project website](https://www.npmjs.com/package/ai-digest)
- [README](https://github.com/khromov/ai-digest/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/khromov-ai-digest
