The `cd "$core_dir"` for npm install changed cwd, so the trailing
`du -sh "$stage_dir"` (with stage_dir as relative path) failed:
du: cannot access 'dist/u-claw-portable-windows-v2.1.3'
Fix: prefix stage_dir with $(pwd) so it's absolute.
Surfaced by v2.1.3 release run that successfully npm-installed all
764 packages in 70s but exited 1 on the cosmetic du line.
Root cause: portable zip was 1MB skeleton; first launch triggered
`npm install` of OpenClaw + 36 bundled deps on customer's USB drive.
On exFAT-formatted USB this hangs/takes 20+ minutes, gateway never
binds 18789, dashboard shows "Gateway 未启动".
Fix follows StanleyChanH/openclaw-offline-package pattern (153MB
single-platform zip, gateway starts directly):
- release.yml: only build Windows bundle (~150-200MB). Mac users
fall back to setup.sh. Reasoning: 99% of customers are Windows;
bundling 3 platforms × Node ~30MB + 3× node_modules dedup pain
is what blew the previous attempt past GitHub's 2GB cap (see
5916ff5 history). Smaller scope = simpler + safer.
- Windows-Start.bat / Mac-Start.command: warn if node_modules
missing; fallback `npm install` adds --ignore-scripts --no-audit
--no-fund for speed.
- Release notes: NTFS U-disk recommendation.
Lessons applied (from 5916ff5):
- Stay on linux runner with --ignore-scripts (Stanley pattern)
- Drop mac-x64 / mac-arm64 Node from bundle (setup.sh handles Mac)
- rm -rf node-llama-cpp / sharp / canvas explicitly
- Hard size guard: fail CI if zip > 1500MB (buffer below 2GB cap)
Real bug found in v2.1.0: ubuntu-runner zip preserved LF line endings, which
breaks Windows batch parsing. cmd.exe mis-tokenized 'setlocal' as 'local',
trashed env vars, and produced 'URL: //node--win-x64.zip' on Node download.
Symptom: Windows users who unzip and double-click setup.bat see a flood of
'XXX is not recognized as a command' errors followed by curl 'No host part'.
Fix: convert .bat/.cmd/.ps1 to CRLF, ensure .sh/.command/.mjs stay LF, before
zipping in the portable-skeleton job.
The previous job ran setup.{sh,bat} on the runner which downloaded Node.js +
3.4 GB of OpenClaw deps (clawdbot, @sliverp, node-llama-cpp), pushing the
Windows zip past GitHub's 2 GB single-file limit.
The portable folder is designed to fetch deps on first launch via setup.sh —
ship just the source skeleton (~1 MB) and let the user-side script populate
app/runtime + app/core/node_modules from China mirrors at first launch.
This also collapses portable-windows + portable-mac into one ubuntu-runner
job since the skeleton is platform-agnostic.