# Dev Setup

> First-time Treadstone local development environment setup. Run once after cloning the repo and before starting any development. Covers system dependency installation, Python environment, Neon database connection, migrations, and environment verification. Use this skill when the user/agent just entered the project, needs to rebuild the environment, or encounters setup-related issues like missing dependencies, broken .env, or failed migrations.

- Skill: `earayu/dev-setup` (Agent Skill)
- Install (CLI): `npx skillmds@latest add earayu/dev-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/earayu/dev-setup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: earayu (https://skillmd.com/u/earayu)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/earayu/dev-setup

---


# First-Time Dev Environment Setup

Run this once. After completion, switch to the `dev-lifecycle` skill for daily development.

## 1. System Dependencies

Verify these tools are installed:

```bash
python3 --version        # 3.12+
uv --version             # Python package manager
gh --version             # GitHub CLI (optional, for PR/issue ops)
docker --version         # Container builds + Kind cluster
kind --version           # Local K8s cluster (sandbox dev only)
kubectl version --client # K8s CLI
helm version --short     # Helm chart deployment
hurl --version           # E2E testing (HTTP request runner)
```

Install missing tools (macOS):

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
brew install kind kubectl helm hurl
```

## 2. Install Repo Dependencies

```bash
make install
```

This installs Python dependencies with `uv`, installs web dependencies with `pnpm`, and configures git hooks.

## 3. Configure Database (Neon)

The project uses [Neon](https://neon.tech) Serverless PostgreSQL — no local Postgres needed.

For local API development (`make dev-api`), start from:

```bash
cp .env.example .env
```

Edit `.env` and set at least:

```
TREADSTONE_DATABASE_URL=postgresql+asyncpg://neondb_owner:xxx@ep-xxx.ap-southeast-1.aws.neon.tech/neondb?sslmode=require
TREADSTONE_JWT_SECRET=CHANGE_ME
```

The URL scheme must be `postgresql+asyncpg://` (not `postgresql://`). Keep `?sslmode=require`.

For local Kubernetes deployment (`make local`), also prepare:

```bash
cp .env.example .env.local
```

Then set:

```
TREADSTONE_DATABASE_URL=postgresql+asyncpg://...
TREADSTONE_JWT_SECRET=CHANGE_ME
TREADSTONE_LEADER_ELECTION_ENABLED=true
```

## 4. Apply Database Migrations

```bash
make migrate
```

Expected: `INFO [alembic.runtime.migration] Context impl PostgresqlImpl.` with migration details listed.

## 5. Verify Environment

```bash
make test
```

Expected: all tests pass (integration tests are excluded by default). If tests pass, the environment is ready.

Optional API sanity check:

```bash
make dev-api
# In another terminal:
curl http://localhost:8000/health
```

## 6. Local K8s Cluster (Sandbox Development)

For sandbox-related features that require a real Kubernetes cluster, follow `deploy/README.md` — use **`make local`** (and **`make destroy-local`** to tear down) so the Makefile runs context checks before Helm; smoke testing end-to-end.

Quick start:

```bash
kubectl config use-context kind-treadstone   # or your Kind context name
make local   # One-command: Kind cluster + build + deploy
curl -sf http://api.localhost/health   # API via Ingress (Web UI: http://app.localhost)
make test-e2e                          # default BASE_URL=http://api.localhost
```

Pure API development (`make dev-api`) does not require a K8s cluster.

---

## Troubleshooting

**`uv sync` fails:**
- Confirm Python 3.12+: `python3 --version`
- Try: `uv python install 3.12`

**Database connection fails (`could not connect`):**
- Check the connection string in `.env`
- Confirm the URL uses `postgresql+asyncpg://` not `postgresql://`
- Neon free-tier projects auto-suspend; first connection may be slow (~1s cold start)

**`alembic upgrade head` reports `authentication failed`:**
- Confirm `.env` exists in the project root
- URL-encode special characters in the password

**`make local` fails before app startup:**
- Confirm `.env.local` exists
- Confirm `TREADSTONE_JWT_SECRET` is set
- Confirm `TREADSTONE_LEADER_ELECTION_ENABLED=true` for the K8s environment
- Optional: set `TREADSTONE_PROD_CONTEXT` so `destroy-local` is refused while kubectl points at prod; `make local` runs the context check **after** Kind setup and **before** Helm (see `deploy/README.md`). If Kind already exists but kubectl still points at prod, switch with `kubectl config use-context kind-treadstone`

