diff --git a/image-recipe/configs/nginx-archipelago.conf b/image-recipe/configs/nginx-archipelago.conf index 74a881c4..45692c6f 100644 --- a/image-recipe/configs/nginx-archipelago.conf +++ b/image-recipe/configs/nginx-archipelago.conf @@ -10,7 +10,7 @@ server { location /aiui/ { alias /opt/archipelago/web-ui/aiui/; index index.html; - try_files $uri $uri/ =404; + try_files $uri $uri/ /aiui/index.html; } # AIUI Claude API proxy — routes through claude-proxy service (port 3141) @@ -54,6 +54,12 @@ server { return 503 '{"error":"SearXNG is not running"}'; } + # Icons, favicon, manifest — always revalidate (no heuristic caching) + location ~* ^/(favicon\.ico|manifest\.webmanifest|assets/icon/) { + add_header Cache-Control "no-cache, must-revalidate"; + try_files $uri =404; + } + # Serve static files (Vue.js SPA) location / { try_files $uri $uri/ /index.html; @@ -385,17 +391,23 @@ server { proxy_send_timeout 120s; } + # Icons, favicon, manifest — always revalidate (no heuristic caching) + location ~* ^/(favicon\.ico|manifest\.webmanifest|assets/icon/) { + add_header Cache-Control "no-cache, must-revalidate"; + try_files $uri =404; + } + location / { try_files $uri $uri/ /index.html; } - + location /archipelago/ { proxy_pass http://127.0.0.1:5678; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } - + location /rpc/ { proxy_pass http://127.0.0.1:5678; proxy_http_version 1.1; @@ -405,7 +417,7 @@ server { proxy_send_timeout 600s; proxy_read_timeout 600s; } - + location /app/nextcloud/ { proxy_pass http://127.0.0.1:8085/; proxy_http_version 1.1; diff --git a/neode-ui/dev-dist/sw.js b/neode-ui/dev-dist/sw.js index a6e880ca..891dcb84 100644 --- a/neode-ui/dev-dist/sw.js +++ b/neode-ui/dev-dist/sw.js @@ -82,11 +82,12 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.0ddc43l70qk" + "revision": "0.qqvn6d3mva8" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { - allowlist: [/^\/$/] + allowlist: [/^\/$/], + denylist: [/^\/app\//, /^\/rpc\//, /^\/ws/, /^\/aiui\//] })); workbox.registerRoute(/^https:\/\/fonts\.googleapis\.com\/.*/i, new workbox.CacheFirst({ "cacheName": "google-fonts-cache", diff --git a/neode-ui/index.html b/neode-ui/index.html index b90ece73..a486583f 100644 --- a/neode-ui/index.html +++ b/neode-ui/index.html @@ -2,15 +2,15 @@ - - - - - - - - - + + + + + + + + + @@ -20,7 +20,7 @@ - + Archipelago OS diff --git a/neode-ui/mock-backend.js b/neode-ui/mock-backend.js index 35b6331b..4cc3cdea 100755 --- a/neode-ui/mock-backend.js +++ b/neode-ui/mock-backend.js @@ -235,7 +235,7 @@ async function getDockerContainers() { const metadata = appMetadata[appId] || { title: appId, - icon: '/assets/img/favico.png', + icon: '/assets/icon/pwa-192x192-v2.png', description: `${appId} application` } @@ -342,15 +342,15 @@ async function installPackage(id, manifestUrl) { title: 'Amin', shortDesc: 'Administrative interface for Archipelago', longDesc: 'Amin provides administrative tools and monitoring.', - icon: '/assets/img/favico.png' + icon: '/assets/icon/pwa-192x192-v2.png' } } - + const metadata = packageMetadata[id] || { title: id.charAt(0).toUpperCase() + id.slice(1), shortDesc: `${id} application`, longDesc: `${id} application for Archipelago`, - icon: '/assets/img/favico.png' + icon: '/assets/icon/pwa-192x192-v2.png' } // Determine port diff --git a/neode-ui/public/assets/icon/apple-touch-icon-180x180-v2.png b/neode-ui/public/assets/icon/apple-touch-icon-180x180-v2.png new file mode 100644 index 00000000..a9040bb7 Binary files /dev/null and b/neode-ui/public/assets/icon/apple-touch-icon-180x180-v2.png differ diff --git a/neode-ui/public/assets/icon/apple-touch-icon-180x180.png b/neode-ui/public/assets/icon/apple-touch-icon-180x180.png deleted file mode 100644 index 4ca6fe17..00000000 Binary files a/neode-ui/public/assets/icon/apple-touch-icon-180x180.png and /dev/null differ diff --git a/neode-ui/public/assets/icon/favico-black-v2.svg b/neode-ui/public/assets/icon/favico-black-v2.svg new file mode 100644 index 00000000..098675b0 --- /dev/null +++ b/neode-ui/public/assets/icon/favico-black-v2.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/neode-ui/public/assets/icon/favico-black.svg b/neode-ui/public/assets/icon/favico-black.svg deleted file mode 100644 index b886a54c..00000000 --- a/neode-ui/public/assets/icon/favico-black.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/neode-ui/public/assets/icon/favico.png b/neode-ui/public/assets/icon/favico.png deleted file mode 100644 index a9c8440a..00000000 Binary files a/neode-ui/public/assets/icon/favico.png and /dev/null differ diff --git a/neode-ui/public/assets/icon/favico.svg b/neode-ui/public/assets/icon/favico.svg deleted file mode 100644 index a33d3844..00000000 --- a/neode-ui/public/assets/icon/favico.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/neode-ui/public/assets/icon/favicon.ico b/neode-ui/public/assets/icon/favicon.ico deleted file mode 100644 index d3d526c9..00000000 Binary files a/neode-ui/public/assets/icon/favicon.ico and /dev/null differ diff --git a/neode-ui/public/assets/icon/maskable-icon-512x512-v2.png b/neode-ui/public/assets/icon/maskable-icon-512x512-v2.png new file mode 100644 index 00000000..1087cdbc Binary files /dev/null and b/neode-ui/public/assets/icon/maskable-icon-512x512-v2.png differ diff --git a/neode-ui/public/assets/icon/maskable-icon-512x512.png b/neode-ui/public/assets/icon/maskable-icon-512x512.png deleted file mode 100644 index 64bf9a6f..00000000 Binary files a/neode-ui/public/assets/icon/maskable-icon-512x512.png and /dev/null differ diff --git a/neode-ui/public/assets/icon/pwa-192x192-v2.png b/neode-ui/public/assets/icon/pwa-192x192-v2.png new file mode 100644 index 00000000..b3d24cde Binary files /dev/null and b/neode-ui/public/assets/icon/pwa-192x192-v2.png differ diff --git a/neode-ui/public/assets/icon/pwa-192x192.png b/neode-ui/public/assets/icon/pwa-192x192.png deleted file mode 100644 index 673e3374..00000000 Binary files a/neode-ui/public/assets/icon/pwa-192x192.png and /dev/null differ diff --git a/neode-ui/public/assets/icon/pwa-512x512-v2.png b/neode-ui/public/assets/icon/pwa-512x512-v2.png new file mode 100644 index 00000000..062c9be7 Binary files /dev/null and b/neode-ui/public/assets/icon/pwa-512x512-v2.png differ diff --git a/neode-ui/public/assets/icon/pwa-512x512.png b/neode-ui/public/assets/icon/pwa-512x512.png deleted file mode 100644 index c798b722..00000000 Binary files a/neode-ui/public/assets/icon/pwa-512x512.png and /dev/null differ diff --git a/neode-ui/public/assets/icon/pwa-64x64-v2.png b/neode-ui/public/assets/icon/pwa-64x64-v2.png new file mode 100644 index 00000000..b6a935db Binary files /dev/null and b/neode-ui/public/assets/icon/pwa-64x64-v2.png differ diff --git a/neode-ui/public/assets/icon/pwa-64x64.png b/neode-ui/public/assets/icon/pwa-64x64.png deleted file mode 100644 index 7c0c61fc..00000000 Binary files a/neode-ui/public/assets/icon/pwa-64x64.png and /dev/null differ diff --git a/neode-ui/public/assets/img/favico.png b/neode-ui/public/assets/img/favico.png deleted file mode 100644 index a9c8440a..00000000 Binary files a/neode-ui/public/assets/img/favico.png and /dev/null differ diff --git a/neode-ui/public/assets/img/favico.svg b/neode-ui/public/assets/img/favico.svg deleted file mode 100644 index a33d3844..00000000 --- a/neode-ui/public/assets/img/favico.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/neode-ui/public/assets/img/favicon.png b/neode-ui/public/assets/img/favicon.png deleted file mode 100644 index ab221307..00000000 Binary files a/neode-ui/public/assets/img/favicon.png and /dev/null differ diff --git a/neode-ui/public/assets/img/icon.png b/neode-ui/public/assets/img/icon.png deleted file mode 100644 index c8790391..00000000 Binary files a/neode-ui/public/assets/img/icon.png and /dev/null differ diff --git a/neode-ui/public/assets/img/icon_apple_touch.png b/neode-ui/public/assets/img/icon_apple_touch.png deleted file mode 100644 index 3ca45d44..00000000 Binary files a/neode-ui/public/assets/img/icon_apple_touch.png and /dev/null differ diff --git a/neode-ui/public/assets/img/l484-icon.svg b/neode-ui/public/assets/img/l484-icon.svg deleted file mode 100644 index f7405444..00000000 --- a/neode-ui/public/assets/img/l484-icon.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/neode-ui/public/favicon-v2.ico b/neode-ui/public/favicon-v2.ico new file mode 100644 index 00000000..94b24860 Binary files /dev/null and b/neode-ui/public/favicon-v2.ico differ diff --git a/neode-ui/public/favicon.ico b/neode-ui/public/favicon.ico deleted file mode 100644 index d3d526c9..00000000 Binary files a/neode-ui/public/favicon.ico and /dev/null differ diff --git a/neode-ui/src/components/PWAInstallPrompt.vue b/neode-ui/src/components/PWAInstallPrompt.vue index d9dcf5ae..f44c182c 100644 --- a/neode-ui/src/components/PWAInstallPrompt.vue +++ b/neode-ui/src/components/PWAInstallPrompt.vue @@ -7,7 +7,7 @@ >
Archipelago diff --git a/neode-ui/src/views/OnboardingOptions.vue b/neode-ui/src/views/OnboardingOptions.vue index 95be9a72..25ce98f1 100644 --- a/neode-ui/src/views/OnboardingOptions.vue +++ b/neode-ui/src/views/OnboardingOptions.vue @@ -4,7 +4,7 @@
Archipelago diff --git a/neode-ui/vite.config.ts b/neode-ui/vite.config.ts index a70055a0..dfaac751 100644 --- a/neode-ui/vite.config.ts +++ b/neode-ui/vite.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ vue(), VitePWA({ registerType: 'autoUpdate', - includeAssets: ['assets/icon/favico-black.svg', 'assets/icon/pwa-192x192.png', 'assets/icon/pwa-512x512.png', 'assets/icon/apple-touch-icon-180x180.png', 'favicon.ico'], + includeAssets: ['assets/icon/favico-black-v2.svg', 'assets/icon/pwa-64x64-v2.png', 'assets/icon/pwa-192x192-v2.png', 'assets/icon/pwa-512x512-v2.png', 'assets/icon/maskable-icon-512x512-v2.png', 'assets/icon/apple-touch-icon-180x180-v2.png', 'favicon-v2.ico'], manifest: { name: 'Archipelago', short_name: 'Archipelago', @@ -25,15 +25,15 @@ export default defineConfig({ categories: ['productivity', 'utilities'], prefer_related_applications: false, icons: [ - { src: '/assets/icon/pwa-64x64.png', sizes: '64x64', type: 'image/png', purpose: 'any' }, - { src: '/assets/icon/pwa-192x192.png', sizes: '192x192', type: 'image/png', purpose: 'any' }, - { src: '/assets/icon/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'any' }, - { src: '/assets/icon/maskable-icon-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' } + { src: '/assets/icon/pwa-64x64-v2.png', sizes: '64x64', type: 'image/png', purpose: 'any' }, + { src: '/assets/icon/pwa-192x192-v2.png', sizes: '192x192', type: 'image/png', purpose: 'any' }, + { src: '/assets/icon/pwa-512x512-v2.png', sizes: '512x512', type: 'image/png', purpose: 'any' }, + { src: '/assets/icon/maskable-icon-512x512-v2.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' } ], shortcuts: [ - { name: 'Dashboard', short_name: 'Dashboard', description: 'Open the dashboard', url: '/dashboard', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] }, - { name: 'My Apps', short_name: 'Apps', description: 'Manage your apps', url: '/dashboard/apps', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] }, - { name: 'App Store', short_name: 'Store', description: 'Browse and install apps', url: '/dashboard/marketplace', icons: [{ src: '/assets/icon/pwa-192x192.png', sizes: '192x192' }] } + { name: 'Dashboard', short_name: 'Dashboard', description: 'Open the dashboard', url: '/dashboard', icons: [{ src: '/assets/icon/pwa-192x192-v2.png', sizes: '192x192' }] }, + { name: 'My Apps', short_name: 'Apps', description: 'Manage your apps', url: '/dashboard/apps', icons: [{ src: '/assets/icon/pwa-192x192-v2.png', sizes: '192x192' }] }, + { name: 'App Store', short_name: 'Store', description: 'Browse and install apps', url: '/dashboard/marketplace', icons: [{ src: '/assets/icon/pwa-192x192-v2.png', sizes: '192x192' }] } ] }, workbox: { @@ -44,8 +44,6 @@ export default defineConfig({ '**/*-1.47mb.mp4', '**/bg-*.mp4', // Exclude large background videos from precache '**/video-intro.mp4', // Exclude video-intro.mp4 from precache (7MB, cached at runtime) - '**/favico.svg', // Exclude large SVG (5.73MB) - use PNG instead - '**/icon/favico.svg' // Exclude duplicate large SVG ], maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit (increased from 2MB) skipWaiting: false, // Wait for user to accept update @@ -95,7 +93,7 @@ export default defineConfig({ urlPattern: /\/assets\/.*/i, handler: 'CacheFirst', options: { - cacheName: 'assets-cache', + cacheName: 'assets-cache-v2', expiration: { maxEntries: 100, maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days diff --git a/scripts/deploy-to-target.sh b/scripts/deploy-to-target.sh index b2caea62..d7aaa8fd 100755 --- a/scripts/deploy-to-target.sh +++ b/scripts/deploy-to-target.sh @@ -153,19 +153,26 @@ if [ "$LIVE" = true ]; then sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp -rf $TARGET_DIR/web/dist/neode-ui/* /opt/archipelago/web-ui/" sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui" - # Build and deploy AIUI + # Build and deploy AIUI (non-fatal — never delete existing AIUI on failure) AIUI_DIR="$PROJECT_DIR/../AIUI" AIUI_DIST="$AIUI_DIR/packages/app/dist" if [ -d "$AIUI_DIR/packages/app" ]; then echo "$(timestamp) Building AIUI for /aiui/ base path..." - cd "$AIUI_DIR" && VITE_BASE_PATH=/aiui/ pnpm build 2>&1 | tail -5 + AIUI_BUILD_OK=false + if (cd "$AIUI_DIR" && VITE_BASE_PATH=/aiui/ pnpm build 2>&1 | tail -10); then + AIUI_BUILD_OK=true + fi cd "$PROJECT_DIR" - echo "$(timestamp) Deploying AIUI..." - sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo mkdir -p /opt/archipelago/web-ui/aiui" - sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo rm -rf /opt/archipelago/web-ui/aiui/*" - cd "$AIUI_DIST" && tar cf - . | sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo tar xf - -C /opt/archipelago/web-ui/aiui/" - cd "$PROJECT_DIR" - sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui/aiui && sudo chmod 755 /opt/archipelago/web-ui/aiui && sudo find /opt/archipelago/web-ui/aiui -type d -exec chmod 755 {} \;" + if [ "$AIUI_BUILD_OK" = true ] && [ -d "$AIUI_DIST" ] && [ -f "$AIUI_DIST/index.html" ]; then + echo "$(timestamp) Deploying AIUI..." + sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo mkdir -p /opt/archipelago/web-ui/aiui" + sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo rm -rf /opt/archipelago/web-ui/aiui/*" + cd "$AIUI_DIST" && tar cf - . | sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo tar xf - -C /opt/archipelago/web-ui/aiui/" + cd "$PROJECT_DIR" + sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui/aiui && sudo chmod 755 /opt/archipelago/web-ui/aiui && sudo find /opt/archipelago/web-ui/aiui -type d -exec chmod 755 {} \;" + else + echo "$(timestamp) ⚠️ AIUI build failed — keeping existing AIUI on server" + fi else echo "$(timestamp) ⚠️ AIUI not found at $AIUI_DIR, skipping" fi