diff --git a/.github/workflows/crabbox-hydrate.yml b/.github/workflows/crabbox-hydrate.yml index 1037b13fcd92..8ac43e68c793 100644 --- a/.github/workflows/crabbox-hydrate.yml +++ b/.github/workflows/crabbox-hydrate.yml @@ -34,7 +34,6 @@ env: PNPM_CONFIG_CHILD_CONCURRENCY: "1" PNPM_CONFIG_MODULES_DIR: "/var/tmp/openclaw-pnpm/node_modules" PNPM_CONFIG_NETWORK_CONCURRENCY: "1" - PNPM_CONFIG_STORE_DIR: "/var/cache/crabbox/pnpm/store" PNPM_CONFIG_VERIFY_DEPS_BEFORE_RUN: "false" PNPM_CONFIG_VIRTUAL_STORE_DIR: "/var/tmp/openclaw-pnpm/virtual-store" @@ -65,11 +64,21 @@ jobs: export COREPACK_HOME="${COREPACK_HOME:-$XDG_CACHE_HOME/corepack}" export PNPM_HOME="${PNPM_HOME:-$RUNNER_TEMP/pnpm-home}" mkdir -p "$XDG_CACHE_HOME" "$COREPACK_HOME" "$PNPM_HOME" + preferred_pnpm_store="/var/cache/crabbox/pnpm/store" + if mkdir -p "$preferred_pnpm_store" 2>/dev/null && + [ ! -L "$preferred_pnpm_store" ] && + [ -d "$preferred_pnpm_store" ] && + [ -w "$preferred_pnpm_store" ]; then + export PNPM_CONFIG_STORE_DIR="$preferred_pnpm_store" + else + export PNPM_CONFIG_STORE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/openclaw/pnpm/store" + fi export PATH="$PNPM_HOME:$PATH" { echo "XDG_CACHE_HOME=$XDG_CACHE_HOME" echo "COREPACK_HOME=$COREPACK_HOME" echo "PNPM_HOME=$PNPM_HOME" + echo "PNPM_CONFIG_STORE_DIR=$PNPM_CONFIG_STORE_DIR" } >> "$GITHUB_ENV" package_manager="$(node -e "const fs = require('node:fs'); const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); process.stdout.write(pkg.packageManager || '')")" diff --git a/CHANGELOG.md b/CHANGELOG.md index 260255abd777..3a09d70b3772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Docs: https://docs.openclaw.ai ### Changes +- Fixed Crabbox hydration on unprivileged cloud sandboxes by falling back to a user-writable pnpm store when the shared `/var/cache/crabbox` cache is unavailable. + - **Browser extension relay CDP compat:** answer `Target.getBrowserContexts` so Puppeteer-based clients (chrome-devtools-mcp) can drive the paired Chrome without the remote-debugging permission prompt, serve DevTools-style `/json/list` target descriptors, and add `openclaw browser extension cdp` to print the relay endpoint plus auth header for external CDP clients. - **Local model setup:** advertise provider-owned Ollama, llama.cpp, and LM Studio setup choices to Control UI and macOS, retry unavailable LM Studio services in place, and verify the exact prepared model before showing success. - **Control UI first-run setup:** continue verified model setup into Custodian, explain that the web app is ready without a channel, and offer an optional dismissible path to Channels. diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index bf000e917e2d..54e48c1d81c7 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -1121,7 +1121,15 @@ describe("package acceptance workflow", () => { expect(hydratePnpm.if).toBeUndefined(); expect(hydratePnpm.run).toContain('corepack enable --install-directory "$PNPM_HOME"'); expect(hydratePnpm.run).toContain("COREPACK_HOME"); - expect(workflowText).toContain('PNPM_CONFIG_STORE_DIR: "/var/cache/crabbox/pnpm/store"'); + expect(workflowText).not.toContain('PNPM_CONFIG_STORE_DIR: "/var/cache/crabbox/pnpm/store"'); + expect(hydratePnpm.run).toContain('preferred_pnpm_store="/var/cache/crabbox/pnpm/store"'); + expect(hydratePnpm.run).toContain('mkdir -p "$preferred_pnpm_store" 2>/dev/null'); + expect(hydratePnpm.run).toContain('[ -w "$preferred_pnpm_store" ]'); + expect(hydratePnpm.run).toContain( + 'export PNPM_CONFIG_STORE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/openclaw/pnpm/store"', + ); + expect(hydratePnpm.run).toContain('echo "PNPM_CONFIG_STORE_DIR=$PNPM_CONFIG_STORE_DIR"'); + expect(hydratePnpm.run).toContain('} >> "$GITHUB_ENV"'); expect(hydratePnpm.run).toContain("prepare_crabbox_pnpm_dirs"); expect(hydratePnpm.run).toContain('case "${PNPM_CONFIG_MODULES_DIR:?}" in "$volatile_root"/*)'); expect(hydratePnpm.run).toContain(