diff --git a/PROMPT.md b/PROMPT.md index c511d45..1bf2570 100644 --- a/PROMPT.md +++ b/PROMPT.md @@ -1,364 +1,33 @@ -# BotUI Development Prompt Guide +# BotUI Development Guide -**Version:** 6.1.0 -**Purpose:** LLM context for BotUI development +**Version:** 6.2.0 +**Purpose:** Web UI server for General Bots (Axum + HTMX + CSS) --- ## ZERO TOLERANCE POLICY -**This project has the strictest code quality requirements possible.** - **EVERY SINGLE WARNING MUST BE FIXED. NO EXCEPTIONS.** --- -## ABSOLUTE PROHIBITIONS +## ❌ ABSOLUTE PROHIBITIONS ``` -❌ NEVER use #![allow()] or #[allow()] in source code to silence warnings -❌ NEVER use _ prefix for unused variables - DELETE the variable or USE it +❌ 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!() - handle all cases -❌ NEVER use todo!() or unimplemented!() - write real code -❌ NEVER leave unused imports - DELETE them -❌ NEVER leave dead code - DELETE it or IMPLEMENT it -❌ NEVER use approximate constants (3.14159) - use std::f64::consts::PI -❌ NEVER silence clippy in code - FIX THE CODE or configure in Cargo.toml -❌ NEVER add comments explaining what code does - code must be self-documenting +❌ 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 ``` --- -## CARGO.TOML LINT EXCEPTIONS - -When a clippy lint has **technical false positives** that cannot be fixed in code, -disable it in `Cargo.toml` with a comment explaining why: - -```toml -[lints.clippy] -# Disabled: has false positives for functions with mut self, heap types (Vec, String) -missing_const_for_fn = "allow" -# Disabled: Tauri commands require owned types (Window) that cannot be passed by reference -needless_pass_by_value = "allow" -# Disabled: transitive dependencies we cannot control -multiple_crate_versions = "allow" -``` - -**Approved exceptions:** -- `missing_const_for_fn` - false positives for `mut self`, heap types -- `needless_pass_by_value` - Tauri/framework requirements -- `multiple_crate_versions` - transitive dependencies -- `future_not_send` - when async traits require non-Send futures - ---- - -## MANDATORY CODE PATTERNS - -### Error Handling - Use `?` Operator - -```rust -// ❌ WRONG -let value = something.unwrap(); -let value = something.expect("msg"); - -// ✅ CORRECT -let value = something?; -let value = something.ok_or_else(|| Error::NotFound)?; -``` - -### Self Usage in Impl Blocks - -```rust -// ❌ WRONG -impl MyStruct { - fn new() -> MyStruct { MyStruct { } } -} - -// ✅ CORRECT -impl MyStruct { - fn new() -> Self { Self { } } -} -``` - -### Format Strings - Inline Variables - -```rust -// ❌ WRONG -format!("Hello {}", name) - -// ✅ CORRECT -format!("Hello {name}") -``` - -### Display vs ToString - -```rust -// ❌ WRONG -impl ToString for MyType { } - -// ✅ CORRECT -impl std::fmt::Display for MyType { } -``` - -### Derive Eq with PartialEq - -```rust -// ❌ WRONG -#[derive(PartialEq)] -struct MyStruct { } - -// ✅ CORRECT -#[derive(PartialEq, Eq)] -struct MyStruct { } -``` - ---- - -## Weekly Maintenance - EVERY MONDAY - -### Package Review Checklist - -**Every Monday, review the following:** - -1. **Dependency Updates** - ```bash - cargo outdated - cargo audit - ``` - -2. **Package Consolidation Opportunities** - - Check if new crates can replace custom code - - Look for crates that combine multiple dependencies - - Review `Cargo.toml` for redundant dependencies - -3. **Code Reduction Candidates** - - Custom implementations that now have crate equivalents - - Boilerplate that can be replaced with derive macros - - Manual serialization that `serde` can handle - -4. **Frontend Asset Updates** - ```bash - # Check vendor libs in ui/suite/js/vendor/ - # Compare with latest versions of htmx, gsap, etc. - ``` - -### Packages to Watch - -| Area | Potential Packages | Purpose | -|------|-------------------|---------| -| HTTP Client | `reqwest` | Consolidate HTTP handling | -| Templates | `askama` | Efficient HTML templates | -| Animations | `gsap` | Replace CSS animations | - ---- - -## Version Management - CRITICAL - -**Current version is 6.1.0 - DO NOT CHANGE without explicit approval!** - -### Rules - -1. **Version is 6.1.0 across ALL workspace crates** -2. **NEVER change version without explicit user approval** -3. **BotUI does not have migrations - all migrations are in botserver/** -4. **All workspace crates share version 6.1.0** - ---- - -## Official Icons - MANDATORY - -**NEVER generate icons with LLM. ALWAYS use official SVG icons from:** - -``` -ui/suite/assets/icons/ -├── gb-logo.svg # Main GB logo -├── gb-bot.svg # Bot/assistant -├── gb-analytics.svg # Analytics app -├── gb-calendar.svg # Calendar app -├── gb-chat.svg # Chat app -├── gb-compliance.svg # Compliance/security -├── gb-designer.svg # Workflow designer -├── gb-drive.svg # File storage -├── gb-mail.svg # Email -├── gb-meet.svg # Video meetings -├── gb-paper.svg # Documents -├── gb-research.svg # Research/search -├── gb-sources.svg # Knowledge sources -└── gb-tasks.svg # Task management -``` - -### Usage in HTML - -```html - -Chat - - - - - -``` - -### Icon Style Guidelines - -- All icons use `stroke="currentColor"` for theming -- ViewBox: `0 0 24 24` -- Stroke width: `1.5` -- Rounded caps and joins -- Consistent with GB brand identity - -**DO NOT:** -- Generate new icons with AI/LLM -- Use emoji or unicode symbols as icons -- Use external icon libraries (FontAwesome, etc.) -- Create inline SVG content in templates - ---- - -## Project Overview - -BotUI is a **dual-mode UI application** built in Rust that runs as either a desktop app (Tauri) or web server (Axum). All business logic is in **botserver** - BotUI is purely presentation + HTTP bridge. - -### Workspace Position - -``` -botui/ # THIS PROJECT - Web/Desktop UI -botserver/ # Main server (business logic) -botlib/ # Shared library (consumed here) -botapp/ # Desktop wrapper (consumes botui) -botbook/ # Documentation -``` - ---- - -## LLM Workflow Strategy - -### Two Types of LLM Work - -1. **Execution Mode (Fazer)** - - Pre-annotate phrases and send for execution - - Focus on automation freedom - - Less concerned with code details - - Primary concern: Is the LLM destroying something? - - Trust but verify output doesn't break existing functionality - -2. **Review Mode (Conferir)** - - Read generated code with full attention - - Line-by-line verification - - Check for correctness, security, performance - - Validate against requirements - -### LLM Fallback Strategy (After 3 attempts / 10 minutes) - -1. DeepSeek-V3-0324 (good architect, reliable) -2. gpt-5-chat (slower but thorough) -3. gpt-oss-120b (final validation) -4. Claude Web (for complex debugging, unit tests, UI) - ---- - -## Code Generation Rules - -### CRITICAL REQUIREMENTS - -``` -- BotUI = Presentation + HTTP bridge ONLY -- All business logic goes in botserver -- No code duplication between layers -- Feature gates eliminate unused code paths -- Zero warnings - feature gating prevents dead code -- NO DEAD CODE - implement real functionality, never use _ for unused -- All JS/CSS must be local (no CDN) -``` - -### HTMX-First Frontend - -``` -- Use HTMX to minimize JavaScript at maximum -- Delegate ALL logic to Rust server -- Server returns HTML fragments, not JSON -- Use hx-get, hx-post, hx-target, hx-swap attributes -- WebSocket via htmx-ws extension for real-time -- NO custom JavaScript where HTMX can handle it -``` - -### JavaScript Usage Guidelines - -**JS is ONLY acceptable when HTMX cannot handle the requirement:** - -| Use Case | Solution | -|----------|----------| -| Data fetching | HTMX `hx-get`, `hx-post` | -| Form submission | HTMX `hx-post`, `hx-put` | -| Real-time updates | HTMX WebSocket extension `hx-ext="ws"` | -| Content swapping | HTMX `hx-target`, `hx-swap` | -| Polling | HTMX `hx-trigger="every 5s"` | -| Loading states | HTMX `hx-indicator` | -| **Modal show/hide** | **JS required** - DOM manipulation | -| **Toast notifications** | **JS required** - dynamic element creation | -| **Clipboard operations** | **JS required** - `navigator.clipboard` API | -| **Keyboard shortcuts** | **JS required** - `keydown` event handling | -| **WebSocket state mgmt** | **JS required** - connection lifecycle | -| **Complex animations** | **JS required** - GSAP or custom | -| **Client-side validation** | **JS required** - before submission UX | - -**When writing JS:** -``` -- Keep it minimal - one function per concern -- No frameworks (React, Vue, etc.) - vanilla JS only -- Use vendor libs sparingly (htmx, marked, gsap) -- All JS must work with HTMX lifecycle (htmx:afterSwap, etc.) -- Prefer CSS for animations when possible -``` - -### Local Assets Only - -All external libraries are bundled locally - NEVER use CDN: - -``` -ui/suite/js/vendor/ -├── htmx.min.js # HTMX core -├── htmx-ws.js # WebSocket extension -├── htmx-json-enc.js # JSON encoding -├── marked.min.js # Markdown parser -├── gsap.min.js # Animation (minimal use) -└── livekit-client.umd.min.js # LiveKit video - -ui/minimal/js/vendor/ -└── (same structure) -``` - -```html - - - - - -``` - -### Dependency Management - -``` -- Use diesel for any local database needs -- After adding to Cargo.toml: cargo audit must show 0 warnings -- If audit fails, find alternative library -- Minimize redundancy - check existing libs before adding new ones -``` - -### Documentation Rules - -``` -- Rust code examples ONLY allowed in architecture/gbapp documentation -- Scan for ALL_CAPS.md files created at wrong places - delete or integrate -- Keep only README.md and PROMPT.md at project root level -``` - ---- - -## Architecture +## 🏗️ ARCHITECTURE ### Dual Modes @@ -373,14 +42,13 @@ ui/minimal/js/vendor/ src/ ├── main.rs # Entry point - mode detection ├── lib.rs # Feature-gated module exports -├── http_client.rs # HTTP wrapper for botserver (web-only) +├── http_client.rs # HTTP wrapper for botserver ├── ui_server/ -│ └── mod.rs # Axum router + UI serving (web-only) +│ └── mod.rs # Axum router + UI serving ├── desktop/ │ ├── mod.rs # Desktop module organization │ ├── drive.rs # File operations via Tauri -│ ├── tray.rs # System tray infrastructure -│ └── stream.rs # Streaming operations +│ └── tray.rs # System tray └── shared/ └── state.rs # Shared application state @@ -389,44 +57,99 @@ ui/ │ ├── js/vendor/ # Local JS libraries │ └── css/ # Stylesheets └── minimal/ # Minimal chat UI - └── js/vendor/ # Local JS libraries -``` - -### Feature Gating - -```rust -#[cfg(feature = "desktop")] -pub mod desktop; - -#[cfg(not(feature = "desktop"))] -pub mod http_client; ``` --- -## Security Architecture - MANDATORY +## 🎨 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 +``` + +```html + + + + + +``` + +--- + +## 🎨 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 in the `` section. This provides: - -1. **Automatic HTMX auth headers** - All `hx-get`, `hx-post`, etc. requests get Authorization header -2. **Fetch API interception** - All `fetch()` calls automatically get auth headers -3. **XMLHttpRequest interception** - Legacy XHR calls also get auth headers -4. **Session management** - Handles token storage, refresh, and expiration - -### Script Loading Order (CRITICAL) +All authentication is handled by `security-bootstrap.js` which MUST be loaded immediately after HTMX: ```html - + - + - + ``` @@ -443,174 +166,95 @@ fetch("/api/data", { fetch("/api/data"); ``` -### DO NOT Register Multiple HTMX Auth Listeners +--- -```javascript -// ❌ WRONG - Don't register duplicate listeners -document.addEventListener("htmx:configRequest", (e) => { - e.detail.headers["Authorization"] = "Bearer " + token; -}); +## 🎨 DESIGN SYSTEM -// ✅ CORRECT - This is handled by security-bootstrap.js automatically +### Layout Standards + +```css +.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; +} ``` -### Auth Events +### Theme Variables Required -The security engine dispatches these events: - -- `gb:security:ready` - Security bootstrap initialized -- `gb:auth:unauthorized` - 401 response received -- `gb:auth:expired` - Session expired, user should re-login -- `gb:auth:login` - Dispatch to store tokens after login -- `gb:auth:logout` - Dispatch to clear tokens - -### Token Storage Keys - -All auth data uses these keys (defined in security-bootstrap.js): - -- `gb-access-token` - JWT access token -- `gb-refresh-token` - Refresh token -- `gb-session-id` - Session identifier -- `gb-token-expires` - Token expiration timestamp -- `gb-user-data` - Cached user profile +```css +[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; +} +``` --- -## HTMX Patterns +## ✅ CODE PATTERNS -### Server-Side Rendering - -```html - - - -
- -
-``` - -### Form Submission - -```html -
- - -
-``` - -### WebSocket Real-time - -```html -
-
-
- - -
-
-``` - -### Server Response (Rust/Askama) +### Error Handling ```rust -#[derive(Template)] -#[template(path = "partials/item.html")] -struct ItemTemplate { - item: Item, -} +// ❌ WRONG +let value = something.unwrap(); -async fn create_item( - State(state): State>, - Form(input): Form, -) -> Html { - let item = save_item(&state, input).await; - let template = ItemTemplate { item }; - Html(template.render().unwrap()) -} +// ✅ CORRECT +let value = something?; +let value = something.ok_or_else(|| Error::NotFound)?; ``` ---- - -## Adding Features - -### Process - -1. Add business logic to **botserver** first -2. Create REST API endpoint in botserver (returns HTML for HTMX) -3. Add HTTP wrapper in BotUI if needed -4. Add UI in `ui/suite/` using HTMX attributes -5. For desktop-specific: Add Tauri command in `src/desktop/` - -### Desktop Tauri Command +### Self Usage ```rust -#[tauri::command] -pub fn list_files(path: &str) -> Result, String> { - let entries = std::fs::read_dir(path) - .map_err(|e| e.to_string())?; - - let items: Vec = entries - .filter_map(|e| e.ok()) - .map(|e| FileItem { - name: e.file_name().to_string_lossy().to_string(), - is_dir: e.path().is_dir(), - }) - .collect(); - - Ok(items) +impl MyStruct { + fn new() -> Self { Self { } } // ✅ Not MyStruct } ``` ---- - -## COMPILATION POLICY - CRITICAL - -**NEVER compile during development. NEVER run `cargo build` or `cargo check`. Use static analysis only.** - -### Workflow - -1. Make all code changes -2. Use `diagnostics` tool for static analysis (NOT compilation) -3. Fix any errors found by diagnostics -4. **At the end**, inform user what needs restart - -### After All Changes Complete - -| Change Type | User Action Required | -|-------------|----------------------| -| Rust code (`.rs` files) | "Recompile and restart **botui**" | -| HTML templates (`.html` in ui/) | "Browser refresh only" | -| CSS/JS files | "Browser refresh only" | -| Askama templates (`.html` in src/) | "Recompile and restart **botui**" | -| Cargo.toml changes | "Recompile and restart **botui**" | - -**Format:** At the end of your response, always state: -- ✅ **No restart needed** - browser refresh only -- 🔄 **Restart botui** - recompile required - ---- - -## Key Files Reference +### Format Strings +```rust +format!("Hello {name}") // ✅ Not format!("{}", name) ``` -src/main.rs # Entry point, mode detection -src/lib.rs # Feature-gated exports -src/http_client.rs # botserverClient wrapper -src/ui_server/mod.rs # Axum router, static files -ui/suite/index.html # Main UI entry -ui/suite/base.html # Base template -ui/minimal/index.html # Minimal chat UI + +### Derive Eq with PartialEq + +```rust +#[derive(PartialEq, Eq)] // ✅ Always both +struct MyStruct { } ``` --- -## Dependencies +## 📦 KEY DEPENDENCIES | Library | Version | Purpose | |---------|---------|---------| @@ -618,389 +262,17 @@ ui/minimal/index.html # Minimal chat UI | reqwest | 0.12 | HTTP client | | tokio | 1.41 | Async runtime | | askama | 0.12 | HTML Templates | -| diesel | 2.1 | Database (sqlite) | --- ---- - -## Design System - UI Standards - -**The `tasks.css` file defines the standard patterns for ALL screens in General Bots.** - -All themes MUST implement these core components consistently. - -### Layout Standards - -```css -/* Full-height container - no global scroll */ -.app-container { - display: flex; - flex-direction: column; - height: 100vh; - max-height: 100vh; - overflow: hidden; -} - -/* Two-column layout - list + detail */ -.main-content { - display: grid; - grid-template-columns: 320px 1fr; - flex: 1; - overflow: hidden; - height: calc(100vh - 120px); -} - -/* Scrollable list panel (LEFT) */ -.list-panel { - overflow-y: scroll; - overflow-x: hidden; - height: 100%; - scrollbar-width: auto; - scrollbar-color: var(--border-light) var(--surface); -} - -/* Fixed detail panel (RIGHT) - no scroll */ -.detail-panel { - display: flex; - flex-direction: column; - overflow: hidden; - height: 100%; -} -``` - -### Scrollbar Standards - -```css -/* Visible scrollbar - 10px width */ -.scrollable::-webkit-scrollbar { - width: 10px; -} - -.scrollable::-webkit-scrollbar-track { - background: var(--surface); - border-radius: 5px; -} - -.scrollable::-webkit-scrollbar-thumb { - background: var(--border-light); - border-radius: 5px; - border: 2px solid var(--surface); -} - -.scrollable::-webkit-scrollbar-thumb:hover { - background: var(--primary); -} - -/* Firefox */ -.scrollable { - scrollbar-width: auto; - scrollbar-color: var(--border-light) var(--surface); -} -``` - -### Card Standards - -```css -/* Base card - used in task lists, items, etc. */ -.card { - background: var(--surface-hover); - border: 2px solid var(--border); - border-radius: 16px; - padding: 16px 20px; - cursor: pointer; - transition: all 0.2s ease; - position: relative; -} - -.card:hover { - border-color: var(--border-hover); - background: var(--surface); -} - -.card.selected { - border-color: var(--primary); - box-shadow: 0 0 0 2px var(--primary); -} - -/* Card status indicator (left bar) */ -.card::before { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 5px; - height: 100%; - background: var(--text-secondary); - transition: background 0.2s ease; -} - -.card.status-running::before { background: var(--primary); } -.card.status-complete::before { background: var(--success); } -.card.status-error::before { background: var(--error); } -.card.status-pending::before { background: var(--text-secondary); } -``` - -### Progress/Tree Indicators - -```css -/* Dot indicator - shows status */ -.status-dot { - width: 8px; - height: 8px; - border-radius: 50%; - flex-shrink: 0; - background: var(--text-secondary); - transition: all 0.3s ease; -} - -.status-dot.running { - background: var(--primary); - box-shadow: 0 0 8px var(--primary-light); - animation: dot-pulse 1.5s ease-in-out infinite; -} - -.status-dot.completed { - background: var(--primary); -} - -.status-dot.pending { - background: var(--text-secondary); -} - -@keyframes dot-pulse { - 0%, 100% { - opacity: 1; - box-shadow: 0 0 10px var(--primary-light); - transform: scale(1); - } - 50% { - opacity: 0.7; - box-shadow: 0 0 4px var(--primary-light); - transform: scale(0.9); - } -} - -/* Step badge */ -.step-badge { - padding: 4px 12px; - background: var(--primary); - color: var(--bg); - border-radius: 4px; - font-size: 11px; - font-weight: 600; -} - -.step-badge.pending { - background: var(--surface); - color: var(--text-secondary); -} -``` - -### Tree/List with Children - -```css -/* Parent-child expandable tree */ -.tree-section { - border: 1px solid var(--border); - background: var(--surface); - border-radius: 8px; - margin: 8px 16px; - overflow: hidden; -} - -.tree-row { - display: flex; - align-items: center; - padding: 16px 20px; - cursor: pointer; - transition: background 0.15s; -} - -.tree-row:hover { - background: var(--surface-hover); -} - -.tree-children { - display: none; - background: var(--bg); -} - -.tree-section.expanded .tree-children { - display: block; -} - -.tree-child { - border-bottom: 1px solid var(--border); - padding-left: 24px; -} - -.tree-item { - display: flex; - align-items: center; - padding: 8px 20px 8px 40px; - min-height: 32px; -} -``` - -### Fixed Panels (Terminal, Status) - -```css -/* Fixed-height panel at bottom */ -.fixed-panel { - flex: 0 0 120px; - height: 120px; - min-height: 120px; - max-height: 120px; - display: flex; - flex-direction: column; - overflow: hidden; - border-top: 1px solid var(--border); -} - -/* Variable-height panel with scroll */ -.variable-panel { - flex: 1 1 auto; - min-height: 150px; - display: flex; - flex-direction: column; - overflow: hidden; -} - -.variable-panel-content { - flex: 1 1 auto; - min-height: 0; - overflow-y: scroll; -} -``` - -### Status Badges - -```css -.status-badge { - font-size: 11px; - font-weight: 700; - padding: 6px 12px; - border-radius: 6px; - text-transform: uppercase; -} - -.status-badge.running { - background: rgba(var(--primary-rgb), 0.15); - color: var(--primary); -} - -.status-badge.completed { - background: rgba(var(--success-rgb), 0.15); - color: var(--success); -} - -.status-badge.error { - background: rgba(var(--error-rgb), 0.15); - color: var(--error); -} - -.status-badge.pending { - background: var(--surface); - color: var(--text-secondary); -} -``` - -### Theme Variables Required - -Every theme MUST define these CSS variables: - -```css -[data-theme="your-theme"] { - /* Backgrounds */ - --bg: #0a0a0a; - --surface: #161616; - --surface-hover: #1e1e1e; - - /* Borders */ - --border: #2a2a2a; - --border-light: #3a3a3a; - --border-hover: #4a4a4a; - - /* Text */ - --text: #ffffff; - --text-secondary: #888888; - --text-tertiary: #666666; - - /* Primary (accent) */ - --primary: #c5f82a; - --primary-hover: #d4ff3a; - --primary-light: rgba(197, 248, 42, 0.15); - - /* Status colors */ - --success: #22c55e; - --warning: #f59e0b; - --error: #ef4444; - --info: #3b82f6; -} -``` - -### Component Checklist for New Screens - -When creating a new screen, ensure it has: - -- [ ] Full-height container with `overflow: hidden` -- [ ] No global page scroll -- [ ] List panel with visible scrollbar (if applicable) -- [ ] Detail panel with fixed layout -- [ ] Cards with status indicator bar -- [ ] Status dots/badges using standard classes -- [ ] Tree sections if showing parent-child relationships -- [ ] Fixed terminal/status panels at bottom -- [ ] Variable content area with internal scroll - -### Alert Infrastructure (Bell Notifications) - -Use `window.GBAlerts` for app notifications that appear in the global bell icon: - -```javascript -// Task completed (with optional app URL) -window.GBAlerts.taskCompleted("My App", "/apps/my-app/"); - -// Email notification -window.GBAlerts.newEmail("john@example.com", "Meeting tomorrow"); - -// Chat message -window.GBAlerts.newChat("John", "Hey, are you there?"); - -// Drive sync -window.GBAlerts.driveSync("report.pdf", "uploaded"); - -// Calendar reminder -window.GBAlerts.calendarReminder("Team Meeting", "15 minutes"); - -// Error -window.GBAlerts.error("Drive", "Failed to sync file"); - -// Generic notification -window.GBAlerts.add("Title", "Message", "success", "🎉"); -``` - -All notifications appear in the bell dropdown with sound (if enabled). - ---- - -## Remember +## 🔑 REMEMBER - **ZERO WARNINGS** - Every clippy warning must be fixed - **NO ALLOW IN CODE** - Never use #[allow()] in source files -- **CARGO.TOML EXCEPTIONS OK** - Disable lints with false positives in Cargo.toml with comment -- **NO DEAD CODE** - Delete unused code, never prefix with _ -- **NO UNWRAP/EXPECT** - Use ? operator or proper error handling -- **INLINE FORMAT ARGS** - format!("{name}") not format!("{}", name) -- **USE SELF** - In impl blocks, use Self not the type name -- **DERIVE EQ** - Always derive Eq with PartialEq -- **DISPLAY NOT TOSTRING** - Implement Display, not ToString -- **USE DIAGNOSTICS** - Use IDE diagnostics tool, never call cargo clippy directly -- **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**: Always 6.1.0 - do not change without approval -- **Theme system**: Use data-theme attribute on body, 6 themes available -- **Session Continuation**: When running out of context, create detailed summary: (1) what was done, (2) what remains, (3) specific files and line numbers, (4) exact next steps. \ No newline at end of file +- **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 \ No newline at end of file diff --git a/src/ui_server/mod.rs b/src/ui_server/mod.rs index a62797b..e2148da 100644 --- a/src/ui_server/mod.rs +++ b/src/ui_server/mod.rs @@ -61,6 +61,7 @@ const SUITE_DIRS: &[&str] = &[ "billing", "products", "tickets", + "about", ]; pub async fn index() -> impl IntoResponse { diff --git a/ui/suite/about/about.css b/ui/suite/about/about.css new file mode 100644 index 0000000..209c394 --- /dev/null +++ b/ui/suite/about/about.css @@ -0,0 +1,2 @@ +/* About page styles - most styles are inline in about.html */ +/* This file is for additional customization if needed */ diff --git a/ui/suite/about/about.html b/ui/suite/about/about.html new file mode 100644 index 0000000..74d54d8 --- /dev/null +++ b/ui/suite/about/about.html @@ -0,0 +1,571 @@ + + +
+ +
+ +

General Bots

+

AI-Powered Agentic Office Suite

+
+ Version + 6.1.0 +
+
+ + +
+
+
+ + + + + +
+

Architecture

+

Rust-based high-performance server with HTMX-powered reactive UI

+
+ +
+
+ + + + + + + + + + + +
+

Multi-Agent AI

+

Collaborative AI agents with specialized roles for complex task automation

+
+ +
+
+ + + + + +
+

Modular Design

+

Feature-gated compilation for minimal binary size and resource usage

+
+ +
+
+ + + + +
+

Enterprise Security

+

RBAC, SOC 2 compliance ready, multi-tenant architecture

+
+
+ + +
+

Feature Matrix

+ +
+

+ + + + Compiled Features +

+

Features included in this build

+
+ chat + drive + tasks + automation + cache + directory +
+
+ +
+

+ + + + + Enabled Apps +

+

Applications active for this instance

+
+ chat + drive + tasks +
+
+ +
+

+ + + + + + Not Compiled / Disabled +

+

Features not included or disabled in configuration

+
+ Loading... +
+
+
+ + +
+

Feature Dependency Tree

+

How features relate to each other

+
+ Feature Dependency Tree +
+
+ + +
+

System Information

+
+
+ Platform + Rust + Axum + HTMX +
+
+ Database + PostgreSQL + Diesel ORM +
+
+ Cache + Redis +
+
+ Vector DB + Qdrant (optional) +
+
+ License + AGPL-3.0 +
+
+ Documentation + docs.pragmatismo.com.br +
+
+
+ + +
+

Resources

+ +
+ + +
+ +

Built with ❤️ by Pragmatismo

+
+
+ + diff --git a/ui/suite/about/feature-tree.svg b/ui/suite/about/feature-tree.svg new file mode 100644 index 0000000..75554ab --- /dev/null +++ b/ui/suite/about/feature-tree.svg @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + General Bots Feature Dependency Tree + Cargo.toml Feature Flags and Dependencies + + + + + Legend + + Core Technology + + Application + + Bundle (group) + + + + CORE TECHNOLOGIES + + + + + cache + redis + + + + + + automation + rhai, cron + + + + + + llm + + + + + + vectordb + qdrant + + + + + + monitoring + sysinfo + + + + + + directory + + + + PRODUCTIVITY + + + + + tasks + cron + + + + + + + + calendar + + + + + + project + quick-xml + + + + + + goals + + + + COMMUNICATION + + + + + chat + + + + + + mail + lettre,imap + + + + + + meet + livekit + + + + + + people + + + + DOCUMENTS + + + + + drive + aws-s3 + + + + + + docs + docx-rs + + + + + + sheet + calamine + + + + + + slides + ooxmlsdk + + + + + + paper + pdf-extract + + + + + RESEARCH & LEARNING + + + + + research + + + + + + + + learn + + + + + + sources + + + + ADMIN & ANALYTICS + + + + + analytics + + + + + + dashboards + + + + + + admin + + + + + + settings + + + + DEVELOPMENT + + + + + designer + + + + + + editor + + + + + + console + crossterm + + + + + BUNDLE FEATURES + + + + + communications + + + + + + + + + productivity + + + + + + + + + documents + + + + + + + + + + full + + diff --git a/ui/suite/js/base.js b/ui/suite/js/base.js index 2cd818b..0b43021 100644 --- a/ui/suite/js/base.js +++ b/ui/suite/js/base.js @@ -42,7 +42,25 @@ function applyProductConfig(config) { // Filter apps based on enabled list if (config.apps && Array.isArray(config.apps)) { - filterAppsByConfig(config.apps); + let effectiveApps = config.apps; + + // Check if we have compiled_features info to filter even further + // This ensures we don't show apps that are enabled in config but not compiled in binary + if (config.compiled_features && Array.isArray(config.compiled_features)) { + const compiledSet = new Set(config.compiled_features.map(f => f.toLowerCase())); + effectiveApps = effectiveApps.filter(app => + compiledSet.has(app.toLowerCase()) || + app.toLowerCase() === 'settings' || + app.toLowerCase() === 'auth' || + app.toLowerCase() === 'admin' // Admin usually contains settings which is always there + ); + + // Also call a helper to hide UI elements for non-compiled features explicitly + // This handles features that might not be "apps" but are UI sections + hideNonCompiledUI(compiledSet); + } + + filterAppsByConfig(effectiveApps); } // Apply custom logo @@ -74,6 +92,28 @@ function applyProductConfig(config) { } } +// Hide UI elements that require features not compiled in the binary +function hideNonCompiledUI(compiledSet) { + // Hide elements with data-feature attribute that aren't in compiled set + document.querySelectorAll('[data-feature]').forEach(el => { + const feature = el.getAttribute('data-feature').toLowerCase(); + // Allow settings/admin as they are usually core + if (!compiledSet.has(feature) && feature !== 'settings' && feature !== 'admin') { + el.style.display = 'none'; + el.classList.add('hidden-uncompiled'); + } + }); + + // Also look for specific sections that might map to features + // e.g. .feature-mail, .feature-meet classes + compiledSet.forEach(feature => { + // This loop defines what IS available. + // Logic should be inverse: find all feature- classes and hide if not in set + // But scanning all classes is expensive. + // Better to rely on data-feature or explicit app hiding which filterAppsByConfig does. + }); +} + // Filter visible apps based on enabled list function filterAppsByConfig(enabledApps) { const enabledSet = new Set(enabledApps.map((a) => a.toLowerCase())); diff --git a/ui/suite/settings/index.html b/ui/suite/settings/index.html index 5db97ec..2a76a2e 100644 --- a/ui/suite/settings/index.html +++ b/ui/suite/settings/index.html @@ -6,7 +6,9 @@
- + + Settings
@@ -44,7 +46,9 @@ - + + Language @@ -121,7 +125,9 @@ - + + DNS @@ -135,6 +141,15 @@ Audit Log + + + + + + + About + -
+
@@ -174,7 +187,8 @@