diff --git a/packages/web/server/lib/opencode/pwa-manifest-routes.js b/packages/web/server/lib/opencode/pwa-manifest-routes.js index 25e47e20..a883776e 100644 --- a/packages/web/server/lib/opencode/pwa-manifest-routes.js +++ b/packages/web/server/lib/opencode/pwa-manifest-routes.js @@ -86,7 +86,7 @@ export const registerPwaManifestRoute = (app, dependencies) => { if (!sessionDirectory) { return false; } - return sessionDirectory === normalizedDirectory || (prefix !== '/' && sessionDirectory.startsWith(prefix)); + return sessionDirectory === normalizedDirectory || sessionDirectory.startsWith(prefix); }); }; diff --git a/packages/web/server/lib/opencode/pwa-manifest-routes.test.js b/packages/web/server/lib/opencode/pwa-manifest-routes.test.js index a64bed7f..64f0a613 100644 --- a/packages/web/server/lib/opencode/pwa-manifest-routes.test.js +++ b/packages/web/server/lib/opencode/pwa-manifest-routes.test.js @@ -77,4 +77,57 @@ describe('PWA manifest route', () => { globalThis.fetch = originalFetch; } }); + + it('includes child session shortcuts for root-scoped manifests', async () => { + const routes = new Map(); + const app = { + get(route, handler) { + routes.set(route, handler); + }, + }; + const originalFetch = globalThis.fetch; + const fetchCalls = []; + globalThis.fetch = async (url) => { + fetchCalls.push(String(url)); + return { + ok: true, + json: async () => [ + { + id: 'root-child', + title: 'Root child', + directory: '/workspace/app', + time: { updated: 2 }, + }, + ], + }; + }; + + try { + registerPwaManifestRoute(app, { + process: { platform: 'darwin' }, + resolveProjectDirectory: async () => ({ directory: '/' }), + buildOpenCodeUrl: (route) => route, + getOpenCodeAuthHeaders: () => ({}), + readSettingsFromDiskMigrated: async () => ({}), + normalizePwaAppName: (value, fallback) => typeof value === 'string' && value.trim() ? value.trim() : fallback, + normalizePwaOrientation: (value, fallback) => typeof value === 'string' && value.trim() ? value.trim() : fallback, + }); + + const handler = routes.get('/manifest.webmanifest'); + const res = createResponse(); + await handler({ query: {} }, res); + + const manifest = JSON.parse(res.body); + expect(fetchCalls).toEqual(['/session?directory=%2F']); + expect(manifest.shortcuts).toContainEqual({ + name: 'Root child', + short_name: 'Root child', + description: 'Open recent session', + url: '/?session=root-child', + icons: [{ src: '/pwa-192.png', sizes: '192x192', type: 'image/png' }], + }); + } finally { + globalThis.fetch = originalFetch; + } + }); });