Pack an entire project into one AI-ready context file: directory tree, full file contents, and token estimates.
Project description
ClioLens
One command. One file. Your whole codebase, ready for any AI.
ClioLens packs a project directory into a single markdown context dump with a visual directory tree, the full text of every relevant file, and metadata. It's designed to be attached to free web-based AI models (Qwen, Kimi, ChatGPT, Claude…) for whole-codebase analysis.
No API keys, local GPU, IDE extensions, or telemetry. Read-only.
Why
Free-tier web models accept file uploads but can't see your repo. Copy-pasting files one by one is slow and loses structure. ClioLens gives you the copy-paste workflow in one shot, with guardrails:
- Zero-config:
cliolens .produces something useful immediately. - Respects your project: build artifacts, dependencies, VCS data, and
.gitignorerules are excluded automatically. - Transparent: you always know what was included, what was skipped, and why.
- Model-aware: clean headers, syntax-fenced code, token budgets.
Requirements
- Python 3.10+ (on Windows 11, uv manages this for you)
- Any OS; developed and tested against Windows 11 (paths with spaces, Unicode, backslashes, and long paths all handled)
Installation
Prerequisites (one-time):
# uv — manages Python and packages for you
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Git — needed to fetch from GitHub (skip if you already have it)
winget install Git.Git
Install ClioLens (open a new terminal after the steps above):
uv tool install git+https://github.com/SPARTonScratch/cliolens
cliolens --version # verify
To pin a specific release instead of tracking main:
uv tool install git+https://github.com/SPARTonScratch/cliolens@v0.1.0
From source (for contributors)
git clone https://github.com/SPARTonScratch/cliolens
cd cliolens
uv tool install . # or: uv pip install -e ".[dev]" for editable + test tooling
Upgrade / uninstall: uv tool upgrade cliolens · uv tool uninstall cliolens.
Plain pip install . also works from a local clone.
Quickstart
# Dump the current directory, writes 'cliolens project context.md' right here
cliolens .
# Want it on stdout instead (to pipe or copy)?
cliolens . -o -
# Preview exactly what will be included before generating
cliolens . --dry-run
# Check against a 128K-token model window
cliolens . -t 128000
CLI reference
cliolens [OPTIONS] [DIRECTORY]
| Flag | Default | Description |
|---|---|---|
DIRECTORY |
. |
Root directory to scan |
-o, --output PATH |
cliolens project context.md |
Output file in the current directory (-o - for stdout; existing files overwritten) |
-m, --max-file-size SIZE |
100KB |
Larger files are truncated with a notice (B/KB/MB/GB) |
-e, --exclude GLOB |
— | Extra exclude pattern, repeatable (*.log, temp/, src/gen/*.py) |
-n, --no-gitignore |
off | Ignore .gitignore files (built-in exclusions still apply) |
-f, --follow-symlinks |
off | Follow symlinks (loop-safe via inode tracking) |
-d, --dry-run |
off | Report include/skip decisions without generating output |
-t, --max-tokens N |
0 |
Warn on stderr if the estimate exceeds N |
--show-binary |
off | Dump binary file contents as base64-encoded text in File Contents; without this flag, a placeholder notice (type + size) is shown instead. Binaries always appear in the tree and counts regardless. |
--version |
— | Print version and exit |
What gets excluded
Always (built-in): .git, .svn, .hg, node_modules, vendor,
__pycache__, .mypy_cache, .pytest_cache, .ruff_cache, .venv,
venv, env, ENV, dist, build, target, .out, .idea, .vscode,
.DS_Store, Thumbs.db, and files matching *.pyc *.pyo *.class *.o *.so *.dll *.exe *.bin *.lock.
Then: every .gitignore in the tree (root and nested, including !
negations and ** patterns, via the pathspec library).
Then: your --exclude globs — matched against the full relative path,
the basename (gitignore-style), or a path suffix. dir/ patterns prune the
whole directory.
Plus: the output file itself, as a safety guard so re-runs never dump the previous dump. On Windows all matching is case-insensitive.
Binary files (images, fonts, media, archives, ML artifacts…) are detected
by a built-in extension blacklist (fast path) with content analysis as the
fallback authority. They always appear in the directory tree, count toward
included files, and show a placeholder notice in the File Contents section
with their MIME type and size. Use --show-binary to replace the placeholder
with the file's full content as base64-encoded text (subject to
--max-file-size truncation, measured in bytes).
Anatomy of the output
# Project Context Dump
## Metadata
- **Project Name:** my-app
- **Root Path:** C:\Users\Dev\my-app
- **Generated At:** 2026-08-01 18:40:05 -02:00
- **Files Scanned:** 142
- **Files Included:** 87
- **Files Skipped:** 55
- **Estimated Tokens:** 45,210 (~180,840 characters)
- **Total Source Size:** 312.4KB
---
## Directory Tree
```
my-app/
├── src/
│ └── main.py
└── README.md
```
---
## File Contents
### src/main.py
```python
def main():
print("hello")
```
End of dump. Generated by cliolens v0.1.0
- Scanned = every file encountered; included = in the dump (truncated files and binary files count as included); skipped = excluded or unreadable.
- Oversized files keep their first 50 lines plus a truncation banner.
- With
--show-binary, binary placeholders are replaced with base64-encoded content in a code fence, truncated at--max-file-sizeif necessary.
Token estimation
ceil(characters / 4) is used to estimate token count, so expect ±20% of a real tokenizer on typical source. Diagnostics and warnings print to stderr in color (TTY-only, honors NO_COLOR), so piping stdout is always clean markdown.
Exit codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Input/runtime error (missing dir, permission denied, bad output path…) |
2 |
Usage error (unknown flag, malformed --max-file-size) |
130 |
Interrupted (Ctrl+C) |
Development
uv pip install -e ".[dev]" # editable install + test tooling
pytest # unit + integration tests
pytest --cov=cliolens # with coverage
ruff check src tests # lint
src/cliolens/
├── cli.py # argument parsing, orchestration, error presentation
├── scanner.py # traversal, filter pipeline, binary detection, metadata
├── formatter.py # tree rendering, markdown assembly, content wrapping
└── utils.py # token estimation, size formatting, path helpers
License
MIT License, see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cliolens-0.1.0.tar.gz.
File metadata
- Download URL: cliolens-0.1.0.tar.gz
- Upload date:
- Size: 83.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29cd6e15323e60cd99c2aae8946fef7f629a09067a7a54baf8ff9e1937131595
|
|
| MD5 |
c688e362d2e9d07342acd385a166e6b4
|
|
| BLAKE2b-256 |
7d8cc50136fc8f60cd5782edd0c03081b75842fa4ce13b77d18d03aa986a71a6
|
File details
Details for the file cliolens-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cliolens-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cfcb88f9ac1e86cb9a188d8dd509bd1b062548702000d38b77ced04665cdeb55
|
|
| MD5 |
6abf6c3ad0990d4300e4d521925e24d1
|
|
| BLAKE2b-256 |
66272e6e64b899cf1b89c24348ff43076060b00b1a1f42fe3b34e54612501ca3
|