{"id":34853849,"url":"https://github.com/nikolay-e/treemapper","last_synced_at":"2026-04-09T00:07:24.570Z","repository":{"id":321990260,"uuid":"874863439","full_name":"nikolay-e/treemapper","owner":"nikolay-e","description":"Export your entire codebase to ChatGPT/Claude in one command. Structure + contents in YAML/JSON — optimized for LLM context windows.","archived":false,"fork":false,"pushed_at":"2026-03-22T22:06:25.000Z","size":7444,"stargazers_count":1,"open_issues_count":7,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-23T08:49:00.103Z","etag":null,"topics":["ai","anthropic","chatgpt","claude","cli","code-context","code-review","code-to-prompt","codebase","context-window","developer-tools","diff-context","directory-tree","git-diff","llm","llm-context","openai","prompt-engineering","python","yaml"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/treemapper","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nikolay-e.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-18T15:44:33.000Z","updated_at":"2026-03-22T22:06:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nikolay-e/treemapper","commit_stats":null,"previous_names":["nikolay-e/treemapper"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/nikolay-e/treemapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolay-e%2Ftreemapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolay-e%2Ftreemapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolay-e%2Ftreemapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolay-e%2Ftreemapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nikolay-e","download_url":"https://codeload.github.com/nikolay-e/treemapper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolay-e%2Ftreemapper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31304998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T09:48:21.550Z","status":"ssl_error","status_checked_at":"2026-04-02T09:48:19.196Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","anthropic","chatgpt","claude","cli","code-context","code-review","code-to-prompt","codebase","context-window","developer-tools","diff-context","directory-tree","git-diff","llm","llm-context","openai","prompt-engineering","python","yaml"],"created_at":"2025-12-25T19:56:35.962Z","updated_at":"2026-04-09T00:07:24.558Z","avatar_url":"https://github.com/nikolay-e.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TreeMapper\n\n[![CI](https://github.com/nikolay-e/treemapper/actions/workflows/ci.yml/badge.svg)](https://github.com/nikolay-e/treemapper/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/treemapper)](https://pypi.org/project/treemapper/)\n[![Downloads](https://img.shields.io/pypi/dm/treemapper)](https://pypi.org/project/treemapper/)\n[![License](https://img.shields.io/pypi/l/treemapper)](https://pypi.org/project/treemapper/)\n\n**Smart diff context for LLM code review.** Selects the minimal set of code\nfragments needed to understand a git change — instead of dumping entire files.\n\nAlso exports full codebase structure + contents in YAML/JSON/MD/txt.\nWorks with any LLM. 100% local, free, no GitHub dependency.\n\n```bash\npipx install treemapper\n\ntreemapper . --diff HEAD~1       # smart context for last commit → paste into Claude/ChatGPT\ntreemapper . -f md -c           # full export → clipboard in Markdown\n```\n\n![demo](docs/demo.gif)\n\n## Why not just use `tree` or repomix?\n\n| | `tree` | repomix | Claude Code Review | **TreeMapper** |\n|---|:---:|:---:|:---:|:---:|\n| **Primary use case** | directory listing | full repo export | automated PR review | **diff context for code review** |\n| Smart diff context | ✗ | ✗ | ✓ | ✓ |\n| Works with any LLM | ✓ | ✓ | Claude only | ✓ |\n| Free / local / offline | ✓ | ✓ | $15–25/review | ✓ |\n| GitHub required | ✗ | ✗ | ✓ | ✗ |\n| Multiple output formats | ✗ | limited | — | YAML/JSON/MD/txt |\n| Python API | ✗ | ✗ | ✗ | ✓ |\n\n## Installation\n\n```bash\npipx install treemapper                    # recommended: isolated, no venv needed\npip install treemapper                     # or with pip\npip install 'treemapper[tree-sitter]'      # + AST parsing for smarter diff context\n```\n\n**Standalone binary** (no Python required): download from the\n[releases page](https://github.com/nikolay-e/treemapper/releases/latest).\n\n\u003e Diff context mode works out of the box. Adding `[tree-sitter]` enables AST-level\n\u003e parsing for more accurate context selection across 12 languages.\n\n## Diff Context Mode\n\n**Paper:** [Context-Selection for Git Diff (Zenodo, 2026)](https://doi.org/10.5281/zenodo.18824580)\n\nAutomatically finds the minimal set of code fragments needed to understand\na change — imports, callers, type definitions, config dependencies — without\ndumping entire files. Understands 50+ file types.\n\n```yaml\nname: myproject\ntype: diff_context\nfragment_count: 5\nfragments:\n  - path: src/main.py\n    lines: \"10-25\"\n    kind: function\n    symbol: process_data\n    content: |\n      def process_data(items):\n          ...\n```\n\n### How it works\n\nUses Personalized PageRank on a code graph (imports, co-changes, type refs)\nto propagate relevance from changed lines outward. Stops when signal decays\nbelow threshold τ, or at an explicit `--budget` token limit.\n\n| Flag       | Default | Description                              |\n|------------|---------|------------------------------------------|\n| `--budget` | none    | Token limit (convergence-based by default) |\n| `--full`   | false   | Include all changed code, skip selection |\n| `--alpha`  | 0.60    | PPR damping factor                       |\n| `--tau`    | 0.08    | Convergence threshold                    |\n\n## Usage\n\n\u003c!-- BEGIN USAGE --\u003e\n```bash\n# full codebase export:\ntreemapper .                                # YAML to stdout + token count\ntreemapper . -f md -c                       # Markdown → clipboard\ntreemapper . -f json -o tree.json           # JSON → file\ntreemapper . --no-content                   # structure only, no file contents\ntreemapper . --max-depth 3                  # limit depth\ntreemapper . -i custom.ignore               # custom ignore patterns\n\n# diff context mode (requires git repo):\ntreemapper . --diff HEAD~1                  # context for last commit\ntreemapper . --diff main..feature           # context for feature branch\ntreemapper . --diff HEAD~1 --budget 30000   # limit to ~30k tokens\ntreemapper . --diff HEAD~1 -c               # diff context to clipboard\n```\n\u003c!-- END USAGE --\u003e\n\nFull codebase export output format:\n\n```yaml\nname: myproject\ntype: directory\nchildren:\n  - name: main.py\n    type: file\n    content: |\n      def hello():\n          print(\"Hello, World!\")\n  - name: utils/\n    type: directory\n    children:\n      - name: helpers.py\n        type: file\n        content: |\n          def add(a, b):\n              return a + b\n```\n\n## Token Counting\n\nToken count and size are always displayed on stderr:\n\n```text\n12,847 tokens (o200k_base), 52.3 KB\n```\n\nFor large outputs (\u003e1MB), approximate counts with `~` prefix:\n\n```text\n~125,000 tokens (o200k_base), 5.2 MB\n```\n\nUses tiktoken with `o200k_base` encoding (GPT-4o tokenizer).\n\n## Clipboard Support\n\nCopy output directly to clipboard with `-c` or `--copy`:\n\n```bash\ntreemapper . -c                       # copy (stdout suppressed, stderr: token count)\ntreemapper . -c -o tree.yaml          # copy + save to file\n```\n\n**System Requirements:**\n\n- **macOS:** `pbcopy` (pre-installed)\n- **Windows:** `clip` (pre-installed)\n- **Linux (Wayland):** `wl-copy`\n- **Linux (X11):** `xclip` or `xsel`\n\n## Python API\n\n```python\nfrom treemapper import map_directory\nfrom treemapper import to_yaml, to_json, to_text, to_markdown\n\ntree = map_directory(\n    path,                     # directory path\n    max_depth=None,           # limit traversal depth\n    no_content=False,         # exclude file contents\n    max_file_bytes=None,      # skip large files\n    ignore_file=None,         # custom ignore file\n    no_default_ignores=False, # disable default ignores\n    whitelist_file=None,      # include-only filter\n)\n\nyaml_str = to_yaml(tree)\njson_str = to_json(tree)\ntext_str = to_text(tree)\nmd_str = to_markdown(tree)\n\n# Diff context mode\nfrom treemapper import build_diff_context\n\nctx = build_diff_context(\n    root_dir,                 # Path to repository root\n    diff_range,               # e.g. \"HEAD~1..HEAD\", \"main..feature\"\n    budget_tokens=None,       # token limit (None = convergence-based)\n    alpha=0.6,                # PPR damping factor\n    tau=0.08,                 # stopping threshold\n    full=False,               # skip smart selection\n)\nyaml_str = to_yaml(ctx)\n```\n\n## Ignore Patterns\n\nRespects `.gitignore` and `.treemapper/ignore` automatically.\nUse `--no-default-ignores` to disable built-in patterns\n(`.gitignore` and `.treemapper/ignore` still apply).\n\n- Hierarchical: nested ignore files at each directory level\n- Negation patterns: `!important.log` un-ignores a file\n- Anchored patterns: `/root_only.txt` matches only in root\n- Output file is always auto-ignored\n\nAuto-discovered files:\n\n- `.treemapper/ignore` — TreeMapper-specific ignore patterns\n- `.treemapper/whitelist` — Include-only filter (only matched files included)\n\n## Content Placeholders\n\n- `\u003cfile too large: N bytes\u003e` — exceeds `--max-file-bytes`\n- `\u003cbinary file: N bytes\u003e` — binary file detected\n- `\u003cunreadable content: not utf-8\u003e` — not valid UTF-8\n- `\u003cunreadable content\u003e` — permission denied or I/O error\n\n## License\n\nApache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikolay-e%2Ftreemapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikolay-e%2Ftreemapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikolay-e%2Ftreemapper/lists"}