Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ I then used a combination of Aider w/Claude 3.7, Cline w/Gemini 2.5 Pro Preview
## Example Output

```
> python repomap.py . --chat-files repomap_class.py
> uv run repomapper . --chat-files repomap_class.py
Chat files: ['/mnt/programming/RepoMapper/repomap_class.py']
repomap_class.py:
(Rank value: 10.8111)
Expand Down Expand Up @@ -94,7 +94,11 @@ importance.py:
## Installation

```bash
pip install -r requirements.txt
# Install with uv (recommended)
uv sync

# Or install as editable package
uv pip install -e .
```

----------
Expand All @@ -105,34 +109,34 @@ pip install -r requirements.txt

```bash
# Map current directory
python repomap.py .
uv run repomapper .

# Map specific directory with custom token limit
python repomap.py src/ --map-tokens 2048
uv run repomapper src/ --map-tokens 2048

# Map specific files
python repomap.py file1.py file2.py
uv run repomapper file1.py file2.py

# Specify chat files (higher priority) vs other files
python repomap.py --chat-files main.py --other-files src/
uv run repomapper --chat-files main.py --other-files src/

# Specify mentioned files and identifiers
python repomap.py --mentioned-files config.py --mentioned-idents "main_function"
uv run repomapper --mentioned-files config.py --mentioned-idents "main_function"

# Enable verbose output
python repomap.py . --verbose
uv run repomapper . --verbose

# Force refresh of caches
python repomap.py . --force-refresh
uv run repomapper . --force-refresh

# Specify model for token counting
python repomap.py . --model gpt-3.5-turbo
uv run repomapper . --model gpt-3.5-turbo

# Set maximum context window
python repomap.py . --max-context-window 8192
uv run repomapper . --max-context-window 8192

# Exclude files with Page Rank 0
python repomap.py . --exclude-unranked
uv run repomapper . --exclude-unranked
```

The tool prioritizes files in the following order:
Expand All @@ -145,22 +149,22 @@ The tool prioritizes files in the following order:

```bash
# Enable verbose output
python repomap.py . --verbose
uv run repomapper . --verbose

# Force refresh of caches
python repomap.py . --force-refresh
uv run repomapper . --force-refresh

# Specify model for token counting
python repomap.py . --model gpt-3.5-turbo
uv run repomapper . --model gpt-3.5-turbo

# Set maximum context window
python repomap.py . --max-context-window 8192
uv run repomapper . --max-context-window 8192

# Exclude files with Page Rank 0
python repomap.py . --exclude-unranked
uv run repomapper . --exclude-unranked

# Mention specific files or identifiers for higher priority
python repomap.py . --mentioned-files config.py --mentioned-idents "main_function"
uv run repomapper . --mentioned-files config.py --mentioned-idents "main_function"
```

----------
Expand Down Expand Up @@ -271,23 +275,26 @@ RepoMap can also be run as an MCP (Model Context Protocol) server, allowing othe
"disabled": false,
"timeout": 60,
"type": "stdio",
"command": "/usr/bin/python3",
"command": "uv",
"args": [
"/absolute/path/to/repomap_server.py"
"run",
"--directory",
"/absolute/path/to/RepoMapper",
"repomap-mcp"
]
}
}
}
```

- Replace `"/absolute/path/to/repomap_server.py"` with the actual path to your `repomap_server.py` file.
- Replace `"/absolute/path/to/RepoMapper"` with the actual path to your RepoMapper installation directory.

### Usage

1. Run the `repomap_server.py` script:
1. Run the MCP server:

```bash
python repomap_server.py
uv run repomap-mcp
```

2. The server will start and listen for requests via STDIO.
Expand Down
46 changes: 39 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,55 @@
[build-system]
requires = ["setuptools>=69.0", "wheel"]
build-backend = "setuptools.build_meta"
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "repomapper"
version = "0.1.0"
requires-python = ">=3.13"
version = "0.1.1"
requires-python = ">=3.11"
dependencies = [
"diskcache>=5.6.0",
"fastmcp>=2.11.3",
"grep-ast>=0.3.0",
"networkx>=3.0",
"pygments>=2.14.0",
"scipy>=1.17.0",
"tiktoken>=0.5.0",
"tree-sitter>=0.20.0",
]

[project.scripts]
repomap-mcp = "repomap_server:main"
repomapper = "repomapper.repomap:main"
repomap-mcp = "repomapper.repomap_server:main"

[tool.setuptools]
py-modules = ["repomap_server", "repomap", "repomap_class", "utils", "importance", "scm"]
[tool.hatch.build.targets.wheel]
packages = ["src/repomapper"]

[tool.ruff]
line-length = 100

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"F", # pyflakes
"UP", # pyupgrade
"B", # flake8-bugbear
"I", # isort
]
ignore = [
"E501", # line too long (handled by formatter)
"E402", # module level import not at top of file
"E731", # do not assign a lambda expression, use a def
"W191", # indentation contains tabs
"E111", # indentation is not a multiple of four
"E114", # indentation is not a multiple of four (comment)
"E117", # over-indented
"D206", # indent with spaces
"D300", # use triple quotes
"Q000", # single quotes found but double quotes preferred
"Q001", # single quote multiline found but double quotes preferred
"Q002", # single quote docstring found but double quotes preferred
"Q003", # avoidable escaped quote
"COM812", # missing trailing comma
"COM819", # prohibited trailing comma
"ISC002", # multi-line implicit string concatenation
]
7 changes: 0 additions & 7 deletions requirements.txt

This file was deleted.

59 changes: 0 additions & 59 deletions scm.py

This file was deleted.

3 changes: 3 additions & 0 deletions src/repomapper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""RepoMapper - Generate repository maps for code understanding."""

__version__ = "0.1.1"
77 changes: 56 additions & 21 deletions importance.py → src/repomapper/importance.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,60 @@
"""

import os
from typing import List

IMPORTANT_FILENAMES = {
"README.md", "README.txt", "readme.md", "README.rst", "README",
"requirements.txt", "Pipfile", "pyproject.toml", "setup.py", "setup.cfg",
"package.json", "yarn.lock", "package-lock.json", "npm-shrinkwrap.json",
"Dockerfile", "docker-compose.yml", "docker-compose.yaml",
".gitignore", ".gitattributes", ".dockerignore",
"Makefile", "makefile", "CMakeLists.txt",
"LICENSE", "LICENSE.txt", "LICENSE.md", "COPYING",
"CHANGELOG.md", "CHANGELOG.txt", "HISTORY.md",
"CONTRIBUTING.md", "CODE_OF_CONDUCT.md",
".env", ".env.example", ".env.local",
"tox.ini", "pytest.ini", ".pytest.ini",
".flake8", ".pylintrc", "mypy.ini",
"go.mod", "go.sum", "Cargo.toml", "Cargo.lock",
"pom.xml", "build.gradle", "build.gradle.kts",
"composer.json", "composer.lock",
"Gemfile", "Gemfile.lock",
"README.md",
"README.txt",
"readme.md",
"README.rst",
"README",
"requirements.txt",
"Pipfile",
"pyproject.toml",
"setup.py",
"setup.cfg",
"package.json",
"yarn.lock",
"package-lock.json",
"npm-shrinkwrap.json",
"Dockerfile",
"docker-compose.yml",
"docker-compose.yaml",
".gitignore",
".gitattributes",
".dockerignore",
"Makefile",
"makefile",
"CMakeLists.txt",
"LICENSE",
"LICENSE.txt",
"LICENSE.md",
"COPYING",
"CHANGELOG.md",
"CHANGELOG.txt",
"HISTORY.md",
"CONTRIBUTING.md",
"CODE_OF_CONDUCT.md",
".env",
".env.example",
".env.local",
"tox.ini",
"pytest.ini",
".pytest.ini",
".flake8",
".pylintrc",
"mypy.ini",
"go.mod",
"go.sum",
"Cargo.toml",
"Cargo.lock",
"pom.xml",
"build.gradle",
"build.gradle.kts",
"composer.json",
"composer.lock",
"Gemfile",
"Gemfile.lock",
}

IMPORTANT_DIR_PATTERNS = {
Expand All @@ -41,18 +76,18 @@ def is_important(rel_file_path: str) -> bool:
for important_dir, checker_func in IMPORTANT_DIR_PATTERNS.items():
if dir_name == important_dir and checker_func(file_name):
return True

# Check if the full normalized path is important
if normalized_path in IMPORTANT_FILENAMES:
return True

# Check if just the basename is important
if file_name in IMPORTANT_FILENAMES:
return True

return False


def filter_important_files(file_paths: List[str]) -> List[str]:
def filter_important_files(file_paths: list[str]) -> list[str]:
"""Filter list to only include important files."""
return [path for path in file_paths if is_important(path)]
Loading