# Scaffold Repo

> Initialize a new Python repository with correct structure following RAE guidelines. Use when the user says "new repo", "new project", "initialize", "scaffold", "create a project", "set up a repo", or "start a new package". Creates src/ layout, pyproject.toml, tests, .gitignore, and optionally a devcontainer.

- Skill: `peabody124/scaffold-repo` (Agent Skill)
- Install (CLI): `npx skillmds@latest add peabody124/scaffold-repo`
- Raw SKILL.md: https://api.skillmd.com/api/skills/peabody124/scaffold-repo/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: peabody124 (https://skillmd.com/u/peabody124)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/peabody124/scaffold-repo

---


## Overview

This skill creates a properly structured Python repository from scratch. It enforces
the standards in `enforce-guidelines/references/repo-structure.md`.

**Use when:**
- Creating a new Python project
- Converting an unstructured project to proper layout
- User says "new repo", "new project", "initialize", "scaffold"

## Parameters

- **name** (required): Project name (lowercase, hyphens allowed)
- **description** (required): One-line project description
- **package_name** (optional): Python package name (defaults to name with underscores)
- **author** (optional): Author name (defaults to "James Cotton")
- **extras** (optional): Additional optional-dependencies groups to include

## Steps

### 1. Validate Inputs

- You MUST verify project name is lowercase with hyphens only
- You MUST derive package_name from project name (replace hyphens with underscores)
- You MUST NOT proceed without a description

### 2. Create Directory Structure

```bash
mkdir -p src/{package_name}
mkdir -p tests
touch src/{package_name}/__init__.py
touch src/{package_name}/py.typed
touch tests/__init__.py
```

- You MUST use src/ layout
- You MUST create both src/ and tests/ directories
- You MUST include py.typed marker for type hint support

### 3. Create pyproject.toml

Copy the canonical template from `templates/pyproject.toml` in the RAE plugin and customize:
- Replace `your-project-name` with `{name}`
- Replace `your_package` with `{package_name}`
- Replace author name/email
- Set the project description
- Add any project-specific dependencies

The template is the **single source of truth** for ruff, pytest, and coverage config.
Do not hardcode these values — always read from the template file.

- You MUST set line-length = 120
- You MUST put pytest and ruff in dev optional-dependencies
- You MUST NOT put dev tools in main dependencies

### 4. Create .gitignore

```gitignore
# Python
__pycache__/
*.py[cod]
*.egg-info/
dist/
build/
.eggs/

# Virtual environments
.venv/
venv/
ENV/

# IDE
.idea/
.vscode/
*.swp

# Testing
.pytest_cache/
.coverage
htmlcov/

# RAE
scraps/
scratch/
.rae-version

# OS
.DS_Store
Thumbs.db
```

### 5. Create README.md

```markdown
# {name}

{description}

## Installation

```bash
uv pip install -e ".[dev]"
```

## Development

```bash
# Run tests
pytest

# Format code
ruff format .

# Lint code
ruff check .
```
```

### 6. Create Initial Test Files

Create `tests/conftest.py`:

```python
"""Shared test fixtures."""
```

Create `tests/test_placeholder.py`:

```python
"""Placeholder test to verify pytest works."""


def test_placeholder() -> None:
    """Remove this test once real tests exist."""
    assert True
```

- You MUST include type hints (-> None)
- You MUST create conftest.py for shared fixtures

### 7. Initialize Git (if not already)

```bash
git init
git add .
git commit -m "feat: Initialize {name} with RAE structure"
```

- You MUST NOT commit if already in a git repo with uncommitted changes
- You SHOULD offer to commit but confirm with user first

### 8. Create CLAUDE.md

Create a `CLAUDE.md` with project-specific instructions. If the project uses DataJoint, **always** include this section:

```markdown
## CRITICAL: NEVER Modify Database Entries

**DO NOT update, delete, or alter any DataJoint database entries.** This includes:
- `update1()`, `delete()`, `drop()` on any table
- Modifying settings lookup tables (KinematicReconstructionSettingsLookup, ProbabilisticReconstructionSettingsLookup, KineticReconstructionSettingsLookup, KeypointSet, etc.)
- Altering any computed table entries

Database entries are shared state used by the entire lab. Changing a settings entry changes it for everyone and invalidates prior results computed with those settings.
```

- You MUST include this section if datajoint is in the project's dependencies
- You SHOULD include it by default for any biomechanics/motion-capture project

### 9. Verify Structure

```bash
ruff format .
ruff check .
pytest
```

- You MUST run ruff format before completing
- You MUST run ruff check with no errors
- You MUST run pytest with all tests passing

### 10. (Optional) Add Devcontainer

If the user wants devcontainer support, ask which template to use:

**Option 1: CPU-only (lightweight, faster startup)**
- Copy from `templates/devcontainer-cpu/devcontainer.json`
- Uses `mcr.microsoft.com/devcontainers/python:3.11`
- No GPU support, minimal dependencies
- Best for: web apps, APIs, general Python development

**Option 2: GPU-enabled (CUDA + cuDNN for ML/CV)**
- Copy from `templates/devcontainer-gpu/devcontainer.json`
- Uses `nvidia/cuda:12.6.0-cudnn-devel-ubuntu24.04`
- Includes: GPU access, OpenCV dependencies, git-lfs, Jupyter
- Requires: `--env-file .env` in project root
- Best for: machine learning, computer vision, biomechanics

Both templates:
- Install Claude Code, pyright, RAE plugin, and full plugin suite via `postCreateCommand`
- Mount `~/.claude` for config persistence
- Configure VSCode with ruff, Python testing, 120-char rulers
- Include Node.js via `"ghcr.io/devcontainers/features/node:1": {}` (required for excalidraw rendering via npx)
- No Dockerfile needed - everything via features and install script

**Beads (bead-driven development):**
Ask the user whether they want beads enabled for this project. Beads is **off by default**.
Only enable if the user explicitly opts in. If enabled, add the beads plugin to the
devcontainer's postCreateCommand install list.

**Note:** Ensure `~/.claude` exists on the host before starting: `mkdir -p ~/.claude`

**GPU template also requires:** Create a `.env` file in project root for secrets (gitignored)

## Adding Optional Dependencies

If user requests specific libraries, add appropriate optional-dependencies:

**OpenCV:**
```toml
[project.optional-dependencies]
opencv = ["opencv-python>=4.0.0"]
opencv-headless = ["opencv-python-headless>=4.0.0"]
opencv-contrib = ["opencv-contrib-python>=4.0.0"]
```

**PyTorch:**
```toml
[project.optional-dependencies]
torch-cpu = ["torch>=2.0"]
torch-cuda = ["torch>=2.0"]  # User installs with CUDA separately
```

**Jupyter:**
```toml
[project.optional-dependencies]
notebooks = ["jupyter>=1.0", "ipykernel>=6.0"]
```

**Headless 3D rendering (meshes / point clouds / video overlays):**
```toml
[project.optional-dependencies]
viz = ["pyrender>=0.1.45", "trimesh>=4.0", "PyOpenGL>=3.1", "opencv-python-headless>=4.0.0"]
```
This needs the EGL system libraries from the GPU devcontainer (`libgl1`,
`libegl1`, `libosmesa6-dev`) — already in `templates/devcontainer-gpu`. At
runtime the project must set `PYOPENGL_PLATFORM=egl` **before** importing any GL
library and verify it didn't fall back to the `llvmpipe` CPU rasterizer. Point
the user at the **`/efficient-rendering`** skill for the device-probing,
context-reuse, camera-convention, and video-compositing patterns rather than
re-deriving them here.

## Examples

**User:** "/scaffold-repo my-analysis-tool A tool for analyzing motion capture data"

**Agent:**
1. Creates directory structure
2. Generates pyproject.toml with name="my-analysis-tool", package="my_analysis_tool"
3. Creates .gitignore, README.md
4. Creates placeholder test
5. Runs ruff format, ruff check, pytest
6. Reports success with next steps

**User:** "/scaffold-repo cv-processor Image processing pipeline --extras opencv-headless"

**Agent:**
1. Creates standard structure
2. Adds opencv-headless to optional-dependencies
3. Completes verification

