Skip to main content

V5 theia Wrapper Architecture

Date: 2025-10-08 Status: ✅ STRATEGIC ARCHITECTURE


🎯 Core Insight

V5 = theia + Thin Wrapper Layer

We're not building an IDE. We're building a mobile-first, multi-tenant wrapper around Eclipse theia's mature IDE platform.

What theia Provides (95% of functionality)

  • ✅ Complete AI system (chat, agents, code completion)
  • ✅ Monaco code editor (VS Code-quality)
  • ✅ Integrated terminal (xterm.js)
  • ✅ File explorer with drag-drop
  • ✅ Git integration
  • ✅ Extension system (VS Code compatible)
  • ✅ Debugging
  • ✅ Search & replace
  • ✅ Multi-file editing
  • ✅ Command palette
  • ✅ Keybindings
  • ✅ Themes
  • ✅ Settings UI

What V5 Adds (5% unique value)

  • 🆕 Mobile-first responsive wrapper (320px to 4K)
  • 🆕 Touch-friendly navigation (56px targets)
  • 🆕 Multi-tenant session routing
  • 🆕 Header/Footer branding
  • 🆕 Three tab modalities (AI Studio / workspace / theia IDE)
  • 🆕 V5 backend integration (JWT auth, FoundationDB)
  • 🆕 Progressive disclosure (accordion cards)
  • 🆕 LM Studio integration (16+ local llms)

🏗️ Architecture Layers

┌─────────────────────────────────────────────────────────┐
│ V5 Wrapper Layer (React + Chakra UI) │
│ ───────────────────────────────────────────────── │
│ • Header (56px) - Logo, nav, user menu, theme │
│ • Footer (40px) - Copyright, links │
│ • Mobile navigation - TouchFriendlyCard system │
│ • Session routing - /ai-studio/:sessionId │
│ • Multi-tab modality - AI Studio / workspace / IDE │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ React-theia Bridge Layer (Wrapper Components) │
│ ───────────────────────────────────────────────── │
│ • theiaChatWidget - Wraps ChatViewWidget │
│ • theiaterminalWidget - Wraps terminalWidget │
│ • theiaMonacoWidget - Wraps Monacoeditor │
│ • theiafile-explorerWidget - Wraps FileTreeWidget │
│ • theiaDI Container - Inversify ↔ React bridge │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ Eclipse theia Platform (Inversify DI) │
│ ───────────────────────────────────────────────── │
│ • @theia/ai-chat-ui - Complete AI chat interface │
│ • @theia/terminal - Multi-terminal support │
│ • @theia/monaco - VS Code editor │
│ • @theia/navigator - File tree + operations │
│ • @theia/ai-core - Agent system, MCP, tools │
│ • @theia/workspace - Multi-folder workspaces │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ Backend Services (Rust + FoundationDB) │
│ ───────────────────────────────────────────────── │
│ • JWT authentication (V5 API) │
│ • Session persistence (FoundationDB) │
│ • File operations (FDB + OPFS) │
│ • LM Studio proxy (http://localhost:1234/v1) │
│ • WebSocket sidecar (real-time sync) │
└─────────────────────────────────────────────────────────┘

🎨 Three Tab Modalities (All Use theia Components)

1. AI Studio Tab (Loveable-Style)

layout: Split-screen (Chat | Preview)

// src/components/ai-studio/ai-studio-tab.tsx
export const ai-studioTab = ({ tabId }: { tabId: string }) => {
return (
<SplitPane>
{/* LEFT: theia AI Chat */}
<Panel minSize="40%" defaultSize="50%">
<theiaChatWidget
sessionId={tabId}
agents={['code-generator', 'ui-designer']}
showHistory
/>
</Panel>

{/* RIGHT: Live Preview */}
<Panel minSize="40%">
<CodePreview
sessionId={tabId}
mode="live-reload"
/>
</Panel>
</SplitPane>
)
}

What's Custom: Split layout, CodePreview component What's theia: Chat UI, AI agents, model selection


2. workspace Tab (VS Code-Style)

layout: Explorer | editor | terminal

// src/components/workspace/workspace-tab.tsx
export const workspaceTab = ({ tabId }: { tabId: string }) => {
return (
<Flex direction="column" h="100%">
{/* TOP: Tab bar (custom mobile-first) */}
<TouchFriendlyTabBar
openFiles={openFiles}
onFileSelect={handleFileSelect}
/>

{/* MIDDLE: Main area */}
<Flex flex={1}>
{/* LEFT: theia File Explorer */}
<theiafile-explorerWidget
sessionId={tabId}
onFileOpen={handleFileOpen}
width={isExplorerOpen ? 280 : 0}
/>

{/* CENTER: theia Monaco editor */}
<theiaMonacoWidget
sessionId={tabId}
file={activeFile}
onChange={handleContentChange}
/>
</Flex>

{/* BOTTOM: theia terminal */}
<theiaterminalWidget
sessionId={tabId}
height={isterminalOpen ? 200 : 0}
/>
</Flex>
)
}

What's Custom: TouchFriendlyTabBar, responsive layout What's theia: File explorer, Monaco editor, terminal


3. theia IDE Tab (Full theia)

layout: Full iframe embed

// src/components/theia-embed.tsx
export const theiaEmbed = ({ sessionId }: { sessionId: string }) => {
return (
<iframe
src={`http://localhost:3000?sessionId=${sessionId}`}
style={{ width: '100%', height: '100%', border: 'none' }}
sandbox="allow-same-origin allow-scripts allow-forms"
/>
)
}

What's Custom: Iframe wrapper, session routing What's theia: Everything (100% native experience)


🔌 React-theia Bridge Pattern

The Challenge

  • theia: Uses Inversify DI container
  • React: Uses props/hooks/context

We need to bridge these two worlds.

The Solution

Create a theiaDI service that exposes theia widgets to React:

// src/services/theia-di-service.ts
import { Container } from '@theia/core/shared/inversify'
import { ChatViewWidget } from '@theia/ai-chat-ui/lib/browser/chat-view-widget'
import { terminalWidget } from '@theia/terminal/lib/browser/terminal-widget'
import { Monacoeditor } from '@theia/monaco/lib/browser/monaco-editor'

/**
* theia DI Service - Bridge between theia's Inversify container and React.
*
* Provides access to theia widgets from React components.
*/
class theiaDIService {
private container: Container | null = null
private widgetCache = new Map<string, any>()

/**
* Initialize with theia's DI container.
* Called once during app startup.
*/
initialize(container: Container) {
this.container = container
console.log('✅ theia DI container initialized')
}

/**
* Get or create a theia widget.
*/
getWidget<T>(identifier: symbol | string, sessionId?: string): T {
if (!this.container) {
throw new Error('theia DI container not initialized')
}

// Use cache for singletons
const cacheKey = `${String(identifier)}-${sessionId || 'default'}`
if (this.widgetCache.has(cacheKey)) {
return this.widgetCache.get(cacheKey)
}

const widget = this.container.get<T>(identifier)
this.widgetCache.set(cacheKey, widget)
return widget
}

/**
* Create a new ChatViewWidget instance.
*/
createChatWidget(sessionId: string): ChatViewWidget {
return this.getWidget<ChatViewWidget>(ChatViewWidget, sessionId)
}

/**
* Create a new terminalWidget instance.
*/
createterminalWidget(sessionId: string): terminalWidget {
return this.getWidget<terminalWidget>(terminalWidget, sessionId)
}

/**
* Create a new Monacoeditor instance.
*/
createMonacoeditor(sessionId: string): Monacoeditor {
return this.getWidget<Monacoeditor>(Monacoeditor, sessionId)
}
}

export const theiaDI = new theiaDIService()

📦 Wrapper Component Pattern

All theia widgets follow this pattern:

// src/components/theia/theia-chat-widget.tsx
import React, { useRef, useEffect } from 'react'
import { Box } from '@chakra-ui/react'
import { ChatViewWidget } from '@theia/ai-chat-ui/lib/browser/chat-view-widget'
import { theiaDI } from '../../services/theia-di-service'

interface theiaChatWidgetProps {
sessionId: string
height?: string | number
}

export const theiaChatWidget: React.FC<theiaChatWidgetProps> = ({
sessionId,
height = '100%',
}) => {
const containerRef = useRef<HTMLDivElement>(null)
const widgetRef = useRef<ChatViewWidget | null>(null)

useEffect(() => {
if (!containerRef.current) return

// Get widget from theia DI container
const widget = theiaDI.createChatWidget(sessionId)

// Mount widget to DOM
widget.node.style.height = '100%'
widget.node.style.width = '100%'
containerRef.current.appendChild(widget.node)
widgetRef.current = widget

// Trigger widget initialization
widget.activate()

return () => {
// Cleanup on unmount
if (widget.dispose) {
widget.dispose()
}
}
}, [sessionId])

return (
<Box
ref={containerRef}
h={height}
w="100%"
overflow="hidden"
sx={{
'& .theia-widget': {
height: '100%',
},
}}
/>
)
}

🖥️ terminal Integration & Connectivity

terminal Architecture Overview

The theiaterminalWidget provides terminal access within the IDE. Where the terminal connects depends on the deployment mode:

┌─────────────────────────────────────────────────────┐
│ User Browser │
│ ├─ V5 Frontend (React) │
│ └─ theiaterminalWidget (React wrapper) │
└─────────────────────────────────────────────────────┘
↓ WebSocket
┌─────────────────────────────────────────────────────┐
│ theia Backend (Node.js) │
│ └─ @theia/terminal │
└─────────────────────────────────────────────────────┘
↓ pty (pseudo-terminal)
┌─────────────────────────────────────────────────────┐
│ Shell Process (bash/zsh/sh) │
│ └─ Runs in: Container OS | Host OS | Remote OS │
└─────────────────────────────────────────────────────┘

Four terminal Connectivity Modes

Mode 1: Container-Only (Production)

terminal connects to: Container OS (Debian)

// theiaterminalWidget configuration
<theiaterminalWidget
sessionId={sessionId}
shell="/bin/bash" // Container's bash
cwd="/workspace" // Container's filesystem
/>

Characteristics:

  • ✅ Secure (isolated from host)
  • ✅ Multi-tenant safe
  • ❌ No access to host files
  • ❌ Git requires manual setup in container

Git Setup:

# Inside container
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Mode 2: Volume Mount (Local Development)

terminal connects to: Container OS (Debian) with host filesystem mounted

// Same theiaterminalWidget, but docker run includes volumes
// docker run -v /host/path:/workspace ...

<theiaterminalWidget
sessionId={sessionId}
shell="/bin/bash"
cwd="/workspace" // Points to mounted host directory
/>

Characteristics:

  • ✅ Edit local files
  • ✅ Git uses host config (if mounted)
  • ✅ Fast iteration
  • ⚠️ Line ending issues (Windows CRLF vs Linux LF)

Docker Configuration:

docker run -d \
-v /home/user/projects:/workspace \
-v /home/user/.gitconfig:/root/.gitconfig:ro \
-v /home/user/.ssh:/root/.ssh:ro \
coditect-combined:test

Git Works Automatically (if volumes mounted)


Mode 3: Remote SSH (Future)

terminal connects to: Remote machine via SSH

// Future implementation - requires theia SSH extension
<theiaterminalWidget
sessionId={sessionId}
remoteHost="dev-server.company.com"
remoteUser="developer"
shell="/bin/bash"
cwd="/home/developer/workspace"
/>

Characteristics:

  • ✅ Native OS access (Windows/Mac/Linux)
  • ✅ Full tool access on remote machine
  • ✅ Git is native on remote
  • ❌ Requires theia SSH extension (not yet implemented)

Architecture:

Browser → theia (Docker) → SSH → Remote Server → Native Shell

Mode 4: Native Desktop (Alternative)

terminal connects to: Host OS (Windows/Mac/Linux)

// No Docker - theia runs on host OS
<theiaterminalWidget
sessionId={sessionId}
shell="C:\\Windows\\System32\\cmd.exe" // Windows
// OR shell="/bin/zsh" // Mac/Linux
cwd="C:\\Users\\Developer\\Projects"
/>

Characteristics:

  • ✅ Perfect OS integration
  • ✅ Git seamless
  • ✅ All local tools available
  • ❌ No isolation (single-user only)

theiaterminalWidget Wrapper Implementation

// src/components/theia/theia-terminal-widget.tsx
import React, { useRef, useEffect } from 'react'
import { Box } from '@chakra-ui/react'
import { terminalWidget } from '@theia/terminal/lib/browser/terminal-widget'
import { theiaDI } from '../../services/theia-di-service'

interface theiaterminalWidgetProps {
sessionId: string
height?: string | number
shell?: string // Override default shell
cwd?: string // Initial working directory
}

export const theiaterminalWidget: React.FC<theiaterminalWidgetProps> = ({
sessionId,
height = 200,
shell = '/bin/bash',
cwd = '/workspace',
}) => {
const containerRef = useRef<HTMLDivElement>(null)
const widgetRef = useRef<terminalWidget | null>(null)

useEffect(() => {
if (!containerRef.current) return

// Get widget from theia DI container
const widget = theiaDI.createterminalWidget(sessionId)

// Configure terminal
widget.start({
shell,
cwd,
env: {
SESSION_ID: sessionId,
TERM: 'xterm-256color',
},
})

// Mount widget to DOM
widget.node.style.height = '100%'
widget.node.style.width = '100%'
containerRef.current.appendChild(widget.node)
widgetRef.current = widget

// Trigger widget initialization
widget.activate()

return () => {
// Cleanup on unmount
if (widget.dispose) {
widget.dispose()
}
}
}, [sessionId, shell, cwd])

return (
<Box
ref={containerRef}
h={height}
w="100%"
bg="gray.900"
overflow="hidden"
sx={{
'& .theia-terminal-widget': {
height: '100%',
},
}}
/>
)
}

Configuration by Deployment Scenario

Production (GKE) - Container-Only Mode

# k8s/coditect-deployment.yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: coditect
image: gcr.io/serene-voltage-464305-n2/coditect-combined:latest
# NO volumes mounted - complete isolation

terminal: Runs in container, isolated per user session


Local Development - Volume Mount Mode

# docker-compose.yml
services:
coditect-dev:
image: coditect-combined:test
volumes:
- /home/user/projects:/workspace
- /home/user/.gitconfig:/root/.gitconfig:ro
- /home/user/.ssh:/root/.ssh:ro

terminal: Runs in container, accesses host files


Enterprise - Remote SSH Mode (Future)

// .theia/settings.json
{
"remote.SSH.hosts": [
{
"host": "dev-server.company.com",
"user": "developer",
"port": 22
}
]
}

terminal: Runs on remote server


Troubleshooting terminal Issues

Problem: terminal shows "bash: command not found" for git

Solution (Container-Only):

# Git not installed in minimal node:20-slim image
# Need to add to Dockerfile:
RUN apt-get update && apt-get install -y git

Solution (Volume Mount):

# Git installed in container, but can use host's git config
# Verify mount: docker exec -it coditect-dev ls -la /root/.gitconfig

Problem: Line endings corrupted (Windows)

Solution:

# In container terminal
git config --global core.autocrlf input

# Or in .gitattributes
echo "* text=auto eol=lf" > .gitattributes

Problem: Permission denied when editing files (Linux/Mac)

Solution:

# Run container as your user
docker run --user $(id -u):$(id -g) ...

# OR fix ownership after
sudo chown -R $USER:$USER /path/to/projects

See Also


🔒 Wrapper Persistence & Security

Decision Reference: ADR-026: V5 Wrapper Persistence Architecture Visual Guide: docs/02-architecture/wrapper-persistence-flow.md

The Security Requirement

The V5 wrapper must always remain around theia to provide:

  • 🧭 Navigation - Header with links to all V5 endpoints
  • 🎨 Branding - Coditect AI logo and custom design
  • 🔐 Authentication - Login, profile, settings access
  • 📊 Session Management - Multi-tab session switching
  • 📚 Documentation - Access to /docs, /support, /faq

Problem: Without protection, users could bypass the wrapper by accessing:

  • Development: http://localhost:3000 (direct theia port)
  • Production: http://coditect.ai/theia (NGINX proxy path)

This would result in loss of navigation, branding, and all V5 features.

Three-Layer Security Architecture

1. React Router Layer

All routes go through <layout> component:

// Every route renders Header + Footer
<Route path="/ide" element={<layout showIDE tabModality="theia" />} />
<Route path="/workspace" element={<layout showIDE tabModality="workspace" />} />
<Route path="/docs" element={<layout showIDE={false}><DocumentationPage /></layout>} />

Effect: Header and Footer always present, ensuring navigation access.

2. Iframe Sandbox Layer

theia embedded with strict sandbox rules:

// src/components/theia-embed.tsx
<iframe
src={`http://localhost:3000?sessionId=${sessionId}`}
sandbox="allow-same-origin allow-scripts allow-forms allow-modals allow-popups allow-downloads"
// ❌ NO allow-top-navigation - prevents breakout!
/>

Security Properties:

  • ✅ Enables postMessage for theme sync
  • ✅ Allows theia JavaScript execution
  • ✅ Permits theia forms and dialogs
  • Blocks parent window navigation (no breakout)

3. NGINX Redirect Layer (Production)

Prevents direct /theia access:

# nginx-combined.conf

# SECURITY: Redirect direct /theia to /ide (wrapper)
location = /theia {
return 301 /ide;
}

# API/WebSocket endpoints (iframe only)
location /theia/ {
rewrite ^/theia/(.*) /$1 break;
proxy_pass http://localhost:3000;
}

Effect:

  • http://coditect.ai/theia → Redirects to /ide (wrapper)
  • http://coditect.ai/theia/services → Proxied for iframe API calls
  • Users cannot bypass wrapper in production

Security Flow Diagram

User accesses http://coditect.ai/ide

NGINX serves V5 React SPA

React Router: <layout showIDE tabModality="theia">

┌──────────────────────────────────┐
│ Header (56px) - Always visible │
├──────────────────────────────────┤
│ theiaEmbed (iframe) │
│ - Sandbox: NO top-navigation │
│ - Cannot break out │
├──────────────────────────────────┤
│ Footer (40px) - Always visible │
└──────────────────────────────────┘

Navigation always available ✅

What Happens When Users Try to Bypass?

Scenario: Direct /theia Access

User tries: http://coditect.ai/theia

NGINX: location = /theia { return 301 /ide; }

HTTP 301 Redirect

Browser: http://coditect.ai/ide

V5 wrapper loads with Header/Footer ✅

Scenario: Iframe Breakout Attempt

// Inside theia iframe console:
try {
window.top.location = 'http://evil.com'
} catch (e) {
console.error('Blocked by sandbox:', e)
// SecurityError: Blocked by iframe sandbox
}

Result: theia cannot navigate parent window.

Benefits of Wrapper Persistence

FeatureWith WrapperWithout Wrapper
Navigation✅ Header links❌ No navigation
Branding✅ Coditect logo❌ theia logo
Documentation✅ /docs accessible❌ Can't access
Session Switching✅ Multi-tab UI❌ No management
Authentication✅ Login/logout❌ No auth UI
Mobile-Friendly✅ Touch targets❌ Desktop-only

Testing Wrapper Security

1. Test NGINX Redirect:

curl -I http://coditect.ai/theia
# Expected: HTTP/1.1 301 Moved Permanently
# Location: /ide

2. Test Wrapper Presence:

// In browser at /ide
document.querySelector('header') // Should exist
document.querySelector('footer') // Should exist

3. Test Iframe Sandbox:

// In theia iframe console
try {
window.top.location = 'http://test.com'
} catch (e) {
console.log('✅ Security confirmed:', e.message)
}

Configuration Summary

nginx-combined.conf (Production):

  • / → V5 React SPA
  • /theia → 301 redirect to /ide
  • /theia/* → Proxy to theia backend

layout.tsx (React):

  • Wraps all routes
  • Always renders Header + Footer

theia-embed.tsx (Iframe):

  • Sandbox without allow-top-navigation
  • Prevents parent window navigation

Further Reading


🚀 Implementation Plan

Phase 1: Setup theia DI Bridge (1 day)

✅ Create src/services/theia-di-service.ts
✅ Create src/components/theia/ directory
✅ Initialize theia container in app.tsx
✅ Test widget instantiation

Phase 2: Create Widget Wrappers (2 days)

✅ theia-chat-widget.tsx - AI chat interface
✅ theia-terminal-widget.tsx - Integrated terminal
✅ theia-monaco-widget.tsx - Code editor
✅ theia-file-explorer-widget.tsx - File tree

Phase 3: Integrate into Tab Modalities (2 days)

✅ Update AI Studio tab - Use theiaChatWidget
✅ Update workspace tab - Use theia components
✅ Keep theia IDE tab - Full iframe embed
✅ Add mobile wrappers (TouchFriendlyCard)

Phase 4: Connect to V5 Backend (1 day)

✅ Configure theia AI to use LM Studio
✅ Wire session persistence to FoundationDB
✅ Test JWT auth with theia requests
✅ Verify file operations work

🎯 Unique Value Proposition

What Makes V5 Different from Stock theia?

FeatureStock theiaV5 (theia + Wrapper)
Mobile SupportDesktop-onlyTouch-friendly (320px to 4K)
Multi-TenancySingle workspaceSession-based isolation
Tab ModalitiesOne IDEAI Studio / workspace / Full IDE
NavigationMenu + sidebarsProgressive disclosure cards
AuthNo built-inJWT + V5 backend
llmsCloud APIs16+ local models (LM Studio)
PersistenceLocal filesFoundationDB + OPFS sync
Brandingtheia logoCustom header/footer
Use CasesDeveloper IDENovice to Pro progression

V5 = theia Made Mobile-First, Multi-Tenant, and Local-llm Powered


📱 Mobile-First Enhancements

Touch-Friendly Wrappers

Wrap theia widgets in mobile-optimized containers:

// Mobile-optimized AI chat
export const MobileAIChatWidget = ({ sessionId }) => {
const [isExpanded, setIsExpanded] = useState(true)

return (
<TouchFriendlyCard
title="AI Assistant"
icon={FiMessageSquare}
isOpen={isExpanded}
onToggle={() => setIsExpanded(!isExpanded)}
>
<Box h={{ base: '300px', md: '100%' }}>
<theiaChatWidget sessionId={sessionId} />
</Box>
</TouchFriendlyCard>
)
}

Responsive layout Adjustments

// Desktop: Side-by-side
// Mobile: Stack vertically
<Stack
direction={{ base: 'column', md: 'row' }}
h="100%"
spacing={0}
>
<Box
w={{ base: '100%', md: '280px' }}
h={{ base: '40%', md: '100%' }}
>
<theiafile-explorerWidget />
</Box>

<Box flex={1}>
<theiaMonacoWidget />
</Box>
</Stack>

🔗 Configuration: theia → LM Studio

theia's @theia/ai-openai package supports OpenAI-compatible APIs. LM Studio IS OpenAI-compatible.

Step 1: Configure theia Preferences

// .theia/settings.json
{
"ai.openai.api.baseUrl": "http://localhost:1234/v1",
"ai.openai.api.key": "not-needed",
"ai.openai.models": [
"meta-llama-3.3-70b-instruct",
"qwen/qwq-32b",
"deepseek-coder-v2"
],
"ai.chat.defaultAgent": "code-generator"
}

Step 2: Register Custom Agents (Optional)

// src/browser/ai-agents/custom-agents-module.ts
import { ContainerModule } from '@theia/core/shared/inversify'
import { Agent } from '@theia/ai-core'

export default new ContainerModule(bind => {
bind(Agent).toConstantValue({
id: 'code-generator',
name: 'Code Generator',
description: 'Generates production-ready code',
model: 'meta-llama-3.3-70b-instruct',
prompt: 'You are an expert software engineer...',
})

bind(Agent).toConstantValue({
id: 'ui-designer',
name: 'UI Designer',
description: 'Designs mobile-first UIs',
model: 'qwen/qwq-32b',
prompt: 'You are an expert UI/UX designer...',
})
})

✅ Success Criteria

Week 1 Deliverables

  • theia DI bridge service working
  • theiaChatWidget wrapper created and tested
  • AI Studio tab using theiaChatWidget
  • Chat connected to LM Studio
  • Mobile-responsive (tested on 320px)

Week 2 Deliverables

  • theiaterminalWidget wrapper created
  • theiaMonacoWidget wrapper created
  • theiafile-explorerWidget wrapper created
  • workspace tab using all theia components
  • Session routing working

Week 3 Deliverables

  • V5 backend integration (JWT auth)
  • FoundationDB session persistence
  • Touch-friendly mobile wrappers
  • Full E2E testing
  • Documentation complete

🎉 Final Result

What We Get

A production-ready IDE with:

  • ✅ VS Code-quality editor (Monaco)
  • ✅ Full AI chat with 16+ local llms
  • ✅ Multi-terminal support
  • ✅ File explorer with drag-drop
  • ✅ Code completion, debugging, git
  • ✅ Mobile-first responsive UI
  • ✅ Multi-tenant session isolation
  • ✅ Three tab modalities for different skill levels

What We Build

Just the wrapper layer:

  • ~500 lines: React-theia bridge
  • ~800 lines: Wrapper components
  • ~400 lines: Mobile-first layout
  • ~300 lines: V5 backend integration

Total: ~2,000 lines of custom code vs 50,000+ lines if we built from scratch


📚 References


Conclusion: V5 is a thin, mobile-first wrapper around theia's mature IDE platform. We leverage 95% of theia's functionality and add 5% unique value (mobile UX, multi-tenancy, local llms).

Strategic Decision: Wrap, don't rewrite. Build on giants' shoulders.


Document Version: 1.0.0 Last Updated: 2025-10-08 Status: ✅ APPROVED ARCHITECTURE