Skip to main content

DEFINITIVE V5 Architecture

Version: 5.0.0 Date: 2025-10-08 Status: ✅ FINAL ARCHITECTURE - NO AMBIGUITY


🎯 Executive Summary

What V5 Is: A mobile-first, multi-tenant AI IDE that wraps Eclipse theia's production-ready components with a custom React UI layer.

Core Strategy: 95% theia + 5% Custom Wrapper = V5

Key Decision: We do NOT build custom IDE components. We wrap theia's battle-tested widgets in mobile-first React components.


📊 The Complete Stack (Definitive)

Frontend Stack

ComponentTechnologyVersionPurposeCustom or theia
UI FrameworkReact18.3Component renderingCustom
TypeScriptTypeScript5.3Type safetyCustom
UI LibraryChakra UI2.8Mobile-first componentsCustom
State ManagementZustand4.4Global state + persistenceCustom
RoutingReact Router6.xSession-based routingCustom
IDE FoundationEclipse theia1.65.0Complete IDE platformtheia
AI Chat@theia/ai-chat-ui1.65.0ChatViewWidgettheia
AI Core@theia/ai-core1.65.0Agent system, MCPtheia
llm Provider@theia/ai-openai1.65.0OpenAI-compatible (LM Studio)theia
MCP Support@theia/ai-mcp1.65.0Model Context Protocoltheia
Code editor@theia/monaco1.65.0Monaco editortheia
terminal@theia/terminal1.65.0xterm.js integrationtheia
File Explorer@theia/navigator1.65.0File tree widgettheia
DI ContainerInversify6.0Dependency injectiontheia

Backend Stack

ComponentTechnologyVersionPurpose
API ServerRust + Actix-web4.xV5 REST API
DatabaseFoundationDB7.1+Session/file persistence
AuthJWT-Token-based authentication
WebSocketActix WS4.xReal-time sync
llm BackendLM Studio0.3+Local llm inference (16+ models)

Infrastructure

ComponentTechnologyPurpose
Container OrchestrationKubernetes (GKE)Pod auto-provisioning
Load BalancerNGINXFrontend routing
Domaincoditect.aiProduction domain
SSLGoogle-managed certHTTPS
Registrygcr.ioContainer images

🏗️ Architecture Diagram (Complete)

┌──────────────────────────────────────────────────────────────────┐
│ USER (Browser) │
│ Mobile (320px) ←────→ Tablet (768px) ←────→ Desktop (1920px) │
└───────────────────────────────┬──────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────┐
│ V5 REACT WRAPPER LAYER (Custom Code) │
│ ────────────────────────────────────────────────────────────── │
│ Components: │
│ • header.tsx - Navigation, auth, theme (Chakra UI) │
│ • footer.tsx - Copyright, links (Chakra UI) │
│ • layout.tsx - Tab modality router │
│ • touch-friendly-card.tsx - Mobile-first accordion (56px) │
│ │
│ Stores (Zustand): │
│ • auth-store.ts - JWT, user profile │
│ • session-store.ts - Active sessions │
│ │
│ Services: │
│ • theia-container.ts - Inversify DI bridge (NEW) │
│ • session-service.ts - V5 backend CRUD │
│ • user-service.ts - Profile, password │
│ • file-service.ts - File operations │
└───────────────────────────────┬──────────────────────────────────┘

↓ React-theia Bridge
┌──────────────────────────────────────────────────────────────────┐
│ THEIA WIDGET WRAPPERS (Thin React Components) │
│ ────────────────────────────────────────────────────────────── │
│ src/components/theia/: │
│ • theia-chat-widget.tsx - Wraps ChatViewWidget (~50 lines) │
│ • theia-terminal-widget.tsx - Wraps terminalWidget (~50 lines) │
│ • theia-monaco-widget.tsx - Wraps Monacoeditor (~50 lines) │
│ • theia-file-explorer-widget.tsx - Wraps FileTreeWidget (~50) │
│ │
│ Pattern: │
│ 1. Get widget from theia DI container │
│ 2. Mount widget.node into React ref │
│ 3. Handle lifecycle (mount/unmount) │
│ 4. Bridge events (theia ↔ React) │
└───────────────────────────────┬──────────────────────────────────┘

↓ Inversify DI
┌──────────────────────────────────────────────────────────────────┐
│ ECLIPSE THEIA 1.65 (Core Platform) │
│ ────────────────────────────────────────────────────────────── │
│ AI System (@theia/ai-*): │
│ • @theia/ai-chat-ui - ChatViewWidget, ChatInputWidget │
│ • @theia/ai-chat - ChatService, ChatSession, agents │
│ • @theia/ai-core - Agent system, tool calling, prompts │
│ • @theia/ai-mcp - Model Context Protocol integration │
│ • @theia/ai-openai - OpenAI-compatible API (LM Studio!) │
│ • @theia/ai-ollama - Local llm support │
│ • @theia/ai-code-completion - AI IntelliSense │
│ • @theia/ai-history - Conversation persistence │
│ │
│ IDE Components: │
│ • @theia/monaco - Monaco editor (VS Code editor) │
│ • @theia/terminal - xterm.js terminal widget │
│ • @theia/navigator - File tree widget │
│ • @theia/editor - editor management │
│ • @theia/workspace - Multi-folder workspaces │
│ • @theia/git - Git integration │
│ • @theia/debug - Debugging support │
│ • @theia/search-in-workspace - Search & replace │
└───────────────────────────────┬──────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────┐
│ V5 BACKEND (Rust + FoundationDB) │
│ ────────────────────────────────────────────────────────────── │
│ REST API (Actix-web): │
│ • POST /v5/auth/login - JWT authentication │
│ • POST /v5/auth/register - User registration │
│ • GET /v5/sessions - List user sessions │
│ • POST /v5/sessions/create - Create new session │
│ • PUT /v5/users/profile - Update profile │
│ • POST /v5/users/change-password - Password change │
│ • POST /v5/files/list - File tree │
│ • POST /v5/files/read - Read file │
│ • POST /v5/files/update - Write file │
│ │
│ FoundationDB Schema: │
│ • tenant_id/user/{user_id} - User data │
│ • tenant_id/session/{session_id} - Session metadata │
│ • tenant_id/session/{session_id}/files/{path} - Files │
│ • tenant_id/session/{session_id}/chat/{msg_id} - Chat history │
└───────────────────────────────┬──────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────┐
│ LM STUDIO (Local llm Inference) │
│ ────────────────────────────────────────────────────────────── │
│ OpenAI-compatible API: http://localhost:1234/v1 │
│ │
│ Models (16+ available): │
│ • meta-llama-3.3-70b-instruct - Code generation │
│ • qwen/qwq-32b - Reasoning, planning │
│ • deepseek-coder-v2 - Code review, refactoring │
│ • mistral-nemo - Fast responses │
│ • ... 12 more models ... │
│ │
│ MCP Server (Node.js): mcp-lmstudio/index.js │
│ Tools: │
│ • lmstudio_list_models - Get available models │
│ • lmstudio_chat - Chat completion │
│ • lmstudio_completion - Text completion │
└──────────────────────────────────────────────────────────────────┘

🎨 Three Tab Modalities (Definitive Implementation)

1. AI Studio Tab (Loveable-Style)

Target User: Novice - New to coding, wants AI to do heavy lifting

layout: Split-screen (Chat | Live Preview)

Technology:

// src/components/ai-studio/ai-studio-tab.tsx
import { theiaChatWidget } from '../theia/theiaChatWidget' // THEIA
import { CodePreview } from './CodePreview' // CUSTOM

export const ai-studioTab = ({ tabId }) => (
<SplitPane split="vertical">
{/* LEFT: theia's AI chat */}
<Panel minSize="40%" defaultSize="50%">
<theiaChatWidget
sessionId={tabId}
agents={['v5-code-generator', 'v5-ui-designer']}
showHistory={true}
/>
</Panel>

{/* RIGHT: Custom live preview */}
<Panel minSize="40%">
<CodePreview
sessionId={tabId}
mode="live-reload"
sandbox="iframe"
/>
</Panel>
</SplitPane>
)

What's theia: ChatViewWidget (complete AI chat UI) What's Custom: CodePreview (live sandbox)

Features:

  • ✅ AI chat with 16+ LM Studio models (theia)
  • ✅ Agent switching (Code Generator, UI Designer) (theia)
  • ✅ Context attachment (files, code) (theia)
  • ✅ MCP tool calls (theia)
  • ✅ Live code preview (Custom)
  • ✅ Mobile-responsive (Custom wrapper)

2. workspace Tab (VS Code-Style)

Target User: Power User - Experienced developer, wants full control

layout: Explorer | editor | terminal (3-panel)

Technology:

// src/components/workspace/workspace-tab.tsx
import { theiafile-explorerWidget } from '../theia/theiafile-explorerWidget' // THEIA
import { theiaMonacoWidget } from '../theia/theiaMonacoWidget' // THEIA
import { theiaterminalWidget } from '../theia/theiaterminalWidget' // THEIA

export const workspaceTab = ({ tabId }) => {
const [isExplorerOpen, setIsExplorerOpen] = useState(true)
const [isterminalOpen, setIsterminalOpen] = useState(true)

return (
<Flex direction="column" h="100%">
{/* TOP: Custom tab bar (mobile-first) */}
<HStack h="56px" bg="gray.800">
<IconButton onClick={() => setIsExplorerOpen(!isExplorerOpen)} />
{openFiles.map(file => <Tab key={file.path}>{file.name}</Tab>)}
<IconButton onClick={() => setIsterminalOpen(!isterminalOpen)} />
</HStack>

{/* MIDDLE: Main area */}
<Flex flex={1}>
{/* LEFT: theia File Explorer */}
{isExplorerOpen && (
<Box w="280px">
<theiafile-explorerWidget sessionId={tabId} />
</Box>
)}

{/* CENTER: theia Monaco editor */}
<Box flex={1}>
<theiaMonacoWidget
sessionId={tabId}
file={activeFile}
language={activeFile?.language}
/>
</Box>
</Flex>

{/* BOTTOM: theia terminal */}
{isterminalOpen && (
<Box h="200px">
<theiaterminalWidget sessionId={tabId} />
</Box>
)}
</Flex>
)
}

What's theia: File explorer, Monaco editor, terminal (100%) What's Custom: Tab bar, layout toggles, mobile wrappers

Features:

  • ✅ File tree with drag-drop (theia)
  • ✅ Monaco editor with IntelliSense (theia)
  • ✅ Integrated terminal (theia)
  • ✅ Multi-file tabs (Custom)
  • ✅ Touch-friendly controls (Custom)
  • ✅ Responsive layout (Custom)

3. theia IDE Tab (Full theia)

Target User: Expert - Professional developer, wants full IDE

layout: Full theia iframe (100% native)

Technology:

// src/components/theia-embed.tsx
export const theiaEmbed = ({ sessionId }) => {
const theiaUrl = `http://localhost:3000?sessionId=${sessionId}`

return (
<iframe
src={theiaUrl}
style={{ width: '100%', height: '100%', border: 'none' }}
sandbox="allow-same-origin allow-scripts allow-forms"
title="theia IDE"
/>
)
}

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

Features:

  • ✅ Full theia IDE experience (theia)
  • ✅ All theia extensions (theia)
  • ✅ VS Code extension compatibility (theia)
  • ✅ Debugging, Git, Search, etc. (theia)
  • ✅ Session isolation (Custom routing)

🔌 React-theia Bridge (The Key Integration)

The Challenge

theia: Uses Inversify DI container React: Uses props, hooks, context

We need to bridge these two worlds.

The Solution

Bridge Service:

// src/services/theia-container.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'
import { FileTreeWidget } from '@theia/navigator/lib/browser/navigator-widget'

/**
* theia DI Container Service.
*
* Bridges theia's Inversify DI container with React components.
* Provides type-safe access to theia widgets.
*/
class theiaContainerService {
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 widget from container (with caching).
*/
getWidget<T>(identifier: symbol | any, sessionId?: string): T {
if (!this.container) {
throw new Error('theia container not initialized')
}

const cacheKey = `${String(identifier)}-${sessionId || 'default'}`

if (!this.widgetCache.has(cacheKey)) {
const widget = this.container.get<T>(identifier)
this.widgetCache.set(cacheKey, widget)
}

return this.widgetCache.get(cacheKey)
}

/**
* Type-safe widget getters
*/
getChatWidget(sessionId: string): ChatViewWidget {
return this.getWidget<ChatViewWidget>(ChatViewWidget, sessionId)
}

getterminalWidget(sessionId: string): terminalWidget {
return this.getWidget<terminalWidget>(terminalWidget, sessionId)
}

getMonacoeditor(sessionId: string): Monacoeditor {
return this.getWidget<Monacoeditor>(Monacoeditor, sessionId)
}

getfile-explorer(sessionId: string): FileTreeWidget {
return this.getWidget<FileTreeWidget>(FileTreeWidget, sessionId)
}
}

export const theiaContainer = new theiaContainerService()

Wrapper Pattern:

// src/components/theia/theia-chat-widget.tsx
import React, { useRef, useEffect } from 'react'
import { Box } from '@chakra-ui/react'
import { theiaContainer } from '../../services/theia-container'

interface theiaChatWidgetProps {
sessionId: string
height?: string | number
agents?: string[]
showHistory?: boolean
}

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

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

// Get widget from theia DI
const widget = theiaContainer.getChatWidget(sessionId)

// Configure widget
if (agents) {
widget.setAvailableAgents(agents)
}
widget.setShowHistory(showHistory)

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

// Activate widget
widget.activate()

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

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

🗂️ File Structure (Definitive)

/workspace/PROJECTS/t2/
├── src/
│ ├── services/ # Service Layer
│ │ ├── theia-container.ts # ✅ NEW: theia DI bridge
│ │ ├── session-service.ts # ✅ KEEP: V5 backend CRUD
│ │ ├── user-service.ts # ✅ KEEP: Profile, password
│ │ └── file-service.ts # ✅ KEEP: File operations
│ │
│ ├── components/
│ │ ├── theia/ # ✅ NEW: theia widget wrappers
│ │ │ ├── theia-chat-widget.tsx
│ │ │ ├── theia-terminal-widget.tsx
│ │ │ ├── theia-monaco-widget.tsx
│ │ │ └── theia-file-explorer-widget.tsx
│ │ │
│ │ ├── ai-studio/ # AI Studio Tab
│ │ │ ├── ai-studio-tab.tsx # ✅ UPDATE: Use theiaChatWidget
│ │ │ └── CodePreview.tsx # ✅ KEEP: Custom component
│ │ │
│ │ ├── workspace/ # workspace Tab
│ │ │ └── workspace-tab.tsx # ✅ UPDATE: Use theia widgets
│ │ │
│ │ ├── touch-friendly-card.tsx # ✅ KEEP: Mobile-first wrapper
│ │ ├── header.tsx # ✅ KEEP: V5 branding
│ │ ├── footer.tsx # ✅ KEEP: V5 branding
│ │ ├── layout.tsx # ✅ UPDATE: Route to widgets
│ │ └── theia-embed.tsx # ✅ KEEP: Full theia iframe
│ │
│ ├── stores/ # Zustand State
│ │ ├── auth-store.ts # ✅ KEEP: JWT, user
│ │ └── session-store.ts # ✅ KEEP: Active sessions
│ │
│ ├── pages/ # Route Pages
│ │ ├── login-page.tsx
│ │ ├── register-page.tsx
│ │ ├── profile-page.tsx
│ │ ├── settings-page.tsx
│ │ └── (26 more doc pages)
│ │
│ ├── theme/ # Chakra UI Theme
│ │ ├── index.ts
│ │ └── mobile-first.ts
│ │
│ ├── app.tsx # ✅ UPDATE: Initialize theia container
│ └── main.tsx

├── .theia/ # ✅ NEW: theia configuration
│ ├── settings.json # LM Studio config
│ └── mcp-servers.json # MCP server registration

├── mcp-lmstudio/ # ✅ KEEP: MCP server
│ ├── index.js
│ └── package.json

├── docs/ # Documentation
│ ├── DEFINITIVE-V5-architecture.md # ✅ THIS FILE
│ ├── v5-frontend-build-strategy.md
│ ├── theia-ai-research-findings.md
│ ├── theia-component-reuse-strategy.md
│ ├── V5-THEIA-WRAPPER-architecture.md
│ └── mobile-first-design-system.md

├── package.json
├── tsconfig.json
└── vite.config.ts

⚙️ Configuration Files (Definitive)

1. theia LM Studio Configuration

File: .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",
"mistral-nemo",
"codellama-70b",
"mixtral-8x7b"
],
"ai.chat.defaultAgent": "v5-code-generator"
}

2. MCP Server Registration

File: .theia/mcp-servers.json

{
"servers": {
"lmstudio": {
"command": "node",
"args": ["${workspaceFolder}/mcp-lmstudio/index.js"],
"env": {
"LM_STUDIO_HOST": "localhost",
"LM_STUDIO_PORT": "1234"
}
}
}
}

3. Custom Agents

File: 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 => {
// Code Generator Agent
bind(Agent).toConstantValue({
id: 'v5-code-generator',
name: 'Code Generator',
description: 'Generates production-ready TypeScript code with mobile-first design',
model: 'meta-llama-3.3-70b-instruct',
prompt: `You are an expert TypeScript engineer.
Generate clean, well-documented, production-ready code.
Follow mobile-first design principles (56px touch targets).
Use Chakra UI for styling with TouchFriendlyCard components.
Write comprehensive tests for all code.
Use TypeScript strict mode with full type annotations.`,
tools: ['lmstudio_chat', 'file_read', 'file_write'],
})

// UI Designer Agent
bind(Agent).toConstantValue({
id: 'v5-ui-designer',
name: 'UI Designer',
description: 'Designs mobile-first UIs with Chakra UI and accessibility',
model: 'qwen/qwq-32b',
prompt: `You are a mobile-first UI/UX designer.
Create touch-friendly interfaces (56px minimum touch targets).
Use TouchFriendlyCard for all navigation (click to expand/collapse).
Follow WCAG 2.1 AAA accessibility standards.
Design for 320px to 4K displays (mobile-first responsive).
Use Chakra UI components with semantic colors.`,
tools: ['lmstudio_chat', 'file_read', 'file_write'],
})

// Code Reviewer Agent
bind(Agent).toConstantValue({
id: 'v5-code-reviewer',
name: 'Code Reviewer',
description: 'Reviews code for quality, security, performance, and accessibility',
model: 'deepseek-coder-v2',
prompt: `You are a senior code reviewer.
Check for security vulnerabilities (SQL injection, XSS, auth bypasses).
Suggest performance optimizations (memoization, lazy loading).
Enforce mobile-first patterns (touch targets, responsive design).
Verify accessibility compliance (ARIA labels, keyboard nav).
Ensure TypeScript type safety and test coverage.`,
tools: ['lmstudio_chat', 'file_read'],
})
})

🚀 Implementation Timeline (Definitive)

Week 1: Foundation (5 days)

Monday: theia-React Bridge

  • Create src/services/theia-container.ts
  • Initialize theia container in app.tsx
  • Test widget retrieval

Tuesday: Chat Widget Wrapper

  • Create theia-chat-widget.tsx
  • Test in isolation
  • Add mobile wrapper

Wednesday: AI Studio Integration

  • Update ai-studio-tab.tsx to use theiaChatWidget
  • Delete custom chat components
  • Test with LM Studio

Thursday: LM Studio Configuration

  • Create .theia/settings.json
  • Configure OpenAI-compatible API
  • Register MCP server
  • Test chat with all models

Friday: Custom Agents

  • Create custom-agents-module.ts
  • Define 3 agents
  • Test agent switching

Week 2: workspace Tab (5 days)

Monday: terminal & Monaco Wrappers

  • Create theia-terminal-widget.tsx
  • Create theia-monaco-widget.tsx
  • Test in isolation

Tuesday: File Explorer Wrapper

  • Create theia-file-explorer-widget.tsx
  • Test file operations

Wednesday: workspace Integration

  • Update workspace-tab.tsx
  • Wire all theia widgets
  • Delete custom components

Thursday: Mobile Optimization

  • Add TouchFriendlyCard wrappers
  • Test 320px viewport
  • Test 4K viewport

Friday: E2E Testing

  • Test all 3 tab modalities
  • Test session isolation
  • Test mobile responsive

✅ Success Criteria (Definitive)

Functional Requirements

  • AI Studio: Chat with 16+ LM Studio models
  • AI Studio: Switch between 3 agents
  • AI Studio: Attach files to context
  • AI Studio: MCP tool calls work
  • AI Studio: Live code preview
  • workspace: File explorer (open, create, delete)
  • workspace: Monaco editor (edit, save)
  • workspace: terminal (run commands)
  • theia IDE: Full iframe embed works
  • Auth: Login, register, password change
  • Sessions: Create, list, switch, delete
  • Mobile: Works on 320px viewport
  • Desktop: Works on 1920px viewport

Non-Functional Requirements

  • Load time: < 3 seconds
  • Chat response: < 2 seconds (LM Studio)
  • File operations: < 500ms
  • Mobile touch targets: ≥ 56px
  • Accessibility: WCAG 2.1 AAA
  • Type safety: 100% TypeScript coverage
  • Code quality: ESLint + Prettier

📊 Metrics (Definitive)

Code Metrics

MetricTargetActual
Custom Code< 2,500 linesTBD
theia Wrappers< 500 linesTBD
Type Coverage100%TBD
Test Coverage> 80%TBD

Performance Metrics

MetricTargetActual
Initial Load< 3sTBD
Chat Response< 2sTBD
File Open< 500msTBD
Session Switch< 1sTBD

UX Metrics

MetricTargetActual
Mobile Touch Targets≥ 56px
WCAG ComplianceAAATBD
Responsive Breakpoints5

🎯 The Value Proposition (Final)

What Makes V5 Unique?

NOT: Custom IDE built from scratch YES: Production-ready theia wrapped in mobile-first UX

FeatureStock theiaV5 (theia + Wrapper)
AI ChatBasic✅ 16+ local llms
Mobile SupportDesktop-only✅ Touch-friendly (320px to 4K)
Multi-TenancySingle workspace✅ Session isolation
Tab ModalitiesOne IDE✅ 3 modes (Novice to Expert)
NavigationMenu bars✅ Progressive disclosure cards
AuthNo built-in✅ JWT + V5 backend
PersistenceLocal files✅ FoundationDB + OPFS
llmsCloud APIs only✅ Local-first (privacy)
MCPBuilt-in✅ + Custom servers
Brandingtheia logo✅ Custom header/footer

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


🔌 Development Modes & workspace Connectivity

Decision Reference: ADR-025

V5 supports multiple development modes to accommodate different deployment scenarios and user needs. Each mode has different characteristics for terminal execution, file access, and git integration.

Mode 1: Container-Only (Production Default)

Overview: Complete isolation with all operations inside Docker container.

Characteristics:

  • ✅ terminal: Container OS (Debian from node:20-slim)
  • ✅ File System: Container file system
  • ✅ Git: Manual configuration required
  • ✅ Multi-tenant safe
  • ✅ Cloud-deployable (GKE/Kubernetes)

Use Cases:

  • Production SaaS deployment
  • Multi-tenant cloud IDE
  • CI/CD integration
  • Isolated development environments

Docker Command:

docker run -d \
-p 8080:80 \
--name coditect-prod \
coditect-combined:prod

terminal Access: Opens /bin/bash inside container with root user.

Git Setup (Manual):

docker exec -it coditect-prod bash
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# SSH keys must be added separately

Mode 2: Docker Volume Mounts (Local Development)

Overview: Hybrid approach - container runtime with host file system access.

Characteristics:

  • ✅ terminal: Container OS (Debian)
  • ✅ File System: Mounted from host (Windows/Mac/Linux)
  • ✅ Git: Uses host configuration and SSH keys
  • ✅ Persistent storage across container restarts
  • ⚠️ NOT multi-tenant safe
  • ❌ NOT for production

Use Cases:

  • Local development and testing
  • Customizing theia extensions
  • Debugging with local files
  • Training and education

Docker Command:

docker run -d \
-p 8080:80 \
-p 3001:3000 \
-v /home/user/projects:/workspace \
-v /home/user/.gitconfig:/root/.gitconfig:ro \
-v /home/user/.ssh:/root/.ssh:ro \
--name coditect-dev \
coditect-combined:test

terminal Access: Opens /bin/bash inside container with access to mounted files.

Git Integration: Automatically works with host SSH keys and git configuration.

Benefits:

  • Edit files on your local machine
  • Use your existing git setup
  • Fast file operations
  • Familiar development workflow

Considerations:

  • Line ending issues (Windows CRLF vs Linux LF)
  • File permission mapping (UID/GID)
  • Platform-specific Docker volume syntax

Mode 3: Remote SSH (Future - Not Yet Implemented)

Overview: terminal connects to remote machine via SSH, theia acts as thin client.

Characteristics:

  • ✅ terminal: Remote machine OS (any OS)
  • ✅ File System: Remote machine
  • ✅ Git: Native on remote machine
  • ✅ Full tool access on remote machine
  • ⚠️ Requires SSH server and authentication
  • 🔲 Requires theia SSH extension (not yet integrated)

Use Cases:

  • Remote development on powerful servers
  • Accessing production-like environments
  • Team development on shared infrastructure
  • WSL/Docker development from Windows

Planned Architecture:

User Browser
↓ HTTPS
theia (in Docker/Cloud)
↓ SSH
Remote Development Server
↓ Direct access
Files, Git, Tools, Databases

Implementation Status: 🔲 Planned for future release


Overview: Run theia directly on user's OS without Docker.

Characteristics:

  • ✅ terminal: Native OS shell
  • ✅ File System: Native
  • ✅ Git: Native system git
  • ✅ Perfect OS integration
  • ❌ Single-user only
  • ❌ NOT cloud-deployable
  • ❌ NOT multi-tenant safe

Use Cases:

  • Single-user local IDE
  • Offline development
  • Custom enterprise installations

Installation:

npm install -g @theia/cli
theia start /path/to/workspace

Why Not Recommended: Doesn't align with cloud-first architecture and multi-tenant requirements.


Comparison Matrix

FeatureContainer-OnlyVolume MountRemote SSHNative Desktop
Multi-tenant Safe✅ Yes❌ No⚠️ Depends❌ No
Local File Access❌ No✅ Yes✅ Yes✅ Yes
Git Integration⚠️ Manual✅ Host config✅ Native✅ Native
terminal OSDebianDebianRemote OSHost OS
Cloud Deployable✅ Yes❌ No✅ Yes❌ No
GKE/Kubernetes✅ Yes❌ No⚠️ Complex❌ No
Security Isolation✅ High⚠️ Medium⚠️ Medium❌ Low
Setup ComplexityLowMediumHighLow
Status✅ Ready✅ Ready🔲 Future⚠️ Available

Production SaaS (GKE):

  • Use: Container-Only Mode
  • Why: Multi-tenant security, cloud-native, scalable

Local Development:

  • Use: Volume Mount Mode
  • Why: Edit local files, use existing git setup, fast iteration

Enterprise On-Premise:

  • Use: Container-Only Mode
  • Why: Consistent environment, IT control, security

Remote Development:

  • Use: Remote SSH Mode (when available)
  • Why: Access powerful backends, team environments

Further Reading: See ADR-025 and docs/01-getting-started/development-modes.md for complete details.


🔒 Wrapper Persistence & Security

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

The Requirement

The Coditect V5 wrapper must always remain around theia to provide:

  • Navigation (Header with links to all endpoints)
  • Branding (Coditect AI logo and design)
  • Authentication (Login, profile, settings)
  • Session management (Multi-tab switching)
  • Documentation access (/docs, /support, /faq, etc.)

Problem: 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 V5 features.

The Solution: Three-Layer Protection

Layer 1: React Router Architecture

All routes go through <layout> component:

// src/app.tsx
<Routes>
{/* Root redirects to IDE */}
<Route path="/" element={isAuthenticated ? <Navigate to="/ide" /> : <Navigate to="/login" />} />

{/* IDE routes with wrapper */}
<Route path="/ide" element={<layout showIDE tabModality="theia" />} />
<Route path="/workspace" element={<layout showIDE tabModality="workspace" />} />
<Route path="/ai-studio" element={<layout showIDE tabModality="ai-studio" />} />

{/* Page routes with wrapper */}
<Route path="/docs" element={<layout showIDE={false}><DocumentationPage /></layout>} />
<Route path="/settings" element={<layout showIDE={false}><SettingsPage /></layout>} />
</Routes>

Effect: Every route renders Header and Footer, ensuring wrapper presence.

Layer 2: Iframe Sandbox Protection

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 theia from navigating parent window
/>

Security Properties:

  • allow-same-origin - Enables postMessage (theme sync)
  • allow-scripts - theia needs JavaScript
  • allow-forms - theia forms and inputs
  • allow-modals - theia dialogs
  • allow-popups - File downloads
  • allow-downloads - Save files
  • NOT included: allow-top-navigation - Prevents breakout

Effect: theia cannot navigate the parent window or break out of the iframe.

Layer 3: NGINX Redirect Protection (Production)

Prevents direct /theia access:

# nginx-combined.conf

# SECURITY: Redirect direct /theia access to wrapper
location = /theia {
return 301 /ide; # Force users through wrapper
}

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

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

Architecture Flow

User accesses http://coditect.ai/ide

NGINX serves V5 React SPA (/)

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

layout renders:
┌─────────────────────────────────┐
│ Header (56px) │
│ - Logo, Nav, Theme, User Menu │
├─────────────────────────────────┤
│ theiaEmbed (iframe) │
│ - theia IDE at :3000 │
│ - Sandbox: NO top-navigation │
├─────────────────────────────────┤
│ Footer (40px) │
│ - Copyright, Links │
└─────────────────────────────────┘

User interacts with theia inside iframe

Header/Footer remain visible ✅
Navigation available via Header ✅

What Happens When User Tries to Bypass Wrapper?

Scenario 1: Direct /theia Access (Production)

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

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

HTTP 301 Redirect

Browser navigates to: http://coditect.ai/ide

V5 wrapper loads with Header/Footer ✅

Scenario 2: Direct :3000 Access (Development)

Developer tries: http://localhost:3000

⚠️ Development mode allows direct access

theia loads without wrapper (no Header/Footer)

❌ This is OK for debugging but NOT recommended

Recommendation: Always use http://localhost:5173/ide (wrapper) in development.

Benefits of Wrapper Persistence

FeatureWith WrapperWithout Wrapper
Navigation✅ Header with links❌ No navigation UI
Branding✅ Coditect logo❌ theia logo
Documentation✅ /docs link available❌ Can't access docs
Settings✅ /settings link available❌ Can't access settings
Session Switching✅ Multi-tab UI❌ No session management
Authentication✅ Login/logout❌ No auth UI
Theme✅ V5 custom theme❌ theia default theme
Mobile-Friendly✅ Touch-friendly header❌ Desktop-only

Configuration Files

1. NGINX Configuration (nginx-combined.conf):

# V5 Frontend at root
location / {
root /app/v5-frontend;
try_files $uri /index.html;
}

# Security: Redirect direct /theia to /ide
location = /theia {
return 301 /ide;
}

# theia API/WebSocket (for iframe)
location /theia/ {
proxy_pass http://localhost:3000;
# WebSocket support...
}

2. layout Component (src/components/layout.tsx):

export const layout: React.FC<layoutProps> = ({
sessionId,
theiaUrl = 'http://localhost:3000',
children,
showIDE = false,
tabModality = 'theia',
}) => {
return (
<Flex direction="column" h="100vh" w="100vw">
<Header /> {/* ✅ Always visible */}

<Flex flex={1}>
{showSidePanel && <SidePanel />}
{renderMainContent()} {/* theia iframe or page content */}
</Flex>

<Footer /> {/* ✅ Always visible */}
</Flex>
)
}

3. Iframe Embed (src/components/theia-embed.tsx):

<Box
as="iframe"
src={sessionId ? `${theiaUrl}?sessionId=${sessionId}` : theiaUrl}
w="100%"
h="100%"
border="none"
sandbox="allow-same-origin allow-scripts allow-forms allow-modals allow-popups allow-downloads"
// ❌ NO allow-top-navigation (security)
/>

Testing

1. Test NGINX Redirect (Production):

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

2. Test Wrapper Presence (Browser):

// In browser console at /ide
document.querySelector('header') // Should exist
document.querySelector('footer') // Should exist
document.querySelector('iframe[title="theia IDE"]') // Should exist

3. Test Iframe Sandbox (Browser DevTools):

// Inside theia iframe console:
try {
window.top.location = 'http://evil.com'
} catch (e) {
console.error('Blocked by sandbox:', e)
// SecurityError: Blocked a frame with origin from accessing a cross-origin frame
}

Result: ✅ theia cannot navigate parent window (security confirmed).

Monitoring

Metrics to Track:

  • nginx_redirect_count{path="/theia"} - Users trying to bypass wrapper
  • theia_iframe_load_duration_ms - Iframe performance
  • v5_header_click_count - Header navigation engagement

Alert: If redirect count > 100/day, users need education about proper access.

Documentation for Users

✅ Correct Access:

https://coditect.ai/ide
https://coditect.ai/workspace
https://coditect.ai/ai-studio

❌ Incorrect Access (will redirect):

https://coditect.ai/theia  → Redirects to /ide

💡 Why the wrapper matters:

  • Access documentation and help
  • Switch between sessions
  • Change settings and profile
  • Professional Coditect branding
  • Mobile-friendly navigation

Further Reading: See ADR-026 and docs/02-architecture/wrapper-persistence-flow.md for complete technical details and visual diagrams.


📚 Documentation Index (Complete)

  1. DEFINITIVE-V5-architecture.md (this file) - Complete system overview
  2. v5-frontend-build-strategy.md - Implementation plan
  3. theia-ai-research-findings.md - theia capabilities
  4. theia-component-reuse-strategy.md - Why wrap, not rebuild
  5. V5-THEIA-WRAPPER-architecture.md - How to wrap widgets
  6. mobile-first-design-system.md - Touch-friendly patterns
  7. build-completion-summary.md - Phase 1 status

Total Documentation: ~50,000 words


✅ Final Statement (No Ambiguity)

V5 Architecture:

  • 95% Eclipse theia (AI, editor, terminal, file explorer)
  • 5% Custom React Wrapper (mobile-first UI, multi-tenancy, branding)

Technology Stack:

  • Frontend: React 18 + TypeScript 5.3 + Chakra UI 2.8
  • IDE: Eclipse theia 1.65.0 (complete AI platform)
  • State: Zustand 4.4 (persisted to localStorage)
  • Backend: Rust + Actix-web + FoundationDB
  • llms: LM Studio (16+ local models, OpenAI-compatible)
  • Protocol: MCP (Anthropic standard)

Implementation:

  1. Create theia DI bridge (theia-container.ts)
  2. Wrap 4 theia widgets (Chat, terminal, Monaco, file-explorer)
  3. Integrate into 3 tab modalities (AI Studio, workspace, theia IDE)
  4. Configure LM Studio as OpenAI provider
  5. Register custom agents (Code Generator, UI Designer, Code Reviewer)

Timeline: 2 weeks (vs 4+ weeks custom build)

Result: Production-ready, mobile-first AI IDE with minimal custom code


Status: ✅ DEFINITIVE ARCHITECTURE - ZERO AMBIGUITY - READY TO BUILD

Version: 5.0.0 Final Date: 2025-10-08 Author: V5 Development Team