Skip to main content

FileMerger

Python PyPI Downloads Build Coverage License GitHub Release GitHub Stars

A developer-focused CLI that consolidates project files into a single AI-ready context document for LLMs.

Maintained by DjangoPlay.


FileMerger is a developer-focused CLI tool that consolidates project files into a single, AI-ready text output. It's built to be read by a model, not a human — the goal is to give an AI an accurate, low-noise, structurally-aware picture of "the underlying implementation" of a codebase or a slice of one.

It helps you:

  • Feed complete, structured code context to AI tools (ChatGPT, Gemini, Grok, Claude, etc.)
  • Target files/directories by name across multiple source roots, without hand-writing paths
  • Keep secrets out of what you paste into a chat window
  • Produce deterministic, git-ignore-aware snapshots for review or audit

Installation

pip install filemerger-cli

Basic Usage

Merge a directory:

filemerger src/

Merge from multiple named sources, targeting by directory/file name, skipping others:

filemerger --source app api --target views/ models.py --skip migrations/ __pycache__/

Stream Markdown straight to stdout (e.g. to pipe into a clipboard tool):

filemerger src/ --format markdown --stdout | pbcopy

Dry run (no file written):

filemerger . --dry-run

Advanced Usage

Default Output

Merge the current directory using the default output format with common filtering, limits, and statistics.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --no-tree --separator 80 --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

Markdown Output

Merge the current directory and generate Markdown output.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --format markdown --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

LLM Output

Merge the current directory using the LLM-optimized output format.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --llm --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

Compact LLM Output

Merge the current directory using the compact LLM output format.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --llm-compact --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

AI Markers Output

Merge the current directory using AI-friendly file boundary markers.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --ai-markers --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

JSON Output

Merge the current directory and generate JSON output.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --format json --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

Print to Standard Output

Merge the current directory and print Markdown output directly to the terminal.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --stdout --format markdown --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

Dry Run

Preview which files would be merged without generating any output.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --format markdown --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --max-lines-per-file 1000 --max-tokens 200000 --dry-run --stats --verbose

Without Secret Redaction

Merge the current directory while disabling automatic secret redaction.

filemerger . --source . --skip __pycache__/ node_modules/ .git/ --output merged --format markdown --no-tree --include Dockerfile "*.env.example" --exclude "*.min.js" "*.map" --allow-dir migrations,tests --allow-file .DS_Store --allow-ext .yaml,.yml,.toml --max-size 25 --follow-symlinks --sort path --no-redact-secrets --max-lines-per-file 1000 --max-tokens 200000 --stats --verbose

Selecting Files

There are two ways to choose input, and they can be combined in one run.

1. Explicit paths (original behavior)

filemerger src/ utils/helpers.py

Any mix of files and directories.

2. Name/path targeting — --source / --target / --skip

For codebases where you want "every views/ folder and every models.py file under these roots, except migrations":

filemerger --source users apidocs/views help/forms \
           --target views/ models.py \
           --skip migrations/ __pycache__/

Matching rules (identical for --target and --skip):

Entry form Meaning
views/ (trailing slash) Directory name, matched anywhere under a --source root
views/login.py (contains /, no trailing slash) An exact relative path from a --source root
models.py (no slash) A bare filename, matched anywhere under a --source root

If --target is omitted, every file under --source is a candidate (subject to the usual filtering below).

This replaces the standalone get_filemerger_paths.py helper script — its intent is now built directly into the main tool, with the directory matching bug fixed (it previously never actually included directory targets) and dependable pruning during the directory walk instead of fragile path-prefix comparisons.


Filtering

Applied to every candidate file, from either selection method:

  • Extensions — allow-listed (.py, .js, .ts, .json, .md, …). Extend with --allow-ext, or force-include a specific file regardless of extension with --include (glob, e.g. --include Dockerfile).
  • .gitignore — honored per-directory, the same way git does (a nested .gitignore only applies to its own subtree), plus an optional .filemergerignore with identical syntax.
  • Excluded directories/filesnode_modules, __pycache__, .git, migrations, tests, etc. by default. Restore one with --allow-dir/--allow-file; drop more with --exclude (glob).
  • Symlinks — not followed by default. Opt in with --follow-symlinks.
  • Binary files — detected via a null-byte heuristic (not just a failed extension check) and skipped, reported as such.
  • Max file size — 2 MB default, override with --max-size.

Safety

Secret redaction (on by default)

Before anything is written, file content is scanned for common secret shapes (AWS keys, generic api_key=..., bearer tokens, private key blocks, Slack/GitHub tokens) and matches are replaced with [REDACTED:SECRET]. Disable with --no-redact-secrets if you specifically need raw content. The number of redactions appears in --stats.

Context budgeting

filemerger . --stats --max-tokens 100000

--stats reports an approximate token count (character-based heuristic, no extra dependency). --max-tokens warns and exits non-zero if the merged output would exceed that budget — useful in scripts/CI before piping into a model with a fixed context window.

Per-file truncation

filemerger . --max-lines-per-file 400

Caps any single file's contributed lines, appending a [truncated after N lines] marker, so one huge generated file can't dominate the output.


Output Formats

Select with --format, or the older shorthand flags (kept for backward compatibility).

--format Shorthand flag Best for
default (none) Human review, audits
llm --llm / --llm-compact Legacy structured plain-text for AI ingestion
ai-markers --ai-markers Explicit <<<FILE>>> boundary markers
markdown Recommended default for AI chat tools — fenced code blocks, per-language syntax highlighting, renders cleanly
json Programmatic consumption — a list of {path, language, content, skipped, redactions, ...}

All formats (except json) are preceded by a directory-tree summary so the model sees project shape before content. Disable with --no-tree.

filemerger src/ --format markdown

Output Destination

By default, output is written to filemerger-output.txt (or -o <name>) in the current directory. Use --stdout to stream to stdout instead (status/stat lines go to stderr so stdout stays clean for piping):

filemerger src/ --format json --stdout > context.json

Statistics

filemerger src/ --stats

Reports: files, lines, bytes, estimated tokens, skipped files (binary / non-UTF8 / unreadable), and redacted-secret count.


Ordering

filemerger src/ --sort {path,name,size,mtime}

Default is path (deterministic, matches prior versions).


Configuration

Optional .filemerger.toml, discovered by searching upward from the current directory to the filesystem root (git-style), so it works the same whether you run filemerger from the project root or a subdirectory:

[filters]
max_file_size_mb = 1
exclude_dirs = ["tests"]

[output]
separator_length = 60

Runtime Overrides

CLI flags always win over .filemerger.toml, which always wins over built-in defaults:

CLI arguments → .filemerger.toml → config.py defaults
filemerger . \
  --allow-dir migrations,tests \
  --allow-ext .yaml \
  --allow-file .DS_Store \
  --max-size 5 \
  --separator 40

Design Goals

  • Deterministic output
  • Minimal configuration
  • AI-first formatting (Markdown/JSON as first-class formats, not afterthoughts)
  • Safe by default (secrets redacted, binaries skipped, symlinks not followed)
  • Predictable file ordering
  • Zero project mutation

License

This project is licensed under the MIT License. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

filemerger_cli-0.4.0.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

filemerger_cli-0.4.0-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file filemerger_cli-0.4.0.tar.gz.

File metadata

  • Download URL: filemerger_cli-0.4.0.tar.gz
  • Upload date:
  • Size: 24.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for filemerger_cli-0.4.0.tar.gz
Algorithm Hash digest
SHA256 bbe415587f9ab063ea176279ffae2f0344a5e6f3e096d8a7fb5b447ca4df66f9
MD5 bebd9634d957b72de2cef7d0358f7372
BLAKE2b-256 a9289fd4467c7bde3430ff3dac887760afbb29571967a53d2fa888cf5bf9940e

See more details on using hashes here.

File details

Details for the file filemerger_cli-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: filemerger_cli-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for filemerger_cli-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 290570e72a08aa8376c01c74d62c761a2e82f6a10d483d58412ae906b8170dea
MD5 45f580b92759850852ebeabc8a3fd4be
BLAKE2b-256 b38922fd997dfeeff2bda887a005c205216d3dea1e1da68c37a4a2d6702c5686

See more details on using hashes here.

Release history Release notifications | RSS feed

0.4.1

2 files

This release

0.4.0 This release

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page