···11-#!/usr/bin/env bash
11+# #!/usr/bin/env bash
2233-export DIRENV_WARN_TIMEOUT=20s
33+# export DIRENV_WARN_TIMEOUT=20s
4455-eval "$(devenv direnvrc)"
55+# eval "$(devenv direnvrc)"
6677-# `use devenv` supports the same options as the `devenv shell` command.
88-#
99-# To silence all output, use `--quiet`.
1010-#
1111-# Example usage: use devenv --quiet --impure --option services.postgres.enable:bool true
1212-use devenv
77+# # `use devenv` supports the same options as the `devenv shell` command.
88+# #
99+# # To silence all output, use `--quiet`.
1010+# #
1111+# # Example usage: use devenv --quiet --impure --option services.postgres.enable:bool true
1212+# use devenv
+21
CLAUDE.md
···1414cp .env.example .env # configure environment variables
1515```
16161717+### Nix Package Hash (`pnpmDeps`)
1818+1919+`nix/package.nix` contains a `hash =` for `pnpm_9.fetchDeps`. This hash must be updated every time `pnpm-lock.yaml` changes.
2020+2121+**Why it changes:** `pnpm_9.fetchDeps` is a Nix fixed-output derivation (FOD) that downloads packages via pnpm in a sandbox. When the lockfile changes, the set of downloaded packages changes, so the hash changes. Platform-specific optional packages (e.g. `@esbuild/linux-arm64`) mean macOS and Linux produce different hashes — the hash in the repo must match what the Linux build produces.
2222+2323+**How to update it:** Run the helper script **on a Linux machine** (or with a Linux remote Nix builder configured):
2424+2525+```sh
2626+pnpm nix:update-hash
2727+# or directly:
2828+bash scripts/update-pnpmdeps-hash.sh
2929+```
3030+3131+The script:
3232+1. Replaces the current hash with `lib.fakeHash` (a known-invalid placeholder)
3333+2. Runs `nix build .#packages.x86_64-linux.default` — which fails with the correct hash in the error
3434+3. Parses that hash and writes it back to `nix/package.nix`
3535+3636+**On macOS without a Linux builder:** Push your branch to CI, copy the correct hash from the build failure output, and update `nix/package.nix` manually.
3737+1738### Auto-Fixing Lint Issues
18391940Before committing, auto-fix safe lint violations:
···11+#!/usr/bin/env bash
22+set -eo pipefail
33+44+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
55+PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
66+PACKAGE_NIX="$PROJECT_ROOT/nix/package.nix"
77+88+# lib.fakeHash — a structurally valid but incorrect sha256 that forces Nix
99+# to report the actual hash of whatever it fetches.
1010+FAKE_HASH="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
1111+1212+# ---------------------------------------------------------------------------
1313+# Platform check
1414+# ---------------------------------------------------------------------------
1515+# The Nix flake only targets x86_64-linux / aarch64-linux. pnpm fetchDeps
1616+# downloads platform-specific optional packages (e.g. @esbuild/darwin-arm64
1717+# vs @esbuild/linux-arm64), so a macOS pnpm fetch produces a different hash
1818+# than a Linux one. This script must run on Linux or use a remote Linux
1919+# Nix builder to produce the correct hash.
2020+# ---------------------------------------------------------------------------
2121+if [[ "$(uname)" == "Darwin" ]]; then
2222+ echo "WARNING: This script should run on Linux (or via a Linux Nix remote builder)."
2323+ echo ""
2424+ echo "The Nix flake targets x86_64-linux/aarch64-linux only. When pnpm fetches"
2525+ echo "on macOS it downloads darwin-specific optional packages (@esbuild/darwin-arm64,"
2626+ echo "etc.), producing a different hash than the Linux build expects."
2727+ echo ""
2828+ echo "Options:"
2929+ echo " 1. SSH into a Linux machine and run this script there"
3030+ echo " 2. Configure a Linux Nix remote builder in ~/.config/nix/nix.conf"
3131+ echo " 3. Push to CI, copy the correct hash from the build error output,"
3232+ echo " then update nix/package.nix manually"
3333+ echo ""
3434+ read -p "Continue anyway (e.g. you have a remote builder configured)? [y/N] " -n 1 -r
3535+ echo
3636+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
3737+ exit 0
3838+ fi
3939+fi
4040+4141+echo "Updating pnpmDeps hash in nix/package.nix..."
4242+4343+# Extract current hash
4444+CURRENT_HASH=$(grep -oP '(?<=hash = ")[^"]+' "$PACKAGE_NIX")
4545+echo " Current: $CURRENT_HASH"
4646+4747+# Swap in the fake hash so Nix is forced to compute and report the real one
4848+if [[ "$(uname)" == "Darwin" ]]; then
4949+ sed -i '' "s|$CURRENT_HASH|$FAKE_HASH|" "$PACKAGE_NIX"
5050+else
5151+ sed -i "s|$CURRENT_HASH|$FAKE_HASH|" "$PACKAGE_NIX"
5252+fi
5353+5454+echo " Running: nix build .#packages.x86_64-linux.default"
5555+echo " (Nix will fail with a hash mismatch — that is expected)"
5656+5757+BUILD_OUTPUT=$(nix build .#packages.x86_64-linux.default 2>&1 || true)
5858+5959+# Nix prints: " got: sha256-<actual hash>"
6060+NEW_HASH=$(echo "$BUILD_OUTPUT" | grep "got:" | awk '{print $NF}' | head -1)
6161+6262+if [ -z "$NEW_HASH" ]; then
6363+ echo ""
6464+ echo "ERROR: Could not parse the correct hash from nix output."
6565+ echo ""
6666+ echo "Full build output:"
6767+ echo "$BUILD_OUTPUT"
6868+ echo ""
6969+ echo "Restoring original hash..."
7070+ if [[ "$(uname)" == "Darwin" ]]; then
7171+ sed -i '' "s|$FAKE_HASH|$CURRENT_HASH|" "$PACKAGE_NIX"
7272+ else
7373+ sed -i "s|$FAKE_HASH|$CURRENT_HASH|" "$PACKAGE_NIX"
7474+ fi
7575+ exit 1
7676+fi
7777+7878+# Write the real hash back
7979+if [[ "$(uname)" == "Darwin" ]]; then
8080+ sed -i '' "s|$FAKE_HASH|$NEW_HASH|" "$PACKAGE_NIX"
8181+else
8282+ sed -i "s|$FAKE_HASH|$NEW_HASH|" "$PACKAGE_NIX"
8383+fi
8484+8585+echo " Updated: $NEW_HASH"
8686+echo ""
8787+echo "Commit the change:"
8888+echo " git add nix/package.nix && git commit -m 'chore: adjust pnpmdeps hash'"