2026 03 07 Vitto Mobile Separation Design
Documentation for Plans
Vitto Mobile/Extension Separation - Implementation Plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Make vitto-mobile render only chat + observatory (same as chrome extension), while desktop keeps the full app.
Architecture: Rename /panel-v2 route to /vitto-mobile, auto-redirect Capacitor mobile to it, hide the header on that route. No new components or apps — reuses existing VittoPanelUnifiedComponent.
Tech Stack: Angular 20 routing, Capacitor bridge detection, Chrome Extension sidepanel
Date: 2026-03-07 Session: 188.2 Status: Approved
Problem
The vitto-mobile (Capacitor) app renders the full gograb-ai Angular app — dashboard, navigation header, all routes — instead of a focused experience. The vitto-chrome-extension already solves this by loading only /panel-v2 (chat + observatory), but mobile doesn't follow the same pattern.
Goal: Mobile should render only what the extension renders (chat + observatory), while desktop continues to get the full app.
Current Architecture
| Host | Load Method | What It Renders |
|---|---|---|
| Desktop (Tauri) | Bundled WebView, full app | All routes (dashboard, vitto, observatory, etc.) |
| Chrome Extension | iframe to /panel-v2 |
Chat + Observatory tabs only |
| Mobile (Capacitor) | Bundled WebView, full app | All routes (same as desktop) - problem |
Key insight: vitto-mobile has no Angular code of its own — it's a Capacitor shell pointing to dist/apps/gograb-ai/browser. All rendering decisions happen inside gograb-ai.
Solution: Route Rename + Mobile Auto-Redirect
Change 1: Rename route /panel-v2 to /vitto-mobile
File: apps/gograb-ai/src/app/app.routes.ts
- Rename the route path from
panel-v2tovitto-mobile - Add redirect:
panel-v2->vitto-mobile(backwards compatibility) - Component stays the same:
VittoPanelUnifiedComponent->AiPanelTabsComponent
Change 2: Update Chrome Extension iframe URL
File: apps/vitto-chrome-extension/sidepanel/sidepanel.js
- Update
buildFrameUrl()to use/vitto-mobileinstead of/panel-v2
Change 3: Auto-redirect mobile to /vitto-mobile
File: apps/gograb-ai/src/app/core/guards/desktop-auth.guard.ts
- When
CapacitorBridgeService.isMobileApp()is true and user navigates to/dashboard(default redirect), redirect to/vitto-mobileinstead - After auth at
/welcome, navigate to/vitto-mobilefor mobile users
Change 4: Hide header on /vitto-mobile route
File: apps/gograb-ai/src/app/app.component.ts
- Add
/vitto-mobileto the fullscreen routes list (alongside/welcome,/auth/desktop,/login) - Mobile gets clean, full-screen chat+observatory with no navigation chrome
What Does NOT Change
- Desktop (Tauri): Unchanged, full app experience
AiPanelTabsComponent: Unchanged, already has Chat + Observatory tabs- Auth flow:
/welcomestill works for mobile onboarding vitto-mobileCapacitor config: No changes to native shell, manifests, or build pipeline- All other routes: Still exist in the app, just not navigable from mobile context
Rendering Matrix (After)
| Host | Default Route | Header | Available Routes |
|---|---|---|---|
| Desktop (Tauri) | /dashboard |
Full header + nav | All routes |
| Chrome Extension | /vitto-mobile (iframe) |
Hidden (embedded) | /vitto-mobile only |
| Mobile (Capacitor) | /vitto-mobile (redirect) |
Hidden (fullscreen) | /vitto-mobile + /welcome + /auth/desktop |
| Browser | /dashboard |
Full header + nav | All routes |
Risk Assessment
- Very low risk — route rename + conditional redirect
- Backwards compatibility preserved via
/panel-v2redirect rule - No new components, no new apps, no build pipeline changes
- Chrome extension and mobile both end up on the same proven component
Implementation Plan
Task 1: Rename /panel-v2 route to /vitto-mobile + add backwards-compat redirect
Files:
- Modify:
apps/gograb-ai/src/app/app.routes.ts:60-67
Step 1: Update route definition
Change the panel-v2 route to vitto-mobile and add a redirect from the old path:
{
// Session 188.2: Renamed from /panel-v2 — unified Chat + Observatory for mobile + extension
path: 'vitto-mobile',
canActivate: [appAuthGuard],
loadComponent: () => import('./pages/vitto-chat-panel/vitto-panel-unified.component').then(m => m.VittoPanelUnifiedComponent),
title: 'Vitto',
},
// Session 188.2: Backwards compat — old /panel-v2 links still work
{ path: 'panel-v2', redirectTo: 'vitto-mobile', pathMatch: 'full' },
Step 2: Verify — run yarn serve:gograb-ai and confirm:
/vitto-mobileloads AiPanelTabsComponent (chat + observatory)/panel-v2redirects to/vitto-mobile
Step 3: Commit
git add apps/gograb-ai/src/app/app.routes.ts
git commit -m "feat: rename /panel-v2 route to /vitto-mobile (S188.2)"
Task 2: Update Chrome Extension to use /vitto-mobile
Files:
- Modify:
apps/vitto-chrome-extension/sidepanel/sidepanel.js:152-171
Step 1: Update buildFrameUrl() and its JSDoc
/**
* Build iframe URL — always /vitto-mobile
*/
function buildFrameUrl(tab, authStatus) {
// ... same params logic ...
return `${AI_APP_URL}/vitto-mobile?${params.toString()}`;
}
Step 2: Verify — reload Chrome extension, confirm sidepanel loads /vitto-mobile in iframe
Step 3: Commit
git add apps/vitto-chrome-extension/sidepanel/sidepanel.js
git commit -m "feat: update chrome extension to use /vitto-mobile route (S188.2)"
Task 3: Hide header on /vitto-mobile route
Files:
- Modify:
apps/gograb-ai/src/app/app.component.ts:109-110
Step 1: Add /vitto-mobile to fullscreen route check and chat input check
const isFullscreenRoute = (url: string) =>
url.startsWith('/welcome') || url.startsWith('/auth/desktop') || url.startsWith('/login') || url.startsWith('/vitto-mobile');
const hasChatInput = (url: string) =>
url.startsWith('/panel') || url.startsWith('/vitto/chat') || url.startsWith('/vitto-mobile');
Step 2: Verify — navigate to /vitto-mobile in browser, confirm header is hidden
Step 3: Commit
git add apps/gograb-ai/src/app/app.component.ts
git commit -m "feat: hide header on /vitto-mobile route for clean mobile UX (S188.2)"
Task 4: Auto-redirect mobile (Capacitor) to /vitto-mobile
Files:
- Modify:
apps/gograb-ai/src/app/core/guards/desktop-auth.guard.ts:112-115 - Modify:
apps/gograb-ai/src/app/pages/desktop-welcome/desktop-welcome.component.ts:77,129,186
Step 1: Split desktop and mobile in auth guard
Replace the combined isDesktop || isMobile block with separate logic:
// Desktop (Tauri) — full app experience
if (isDesktop) {
if (hasActiveSession()) return true;
return router.createUrlTree(['/welcome']);
}
// Mobile (Capacitor) — focused chat+observatory
if (isMobile) {
if (hasActiveSession()) {
// Session 188.2: Mobile gets focused chat+observatory, not full dashboard
if (state.url === '/dashboard' || state.url === '/') {
return router.createUrlTree(['/vitto-mobile']);
}
return true;
}
return router.createUrlTree(['/welcome']);
}
Step 2: Update DesktopWelcomeComponent post-auth navigation (3 locations)
Change all three navigate(['/dashboard']) to:
this.router.navigate([this.capBridge.isMobileApp() ? '/vitto-mobile' : '/dashboard'], { replaceUrl: true });
Step 3: Verify — mock isMobileApp() returning true, confirm mobile lands on /vitto-mobile
Step 4: Commit
git add apps/gograb-ai/src/app/core/guards/desktop-auth.guard.ts apps/gograb-ai/src/app/pages/desktop-welcome/desktop-welcome.component.ts
git commit -m "feat: auto-redirect mobile to /vitto-mobile after auth (S188.2)"
Task 5: Final verification
| Test | Expected |
|---|---|
Browser: / |
Redirects to /dashboard with full header |
Browser: /vitto-mobile |
Full-screen chat+observatory, no header |
Browser: /panel-v2 |
Redirects to /vitto-mobile |
| Extension: open sidepanel | Loads /vitto-mobile in iframe with auth params |
Mobile (mock): / |
Guard redirects to /vitto-mobile |
Desktop (Tauri): / |
Redirects to /dashboard with full header |