diff --git a/Backend/src/index.ts b/Backend/src/index.ts index 56f7379..a9e9767 100644 --- a/Backend/src/index.ts +++ b/Backend/src/index.ts @@ -86,7 +86,12 @@ server.notFound(async (ctr) => { // Serve a matching build file (assets, favicons, etc.) if present. const file = resolveStaticFile(path); - if (file) return ctr.status(200, "OK").printFile(file, { addTypes: true }); + if (file) { + // rjweb's type map has no entry for .webmanifest, and browsers want the + // PWA manifest served as application/manifest+json. + if (file.endsWith(".webmanifest")) ctr.headers.set("Content-Type", "application/manifest+json"); + return ctr.status(200, "OK").printFile(file, { addTypes: !file.endsWith(".webmanifest") }); + } // SPA fallback — hand any other route to the React app. if (hasUiIndex) return ctr.status(200, "OK").printFile(uiIndexPath, { addTypes: true }); diff --git a/UI/index.html b/UI/index.html index 0593d03..cdbca07 100644 --- a/UI/index.html +++ b/UI/index.html @@ -2,9 +2,27 @@ - - + + + + + + + + + + + + + + + PatchPass diff --git a/UI/public/apple-touch-icon.png b/UI/public/apple-touch-icon.png new file mode 100644 index 0000000..7f14922 Binary files /dev/null and b/UI/public/apple-touch-icon.png differ diff --git a/UI/public/icon-192.png b/UI/public/icon-192.png new file mode 100644 index 0000000..d4a96fc Binary files /dev/null and b/UI/public/icon-192.png differ diff --git a/UI/public/icon-512.png b/UI/public/icon-512.png new file mode 100644 index 0000000..87aaac6 Binary files /dev/null and b/UI/public/icon-512.png differ diff --git a/UI/public/icon.svg b/UI/public/icon.svg new file mode 100644 index 0000000..859e4e0 --- /dev/null +++ b/UI/public/icon.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/UI/public/manifest.webmanifest b/UI/public/manifest.webmanifest new file mode 100644 index 0000000..640ae06 --- /dev/null +++ b/UI/public/manifest.webmanifest @@ -0,0 +1,24 @@ +{ + "name": "PatchPass", + "short_name": "PatchPass", + "description": "A human approval layer for AI agents. Review changes, approve intent, let agents proceed.", + "start_url": "/", + "scope": "/", + "display": "standalone", + "display_override": ["standalone", "minimal-ui"], + "orientation": "any", + "background_color": "#0a0e17", + "theme_color": "#0a0e17", + "categories": ["developer", "productivity", "utilities"], + "icons": [ + { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, + { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" }, + { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }, + { "src": "/icon.svg", "sizes": "any", "type": "image/svg+xml", "purpose": "any" } + ], + "shortcuts": [ + { "name": "Awaiting review", "url": "/", "description": "Requests waiting for your review" }, + { "name": "All requests", "url": "/requests", "description": "Full change request history" }, + { "name": "Agents", "url": "/agents", "description": "Manage your agents and API keys" } + ] +} diff --git a/UI/src/components/AgentModals.tsx b/UI/src/components/AgentModals.tsx index ad78967..d7acc26 100644 --- a/UI/src/components/AgentModals.tsx +++ b/UI/src/components/AgentModals.tsx @@ -47,9 +47,7 @@ export function AgentFormModal({ icon_url: iconUrl.trim() || null, max_pending_requests: maxPending, }; - const saved = editing - ? await agentsApi.update(agent!.id, payload) - : await agentsApi.create(payload); + const saved = editing ? await agentsApi.update(agent!.id, payload) : await agentsApi.create(payload); toast.success(editing ? "Agent updated" : "Agent created"); onSaved(saved, !editing); onClose(); @@ -68,17 +66,17 @@ export function AgentFormModal({ title={editing ? "Edit agent" : "New agent"} footer={ <> - - } >
- setName(e.target.value)} autoFocus /> + setName(e.target.value)} />