V5 Wrapper Persistence Flow
Purpose: Visual guide showing how the Coditect V5 wrapper always remains around theia IDE.
Related Documents:
- ADR-026: Wrapper Persistence Architecture
- DEFINITIVE-V5-architecture.md
- V5-THEIA-WRAPPER-architecture.md
High-Level Flow
┌─────────────────────────────────────────────────────────────────────────────────┐
│ USER │
│ │
│ Accesses: http://coditect.ai/ide or http://coditect.ai/workspace │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────────────────┐
│ NGINX (Port 80/443) │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ location / { │ │
│ │ root /app/v5-frontend; ← Serves React SPA │ │
│ │ try_files $uri /index.html; │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ location = /theia { │ │
│ │ return 301 /ide; ← 🔒 SECURITY: Redirect to wrapper │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ location /theia/ { │ │
│ │ proxy_pass http://localhost:3000; ← theia API/WebSocket │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────────────────┐
│ V5 REACT WRAPPER (Port 5173/80) │
│ │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ HEADER (56px) │ │
│ │ ┌──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐ │ │
│ │ │ Logo │ IDE │ Docs │ Support │ Theme │ User │ │ │
│ │ │ │ │ │ │ Toggle │ Menu │ │ │
│ │ └──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘ │ │
│ │ │ │
│ │ ✅ Always visible - provides navigation to all V5 endpoints │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ MAIN CONTENT AREA (Flex: 1) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ React Router <Routes> │ │ │
│ │ │ │ │ │
│ │ │ /ide → <layout tabModality="theia"> │ │ │
│ │ │ /workspace → <layout tabModality="workspace"> │ │ │
│ │ │ /ai-studio → <layout tabModality="ai-studio"> │ │ │
│ │ │ /docs → <layout showIDE={false}><DocsPage /></layout> │ │ │
│ │ │ /settings → <layout showIDE={false}><SettingsPage /> │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ ↓ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ TabModality = "theia" │ │ │
│ │ │ │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ theiaEmbed Component (iframe) │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ 🔒 Sandbox Attributes: │ │ │ │
│ │ │ │ ✅ allow-same-origin (postMessage) │ │ │ │
│ │ │ │ ✅ allow-scripts (theia JS) │ │ │ │
│ │ │ │ ✅ allow-forms (theia forms) │ │ │ │
│ │ │ │ ✅ allow-modals (theia dialogs) │ │ │ │
│ │ │ │ ✅ allow-popups (file downloads) │ │ │ │
│ │ │ │ ❌ NO allow-top-navigation (prevents breakout) │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ src="http://localhost:3000?sessionId=xyz" │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ ECLIPSE THEIA IDE (Port 3000) │ │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ - Monaco editor (TypeScript, Python, etc.) │ │ │ │ │
│ │ │ │ │ - terminal (xterm.js) │ │ │ │ │
│ │ │ │ │ - File Explorer (tree view) │ │ │ │ │
│ │ │ │ │ - AI Chat (theia AI extension) │ │ │ │ │
│ │ │ │ │ - Settings, Search, Debug, Extensions │ │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ ✅ Cannot navigate parent window (sandbox) │ │ │ │ │
│ │ │ │ │ ✅ Cannot break out of iframe │ │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ FOOTER (40px) │ │
│ │ ┌──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐ │ │
│ │ │ © 2025 │ Privacy │ Terms │ Status │ FAQ │ Version │ │ │
│ │ │ Coditect │ │ │ │ │ v5.0 │ │ │
│ │ └──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘ │ │
│ │ │ │
│ │ ✅ Always visible - provides links to important pages │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Security: Redirect Protection
❌ Direct /theia Access Prevented
User tries: http://coditect.ai/theia
↓
┌───────────────────────┐
│ NGINX location = /theia │
│ return 301 /ide; │
└───────────────────────┘
↓
HTTP 301 Redirect
↓
User lands at: http://coditect.ai/ide
↓
┌───────────────────────┐
│ V5 Wrapper + theia │
│ Header/Footer visible │
└───────────────────────┘
Effect: Users cannot bypass the wrapper by accessing /theia directly.
✅ Wrapper Access (Normal Flow)
User accesses: http://coditect.ai/ide
↓
┌───────────────────────┐
│ NGINX location / │
│ Serves V5 React SPA │
└───────────────────────┘
↓
React Router loads
↓
<layout tabModality="theia">
↓
┌───────────────────────┐
│ Header │
│ theiaEmbed (iframe) │
│ Footer │
└───────────────────────┘
↓
iframe loads: http://localhost:3000?sessionId=xyz
↓
┌───────────────────────┐
│ theia Backend │
│ (proxied via NGINX) │
└───────────────────────┘
Effect: Wrapper always present, theia embedded securely.
Three Tab Modalities
The V5 wrapper supports three different IDE experiences, all with wrapper persistence:
1. theia IDE Tab (/ide)
┌────────────────────────────────────────────────────────────────┐
│ HEADER (V5) │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ FULL ECLIPSE THEIA IDE │ │
│ │ (iframe) │ │
│ │ │ │
│ │ - Complete IDE experience │ │
│ │ - Monaco editor, terminal, File Explorer │ │
│ │ - AI Chat, Extensions, Settings │ │
│ │ - Professional developers │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
├────────────────────────────────────────────────────────────────┤
│ FOOTER (V5) │
└────────────────────────────────────────────────────────────────┘
2. workspace Tab (/workspace)
┌────────────────────────────────────────────────────────────────┐
│ HEADER (V5) │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┬──────────────────────────────────────────────┐ │
│ │ File │ │ │
│ │ Tree │ Monaco editor │ │
│ │ │ (theia Widget) │ │
│ │ (theia │ │ │
│ │ Widget) │ │ │
│ └──────────┴──────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ terminal (theia Widget) │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
├────────────────────────────────────────────────────────────────┤
│ FOOTER (V5) │
└────────────────────────────────────────────────────────────────┘
Key: Uses theia widgets directly (no full iframe), gives V5 more control.
3. AI Studio Tab (/ai-studio)
┌────────────────────────────────────────────────────────────────┐
│ HEADER (V5) │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┬──────────────────────────────────┐ │
│ │ │ │ │
│ │ AI Chat Panel │ Code Preview Panel │ │
│ │ (LM Studio) │ (Monaco editor) │ │
│ │ │ │ │
│ │ - Model selector │ - Live preview │ │
│ │ - Chat history │ - Syntax highlighting │ │
│ │ - Prompt input │ - Copy/Apply code │ │
│ │ │ │ │
│ │ Loveable-style │ │ │
│ │ split screen │ │ │
│ │ │ │ │
│ └──────────────────────┴──────────────────────────────────┘ │
│ │
├────────────────────────────────────────────────────────────────┤
│ FOOTER (V5) │
└────────────────────────────────────────────────────────────────┘
Key: No full theia, custom V5 UI with AI focus (novice-friendly).
Component Hierarchy
app.tsx (React Router)
│
├─ <layout> ← Wrapper component
│ │
│ ├─ <Header> ← ✅ Always visible
│ │ ├─ Logo
│ │ ├─ Navigation (IDE, Docs, Support)
│ │ ├─ Theme Toggle
│ │ └─ User Menu
│ │
│ ├─ <MainContent>
│ │ │
│ │ └─ Based on tabModality:
│ │ │
│ │ ├─ tabModality="theia"
│ │ │ └─ <theiaEmbed> ← iframe with sandbox
│ │ │ └─ theia IDE (3000)
│ │ │
│ │ ├─ tabModality="workspace"
│ │ │ └─ <workspaceTab>
│ │ │ ├─ <theiafile-explorerWidget>
│ │ │ ├─ <theiaMonacoWidget>
│ │ │ └─ <theiaterminalWidget>
│ │ │
│ │ └─ tabModality="ai-studio"
│ │ └─ <ai-studioTab>
│ │ ├─ <ChatPanel>
│ │ └─ <PreviewPanel>
│ │
│ └─ <Footer> ← ✅ Always visible
│ ├─ Copyright
│ ├─ Links (Privacy, Terms, Status, FAQ)
│ └─ Version
│
└─ (Routes without IDE)
└─ <layout showIDE={false}>
├─ <Header>
├─ <DocumentationPage>
└─ <Footer>
Key Insight: Every route uses <layout>, ensuring Header/Footer always present.
Iframe Sandbox Security
Sandbox Attributes Explained
<iframe
src="http://localhost:3000?sessionId=xyz"
sandbox="
allow-same-origin ← ✅ Enables postMessage (theme sync)
allow-scripts ← ✅ theia needs JavaScript
allow-forms ← ✅ theia forms (settings, search)
allow-modals ← ✅ theia dialogs
allow-popups ← ✅ File downloads
allow-downloads ← ✅ Save files
"
// ❌ NOT INCLUDED: allow-top-navigation (prevents breakout)
/>
What Each Attribute Does
| Attribute | Purpose | Why Included? |
|---|---|---|
allow-same-origin | postMessage between iframe and parent | ✅ Theme sync, communication |
allow-scripts | Execute JavaScript | ✅ theia requires JS |
allow-forms | Submit forms | ✅ theia settings, search |
allow-modals | Show modal dialogs | ✅ theia prompts |
allow-popups | Open popups | ✅ File downloads |
allow-downloads | Download files | ✅ Save files |
allow-top-navigation | Navigate parent window | ❌ NOT INCLUDED - prevents breakout |
Security Test
// Inside theia iframe console:
try {
window.top.location = 'http://evil.com'
} catch (e) {
console.error('Blocked by sandbox:', e)
// SecurityError: Blocked by sandbox
}
Result: ❌ Blocked - theia cannot navigate parent window.
Navigation Flow
User Clicks "Docs" in Header
User clicks Header → "Docs"
↓
React Router navigates to /docs
↓
<layout showIDE={false}>
<Header /> ← Still present
<DocumentationPage />
<Footer /> ← Still present
</layout>
↓
User can click "IDE" to return
↓
React Router navigates to /ide
↓
<layout showIDE tabModality="theia">
<Header /> ← Still present
<theiaEmbed /> ← Back to IDE
<Footer /> ← Still present
</layout>
Key: Header and Footer never disappear - seamless navigation.
User Switches Sessions
User clicks session tab "Project A"
↓
SessionTabManager updates currentSessionId
↓
theiaEmbed re-renders with new sessionId
↓
iframe src="http://localhost:3000?sessionId=projectA"
↓
theia loads different workspace
↓
Header/Footer remain unchanged ✅
Development vs Production
Development Mode
Developer runs:
npm run dev (V5 wrapper on :5173)
npm run theia:start (theia on :3000)
Access:
✅ http://localhost:5173/ide → Wrapper + theia
⚠️ http://localhost:3000 → Direct theia (no wrapper)
Notes:
- Direct :3000 access is OK for theia debugging
- Recommended to use :5173/ide for normal development
- No redirect on :3000 (developer choice)
Production Mode
Docker container runs:
NGINX on :80
theia on :3000 (internal)
V5 frontend served from /app/v5-frontend
Access:
✅ http://coditect.ai/ide → Wrapper + theia
❌ http://coditect.ai/theia → 301 redirect to /ide
❌ http://coditect.ai:3000 → Blocked by firewall
Notes:
- :3000 not exposed externally
- /theia redirects to /ide (NGINX)
- Users MUST go through wrapper
Summary: Why Wrapper Always Stays
🔒 Three Layers of Protection
-
React Router: All routes use
<layout>component- Header and Footer always rendered
- Navigation happens client-side (no page reloads)
-
Iframe Sandbox: theia cannot break out
allow-top-navigationNOT included- theia cannot navigate parent window
- Wrapper stays in control
-
NGINX Redirect: Direct /theia access prevented
location = /theia { return 301 /ide; }- Users redirected to wrapper
- Production enforcement
✅ Benefits
- Navigation: Always accessible via Header
- Branding: Coditect logo always visible
- Features: Full V5 features available
- Consistency: Same experience across all pages
- Documentation: /docs, /support always one click away
📊 User Experience Flow
Start → Login → /ide → Use theia (in iframe)
↓
Click "Docs" (Header)
↓
/docs → Read documentation
↓
Click "IDE" (Header)
↓
/ide → Back to theia (in iframe)
↓
Click "Settings" (Header)
↓
/settings → Update preferences
↓
Click "IDE" (Header)
↓
/ide → Resume work
Header/Footer present at EVERY step ✅
References
- ADR-026: Wrapper Persistence Architecture
- DEFINITIVE-V5-architecture.md: Complete V5 design
- V5-THEIA-WRAPPER-architecture.md: React-theia integration
- nginx-combined.conf: NGINX configuration with redirect
- layout.tsx: Wrapper component implementation
- theia-embed.tsx: Iframe component with sandbox
Last Updated: 2025-10-13 Version: 1.0 Purpose: Visual documentation of wrapper persistence flow