No description
Find a file
Rodrigo Rodriguez (Pragmatismo) 7c1deca8ae fix: resolve infinite WebSocket reconnection loop
The ui_server proxies WebSocket connections. It was accepting the client's WebSocket connection (ws.onopen triggered on the client), but if it couldn't connect to the backend (or if the backend disconnected), it would drop the client connection right away (ws.onclose triggered).

The issue was that reconnectAttempts was being reset to 0 inside the ws.onopen handler. Because the connection was briefly succeeding before failing, the reconnectAttempts counter was resetting to 0 on every attempt, completely circumventing the exponential backoff mechanism and causing a tight reconnection loop.

Modified the WebSocket logic across all relevant UI components to delay resetting reconnectAttempts = 0. Instead of resetting immediately upon the TCP socket opening, it now safely waits until a valid JSON payload {"type": "connected"} is successfully received from the backend.
2026-02-25 10:15:47 -03:00
.forgejo/workflows fix: Avoid workspace conflict in Forgejo CI 2026-02-15 23:26:37 +00:00
.vscode Add VS Code settings for rust-analyzer 2025-12-04 09:38:10 -03:00
gen/schemas - Spliting from botserver. 2025-12-03 18:42:22 -03:00
src feat(ui): implement Window Manager desktop shell based on BUILD V3 design 2026-02-24 19:02:48 -03:00
ui fix: resolve infinite WebSocket reconnection loop 2026-02-25 10:15:47 -03:00
.gitignore - Spliting from botserver. 2025-12-03 18:42:22 -03:00
build.rs Fix email module integration - update build and UI server 2026-02-07 16:28:36 +00:00
Cargo.lock fix: suite chat now works like minimal UI with HTMX loading 2025-12-10 22:58:09 -03:00
Cargo.toml feat(ui): implement Window Manager desktop shell based on BUILD V3 design 2026-02-24 19:02:48 -03:00
html3.html feat(ui): implement Window Manager desktop shell based on BUILD V3 design 2026-02-24 19:02:48 -03:00
LICENSE Initial commit 2024-10-26 13:00:42 -03:00
README.md Update submodule changes 2026-02-13 22:31:49 +00:00

BotUI - General Bots Web Interface

Version: 6.2.0
Purpose: Web UI server for General Bots (Axum + HTMX + CSS)


Overview

BotUI is a modern web interface for General Bots, built with Rust, Axum, and HTMX. It provides a clean, responsive interface for interacting with the General Bots platform, featuring real-time updates via WebSocket connections and a minimalist JavaScript approach powered by HTMX.

The interface supports multiple features including chat, file management, tasks, calendar, analytics, and more - all served through a fast, efficient Rust backend with a focus on server-rendered HTML and minimal client-side JavaScript.

For comprehensive documentation, see docs.pragmatismo.com.br or the BotBook for detailed guides and API references.


Quick Start

# Development mode - starts Axum server on port 9000
cargo run

# Desktop mode (Tauri) - starts native window
cargo tauri dev

Environment Variables

  • BOTUI_PORT - Server port (default: 9000)

ZERO TOLERANCE POLICY

EVERY SINGLE WARNING MUST BE FIXED. NO EXCEPTIONS.


ABSOLUTE PROHIBITIONS

❌ NEVER use #![allow()] or #[allow()] in source code
❌ NEVER use _ prefix for unused variables - DELETE or USE them
❌ NEVER use .unwrap() - use ? or proper error handling
❌ NEVER use .expect() - use ? or proper error handling  
❌ NEVER use panic!() or unreachable!()
❌ NEVER use todo!() or unimplemented!()
❌ NEVER leave unused imports or dead code
❌ NEVER add comments - code must be self-documenting
❌ NEVER use CDN links - all assets must be local

🏗️ ARCHITECTURE

Dual Modes

Mode Command Description
Web cargo run Axum server on port 9000
Desktop cargo tauri dev Tauri native window

Code Organization

src/
├── main.rs           # Entry point - mode detection
├── lib.rs            # Feature-gated module exports
├── http_client.rs    # HTTP wrapper for botserver
├── ui_server/
│   └── mod.rs        # Axum router + UI serving
├── desktop/
│   ├── mod.rs        # Desktop module organization
│   ├── drive.rs      # File operations via Tauri
│   └── tray.rs       # System tray
└── shared/
    └── state.rs      # Shared application state

ui/
├── suite/            # Main UI (HTML/CSS/JS)
│   ├── js/vendor/    # Local JS libraries
│   └── css/          # Stylesheets
└── minimal/          # Minimal chat UI

🎨 HTMX-FIRST FRONTEND

Core Principle

  • Use HTMX to minimize JavaScript
  • Server returns HTML fragments, not JSON
  • Delegate ALL logic to Rust server

HTMX Usage

Use Case Solution
Data fetching hx-get, hx-post
Form submission hx-post, hx-put
Real-time updates hx-ext="ws"
Content swapping hx-target, hx-swap
Polling hx-trigger="every 5s"
Loading states hx-indicator

When JS is Required

Use Case Why JS Required
Modal show/hide DOM manipulation
Toast notifications Dynamic element creation
Clipboard operations navigator.clipboard API
Keyboard shortcuts keydown event handling
Complex animations GSAP or custom

📦 LOCAL ASSETS ONLY - NO CDN

ui/suite/js/vendor/
├── htmx.min.js
├── htmx-ws.js
├── marked.min.js
├── gsap.min.js
└── livekit-client.umd.min.js
<!-- ✅ CORRECT -->
<script src="js/vendor/htmx.min.js"></script>

<!-- ❌ WRONG -->
<script src="https://unpkg.com/htmx.org@1.9.10"></script>

🎨 OFFICIAL ICONS - MANDATORY

NEVER generate icons with LLM. Use official SVG icons:

ui/suite/assets/icons/
├── gb-logo.svg        # Main GB logo
├── gb-bot.svg         # Bot/assistant
├── gb-analytics.svg   # Analytics
├── gb-calendar.svg    # Calendar
├── gb-chat.svg        # Chat
├── gb-drive.svg       # File storage
├── gb-mail.svg        # Email
├── gb-meet.svg        # Video meetings
├── gb-tasks.svg       # Task management
└── ...

All icons use stroke="currentColor" for CSS theming.


🔒 SECURITY ARCHITECTURE

Centralized Auth Engine

All authentication is handled by security-bootstrap.js which MUST be loaded immediately after HTMX:

<head>
    <!-- 1. HTMX first -->
    <script src="js/vendor/htmx.min.js"></script>
    <script src="js/vendor/htmx-ws.js"></script>
    
    <!-- 2. Security bootstrap immediately after -->
    <script src="js/security-bootstrap.js"></script>
    
    <!-- 3. Other scripts -->
    <script src="js/api-client.js"></script>
</head>

DO NOT Duplicate Auth Logic

// ❌ WRONG - Don't add auth headers manually
fetch("/api/data", {
    headers: { "Authorization": "Bearer " + token }
});

// ✅ CORRECT - Let security-bootstrap.js handle it
fetch("/api/data");

🎨 DESIGN SYSTEM

Layout Standards

.app-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    overflow: hidden;
}

.main-content {
    display: grid;
    grid-template-columns: 320px 1fr;
    flex: 1;
    overflow: hidden;
}

.list-panel {
    overflow-y: scroll;
    scrollbar-width: auto;
}

.detail-panel {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

Theme Variables Required

[data-theme="your-theme"] {
    --bg: #0a0a0a;
    --surface: #161616;
    --surface-hover: #1e1e1e;
    --border: #2a2a2a;
    --text: #ffffff;
    --text-secondary: #888888;
    --primary: #c5f82a;
    --success: #22c55e;
    --warning: #f59e0b;
    --error: #ef4444;
}

CODE PATTERNS

Error Handling

// ❌ WRONG
let value = something.unwrap();

// ✅ CORRECT
let value = something?;
let value = something.ok_or_else(|| Error::NotFound)?;

Self Usage

impl MyStruct {
    fn new() -> Self { Self { } }  // ✅ Not MyStruct
}

Format Strings

format!("Hello {name}")  // ✅ Not format!("{}", name)

Derive Eq with PartialEq

#[derive(PartialEq, Eq)]  // ✅ Always both
struct MyStruct { }

📦 KEY DEPENDENCIES

Library Version Purpose
axum 0.7.5 Web framework
reqwest 0.12 HTTP client
tokio 1.41 Async runtime
askama 0.12 HTML Templates

📚 Documentation

For complete documentation, guides, and API references:


🔑 REMEMBER

  • ZERO WARNINGS - Every clippy warning must be fixed
  • NO ALLOW IN CODE - Never use #[allow()] in source files
  • NO DEAD CODE - Delete unused code
  • NO UNWRAP/EXPECT - Use ? operator
  • HTMX first - Minimize JS, delegate to server
  • Local assets - No CDN, all vendor files local
  • No business logic - All logic in botserver
  • HTML responses - Server returns fragments, not JSON
  • Version 6.2.0 - do not change without approval