Skip to main content

V4/theia Frontend Integration Plan

Date: 2025-10-06 Goal: Wrap theia IDE with V4 frontend components (Header, Footer, layout) and integrate pre-theia work


🎯 Architecture Overview

Current State

V4 Frontend (src/frontend-original/):

  • ✅ Complete React app with Chakra UI
  • ✅ Header with auth, theme toggle, user menu
  • ✅ Footer with links and branding
  • ✅ 50+ documentation pages
  • ✅ Login/Register pages
  • ✅ Admin dashboard
  • ✅ workspace management UI

theia IDE (src/browser/):

  • ✅ Eclipse theia framework
  • ✅ llm integration extension (partially complete)
  • ✅ Monaco editor, xterm.js terminal
  • ✅ File explorer (built-in)

Pre-theia Components (need to map):

  • React prototype with 4 llm workflow modes
  • File explorer UI
  • llm chat panel
  • Model selector

Target Architecture

┌─────────────────────────────────────────────────────────┐
│ V4 Header (React/Chakra) │
│ Logo | Nav | Theme Toggle | User Menu (Auth) │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ Main Content Area (Flexbox) │
│ ┌─────────────────────┬─────────────────────────────┐ │
│ │ V4 Sidebar (React) │ theia IDE (iframe/embed) │ │
│ │ - Sessions │ - Monaco editor │ │
│ │ - Projects │ - File Explorer │ │
│ │ - Models │ - terminal │ │
│ │ - llm Chat Panel │ - Extensions │ │
│ └─────────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ V4 Footer (React/Chakra) │
│ Links | Docs | Support | © Coditect │
└─────────────────────────────────────────────────────────┘

📦 Component Mapping

V4 Components to Reuse

ComponentLocationPurpose in V5
header.tsxfrontend-original/src/components/Top nav with auth, theme, user menu
footer.tsxfrontend-original/src/components/Bottom links, branding
layout.tsxfrontend-original/src/components/Wrapper layout for all pages
login-page.tsxfrontend-original/src/pages/User login (integrate with auth-service)
register-page.tsxfrontend-original/src/pages/User registration
profile-page.tsxfrontend-original/src/pages/User profile management
settings-page.tsxfrontend-original/src/pages/IDE/user settings
documentation-page.tsxfrontend-original/src/pages/Docs landing page
workspace-page.tsxfrontend-original/src/pages/workspace selector/manager
coditect-workspace.tsxfrontend-original/src/pages/Main workspace container

Pre-theia Components to Integrate

ComponentCurrent LocationIntegration Strategy
llm Chat PanelPhase 2 React prototype→ theia sidebar widget
Workflow Mode SelectorPhase 2 React prototype→ theia toolbar contribution
Model SelectorPhase 2 React prototype→ theia statusbar item
File Explorer (custom)Phase 2 React prototype❌ Use theia's built-in explorer instead
Monaco editor (custom)Phase 2 React prototype❌ Use theia's built-in editor instead

theia Components (Built-in)

ComponentSourceNotes
File Explorer@theia/navigatorUse as-is, already better than custom
Monaco editor@theia/monacoUse as-is, feature-complete
terminal@theia/terminalUse as-is, xterm.js integration
Search@theia/search-in-workspaceBuilt-in full-text search
SCM@theia/scmGit integration

🏗️ Implementation Strategy

Phase 1: Wrapper Foundation (Week 1)

Goal: Embed theia inside V4 layout

  1. Create theia Embed Component:

    // src/components/theia-embed.tsx
    import React, { useEffect, useRef } from 'react';
    import { Box } from '@chakra-ui/react';

    interface theiaEmbedProps {
    sessionId: string;
    userId: string;
    }

    export const theiaEmbed: React.FC<theiaEmbedProps> = ({ sessionId, userId }) => {
    const iframeRef = useRef<HTMLIFrameElement>(null);

    useEffect(() => {
    // Initialize theia iframe communication
    if (iframeRef.current) {
    const theiaUrl = `${import.meta.env.VITE_THEIA_URL}?session=${sessionId}&user=${userId}`;
    iframeRef.current.src = theiaUrl;
    }
    }, [sessionId, userId]);

    return (
    <Box
    as="iframe"
    ref={iframeRef}
    w="100%"
    h="100%"
    border="none"
    bg="transparent"
    title="theia IDE"
    />
    );
    };
  2. Update V4 layout for theia:

    // src/components/layout.tsx (modified from V4)
    import React from 'react';
    import { Box, Flex } from '@chakra-ui/react';
    import { Header } from './Header';
    import { Footer } from './Footer';
    import { theiaEmbed } from './theiaEmbed';
    import { SidePanel } from './SidePanel';
    import { useAuthStore } from '../stores/authStore';

    interface layoutProps {
    children?: React.ReactNode;
    showIDE?: boolean;
    }

    export const layout: React.FC<layoutProps> = ({ children, showIDE = false }) => {
    const { user, sessionId } = useAuthStore();

    return (
    <Flex direction="column" minH="100vh">
    <Header />

    <Flex flex={1} overflow="hidden">
    {showIDE ? (
    <>
    <SidePanel user={user} />
    <Box flex={1} position="relative">
    <theiaEmbed
    sessionId={sessionId}
    userId={user?.id}
    />
    </Box>
    </>
    ) : (
    <Box flex={1} overflow="auto">
    {children}
    </Box>
    )}
    </Flex>

    <Footer />
    </Flex>
    );
    };
  3. Create SidePanel Component:

    // src/components/side-panel.tsx
    import React from 'react';
    import { Box, VStack, Button, Text, useColorModeValue } from '@chakra-ui/react';
    import { FiFolder, FiMessageSquare, FiCpu, FiBox } from 'react-icons/fi';

    export const SidePanel: React.FC<{ user: any }> = ({ user }) => {
    const bgColor = useColorModeValue('gray.50', 'gray.900');
    const borderColor = useColorModeValue('gray.200', 'gray.700');

    return (
    <Box
    w="250px"
    bg={bgColor}
    borderRight="1px"
    borderColor={borderColor}
    p={4}
    overflow="auto"
    >
    <VStack spacing={4} align="stretch">
    <Box>
    <Text fontSize="xs" fontWeight="bold" mb={2} textTransform="uppercase">
    workspace
    </Text>
    <Button leftIcon={<FiFolder />} variant="ghost" size="sm" justifyContent="flex-start">
    My Projects
    </Button>
    <Button leftIcon={<FiBox />} variant="ghost" size="sm" justifyContent="flex-start">
    Sessions
    </Button>
    </Box>

    <Box>
    <Text fontSize="xs" fontWeight="bold" mb={2} textTransform="uppercase">
    AI Tools
    </Text>
    <Button leftIcon={<FiMessageSquare />} variant="ghost" size="sm" justifyContent="flex-start">
    llm Chat
    </Button>
    <Button leftIcon={<FiCpu />} variant="ghost" size="sm" justifyContent="flex-start">
    Model Selector
    </Button>
    </Box>
    </VStack>
    </Box>
    );
    };
  4. Update App Routes:

    // src/app.tsx (modified from V4)
    import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
    import { ChakraProvider } from '@chakra-ui/react';
    import { layout } from './components/layout';
    import { LoginPage } from './pages/LoginPage';
    import { RegisterPage } from './pages/RegisterPage';
    import { workspacePage } from './pages/workspacePage';
    import { DocumentationPage } from './pages/DocumentationPage';
    import { useAuthStore } from './stores/authStore';
    import theme from './theme';

    function App() {
    const { isAuthenticated } = useAuthStore();

    return (
    <ChakraProvider theme={theme}>
    <BrowserRouter>
    <Routes>
    {/* Public routes */}
    <Route path="/login" element={<LoginPage />} />
    <Route path="/register" element={<RegisterPage />} />
    <Route path="/docs/*" element={<layout><DocumentationPage /></layout>} />

    {/* Protected routes */}
    <Route
    path="/workspace"
    element={
    isAuthenticated ? (
    <layout showIDE={true} />
    ) : (
    <Navigate to="/login" />
    )
    }
    />

    <Route
    path="/projects"
    element={
    isAuthenticated ? (
    <layout><workspacePage /></layout>
    ) : (
    <Navigate to="/login" />
    )
    }
    />

    <Route path="/" element={<Navigate to="/workspace" />} />
    </Routes>
    </BrowserRouter>
    </ChakraProvider>
    );
    }

Deliverables:

  • theiaEmbed component created
  • V4 layout modified for theia
  • SidePanel component created
  • App routes updated
  • theia loads inside V4 wrapper

Phase 2: Theme Unification (Week 1-2)

Goal: Make theia match V4 Chakra UI theme

  1. Extract V4 Theme:

    // src/theme.ts (from V4)
    import { extendTheme } from '@chakra-ui/react';

    const theme = extendTheme({
    config: {
    initialColorMode: 'dark',
    useSystemColorMode: false,
    },
    colors: {
    brand: {
    50: '#e6f7ff',
    100: '#bae7ff',
    200: '#91d5ff',
    300: '#69c0ff',
    400: '#40a9ff',
    500: '#1890ff', // Primary
    600: '#096dd9',
    700: '#0050b3',
    800: '#003a8c',
    900: '#002766',
    },
    },
    styles: {
    global: (props: any) => ({
    body: {
    bg: props.colorMode === 'dark' ? 'gray.900' : 'white',
    color: props.colorMode === 'dark' ? 'white' : 'gray.800',
    },
    }),
    },
    });

    export default theme;
  2. Create theia Theme CSS:

    /* public/theia-theme.css */
    :root {
    /* Match Chakra UI colors */
    --theia-ui-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
    --theia-brand-primary: #1890ff;
    --theia-brand-secondary: #096dd9;
    }

    /* Dark mode (default) */
    [data-theme='dark'] {
    --theia-editor-background: #1a202c; /* gray.900 */
    --theia-editor-foreground: #ffffff;
    --theia-sideBar-background: #171923; /* gray.950 */
    --theia-statusBar-background: #0f1419;
    --theia-activityBar-background: #0f1419;
    --theia-menu-background: #2d3748; /* gray.700 */
    --theia-input-background: #2d3748;
    }

    /* Light mode */
    [data-theme='light'] {
    --theia-editor-background: #ffffff;
    --theia-editor-foreground: #1a202c; /* gray.900 */
    --theia-sideBar-background: #f7fafc; /* gray.50 */
    --theia-statusBar-background: #edf2f7;
    --theia-activityBar-background: #edf2f7;
    --theia-menu-background: #ffffff;
    --theia-input-background: #ffffff;
    }
  3. Sync Theme Between V4 and theia:

    // src/hooks/use-theia-theme.ts
    import { useEffect } from 'react';
    import { useColorMode } from '@chakra-ui/react';

    export const usetheiaTheme = () => {
    const { colorMode } = useColorMode();

    useEffect(() => {
    // Send theme to theia iframe
    const theiaIframe = document.querySelector('iframe[title="theia IDE"]') as HTMLIFrameElement;
    if (theiaIframe?.contentWindow) {
    theiaIframe.contentWindow.postMessage(
    { type: 'SET_THEME', theme: colorMode },
    '*'
    );
    }

    // Also set CSS data attribute for theia CSS
    document.documentElement.setAttribute('data-theme', colorMode);
    }, [colorMode]);
    };
  4. theia Theme Receiver (in theia extension):

    // src/browser/theme-sync-contribution.ts
    import { injectable, postConstruct } from '@theia/core/shared/inversify';
    import { CommandContribution, CommandRegistry } from '@theia/core';
    import { ColorTheme } from '@theia/core/lib/common/theme';

    @injectable()
    export class ThemeSyncContribution implements CommandContribution {
    @postConstruct()
    protected init(): void {
    // Listen for theme changes from parent window
    window.addEventListener('message', (event) => {
    if (event.data.type === 'SET_THEME') {
    const theme = event.data.theme === 'dark' ? 'dark' : 'light';
    this.settheiaTheme(theme);
    }
    });
    }

    private settheiaTheme(theme: string): void {
    // Apply theia theme
    document.body.classList.remove('theia-light', 'theia-dark');
    document.body.classList.add(`theia-${theme}`);
    }

    registerCommands(commands: CommandRegistry): void {
    // No commands needed
    }
    }

Deliverables:

  • V4 Chakra theme extracted
  • theia CSS theme created
  • Theme sync hook implemented
  • theia visually matches V4 wrapper

Phase 3: Component Integration (Week 2)

Goal: Integrate pre-theia llm components

  1. Port llm Chat Panel to theia Widget:

    // src/browser/llm-chat-panel/llm-chat-panel-widget.tsx
    import * as React from 'react';
    import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
    import { injectable, inject } from '@theia/core/shared/inversify';
    import { llmService } from '../../services/llm-service';
    import { ChakraProvider, VStack, Input, Button, Box, Text } from '@chakra-ui/react';
    import theme from '../../theme'; // Reuse V4 theme

    @injectable()
    export class llmChatPanelWidget extends ReactWidget {
    static readonly ID = 'llm-chat-panel';
    static readonly LABEL = 'llm Chat';

    @inject(llmService) llmService!: llmService;

    constructor() {
    super();
    this.id = llmChatPanelWidget.ID;
    this.title.label = llmChatPanelWidget.LABEL;
    this.title.closable = true;
    this.title.iconClass = 'fa fa-comments';
    }

    protected render(): React.ReactNode {
    return (
    <ChakraProvider theme={theme}>
    <VStack spacing={4} p={4} h="100%" align="stretch">
    <Box flex={1} overflow="auto">
    {/* Chat messages */}
    <Text>Chat history...</Text>
    </Box>
    <Input placeholder="Type a message..." />
    <Button colorScheme="brand">Send</Button>
    </VStack>
    </ChakraProvider>
    );
    }
    }
  2. Port Model Selector to Statusbar:

    // src/browser/model-selector/model-selector-contribution.ts
    import { injectable, inject } from '@theia/core/shared/inversify';
    import { StatusBar, StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
    import { FrontendApplicationContribution } from '@theia/core/lib/browser';
    import { llmService } from '../../services/llm-service';

    @injectable()
    export class ModelSelectorContribution implements FrontendApplicationContribution {
    @inject(StatusBar) statusBar!: StatusBar;
    @inject(llmService) llmService!: llmService;

    async onStart(): Promise<void> {
    const models = await this.llmService.listLMStudioModels();
    const selectedModel = models[0]?.id || 'No models';

    this.statusBar.setElement('model-selector', {
    text: `🤖 ${selectedModel}`,
    alignment: StatusBarAlignment.RIGHT,
    priority: 100,
    command: 'model-selector.select',
    tooltip: 'Click to select llm model'
    });
    }
    }
  3. Port Workflow Mode Selector to Toolbar:

    // src/browser/workflow-mode/workflow-mode-contribution.ts
    import { injectable } from '@theia/core/shared/inversify';
    import { CommandContribution, CommandRegistry, MenuContribution, MenuModelRegistry } from '@theia/core';
    import { CommonMenus } from '@theia/core/lib/browser';

    export const WorkflowModes = {
    SINGLE: 'single',
    PARALLEL: 'parallel',
    SEQUENTIAL: 'sequential',
    CONSENSUS: 'consensus'
    };

    @injectable()
    export class WorkflowModeContribution implements CommandContribution, MenuContribution {
    registerCommands(commands: CommandRegistry): void {
    commands.registerCommand({
    id: 'workflow-mode.single',
    label: 'Single Mode'
    }, {
    execute: () => this.setWorkflowMode('single')
    });

    commands.registerCommand({
    id: 'workflow-mode.parallel',
    label: 'Parallel Mode'
    }, {
    execute: () => this.setWorkflowMode('parallel')
    });

    // ... other modes
    }

    registerMenus(menus: MenuModelRegistry): void {
    menus.registerMenuAction(CommonMenus.VIEW, {
    commandId: 'workflow-mode.single',
    label: 'Workflow: Single',
    order: '0'
    });

    // ... other modes
    }

    private setWorkflowMode(mode: string): void {
    console.log('Workflow mode set to:', mode);
    // Trigger workflow change in llm service
    }
    }

Deliverables:

  • llm chat panel as theia widget
  • Model selector in theia statusbar
  • Workflow mode in theia toolbar
  • All components use Chakra theme

Phase 4: Authentication Integration (Week 2-3)

Goal: Connect V4 auth UI to theia backend

  1. Update V4 Auth Store (use FDBService):

    // src/stores/auth-store.ts (modified from V4)
    import create from 'zustand';
    import { persist } from 'zustand/middleware';

    interface User {
    id: string;
    tenantId: string;
    email: string;
    name: string;
    avatar?: string;
    }

    interface AuthState {
    user: User | null;
    token: string | null;
    sessionId: string | null;
    isAuthenticated: boolean;
    login: (email: string, password: string) => Promise<void>;
    register: (email: string, password: string, name: string) => Promise<void>;
    logout: () => void;
    }

    export const useAuthStore = create<AuthState>()(
    persist(
    (set) => ({
    user: null,
    token: null,
    sessionId: null,
    isAuthenticated: false,

    login: async (email, password) => {
    const response = await fetch('/api/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password })
    });

    const data = await response.json();

    set({
    user: data.user,
    token: data.token,
    sessionId: data.sessionId,
    isAuthenticated: true
    });
    },

    register: async (email, password, name) => {
    const response = await fetch('/api/auth/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password, name })
    });

    const data = await response.json();

    set({
    user: data.user,
    token: data.token,
    sessionId: data.sessionId,
    isAuthenticated: true
    });
    },

    logout: () => {
    set({
    user: null,
    token: null,
    sessionId: null,
    isAuthenticated: false
    });
    }
    }),
    { name: 'auth-storage' }
    )
    );
  2. Create Auth Backend Endpoint (Node.js/Express):

    // server/auth.ts
    import express from 'express';
    import { FDBService } from './services/fdb-service';
    import { PodProvisioningService } from './services/pod-provisioning-service';
    import * as argon2 from 'argon2';
    import * as jwt from 'jsonwebtoken';

    const router = express.Router();
    const fdb = new FDBService();
    const podService = new PodProvisioningService();

    router.post('/register', async (req, res) => {
    const { email, password, name } = req.body;

    const userId = `usr-${Date.now()}`;
    const tenantId = `tenant-${Date.now()}`;
    const passwordHash = await argon2.hash(password);

    const user = {
    userId,
    tenantId,
    email,
    name,
    passwordHash,
    createdAt: new Date().toISOString()
    };

    // Store user in FDB
    await fdb.set(`${tenantId}/user/${userId}`, user);

    // Auto-provision pod
    const pod = await podService.createUserPod(userId, tenantId);

    // Create session
    const sessionId = `ses-${Date.now()}`;
    await fdb.set(`${tenantId}/session/${sessionId}`, {
    sessionId,
    userId,
    tenantId,
    podNamespace: pod.namespace,
    createdAt: new Date().toISOString()
    });

    // Generate JWT
    const token = jwt.sign({ userId, tenantId }, process.env.JWT_SECRET || 'dev-secret', {
    expiresIn: '7d'
    });

    res.json({
    user: { id: userId, tenantId, email, name },
    token,
    sessionId
    });
    });

    router.post('/login', async (req, res) => {
    const { email, password } = req.body;

    // Find user by email (scan all tenants)
    const users = await fdb.scan('*/user/*');
    const user = users.find(u => u.email === email);

    if (!user) {
    return res.status(401).json({ error: 'User not found' });
    }

    const valid = await argon2.verify(user.passwordHash, password);
    if (!valid) {
    return res.status(401).json({ error: 'Invalid password' });
    }

    // Create session
    const sessionId = `ses-${Date.now()}`;
    const pod = await fdb.get(`${user.tenantId}/pod/${user.userId}`);

    await fdb.set(`${user.tenantId}/session/${sessionId}`, {
    sessionId,
    userId: user.userId,
    tenantId: user.tenantId,
    podNamespace: pod?.namespace,
    createdAt: new Date().toISOString()
    });

    // Generate JWT
    const token = jwt.sign(
    { userId: user.userId, tenantId: user.tenantId },
    process.env.JWT_SECRET || 'dev-secret',
    { expiresIn: '7d' }
    );

    res.json({
    user: { id: user.userId, tenantId: user.tenantId, email: user.email, name: user.name },
    token,
    sessionId
    });
    });

    export default router;

Deliverables:

  • Auth store updated for FDB backend
  • Auth backend endpoints created
  • Login/Register pages working
  • Pod auto-provisioning on register

Phase 5: Docker Persistence (Week 3)

Goal: Persist gcloud SDK and other tools in Docker image

  1. Update Debian Dockerfile:

    # Dockerfile (update existing)
    FROM debian:13-slim

    # Install base dependencies
    RUN apt-get update && apt-get install -y \
    curl wget git vim build-essential \
    python3 python3-pip nodejs npm \
    && rm -rf /var/lib/apt/lists/*

    # Install Google Cloud SDK
    RUN curl https://sdk.cloud.google.com | bash -s -- \
    --disable-prompts \
    --install-dir=/opt/google-cloud-sdk

    # Add gcloud to PATH
    ENV PATH="/opt/google-cloud-sdk/google-cloud-sdk/bin:${PATH}"

    # Install kubectl
    RUN gcloud components install kubectl --quiet

    # Install Rust (for CODI2 builds)
    RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
    ENV PATH="/root/.cargo/bin:${PATH}"

    # Install FoundationDB client
    RUN wget https://github.com/apple/foundationdb/releases/download/7.1.61/foundationdb-clients_7.1.61-1_amd64.deb && \
    dpkg -i foundationdb-clients_7.1.61-1_amd64.deb && \
    rm foundationdb-clients_7.1.61-1_amd64.deb

    # Copy project files
    WORKDIR /workspace
    COPY . .

    # Install Node.js dependencies
    RUN npm install

    # Build theia
    RUN npm run theia:build

    # Expose ports
    EXPOSE 3000 5173 8080

    # Default command
    CMD ["npm", "run", "theia:start"]
  2. Update docker-compose.yml:

    version: '3.8'
    services:
    claude-code-dev:
    build:
    context: .
    dockerfile: Dockerfile
    container_name: claude-code-dev
    volumes:
    # Persist workspace
    - ./:/workspace
    # Persist gcloud config
    - gcloud-config:/root/.config/gcloud
    # Persist npm cache
    - npm-cache:/root/.npm
    ports:
    - "3000:3000" # theia
    - "5173:5173" # Vite dev server
    - "8080:8080" # Backend API
    environment:
    - FDB_CLUSTER_FILE=/etc/foundationdb/fdb.cluster
    - FDB_CLUSTER_STRING=coditect:production@10.128.0.8:4500
    - GCP_PROJECT=serene-voltage-464305-n2
    networks:
    - coditect-network

    volumes:
    gcloud-config:
    npm-cache:

    networks:
    coditect-network:
    driver: bridge
  3. Rebuild and Test:

    # Rebuild Docker image with persistence
    docker-compose down
    docker-compose build --no-cache
    docker-compose up -d

    # Verify gcloud persists
    docker exec -it claude-code-dev gcloud --version
    docker exec -it claude-code-dev gcloud config list

    # Verify kubectl
    docker exec -it claude-code-dev kubectl version --client

Deliverables:

  • Dockerfile updated with gcloud SDK
  • docker-compose.yml updated with volumes
  • Container rebuilt with persistent tools
  • gcloud/kubectl working after rebuild

📋 Complete Task Checklist

Phase 1: Wrapper Foundation

  • Create theiaEmbed component
  • Modify V4 layout for theia
  • Create SidePanel component
  • Update App routes
  • Test theia loading in V4 wrapper

Phase 2: Theme Unification

  • Extract V4 Chakra theme
  • Create theia CSS theme
  • Implement theme sync hook
  • Create theia theme receiver
  • Verify visual consistency

Phase 3: Component Integration

  • Port llm chat panel to theia widget
  • Port model selector to statusbar
  • Port workflow mode to toolbar
  • Apply Chakra theme to all widgets
  • Test component interactions

Phase 4: Authentication Integration

  • Update auth store for FDB
  • Create auth backend endpoints
  • Wire up Login/Register pages
  • Test pod auto-provisioning
  • Verify session persistence

Phase 5: Docker Persistence

  • Update Dockerfile with gcloud SDK
  • Update docker-compose.yml volumes
  • Rebuild Docker image
  • Test gcloud persistence
  • Test kubectl persistence

🎯 Success Criteria

Integration Complete When:

  1. ✅ theia loads inside V4 layout (Header + Footer)
  2. ✅ Theme is consistent across V4 wrapper and theia
  3. ✅ llm chat panel, model selector, workflow mode integrated
  4. ✅ Login/Register pages working with FDB backend
  5. ✅ User pod auto-provisioned on registration
  6. ✅ gcloud SDK persists across Docker rebuilds
  7. ✅ All 50+ V4 docs pages accessible
  8. ✅ Mobile-responsive (V4 hamburger menu works)

🔗 Key Files

V4 Components (Reuse)

  • src/frontend-original/src/components/header.tsx
  • src/frontend-original/src/components/footer.tsx
  • src/frontend-original/src/components/layout.tsx
  • src/frontend-original/src/pages/login-page.tsx
  • src/frontend-original/src/pages/register-page.tsx

New Integration Components (Create)

  • src/components/theia-embed.tsx
  • src/components/side-panel.tsx
  • src/hooks/use-theia-theme.ts
  • src/browser/theme-sync-contribution.ts
  • server/auth.ts

Docker (Update)

  • Dockerfile (add gcloud SDK)
  • docker-compose.yml (add volumes)

Timeline: 3 weeks to complete V4/theia integration with Docker persistence.