mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-12 20:57:42 +02:00
[pierre] fix: self-heal half-installed vite warm cache
An npm install killed mid-warm leaves node_modules/ populated but no .bin/, so _ensure_warm_cache (which only checked the dir exists) trusted the half-tree forever and every app symlinked to it died with `vite: command not found`. Gate the cache on .bin/vite existing, and harden the app's frontend/run.sh skip-install guard the same way. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b7450f885a
commit
998e8605c6
@@ -286,15 +286,27 @@ def _warm_cache_dir() -> str:
|
||||
return os.path.join(base, _warm_cache_digest())
|
||||
|
||||
|
||||
def _warm_cache_is_complete(cache_modules: str) -> bool:
|
||||
"""A populated node_modules/ dir is not proof of a *finished* install.
|
||||
npm links package bins (node_modules/.bin/*) in the final phase, so an
|
||||
install killed partway (e.g. Electron quit mid-warm) leaves the package
|
||||
trees on disk but no .bin/. The old `os.path.isdir(node_modules)` check
|
||||
then trusted that half-tree forever, every app symlinked to it, and
|
||||
`npm run dev` died with `vite: command not found`. Require the one bin
|
||||
every webapp-template app actually launches with so a partial cache is
|
||||
treated as not-ready and repopulated instead of cached as good."""
|
||||
return os.path.exists(os.path.join(cache_modules, ".bin", "vite"))
|
||||
|
||||
|
||||
def _ensure_warm_cache() -> str | None:
|
||||
"""Populate the warm-cache node_modules if missing. Returns the
|
||||
absolute path to the populated `node_modules` directory, or None on
|
||||
failure. Thread-safe; concurrent callers block on a single install
|
||||
instead of racing. Idempotent and fast after the first call."""
|
||||
"""Populate the warm-cache node_modules if missing or incomplete.
|
||||
Returns the absolute path to the populated `node_modules` directory, or
|
||||
None on failure. Thread-safe; concurrent callers block on a single
|
||||
install instead of racing. Idempotent and fast after the first call."""
|
||||
cache_dir = _warm_cache_dir()
|
||||
cache_modules = os.path.join(cache_dir, "node_modules")
|
||||
|
||||
if os.path.isdir(cache_modules):
|
||||
if _warm_cache_is_complete(cache_modules):
|
||||
return cache_modules
|
||||
|
||||
# Prefer a pre-extracted bundled tree: junction the workspace straight at it,
|
||||
@@ -305,7 +317,7 @@ def _ensure_warm_cache() -> str | None:
|
||||
return bundled
|
||||
|
||||
with _warm_cache_lock:
|
||||
if os.path.isdir(cache_modules):
|
||||
if _warm_cache_is_complete(cache_modules):
|
||||
return cache_modules
|
||||
# Fast path: pre-built archive shipped inside the release. The
|
||||
# build script generates this so users hitting OpenSwarm for the
|
||||
|
||||
@@ -43,8 +43,13 @@ fi
|
||||
# to vite. Only run npm install when node_modules is genuinely missing
|
||||
# or empty — e.g. a workspace seeded before the warm-cache existed, or
|
||||
# the user's cache was cleared.
|
||||
if [ -d node_modules ] && [ -n "$(ls -A node_modules 2>/dev/null)" ]; then
|
||||
echo "Dependencies already present — skipping install."
|
||||
# A non-empty node_modules is NOT proof of a finished install.
|
||||
# non-empty -> skip" check then trusted that, and `npm run dev` died with
|
||||
# `vite: command not found`. Gate on the bin we actually launch with so a
|
||||
# broken/partial tree self-heals via install instead of being skipped.
|
||||
#So thats why i explicitly have "/.bin/vite"
|
||||
if [ -e node_modules/.bin/vite ]; then
|
||||
echo "Dependencies already present - skipping install."
|
||||
else
|
||||
echo "Installing dependencies..."
|
||||
"$NPM" install --prefer-offline --no-audit --no-fund
|
||||
|
||||
Reference in New Issue
Block a user