Skip to main content

Overview

Splat leverages Git repository information to provide context-aware debugging. By understanding .gitignore patterns, repository boundaries, and project structure, Splat focuses analysis on relevant code while respecting your project’s organization.

Project Root Detection

Finding the Repository Root

Splat identifies the project root to establish boundaries:
relational.py
project_root = os.getcwd()
collected_traceback_files = parse_error_stack(traceback)
utils/utils.py
def is_project_file(file_path: str, project_root: str) -> bool:
  return os.path.commonpath([file_path, project_root]) == project_root
The project root is determined by the current working directory when Splat is invoked. This should typically be your Git repository root.

Why Root Detection Matters

Prevents Splat from analyzing system Python files or dependencies in virtual environments.
Enables correct resolution of absolute imports relative to project structure.
Ensures only relevant project files are sent to the LLM, reducing token usage.

File Filtering

Project File Validation

Before processing any file, Splat validates it’s within project bounds:
utils/utils.py
def process_file(file: str):
    if file in processed_files or not is_project_file(file, project_root):
        return  # Skip external files

Path Comparison

The os.path.commonpath() function determines if a file is within the project:
# Example 1: Project file
file_path = "/home/user/project/src/main.py"
project_root = "/home/user/project"
commonpath = "/home/user/project"  # Matches project_root ✓

# Example 2: External file
file_path = "/usr/lib/python3.9/os.py"
project_root = "/home/user/project"
commonpath = "/"  # Doesn't match project_root ✗
This approach works even with symlinks and relative paths, as os.path.commonpath() resolves them first.

.gitignore Integration (Future Enhancement)

The current codebase includes framework detection and language identification logic (see detect_framework_or_language in utils/utils.py), suggesting future plans for .gitignore integration and smarter file filtering.

Planned Features

Based on the codebase structure, future versions may include:
1

.gitignore Parsing

Read and parse .gitignore patterns to exclude files
2

Node Modules Exclusion

Automatically skip node_modules/, venv/, and other dependency directories
3

Build Artifact Filtering

Ignore compiled files, build outputs, and cached data
4

Framework-Specific Rules

Apply framework-specific ignore patterns (e.g., Next.js .next/ directory)

Current Filtering Approach

While .gitignore integration isn’t implemented yet, Splat currently:
  • Only processes files mentioned in error traces (basic mode)
  • Only processes files imported by error trace files (relational mode with -r)
  • Validates all files exist on the filesystem before inclusion
  • Excludes files outside the project root
If your error trace references a file in node_modules/ or a virtual environment, Splat will currently skip it during the project boundary check. This is usually desirable behavior.

Repository Structure Analysis

Framework Detection

Splat includes comprehensive framework detection logic:
utils/utils.py
def detect_framework_or_language(command, directory='.'):
  indicators = {
    'python': {
      'commands': ['python', 'python3'],
      'files': [],
      'extensions': ['.py']
    },
    'nextjs': {
      'commands': ['next', 'npm run dev', 'yarn dev'],
      'files': ['next.config.js', 'pages'],
      'extensions': ['.jsx', '.tsx']
    },
    'django': {
      'commands': ['python manage.py runserver', 'django-admin'],
      'files': ['manage.py', 'settings.py'],
      'extensions': ['.py']
    },
    # ... 20+ frameworks supported
  }
While this function is currently marked as “NOT IMPLEMENTED” in the source, the infrastructure exists for framework-aware context collection in future versions.

Supported Frameworks

The detection system recognizes:

Python

Django, Flask, FastAPI

JavaScript

Next.js, React, Vue, Angular, Express

Compiled

Go, Rust, Java, Kotlin, Scala

Dynamic

Ruby on Rails, Laravel, .NET

Functional

Haskell, Scala, Julia

Scripting

Perl, Lua, R

Detection Strategy

The framework detector uses three strategies:
def check_command(cmd):
  for framework, data in indicators.items():
    if any(c in cmd for c in data['commands']):
      return framework
Example: npm run dev → Next.js

Context Packaging

Repopack Integration

Splat uses a “mock repopack” function to bundle context:
utils/utils.py
def run_mock_repopack(paths: List[str], style: str = 'json') -> str:
  result = []
  for path in paths:
    if os.path.exists(path):  # Validate file existence
      with open(path, 'r') as f:
        content = f.read()
      result.append(f"File: {path}\nContent:\n{content}\n")

  return "\n" + "="*50 + "\n".join(result) + "="*50 + "\n"
The function is named run_mock_repopack suggesting it may integrate with the actual Repopack tool in the future for more sophisticated context packaging.

Context Format

Files are concatenated with clear delimiters:
==================================================
File: /project/main.py
Content:
from utils import calculate

result = calculate(42)

==================================================
File: /project/utils.py
Content:
def calculate(x, y):
    return x + y

==================================================
This format is easy for LLMs to parse while maintaining clear file boundaries.

Repository Metadata (Future)

Potential Git Integration

Future versions could leverage Git for:

Recent Changes

Show files modified in recent commits to highlight potential error sources

Blame Analysis

Identify when and by whom error-prone code was introduced

Branch Context

Understand if errors are specific to certain branches

Commit Messages

Use commit history to understand code intent and changes

Example Implementation

Example: Git blame integration
import subprocess

def get_recent_changes(file_path: str, days: int = 7) -> dict:
  result = subprocess.run(
    ['git', 'log', '--since', f'{days} days ago', '--pretty=format:%h|%s', file_path],
    capture_output=True,
    text=True
  )
  commits = []
  for line in result.stdout.split('\n'):
    if line:
      hash, message = line.split('|', 1)
      commits.append({'hash': hash, 'message': message})
  return commits
This is a conceptual example and not currently implemented in Splat.

Working Directory Awareness

Path Resolution

Splat handles both absolute and relative paths:
relational.py
project_root = os.getcwd()
error_files = [os.path.join(project_root, file) for file in parse_error_stack(error_info)]

Relative Path Handling

Error traces often contain relative paths:
# Error trace shows:
File "./src/main.py", line 5

# Splat converts to absolute:
/home/user/project/src/main.py
1

Get CWD

os.getcwd() returns the directory where Splat was invoked
2

Join Paths

os.path.join() combines root and relative paths
3

Normalize

Resolve . and .. to canonical absolute paths

Best Practices

Always invoke Splat from your Git repository root to ensure correct path resolution:
cd /path/to/project
splat python src/main.py  # Correct
Not:
cd /path/to/project/src
splat python main.py  # May have incorrect project_root
When possible, use absolute paths in your entrypoint:
splat python /full/path/to/script.py
This eliminates ambiguity in path resolution.
Ensure your .gitignore excludes files you don’t want analyzed (once this feature is implemented):
__pycache__/
*.pyc
venv/
.env

Environment Isolation

Virtual Environment Handling

Splat automatically excludes virtual environment files:
# Virtual env file:
/home/user/project/venv/lib/python3.9/site-packages/requests/api.py

# Project root:
/home/user/project

# Common path:
/home/user/project/venv/...

# is_project_file() returns:
True (currently included)
Currently, Splat may include virtual environment files if they’re within the project directory. This is an area for future improvement using .gitignore integration.

Workaround

To exclude venv files now, ensure your virtual environment is outside your project:
# Good:
/home/user/venvs/myproject-env/
/home/user/projects/myproject/

# Risky:
/home/user/projects/myproject/venv/  # May be analyzed

Next Steps

How It Works

See how Git awareness fits into the overall architecture

Dependency Graphs

Learn how project structure affects dependency mapping

Build docs developers (and LLMs) love