# Python
__pycache__/
*.py[cod]
*.egg-info/
*.egg
.eggs/
dist/
build/
.cache/pip/
.venv
venv/
env/

# Mypy / Ruff / Pytest
.mypy_cache/
.ruff_cache/
.pytest_cache/
.coverage
htmlcov/

# Node — no trailing slash so a worktree's `node_modules` *symlink*
# (created by scripts/wt) is ignored too, not just real directories.
node_modules

# Coverage
coverage/
coverage.xml

# uv lockfile. The api (APPLICATION) and the scheduler (published LIBRARY) both
# commit a resolved lock — for reproducible dev/CI installs and a scannable
# dependency surface: an SCA tool (security:osv) can audit a committed lockfile
# but not the version ranges a library declares. The published scheduler wheel
# still ships ranges from pyproject.toml; the lock is a repo-side artifact only
# (#904 api supply-chain hardening, #1153 scheduler OSV migration). Keep the
# blanket ignore for everything else.
uv.lock
!packages/api/uv.lock
!packages/scheduler/uv.lock

# Docker
*.override.yml

# OS
.DS_Store
Thumbs.db

# Editor
.idea/
.vscode/
*.swp
*.swo

# Docusaurus build cache
.docusaurus/

# Claude Code runtime state
.claude/scheduled_tasks.lock
.claude/worktrees/

# Playwright test runtime output
test-results/
packages/web/test-results/
packages/web/playwright-report/

# Local dev attachment + media blobs (Closes #817)
packages/api/attachments/
packages/api/media/
# Workspace logo blobs (#969) — local-disk storage root; prod uses object storage
packages/api/branding/

# Workspace export test/runtime artifacts (written by export tests; never committed)
packages/api/workspace-exports/
