Skip to main content

An intelligent tool to map, analyze, and compile project source code for LLM context.

Project description

ProjectScriber Logo
ProjectScriber Name

License Latest Version PyPI Version

An intelligent tool to map, analyze, and compile project source code into a single, context-optimized text file for Large Language Models (LLMs), available as both a powerful CLI and a flexible Python library.

📖 Table of Contents


🤔 Why ProjectScriber?

When working with Large Language Models, providing the full context of a codebase is crucial for getting accurate analysis, documentation, or refactoring suggestions. Manually copying and pasting files is tedious, error-prone, and unsustainable for projects of any real size. ProjectScriber automates this entire process. It intelligently scans your project, respects your existing .gitignore rules, applies custom filters, and bundles all relevant code into a single, clean, and readable format perfect for any AI model.

📁 Your Codebase → 📦 ProjectScriber → 📋 LLM-Ready Context


✨ Key Features

Feature Description
🌳 Smart Project Mapping Generates a clear and intuitive tree view of your project's structure.
⚙️ Intelligent Filtering Automatically respects .gitignore and supports custom include, exclude, and hidden patterns. You can even define language-specific exclusions!
📊 In-depth Code Analysis Provides a summary with total file size, estimated token count (using cl100k_base), and a language breakdown.
🐍 Flexible Python Library Import and use the Scriber class directly in your Python projects for full programmatic control.
✨ Interactive CLI A simple scriber init command walks you through creating a configuration file for your project.
📋 Clipboard Integration Use the --copy flag to automatically send the entire output to your clipboard, ready for pasting.
💨 Lightweight & Fast The default installation is minimal, and file analysis is multi-threaded for improved performance.

🚀 Quick Start

Install the package directly from the Python Package Index (PyPI).

  1. Install Scriber:

    pip install project-scriber
    
  2. Navigate to your project's root and run:

    scriber
    
  3. That's it! A scriber_output.txt file is now in your directory. It will look something like this:

    ===
     Mapped Folder Structure
    ===
    
    ProjectScriber
    ├── .github
    │   └── workflows
    │       ├── ci.yml
    │       └── release.yml
    ├── README.md
    └── src
        └── scriber
            ├── __init__.py
            └── core.py
    
    ---
    File: .github/workflows/ci.yml
    Size: 512 bytes
    ---
    ```yaml
    name: Continuous Integration
    
    on:
      push:
        branches:
          - develop
    
    jobs:
      run_tests:
    ...
    

💾 Installation

You have two options for installation.

Standard Installation

This provides the core functionality with a minimal, text-based interface.

pip install project-scriber

With Rich UI ✨

For an enhanced terminal experience with colors, tables, and progress bars, install the rich extra:

pip install project-scriber[rich]

🖥️ Command-Line Usage

Basic Commands

  • Scan the current directory:
    scriber
    
  • Scan a different directory:
    scriber /path/to/your/project
    
  • Interactive Setup: Create a configuration file (.scriber.json or pyproject.toml) for your project.
    scriber init
    

CLI Options

Option Alias Description
root_path The project directory to map. Defaults to the current directory.
--output [file] -o Set a custom name for the output file.
--config [path] Path to a custom config file (e.g., a pyproject.toml in a monorepo).
--copy -c Copy the final output to the clipboard.
--tree-only Generate only the file tree structure, without any file content.
--version -v Show the installed version of ProjectScriber.
--help -h Display the help message.

Advanced Example

Scan another project, save the output to custom_map.txt, and copy the result to the clipboard in one go:

scriber ../my-other-project --output custom_map.txt --copy

📚 Library Usage (API)

Use ProjectScriber directly in your Python code for maximum flexibility and automation.

Basic Example: Get Context as a String

Initialize Scriber, and it will automatically handle mapping and analysis.

from pathlib import Path
from scriber import Scriber  # The class is exposed for direct import

# 1. Initialize Scriber for the current directory
scriber = Scriber(root_path=Path('.'))

# 2. Get the complete output directly as a string
project_context = scriber.get_output_as_string()

# 3. Use the context for your application
print(f"Generated context of {len(project_context)} characters.")

# 4. Access the calculated statistics
stats = scriber.get_stats()
print(f"Total files mapped: {stats['total_files']}")
print(f"Estimated tokens: {stats['total_tokens']:,}")

Advanced Configuration via Dictionary

Bypass all on-disk configuration files by passing a dictionary directly to the constructor. This is perfect for dynamic or controlled environments.

from pathlib import Path
from scriber import Scriber

my_config = {
    "use_gitignore": True,
    "exclude": ["node_modules/", "dist/"],
    "include": ["*.py", "*.js", "Dockerfile"],
    "hidden": ["poetry.lock", "package-lock.json"],
    "exclude_map": {
        "global": ["*.log", "temp.*"],
        "python": ["*_test.py", "conftest.py"],
        "javascript": ["*.min.js"]
    }
}

scriber = Scriber(root_path=Path('/path/to/your/project'), config=my_config)
project_context = scriber.get_output_as_string()
print(project_context)

Scanning Multiple Directories

You can pass a list of paths to the Scriber constructor to map multiple directories into a single output. The first path in the list is treated as the "primary root" for loading configurations (.gitignore, pyproject.toml, etc.).

from pathlib import Path
from scriber import Scriber

# Example: Scan both a 'backend' and a 'frontend' directory
backend_path = Path('./my_backend_project')
frontend_path = Path('./my_frontend_project')

# Create dummy directories and files for the example
backend_path.mkdir(exist_ok=True)
(backend_path / "main.py").write_text("print('hello from backend')")
frontend_path.mkdir(exist_ok=True)
(frontend_path / "app.js").write_text("console.log('hello from frontend')")

# Initialize with a list of paths. `backend_path` is the primary root.
scriber = Scriber(root_path=[backend_path, frontend_path])

# Get the combined context as a single string
combined_context = scriber.get_output_as_string()
print(combined_context)

# The output will contain two separate trees and file content blocks,
# with file paths prefixed by their root folder's name.

Accessing Intermediate Data

You can also access the generated file tree and the list of mapped files before the final output is compiled.

from pathlib import Path
from scriber import Scriber

scriber = Scriber(root_path=Path('.'))

# Get just the formatted file tree
tree_representation = scriber.get_tree()
print("--- Project Tree ---")
print(tree_representation)

# Get a list of all mapped file paths
print("\n--- Mapped Files ---")
file_paths = scriber.get_mapped_files()
for path in file_paths:
    print(path.relative_to(scriber.primary_root))

Practical Example: Preparing Context for an LLM

Here's a small function demonstrating how you can use ProjectScriber to generate a complete, well-formatted prompt for an LLM.

from pathlib import Path
from scriber import Scriber


def get_llm_context(project_path: Path, task: str) -> str:
    '''
    Generates a complete project context string ready for an LLM.

    Args:
        project_path: The root directory of the project.
        task: The specific task you want the LLM to perform.

    Returns:
        A formatted string to be used as a prompt for an LLM.
    '''
    # Initialize Scriber and get the project map
    scriber = Scriber(root_path=project_path)
    project_map = scriber.get_output_as_string()

    # Get some stats for the context header
    stats = scriber.get_stats()
    token_count = stats.get("total_tokens", 0)

    # Assemble the final prompt for the LLM
    prompt = (
        f"Please perform the following task: {task}\n\n"
        f"Here is the full context of the project codebase. "
        f"It includes a file tree and the content of all relevant files.\n"
        f"Estimated Token Count: {token_count:,}\n\n"
        "--- PROJECT CONTEXT BEGINS ---\n"
        f"{project_map}"
        "--- PROJECT CONTEXT ENDS ---"
    )

    return prompt


# --- Usage ---
if __name__ == "__main__":
    my_project_path = Path('.')
    user_task = "Analyze the code for potential bugs and suggest improvements."
    llm_prompt = get_llm_context(my_project_path, user_task)

    print(llm_prompt)

    # Now you can send `llm_prompt` to your favorite LLM API.

⚙️ Configuration

ProjectScriber is configured via a file in your project's root. It searches for configurations in the following order of precedence:

  1. Direct config dictionary (Library mode only).
  2. --config [path] flag (CLI mode only).
  3. .scriber.json in the project root.
  4. [tool.scriber] section in pyproject.toml.
  5. Default Config: If no file is found, a default .scriber.json is created on the first run.

Configuration Keys

Key Type Default Description
use_gitignore boolean true If true, all patterns in the .gitignore file will be used for exclusion.
exclude list See core.py A list of file/folder names or patterns to exclude globally (e.g., "node_modules", "*.log").
include list [] If not empty, only files matching these patterns will be included.
hidden list [] Files matching these patterns will appear in the tree but their content will be replaced with a placeholder. Useful for large lock files.
exclude_map object {} A dictionary for language-specific and global exclusion patterns. See example below.
output string "scriber_output.txt" The default name for the output file.

Example pyproject.toml Configuration

Here is an example of a well-configured [tool.scriber] section in your pyproject.toml file:

[tool.scriber]
# Respect the project's .gitignore file
use_gitignore = true

# Globally exclude common folders and file types
exclude = [
    "__pycache__",
    "node_modules",
    "dist",
    "build",
    ".venv",
]

# Only include files with these extensions
include = [
    "*.py",
    "*.js",
    "*.css",
    "*.md"
]

# Show these files in the tree, but hide their content
hidden = [
    "poetry.lock"
]

# Language-specific and global exclusion rules
[tool.scriber.exclude_map]
# Exclude these patterns from all files
global = ["*.log", "*.tmp"]
# In Python files, exclude tests and setup scripts
python = ["*_test.py", "setup.py"]
# In JavaScript files, exclude spec files
javascript = ["*.spec.js"]

💡 Note on Excluding Directories: For patterns that should only match directories (e.g., build/), it's best practice to use your .gitignore file, which has more advanced pattern matching that ProjectScriber understands.


🤝 Contributing & Development

Contributions are welcome! If you have a suggestion or find a bug, please open an issue to discuss it first.

Development Setup

  1. Prerequisites:

    • Python 3.10 or higher.
  2. Clone the Repository:

    git clone https://github.com/SunneV/ProjectScriber.git
    
  3. Navigate to the Project Directory:

    cd ProjectScriber
    
  4. Install Dependencies: Choose one of the following methods to install the project in editable mode with all development dependencies.

    • Using pip:

      pip install -e .[dev]
      
    • Using uv:

      uv sync --all-packages --extra dev
      

Running Tests

Run the test suite using pytest:

pytest

Project details


Download files

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

Source Distribution

project_scriber-1.1.0.tar.gz (33.7 kB view details)

Uploaded Source

Built Distribution

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

project_scriber-1.1.0-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file project_scriber-1.1.0.tar.gz.

File metadata

  • Download URL: project_scriber-1.1.0.tar.gz
  • Upload date:
  • Size: 33.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.8.17

File hashes

Hashes for project_scriber-1.1.0.tar.gz
Algorithm Hash digest
SHA256 767e37bb7be6d7e7141c9f7fe6be1a6e6b70ce5d3c9b87c2114f35e019912381
MD5 200dc05c757ece8578dc7bbb2ca66c1d
BLAKE2b-256 3d1137e0c8a78a6d2dba6eed19cd1d0374d73912cb5a388a265eb4b6d22830b3

See more details on using hashes here.

File details

Details for the file project_scriber-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for project_scriber-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f09102afde4ddd4057e661e4dde7b9c79bf562ade4b1cd49d41cc1e0d9772cee
MD5 8ae27e67762073a879a44b8369cb6089
BLAKE2b-256 4144848d1632d60e08d54402f5ee53cbef54e162fcef964dedd4c16b7a362372

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page