* docs: move superpowers/research artifacts to isolated _tasks repo + docs tree cleanup
- Move docs/superpowers/{plans,specs} and docs/research/* into the gitignored,
separately-versioned _tasks/ repo; untrack the two tracked research design docs.
- Add CLAUDE.md "Planning & Research Artifacts" section overriding the superpowers
default save paths (docs/... -> _tasks/...); align REPOSITORY_MAP and
DOCUMENTATION_OVERHAUL_PLAN with the new convention.
- Drop 4 now-obsolete /api/discovery/* entries from check-docs-symbols allowlist
(stale-enforcement) and refresh code/spec path comments to _tasks/...
- Sweeps in concurrent docs-tree restructuring (root-level provider/guide docs,
compression spec cleanup, .mcp.json.example removal).
* docs: reorganize docs/ tree + fix stale facts across ~26 docs
Phase A — reorganization:
- Move 7 orphan root docs into subfolders (providers/ created; TIERS+USAGE_QUOTA→guides/;
plugins+PLUGIN_SDK→frameworks/); delete 8 obsolete/redundant docs (SUBMIT_PR superseded
by CONTRIBUTING; DOCUMENTATION_OVERHAUL_PLAN; INCIDENT_RESPONSE/PERF_BUDGETS/THREAT_MODEL;
3 ops snapshots). Rebuild README index (was missing ~40 files) + per-folder meta.json nav.
- Clean 14 dangling doc-path references in bin/ ops scripts, scripts/, workflow, tests;
fix the dockerignore-docs-coverage required-docs path (PROVIDERS→providers/CLAUDE_WEB).
Phase B — content accuracy (verified against code, not the audit summary):
- Functional: ENVIRONMENT flag defaults (INPUT_SANITIZER/MCP_ENFORCE_SCOPES=true,
COMPRESS_DESCRIPTIONS=false, dynamic heap); MCP-SERVER notion tool names (omniroute_*→
notion_*) + counts 87→94; coverage gate 75/70→60/60/60/60 (RELEASE_CHECKLIST, COVERAGE_PLAN,
ERROR_SANITIZATION, CONTRIBUTING); pre-push hook description; regenerate PROVIDER_REFERENCE (237).
- Count drift: providers 237, executors 70, migrations 106, db modules 94, oauth 19,
strategies 17, MCP 94, flags 38, TS 6.0, open-sse ~900/services 294 across architecture/
frameworks/ops docs; AUTO-COMBO 9→12 factors w/ correct DEFAULT_WEIGHTS; REASONING +2
patterns; STEALTH UA defaults; AGENT_PROTOCOLS +cursor-cloud/list-capabilities;
LANGUAGE_PACKS +id pack.
- Kept Node 20 (runtime guard accepts 20.20.2+; only engines is stricter) and MCP scopes=13
(mcpScopes.ts) — both were correct in the docs; corrected only the attribution.
* docs: finish content refresh — compression engines, CLI_TOKEN merge, metadata sweep
- Compression: document the additional built-in engines (CCR, headroom, ionizer,
session-dedup) in COMPRESSION_ENGINES; clarify LLMLingua-2 is the ultra-mode SLM
backend + cross-ref the extra engines in EXTENDING_COMPRESSION; add the id
(Indonesian) language pack to LANGUAGE_PACKS.
- AUTO-COMBO: replace the orphan 'How tiers fit' weight table (stale weights) with a
pointer to the canonical 12-factor DEFAULT_WEIGHTS table.
- Security: merge CLI_TOKEN_AUTH.md (legacy 32-char SHA-256 format) into CLI_TOKEN.md
as a 'Legacy format — still accepted' section (server accepts both HMAC + legacy),
delete CLI_TOKEN_AUTH.md, drop it from the index + security nav.
- Metadata: bump stale frontmatter (version/lastUpdated) to 3.8.40/2026-06-28 across the
doc set audited this pass, and normalize the in-body 'Last updated' header lines to match.
* fix(runtime): drop Node 20 from supported range + align all docs/diagrams/counts
- Node minimum is now 22 (aligned with package.json engines). SUPPORTED_NODE_RANGE in
src/shared/utils/nodeRuntimeSupport.ts (and the bin/ mirror) drops the 20.x line →
'>=22.22.2 <23 || >=24.0.0 <27'; getNodeRuntimeSupport now rejects Node 20 as
unsupported-major. Test updated (TDD): node-runtime-support.test.ts asserts Node 20
rejected. Docs aligned (TROUBLESHOOTING ×2, TERMUX, RELEASE_CHECKLIST, CODEBASE,
CLI-TOOLS, README, llm.txt + 42 i18n llm.txt mirrors, skills/cli-serve).
- Diagrams regenerated: mcp-tools-87 -> mcp-tools-94 (34 base + pool 6 = 94) and
auto-combo-9factor -> auto-combo-12factor (correct DEFAULT_WEIGHTS); SVGs re-rendered
via mermaid-cli; doc refs + diagrams/README updated; fixed a pre-existing broken
resilience-3layers image path.
- CLAUDE.md + AGENTS.md aligned to real counts (237 providers, 94 MCP tools / 34 base,
106 migrations, 94 db modules, 12-factor auto-combo, 17 strategies); README provider
count 231 -> 237; executor count corrected to 68 (provider executors, excl base/index)
and OAuth to 18 across architecture docs. check:docs-all now passes (0 strict drift,
0 broken links); removed dead .mcp.json.example doc link.
* fix(services): update installer Node hint to >=22.22.2 (aligned with dropped Node 20)
* docs: realign counts to current release tip after rebase
The release tip advanced while this work was in flight (Gemini CLI provider/executor
removed by #5246, plus other PRs). Re-counted against the current code and updated:
providers 237->236, executors 68->67, OAuth modules 18->17, open-sse services 294->298;
regenerated PROVIDER_REFERENCE.md (236). check:docs-all passes (0 strict drift).
* docs(changelog) + i18n: record Node 20 drop + fix nodeIncompatibleHint
- CHANGELOG: add [3.8.40] entries for the Node 20.x removal (runtime) and the docs
reorganization/accuracy audit.
- i18n: nodeIncompatibleHint across all 42 locales no longer lists Node 20.x as
supported (ASCII + CJK full-width variants), aligned with the dropped Node 20.
* fix(docs): repair CI breakages from the doc moves
- test: cli-plugin-system asserted docs/dev/plugins.md exists; the file moved to
docs/frameworks/PLUGINS.md — point the test at the new path (Unit fast-path 2/2 fix).
- frontmatter: PLUGINS.md and PLUGIN_SDK.md moved into the fumadocs-indexed
docs/frameworks/ which requires a 'title' frontmatter; the missing frontmatter
failed the Next.js MDX build (dast-smoke 'invalid frontmatter'). Added frontmatter
to both, plus the providers/ docs (consistency; that folder is not indexed).
9.5 KiB
title, version, lastUpdated
| title | version | lastUpdated |
|---|---|---|
| Progressive Web App (PWA) Guide | 3.8.40 | 2026-06-28 |
Progressive Web App (PWA) Guide
OmniRoute ships as a fully installable Progressive Web App. When you access the dashboard from any mobile browser — Android (Chrome) or iOS (Safari) — you can "Add to Home Screen" and get a native app-like experience with no app store required.
What Is a PWA?
A Progressive Web App turns the OmniRoute web dashboard into something that looks and feels like a native mobile app. Once installed, it:
- Launches from your home screen with its own icon
- Opens fullscreen — no browser address bar or tab UI
- Works offline with a dedicated connectivity page
- Caches static assets for faster loading
- Supports both portrait and landscape orientations
Installation
Android (Chrome)
- Open the OmniRoute dashboard in Chrome:
http://YOUR_IP:20128 - Chrome will show an "Add OmniRoute to Home screen" banner automatically, or:
- Tap the ⋮ menu (three dots) → "Add to Home screen" or "Install app"
- Confirm the prompt
- OmniRoute appears on your home screen as a standalone app
iOS (Safari)
- Open the OmniRoute dashboard in Safari:
http://YOUR_IP:20128 - Tap the Share button (box with arrow)
- Scroll down and tap "Add to Home Screen"
- Name it (defaults to "OmniRoute") and tap Add
- OmniRoute appears on your home screen with the app icon
Desktop (Chrome / Edge)
- Open the OmniRoute dashboard
- Click the install icon in the address bar (or ⋮ → "Install OmniRoute...")
- Confirm the prompt
- OmniRoute opens as a standalone window — no tabs, no address bar
Features
Fullscreen Experience
The manifest is configured with display: "fullscreen", which means the installed app uses the entire screen — no browser chrome, no status bar overlap. This makes the dashboard feel truly native.
Offline Support
OmniRoute includes a service worker (sw.js) that provides intelligent caching:
| Asset Type | Strategy | Behavior |
|---|---|---|
| App Shell | Cache-first | /, /offline, manifest, and icons are pre-cached on install |
| Static assets (CSS, JS, images, fonts) | Network-first with cache fallback | Fetches fresh from the network; falls back to cache if offline |
Next.js bundles (/_next/) |
Network-first with cache update | Fetches from network and updates cache; serves cached version if offline |
| Navigation requests | Network-only with offline fallback | Always fetches from network; shows /offline page if network is unavailable |
API routes (/api/, /a2a, /dashboard/endpoint) |
Bypass (never cached) | Always goes directly to the server — never intercepted by the service worker |
Offline Page
When the network is unavailable and a user navigates to a new page, the service worker serves a dedicated /offline page that:
- Displays a clear "Connectivity Issue" message
- Shows a live online/offline status indicator that updates in real time
- Provides a "Retry Connection" button to reload when connectivity returns
- Links to the Status Page for diagnostics
App Icons
OmniRoute provides icons optimized for each platform:
| File | Size | Used By |
|---|---|---|
icon-512.png |
512×512 | Android install prompt, splash screen |
apple-touch-icon.png |
180×180 | iOS home screen icon |
icon-192.svg |
192×192 (vector) | Android adaptive icon |
apple-touch-icon.svg |
180×180 (vector) | Apple fallback |
favicon.svg |
Vector | Browser tabs |
favicon.ico |
Multi-size | Legacy browsers |
Automatic Registration
The service worker is registered automatically via the <PwaRegister /> component in the root layout. No user action is needed — the app becomes installable as soon as the browser detects the valid manifest and service worker.
Technical Architecture
Web App Manifest (manifest.webmanifest)
Generated by Next.js via src/app/manifest.ts:
{
"name": "OmniRoute",
"short_name": "OmniRoute",
"description": "OmniRoute is an AI gateway for multi-provider LLMs. One endpoint for all your AI providers.",
"start_url": "/",
"scope": "/",
"display": "fullscreen",
"orientation": "any",
"background_color": "#0b0f1a",
"theme_color": "#0b0f1a",
"icons": [
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" },
{ "src": "/apple-touch-icon.png", "sizes": "180x180", "type": "image/png" }
]
}
Service Worker (public/sw.js)
A vanilla service worker (no framework dependencies) with:
- Install phase: Pre-caches the app shell (root, offline page, manifest, icons)
- Activate phase: Cleans up old cache versions and claims all clients
- Fetch phase: Intelligent routing based on request type (navigation, static asset, API)
- Cache versioning:
omniroute-pwa-v2— bump this to force a fresh cache on update
Layout Metadata (src/app/layout.tsx)
The root layout provides all the meta tags required for PWA compliance:
manifestlink to/manifest.webmanifestapple-web-app-capable: truefor iOS standalone modeapple-web-app-status-bar-style: black-translucentmobile-web-app-capable: yesfor Android Chrometheme-color: #0b0f1aviewport-fit: coverfor edge-to-edge rendering
Component: PwaRegister
Located at src/shared/components/PwaRegister.tsx, this client component:
- Runs on mount (client-side only)
- Checks for
serviceWorkersupport in the browser - Registers
/sw.jssilently (errors are swallowed to avoid blocking the app) - Renders nothing (
return null) — it's a side-effect-only component
Use With Termux (Android)
When running OmniRoute on Android via Termux, the PWA works seamlessly:
- Start OmniRoute in Termux:
npx omniroute - Open Chrome on the same phone:
http://localhost:20128 - Install the PWA via "Add to Home Screen"
- The PWA connects to the local Termux server — everything runs on-device
This combination means your Android phone is both the server (Termux) and the client (PWA) — a complete self-contained AI gateway.
Use From Other Devices
Install the PWA on any device that has browser access to your OmniRoute server:
- Another phone/tablet: Navigate to
http://PHONE_IP:20128and install the PWA - Laptop: Open Chrome/Edge and install it as a desktop PWA
- Smart TV with browser: Access the dashboard fullscreen
Customization
Instance Name
The PWA title respects the Instance Name setting from Dashboard → Settings. If you rename your instance to "My AI Gateway", the installed PWA will show that name.
Custom Favicon
If you upload a custom favicon via Dashboard → Settings, the PWA icon on desktop will reflect the custom icon. Mobile home screen icons use the pre-built icon-512.png and apple-touch-icon.png files.
Limitations
- No push notifications — The service worker does not implement the Push API. Notifications are handled by the Electron app instead.
- No background sync — Offline actions are not queued for replay. The PWA is primarily a dashboard viewer.
- iOS restrictions — Safari on iOS does not support all PWA features (e.g., install prompts are manual, and background service workers are limited).
- Cache size — The service worker caches static assets only. Large response payloads from
/api/routes are never cached. - Custom icons on mobile — Changing the favicon in settings does not update the home screen icon on mobile (this requires regenerating the PWA icons).
Files Reference
| File | Purpose |
|---|---|
src/app/manifest.ts |
Next.js manifest route (generates manifest.webmanifest) |
public/sw.js |
Service worker with caching logic |
src/shared/components/PwaRegister.tsx |
Client component that registers the service worker |
src/app/offline/page.tsx |
Offline fallback page with live status indicator |
src/app/layout.tsx |
Root layout with PWA metadata (apple-web-app, theme-color, etc.) |
public/icon-512.png |
512×512 PNG icon (Android, splash screen) |
public/apple-touch-icon.png |
180×180 PNG icon (iOS home screen) |
public/icon-192.svg |
192×192 SVG icon (Android adaptive) |
public/apple-touch-icon.svg |
180×180 SVG icon (Apple fallback) |