Metadata-Version: 2.4
Name: treemapper
Version: 1.3.2
Summary: Export codebase structure and contents for AI/LLM context
Author-email: Nikolay Eremeev <nikolay.eremeev@outlook.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/nikolay-e/treemapper
Project-URL: Repository, https://github.com/nikolay-e/treemapper
Project-URL: Issues, https://github.com/nikolay-e/treemapper/issues
Project-URL: Changelog, https://github.com/nikolay-e/treemapper/releases
Keywords: code-analysis,directory-tree,yaml,json,llm,ai,codebase,context,chatgpt,claude,code-context,export,tree,gpt-context,llm-context,code-to-prompt,claude-context
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pathspec<2.0,>=0.11
Requires-Dist: pyyaml<8.0,>=6.0.2
Requires-Dist: tiktoken<1.0,>=0.7
Requires-Dist: mistune<4.0,>=3.0
Requires-Dist: ruamel.yaml<1.0,>=0.18
Requires-Dist: lxml<7.0,>=5.0
Provides-Extra: tree-sitter
Requires-Dist: tree-sitter<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-python<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-javascript<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-typescript<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-go<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-rust<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-java<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-c<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-cpp<1.0,>=0.22; extra == "tree-sitter"
Requires-Dist: tree-sitter-ruby<1.0,>=0.21; extra == "tree-sitter"
Requires-Dist: tree-sitter-c-sharp<1.0,>=0.21; extra == "tree-sitter"
Provides-Extra: full
Requires-Dist: treemapper[tree-sitter]; extra == "full"
Requires-Dist: pysbd<1.0,>=0.3; extra == "full"
Provides-Extra: embeddings
Requires-Dist: sentence-transformers<6.0,>=3.0; extra == "embeddings"
Provides-Extra: nlp
Requires-Dist: spacy<4.0,>=3.7; extra == "nlp"
Provides-Extra: dev
Requires-Dist: treemapper[tree-sitter]; extra == "dev"
Requires-Dist: pytest<10.0,>=7.0; extra == "dev"
Requires-Dist: pytest-cov<8.0,>=3.0; extra == "dev"
Requires-Dist: pytest-xdist<4.0,>=3.0; extra == "dev"
Requires-Dist: hypothesis<7.0,>=6.0; extra == "dev"
Requires-Dist: mutmut<4.0,>=2.0; extra == "dev"
Requires-Dist: coverage<8.0,>=7.0; extra == "dev"
Requires-Dist: ruff<1.0,>=0.4; extra == "dev"
Requires-Dist: black<27.0,>=23.0.0; extra == "dev"
Requires-Dist: isort<9.0,>=5.12; extra == "dev"
Requires-Dist: mypy<2.0,>=1.0; extra == "dev"
Requires-Dist: radon<7.0,>=6.0; extra == "dev"
Requires-Dist: import-linter<3.0,>=2.0; extra == "dev"
Requires-Dist: pre-commit<5.0,>=3.0; extra == "dev"
Requires-Dist: autoflake<3.0,>=2.0; extra == "dev"
Requires-Dist: types-PyYAML<7.0,>=6.0; extra == "dev"
Requires-Dist: build<2.0,>=0.10; extra == "dev"
Requires-Dist: twine<7.0,>=4.0; extra == "dev"
Requires-Dist: pyinstaller<7.0,>=5.0; extra == "dev"
Requires-Dist: urllib3>=2.6.0; extra == "dev"
Dynamic: license-file

# TreeMapper

[![CI](https://github.com/nikolay-e/treemapper/actions/workflows/ci.yml/badge.svg)](https://github.com/nikolay-e/treemapper/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/nikolay-e/treemapper/branch/main/graph/badge.svg)](https://codecov.io/gh/nikolay-e/treemapper)
[![PyPI](https://img.shields.io/pypi/v/treemapper)](https://pypi.org/project/treemapper/)
[![Python versions](https://img.shields.io/pypi/pyversions/treemapper)](https://pypi.org/project/treemapper/)
[![Downloads](https://img.shields.io/pypi/dm/treemapper)](https://pypi.org/project/treemapper/)
[![License](https://img.shields.io/pypi/l/treemapper)](https://pypi.org/project/treemapper/)

**Export your codebase for AI/LLM context in one command.**

```bash
pip install treemapper                    # core (no native extensions)
pip install 'treemapper[tree-sitter]'     # + AST parsing for 10 languages
treemapper . -o context.yaml              # paste into ChatGPT/Claude
```

## Why TreeMapper?

Unlike `tree` or `find`, TreeMapper exports **structure + file
contents** in a format optimized for fast comprehension:

```yaml
name: myproject
type: directory
children:
  - name: main.py
    type: file
    content: |
      def hello():
          print("Hello, World!")
  - name: utils/
    type: directory
    children:
      - name: helpers.py
        type: file
        content: |
          def add(a, b):
              return a + b
```

## Usage

```bash
treemapper                               # current dir, YAML to stdout
treemapper .                          # YAML to stdout + token count
treemapper . -o tree.yaml             # save to file
treemapper . -o                       # save to tree.yaml (default)
treemapper . -o -                     # explicit stdout output
treemapper . -f json                  # JSON format
treemapper . -f txt                   # plain text with indentation
treemapper . -f md                    # Markdown with fenced code
treemapper . -f yml                   # YAML (alias)
treemapper . --no-content             # structure only
treemapper . --max-depth 3            # limit depth (0=root, 1=children)
treemapper . --max-file-bytes 10000   # skip files > 10KB (default: 10 MB)
treemapper . --max-file-bytes 0       # no limit
treemapper . -i custom.ignore         # custom ignore patterns
treemapper . --no-default-ignores     # disable .gitignore + defaults
treemapper . --log-level info         # log level (default: error)
treemapper . -c                       # copy to clipboard
treemapper . -c -o tree.yaml          # clipboard + save to file
treemapper -v                         # show version
```

## Diff Context Mode

Smart context selection for git diffs — automatically finds the
minimal set of code fragments needed to understand a change:

```bash
treemapper . --diff HEAD~1..HEAD      # recent changes
treemapper . --diff main..feature     # feature branch
treemapper . --diff HEAD~1 --budget 30000  # limit tokens
treemapper . --diff HEAD~1 --full     # all changed code
```

Uses graph-based relevance propagation (Personalized PageRank)
to select the most important context. Output size is controlled
by algorithm convergence (τ-stopping) by default, or an explicit
`--budget` token limit. Understands imports, type references,
config dependencies, and co-change patterns across 15+
programming languages.

Output format:

```yaml
name: myproject
type: diff_context
fragment_count: 5
fragments:
  - path: src/main.py
    lines: "10-25"
    kind: function
    symbol: process_data
    content: |
      def process_data(items):
          ...
```

| Flag       | Default       | Description                                    |
|------------|---------------|------------------------------------------------|
| `--budget` | none          | Token limit (convergence-based by default)     |
| `--alpha`  | 0.60          | PPR damping factor                             |
| `--tau`    | 0.08          | Stopping threshold                             |
| `--full`   | false         | Include all changed code                       |

## Token Counting

Token count and size are always displayed on stderr:

```text
12,847 tokens (o200k_base), 52.3 KB
```

For large outputs (>1MB), approximate counts with `~` prefix:

```text
~125,000 tokens (o200k_base), 5.2 MB
```

Uses tiktoken with `o200k_base` encoding (GPT-4o tokenizer).

## Clipboard Support

Copy output directly to clipboard with `-c` or `--copy`:

```bash
treemapper . -c                       # copy (no stdout)
treemapper . -c -o tree.yaml          # copy + save to file
```

**System Requirements:**

- **macOS:** `pbcopy` (pre-installed)
- **Windows:** `clip` (pre-installed)
- **Linux (Wayland):** `wl-copy`
- **Linux (X11):** `xclip` or `xsel`

## Python API

```python
from treemapper import map_directory
from treemapper import to_yaml, to_json, to_text, to_markdown

tree = map_directory(
    path,                    # directory path
    max_depth=None,          # limit traversal depth
    no_content=False,        # exclude file contents
    max_file_bytes=None,     # skip large files
    ignore_file=None,        # custom ignore file
    no_default_ignores=False,# disable default ignores
)

yaml_str = to_yaml(tree)
json_str = to_json(tree)
text_str = to_text(tree)
md_str = to_markdown(tree)
```

## Ignore Patterns

Respects `.gitignore` and `.treemapperignore` automatically.
Use `--no-default-ignores` to disable all ignore processing
(`.gitignore`, `.treemapperignore`, and built-in defaults).

- Hierarchical: nested ignore files at each directory level
- Negation patterns: `!important.log` un-ignores a file
- Anchored patterns: `/root_only.txt` matches only in root
- Output file is always auto-ignored

## Content Placeholders

- `<file too large: N bytes>` — exceeds `--max-file-bytes`
- `<binary file: N bytes>` — binary file detected
- `<unreadable content: not utf-8>` — not valid UTF-8
- `<unreadable content>` — permission denied or I/O error

## License

Apache 2.0
