Deploys ran `npm ci` unconditionally, which wipes node_modules and
rebuilds native modules (better-sqlite3) on every push — ~20 min even
for a frontend-only change with no dependency changes.
Gate the clean install on package.json / package-lock.json actually
changing between the pre-pull HEAD and the new HEAD. As a safety net,
still install whenever the build's required modules (@vitejs/plugin-react,
@rollup/rollup-linux-x64-*) are missing from node_modules, so a skipped
install can never leave an incomplete tree. Frontend-only deploys now
skip straight to the build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>