---
name: treehouse-git
description: INVOKE THIS FIRST before any git operation on apps or projects. Git workflow for Treehouse apps and projects — repo bootstrapping, .gitignore setup, and Conventional Commits format. MUST be used whenever developing, creating, or modifying any app or project.
---

# treehouse-git Skill

Git workflow for all Treehouse apps and projects.

## Rule

Every directory under `/workspace/apps/<app>/` MUST have a local git repo. Check before doing any work. If missing, run the bootstrap procedure below.

## Bootstrap a New Repo

```bash
cd /workspace/apps/<app>

git init
git config user.email "agent@treehouse"
git config user.name "Treehouse Agent"

# Create a project-specific .gitignore (see .gitignore section below)
# Then stage everything and make initial commit:
git add .
git commit -m "chore: initial commit"
```

## NEVER Commit Secrets or Database Files

**Before every `git add`, check what you're staging.** Never commit:

- **Secrets**: API keys, tokens, passwords, private keys, credentials — whether in `.env` files, config files, JSON, YAML, or hardcoded in source code
- **Database files**: `*.db`, `*.sqlite`, `*.sqlite3`, `*.sql` dumps — these are runtime data, not source code

If you accidentally commit a secret, it is in the git history forever (even after deletion). Treat it as compromised and rotate it.

If a config file needs a secret at runtime, use environment variables or `.env` files (which are gitignored). Provide a `.env.example` with placeholder values instead.

## .gitignore — Project-Specific, Keep It Lean

**Do not paste a generic catch-all.** Look at what the project actually uses and only exclude what applies.

**Always include:**
```gitignore
# Secrets
.env
.env.*
!.env.example

# Database files
*.db
*.sqlite
*.sqlite3
```

**Add only what fits the project stack**, for example:

- Node.js: `node_modules/`, `npm-debug.log*`
- Python: `__pycache__/`, `*.pyc`, `.venv/`
- Build output (if applicable): `dist/`, `build/`, `.next/`, `.cache/`
- Large generated/binary files actually present: e.g. `*.mp4` only if the project stores video
- OS/editor noise: `.DS_Store`, `*.swp`

**Don't add entries for things that don't exist in the project.** A 5-line `.gitignore` that covers the real files is better than a 60-line one that doesn't.

## Conventional Commits Format

Every commit title MUST follow this format:

```
<type>(<scope>): <short description>
```

**Types:**
- `feat` — new feature or capability
- `fix` — bug fix
- `chore` — maintenance, deps, config (no production code change)
- `refactor` — restructure without changing behaviour
- `docs` — documentation only
- `style` — formatting, whitespace (no logic change)
- `test` — add or update tests

**Rules:**
- Title max 72 characters
- Use imperative mood: "add login page" not "added login page"
- Scope is optional but helpful: `feat(auth): add JWT refresh`
- Body: explain *what* and *why*, separated from title by a blank line

**Examples:**
```
feat(ui): add dark mode toggle

Adds a toggle in user settings that persists the theme preference
to localStorage. Defaults to system preference on first load.
```

```
fix(api): handle empty response from upstream

Upstream occasionally returns an empty body on 200. This caused
a JSON parse error. Now returns an empty object as fallback.
```

```
chore: update .gitignore to exclude build artefacts
```

## Audit Existing Apps

To check which apps are missing a git repo:

```bash
for d in /workspace/apps/*/; do
  if [ ! -d "$d/.git" ]; then
    echo "MISSING GIT: $d"
  fi
done
```
