From 3810d0e4012ab87f6fcfefd6b691b758f73acf77 Mon Sep 17 00:00:00 2001 From: Giancarmine Salucci Date: Mon, 16 Feb 2026 12:19:49 +0100 Subject: [PATCH] =?UTF-8?q?feat(RECIPE-0002):=20complete=20iteration=200?= =?UTF-8?q?=20=E2=80=94=20generate=20PWA=20icons=20and=20update=20manifest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/FINDINGS.md | 144 +++++++++++- package-lock.json | 529 ++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + secrets/auth.json | 42 ++-- static/favicon.png | Bin 0 -> 6120 bytes static/icon-512.png | Bin 0 -> 20460 bytes static/manifest.json | 10 +- 7 files changed, 700 insertions(+), 26 deletions(-) create mode 100644 static/favicon.png create mode 100644 static/icon-512.png diff --git a/docs/FINDINGS.md b/docs/FINDINGS.md index 882153d..8b898b7 100644 --- a/docs/FINDINGS.md +++ b/docs/FINDINGS.md @@ -356,6 +356,144 @@ This document will be updated by subsequent agents: --- -**Document Version:** 1.0 -**Generated by:** Initializer Agent -**Next Update:** Planner Agent +### [Planner] Research Notes - RECIPE-0002 (2026-02-16) + +**Task:** Complete PWA implementation (installability, push notifications, share target) + +#### PWA Documentation Research +**Research Date:** 2026-02-16 +**Sources:** MDN Web Docs, web.dev, W3C specifications + +**Progressive Web Apps (PWA) - Key Requirements:** +1. **Web App Manifest** (`manifest.json`) + - Required members: `name` or `short_name`, `icons` (192x192 PNG minimum), `start_url`, `display` + - Share target support via `share_target` member (method, action, params) + - Icons should include 192x192 and 512x512 sizes for optimal display + - Browser compatibility: Chrome/Edge (full), Firefox/Safari (limited for share_target) + +2. **Service Worker** + - Must be registered to enable offline functionality + - Lifecycle: install → activate → fetch events + - Required for push notifications + - Must be served over HTTPS (or localhost) + +3. **HTTPS Requirement** + - Mandatory for service worker registration + - Required for push notifications and other secure contexts + - Local development: `http://localhost` is treated as secure + +4. **Installability Criteria** (from MDN/web.dev): + - Valid manifest with required members + - Service worker registered with fetch event handler + - Served over HTTPS + - At least one 192x192 PNG or SVG icon + - Display mode set (fullscreen, standalone, minimal-ui) + +**Push Notifications (Web Push API):** +- Requires service worker to receive push events +- VAPID authentication (application server keys) required for Chrome +- Subscription process: permission → subscribe → store subscription → send push +- Push service (browser vendor controlled) routes messages +- Notification permissions: default, granted, denied +- Best practice: request permission after user interaction + +**Web Share Target API:** +- Registers PWA as share destination +- Configuration via manifest `share_target` member +- Supports GET or POST methods +- `params` define query string mapping (title, text, url) +- Files can be shared via POST with `multipart/form-data` +- Currently Chrome/Edge only (experimental) +- App must be installed to appear in share sheet + +#### Current Implementation Analysis +**Research Date:** 2026-02-16 +**Files Analyzed:** manifest.json, service-worker.ts, app.html, svelte.config.js, PWAInstallManager.ts, PushNotificationManager.ts + +**Manifest Analysis (`static/manifest.json`):** +- ✅ Has all required PWA members (name, short_name, start_url, display, scope, theme_color, background_color) +- ✅ Share target configured correctly (GET /share with title/text/url params) +- ⚠️ Icons reference `/favicon.png` but file does NOT exist in static folder +- ⚠️ Uses same icon path for both 192x192 and 512x512 sizes +- ℹ️ Missing optional but recommended members: `description`, `screenshots`, `categories` + +**Service Worker Analysis (`src/service-worker.ts`):** +- ✅ Native SvelteKit service worker (migrated from vite-pwa plugin) +- ✅ Install event: caches all build assets and static files +- ✅ Activate event: cleans up old caches +- ✅ Fetch event: cache-first for assets, network-first with cache fallback for others +- ✅ Push event handler: processes push messages, shows notifications with actions +- ✅ Notification click handler: opens/focuses app, handles action buttons +- ✅ Notification close handler: tracks dismissals +- ✅ Background sync handler: supports retry operations +- ✅ Message handler: supports service worker communication +- ✅ Global error handlers present + +**Service Worker Registration (`svelte.config.js`):** +- ✅ `serviceWorker.register: true` enabled +- ✅ SvelteKit handles registration automatically + +**Manifest Link (`src/app.html`):** +- ✅ `` present in head + +**Client-Side Managers:** +- ✅ `PushNotificationManager.ts`: Full implementation with permission, subscribe, unsubscribe +- ✅ `PWAInstallManager.ts`: beforeinstallprompt handling, install prompt triggering +- ✅ Both are SSR-safe with browser guards + +**Share Target (`/share` route):** +- ✅ Route exists at `src/routes/share/+page.svelte` +- ✅ Parses query params (text, url) from share target +- ✅ Extracts Instagram URLs from shared text +- ✅ Auto-processes URLs on mount +- ✅ Enqueues items and redirects to dashboard + +**Icons/Assets Issue:** +- ⚠️ **CRITICAL**: `manifest.json` references `/favicon.png` but file doesn't exist +- ✅ `src/lib/assets/favicon.svg` exists (used in layout) +- ⚠️ No PNG icons in `static/` folder +- ⚠️ Service worker references `/favicon.png` for notifications + +**Push Notifications Infrastructure:** +- ✅ VAPID keys configured in `queueConfig.push` (uses env vars or defaults) +- ✅ Server endpoint: `/api/notifications/vapid-key` (GET) +- ✅ Server endpoint: `/api/notifications/subscribe` (POST/DELETE) +- ✅ PushNotificationService stores subscriptions in-memory +- ℹ️ Note: Subscriptions are not persisted (lost on restart) + +#### What Works Already: +1. **PWA Structure**: Complete Native SvelteKit PWA implementation +2. **Service Worker**: Fully functional with caching, push, notifications +3. **Push Notifications**: Client and server infrastructure in place +4. **Share Target**: Configured in manifest and `/share` route working +5. **Install Prompts**: PWAInstallManager ready to trigger install +6. **HTTPS**: App served at https://localhost:5173/ + +#### What Needs Attention: +1. **Icons**: Create PNG icons (192x192, 512x512) from existing SVG +2. **Icon Verification**: Ensure icons are properly sized and optimized +3. **Installability Testing**: Verify all criteria met via chrome://pwa-internals +4. **Push Notification Testing**: Verify VAPID key generation and push flow +5. **Share Target Testing**: Test share from external apps (Instagram) +6. **Manifest Enhancement**: Add description, categories for better discoverability + +#### Dependencies & Constraints (from ARCHITECTURE.md, CODE_STYLE.md): +- Using native SvelteKit PWA (no plugins needed) +- Service worker: `$service-worker` module provides build, files, version +- Environment: uses `$env/dynamic/private` for server configs +- HTTPS required (already configured at https://localhost:5173/) +- TypeScript strict mode enabled +- All file paths must use SvelteKit path aliases (`$lib`, `$service-worker`) + +#### Code Style Requirements (from CODE_STYLE.md): +- FilesNaming: manifest.json, service-worker.ts, lowercase for utilities +- Type annotations required for public APIs +- SSR-safe code: all browser API usage must be guarded with `browser` check +- Error handling: try-catch with descriptive messages +- Comments: JSDoc for public APIs, inline for complex logic + +--- + +**Document Version:** 1.1 +**Last Updated by:** Planner Agent +**Next Update:** Developer Agent diff --git a/package-lock.json b/package-lock.json index f35be1c..4c08e2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "date-fns": "^4.1.0", "openai": "^4.20.0", "playwright": "^1.56.1", + "sharp": "^0.34.5", "uuid": "^13.0.0", "zod": "^3.23.0" }, @@ -206,6 +207,16 @@ "node": ">=18" } }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", @@ -878,6 +889,471 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2749,7 +3225,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -5041,7 +5516,6 @@ "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -5057,6 +5531,50 @@ "dev": true, "license": "MIT" }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5405,6 +5923,13 @@ "typescript": ">=4.8.4" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 256add0..0967508 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "date-fns": "^4.1.0", "openai": "^4.20.0", "playwright": "^1.56.1", + "sharp": "^0.34.5", "uuid": "^13.0.0", "zod": "^3.23.0" } diff --git a/secrets/auth.json b/secrets/auth.json index 96f1754..15c7745 100644 --- a/secrets/auth.json +++ b/secrets/auth.json @@ -5,7 +5,7 @@ "value": "SDRORLyWEsWWty2ZoVGdER", "domain": ".instagram.com", "path": "/", - "expires": 1805792736.022295, + "expires": 1805800160.063011, "httpOnly": false, "secure": true, "sameSite": "Lax" @@ -45,7 +45,7 @@ "value": "59661903731", "domain": ".instagram.com", "path": "/", - "expires": 1779008736.02238, + "expires": 1779016160.063112, "httpOnly": false, "secure": true, "sameSite": "None" @@ -65,14 +65,14 @@ "value": "1280x720", "domain": ".instagram.com", "path": "/", - "expires": 1771837537, + "expires": 1771844962, "httpOnly": false, "secure": true, "sameSite": "Lax" }, { "name": "rur", - "value": "\"CLN\\05459661903731\\0541802768735:01fe34704641561c6ed37bf16859325013ed352014b25962418c499d479983b6e579b321\"", + "value": "\"CLN\\05459661903731\\0541802776160:01fe4a2af312a4a53c101bc8cd61c34ba931eb14a5553a656ce440fa654b579d6cf960af\"", "domain": ".instagram.com", "path": "/", "expires": -1, @@ -87,39 +87,47 @@ "localStorage": [ { "name": "chatd-deviceid", - "value": "e884b61b-6fec-41c6-9587-2081a703df8a" - }, - { - "name": "hb_timestamp", - "value": "1771231102978" + "value": "1aa1484c-fbba-44d9-8b1e-1c19a275a8ca" }, { "name": "IGSession", - "value": "53laur:1771234537846" + "value": "hpur03:1771241962285" + }, + { + "name": "mutex_polaris_banzai", + "value": "jp6r38:1771240163284" }, { "name": "pixel_fire_ts", "value": "1771121302843" }, - { - "name": "signal_flush_timestamp", - "value": "1771231102993" - }, { "name": "Session", - "value": "glrtqk:1771232772846" + "value": "dbjbai:1771240197285" }, { "name": "has_interop_upgraded", "value": "{\"lastCheckedAt\":1766366944051,\"status\":false}" }, { - "name": "ig_boost_on_web_campaign_upsell_shown", - "value": "false" + "name": "mutex_banzai", + "value": "jp6r38:1771240163284" }, { "name": "banzai:last_storage_flush", "value": "1771205738044.8" + }, + { + "name": "hb_timestamp", + "value": "1771239264002" + }, + { + "name": "signal_flush_timestamp", + "value": "1771239264014" + }, + { + "name": "ig_boost_on_web_campaign_upsell_shown", + "value": "false" } ] } diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..2bf783080f73e7c07708b97b14430720c47dabe2 GIT binary patch literal 6120 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 Pd>_KW)`?g_@W1#!+ffeA literal 0 HcmV?d00001 diff --git a/static/manifest.json b/static/manifest.json index 2c4121d..c830e97 100644 --- a/static/manifest.json +++ b/static/manifest.json @@ -10,12 +10,14 @@ { "src": "/favicon.png", "sizes": "192x192", - "type": "image/png" + "type": "image/png", + "purpose": "any maskable" }, { - "src": "/favicon.png", - "sizes": "512x512", - "type": "image/png" + "src": "/icon-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any maskable" } ], "share_target": {