v1.7.38 and v1.7.39 both shipped with `./` inside the frontend tarball marked drwx------ (700). Tar extraction preserves archive perms, so every node that pulled the OTA landed with /opt/archipelago/web-ui at 700, nginx (www-data) returned 500 "permission denied" on every page, and the browser showed "Internal Server Error nginx". .116 hit this on both v1.7.38 and v1.7.39 rollouts. The v1.7.39 runtime self-heal in main.rs was the wrong layer — systemd's ReadOnlyPaths namespace made /opt/archipelago read-only from inside the archipelago service, so chmod from there returned EROFS. Root cause: create-release-manifest.sh used mktemp -d (700 default umask) for staging, then tar preserved that 700 in the archive's root entry. Fix the archive itself: - chmod 755 staging dir + `find -type d -exec chmod 755` + `-type f chmod 644` before tar, so the on-disk entries are correct. - tar --owner=0 --group=0 --mode='u=rwX,go=rX' to normalize archive perms belt-and-braces in case file-mode drift ever reappears. - Post-tar verify: `tar tvzf | head -1` must show drwxr-xr-x at root, or the release script aborts before the manifest is even generated. Binary unchanged semantically — the main.rs self-heal stays in as a last- resort belt (can't hurt on nodes whose FS isn't namespace-isolated), and the update.rs in-extractor chmod stays in so v1.7.40-onwards extractors are double-safe. The authoritative fix is the archive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.4 KiB
JSON
68 lines
2.4 KiB
JSON
{
|
|
"name": "neode-ui",
|
|
"private": true,
|
|
"version": "1.7.40-alpha",
|
|
"type": "module",
|
|
"scripts": {
|
|
"start": "./start-dev.sh",
|
|
"stop": "./stop-dev.sh",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"dev": "vite",
|
|
"dev:mock": "concurrently --raw \"node mock-backend.js\" \"VITE_AIUI_URL=http://localhost:5173 vite\" \"cd ../../AIUI && perl -MPOSIX -e 'POSIX::setsid(); exec @ARGV' -- pnpm dev 2>/dev/null || echo '[AIUI] Not found at ../../AIUI — chat will show placeholder'\"",
|
|
"dev:boot": "VITE_DEV_MODE=boot concurrently --raw \"VITE_DEV_MODE=boot node mock-backend.js\" \"VITE_DEV_MODE=boot vite\"",
|
|
"dev:real": "echo 'Start backend: cd ../core && cargo run --release' && vite",
|
|
"backend:mock": "node mock-backend.js",
|
|
"backend:real": "cd ../core && cargo run --release",
|
|
"prebuild": "cp ../app-catalog/catalog.json public/catalog.json",
|
|
"build": "vue-tsc -b && vite build",
|
|
"build:docker": "vite build",
|
|
"build:production": "NODE_ENV=production vue-tsc -b && vite build --mode production",
|
|
"preview": "vite preview",
|
|
"type-check": "vue-tsc --noEmit",
|
|
"generate-pwa-icons": "pwa-assets-generator --preset minimal-2023 public/assets/icon/favico-black.svg && cp public/assets/icon/favicon.ico public/favicon.ico",
|
|
"generate-welcome-speech": "node scripts/generate-welcome-speech.js"
|
|
},
|
|
"dependencies": {
|
|
"@types/dompurify": "^3.0.5",
|
|
"@vue-leaflet/vue-leaflet": "^0.10.1",
|
|
"d3": "^7.9.0",
|
|
"dompurify": "^3.3.3",
|
|
"fast-json-patch": "^3.1.1",
|
|
"fuse.js": "^7.1.0",
|
|
"leaflet": "^1.9.4",
|
|
"pinia": "^3.0.4",
|
|
"qrcode": "^1.5.4",
|
|
"vue": "^3.5.24",
|
|
"vue-i18n": "^11.3.0",
|
|
"vue-router": "^4.6.3"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.58.2",
|
|
"@types/d3": "^7.4.3",
|
|
"@types/leaflet": "^1.9.21",
|
|
"@types/node": "^24.10.0",
|
|
"@types/qrcode": "^1.5.6",
|
|
"@vite-pwa/assets-generator": "^1.0.2",
|
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
"@vitest/coverage-v8": "^3.2.4",
|
|
"@vue/test-utils": "^2.4.6",
|
|
"@vue/tsconfig": "^0.8.1",
|
|
"autoprefixer": "^10.4.22",
|
|
"concurrently": "^9.1.2",
|
|
"cookie-parser": "^1.4.7",
|
|
"cors": "^2.8.5",
|
|
"dockerode": "^4.0.9",
|
|
"express": "^4.21.2",
|
|
"jsdom": "^25.0.1",
|
|
"postcss": "^8.5.6",
|
|
"tailwindcss": "^3.4.18",
|
|
"typescript": "~5.9.3",
|
|
"vite": "^7.2.2",
|
|
"vite-plugin-pwa": "^1.2.0",
|
|
"vitest": "^3.1.1",
|
|
"vue-tsc": "^3.1.3",
|
|
"ws": "^8.18.0"
|
|
}
|
|
}
|