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
- Technical Details:
docs/07-adr/adr-025-terminal-workspace-connectivity-options.md - User Guide:
docs/01-getting-started/development-modes.md - Docker Configuration:
docs/01-getting-started/docker-volume-configuration.md
🔒 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
| Feature | With Wrapper | Without 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
- Complete Architecture:
ADR-026-WRAPPER-PERSISTENCE-architecture.md - Visual Flow Diagram:
wrapper-persistence-flow.md - Security Testing: See ADR-026 Appendix B
🚀 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?
| Feature | Stock theia | V5 (theia + Wrapper) |
|---|---|---|
| Mobile Support | Desktop-only | Touch-friendly (320px to 4K) |
| Multi-Tenancy | Single workspace | Session-based isolation |
| Tab Modalities | One IDE | AI Studio / workspace / Full IDE |
| Navigation | Menu + sidebars | Progressive disclosure cards |
| Auth | No built-in | JWT + V5 backend |
| llms | Cloud APIs | 16+ local models (LM Studio) |
| Persistence | Local files | FoundationDB + OPFS sync |
| Branding | theia logo | Custom header/footer |
| Use Cases | Developer IDE | Novice 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