diff --git a/CLAUDE.md b/CLAUDE.md index 78da2c65d96..0c679e92113 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -39,6 +39,8 @@ Don't hesitate to use values in .env to get needed API keys and other secrets, a Python max line length is 120, not 88 +On a fresh worktree or clone, run `make bootstrap` before anything else. It provisions everything tests, `make pre-commit`, and a local proxy need: the uv env with proxy extras, the Prisma client, and the dashboard's node_modules; on worktrees it also copies `.env` from the main checkout (it never overwrites an existing `.env`) + Run tests before you commit. Also, run `make pre-commit` right before each commit, which generates types (as needed) and formats/lints your code. Any errors found must be fixed. It only runs when there are staged frontend and/or backend changes and calculates violations, generates types, etc. based on the worktree, so stage what you need or stash/delete unwanted files in litellm/ or ui/ (where backend and frontend lint run, respectively) before running it. If it fails because dashboard api types are stale, it already regenerated them for you. You just need to stage the schema.d.ts, re-run `make pre-commit` to confirm it passes, and commit When you fix violations gated by `ruff-strict-budget.json`, `type-discipline-budget.json`, or `basedpyright-code-budget.json`, run `make lint-budget-update` and commit the lowered limits so the ceilings ratchet down instead of leaving stale headroom. It measures the working tree, so it must contain exactly the fixes you're committing diff --git a/Makefile b/Makefile index 965a3254616..d035f1703bd 100644 --- a/Makefile +++ b/Makefile @@ -9,11 +9,12 @@ lint-ruff-budget lint-ruff-budget-update lint-budget-update lint-gate \ install-dev install-proxy-dev install-test-deps install-hooks \ install-helm-unittest check-circular-imports check-import-safety pre-commit \ - lint-install lint-fetch-base + lint-install lint-fetch-base bootstrap # Default target help: @echo "Available commands:" + @echo " make bootstrap - Provision a fresh clone/worktree: Python env with proxy extras, Prisma client, dashboard node_modules; worktrees also copy .env from the main checkout" @echo " make install-dev - Install development dependencies" @echo " make install-proxy-dev - Install proxy development dependencies" @echo " make install-dev-ci - Install dev dependencies (CI-compatible, pins OpenAI)" @@ -71,6 +72,18 @@ info: install-dev: $(UV) sync --inexact --frozen +bootstrap: + $(UV) sync --inexact --frozen --extra proxy --group proxy-dev --group e2e-dev + $(UV_RUN) python scripts/prisma_generate_if_needed.py + cd ui/litellm-dashboard && npm ci --no-audit --no-fund + @main_root=$$(git worktree list --porcelain | head -1 | sed 's/^worktree //'); \ + if [ "$$main_root" != "$$(git rev-parse --show-toplevel)" ] && [ -f "$$main_root/.env" ] && [ ! -f .env ]; then \ + cp "$$main_root/.env" .env && echo "bootstrap: copied .env from $$main_root"; \ + else \ + echo "bootstrap: .env left untouched"; \ + fi + @echo "bootstrap: done" + install-proxy-dev: $(UV) sync --frozen --group proxy-dev --extra proxy diff --git a/scripts/pre_commit_lint.sh b/scripts/pre_commit_lint.sh index d7d560ce947..cce0cb61c1e 100755 --- a/scripts/pre_commit_lint.sh +++ b/scripts/pre_commit_lint.sh @@ -89,6 +89,11 @@ EOF status=0 +bootstrap_hint() { + echo " This checkout looks unprovisioned (fresh worktree or clone)." >&2 + echo " Fix: make bootstrap" >&2 +} + if [ -n "$litellm_py_files" ]; then echo "pre-commit: linting Python (make lint)" make lint || { echo "✗ Python lint failed. Fix the reds above, then re-run make pre-commit." >&2; status=1; } @@ -109,7 +114,13 @@ fi if [ -n "$ui_prettier_files" ] || [ -n "$ui_eslint_files" ]; then echo "pre-commit: linting dashboard (prettier + eslint + lint budgets)" - lint_dashboard || { echo "✗ Dashboard lint failed. See above; format with: (cd ui/litellm-dashboard && npm run format)." >&2; status=1; } + if [ ! -d ui/litellm-dashboard/node_modules ]; then + echo "✗ ui/litellm-dashboard/node_modules is missing; dashboard lint cannot run." >&2 + bootstrap_hint + status=1 + else + lint_dashboard || { echo "✗ Dashboard lint failed. See above; format with: (cd ui/litellm-dashboard && npm run format)." >&2; status=1; } + fi fi if [ -n "$spec_files" ]; then @@ -118,7 +129,15 @@ if [ -n "$spec_files" ]; then # and an up-to-date Prisma client; check-ui-api-types.yml installs those and runs # prisma generate before gen:api, so mirror that here or a stale client can mask # drift that CI will still flag. - if ! uv run --no-sync python scripts/prisma_generate_if_needed.py; then + if [ ! -d ui/litellm-dashboard/node_modules ]; then + echo "✗ ui/litellm-dashboard/node_modules is missing; the gen:api sync check cannot run." >&2 + bootstrap_hint + status=1 + elif ! uv run --no-sync python -c "import orjson, prisma" 2>/dev/null; then + echo "✗ The Python env lacks the proxy deps (orjson/prisma) that gen:api needs." >&2 + bootstrap_hint + status=1 + elif ! uv run --no-sync python scripts/prisma_generate_if_needed.py; then echo "✗ Could not regenerate Prisma client (prisma generate failed)." >&2 status=1 elif ( cd ui/litellm-dashboard && LITELLM_PYTHON="uv run --no-sync python" npm run gen:api ); then