- 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
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:
Mantisis nowVibeTerminaladded to suite default featuresBrowseradded to suite default featuresEditoralready in suite, add to default features- Note: Keep
DriveasDrive(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:
ui/desktop.html- The main shell containing the desktop background, desktop icons, and the empty taskbar.js/window-manager.js- The core engine. A JavaScript class responsible for DOM manipulation of windows.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:
- Create the main
desktop.html. - Implement the
workspace-bgandworkspace-gridusing Tailwind and SVG. - Add the left-side Desktop Icons. Each icon must have a
data-app-idanddata-app-titleattribute.- 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>
- Example:
- 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:
- State & Z-Index Management: Keep an array of
openWindows = []. Track theactiveWindowId. Clicking any window must bring it to the front by updating its z-index (stacking context) and highlighting its taskbar icon. 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
#workspacecontainer and its icon to the#taskbar-appscontainer.
- Advanced Drag & Drop (The "WinBox" Feel):
- Smooth Dragging: Use
requestAnimationFramefor 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.
- Smooth Dragging: Use
- Resizing Logic:
- Implement event listeners on the edges/corners. Updating
width,height,top, andleftsimultaneously when resizing from the top or left edges.
- Implement event listeners on the edges/corners. Updating
- Maximize & Minimize Logic:
- Maximize: Save the pre-maximized
top/left/width/heightstate. Animate the window to fill100%of the workspace (accounting for the taskbar). - Minimize: Animate the window shrinking down into its taskbar icon, then set
display: noneor opacity. Clicking the taskbar icon restores it with the reverse animation.
- Maximize: Save the pre-maximized
- 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.
- Vibe (formerly Mantis): Remove the outer
<html>,<head>, and<body>. Return only the inner content grid. - Drive: Ensure HTMX links inside Drive target elements inside Drive's window container (
closest .window-body #target), not the whole page. - 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.
- Route Management (HTMX-First):
GET /-> Returnsdesktop.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).
- 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).
- Local Assets ONLY (NO CDNs):
- CRITICAL: The original
html3.htmlprototype used Tailwind and FontAwesome CDNs.AGENTS.mdexplicitly 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.
- CRITICAL: The original
- 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.
- If the Terminal or Explorer apps need to read files or execute system commands, the backend handlers MUST use
- Theme Manager:
- Update CSS variables locally to match the aesthetic (brand-500 greens, translucent
bg-white/90).
- Update CSS variables locally to match the aesthetic (brand-500 greens, translucent
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...">) fromhtml3.html.AGENTS.mdstrictly forbids CDNs. You must link to local compiled CSS and local HTMX scripts. - The main container must have
position: relativeandoverflow: 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:
- The backend has been re-routed.
localhost:3000now correctly serves the newdesktop.htmlUI shell instead of the olddefault.gbui. - The core assets (
window-manager.js,desktop.css) and static HTMX structure for the desktop sidebar, grid background, and icons are loading successfully. - The apps (Chat, Tasks, Terminal) have existing implementations in the suite directories.
What is Missing/Broken to See Windows Again:
- Window Manager Initialization Bug:
desktop.htmlcurrently crashes on load because it tries to callnew window.WindowManager(). Thewindow-manager.jsscript already exports an instance, not a class, causing aTypeError. - Missing Tailwind CDN/CSS Classes: The original
html3.htmlprototype likely relied on a Tailwind CSS CDN script. Because CDNs are banned,window-manager.jsis creating windows using dynamic Tailwind classes (likew-[700px],bg-white/95) which do not exist in the locally compiled CSS (app.cssordesktop.css). The windows will have no structure or styling until these classes are ported todesktop.cssor compiled. - App Fragment Extraction: HTMX is currently fetching the full
chat/chat.htmlpage (including<head>,<body>, etc.). Whenwindow-manager.jstries to inject this into a floatingdiv, 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.