gb/UI.md
Rodrigo Rodriguez (Pragmatismo) c3c235f8c4 feat(ui): migrate desktop environment to Window Manager
- Updated UI.md with the completed specification and status
- Synced botui submodule with new desktop.html and window-manager.js implementation
- Synced botserver submodule with latest changes
2026-02-24 19:02:48 -03:00

12 KiB

Web Desktop Environment Migration Plan (The "Windows" Vibe)

1. Project Overview & Vision

We are migrating the entire UI suite to a Web Desktop Environment (WDE). The goal is to create a UI that feels like a modern, web-based operating system (inspired by Windows 95's spatial model but with modern Tailwind aesthetics like the html3.html prototype).

Key Principles:

  • Vanilla JS + HTMX: We will build a custom Window Manager in Vanilla JS (window-manager.js) rather than relying on outdated libraries like WinBox. HTMX will handle fetching the content inside the windows.
  • Desktop Metaphor: A main workspace with shortcut icons (Vibe, Tasks, Chat, Terminal, Explorer, Editor, Browser, Mail, Settings).
  • Taskbar: A bottom bar showing currently open applications, allowing users to switch between them, alongside a system tray and clock.
  • Dynamic Windows: Windows must be draggable, closable, minimizable, and maintain their state. The title bar must dynamically reflect the active view.
  • App Renames:
    • Mantis is now Vibe
    • Terminal added to suite default features
    • Browser added to suite default features
    • Editor already in suite, add to default features
    • Note: Keep Drive as Drive (undo Explorer rename).

This document provides a strictly detailed, step-by-step implementation guide so that any LLM or developer can execute it without ambiguity.


2. Architecture & File Structure

Frontend Assets to Create:

  1. ui/desktop.html - The main shell containing the desktop background, desktop icons, and the empty taskbar.
  2. js/window-manager.js - The core engine. A JavaScript class responsible for DOM manipulation of windows.
  3. css/desktop.css - Custom styles for the grid background, scrollbars, and window animations (using Tailwind as the base).

Backend (Botserver) Updates:

  • State Management: The backend needs to track the user's open windows, their positions, and sizes if we want persistence across reloads. Otherwise, local state (localStorage) is fine for V1.
  • HTMX Endpoints: Each app (Explorer, Vibe, Chat, etc.) must expose an endpoint that returns only the HTML fragment for the app's body, NOT a full HTML page.
  • Theme Manager: Needs to be updated to support the new desktop color schemes (e.g., brand-500 greens, transparent glass effects).

3. Step-by-Step Implementation Guide

PHASE 1: The Shell (Desktop & Taskbar)

Goal: Create the static HTML structure based on html3.html.

Tasks:

  1. Create the main desktop.html.
  2. Implement the workspace-bg and workspace-grid using Tailwind and SVG.
  3. Add the left-side Desktop Icons. Each icon must have a data-app-id and data-app-title attribute.
    • Example: <div class="desktop-icon" data-app-id="drive" data-app-title="Drive" hx-get="/app/drive" hx-target="#temp-buffer" hx-swap="none">...</div>
  4. Create the Bottom Taskbar <footer id="taskbar">. It needs an empty container <div id="taskbar-apps"></div> to hold icons of open apps.

PHASE 2: The Window Manager Engine (window-manager.js)

Goal: Build a robust, vanilla JavaScript class WindowManager to handle floating UI panels that feels as native, smooth, and feature-rich as WinBox.

Core Requirements for window-manager.js:

  1. State & Z-Index Management: Keep an array of openWindows = []. Track the activeWindowId. Clicking any window must bring it to the front by updating its z-index (stacking context) and highlighting its taskbar icon.
  2. createWindow(appId, title, initialContent) method:
    • Generates the DOM nodes for a floating window.
    • Includes a Title Bar (drag handle, dynamic title, minimize, maximize, close buttons).
    • Includes invisible 8px borders around the window for resizing (N, S, E, W, NE, NW, SE, SW).
    • Appends it to the #workspace container and its icon to the #taskbar-apps container.
  3. Advanced Drag & Drop (The "WinBox" Feel):
    • Smooth Dragging: Use requestAnimationFrame for drag rendering to prevent lag.
    • Boundary Constraints: Prevent windows from being dragged completely out of the viewport. At least a portion of the title bar must remain grabbable.
    • Snapping: (Optional but recommended) If dragged to the top edge, trigger maximize. If dragged to the left/right, snap to 50% screen width.
  4. Resizing Logic:
    • Implement event listeners on the edges/corners. Updating width, height, top, and left simultaneously when resizing from the top or left edges.
  5. Maximize & Minimize Logic:
    • Maximize: Save the pre-maximized top/left/width/height state. Animate the window to fill 100% of the workspace (accounting for the taskbar).
    • Minimize: Animate the window shrinking down into its taskbar icon, then set display: none or opacity. Clicking the taskbar icon restores it with the reverse animation.
  6. Taskbar Integration:
    • Highlight the active window's icon in the taskbar. Click to toggle minimize/restore.

PHASE 3: HTMX Intercepts (The Magic Glue)

Goal: Connect the Desktop Icons to the Window Manager.

Instead of HTMX swapping directly into the DOM, we use HTMX events to intercept the response and pass it to the Window Manager.

Implementation for the Dumbest LLM:

// Listen to HTMX afterRequest event
document.body.addEventListener('htmx:afterRequest', function(evt) {
    const target = evt.detail.elt;
    
    // Check if the click came from a desktop icon
    if (target.classList.contains('desktop-icon')) {
        const appId = target.getAttribute('data-app-id');
        const title = target.getAttribute('data-app-title');
        const htmlContent = evt.detail.xhr.response;
        
        // Tell WindowManager to open it
        window.WindowManager.open(appId, title, htmlContent);
    }
});

PHASE 4: Migrating the Apps

Goal: Refactor existing pages to be fragments.

  1. Vibe (formerly Mantis): Remove the outer <html>, <head>, and <body>. Return only the inner content grid.
  2. Drive: Ensure HTMX links inside Drive target elements inside Drive's window container (closest .window-body #target), not the whole page.
  3. Chat, Mail, Settings, Terminal: Wrap their specific UIs into clean fragments.

Crucial HTMX Rule for Windows: Any link inside a window MUST use relative HTMX targeting (e.g., hx-target="closest .window-body") so it doesn't break out of the floating window.

PHASE 5: Botserver Routing & AGENTS.md Compliance

Goal: Update backend to serve HTMX fragments while strictly adhering to AGENTS.md security and architecture rules.

  1. Route Management (HTMX-First):
    • GET / -> Returns desktop.html (Full page load).
    • GET /app/vibe -> Returns the Vibe fragment (NO <html> or <body> tags).
    • GET /api/drive/files?path=/ -> Returns the Drive fragment.
    • Rule: All state-changing endpoints (POST/PUT/DELETE) triggered from these windows MUST include CSRF tokens (IMP-08).
  2. File Structure & 450-Line Limit:
    • Do not dump all routes into a single file. Respect the 450-line maximum per file rule.
    • Create separate modules for each app's routes (e.g., botserver/src/handlers/desktop.rs, botserver/src/handlers/vibe.rs, botserver/src/handlers/explorer.rs).
  3. Local Assets ONLY (NO CDNs):
    • CRITICAL: The original html3.html prototype used Tailwind and FontAwesome CDNs. AGENTS.md explicitly forbids this.
    • All CSS, Tailwind outputs, HTMX (htmx.min.js), and Web Fonts MUST be downloaded and served locally from the server's static assets folder.
  4. Command Execution (Terminal/Explorer Apps):
    • If the Terminal or Explorer apps need to read files or execute system commands, the backend handlers MUST use crate::security::command_guard::SafeCommand.
  5. Theme Manager:
    • Update CSS variables locally to match the aesthetic (brand-500 greens, translucent bg-white/90).

4. "Dumbest LLM" Coding Prompts & Snippets

If you are an AI tasked with implementing this, follow these explicit instructions.

A. Implementing desktop.html

  • CRITICAL: Do NOT copy the CDN links (<script src="https://cdn...">) from html3.html. AGENTS.md strictly forbids CDNs. You must link to local compiled CSS and local HTMX scripts.
  • The main container must have position: relative and overflow: hidden.
  • Render the icons exactly as:
<div class="desktop-icon flex flex-col items-center w-20 group cursor-pointer" 
     data-app-id="explorer" data-app-title="Explorer" 
     hx-get="/app/explorer" hx-swap="none">
    <div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
        <i class="fa-regular fa-folder-open drop-shadow-md"></i>
    </div>
    <span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Explorer</span>
</div>

B. Implementing window-manager.js

Create a global object window.WindowManager. It must have an open(id, title, html) method. If the window with id already exists, call focus(id). If it doesn't exist, create this exact DOM structure:

<div id="window-{id}" class="absolute w-[700px] bg-white rounded-lg shadow-2xl flex flex-col border border-gray-200 overflow-hidden z-20" style="top: 100px; left: 150px;">
    <!-- Header (Draggable) -->
    <div class="window-header h-10 bg-white/95 backdrop-blur flex items-center justify-between px-4 border-b border-gray-200 select-none cursor-move">
        <div class="font-mono text-xs font-bold text-brand-600 tracking-wide">{title}</div>
        <div class="flex space-x-3 text-gray-400">
            <button class="btn-minimize hover:text-gray-600"><i class="fa-solid fa-minus"></i></button>
            <button class="btn-maximize hover:text-gray-600"><i class="fa-regular fa-square"></i></button>
            <button class="btn-close hover:text-red-500"><i class="fa-solid fa-xmark"></i></button>
        </div>
    </div>
    <!-- Body (HTMX target) -->
    <div class="window-body relative flex-1 overflow-y-auto bg-[#fafdfa]">
        {html}
    </div>
</div>

C. Implementing the Taskbar Task

When WindowManager.open() is called, also append this to #taskbar-apps:

<div id="taskbar-item-{id}" class="h-10 w-12 flex items-center justify-center cursor-pointer bg-brand-50 rounded border-b-2 border-brand-500 transition-all taskbar-icon" onclick="WindowManager.toggle('{id}')">
    <div class="app-icon w-8 h-8 rounded-md flex items-center justify-center text-white text-xs shadow-sm">
        <!-- Map icon based on ID here -->
    </div>
</div>

5. Summary of Definitions

  • Desktop: The root view of the application.
  • Window: A floating, draggable container for a specific app (Explorer, Vibe, etc.).
  • Taskbar: The bottom panel tracking open windows.
  • App Fragment: The partial HTML code returned by the server to populate a Window.

Execute this plan sequentially. Do not attempt to load full HTML pages inside windows. Build the Window Manager engine first, then migrate apps one by one.

Current Implementation Status (Feb 24, 2026)

What is Working:

  1. The backend has been re-routed. localhost:3000 now correctly serves the new desktop.html UI shell instead of the old default.gbui.
  2. The core assets (window-manager.js, desktop.css) and static HTMX structure for the desktop sidebar, grid background, and icons are loading successfully.
  3. The apps (Chat, Tasks, Terminal) have existing implementations in the suite directories.

What is Missing/Broken to See Windows Again:

  1. Window Manager Initialization Bug: desktop.html currently crashes on load because it tries to call new window.WindowManager(). The window-manager.js script already exports an instance, not a class, causing a TypeError.
  2. Missing Tailwind CDN/CSS Classes: The original html3.html prototype likely relied on a Tailwind CSS CDN script. Because CDNs are banned, window-manager.js is creating windows using dynamic Tailwind classes (like w-[700px], bg-white/95) which do not exist in the locally compiled CSS (app.css or desktop.css). The windows will have no structure or styling until these classes are ported to desktop.css or compiled.
  3. App Fragment Extraction: HTMX is currently fetching the full chat/chat.html page (including <head>, <body>, etc.). When window-manager.js tries to inject this into a floating div, it can break the DOM. The endpoints must be updated to return only the inner content (the fragments) as defined in Phase 4 of this document.