Skip to main content

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

AttributePurposeWhy Included?
allow-same-originpostMessage between iframe and parent✅ Theme sync, communication
allow-scriptsExecute JavaScript✅ theia requires JS
allow-formsSubmit forms✅ theia settings, search
allow-modalsShow modal dialogs✅ theia prompts
allow-popupsOpen popups✅ File downloads
allow-downloadsDownload files✅ Save files
allow-top-navigationNavigate 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.


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

  1. React Router: All routes use <layout> component

    • Header and Footer always rendered
    • Navigation happens client-side (no page reloads)
  2. Iframe Sandbox: theia cannot break out

    • allow-top-navigation NOT included
    • theia cannot navigate parent window
    • Wrapper stays in control
  3. 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