Contributing

Development setup and contribution guidelines

Overview

Thank you for your interest in contributing to AI-Viewer! This guide covers development setup, code standards, and the contribution process.

Development Setup

Prerequisites

  • Python 3.10 or higher

  • Git

  • A PDAI document for testing (e.g., from ai-scholar processing)

Clone and Install

# Clone the repository
git clone https://github.com/grasshoff/ai-viewer.git
cd ai-viewer

# Create virtual environment (optional but recommended)
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode
pip install -e .

# Verify installation
ai-viewer --help

Project Structure

ai-viewer/
├── src/ai_viewer/
│   ├── __init__.py           # Package initialization
│   ├── __main__.py           # Entry point
│   ├── cli.py                # Command-line interface
│   ├── pdai_server.py        # FastAPI server
│   ├── pdai_converter.py     # Document format handling
│   ├── footnote_validator.py # Footnote validation
│   ├── viewer.py             # Core viewer logic
│   └── static/
│       └── main_viewer.html  # Viewer template
├── docs/                     # Quarto documentation
├── tests/                    # Test suite
├── pyproject.toml           # Package configuration
└── README.md

Running the Development Server

# Quick serve a document
ai-viewer ../pdai/E57 --port 5100 --debug

# With uvicorn directly (auto-reload)
uvicorn ai_viewer.pdai_server:app --reload --port 5100

Code Standards

Python Style

We follow PEP 8 with these preferences:

  • Line length: 100 characters maximum

  • Imports: Standard library, third-party, then local (separated by blank lines)

  • Docstrings: Google style for functions and classes

  • No type hints: Keep code clean and simple (per project preference)

Example Code Style

"""Module docstring explaining purpose."""

import os
from pathlib import Path

from fastapi import FastAPI

from ai_viewer.exceptions import DocumentNotFoundError


def load_document(path):
    """Load a PDAI document from the specified path.
    
    Args:
        path: Path to the PDAI document directory.
        
    Returns:
        Document object with loaded content.
        
    Raises:
        DocumentNotFoundError: If the path doesn't exist.
    """
    doc_path = Path(path)
    if not doc_path.exists():
        raise DocumentNotFoundError(f"Document not found: {path}")
    
    return Document(doc_path)

JavaScript Style

For viewer JavaScript:

  • No frameworks: Plain JavaScript only

  • Readable code: Clear variable names, comments for complex logic

  • DOM manipulation: Direct DOM access preferred over jQuery-style

HTML/CSS Style

  • Semantic HTML: Use appropriate elements (<nav>, <main>, <article>)

  • CSS variables: Use for theming and consistency

  • Responsive design: Mobile-first approach

Testing

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=ai_viewer

# Run specific test file
pytest tests/test_pdai_server.py

Writing Tests

# tests/test_document.py
import pytest
from ai_viewer import PdaiDocument

def test_load_document():
    """Test loading a valid PDAI document."""
    doc = PdaiDocument("../pdai/E57")
    assert doc.get_page_count() > 0

def test_load_nonexistent_document():
    """Test error handling for missing document."""
    with pytest.raises(DocumentNotFoundError):
        PdaiDocument("nonexistent/path")

Documentation

Building Documentation

cd docs

# Preview with auto-reload
quarto preview

# Build static site
quarto render

Documentation Style

  • Quarto markdown: Use .qmd files

  • Sandstone theme: Consistent with ai-scholar

  • British English: Preferred spelling

  • Clear structure: Use headings, tables, code blocks

See the AI-Scholar documentation standards for detailed guidelines.

Making Changes

Branch Naming

feature/segment-navigation
fix/footnote-validation
docs/api-reference-update

Commit Messages

Add segment navigation dropdown

- Load segments from manifest.json
- Populate dropdown with segment types
- Jump to segment start page on selection

Closes #42

Pull Request Process

  1. Fork the repository

  2. Create a feature branch

  3. Make your changes with clear commits

  4. Test your changes locally

  5. Update documentation if needed

  6. Submit a pull request

Areas for Contribution

High Priority

  • Segment navigation improvements — Better UI for complex segment structures

  • Agent layer switching — Smooth transitions between output layers

  • Performance optimisation — Faster loading for large documents

  • Accessibility — Screen reader improvements, keyboard navigation

Documentation

  • Examples — More usage examples and tutorials

  • API documentation — Expand endpoint descriptions

  • Integration guides — More cross-package workflow examples

Testing

  • Unit tests — Expand test coverage

  • Integration tests — Full workflow testing

  • Browser tests — Viewer functionality testing

Development Tips

Working with PDAI Documents

Keep a test document available:

# Process a test document with ai-scholar
ai-scholar process test.pdf
ai-scholar segment ../pdai/Test

# Use for development
ai-viewer ../pdai/Test --debug

Debugging the Server

# Enable debug mode for detailed logging
ai-viewer ../pdai/E57 --debug

# Check server logs
tail -f viewer.log

Debugging the Viewer

Open browser developer tools:

  • Console: Check for JavaScript errors

  • Network: Verify API calls

  • Elements: Inspect DOM structure

Release Process

Version Numbering

We follow semantic versioning (MAJOR.MINOR.PATCH):

  • MAJOR: Breaking changes

  • MINOR: New features, backwards compatible

  • PATCH: Bug fixes

Release Checklist

  1. Update version in pyproject.toml

  2. Update CHANGELOG.md

  3. Run full test suite

  4. Build and test documentation

  5. Create release tag

  6. Push to PyPI

Getting Help

Questions

  • Open a GitHub issue with the “question” label

  • Check existing issues for similar questions

Bugs

  • Open a GitHub issue with the “bug” label

  • Include: Python version, OS, steps to reproduce, expected vs actual behaviour

Feature Requests

  • Open a GitHub issue with the “enhancement” label

  • Describe the use case and proposed solution

Code of Conduct

  • Be respectful and inclusive

  • Focus on constructive feedback

  • Help newcomers get started

  • Acknowledge contributions

Licence

By contributing, you agree that your contributions will be licenced under the MIT Licence.

See Also