Remove BOTCODE files

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-03-18 08:48:04 -03:00
parent bfc9ced932
commit 4900274887
39 changed files with 974 additions and 4810 deletions

View file

@ -1 +0,0 @@
export NGROK_AUTHTOKEN=2f3uA0WXL3aDxjABuSWpYTWjjh5_2pqnDyrc7CU4o92UzocEt

View file

@ -1,106 +0,0 @@
name: BotServer CI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
env:
CARGO_BUILD_JOBS: 4
CARGO_NET_RETRY: 10
jobs:
build:
runs-on: gbo
steps:
- name: Disable SSL verification
run: git config --global http.sslVerify false
- name: Checkout BotServer Code
uses: actions/checkout@v4
with:
path: botserver
- name: Setup Workspace
run: |
git clone --depth 1 --branch main https://alm.pragmatismo.com.br/GeneralBots/gb.git workspace
cd workspace
git submodule update --init --depth 1 botlib
git submodule update --init --depth 1 botui
# Remove all members except botserver and botlib from workspace
sed -i '/"botapp",/d' Cargo.toml
sed -i '/"botdevice",/d' Cargo.toml
sed -i '/"bottest",/d' Cargo.toml
sed -i '/"botui",/d' Cargo.toml
sed -i '/"botbook",/d' Cargo.toml
sed -i '/"botmodels",/d' Cargo.toml
sed -i '/"botplugin",/d' Cargo.toml
sed -i '/"bottemplates",/d' Cargo.toml
cd ..
rm -rf workspace/botserver
mv botserver workspace/botserver
- name: Cache Busting
run: |
TS=$(date +%s)
cd workspace/botui/ui/suite/chat
mv chat.css chat.$TS.css
mv chat.js chat.$TS.js
sed -i "s/chat.css/chat.$TS.css/g" chat.html
sed -i "s/chat.js/chat.$TS.js/g" chat.html
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpq-dev libssl-dev liblzma-dev pkg-config
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Install sccache
run: |
wget https://github.com/mozilla/sccache/releases/download/v0.8.2/sccache-v0.8.2-x86_64-unknown-linux-musl.tar.gz
tar xzf sccache-v0.8.2-x86_64-unknown-linux-musl.tar.gz
mv sccache-v0.8.2-x86_64-unknown-linux-musl/sccache $HOME/.cargo/bin/sccache
chmod +x $HOME/.cargo/bin/sccache
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
$HOME/.cargo/bin/sccache --start-server || true
- name: Setup environment
run: sudo cp /opt/gbo/bin/system/.env . 2>/dev/null || true
- name: Build BotServer
working-directory: workspace
run: |
cargo build -p botserver -j 8 2>&1 | tee /tmp/build.log
ls -lh target/debug/botserver
sccache --show-stats || true
- name: Save build log
if: always()
run: |
sudo mkdir -p /opt/gbo/logs
sudo cp /tmp/build.log /opt/gbo/logs/botserver-$(date +%Y%m%d-%H%M%S).log || true
- name: Deploy
working-directory: workspace
run: |
lxc exec bot:pragmatismo-system -- systemctl stop system || true
# Deploy Binary
sudo cp target/debug/botserver /opt/gbo/bin/system/
sudo chmod +x /opt/gbo/bin/system/botserver
# Deploy UI Assets (botui)
sudo mkdir -p /opt/gbo/bin/system/botui/ui
sudo cp -r botui/ui/suite /opt/gbo/bin/system/botui/ui/
sudo cp -r botui/ui/themes /opt/gbo/bin/system/botui/ui/ || true
lxc exec bot:pragmatismo-system -- systemctl start system || true

View file

@ -1,931 +0,0 @@
# Multi-Agent Task Management UI — Implementation Plan
> **Unifying `auto_task`, `tasks`, `designer` → Draggable Multi-Agent Windows**
---
## 1. High-Level Vision (from Screenshots)
The user wants a **desktop-like environment** with these elements:
### Layout Components
```
┌──────┬──────────────────────────────────────────────────────┐
│ │ [Tasks ⚙ 👤] ← Top Left Mini Bar (fixed) │
│ SIDE │ │
│ BAR │ ┌─────────────────────┐ ┌────────────────────────┐ │
│ │ │ PRIMARY WINDOW │ │ SECONDARY WINDOW │ │
│ (far │ │ "Tasks" │ │ "Agents & Workspaces" │ │
│ left)│ │ Tabs: │ │ (can be minimized) │ │
│ │ │ - // DASHBOARD │ │ │ │
│ /chat│ │ - // TASK #N │ │ Agent cards, quota │ │
│/drive│ │ │ │ monitors, workspace │ │
│ etc. │ │ PLAN|BUILD|REVIEW| │ │ assignment │ │
│ │ │ DEPLOY|MONITOR tabs │ │ │ │
│ │ │ │ │ │ │
│ │ │ Draggable task cards│ │ │ │
│ │ │ with sub-tasks, │ │ │ │
│ │ │ logs, output, chat │ │ │ │
│ │ └─────────────────────┘ └────────────────────────┘ │
│ │ │
│ │ ┌───────────────────────────────────────────────┐ │
│ │ │ // Chat (shared chat at bottom) │ │
│ │ │ TIP: Describe your project... │ │
│ │ └───────────────────────────────────────────────┘ │
│ ├──────────────────────────────────────────────────────┤
│ │ [Taskbar: open windows] [Clock] [Date] │
└──────┴──────────────────────────────────────────────────────┘
```
### Key Rules from User Request
1. **Sidebar** → Far left (already exists in `desktop.html`, keep it)
2. **Top-left mini bar** → Fixed bar with "Tasks" label, ⚙ Settings icon, 👤 Account icon. **Remove Mantis logo**.
3. **Where it reads "Mantis" → read "Tasks"** (generic rename throughout)
4. **Primary Window: "Tasks"** → Two tabs:
- **// DASHBOARD** — Overview with Task #N agent card, DNA info, tokens, activity
- **// TASK #N** (project view) — PLAN | BUILD | REVIEW | DEPLOY | MONITOR pipeline tabs, with draggable task cards showing sub-tasks, logs, output
5. **Secondary Window: "Agents & Workspaces"** → Shows agent roster, quota monitors, workspace assignments. Can be minimized.
6. **Chat panel** → Shared at bottom of task view, project-scoped
7. **All windows** → Draggable, resizable, use existing `WindowManager`
8. **VibCode integration** → Multi-draggable agents like the designer canvas
---
## 2. Codebase Inventory & Current State
### Frontend (botui/ui/suite)
| File/Dir | Purpose | Lines | Status |
|----------|---------|-------|--------|
| `desktop.html` | Main desktop shell, sidebar, tabs, workspace | 281 | ✅ Keep as shell |
| `js/window-manager.js` | Window open/close/drag/minimize/maximize | 296 | 🔧 Extend |
| `tasks/tasks.html` | Current task list + detail panel | 318 | 🔄 Refactor into new primary window |
| `tasks/tasks.js` | Task JS (3297 lines) | 3297 | 🔄 Refactor (heavy) |
| `tasks/tasks.css` | Task styles (70k+) | ~2400 | 🔄 Refactor/extend |
| `tasks/autotask.html` | AutoTask standalone UI | 484 | 🔄 Merge into primary window |
| `tasks/autotask.js` | AutoTask JS (2201 lines) | 2201 | 🔄 Merge |
| `tasks/autotask.css` | AutoTask styles | ~1200 | 🔄 Merge |
| `tasks/progress-panel.html` | Floating progress panel | 133 | 🔄 Keep as sub-component |
| `tasks/progress-panel.js` | Progress panel JS | ~550 | ✅ Keep |
| `tasks/intents.html` | Intents listing | ~400 | 🔄 Merge |
| `designer.html` | Visual .bas designer (node canvas) | 2718 | 📎 Reference for drag patterns |
| `designer.js` | Designer JS (nodes, connections, drag) | 921 | 📎 Reference for drag |
| `designer.css` | Designer styles | 500 | 📎 Reference |
| `partials/tasks.html` | Alternative tasks partial | 318 | 🔄 Will be replaced by new entry |
### Backend (botserver/src)
| File/Dir | Purpose | Lines | Status |
|----------|---------|-------|--------|
| `auto_task/autotask_api.rs` | AutoTask CRUD + execution API | 2302 | ✅ Keep (API stable) |
| `auto_task/task_types.rs` | AutoTask data types | 423 | ✅ Keep |
| `auto_task/task_manifest.rs` | Manifest tracking (progress tree) | 977 | ✅ Keep |
| `auto_task/app_generator.rs` | App generation from LLM | 3587 | ✅ Keep |
| `auto_task/intent_classifier.rs` | Intent classification | 1200+ | ✅ Keep |
| `auto_task/intent_compiler.rs` | Intent → plan compilation | 900+ | ✅ Keep |
| `auto_task/mod.rs` | Routes + WebSocket handlers | 293 | 🔧 Add new agent/workspace endpoints |
| `tasks/task_api/handlers.rs` | Task CRUD handlers | 393 | 🔧 Extend with agent-aware responses |
| `tasks/task_api/html_renderers.rs` | HTML card rendering | 700+ | 🔧 Update HTML to new design |
| `tasks/types.rs` | Task data types | 223 | 🔧 Add agent fields |
| `tasks/scheduler.rs` | Task scheduler (cron etc.) | 503 | ✅ Keep |
| `designer/workflow_canvas.rs` | Workflow design types | 421 | 📎 Reference |
| `designer/designer_api/` | Designer API handlers | ~200 | 📎 Reference |
---
## 3. Implementation Phases
### Phase 0: Terminology Rename (Mantis → Tasks/Agent)
**Scope**: All UI references
**Effort**: ~30 min
| What | Where | Change |
|------|-------|--------|
| "Mantis #1" | All HTML templates | → "Agent #1" |
| "MANTIS MANAGER" | Task cards | → "AGENT MANAGER" |
| Mantis logo/icon | Top bar, cards | → Remove, use ⚡ or 🤖 icon |
| "mantis" CSS classes | tasks CSS | → Rename to `agent-*` |
| Variable names | tasks.js, autotask.js | → `agent*` where needed |
**Files to modify**:
- `botui/ui/suite/tasks/tasks.html` — template references
- `botui/ui/suite/tasks/tasks.js` — variable names
- `botui/ui/suite/tasks/tasks.css` — class names
- `botui/ui/suite/tasks/autotask.html` — template references
- `botui/ui/suite/tasks/autotask.js` — variable names
- `botserver/src/tasks/task_api/html_renderers.rs` — server-rendered HTML
---
### Phase 1: Top-Left Mini Bar (Fixed)
**Scope**: New component added to `desktop.html`
**Effort**: ~45 min
Create a fixed top-left panel (anchored above sidebar) matching screenshot:
```
┌──────────────────────┐
│ Tasks ⚙️ 👤 │
└──────────────────────┘
```
#### 1.1 New file: `botui/ui/suite/partials/minibar.html`
```html
<div class="gb-minibar" id="gb-minibar">
<span class="minibar-title">Tasks</span>
<div class="minibar-actions">
<button class="minibar-btn" id="btn-open-settings"
title="Settings" onclick="openSettingsWindow()">
<!-- SVG gear icon -->
</button>
<button class="minibar-btn" id="btn-open-account"
title="Account" onclick="openAccountWindow()">
<!-- SVG user icon -->
</button>
</div>
</div>
```
#### 1.2 CSS additions in `desktop.html <style>` or new `css/minibar.css`
```css
.gb-minibar {
position: fixed;
top: 0;
left: 51px; /* right of sidebar */
height: 34px;
display: flex;
align-items: center;
padding: 0 12px;
gap: 8px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
z-index: 200;
font-family: 'Fira Code', monospace;
font-size: 13px;
font-weight: 600;
}
.minibar-title { color: var(--text); }
.minibar-actions { display: flex; gap: 6px; }
.minibar-btn {
width: 28px; height: 28px;
border: none; background: transparent;
cursor: pointer; border-radius: 6px;
display: flex; align-items: center; justify-content: center;
transition: background 0.15s;
}
.minibar-btn:hover { background: var(--bg-hover); }
.minibar-btn svg { width: 16px; height: 16px; stroke: var(--text-secondary); }
```
#### 1.3 Integration in `desktop.html`
- Add minibar HTML after sidebar, before main-wrapper
- Adjust `.main-wrapper` top padding to account for minibar height
---
### Phase 2: Primary Window — "Tasks" (Dashboard + Project Tabs)
**Scope**: Major refactor of `tasks/` directory
**Effort**: ~4-6 hours
This is the central window. It unifies the old `tasks.html` and `autotask.html` into one coherent window with two tab modes:
#### 2.1 New file: `botui/ui/suite/tasks/task-window.html`
Main entry point loaded by `WindowManager.open('tasks', 'Tasks', html)`.
Structure:
```html
<link rel="stylesheet" href="/suite/tasks/task-window.css" />
<div class="task-window" id="task-window">
<!-- Tab Bar: DASHBOARD | TASK #N -->
<div class="task-window-tabs" id="task-window-tabs">
<button class="tw-tab active" data-tab="dashboard"
onclick="switchTaskTab('dashboard')">
// DASHBOARD
</button>
<!-- Dynamic task tabs appear here -->
</div>
<!-- Tab Content -->
<div class="task-window-content" id="task-window-content">
<!-- Dashboard tab (default) -->
<div class="tw-panel active" id="tw-panel-dashboard">
<!-- Agent overview cards, stats, recent activity -->
</div>
</div>
</div>
<script src="/suite/tasks/task-window.js"></script>
```
#### 2.2 Dashboard Tab Content (`tw-panel-dashboard`)
Based on "Agent #1" screenshot:
```html
<div class="tw-dashboard">
<!-- Overview section -->
<section class="agent-overview">
<div class="agent-card">
<div class="agent-header">
<span class="agent-icon"></span>
<h2 class="agent-name">Agent #1</h2>
<button class="agent-edit-btn">✏️</button>
</div>
<div class="agent-meta">
<div class="meta-row">
<span class="meta-label">Status</span>
<span class="meta-value status-active">● Active</span>
</div>
<div class="meta-row">
<span class="meta-label">DNA</span>
<span class="meta-value">
<a href="#" class="meta-link">Manage Subscription</a>
</span>
</div>
<div class="meta-stats">
<div class="stat-item">
<span class="stat-label">Renewal</span>
<span class="stat-value" id="agent-renewal"></span>
</div>
<div class="stat-item">
<span class="stat-label">Created</span>
<span class="stat-value" id="agent-created"></span>
</div>
<div class="stat-item">
<span class="stat-label">Tokens Used</span>
<span class="stat-value" id="agent-tokens"></span>
</div>
<div class="stat-item">
<span class="stat-label">Tasks Completed</span>
<span class="stat-value" id="agent-tasks-done"></span>
</div>
</div>
</div>
</div>
<!-- Action buttons -->
<div class="agent-actions">
<button class="action-btn" onclick="parkAgent()">// PARK</button>
<button class="action-btn" onclick="cloneAgent()">// CLONE</button>
<button class="action-btn" onclick="exportAgent()">// EXPORT</button>
<button class="action-btn disabled">// DELETE</button>
</div>
</section>
<!-- Assigned Job section -->
<section class="assigned-job" id="assigned-job">
<h3>Assigned Job</h3>
<div class="job-card" hx-get="/api/ui/tasks/current-job"
hx-trigger="load" hx-swap="innerHTML">
<!-- Loaded dynamically -->
</div>
</section>
<!-- Recent Activity -->
<section class="recent-activity" id="recent-activity">
<h3>Recent Activity</h3>
<div class="activity-list" hx-get="/api/ui/tasks/activity"
hx-trigger="load, every 15s" hx-swap="innerHTML">
<!-- Activity items loaded dynamically -->
</div>
</section>
</div>
```
#### 2.3 Project Tab Content (Opens when clicking "Open Project")
Based on the multi-agent task cards screenshot with PLAN|BUILD|REVIEW|DEPLOY|MONITOR:
```html
<div class="tw-project" id="tw-project-{project_id}">
<!-- Top breadcrumb -->
<div class="project-breadcrumb">
<span>// DASHBOARD</span> <span>></span>
<span class="project-name">// {PROJECT_NAME}</span>
</div>
<!-- Pipeline Tabs -->
<div class="pipeline-tabs">
<button class="pipeline-tab" data-phase="plan">// PLAN</button>
<button class="pipeline-tab active" data-phase="build">// BUILD</button>
<button class="pipeline-tab" data-phase="review">// REVIEW</button>
<button class="pipeline-tab" data-phase="deploy">// DEPLOY</button>
<button class="pipeline-tab" data-phase="monitor">// MONITOR</button>
</div>
<!-- Zoomable Canvas with draggable task cards -->
<div class="task-canvas" id="task-canvas-{project_id}">
<div class="canvas-controls">
<button onclick="zoomIn()">🔍+</button>
<span class="zoom-level">100%</span>
<button onclick="zoomOut()">🔍-</button>
</div>
<div class="canvas-inner" id="canvas-inner-{project_id}">
<!-- Draggable task cards rendered here -->
</div>
</div>
<!-- Shared Chat Panel (bottom) -->
<div class="project-chat" id="project-chat">
<div class="chat-header">// Chat <button class="chat-download"></button></div>
<div class="chat-body" id="project-chat-body">
<div class="chat-tip">
💚 TIP: Describe your project. The more detail, the better the plan.
</div>
<!-- Chat messages -->
</div>
<div class="chat-input-area">
<input type="text" placeholder="Describe what you need..."
id="project-chat-input" />
<button class="chat-send" onclick="sendProjectChat()">Send</button>
</div>
</div>
</div>
```
#### 2.4 Draggable Task Cards on Canvas
Each task card (matching the screenshot) is a draggable element:
```html
<div class="task-card draggable" data-task-id="{id}"
style="left: {x}px; top: {y}px;">
<div class="task-card-drag-handle"></div>
<div class="task-card-badge">// TASK</div>
<h3 class="task-card-title">{title}</h3>
<div class="task-card-stats">
<span>{file_count} files</span>
<span>{duration}</span>
<span>~{token_count} tokens</span>
</div>
<p class="task-card-desc">{description}</p>
<div class="task-card-status">
<span class="status-label">Status</span>
<span class="status-value">● {status}</span>
</div>
<!-- Agent Manager section -->
<div class="task-agent-section">
<div class="agent-label">// AGENT MANAGER</div>
<div class="agent-row">
<span class="agent-dot"></span>
<span class="agent-name">Agent #1</span>
<div class="agent-capabilities">
<!-- capability icons -->
</div>
<span class="agent-level">EVOLVED</span>
</div>
</div>
<!-- Collapsible sections -->
<details class="task-detail-section">
<summary>// SUB-TASKS</summary>
<div class="sub-tasks-content" hx-get="/api/ui/tasks/{id}/subtasks"
hx-trigger="toggle" hx-swap="innerHTML"></div>
</details>
<details class="task-detail-section">
<summary>// LOGS</summary>
<div class="logs-content"></div>
</details>
<details class="task-detail-section">
<summary>// OUTPUT</summary>
<div class="output-content"></div>
</details>
</div>
```
#### 2.5 New file: `botui/ui/suite/tasks/task-window.js`
Core logic consolidated from `tasks.js` and `autotask.js`:
```javascript
// task-window.js
// Unified Task Window Manager
const TaskWindow = {
activeTab: 'dashboard',
openProjects: new Map(), // projectId -> project data
wsConnection: null,
init() { ... },
switchTab(tabId) { ... },
openProject(projectId, projectName) { ... },
closeProject(projectId) { ... },
// Dashboard
loadDashboard() { ... },
loadAgentOverview() { ... },
loadRecentActivity() { ... },
// Project Canvas
initCanvas(projectId) { ... },
loadTaskCards(projectId) { ... },
makeCardsDraggable(canvasEl) { ... }, // Uses designer.js patterns
switchPipelinePhase(phase) { ... },
// WebSocket
initWebSocket() { ... }, // Reuses existing WS from tasks.js
handleProgressMessage(data) { ... },
// Chat
initProjectChat(projectId) { ... },
sendProjectChat() { ... },
};
```
Key functions to port from existing files:
- From `tasks.js`: `initWebSocket()`, `handleWebSocketMessage()`, `renderManifestProgress()`, `buildProgressTreeHTML()`, `startTaskPolling()`
- From `autotask.js`: `handleTaskProgressMessage()`, `onTaskStarted()`, `onTaskProgress()`, `selectIntent()`, `loadIntentDetail()`
- From `designer.js`: `initDragAndDrop()`, `startNodeDrag()`, canvas pan/zoom
#### 2.6 New file: `botui/ui/suite/tasks/task-window.css`
Consolidated and pixel-perfect styles. Key sections:
```css
/* Task Window Container */
.task-window { ... }
/* Tab Bar (DASHBOARD / TASK #N) */
.task-window-tabs { ... }
.tw-tab { ... }
.tw-tab.active { ... }
/* Dashboard */
.tw-dashboard { ... }
.agent-overview { ... }
.agent-card { ... }
.agent-actions { ... }
.assigned-job { ... }
.recent-activity { ... }
/* Project View */
.tw-project { ... }
.project-breadcrumb { ... }
.pipeline-tabs { ... }
.pipeline-tab { ... }
/* Task Canvas (zoomable, pannable) */
.task-canvas { ... }
.canvas-inner { ... }
/* Draggable Task Cards */
.task-card { ... }
.task-card.dragging { ... }
.task-card-badge { ... }
.task-agent-section { ... }
/* Shared Chat */
.project-chat { ... }
```
---
### Phase 3: Secondary Window — "Agents & Workspaces"
**Scope**: New component
**Effort**: ~2-3 hours
Auto-opens alongside the primary Tasks window. Can be minimized.
#### 3.1 New file: `botui/ui/suite/tasks/agents-window.html`
```html
<link rel="stylesheet" href="/suite/tasks/agents-window.css" />
<div class="agents-window" id="agents-window">
<!-- Header -->
<div class="aw-header">
<h3>Agents & Workspaces</h3>
</div>
<!-- Agent Cards -->
<section class="aw-agents" id="aw-agents"
hx-get="/api/ui/agents/list" hx-trigger="load, every 30s"
hx-swap="innerHTML">
<!-- Agent cards loaded dynamically -->
</section>
<!-- Workspace List -->
<section class="aw-workspaces" id="aw-workspaces">
<h4>Active Workspaces</h4>
<div class="workspace-list" hx-get="/api/ui/workspaces/list"
hx-trigger="load" hx-swap="innerHTML">
<!-- Workspace items -->
</div>
</section>
<!-- Quota Monitor -->
<section class="aw-quota" id="aw-quota">
<h4>Quota Monitor</h4>
<div class="quota-details">
<div class="quota-row">
<span>All Models</span>
<span class="quota-value">90%</span>
<div class="quota-bar">
<div class="quota-fill" style="width: 90%"></div>
</div>
</div>
<div class="quota-stats">
<span>Runtime: <strong id="aw-runtime">10m 15s</strong></span>
<span>Token Consumption: <strong id="aw-tokens">13k</strong></span>
</div>
<div class="quota-changes">
<span class="change added">Added <strong>+510</strong></span>
<span class="change removed">Removed <strong>+510</strong></span>
</div>
</div>
</section>
</div>
<script src="/suite/tasks/agents-window.js"></script>
```
#### 3.2 New file: `botui/ui/suite/tasks/agents-window.js`
```javascript
const AgentsWindow = {
init() { ... },
loadAgents() { ... },
loadWorkspaces() { ... },
updateQuotaMonitor(data) { ... },
assignAgentToTask(agentId, taskId) { ... },
};
```
#### 3.3 New file: `botui/ui/suite/tasks/agents-window.css`
Styles matching the secondary window screenshot with agent cards, quota bars, etc.
---
### Phase 4: Window Manager Enhancements
**Scope**: `js/window-manager.js`
**Effort**: ~2 hours
#### 4.1 Add `openPair()` method
Opens primary + secondary windows side by side when Tasks is launched:
```javascript
openPair(primaryId, primaryTitle, primaryHtml,
secondaryId, secondaryTitle, secondaryHtml) {
// Open primary window (left, 60% width)
this.open(primaryId, primaryTitle, primaryHtml);
const primaryEl = document.getElementById(`window-${primaryId}`);
primaryEl.style.left = '0px';
primaryEl.style.top = '0px';
primaryEl.style.width = '60%';
primaryEl.style.height = 'calc(100% - 50px)';
// Open secondary window (right, 40% width, minimizable)
this.open(secondaryId, secondaryTitle, secondaryHtml);
const secondaryEl = document.getElementById(`window-${secondaryId}`);
secondaryEl.style.left = '60%';
secondaryEl.style.top = '0px';
secondaryEl.style.width = '40%';
secondaryEl.style.height = 'calc(100% - 50px)';
}
```
#### 4.2 Improve `makeResizable()`
Replace CSS `resize: both` with proper resize handles (8-directional):
```javascript
makeResizable(windowEl) {
const handles = ['n','e','s','w','ne','nw','se','sw'];
handles.forEach(dir => {
const handle = document.createElement('div');
handle.className = `resize-handle resize-${dir}`;
windowEl.appendChild(handle);
// Add mousedown handler for each direction
});
}
```
#### 4.3 Add snap-to-edge behavior
When a window is dragged to the screen edge, snap to fill half:
```javascript
// In onMouseUp:
if (newLeft < 10) snapToLeft(windowEl);
if (newLeft + windowEl.offsetWidth > workspace.offsetWidth - 10) snapToRight(windowEl);
```
#### 4.4 Add `openAsSecondary()` method
Opens a window in minimized-ready state:
```javascript
openAsSecondary(id, title, htmlContent) {
this.open(id, title, htmlContent);
// Mark as secondary (can be auto-minimized)
const windowObj = this.openWindows.find(w => w.id === id);
windowObj.isSecondary = true;
}
```
---
### Phase 5: Backend API Extensions
**Scope**: `botserver/src/auto_task/` and `botserver/src/tasks/`
**Effort**: ~3 hours
#### 5.1 New Agent Management Endpoints
Add to `botserver/src/auto_task/mod.rs` route configuration:
```rust
// New routes
.route("/api/ui/agents/list", get(list_agents_handler))
.route("/api/ui/agents/:id", get(get_agent_handler))
.route("/api/ui/agents/:id/park", post(park_agent_handler))
.route("/api/ui/agents/:id/clone", post(clone_agent_handler))
.route("/api/ui/agents/:id/export", get(export_agent_handler))
.route("/api/ui/workspaces/list", get(list_workspaces_handler))
.route("/api/ui/tasks/current-job", get(current_job_handler))
.route("/api/ui/tasks/activity", get(recent_activity_handler))
.route("/api/ui/tasks/:id/subtasks", get(task_subtasks_handler))
```
#### 5.2 New file: `botserver/src/auto_task/agent_api.rs`
Agent management handlers:
```rust
pub async fn list_agents_handler(...) -> impl IntoResponse { ... }
pub async fn get_agent_handler(...) -> impl IntoResponse { ... }
pub async fn park_agent_handler(...) -> impl IntoResponse { ... }
pub async fn clone_agent_handler(...) -> impl IntoResponse { ... }
// Returns HTML fragments (HTMX pattern)
```
#### 5.3 Extend `task_types.rs` with Agent concept
```rust
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Agent {
pub id: Uuid,
pub name: String,
pub status: AgentStatus,
pub capabilities: Vec<AgentCapability>,
pub level: AgentLevel, // Evolved, etc.
pub quota: QuotaInfo,
pub assigned_tasks: Vec<Uuid>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentStatus { Active, Parked, Cloning }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentCapability { Code, Design, Data, Web, API, ML }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentLevel { Basic, Standard, Evolved, Superior }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QuotaInfo {
pub model_usage_percent: f64,
pub runtime_seconds: u64,
pub tokens_consumed: u64,
pub items_added: i64,
pub items_removed: i64,
}
```
#### 5.4 Extend WebSocket for multi-agent updates
In `handle_task_progress_websocket()`, add agent status broadcasts:
```rust
// New message types:
"agent_status_update" -> { agent_id, status, quota }
"workspace_update" -> { workspace_id, agents, tasks }
"project_canvas_update" -> { project_id, task_positions }
```
---
### Phase 6: Desktop Integration
**Scope**: `desktop.html` and auto-open logic
**Effort**: ~1.5 hours
#### 6.1 Modify `desktop.html` Tasks icon click
Instead of loading `tasks.html` into a single window, load the pair:
```javascript
// In desktop.html htmx:afterRequest handler
if (appId === 'tasks') {
// Fetch both HTML files
Promise.all([
fetch('/suite/tasks/task-window.html').then(r => r.text()),
fetch('/suite/tasks/agents-window.html').then(r => r.text())
]).then(([taskHtml, agentsHtml]) => {
window.wm.openPair(
'tasks', 'Tasks', taskHtml,
'agents', 'Agents & Workspaces', agentsHtml
);
});
evt.detail.isError = true; // prevent default HTMX swap
}
```
#### 6.2 Add minibar to desktop.html
Insert `minibar.html` partial via HTMX or inline.
#### 6.3 Remove old breadcrumb row
The `tabs-container` in `desktop.html` with "E-COMMERCE APP DEVELOPMENT" breadcrumb was hardcoded for demo; replace with dynamic content managed by the active window.
---
### Phase 7: Polish & Pixel-Perfect Styling
**Scope**: CSS refinement
**Effort**: ~3 hours
#### 7.1 Design System Tokens
Add to `css/theme-sentient.css`:
```css
:root {
/* Task Card Colors */
--task-badge-bg: rgba(132, 214, 105, 0.15);
--task-badge-border: #84d669;
--task-badge-text: #84d669;
/* Agent Status Colors */
--agent-active: #84d669;
--agent-parked: #f9e2af;
--agent-evolved: #84d669;
/* Pipeline Tab Colors */
--pipeline-active: var(--primary);
--pipeline-inactive: var(--text-secondary);
/* Canvas */
--canvas-grid: rgba(0,0,0,0.03);
--canvas-card-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
```
#### 7.2 Pixel-Perfect Card Styling
Task cards must match screenshots exactly:
- Monospace font (`Fira Code`) for labels
- `//` prefix on section labels (e.g., `// TASK`, `// SUB-TASKS`)
- Green dot for active status
- Collapsible sections with `▸`/`▾` toggles
- Agent capability icons row (🔧 📝 ↗ ⚙ 🛡 📊)
#### 7.3 Animations
```css
/* Card drag feedback */
.task-card.dragging {
opacity: 0.85;
transform: rotate(1deg) scale(1.02);
box-shadow: 0 8px 30px rgba(0,0,0,0.15);
z-index: 9999;
}
/* Tab switch */
.tw-panel { transition: opacity 0.2s ease; }
.tw-panel:not(.active) { opacity: 0; position: absolute; pointer-events: none; }
/* Window open */
@keyframes window-open {
from { transform: scale(0.95); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.window-element { animation: window-open 0.15s ease-out; }
```
---
## 4. File Creation & Modification Summary
### New Files to Create
| # | File | Purpose |
|---|------|---------|
| 1 | `botui/ui/suite/tasks/task-window.html` | Primary unified task window |
| 2 | `botui/ui/suite/tasks/task-window.js` | Primary window logic |
| 3 | `botui/ui/suite/tasks/task-window.css` | Primary window styles |
| 4 | `botui/ui/suite/tasks/agents-window.html` | Secondary agents/workspaces window |
| 5 | `botui/ui/suite/tasks/agents-window.js` | Secondary window logic |
| 6 | `botui/ui/suite/tasks/agents-window.css` | Secondary window styles |
| 7 | `botui/ui/suite/partials/minibar.html` | Top-left mini bar |
| 8 | `botui/ui/suite/css/minibar.css` | Mini bar styles |
| 9 | `botserver/src/auto_task/agent_api.rs` | Agent management API |
### Existing Files to Modify
| # | File | Changes |
|---|------|---------|
| 1 | `botui/ui/suite/desktop.html` | Add minibar, modify Tasks launch logic |
| 2 | `botui/ui/suite/js/window-manager.js` | Add `openPair()`, improve resize, snap |
| 3 | `botui/ui/suite/css/desktop.css` | Minibar layout adjustments |
| 4 | `botserver/src/auto_task/mod.rs` | Add agent routes, export new module |
| 5 | `botserver/src/auto_task/task_types.rs` | Add Agent, QuotaInfo types |
| 6 | `botserver/src/tasks/task_api/html_renderers.rs` | Update rendered HTML (Mantis→Agent) |
| 7 | `botui/ui/suite/css/theme-sentient.css` | Add new design tokens |
### Files to Keep (No Changes)
- `tasks/progress-panel.html` + `.js` + `.css` — reused as sub-component
- `botserver/src/auto_task/autotask_api.rs` — API stable
- `botserver/src/auto_task/app_generator.rs` — No changes needed
- `botserver/src/auto_task/task_manifest.rs` — No changes needed
- `botserver/src/tasks/scheduler.rs` — No changes needed
### Files Eventually Deprecated (Phase 8 cleanup)
- `tasks/autotask.html` → merged into `task-window.html`
- `tasks/autotask.js` → merged into `task-window.js`
- `tasks/autotask.css` → merged into `task-window.css`
- `tasks/tasks.html` → merged into `task-window.html` (keep as partial fallback)
- Original `partials/tasks.html` → replaced by `task-window.html`
---
## 5. Execution Order
```
Phase 0: Terminology Rename (Mantis → Agent/Tasks) ~30 min
Phase 1: Top-Left Mini Bar ~45 min
Phase 2: Primary Window (task-window.html/js/css) ~4-6 hrs
├─ 2.1: HTML structure
├─ 2.2: Dashboard tab
├─ 2.3: Project tab with pipeline tabs
├─ 2.4: Draggable task cards
├─ 2.5: JavaScript consolidation
└─ 2.6: CSS pixel-perfect styling
Phase 3: Secondary Window (agents-window.html/js/css) ~2-3 hrs
Phase 4: Window Manager Enhancements ~2 hrs
Phase 5: Backend API Extensions ~3 hrs
Phase 6: Desktop Integration ~1.5 hrs
Phase 7: Polish & Pixel-Perfect ~3 hrs
Total estimated: ~17-20 hours
```
---
## 6. Key Design Decisions
1. **Single-window with tabs** vs multi-window for tasks → Using **tabs within a single primary window** (Dashboard / Task #N) matching the screenshots, plus a separate secondary window for agents.
2. **Reuse WindowManager** — All windows still go through the existing WM for consistency with chat/drive/etc.
3. **Drag system from Designer** — Port the `startNodeDrag()` and canvas pan/zoom patterns from `designer.js` for the task card canvas.
4. **HTMX-first** — All data loading uses HTMX fragments from the backend, matching existing patterns in `tasks.html` and `autotask.html`.
5. **WebSocket reuse** — The existing `task_progress_websocket_handler` in `auto_task/mod.rs` is extended with new message types for agent status, not replaced.
6. **Progressive enhancement** — Old `tasks.html` remains functional as a fallback. The new `task-window.html` is the primary entry.
7. **Scoped CSS** — Each new component gets its own CSS file to avoid conflicts with existing 70k+ lines of task styles.
---
## 7. Verification Checklist
- [ ] Sidebar stays on far left
- [ ] Mini bar shows "Tasks ⚙ 👤" at top-left (no Mantis logo)
- [ ] Tasks window opens with Dashboard tab by default
- [ ] Dashboard shows Agent #1 overview (status, tokens, tasks completed)
- [ ] "Open Project" opens project tab with PLAN|BUILD|REVIEW|DEPLOY|MONITOR
- [ ] Task cards are draggable on the canvas
- [ ] Each task card has collapsible SUB-TASKS, LOGS, OUTPUT sections
- [ ] Agent Manager section shows on each task card
- [ ] Secondary "Agents & Workspaces" window opens alongside
- [ ] Secondary window can be minimized
- [ ] Chat panel at bottom of project view
- [ ] All terminology says "Tasks" / "Agent" instead of "Mantis"
- [ ] Monospace `Fira Code` font with `//` prefix styling throughout
- [ ] WebSocket progress updates work in new UI
- [ ] Window drag, resize, minimize, maximize all functional
- [ ] Theme-aware (respects sentient/dark/light themes)

17
.gitignore vendored
View file

@ -8,6 +8,11 @@ bin/
*.log *.log
*logfile* *logfile*
*-log* *-log*
.vscode
.zed
.gemini
.claude
# Temporary files # Temporary files
.tmp* .tmp*
@ -62,15 +67,11 @@ init.json
*.cert *.cert
$null $null
AppData/ AppData/
build_errors.txt build_errors*.txt
build_errors2.txt
build_errors2_utf8.txt
build_errors3.txt
build_errors_utf8.txt build_errors_utf8.txt
check.json check.json
clippy.txt clippy*.txt
clippy2.txt
clippy_output.txt
clippy_warnings.txt
errors.txt errors.txt
errors_utf8.txt errors_utf8.txt
vault-unseal-keys

9
.idea/gb.iml generated
View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View file

@ -1,10 +0,0 @@
<component name="libraryTable">
<library name="botserver-installers">
<CLASSES>
<root url="jar://$PROJECT_DIR$/botserver/botserver-installers/llama-b7345-bin-ubuntu-x64.zip!/" />
<root url="jar://$PROJECT_DIR$/botserver/botserver-installers/vault_1.15.4_linux_amd64.zip!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

6
.idea/misc.xml generated
View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated
View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/gb.iml" filepath="$PROJECT_DIR$/.idea/gb.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

52
.idea/workspace.xml generated
View file

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="32fd08b0-7933-467d-9a46-1a53fd2da15c" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/botserver" beforeDir="false" afterPath="$PROJECT_DIR$/botserver" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 1
}]]></component>
<component name="ProjectId" id="38qdWTFkX8Nem4LzgigXpAycSN7" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"git-widget-placeholder": "main",
"last_opened_file_path": "/home/rodriguez/src/gb",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-30f59d01ecdd-2fc7cc6b9a17-intellij.indexing.shared.core-IU-253.30387.90" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="32fd08b0-7933-467d-9a46-1a53fd2da15c" name="Changes" comment="" />
<created>1769531070022</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1769531070022</updated>
<workItem from="1769531115917" duration="176000" />
</task>
<servers />
</component>
</project>

View file

@ -1,198 +0,0 @@
{
"languages": {
"typescript": {
"name": "typescript-language-server",
"command": "typescript-language-server",
"args": [
"--stdio"
],
"file_extensions": [
"ts",
"js",
"tsx",
"jsx"
],
"project_patterns": [
"package.json",
"tsconfig.json"
],
"exclude_patterns": [
"**/node_modules/**",
"**/dist/**"
],
"multi_workspace": false,
"initialization_options": {
"preferences": {
"disableSuggestions": false
}
},
"request_timeout_secs": 60
},
"python": {
"name": "pyright",
"command": "pyright-langserver",
"args": [
"--stdio"
],
"file_extensions": [
"py"
],
"project_patterns": [
"pyproject.toml",
"setup.py",
"requirements.txt",
"pyrightconfig.json"
],
"exclude_patterns": [
"**/__pycache__/**",
"**/venv/**",
"**/.venv/**",
"**/.pytest_cache/**"
],
"multi_workspace": false,
"initialization_options": {},
"request_timeout_secs": 60
},
"rust": {
"name": "rust-analyzer",
"command": "rust-analyzer",
"args": [],
"file_extensions": [
"rs"
],
"project_patterns": [
"Cargo.toml"
],
"exclude_patterns": [
"**/target/**"
],
"multi_workspace": false,
"initialization_options": {
"cargo": {
"buildScripts": {
"enable": true
}
},
"diagnostics": {
"enable": true,
"enableExperimental": true
},
"workspace": {
"symbol": {
"search": {
"scope": "workspace"
}
}
}
},
"request_timeout_secs": 60
},
"java": {
"name": "jdtls",
"command": "jdtls",
"args": [],
"file_extensions": [
"java"
],
"project_patterns": [
"pom.xml",
"build.gradle",
"build.gradle.kts",
".project"
],
"exclude_patterns": [
"**/target/**",
"**/build/**",
"**/.gradle/**"
],
"multi_workspace": false,
"initialization_options": {
"settings": {
"java": {
"compile": {
"nullAnalysis": {
"mode": "automatic"
}
},
"configuration": {
"annotationProcessing": {
"enabled": true
}
}
}
}
},
"request_timeout_secs": 60
},
"ruby": {
"name": "solargraph",
"command": "solargraph",
"args": [
"stdio"
],
"file_extensions": [
"rb"
],
"project_patterns": [
"Gemfile",
"Rakefile"
],
"exclude_patterns": [
"**/vendor/**",
"**/tmp/**"
],
"multi_workspace": false,
"initialization_options": {},
"request_timeout_secs": 60
},
"go": {
"name": "gopls",
"command": "gopls",
"args": [],
"file_extensions": [
"go"
],
"project_patterns": [
"go.mod",
"go.sum"
],
"exclude_patterns": [
"**/vendor/**"
],
"multi_workspace": false,
"initialization_options": {
"usePlaceholders": true,
"completeUnimported": true
},
"request_timeout_secs": 60
},
"cpp": {
"name": "clangd",
"command": "clangd",
"args": [
"--background-index"
],
"file_extensions": [
"cpp",
"cc",
"cxx",
"c",
"h",
"hpp",
"hxx"
],
"project_patterns": [
"CMakeLists.txt",
"compile_commands.json",
"Makefile"
],
"exclude_patterns": [
"**/build/**",
"**/cmake-build-**/**"
],
"multi_workspace": false,
"initialization_options": {},
"request_timeout_secs": 60
}
}
}

24
.vscode/launch.json vendored
View file

@ -1,24 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'botserver'",
"cargo": {
"args": ["run", "--bin=botserver", "--package=botserver", "--manifest-path=${workspaceFolder}/botserver/Cargo.toml"],
"filter": {
"name": "botserver",
"kind": "bin"
}
},
"args": [],
"env": {
"RUST_LOG": "trace,aws_sigv4=off,aws_smithy_checksums=off,mio=off,reqwest=off,aws_runtime=off,aws_smithy_http_client=off,rustls=off,hyper_util=off,aws_smithy_runtime=off,aws_smithy_runtime_api=off,tracing=off,aws_sdk_s3=off"
},
"cwd": "${workspaceFolder}/botserver"
},
]
}

View file

@ -1,5 +0,0 @@
{
"git.ignoreLimitWarning": true,
"Codegeex.SidebarUI.LanguagePreference": "English",
"Codegeex.RepoIndex": true
}

View file

@ -1,7 +0,0 @@
{
"languages": {
"Rust": {
"enable_language_server": false,
},
},
}

View file

@ -317,6 +317,10 @@ LOOP UNTIL (0 warnings AND 0 errors):
END LOOP END LOOP
``` ```
### ⚡ Streaming Build Rule
**Do NOT wait for `cargo` to finish.** As soon as the first errors appear in output, cancel/interrupt the build, fix those errors immediately, then re-run. This avoids wasting time on a full compile when errors are already visible.
--- ---
## 🧠 Memory Management ## 🧠 Memory Management

178
PROD-AGENTS.md Normal file
View file

@ -0,0 +1,178 @@
# General Bots Cloud — Production Operations Guide
## Infrastructure Overview
- **Host OS:** Ubuntu 24.04 LTS, LXD (snap)
- **SSH:** Key auth only, sudoer user in `lxd` group
- **Container engine:** LXD with ZFS storage pool
## LXC Container Architecture
| Container | Purpose | Exposed Ports |
|---|---|---|
| `<tenant>-proxy` | Caddy reverse proxy | 80, 443 |
| `<tenant>-system` | botserver + botui (privileged!) | internal only |
| `<tenant>-alm` | Forgejo (ALM/Git) | internal only |
| `<tenant>-alm-ci` | Forgejo CI runner | none |
| `<tenant>-email` | Stalwart mail server | 25,465,587,993,995,143,110 |
| `<tenant>-dns` | CoreDNS | 53 |
| `<tenant>-drive` | MinIO S3 | internal only |
| `<tenant>-tables` | PostgreSQL | internal only |
| `<tenant>-table-editor` | NocoDB | internal only |
| `<tenant>-webmail` | Roundcube | internal only |
## Key Rules
- `<tenant>-system` must be **privileged** (`security.privileged: true`) — required for botserver to own `/opt/gbo/` mounts
- All containers use LXD **proxy devices** for port forwarding (network forwards don't work when external IP is on host NIC, not bridge)
- Never remove proxy devices for ports: 80, 443, 25, 465, 587, 993, 995, 143, 110, 4190, 53
- CI runner (`alm-ci`) must NOT have cross-container disk device mounts — deploy via SSH instead
## Firewall (host)
- **ufw** with `DEFAULT_FORWARD_POLICY=ACCEPT` (needed for container internet)
- LXD forward rule must persist via systemd service
- **fail2ban** on host (SSH jail) and in email container (mail jail)
---
## ⚠️ Caddy Config — CRITICAL RULES
**NEVER replace the Caddyfile with a minimal/partial config.**
The full config has ~25 vhosts. If you only see 1-2 vhosts, you are looking at a broken/partial config.
**Before ANY change:**
1. Backup: `cp /opt/gbo/conf/config /opt/gbo/conf/config.bak-$(date +%Y%m%d%H%M)`
2. Validate: `caddy validate --config /opt/gbo/conf/config --adapter caddyfile`
3. Reload (not restart): `caddy reload --config /opt/gbo/conf/config --adapter caddyfile`
**Caddy storage must be explicitly set** in the global block, otherwise Caddy uses `~/.local/share/caddy` and loses existing certificates on restart:
```
{
storage file_system {
root /opt/gbo/data/caddy
}
}
```
**Dead domains cause ERR_SSL_PROTOCOL_ERROR** — if a domain in the Caddyfile has no DNS record, Caddy loops trying to get a certificate and pollutes TLS state. Remove dead domains immediately.
**After removing domains from config**, restart Caddy (not just reload) to clear in-memory ACME state from old domains.
---
## botserver / botui
- botserver: `system.service` on port 5858
- botui: `ui.service` on port 5859
- `BOTSERVER_URL` in `ui.service` must point to **`http://localhost:5858`** (not HTTPS external URL) — using external URL causes WebSocket disconnect before TALK executes
- Valkey/Redis bound to `127.0.0.1:6379` — iptables rules must allow loopback on this port or suggestions/cache won't work
- Vault unseal keys stored in `/opt/gbo/bin/botserver-stack/conf/vault/init.json`
### iptables loopback rule (required)
Internal services (Valkey, MinIO) are protected by DROP rules. Loopback must be explicitly allowed **before** the DROP rules:
```bash
iptables -I INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP # external only
```
---
## CoreDNS Hardening
Corefile must include `acl` plugin to prevent DNS amplification attacks:
```
zone.example.com:53 {
file /opt/gbo/data/zone.example.com.zone
acl {
allow type ANY net 10.0.0.0/8 127.0.0.0/8
allow type A net 0.0.0.0/0
allow type AAAA net 0.0.0.0/0
allow type MX net 0.0.0.0/0
block
}
cache
errors
}
```
Reload with SIGHUP: `pkill -HUP coredns`
---
## fail2ban in Proxy Container
Proxy container needs its own fail2ban for HTTP flood protection:
- Filter: match 4xx errors from Caddy JSON access log
- Jail: `caddy-http-flood` — 100 errors/60s → ban 1h
- Disable default `sshd` jail (no SSH in proxy container) via `jail.d/defaults-debian.conf`
---
## CI/CD (Forgejo Runner)
- Runner container must have **no cross-container disk mounts**
- Deploy via SSH: `scp binary <system-container>:/opt/gbo/bin/botserver`
- SSH key from runner → system container must be pre-authorized
- sccache + cargo registry cache accumulates — daily cleanup cron required
- ZFS snapshots of CI container can be huge if taken while cross-mounts were active — delete stale snapshots after removing mounts
---
## ZFS Disk Space
- Check snapshots: `zfs list -t snapshot -o name,used | sort -k2 -rh`
- Snapshots retain data from device mounts at time of snapshot — removing mounts doesn't free space until snapshot is deleted
- Delete snapshot: `zfs destroy <pool>/containers/<name>@<snapshot>`
- Daily rolling snapshots (7-day retention) via cron
---
## Bot Compiler — Known Issues Fixed
**Tools without PARAM declarations** (e.g. `USE KB` only tools) were not getting `.mcp.json` generated, causing `USE TOOL` to silently skip them. Fixed in compiler: always generate `.mcp.json` even for parameterless tools.
---
## Git Workflow
Push to both remotes after every change:
```bash
cd <submodule>
git push origin main
git push alm main
cd ..
git add <submodule>
git commit -m "Update submodule"
git push alm main
```
Failure to push the root `gb` repo will not trigger CI/CD pipelines.
---
## Useful Commands
```bash
# Check all containers
lxc list
# Check disk device mounts per container
for c in $(lxc list --format csv -c n); do
devices=$(lxc config device show $c | grep 'type: disk' | grep -v 'pool:' | wc -l)
[ $devices -gt 0 ] && echo "=== $c ===" && lxc config device show $c | grep -E 'source:|path:' | grep -v pool
done
# Tail Caddy errors
lxc exec <tenant>-proxy -- tail -f /opt/gbo/logs/access.log
# Restart botserver + botui
lxc exec <tenant>-system -- systemctl restart system.service ui.service
# Check iptables in system container
lxc exec <tenant>-system -- iptables -L -n | grep -E 'DROP|ACCEPT.*lo'
# ZFS snapshot usage
zfs list -t snapshot -o name,used | sort -k2 -rh | head -20
# Unseal Vault
lxc exec <tenant>-system -- bash -c "
export VAULT_ADDR=https://127.0.0.1:8200 VAULT_SKIP_VERIFY=true
/opt/gbo/bin/botserver-stack/bin/vault/vault operator unseal <key>
"
```

@ -1 +1 @@
Subproject commit ae09de3dea792ab10968a554d255b1179ebe854b Subproject commit 94ca51a670cfa664ba7abde24991bf831dac4fbd

View file

@ -1,8 +0,0 @@
data: {"candidates": [{"content": {"role": "model","parts": [{"text": "Hello!"}]}}],"usageMetadata": {"trafficType": "ON_DEMAND"},"modelVersion": "gemini-3.1-flash-lite-preview","createTime": "2026-03-10T14:54:45.066123Z","responseId": "tTCwacuEBMvnitYP06qsgQY"}
data: {"candidates": [{"content": {"role": "model","parts": [{"text": " How can I help you today"}]}}],"usageMetadata": {"trafficType": "ON_DEMAND"},"modelVersion": "gemini-3.1-flash-lite-preview","createTime": "2026-03-10T14:54:45.066123Z","responseId": "tTCwacuEBMvnitYP06qsgQY"}
data: {"candidates": [{"content": {"role": "model","parts": [{"text": "?"}]}}],"usageMetadata": {"trafficType": "ON_DEMAND"},"modelVersion": "gemini-3.1-flash-lite-preview","createTime": "2026-03-10T14:54:45.066123Z","responseId": "tTCwacuEBMvnitYP06qsgQY"}
data: {"candidates": [{"content": {"role": "model","parts": [{"text": "","thoughtSignature": "AY89a18iOcFus5wr5bW5xN6zZ4aUiCyhgmg6HE2YjtYDV/dwZ5oZlZHeTmiUKv34qq0="}]},"finishReason": "STOP"}],"usageMetadata": {"promptTokenCount": 1,"candidatesTokenCount": 9,"totalTokenCount": 10,"trafficType": "ON_DEMAND","promptTokensDetails": [{"modality": "TEXT","tokenCount": 1}],"candidatesTokensDetails": [{"modality": "TEXT","tokenCount": 9}]},"modelVersion": "gemini-3.1-flash-lite-preview","createTime": "2026-03-10T14:54:45.066123Z","responseId": "tTCwacuEBMvnitYP06qsgQY"}

18
package-lock.json generated
View file

@ -1,18 +0,0 @@
{
"name": "gb",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"monaco-editor": "^0.45.0"
}
},
"node_modules/monaco-editor": {
"version": "0.45.0",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.45.0.tgz",
"integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==",
"license": "MIT"
}
}
}

View file

@ -1,5 +0,0 @@
{
"dependencies": {
"monaco-editor": "^0.45.0"
}
}

View file

@ -1,737 +0,0 @@
# BotCoder Multi-Agent OS - Architecture Analysis
## Executive Summary
Based on analysis of **botserver** (Rust backend), **botui** (Web UI), and **botapp** (Tauri Desktop), we can architect **BotCoder** as a unified multi-agent operating system that leverages the existing Mantis Farm infrastructure while adding code-specific capabilities similar to Claude Code.
---
## Current Architecture Analysis
### 1. BotServer (Rust Backend) - `botserver/src/auto_task/`
#### Multi-Agent Pipeline (The "Mantis Farm")
**File:** `orchestrator.rs` (1147 lines)
The orchestrator implements a **5-stage multi-agent pipeline**:
```
┌─────────────────────────────────────────────────────────────┐
│ ORCHESTRATOR PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Stage 1: PLAN ────────► Mantis #1 (Planner) │
│ - Analyze user request │
│ - Break down into sub-tasks │
│ - Identify tables, pages, tools, schedulers │
│ - Derive enterprise-grade work breakdown │
│ │
│ Stage 2: BUILD ───────► Mantis #2 (Builder) │
│ - Generate application code │
│ - Create HTML/CSS/JS files │
│ - Define database schema │
│ - Build tools & schedulers │
│ │
│ Stage 3: REVIEW ───────► Mantis #3 (Reviewer) │
│ - Validate code quality │
│ - Check HTMX patterns │
│ - Verify security │
│ - Ensure no hardcoded data │
│ │
│ Stage 4: DEPLOY ───────► Mantis #4 (Deployer) │
│ - Deploy application │
│ - Verify accessibility │
│ - Confirm static assets loading │
│ │
│ Stage 5: MONITOR ───────► Mantis #1 (Planner) │
│ - Setup health monitoring │
│ - Track error rates │
│ - Monitor response times │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### Agent Status System
**Agent States:**
- **WILD** - Uninitialized agent
- **BRED** - Agent created and ready
- **EVOLVED** - Agent has completed work successfully
- **WORKING** - Agent actively processing
- **DONE** - Agent finished
- **FAILED** - Agent encountered error
**Agent Roles:**
```rust
pub enum AgentRole {
Planner, // Mantis #1 - Architect & Analyst
Builder, // Mantis #2 - Code Generator
Reviewer, // Mantis #3 - QA & Validation
Deployer, // Mantis #4 - Deployment
Monitor, // Mantis #1 (reused) - Health checks
}
```
#### Agent Executor (Container-Based)
**File:** `agent_executor.rs` (115 lines)
Provides **containerized execution environment** for agents:
```rust
pub struct AgentExecutor {
pub state: Arc<AppState>,
pub session_id: String,
pub task_id: String,
container: Option<ContainerSession>,
}
```
**Capabilities:**
- ✅ Spawn containerized terminal sessions
- ✅ Execute shell commands
- ✅ Broadcast terminal output via WebSocket
- ✅ Browser automation integration (chromiumoxide)
- ✅ Real-time progress updates
**WebSocket Events:**
- `terminal_output` - stdout/stderr from agent
- `thought_process` - agent reasoning/thinking
- `step_progress` - pipeline stage progress (1/5, 2/5...)
- `browser_ready` - browser automation available
- `agent_thought` - agent-specific thoughts
- `agent_activity` - structured activity logs
- `task_node` - task breakdown visualization
#### Intent Classification
**File:** `intent_classifier.rs`
Classifies user requests into types:
- **APP_CREATE** - Generate new application
- **APP_MODIFY** - Modify existing app
- **CODE_REVIEW** - Review code
- **DEBUG** - Debug issues
- **DEPLOY** - Deploy application
- **ANALYZE** - Analyze codebase
**Entity Extraction:**
- Tables (database schema)
- Features (UI components)
- Pages (routes/views)
- Tools (business logic)
- Schedulers (background jobs)
#### App Generator
**File:** `app_generator.rs` (3400+ lines)
**LLM-powered code generation:**
- Generates HTMX applications
- Creates database schemas
- Builds REST API endpoints
- Generates BASIC tools
- Creates scheduled jobs
- Produces E2E tests
**Output:**
```rust
pub struct GeneratedApp {
pub name: String,
pub description: String,
pub tables: Vec<TableDefinition>,
pub pages: Vec<GeneratedPage>,
pub tools: Vec<GeneratedTool>,
pub schedulers: Vec<SchedulerDefinition>,
}
```
#### Designer AI
**File:** `designer_ai.rs`
Runtime code modifications with:
- Undo/redo support
- Real-time UI editing
- Visual layout changes
- Style modifications
#### Safety Layer
**File:** `safety_layer.rs`
- Constraint checking
- Simulation before execution
- Audit trail
- Approval workflows
---
### 2. BotUI (Web Interface) - `botui/ui/suite/`
#### Vibe Builder UI
**File:** `partials/vibe.html` (47KB)
**Components:**
1. **Pipeline Tabs** - Plan/Build/Review/Deploy/Monitor stages
2. **Agents Sidebar** - Mantis #1-4 status cards
3. **Workspaces List** - Project management
4. **Canvas Area** - Task node visualization
5. **Chat Overlay** - Real-time communication with agents
**Agent Cards Display:**
```html
<div class="as-agent-card" data-agent-id="1">
<div class="as-agent-header">
<span class="as-status-dot green"></span>
<span class="as-agent-name">Mantis #1</span>
</div>
<div class="as-agent-body">
<span class="as-agent-icons">👀 ⚙️ ⚡</span>
<span class="as-badge badge-evolved">EVOLVED</span>
</div>
</div>
```
**WebSocket Integration:**
```javascript
// Connect to task progress stream
const ws = new WebSocket(`ws://localhost:8080/ws/task-progress/${taskId}`);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
handleTaskProgress(data);
};
// Event types handled:
// - pipeline_start
// - pipeline_complete
// - step_progress (1/5, 2/5, ...)
// - agent_thought
// - agent_activity
// - task_node
// - terminal_output
// - manifest_update
```
**Real-time Updates:**
- Agent status changes (WILD → BRED → WORKING → EVOLVED)
- Task node visualization (plan breakdown)
- Terminal output streaming
- Progress indicators
- File generation notifications
#### Other UI Components
- `chat.html` - Chat interface for agent interaction
- `editor-inner.html` - Code editor (currently textarea, needs Monaco)
- `explorer-inner.html` - File browser
- `settings.html` - Configuration
- `tasks.html` - Task management
- `desktop-inner.html` - Desktop integration
---
### 3. BotApp (Desktop) - `botapp/src/`
**Tauri-based desktop application** with:
- System tray integration
- Service monitoring
- File system access
- Desktop sync (rclone)
- Native notifications
**Main Features:**
```rust
// Desktop service monitoring
pub struct ServiceMonitor {
services: HashMap<String, ServiceStatus>,
}
// Tray management
pub struct TrayManager {
mode: RunningMode, // Server | Desktop | Client
}
// Drive integration
mod drive {
list_files()
upload_file()
create_folder()
}
// Sync integration
mod sync {
get_sync_status()
start_sync()
configure_remote()
}
```
---
## BotCoder Multi-Agent OS Architecture
### Vision
**BotCoder** = **Vibe Builder** + **Code-Specific Agents** + **Professional Tools**
Create a complete development environment that:
1. Uses the existing Mantis Farm infrastructure
2. Adds specialized coding agents (similar to Claude Code)
3. Provides professional editor experience (Monaco, terminal, git, etc.)
4. Supports both internal (GB Platform) and external (Forgejo) deployment
---
## Proposed BotCoder Agent Ecosystem
### Core Mantis Farm (Keep Existing)
```
Mantis #1: Planner & Orchestrator ───► Already exists in botserver
Mantis #2: Code Generator ───► Already exists (AppGenerator)
Mantis #3: Reviewer & Validator ───► Already exists
Mantis #4: Deployer ───► Already exists
```
### New Specialized Agents (Add to BotCoder)
```
┌─────────────────────────────────────────────────────────────────┐
│ BOTCODER AGENTS │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Mantis #5: Editor Agent ───► File operations │
│ - Multi-file editing │
│ - Syntax awareness │
│ - Refactoring support │
│ - Code completion │
│ │
│ Mantis #6: Database Agent ───► Schema operations │
│ - Query optimization │
│ - Migration management │
│ - Data visualization │
│ - Index suggestions │
│ │
│ Mantis #7: Git Agent ───► Version control │
│ - Commit analysis │
│ - Branch management │
│ - Conflict resolution │
│ - Code archaeology │
│ │
│ Mantis #8: Test Agent ───► Quality assurance │
│ - Test generation │
│ - Coverage analysis │
│ - E2E testing (chromiumoxide) │
│ - Performance profiling │
│ │
│ Mantis #9: Browser Agent ───► Web automation │
│ - Page recording │
│ - Element inspection │
│ - Performance monitoring │
│ - SEO checking │
│ │
│ Mantis #10: Terminal Agent ───► Command execution │
│ - Shell command execution │
│ - Build system integration │
│ - Package management │
│ - Docker orchestration │
│ │
│ Mantis #11: Documentation Agent ───► Docs & comments │
│ - Auto-generate docs │
│ - Comment quality check │
│ - README generation │
│ - API documentation │
│ │
│ Mantis #12: Security Agent ───► Security auditing │
│ - Vulnerability scanning │
│ - Dependency analysis │
│ - Secret detection │
│ - OWASP compliance │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## BotCoder Architecture
### Backend (Rust)
```
botserver/src/
├── auto_task/ # EXISTING - Mantis Farm
│ ├── orchestrator.rs # Keep - Multi-agent pipeline
│ ├── agent_executor.rs # Keep - Container execution
│ ├── app_generator.rs # Keep - LLM code gen
│ ├── designer_ai.rs # Keep - Runtime edits
│ ├── intent_classifier.rs # Keep - Request classification
│ └── safety_layer.rs # Keep - Constraint checking
├── botcoder/ # NEW - BotCoder-specific agents
│ ├── mod.rs
│ ├── editor_agent.rs # Mantis #5 - File operations
│ ├── database_agent.rs # Mantis #6 - Schema ops
│ ├── git_agent.rs # Mantis #7 - Version control
│ ├── test_agent.rs # Mantis #8 - Testing
│ ├── browser_agent.rs # Mantis #9 - Web automation
│ ├── terminal_agent.rs # Mantis #10 - Command exec
│ ├── docs_agent.rs # Mantis #11 - Documentation
│ └── security_agent.rs # Mantis #12 - Security
├── deployment/ # NEW - From vibe.md Phase 0
│ ├── mod.rs # DeploymentRouter
│ ├── forgejo.rs # ForgejoClient
│ ├── api.rs # Deployment endpoints
│ └── templates.rs # CI/CD workflows
├── api/ # EXTEND - Add BotCoder APIs
│ ├── editor.rs # Monaco integration
│ ├── database.rs # DB UI backend
│ ├── git.rs # Git operations
│ ├── browser.rs # Browser automation
│ └── terminal.rs # WebSocket terminals
└── browser/ # NEW - From vibe.md Phase 4
├── mod.rs # BrowserSession
├── recorder.rs # ActionRecorder
├── validator.rs # TestValidator
└── api.rs # HTTP endpoints
```
### Frontend (Web + Desktop)
```
botui/ui/suite/
├── partials/
│ ├── vibe.html # EXISTING - Agent sidebar
│ ├── vibe-deployment.html # NEW - Deployment modal
│ ├── editor.html # NEW - Monaco editor
│ ├── database.html # NEW - Schema visualizer
│ ├── git-status.html # NEW - Git operations
│ ├── git-diff.html # NEW - Diff viewer
│ ├── browser-controls.html # NEW - Browser automation
│ └── terminal.html # NEW - Enhanced terminal
├── js/
│ ├── vibe.js # EXISTING - Vibe logic
│ ├── deployment.js # NEW - Deployment handler
│ ├── editor.js # NEW - Monaco integration
│ ├── database.js # NEW - DB visualization
│ ├── git.js # NEW - Git operations
│ ├── browser.js # NEW - Browser automation
│ └── terminal.js # NEW - Terminal (xterm.js)
└── css/
├── agents-sidebar.css # EXISTING - Mantis cards
├── deployment.css # NEW - Deployment styles
├── editor.css # NEW - Editor styles
├── database.css # NEW - DB UI styles
└── terminal.css # NEW - Terminal styles
```
---
## Integration Strategy
### Option 1: BotCoder as Separate Repository (Recommended)
```
gb/
├── botserver/ # Existing - Backend services
├── botui/ # Existing - Web UI
├── botapp/ # Existing - Desktop app
└── botcoder/ # NEW - Multi-agent IDE
├── Cargo.toml
├── src/
│ ├── main.rs
│ ├── agents/ # BotCoder agents
│ ├── editor/ # Editor integration
│ └── workspace/ # Workspace management
└── ui/
├── src/
│ ├── components/ # React/Vue components
│ ├── pages/ # IDE pages
│ └── lib/
└── index.html
```
**Pros:**
- Clean separation of concerns
- Independent release cycle
- Can be deployed standalone
- Easier to maintain
**Cons:**
- Duplicate some botserver code
- Need to share common libs
### Option 2: BotCoder as Module in BotServer
```
botserver/src/
├── auto_task/ # Existing Mantis Farm
└── botcoder/ # New BotCoder module
├── mod.rs
├── agents/
├── editor/
└── workspace/
```
**Pros:**
- Share existing infrastructure
- Single deployment
- Unified WebSocket channels
**Cons:**
- Tighter coupling
- Larger monolith
### Recommendation: **Option 1 (Separate Repo)**
But share common libraries via a `botlib` crate:
```
gb/
├── botlib/ # Shared utilities
│ ├── src/
│ │ ├── agents/ # Agent traits
│ │ ├── llm/ # LLM clients
│ │ └── websocket/ # WebSocket utils
│ └── Cargo.toml
├── botserver/ # Uses botlib
├── botui/ # Uses botlib
├── botapp/ # Uses botlib
└── botcoder/ # Uses botlib ← NEW
```
---
## BotCoder Features vs Vibe Builder
### Vibe Builder (Existing)
- ✅ Multi-agent pipeline (Mantis #1-4)
- ✅ App generation (HTMX apps)
- ✅ WebSocket real-time updates
- ✅ Agent status visualization
- ✅ Task breakdown
- ✅ Deployment (internal GB platform)
### BotCoder (Add)
- 📝 **Monaco Editor** - Professional code editing
- 🗄️ **Database UI** - Schema visualization
- 🐙 **Git Operations** - Version control UI
- 🌐 **Browser Automation** - Testing & recording
- 📂 **Multi-File Workspace** - Tab management
- 🖥️ **Enhanced Terminal** - xterm.js integration
- 🚀 **Dual Deployment** - Internal + Forgejo
- 🔒 **Security Scanning** - Vulnerability detection
- 📚 **Auto-Documentation** - Generate docs
- 🧪 **E2E Testing** - chromiumoxide integration
---
## BotCoder Multi-Agent Workflow Example
### User Request: "Create a CRM with contacts and deals"
```
1. CLASSIFY
└─ Intent: APP_CREATE
└─ Entities: { tables: [contacts, deals], features: [Contact Manager, Deal Pipeline] }
2. PLAN (Mantis #1 - Planner)
├─ Break down into 12 sub-tasks
├─ Create task nodes
└─ Estimate: 45 files, 98k tokens, 2.5 hours
3. BUILD (Mantis #2 - Builder)
├─ Generate HTML/CSS/JS files
├─ Create database schema
├─ Build REST API endpoints
└─ Output: /apps/my-crm/
4. CODE REVIEW (Mantis #3 - Reviewer)
├─ Check HTMX patterns
├─ Verify security
├─ Validate error handling
└─ Status: PASSED
5. OPTIMIZE (Mantis #5 - Editor Agent) ← NEW
├─ Analyze code structure
├─ Suggest refactorings
├─ Apply safe optimizations
└─ Generate PR
6. TEST (Mantis #8 - Test Agent) ← NEW
├─ Generate unit tests
├─ Create E2E tests (chromiumoxide)
├─ Measure coverage
└─ Status: 87% coverage
7. SECURITY CHECK (Mantis #12 - Security Agent) ← NEW
├─ Scan vulnerabilities
├─ Check dependencies
├─ Detect secrets
└─ Status: 0 issues found
8. DEPLOY (Mantis #4 - Deployer)
├─ Choose deployment target
│ ├─ Internal GB Platform ← Selected
│ └─ External Forgejo (optional)
├─ Deploy to /apps/my-crm/
└─ Verify accessibility
9. DOCUMENT (Mantis #11 - Documentation Agent) ← NEW
├─ Generate README.md
├─ Create API docs
├─ Add code comments
└─ Output: /docs/
10. MONITOR (Mantis #1 - Planner)
├─ Setup uptime monitoring
├─ Track error rates
├─ Monitor response times
└─ Status: ACTIVE
```
---
## Technical Implementation Plan
### Phase 1: Core BotCoder Infrastructure (Week 1)
**Tasks:**
1. Create `botcoder/` repository structure
2. Implement `botlib` shared crate
3. Add Mantis #5-12 agent stubs
4. Extend WebSocket protocol for new agents
5. Update orchestrator to support 12 agents
**Deliverables:**
- ✅ BotCoder repo initialized
- ✅ Agent trait system defined
- ✅ WebSocket events extended
- ✅ Orchestrator handles 12-agent pipeline
### Phase 2: Editor & Database UI (Week 2)
**Tasks:**
1. Integrate Monaco Editor (replace textarea)
2. Build database schema visualizer
3. Add query builder UI
4. Implement Mantis #5 (Editor Agent)
5. Implement Mantis #6 (Database Agent)
**Deliverables:**
- ✅ Monaco loads with syntax highlighting
- ✅ ER diagram shows tables/relationships
- ✅ Query builder generates SQL
- ✅ Editor agent can refactor code
- ✅ Database agent optimizes queries
### Phase 3: Git & Browser Automation (Week 3)
**Tasks:**
1. Build git operations UI
2. Implement diff viewer
3. Add browser automation panel (chromiumoxide)
4. Implement Mantis #7 (Git Agent)
5. Implement Mantis #9 (Browser Agent)
**Deliverables:**
- ✅ Git status shows changes
- ✅ Diff viewer displays side-by-side
- ✅ Browser automation records actions
- ✅ Git agent manages branches
- ✅ Browser agent generates Playwright tests
### Phase 4: Testing, Security & Docs (Week 4)
**Tasks:**
1. Implement test generation
2. Add security scanning
3. Build documentation generator
4. Implement Mantis #8 (Test Agent)
5. Implement Mantis #12 (Security Agent)
6. Implement Mantis #11 (Docs Agent)
**Deliverables:**
- ✅ Test agent generates coverage reports
- ✅ Security agent scans vulnerabilities
- ✅ Docs agent generates README
- ✅ E2E tests run via chromiumoxide
### Phase 5: Deployment Integration (Week 5)
**Tasks:**
1. Implement deployment router (from vibe.md Phase 0)
2. Add Forgejo integration
3. Build deployment UI
4. Integrate with existing Mantis #4 (Deployer)
**Deliverables:**
- ✅ Can deploy internally to /apps/
- ✅ Can deploy externally to Forgejo
- ✅ CI/CD pipelines auto-generated
- ✅ Deployment choice in UI
---
## Success Metrics
### Agent Performance
- ⚡ Pipeline completes in < 2 minutes
- 🎯 95%+ task success rate
- 🔄 < 5% agent failures requiring retry
- 📊 Real-time progress updates < 100ms latency
### Code Quality
- ✅ 80%+ test coverage
- 🔒 0 critical vulnerabilities
- 📝 100% documented public APIs
- 🚀 < 30s deployment time
### User Experience
- 💬 Natural language → working app
- 🎨 Beautiful UI by default
- 🔧 Professional tools (Monaco, terminal, git)
- 📱 Works on desktop + web
---
## Comparison: BotCoder vs Claude Code
| Feature | BotCoder | Claude Code |
|---------|----------|-------------|
| Multi-agent pipeline | ✅ 12 specialized agents | ❌ Single agent |
| Visual agent status | ✅ Real-time Mantis cards | ❌ No agent visibility |
| App generation | ✅ Full-stack (HTMX + DB) | ✅ Code generation only |
| Database UI | ✅ Schema visualizer | ❌ No DB tools |
| Git operations | ✅ Dedicated agent (Mantis #7) | ✅ Git integration |
| Browser automation | ✅ chromiumoxide + Mantis #9 | ✅ Playwright support |
| Deployment options | ✅ Dual (Internal + Forgejo) | ❌ No deployment |
| Desktop app | ✅ Tauri (botapp) | ❌ CLI only |
| Multi-user | ✅ SaaS platform | ❌ Single user |
| Visual workspace | ✅ Vibe Builder | ❌ Terminal only |
| Agent reasoning | ✅ Transparent thoughts | ❌ Black box |
---
## Conclusion
**BotCoder** can leverage the existing **Mantis Farm** infrastructure in `botserver` while adding specialized coding agents and professional tools. The architecture is:
1. **Foundation:** Existing orchestrator.rs (1147 lines) - 5-stage pipeline
2. **Extension:** Add 7 new specialized agents (Mantis #5-12)
3. **UI:** Extend vibe.html with editor, database, git, browser panels
4. **Desktop:** Integrate with botapp for native experience
5. **Deployment:** Dual deployment (internal GB Platform + external Forgejo)
**Estimated Effort:** 5 weeks (following vibe.md roadmap)
**Result:** A complete multi-agent development environment that exceeds Claude Code's capabilities while offering visual agent management, dual deployment, and multi-user SaaS architecture.

View file

@ -1,955 +0,0 @@
# BotCoder Hybrid Architecture v2.0
## CLI + Optional Multi-Agent Facade (BYOK vs BotServer)
## Executive Summary
**BotCoder** exists as a **terminal-based AI coding agent** with real-time streaming and tool execution. This document outlines how to extend it into a **hybrid CLI/multi-agent OS** that can:
1. **Work standalone (BYOK)** - Direct LLM access, local execution
2. **Use botserver facade** - Leverage Mantis Farm agents when available
3. **Switch dynamically** - Fall back to local if botserver unavailable
---
## Current BotCoder Architecture
### Existing CLI Implementation (`/home/rodriguez/src/pgm/botcoder`)
**Dependencies:**
```toml
tokio = "1.42" # Async runtime
reqwest = "0.12" # HTTP client
ratatui = "0.29" # TUI framework
crossterm = "0.29" # Terminal handling
futures = "0.3" # Async utilities
regex = "1.10" # Pattern matching
```
**Core Features:**
- ✅ Real-time streaming LLM responses
- ✅ Tool execution (read_file, execute_command, write_file)
- ✅ Delta format parsing (git-style diffs)
- ✅ TPM rate limiting
- ✅ Conversation history management
- ✅ Animated TUI with ratatui
**Tool Support:**
```rust
// Currently supported tools
fn execute_tool(tool: &str, param: &str, project_root: &str) -> String {
match tool {
"read_file" => read_file(param),
"execute_command" => execute_command(param, project_root),
"write_file" => write_file(param),
"list_files" => list_files(param, project_root),
_ => format!("Unknown tool: {}", tool),
}
}
```
**LLM Integration:**
```rust
// Direct Azure OpenAI client
mod llm {
pub struct AzureOpenAIClient {
endpoint: String,
api_key: String,
deployment: String,
}
impl LLMProvider for AzureOpenAIClient {
async fn generate(&self, prompt: &str, params: &serde_json::Value)
-> Result<String, Box<dyn std::error::Error>>;
}
}
```
---
## Proposed Hybrid Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ BOTCODER HYBRID MODE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ BOTCODER CLI (main.rs) │ │
│ │ - TUI interface (ratatui) │ │
│ │ - Tool execution │ │
│ │ - Delta parsing │ │
│ │ - Rate limiting │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ LLM PROVIDER TRAIT (abstraction) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ DIRECT LLM │ │ BOTSERVER FACADE │ │
│ │ (BYOK Mode) │ │ (Multi-Agent Mode) │ │
│ │ │ │ │ │
│ │ - Azure OpenAI │ │ - Mantis #1-4 │ │
│ │ - Anthropic │ │ - Mantis #5-12 │ │
│ │ - OpenAI │ │ - Orchestrator │ │
│ │ - Local LLM │ │ - WebSocket │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │ │ │
│ │ (Optional) │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ LOCAL EXECUTION │ │ AGENT EXECUTION │ │
│ │ │ │ │ │
│ │ - File operations │ │ - Containerized │ │
│ │ - Command execution │ │ - AgentExecutor │ │
│ │ - Git operations │ │ - Browser automation│ │
│ │ - Docker control │ │ - Test generation │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## Implementation Plan
### Phase 1: LLM Provider Abstraction (Week 1)
**Goal:** Create trait-based system for multiple LLM backends
**File:** `src/llm/mod.rs`
```rust
use async_trait::async_trait;
/// Unified LLM provider trait
#[async_trait]
pub trait LLMProvider: Send + Sync {
/// Generate completion with streaming support
async fn generate_stream(
&self,
prompt: &str,
params: &GenerationParams,
) -> Result<StreamResponse, LLMError>;
/// Generate completion (non-streaming)
async fn generate(
&self,
prompt: &str,
params: &GenerationParams,
) -> Result<String, LLMError>;
/// Get provider capabilities
fn capabilities(&self) -> ProviderCapabilities;
/// Get provider name
fn name(&self) -> &str;
}
pub struct GenerationParams {
pub temperature: f32,
pub max_tokens: u32,
pub top_p: f32,
pub tools: Vec<ToolDefinition>,
pub system_prompt: Option<String>,
}
pub struct StreamResponse {
pub content_stream: tokio_stream::wrappers::ReceiverStream<String>,
pub tool_calls: Vec<ToolCall>,
pub usage: TokenUsage,
}
pub struct ProviderCapabilities {
pub streaming: bool,
pub tools: bool,
pub max_tokens: u32,
pub supports_vision: bool,
}
```
**Implementations:**
```rust
// src/llm/azure_openai.rs
pub struct AzureOpenAIClient {
endpoint: String,
api_key: String,
deployment: String,
client: reqwest::Client,
}
#[async_trait]
impl LLMProvider for AzureOpenAIClient {
async fn generate(&self, prompt: &str, params: &GenerationParams)
-> Result<String, LLMError> {
// Existing implementation
}
fn capabilities(&self) -> ProviderCapabilities {
ProviderCapabilities {
streaming: true,
tools: true,
max_tokens: 4096,
supports_vision: false,
}
}
fn name(&self) -> &str {
"azure-openai"
}
}
// src/llm/anthropic.rs
pub struct AnthropicClient {
api_key: String,
client: reqwest::Client,
}
#[async_trait]
impl LLMProvider for AnthropicClient {
async fn generate(&self, prompt: &str, params: &GenerationParams)
-> Result<String, LLMError> {
// Anthropic API implementation
}
fn capabilities(&self) -> ProviderCapabilities {
ProviderCapabilities {
streaming: true,
tools: true,
max_tokens: 8192,
supports_vision: true,
}
}
fn name(&self) -> &str {
"anthropic"
}
}
// src/llm/botserver_facade.rs
pub struct BotServerFacade {
base_url: String,
api_key: Option<String>,
client: reqwest::Client,
}
#[async_trait]
impl LLMProvider for BotServerFacade {
async fn generate(&self, prompt: &str, params: &GenerationParams)
-> Result<String, LLMError> {
// Instead of direct LLM call, use botserver's orchestrator
// 1. Classify intent
// 2. Execute multi-agent pipeline
// 3. Return aggregated result
}
fn capabilities(&self) -> ProviderCapabilities {
ProviderCapabilities {
streaming: true, // Via WebSocket
tools: true, // Via AgentExecutor
max_tokens: 128000, // Multi-agent consensus
supports_vision: true, // Via Browser Agent
}
}
fn name(&self) -> &str {
"botserver-mantis-farm"
}
}
```
**Configuration:**
```rust
// src/config.rs
#[derive(Debug, Clone)]
pub struct BotCoderConfig {
pub llm_provider: LLMProviderType,
pub botserver_url: Option<String>,
pub project_path: PathBuf,
pub enable_facade: bool,
pub fallback_to_local: bool,
}
#[derive(Debug, Clone)]
pub enum LLMProviderType {
AzureOpenAI,
Anthropic,
OpenAI,
LocalLLM,
BotServerFacade, // Use Mantis Farm
}
impl BotCoderConfig {
pub fn from_env() -> Result<Self, ConfigError> {
let llm_provider = match env::var("LLM_PROVIDER").as_deref() {
Ok("azure") => LLMProviderType::AzureOpenAI,
Ok("anthropic") => LLMProviderType::Anthropic,
Ok("botserver") => LLMProviderType::BotServerFacade,
_ => LLMProviderType::AzureOpenAI, // Default
};
let botserver_url = env::var("BOTSERVER_URL").ok();
let enable_facade = env::var("ENABLE_BOTSERVER_FACADE")
.unwrap_or_else(|_| "false".to_string()) == "true";
Ok(Self {
llm_provider,
botserver_url,
project_path: env::var("PROJECT_PATH")?.into(),
enable_facade,
fallback_to_local: true,
})
}
}
```
---
### Phase 2: Multi-Agent Facade Integration (Week 2)
**Goal:** Connect to botserver's Mantis Farm when available
**File:** `src/botserver_client.rs`
```rust
use reqwest::Client;
use serde::{Deserialize, Serialize};
pub struct BotServerClient {
base_url: String,
api_key: Option<String>,
client: Client,
}
impl BotServerClient {
pub fn new(base_url: String, api_key: Option<String>) -> Self {
Self {
base_url,
api_key,
client: Client::new(),
}
}
/// Classify intent using botserver's intent classifier
pub async fn classify_intent(&self, text: &str)
-> Result<ClassifiedIntent, BotServerError> {
let url = format!("{}/api/autotask/classify", self.base_url);
let response = self.client
.post(&url)
.json(&serde_json::json!({ "text": text }))
.header("Authorization", self.api_key.as_ref().map(|k| format!("Bearer {}", k)).unwrap_or_default())
.send()
.await?;
if response.status().is_success() {
Ok(response.json().await?)
} else {
Err(BotServerError::ClassificationFailed(response.text().await?))
}
}
/// Execute multi-agent pipeline
pub async fn execute_pipeline(&self, classification: &ClassifiedIntent)
-> Result<OrchestrationResult, BotServerError> {
let url = format!("{}/api/autotask/execute", self.base_url);
let response = self.client
.post(&url)
.json(classification)
.header("Authorization", self.api_key.as_ref().map(|k| format!("Bearer {}", k)).unwrap_or_default())
.send()
.await?;
if response.status().is_success() {
Ok(response.json().await?)
} else {
Err(BotServerError::PipelineFailed(response.text().await?))
}
}
/// Subscribe to WebSocket progress updates
pub async fn subscribe_progress(&self, task_id: &str)
-> Result<tokio_tungstenite::WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>, BotServerError> {
let ws_url = format!(
"{}/ws/task-progress/{}",
self.base_url.replace("http", "ws"),
task_id
);
tokio_tungstenite::connect_async(&ws_url).await
.map_err(BotServerError::WebSocketError)
}
/// Use specialized agents directly
pub async fn query_agent(&self, agent_id: u8, query: &str)
-> Result<AgentResponse, BotServerError> {
match agent_id {
5 => self.query_editor_agent(query).await,
6 => self.query_database_agent(query).await,
7 => self.query_git_agent(query).await,
8 => self.query_test_agent(query).await,
9 => self.query_browser_agent(query).await,
10 => self.query_terminal_agent(query).await,
11 => self.query_docs_agent(query).await,
12 => self.query_security_agent(query).await,
_ => Err(BotServerError::InvalidAgent(agent_id)),
}
}
// Specific agent methods
async fn query_editor_agent(&self, query: &str)
-> Result<AgentResponse, BotServerError> {
// POST /api/botcoder/editor/query
let url = format!("{}/api/botcoder/editor/query", self.base_url);
let response = self.client
.post(&url)
.json(&serde_json::json!({ "query": query }))
.send()
.await?;
Ok(response.json().await?)
}
async fn query_database_agent(&self, query: &str)
-> Result<AgentResponse, BotServerError> {
// Query database schema, optimize queries
let url = format!("{}/api/botcoder/database/query", self.base_url);
let response = self.client
.post(&url)
.json(&serde_json::json!({ "query": query }))
.send()
.await?;
Ok(response.json().await?)
}
// ... other agent methods
}
#[derive(Debug, Deserialize)]
pub struct ClassifiedIntent {
pub intent_type: String,
pub entities: IntentEntities,
pub original_text: String,
}
#[derive(Debug, Deserialize)]
pub struct OrchestrationResult {
pub success: bool,
pub task_id: String,
pub stages_completed: u8,
pub app_url: Option<String>,
pub message: String,
pub created_resources: Vec<CreatedResource>,
}
#[derive(Debug, thiserror::Error)]
pub enum BotServerError {
#[error("Classification failed: {0}")]
ClassificationFailed(String),
#[error("Pipeline execution failed: {0}")]
PipelineFailed(String),
#[error("WebSocket error: {0}")]
WebSocketError(#[from] tokio_tungstenite::tungstenite::Error),
#[error("Invalid agent ID: {0}")]
InvalidAgent(u8),
#[error("HTTP error: {0}")]
HttpError(#[from] reqwest::Error),
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
}
```
---
### Phase 3: Unified Tool Execution (Week 2-3)
**Goal:** Abstract tool execution to work locally or via agents
**File:** `src/tools/mod.rs`
```rust
use async_trait::async_trait;
/// Unified tool execution trait
#[async_trait]
pub trait ToolExecutor: Send + Sync {
async fn execute(&self, tool: &ToolCall, context: &ExecutionContext)
-> Result<ToolResult, ToolError>;
fn supports_tool(&self, tool_name: &str) -> bool;
}
pub struct ToolCall {
pub name: String,
pub parameters: serde_json::Value,
pub agent_id: Option<u8>, // Which agent should execute
}
pub struct ToolResult {
pub output: String,
pub exit_code: i32,
pub metadata: serde_json::Value,
}
pub struct ExecutionContext {
pub project_path: PathBuf,
pub botserver_client: Option<BotServerClient>,
pub use_local_fallback: bool,
}
/// Local tool executor (existing implementation)
pub struct LocalToolExecutor {
project_root: PathBuf,
}
#[async_trait]
impl ToolExecutor for LocalToolExecutor {
async fn execute(&self, tool: &ToolCall, context: &ExecutionContext)
-> Result<ToolResult, ToolError> {
match tool.name.as_str() {
"read_file" => self.read_file(tool.parameters).await,
"write_file" => self.write_file(tool.parameters).await,
"execute_command" => self.execute_command(tool.parameters).await,
"list_files" => self.list_files(tool.parameters).await,
"git_operation" => self.git_operation(tool.parameters).await,
_ => Err(ToolError::UnknownTool(tool.name.clone())),
}
}
fn supports_tool(&self, tool_name: &str) -> bool {
matches!(tool_name,
"read_file" | "write_file" | "execute_command" |
"list_files" | "git_operation"
)
}
}
/// Agent-based tool executor (via botserver)
pub struct AgentToolExecutor {
botserver_client: BotServerClient,
}
#[async_trait]
impl ToolExecutor for AgentToolExecutor {
async fn execute(&self, tool: &ToolCall, context: &ExecutionContext)
-> Result<ToolResult, ToolError> {
// Route to appropriate agent
let agent_id = tool.agent_id.unwrap_or_else(|| {
self.infer_agent_for_tool(&tool.name)
});
match self.botserver_client.query_agent(agent_id, &tool.parameters.to_string()).await {
Ok(response) => Ok(ToolResult {
output: response.output,
exit_code: response.exit_code,
metadata: response.metadata,
}),
Err(e) => {
// Fallback to local if enabled
if context.use_local_fallback {
warn!("Agent execution failed, falling back to local: {}", e);
LocalToolExecutor::new(context.project_path.clone()).execute(tool, context).await?
} else {
Err(ToolError::AgentError(e.to_string()))
}
}
}
}
fn supports_tool(&self, tool_name: &str) -> bool {
matches!(tool_name,
"database_query" | "schema_visualize" | "git_commit" |
"test_generate" | "browser_record" | "docs_generate" |
"security_scan" | "code_refactor" | "optimize_query"
)
}
fn infer_agent_for_tool(&self, tool_name: &str) -> u8 {
match tool_name {
"code_refactor" | "syntax_check" => 5, // Editor Agent
"database_query" | "schema_visualize" | "optimize_query" => 6, // Database Agent
"git_commit" | "git_branch" | "git_merge" => 7, // Git Agent
"test_generate" | "coverage_report" => 8, // Test Agent
"browser_record" | "page_test" => 9, // Browser Agent
"shell_execute" | "docker_build" => 10, // Terminal Agent
"docs_generate" | "api_docs" => 11, // Docs Agent
"security_scan" | "vulnerability_check" => 12, // Security Agent
_ => 2, // Default to Builder Agent
}
}
}
```
---
### Phase 4: Hybrid Execution Loop (Week 3)
**Goal:** Main loop that seamlessly switches between local and agent execution
**File:** `src/main.rs` (modified)
```rust
use llm::LLMProvider;
use tools::{LocalToolExecutor, AgentToolExecutor, ToolExecutor};
struct BotCoder {
config: BotCoderConfig,
llm_provider: Box<dyn LLMProvider>,
local_executor: LocalToolExecutor,
agent_executor: Option<AgentToolExecutor>,
botserver_client: Option<BotServerClient>,
}
impl BotCoder {
pub async fn new(config: BotCoderConfig) -> Result<Self, Box<dyn std::error::Error>> {
// Initialize LLM provider based on config
let llm_provider: Box<dyn LLMProvider> = match config.llm_provider {
LLMProviderType::AzureOpenAI => {
Box::new(llm::AzureOpenAIClient::new()?)
}
LLMProviderType::Anthropic => {
Box::new(llm::AnthropicClient::new()?)
}
LLMProviderType::BotServerFacade => {
// Will use botserver client
Box::new(llm::BotServerFacade::new(
config.botserver_url.clone().unwrap()
)?)
}
_ => Box::new(llm::AzureOpenAIClient::new()?),
};
// Initialize tool executors
let local_executor = LocalToolExecutor::new(config.project_path.clone());
let mut agent_executor = None;
let mut botserver_client = None;
// Try to connect to botserver if enabled
if config.enable_facade {
if let Some(url) = &config.botserver_url {
match BotServerClient::new(url.clone(), None).health_check().await {
Ok(()) => {
println!("✓ Connected to botserver at {}", url);
let client = BotServerClient::new(url.clone(), None);
botserver_client = Some(client.clone());
agent_executor = Some(AgentToolExecutor::new(client));
}
Err(e) => {
warn!("Failed to connect to botserver: {}", e);
if config.fallback_to_local {
println!("⚠ Falling back to local execution");
}
}
}
}
}
Ok(Self {
config,
llm_provider,
local_executor,
agent_executor,
botserver_client,
})
}
pub async fn run(&mut self) -> Result<(), Box<dyn std::error::Error>> {
let mut iteration = 0;
let mut conversation_history: Vec<String> = Vec::new();
loop {
iteration += 1;
println!("=== ITERATION {} ===", iteration);
// Display execution mode
if self.agent_executor.is_some() {
println!("Mode: Multi-Agent (BotServer Facade)");
println!("Agents Available: Mantis #1-12");
} else {
println!("Mode: Local (BYOK)");
}
println!();
// Build context
let context = self.build_context(&conversation_history);
// Generate response (streaming)
let response = match self.llm_provider.generate_stream(&context, &Default::default()).await {
Ok(r) => r,
Err(e) => {
// Try fallback to local if botserver fails
if self.agent_executor.is_some() && self.config.fallback_to_local {
warn!("LLM provider failed, trying fallback: {}", e);
// Switch to local provider
continue;
} else {
return Err(e.into());
}
}
};
// Stream response to TUI
self.display_streaming_response(response).await?;
// Extract tools from response
let tools = self.extract_tools(&full_response);
// Execute tools (local or agent-based)
for tool in tools {
let result = self.execute_tool_hybrid(tool).await?;
conversation_history.push(format!("Tool: {}\nResult: {}", tool.name, result));
}
conversation_history.push(format!("Assistant: {}", full_response));
// Trim history
if conversation_history.len() > 20 {
conversation_history.drain(0..10);
}
}
}
async fn execute_tool_hybrid(&self, tool: ToolCall) -> Result<ToolResult, ToolError> {
let context = ExecutionContext {
project_path: self.config.project_path.clone(),
botserver_client: self.botserver_client.clone(),
use_local_fallback: self.config.fallback_to_local,
};
// Try agent executor first if available
if let Some(agent_executor) = &self.agent_executor {
if agent_executor.supports_tool(&tool.name) {
println!("🤖 Executing via Mantis Agent: {}", tool.name);
return agent_executor.execute(&tool, &context).await;
}
}
// Fall back to local executor
if self.local_executor.supports_tool(&tool.name) {
println!("🔧 Executing locally: {}", tool.name);
return self.local_executor.execute(&tool, &context).await;
}
Err(ToolError::UnknownTool(tool.name))
}
}
```
---
## Usage Examples
### Example 1: Local Mode (BYOK)
```bash
# .env configuration
LLM_PROVIDER=azure
PROJECT_PATH=/home/user/myproject
ENABLE_BOTSERVER_FACADE=false
```
```bash
$ botcoder
=== ITERATION 1 ===
Mode: Local (BYOK)
✓ Azure OpenAI connected
> Add authentication to this Rust project
[AI Reasoning...]
I'll add JWT authentication using the `jsonwebtoken` crate.
CHANGE: Cargo.toml
<<<<<<< CURRENT
[dependencies]
tokio = "1.0"
=======
[dependencies]
tokio = "1.0"
jsonwebtoken = "9.0"
=======
[EXECUTE] Tool 1/3: write_file -> Cargo.toml
✓ File updated
```
### Example 2: Multi-Agent Mode (BotServer Facade)
```bash
# .env configuration
LLM_PROVIDER=botserver
BOTSERVER_URL=http://localhost:8080
PROJECT_PATH=/home/user/myproject
ENABLE_BOTSERVER_FACADE=true
FALLBACK_TO_LOCAL=true
```
```bash
$ botcoder
=== ITERATION 1 ===
✓ Connected to botserver at http://localhost:8080
Mode: Multi-Agent (BotServer Facade)
Agents Available: Mantis #1-12
> Create a CRM system with contacts and deals
[CLASSIFY] Intent: APP_CREATE
[PLAN] Mantis #1 breaking down request...
✓ 12 sub-tasks identified
✓ Estimated: 45 files, 98k tokens, 2.5 hours
[BUILD] Mantis #2 generating code...
✓ contacts table schema created
✓ deals table schema created
✓ Contact Manager page generated
✓ Deal Pipeline page generated
[REVIEW] Mantis #3 validating code...
✓ HTMX patterns verified
✓ Security checks passed
✓ 0 vulnerabilities found
[OPTIMIZE] Mantis #5 refactoring...
✓ Extracted duplicate code to utils.rs
✓ Added error handling wrappers
[TEST] Mantis #8 generating tests...
✓ 87% code coverage achieved
✓ E2E tests created (chromiumoxide)
[SECURITY] Mantis #12 scanning...
✓ 0 critical vulnerabilities
✓ All dependencies up to date
[DEPLOY] Mantis #4 deploying...
Target: Internal GB Platform
✓ App deployed to /apps/my-crm/
✓ Verify at http://localhost:8080/apps/my-crm/
[DOCUMENT] Mantis #11 generating docs...
✓ README.md created
✓ API documentation generated
✓ Pipeline complete in 1m 47s
```
### Example 3: Hybrid Mode (Automatic Fallback)
```bash
$ botcoder
=== ITERATION 1 ===
Mode: Multi-Agent (BotServer Facade)
✓ Connected to botserver
> Refactor this function for better performance
[EDITOR] Mantis #5 analyzing code...
⚠ BotServer connection lost
[FALLBACK] Switching to local mode...
[LOCAL] Analyzing with Azure OpenAI...
✓ Refactoring complete
```
---
## Benefits of Hybrid Architecture
### For Users (BYOK)
- ✅ **Privacy** - Code never leaves local machine
- ✅ **Speed** - Direct LLM access, no intermediate hops
- ✅ **Cost Control** - Use your own API keys
- ✅ **Offline Capable** - Works with local LLMs (llama.cpp, Ollama)
### For Users (BotServer Facade)
- ✅ **Multi-Agent Consensus** - 12 specialized agents collaborate
- ✅ **Advanced Capabilities** - Browser automation, security scanning, test generation
- ✅ **Visual Debugging** - Watch agent reasoning in Vibe Builder UI
- ✅ **Enterprise Features** - Team sharing, approval workflows, audit trails
### Seamless Switching
- ✅ **Automatic Fallback** - If botserver unavailable, use local
- ✅ **Tool Routing** - Use agent for complex tasks, local for simple ones
- ✅ **Cost Optimization** - Reserve expensive agents for hard problems
- ✅ **Progressive Enhancement** - Start local, upgrade to multi-agent as needed
---
## Configuration Matrix
| Scenario | LLM Provider | Tools | When to Use |
|----------|--------------|-------|-------------|
| **Local Development** | Azure/Anthropic (Direct) | Local file ops | Privacy-critical code |
| **Enterprise Project** | BotServer Facade | Agent-based | Complex refactoring |
| **Open Source** | Local LLM (Ollama) | Local | No API budget |
| **Learning** | BotServer Facade | Agent-based | Study agent reasoning |
| **CI/CD** | BotServer Facade | Agent-based | Automated testing |
| **Quick Fix** | Azure/Anthropic (Direct) | Local | Fast iteration |
| **Security Audit** | BotServer Facade | Mantis #12 | Comprehensive scan |
---
## Implementation Roadmap
### Week 1: Foundation
- [x] Extract existing LLM client to trait
- [ ] Implement Azure OpenAI provider
- [ ] Implement Anthropic provider
- [ ] Add BotServerFacade provider (stub)
### Week 2: BotServer Integration
- [ ] Implement BotServerClient
- [ ] Add WebSocket progress streaming
- [ ] Implement agent query methods
- [ ] Add health check & fallback logic
### Week 3: Tool Execution
- [ ] Refactor existing tools to trait
- [ ] Implement LocalToolExecutor
- [ ] Implement AgentToolExecutor
- [ ] Add tool routing logic
### Week 4: Hybrid Loop
- [ ] Modify main loop for provider switching
- [ ] Add streaming TUI updates
- [ ] Implement automatic fallback
- [ ] Add mode indicator to UI
### Week 5: Testing & Docs
- [ ] Test all three modes (local, agent, hybrid)
- [ ] Add configuration examples
- [ ] Write migration guide
- [ ] Update README
---
## Conclusion
The **hybrid BotCoder** gives users the best of both worlds:
1. **CLI First** - Fast, local, privacy-focused development
2. **Multi-Agent Power** - On-demand access to 12 specialized agents
3. **Seamless Switching** - Automatic fallback between modes
4. **Progressive Enhancement** - Start simple, scale when needed
**Result:** A coding agent that works offline for quick fixes but can call in a full multi-agent orchestra when facing complex challenges.
**Estimated Effort:** 5 weeks (1 developer)
**Lines of Code:** ~2000 new lines (modular, trait-based)
The BotCoder CLI becomes the **control plane** for the Mantis Farm, offering both direct terminal access and a gateway to the full multi-agent OS when needed.

View file

@ -1,113 +0,0 @@
# Pending Tasks - General Bots Platform
> **Last Updated:** 2025-02-28
> **Purpose:** Track actionable tasks and improvements for the GB platform
---
## 🔐 Authentication & Identity (Zitadel)
- [ ] **Fix Zitadel setup issues**
- Check v4 configuration
- Update `zit.md` documentation
- Test login at `http://localhost:3000/login`
- Run `reset.sh` to verify clean setup
---
## 📚 Documentation Consolidation
- [ ] **Aggregate all PROMPT.md files into AGENTS.md**
- Search git history for all PROMPT.md files
- Consolidate into root AGENTS.md
- Remove duplicate/ghost lines
- Keep only AGENTS.md at project root
- [ ] **Update all README.md files**
- Add requirement: Only commit when warnings AND errors are 0
- Add requirement: Run `cargo check` after editing multiple `.rs` files
- Include Qdrant collection access instructions
- Document Vault usage for retrieving secrets
---
## 🔒 Security & Configuration (Vault)
- [ ] **Review all service configurations**
- Ensure Gmail and other service configs go to Vault
- Store per `botid + setting` or `userid` for individual settings
- [ ] **Remove all environment variables**
- Keep ONLY Vault-related env vars
- Migrate all other configs to Vault
- [ ] **Database password management**
- Generate custom passwords for all databases
- Store in Vault
- Update README with Vault retrieval instructions
---
## 🎯 Code Quality & Standards
- [ ] **Clean gbai directory**
- Remove all `.ast` files (work artifacts)
- Remove all `.json` files (work artifacts)
- Add `.gitignore` rules to prevent future commits
- [ ] **Fix logging prefixes**
- Remove duplicate prefixes in `.rs` files
- Example: Change `auth: [AUTH]` to `auth:`
- Ensure botname and GUID appear in all bot logs
- [ ] **Review bot logs format**
- Always include `botname` and `guid`
- Example: `drive_monitor:Error during sync for bot MyBot (a818fb29-9991-4e24-bdee-ed4da2c51f6d): dispatch failure`
---
## 🗄️ Database Management
- [ ] **Qdrant collection management**
- Add collection viewing instructions to README
- Document collection access methods
- Add debugging examples
- [ ] **BASIC table migration**
- Implement table migration in BASIC language
- Document migration process
---
## 🧹 Cleanup Tasks
- [ ] **Remove outdated documentation snippets**
- Remove: "Tools with C++ support, then:# Install PostgreSQL (for libpq)choco install postgresql"
---
## 📝 Notes
---
## 🚀 Priority Order
1. **High Priority:** Security & Configuration (Vault integration)
2. **High Priority:** Authentication & Identity (Zitadel setup)
3. **Medium Priority:** Code Quality & Standards
4. **Medium Priority:** Documentation Consolidation
5. **Low Priority:** Cleanup Tasks
---
## 📋 Task Template
When adding new tasks, use this format:
```markdown
- [ ] **Task Title**
- Detail 1
- Detail 2
- Related file: `path/to/file.ext`
```

View file

@ -1,156 +0,0 @@
# General Bots Security Checklist
## Critical (P1) - Must Fix Immediately
### Authentication & Authorization
- [ ] **SecurityManager Integration** - Initialize in bootstrap
- [ ] **CSRF Protection** - Enable for all state-changing endpoints
- [ ] **Error Handling** - Replace all `unwrap()`/`expect()` calls
- [ ] **Security Headers** - Apply to all HTTP routes
### Data Protection
- [ ] **TLS/MTLS** - Ensure certificates are generated and validated
- [ ] **SafeCommand Usage** - Replace all `Command::new()` calls
- [ ] **Error Sanitization** - Use `ErrorSanitizer` for all HTTP errors
## High Priority (P2) - Fix Within 2 Weeks
### Authentication
- [ ] **Passkey Support** - Complete WebAuthn implementation
- [ ] **MFA Enhancement** - Add backup codes and recovery flows
- [ ] **API Key Management** - Implement rotation and expiration
### Monitoring & Detection
- [ ] **Security Monitoring** - Integrate `SecurityMonitor` with app events
- [ ] **DLP Policies** - Configure default policies for PII/PCI/PHI
- [ ] **Rate Limiting** - Apply consistent limits across all endpoints
## Medium Priority (P3) - Fix Within 1 Month
### Infrastructure
- [ ] **Certificate Management** - Add expiration monitoring and auto-renewal
- [ ] **Audit Logging** - Ensure comprehensive coverage
- [ ] **Security Testing** - Create dedicated test suite
### Compliance
- [ ] **Security Documentation** - Update policies and procedures
- [ ] **Compliance Mapping** - Map controls to SOC2/GDPR/ISO27001
- [ ] **Evidence Collection** - Implement automated evidence gathering
## Quick Wins (Can be done today)
### Code Quality
- [ ] Run `cargo clippy --workspace` and fix all warnings
- [ ] Use `cargo audit` to check for vulnerable dependencies
- [ ] Replace 10 `unwrap()` calls with proper error handling
### Configuration
- [ ] Check `.env` files for hardcoded secrets (move to `/tmp/`)
- [ ] Verify `botserver-stack/conf/` permissions
- [ ] Review `Cargo.toml` for unnecessary dependencies
### Testing
- [ ] Test authentication flows with invalid credentials
- [ ] Verify CSRF tokens are required for POST/PUT/DELETE
- [ ] Check security headers on main endpoints
## Daily Security Tasks
### Morning Check
- [ ] Review `botserver.log` for security events
- [ ] Check `cargo audit` for new vulnerabilities
- [ ] Monitor failed login attempts
- [ ] Verify certificate expiration dates
### Ongoing Monitoring
- [ ] Watch for unusual access patterns
- [ ] Monitor DLP policy violations
- [ ] Track security metric trends
- [ ] Review audit logs for anomalies
### Weekly Tasks
- [ ] Run full security scan with protection tools
- [ ] Review and rotate any expiring credentials
- [ ] Update security dependencies
- [ ] Backup security configurations
## Emergency Response
### If you suspect a breach:
1. **Isolate** - Disconnect affected systems
2. **Preserve** - Don't delete logs or evidence
3. **Document** - Record all actions and observations
4. **Escalate** - Contact security team immediately
5. **Contain** - Implement temporary security measures
6. **Investigate** - Determine scope and impact
7. **Remediate** - Fix vulnerabilities and restore services
8. **Learn** - Update procedures to prevent recurrence
## Security Tools Commands
### Dependency Scanning
```bash
cargo audit
cargo deny check
cargo geiger
```
### Code Analysis
```bash
cargo clippy --workspace -- -D warnings
cargo fmt --check
```
### Security Testing
```bash
# Run security tests
cargo test -p bottest --test security
# Check for unsafe code
cargo geiger --forbid
# Audit dependencies
cargo audit --deny warnings
```
### Protection Tools
```bash
# Security scanning
curl -X POST http://localhost:9000/api/security/protection/scan
# Get security report
curl http://localhost:9000/api/security/protection/report
# Check tool status
curl http://localhost:9000/api/security/protection/status
```
## Common Security Issues to Watch For
### 1. Hardcoded Secrets
**Bad:** `password = "secret123"` in code
**Good:** `password = env::var("DB_PASSWORD")?` from `/tmp/`
### 2. Unsafe Command Execution
**Bad:** `Command::new("rm").arg("-rf").arg(user_input)`
**Good:** `SafeCommand::new("rm")?.arg("-rf")?.arg(sanitized_input)?`
### 3. Missing Input Validation
**Bad:** `format!("SELECT * FROM {}", user_table)`
**Good:** `validate_table_name(&user_table)?; format!("SELECT * FROM {}", safe_table)`
### 4. Information Disclosure
**Bad:** `Json(json!({ "error": e.to_string() }))`
**Good:** `let sanitized = log_and_sanitize(&e, "context", None); (StatusCode::INTERNAL_SERVER_ERROR, sanitized)`
## Security Contact Information
**Primary Contact:** security@pragmatismo.com.br
**Backup Contact:** Check `security.txt` at `/.well-known/security.txt`
**Emergency Response:** Follow procedures in `botbook/src/12-auth/security-policy.md`
---
*Last Updated: 2026-02-22*
*Review Frequency: Weekly*
*Next Review: 2026-03-01*

View file

@ -1,30 +0,0 @@
# Security Review Task List
## 1. Unsafe Unwraps in Production (Violates AGENTS.md Error Handling Rules)
The `AGENTS.md` explicitly forbids the use of `.unwrap()`, `.expect()`, `panic!()`, `todo!()`, and `unimplemented!()` in production code. A search of the codebase revealed several instances of `unwrap()` being used in non-test contexts.
**Vulnerable Locations:**
- `botserver/src/drive/drive_handlers.rs:269` - Contains a `.unwrap()` call during `Response::builder()` generation, which could panic in production.
- `botserver/src/basic/compiler/mod.rs` - Contains `unwrap()` usages outside test boundaries.
- `botserver/src/llm/llm_models/deepseek_r3.rs` - Contains `unwrap()` usages outside test boundaries.
- `botserver/src/botmodels/opencv.rs` - Test scopes use `unwrap()`, but please audit carefully for any leaks to production scope.
**Action:**
- Replace all `.unwrap()` occurrences with safe alternatives (`?`, `unwrap_or_default()`, or pattern matching with early returns) and use `ErrorSanitizer` to avoid panics.
## 2. Dependency Vulnerabilities (Found by cargo audit)
Running `cargo audit` uncovered a reported vulnerability inside the dependency tree.
**Vulnerable Component:**
- **Crate:** `glib`
- **Version:** `0.18.5`
- **Advisory ID:** `RUSTSEC-2024-0429`
- **Title:** Unsoundness in `Iterator` and `DoubleEndedIterator` impls for `glib::VariantStrIter`
- **Dependency Tree context:** It's pulled through `botdevice` and `botapp` via Tauri plugins and GTK dependencies.
**Action:**
- Review dependencies and upgrade the GTK/Glib ecosystem dependencies if patches are available, or evaluate the exact usage to assess the direct risk given the desktop GUI context.
## 3. General Posture Alignment
- Ensure all new state-changing endpoints are correctly shielded by the custom CSRF store (`redis_csrf_store.rs`). Verification is recommended as standard `tower-csrf` is absent from `Cargo.toml`.
- Confirm security headers (`Content-Security-Policy` via `headers.rs`) are indeed attached universally in `botserver` and not selectively omitted in new modules.

View file

@ -1,877 +0,0 @@
# Unified Implementation Plan: VibeCode Platform
## Executive Summary
This document **unifies** two separate task lists into a cohesive roadmap:
- **task.md**: Security & stability fixes (immediate priority)
- **TASK.md**: Feature implementation roadmap (development pipeline)
**Current Status:**
- 🎯 Backend: **80% complete** - LLM-powered app generation, multi-agent orchestration, browser automation ready
- 🎨 Frontend: **40% complete** - Vibe UI exists, missing professional tools (Monaco, Database UI, Git, Browser)
- 🔐 Security: **Needs attention** - Unsafe unwraps, dependency vulnerabilities (see Security Priorities below)
---
## Part I: Security & Stability (FROM task.md) - IMMEDIATE PRIORITY ⚠️
### 1. Unsafe Unwraps in Production (Violates AGENTS.md Error Handling)
**Issue:** The codebase uses `.unwrap()`, `.expect()`, `panic!()` in production code, which is explicitly forbidden by AGENTS.md.
**Vulnerable Locations:**
```
botserver/src/drive/drive_handlers.rs:269 - Response::builder() unwrap
botserver/src/basic/compiler/mod.rs - Multiple unwrap() calls
botserver/src/llm/llm_models/deepseek_r3.rs - unwrap() outside tests
botserver/src/botmodels/opencv.rs - Test scope unwrap() leaks
```
**Action Items:**
- [ ] Replace ALL `.unwrap()` with safe alternatives:
- Use `?` operator with proper error propagation
- Use `unwrap_or_default()` for defaults
- Use pattern matching with early returns
- Apply `ErrorSanitizer` to avoid panics
- [ ] Run `cargo clippy -- -W clippy::unwrap_used -W clippy::expect_used`
- [ ] Add unit tests verifying error paths work correctly
**Estimated Effort:** 4-6 hours
---
### 2. Dependency Vulnerabilities (Found by `cargo audit`)
**Vulnerable Component:**
- **Crate:** `glib 0.18.5`
- **Advisory:** `RUSTSEC-2024-0429`
- **Issue:** Unsoundness in `Iterator` and `DoubleEndedIterator` impls for `glib::VariantStrIter`
- **Context:** Pulled through `botdevice` and `botapp` via Tauri plugins/GTK dependencies
**Action Items:**
- [ ] Review exact usage of glib in the codebase
- [ ] Check if patches are available in newer versions
- [ ] Evaluate risk given desktop GUI context
- [ ] If critical: upgrade GTK/Glib ecosystem dependencies
- [ ] If acceptable: document risk assessment and add to security review checklist
**Estimated Effort:** 2-4 hours
---
### 3. General Security Posture Alignment
**CSRF Protection:**
- ✅ Custom CSRF store exists: `redis_csrf_store.rs`
- ⚠️ Verify: ALL state-changing endpoints use it (standard `tower-csrf` is absent from Cargo.toml)
**Security Headers:**
- ✅ `headers.rs` provides CSP, HSTS, X-Frame-Options
- ⚠️ Verify: Headers are attached UNIVERSALLY in botserver, not selectively omitted
**Action Items:**
- [ ] Audit all POST/PUT/DELETE endpoints for CSRF token validation
- [ ] Create middleware test to ensure security headers on all responses
- [ ] Document security checklist for new endpoints
**Estimated Effort:** 3-4 hours
---
## Part II: Feature Implementation Roadmap (FROM TASK.md) - DEVELOPMENT PIPELINE
### Architecture Overview
```
┌──────────────────────────────────────────────────────────────┐
│ USER REQUEST │
│ "I want a full CRM system" │
└────────────────────────┬─────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ VIBE BUILDER UI │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Agent Sidebar │ │ Canvas Area │ │
│ │ (Mantis #1-4) │ │ - Task Nodes │ │
│ │ - Status cards │ │ - Preview │ │
│ │ - Workspaces │ │ - Chat Overlay │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ NEW TOOLS TO ADD: │
│ 🔌 MCP Sources Panel ← botserver/src/sources/ui.rs │
│ 📝 Monaco Editor ← Phase 1 (Critical) │
│ 🗄️ Database Visualizer ← Phase 2 (Critical) │
│ 🐙 Git Operations ← Phase 3 (High) │
│ 🌐 Browser Automation ← Phase 4 (High) │
│ 📂 Multi-File Workspace ← Phase 5 (Medium) │
│ 🖥️ Enhanced Terminal ← Phase 6 (Medium) │
└────────────────────────┬─────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ BOTSERVER (Rust Backend) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Orchestrator │ │ AppGenerator │ │ Designer AI │ │
│ │ (5 agents) │ │(LLM-driven) │ │(modifications)│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Browser │ │ Git │ │ Terminal │ │
│ │ Automation │ │ Operations │ │ Service │ │
│ │(chromiumoxide)│ │(git2) │ │(xterm.js) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ MCP & Sources Integration ← ALREADY IMPLEMENTED │ │
│ │ - botserver/src/sources/mcp.rs │ │
│ │ - botserver/src/sources/ui.rs │ │
│ │ - /api/ui/sources/* endpoints │ │
│ └──────────────────────────────────────────────────┘ │
└────────────────────────┬─────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ GENERATED OUTPUT │
│ - PostgreSQL tables │
│ - HTML pages with HTMX │
│ - CSS styling │
│ - JavaScript │
│ - BASIC tools/schedulers │
│ - E2E tests (Playwright) │
└──────────────────────────────────────────────────────────────┘
```
---
## Part III: MCP & Sources Integration - EXISTING INFRASTRUCTURE ✅
### What Already Exists
**Backend Implementation (botserver/src/sources/):**
```
sources/
├── mod.rs # Module exports
├── mcp.rs # MCP client, connection, server types
├── ui.rs # HTML pages for /suite/sources/*
├── knowledge_base.rs # Knowledge base upload/query
└── sources_api # API endpoints
```
**API Endpoints (defined in botserver/src/core/urls.rs):**
```
/sources/*:
/suite/sources - Main sources list page
/suite/sources/mcp/add - Add MCP server form
/suite/sources/mcp/catalog - MCP server catalog
/api/ui/sources/*:
/api/ui/sources/mcp - List MCP servers
/api/ui/sources/mcp/:name - Get server details
/api/ui/sources/mcp/:name/enable - Enable server
/api/ui/sources/mcp/:name/disable - Disable server
/api/ui/sources/mcp/:name/tools - List server tools
/api/ui/sources/mcp/:name/test - Test server connection
/api/ui/sources/mcp/scan - Scan for MCP servers
/api/ui/sources/mcp-servers - Get server catalog
/api/ui/sources/kb/upload - Upload to knowledge base
/api/ui/sources/kb/list - List knowledge base docs
/api/ui/sources/kb/query - Query knowledge base
/api/ui/sources/repositories - List repositories
/api/ui/sources/apps - List connected apps
```
**Vibe UI Integration (botui/ui/suite/):**
```
botui/ui/suite/
├── partials/
│ └── vibe.html # Main Vibe Builder UI
│ # - Agent sidebar (Mantis #1-4)
│ # - Canvas area with task nodes
│ # - Chat overlay
│ # - Preview panel
├── vibe/
│ └── agents-sidebar.css # Styles for agent sidebar
├── js/
│ └── chat-agent-mode.js # Agent-mode JavaScript
└── css/
└── chat-agent-mode.css # Agent-mode styles
```
### Integration Task: Add MCP Panel to Vibe UI
**Goal:** Add a "Sources" panel to Vibe that shows connected MCP servers and allows management.
**Action Items:**
1. **Create MCP Panel Component:**
- File: `botui/ui/suite/partials/vibe-mcp-panel.html`
- Features:
- List connected MCP servers
- Show server status (active/inactive)
- Display available tools per server
- Quick enable/disable toggles
- "Add Server" button (opens `/suite/sources/mcp/add`)
2. **Add JavaScript:**
- File: `botui/ui/suite/js/vibe-mcp.js`
- Fetch servers from `/api/ui/sources/mcp`
- Handle enable/disable actions
- Update server status in real-time
- Display tool risk levels
3. **Add Styles:**
- File: `botui/ui/suite/vibe/mcp-panel.css`
- Match existing agents-sidebar.css aesthetic
- Server cards with status indicators
- Tool badges with risk levels
4. **Integrate into Vibe:**
- Add "Sources" tab to Vibe sidebar
- Load MCP panel when tab clicked
- Show server count badge
**Estimated Effort:** 6-8 hours
---
## Part IV: Implementation Phases (UPDATED WITH MCP INTEGRATION)
### Phase 0: Security & Stability ⚠️ - IMMEDIATE (Week 0)
**Priority: CRITICAL - Must complete before any feature work**
**Tasks:**
1. [ ] Fix all unsafe `unwrap()` calls
2. [ ] Address dependency vulnerabilities
3. [ ] Verify CSRF & security headers coverage
**Estimated Effort:** 9-14 hours
**Success Criteria:**
- ✅ Zero `unwrap()` in production code
- ✅ `cargo audit` passes cleanly
- ✅ All state-changing endpoints use CSRF tokens
- ✅ All responses include security headers
---
### Phase 0.5: MCP Integration in Vibe (Week 0.5)
**Priority: HIGH - Leverage existing infrastructure**
**Tasks:**
1. [ ] Create MCP panel component
2. [ ] Add JavaScript for server management
3. [ ] Style panel to match Vibe aesthetic
4. [ ] Integrate into Vibe sidebar
**Estimated Effort:** 6-8 hours
**Success Criteria:**
- ✅ MCP servers visible in Vibe UI
- ✅ Can enable/disable servers
- ✅ Can see available tools
- ✅ Can add new servers
---
### Phase 1: Code Editor Integration (P0 - Critical)
**Goal:** Replace textarea with professional code editor
**Tasks:**
1. **Download Monaco Editor**
```bash
cd botui
npm install monaco-editor@0.45.0
cp -r node_modules/monaco-editor min/vs ui/suite/js/vendor/
```
2. **Create Editor Component**
- `botui/ui/suite/partials/editor.html`
- Monaco container with tab bar
- File tree sidebar
- Save/Publish buttons
3. **Editor JavaScript**
- `botui/ui/suite/js/editor.js`
- Monaco initialization
- Language detection (.html, .css, .js, .bas, .json)
- Tab management (open, close, switch)
- Auto-save with WebSocket sync
4. **API Endpoints**
- `botserver/src/api/editor.rs`
- GET `/api/editor/file/{path}` - Read file
- POST `/api/editor/file/{path}` - Save file
- GET `/api/editor/files` - List files
5. **Integration**
- Update `chat-agent-mode.html` - replace textarea with Monaco
- Update `vibe.html` - add editor panel
- Add keyboard shortcuts (Ctrl+S, Ctrl+P, Ctrl+Shift+F)
**Success Criteria:**
- Monaco loads in < 2 seconds
- Syntax highlighting for 5+ languages
- Multi-file tabs work
- Auto-save completes successfully
**Estimated Effort:** 8-12 hours
---
### Phase 2: Database UI & Schema Visualization (P0 - Critical)
**Goal:** Visual database management and query builder
**Tasks:**
1. **Schema Visualizer Component**
- `botui/ui/suite/partials/database.html`
- Canvas-based ER diagram
- Table cards with fields
- Relationship lines (foreign keys)
- Zoom/pan controls
2. **Database JavaScript**
- `botui/ui/suite/js/database.js`
- Fetch schema: `/api/database/schema`
- Render tables using Canvas API
- Click table → show field details
- Drag to rearrange
3. **Query Builder UI**
- Visual SELECT builder
- Table selection dropdown
- Join interface
- Filter conditions
- SQL preview pane
4. **Data Grid**
- Sortable columns
- Inline editing
- Pagination
- Export (CSV/JSON)
5. **Backend API**
- `botserver/src/api/database.rs`
- GET `/api/database/schema` - Tables, fields, relationships
- GET `/api/database/table/{name}/data` - Paginated data
- POST `/api/database/query` - Execute SQL
- POST `/api/database/table/{name}/row` - Insert/update
- DELETE `/api/database/table/{name}/row/{id}` - Delete
**Success Criteria:**
- ER diagram shows all tables
- Query builder generates valid SQL
- Data grid supports inline edits
- Export works correctly
**Estimated Effort:** 16-20 hours
---
### Phase 3: Git Operations UI (P1 - High Priority)
**Goal:** Version control interface in Vibe
**Tasks:**
1. **Git Status Panel**
- `botui/ui/suite/partials/git-status.html`
- File list with status icons
- Stage/unstage checkboxes
- "Commit" button
2. **Diff Viewer**
- `botui/ui/suite/partials/git-diff.html`
- Side-by-side comparison
- Line highlighting (green/red)
- Syntax highlighting
3. **Commit Interface**
- Message input
- "Commit & Push" button
- Progress indicator
4. **Branch Manager**
- Branch dropdown
- "New Branch" dialog
- Switch/delete actions
5. **Commit Timeline**
- Vertical timeline
- Author, date, message
- Click → view diff
6. **Backend API**
- `botserver/src/api/git.rs`
- GET `/api/git/status` - Git status
- GET `/api/git/diff/{file}` - File diff
- POST `/api/git/commit` - Create commit
- POST `/api/git/push` - Push to remote
- GET `/api/git/branches` - List branches
- POST `/api/git/branch/{name}` - Create/switch
- GET `/api/git/log` - Commit history
**Success Criteria:**
- Git status displays correctly
- Diff viewer shows side-by-side
- Commit workflow works end-to-end
- Branch switching succeeds
**Estimated Effort:** 12-16 hours
---
### Phase 4: Browser Automation Engine (P1 - High Priority)
**Goal:** Pure Rust browser automation for testing & recording
**Why Rust + Chromiumoxide:**
- ✅ Already in workspace: `chromiumoxide = "0.7"`
- ✅ No Node.js dependency
- ✅ Feature flag exists: `browser` in botserver/Cargo.toml
- ✅ Reference implementation: bottest/src/web/browser.rs (1000+ lines)
**Tasks:**
1. **Core Browser Module**
- `botserver/src/browser/mod.rs`
- `BrowserSession` - Manage browser instance
- `BrowserManager` - Session lifecycle
- Methods: `navigate()`, `click()`, `fill()`, `screenshot()`, `execute()`
2. **Action Recorder**
- `botserver/src/browser/recorder.rs`
- `RecordedAction` - Navigate, Click, Fill, Wait, Assert
- `ActionRecorder` - Record/stop/export
- Export as Playwright test
3. **Test Validator**
- `botserver/src/browser/validator.rs`
- Check for flaky selectors
- Validate wait conditions
- Suggest improvements via Designer AI
4. **Browser API**
- `botserver/src/browser/api.rs`
- POST `/api/browser/session` - Create session
- POST `/api/browser/session/:id/execute` - Run action
- GET `/api/browser/session/:id/screenshot` - Capture
- POST `/api/browser/session/:id/record/start` - Start recording
- POST `/api/browser/session/:id/record/stop` - Stop & get actions
- GET `/api/browser/session/:id/record/export` - Export test
5. **Vibe UI - Browser Panel**
- `botui/ui/suite/partials/browser-controls.html`
- URL bar with navigation buttons
- Record/Stop/Export buttons
- Actions timeline
- Browser preview iframe
- Screenshot gallery
- `botui/ui/suite/js/browser.js`
- Session management
- Action recording
- Test export
- `botui/ui/suite/css/browser.css`
- Browser panel styling
- Recording indicator animation
- Actions timeline
- Screenshot gallery grid
6. **Integration with Vibe**
- Add "Browser Automation" button to Vibe toolbar
- Load browser-controls.html in panel
- Element picker for selector capture
- Screenshot capture & gallery
**Success Criteria:**
- Can navigate to any URL
- Element picker captures selectors
- Recording generates valid Playwright tests
- Screenshots capture correctly
**Estimated Effort:** 20-24 hours
---
### Phase 5: Multi-File Editing Workspace (P2 - Medium Priority)
**Goal:** Professional multi-file editing
**Tasks:**
1. **Tab Management**
- File tabs with close buttons
- Active tab highlighting
- Tab overflow scrolling
- Drag to reorder
2. **Split-Pane Layout**
- Split horizontal/vertical buttons
- Resize handles
- 2x2 grid max
3. **File Comparison**
- Side-by-side diff
- Line-by-line navigation
- Copy changes (L→R)
4. **File Tree Sidebar**
- Nested folders
- File type icons
- Expand/collapse
- Double-click to open
5. **Quick Open**
- Ctrl+P → Search files
- Fuzzy matching
- Arrow navigation
6. **Project Search**
- Ctrl+Shift+F → Search all files
- Results with line numbers
- Click to open file
**Success Criteria:**
- 10+ files open in tabs
- Split view works (2-4 panes)
- File comparison displays diffs
- Quick open searches files
**Estimated Effort:** 12-16 hours
---
### Phase 6: Enhanced Terminal (P2 - Medium Priority)
**Goal:** Interactive shell in Vibe
**Tasks:**
1. **Terminal Container**
- xterm.js integration (already vendor file)
- Multiple terminal tabs
- Fit addon for auto-resize
2. **WebSocket Terminal**
- Bi-directional WebSocket: `/ws/terminal/{session_id}`
- Protocol: `{"type": "input", "data": "command\n"}`
- Handle ANSI escape codes
3. **Command History**
- Up/Down arrows
- Ctrl+R search
- Persist in localStorage
4. **Command Completion**
- Tab completion
- File path completion
- Command flags
5. **Backend Terminal Server**
- Spawn PTY per session
- WebSocket handler
- Clean up on disconnect
6. **File Transfer**
- Drag file to upload
- `upload` / `download` commands
- Progress bars
**Success Criteria:**
- Can type commands & see output
- Arrow keys navigate history
- Can run vim, top, etc.
- Multiple terminals work
**Estimated Effort:** 10-14 hours
---
### Phase 7: Advanced CRM Templates (P2 - Medium Priority)
**Goal:** Pre-built CRM accelerators
**Tasks:**
1. **Template System**
- `botserver/src/templates/crm/`
- Template JSON definitions
- Prompt templates
- Field libraries
2. **CRM Templates**
- **Sales CRM**
- Tables: contacts, leads, opportunities, accounts, activities
- Pages: dashboard, pipeline, contacts list
- Tools: lead_scoring, email_automation
- Schedulers: daily_summary, weekly_review
- **Real Estate CRM**
- Tables: properties, clients, showings, offers
- Pages: property gallery, client portal
- Tools: mls_sync, showing_scheduler
- Schedulers: showing_reminders, market_update
- **Healthcare CRM**
- Tables: patients, appointments, treatments, insurance
- Pages: patient portal, appointment scheduler
- Tools: insurance_verification, appointment_reminders
- Schedulers: daily_appointments, insurance_alerts
3. **Template Gallery UI**
- `botui/ui/suite/partials/template-gallery.html`
- Template cards with descriptions
- Preview screenshots
- "Use Template" button
4. **Template Generator**
- Load template JSON
- Customize with user details
- Generate all files
- Deploy to /apps/{name}
**Success Criteria:**
- Can select template from gallery
- Template generates full CRM
- Customization works
- Generated CRM is functional
**Estimated Effort:** 20-24 hours
---
## Part V: Technical Implementation Notes
### Code Quality Standards (per AGENTS.md)
**MUST Follow:**
1. ✅ **Error Handling** - NO panics, use `?` operator
2. ✅ **Safe Commands** - Use `SafeCommand` wrapper
3. ✅ **Error Sanitization** - Use `ErrorSanitizer`
4. ✅ **SQL Safety** - Use `sql_guard`
5. ✅ **Rate Limiting** - Per-IP and per-User limits
6. ✅ **CSRF Protection** - CSRF tokens on state-changing endpoints
7. ✅ **Security Headers** - CSP, HSTS, X-Frame-Options, etc.
8. ✅ **No CDNs** - All assets local
9. ✅ **File Size** - Max 450 lines per file
10. ✅ **Clippy Clean** - 0 warnings, no `#[allow()]`
### File Organization
**Botui (Frontend):**
```
botui/ui/suite/
partials/
editor.html
database.html
git-status.html
git-diff.html
browser-controls.html
terminal.html
template-gallery.html
vibe-mcp-panel.html # NEW - MCP integration
js/
editor.js
database.js
git.js
browser.js
terminal.js
templates.js
vibe-mcp.js # NEW - MCP integration
css/
editor.css
database.css
git.css
browser.css
terminal.css
templates.css
vibe/
mcp-panel.css # NEW - MCP integration
```
**Botserver (Backend):**
```
botserver/src/
api/
editor.rs
database.rs
git.rs
browser/
mod.rs # BrowserSession, BrowserManager
recorder.rs # ActionRecorder
validator.rs # TestValidator
api.rs # HTTP endpoints
test_generator.rs
templates/
crm/
sales.json
real_estate.json
healthcare.json
mod.rs
sources/ # ALREADY EXISTS
mod.rs
mcp.rs
ui.rs
knowledge_base.rs
```
### Dependencies
**Already in Workspace:**
```toml
chromiumoxide = "0.7" # Browser automation
tokio = "1.41" # Async runtime
axum = "0.7" # HTTP framework
diesel = "2.1" # Database
git2 = "0.18" # Git operations (add if needed)
```
**Frontend (download & serve locally):**
```
monaco-editor@0.45.0 # Code editor
xterm.js@5.3.0 # Terminal (already vendor file)
```
---
## Part VI: Testing Strategy
### Unit Tests
- All new modules need unit tests
- Test coverage > 80%
- Location: `botserver/src/<module>/tests.rs`
### Integration Tests
- End-to-end workflows
- Location: `bottest/tests/integration/`
### E2E Tests
- Use chromiumoxide (bottest infrastructure)
- Location: `bottest/tests/e2e/`
- Test scenarios:
- Generate CRM from template
- Edit in Monaco editor
- View database schema
- Create git commit
- Record browser test
---
## Part VII: Rollout Plan (UPDATED)
### Milestone 0: Security & MCP (Week 0)
- **Day 1-2:** Fix all unsafe `unwrap()` calls
- **Day 3:** Address dependency vulnerabilities
- **Day 4:** Verify CSRF & security headers
- **Day 5:** Integrate MCP panel into Vibe UI
### Milestone 1: Core Editor (Week 1)
- Phase 1 complete (Monaco integration)
### Milestone 2: Database & Git (Week 2)
- Phase 2 complete (Database UI)
- Phase 3 complete (Git Operations)
### Milestone 3: Browser & Workspace (Week 3)
- Phase 4 complete (Browser Automation)
- Phase 5 complete (Multi-File Editing)
### Milestone 4: Terminal & Templates (Week 4)
- Phase 6 complete (Enhanced Terminal)
- Phase 7 complete (CRM Templates)
---
## Part VIII: Success Metrics
### Security Milestones
- ✅ Zero `unwrap()` in production code
- ✅ `cargo audit` passes
- ✅ All endpoints have CSRF + security headers
### Phase 0.5: MCP Integration
- ✅ MCP panel visible in Vibe sidebar
- ✅ Can enable/disable servers
- ✅ Can view available tools
- ✅ Can add new servers
### Phase 1: Code Editor
- Monaco loads < 2 seconds
- 5+ syntax highlighters work
- Multi-file tabs functional
- Auto-save succeeds
### Phase 2: Database UI
- Schema visualizer displays all tables
- Query builder generates valid SQL
- Data grid supports inline edits
- Export functionality works
### Phase 3: Git Operations
- Git status shows changed files
- Diff viewer shows side-by-side
- Commit workflow works
- Branch switching succeeds
### Phase 4: Browser Automation
- Can navigate to any URL
- Element picker captures selectors
- Recording generates valid tests
- Screenshots capture correctly
### Phase 5: Multi-File Workspace
- 10+ files open in tabs
- Split view supports 2-4 panes
- File comparison works
- Project search is fast (< 1s for 100 files)
### Phase 6: Terminal
- Interactive shell works
- Can run vim, top, etc.
- Multiple terminals run simultaneously
- File transfer works
### Phase 7: CRM Templates
- 3+ CRM templates available
- Generation takes < 30 seconds
- Generated CRMs are fully functional
- Industry-specific features work
---
## Conclusion
The BotUI platform has a **powerful backend** capable of generating full applications via LLM. The main gaps are in the **frontend user experience** and **security hardening**.
**Key Insight:**
- The `botserver/src/sources/` infrastructure for MCP is **already complete**
- The Vibe UI exists and is functional
- We need to **connect** them: add an MCP panel to the Vibe sidebar
**Updated Priority Order:**
1. ⚠️ **Security fixes** (Week 0) - Unblock development risk
2. 🔌 **MCP integration** (Week 0.5) - Quick win, leverage existing code
3. 📝 **Code editor** (Week 1) - Core developer tool
4. 🗄️ **Database UI** (Week 2) - Visual data management
5. 🐙 **Git operations** (Week 2) - Version control
6. 🌐 **Browser automation** (Week 3) - Testing & recording
7. 📂 **Multi-file workspace** (Week 3) - Professional editing
8. 🖥️ **Terminal** (Week 4) - Interactive shell
9. 📇 **CRM templates** (Week 4) - Accelerators
Once these phases are complete, VibeCode will match or exceed Claude Code's capabilities while offering:
✅ **Multi-user SaaS deployment**
**Visual app building** (Vibe Builder)
✅ **Enterprise-grade multi-agent orchestration**
**Pure Rust backend** (no Node.js dependency)
**Integrated MCP servers** (extensible tools)
**Integrated browser automation** (chromiumoxide)
✅ **Professional development environment**
**Total Estimated Effort:** 113-141 hours (~3-4 weeks with 1 developer)

146
prompts/campaigns.md Normal file
View file

@ -0,0 +1,146 @@
# Email Campaigns — Feature Plan
## Existing Foundation (botserver/src/marketing/)
- `campaigns.rs` — CrmCampaign model, CRUD handlers
- `metrics.rs` — CampaignMetrics, ChannelBreakdown, open/click/conversion rates
- `lists.rs` — recipient lists
- `templates.rs` — content templates
- `triggers.rs` — event-based sending
- `email/tracking.rs` — open/click tracking pixels
---
## Features to Build
### 1. Insights Dashboard
**What:** Time series views of delivery + engagement metrics per campaign.
**Data points per time bucket (hourly/daily):**
- Sent, delivered, bounced, failed
- Opens (unique + total), clicks, replies, unsubscribes
- Delivery rate, open rate, click-to-open rate (CTOR)
**Filters/pivots:**
- By mailbox provider (Gmail, Outlook, Yahoo, etc. — parsed from MX/SMTP response)
- By sender identity (from address / domain)
- By campaign or list
- Message search → show exact SMTP response from provider
**Implementation:**
- Add `email_delivery_events` table: `(id, campaign_id, recipient_id, event_type, provider, smtp_response, ts)`
- API: `GET /api/campaigns/:id/insights?from=&to=&group_by=provider|identity|day`
- UI: HTMX + chart.js time series (local vendor)
---
### 2. Advisor Recommendations
**What:** Analyze sending config + results and surface actionable fixes.
**Checks to run:**
| Check | Signal | Recommendation |
|---|---|---|
| SPF/DKIM/DMARC | DNS lookup | "Add missing record" |
| Bounce rate > 5% | delivery_events | "Clean list — remove hard bounces" |
| Open rate < 15% | metrics | "Improve subject line / send time" |
| Spam complaints > 0.1% | FBL data | "Remove complainers immediately" |
| Sending from new IP | warmup_schedule | "Follow warmup plan" |
| List age > 6 months | list.last_sent | "Re-engagement campaign before bulk send" |
**Implementation:**
- `marketing/advisor.rs``AdvisorEngine::analyze(campaign_id) -> Vec<Recommendation>`
- API: `GET /api/campaigns/:id/advisor`
- Runs automatically after each campaign completes
---
### 3. IP Warmup (like OneSignal / Mailchimp)
**What:** Gradually increase daily send volume over 46 weeks to build sender reputation.
**Warmup schedule (standard):**
| Day | Max emails/day |
|---|---|
| 12 | 50 |
| 34 | 100 |
| 57 | 500 |
| 810 | 1,000 |
| 1114 | 5,000 |
| 1521 | 10,000 |
| 2228 | 50,000 |
| 29+ | unlimited |
**Rules:**
- Only send to most engaged subscribers first (opened in last 90 days)
- Stop warmup if bounce rate > 3% or complaint rate > 0.1%
- Resume next day at same volume if paused
**Implementation:**
- `marketing/warmup.rs``WarmupSchedule`, `WarmupEngine::get_daily_limit(ip, day) -> u32`
- `warmup_schedules` table: `(id, ip, started_at, current_day, status, paused_reason)`
- Scheduler checks warmup limit before each send batch
- API: `GET /api/warmup/status`, `POST /api/warmup/start`
---
### 4. Optimized Shared Delivery
**What:** Auto-select best sending IP based on real-time reputation signals.
**Logic:**
- Track per-IP: bounce rate, complaint rate, delivery rate (last 24h)
- Score each IP: `score = delivery_rate - (bounce_rate * 10) - (complaint_rate * 100)`
- Route each send to highest-scored IP for that destination provider
- Rotate IPs to spread load and preserve reputation
**Implementation:**
- `marketing/ip_router.rs``IpRouter::select(destination_domain) -> IpAddr`
- `ip_reputation` table: `(ip, provider, bounces, complaints, delivered, window_start)`
- Plugs into Stalwart send path via botserver API
---
### 5. Modern Email Marketing Features
| Feature | Description |
|---|---|
| **Send time optimization** | ML-based per-contact best send time (based on past open history) |
| **A/B testing** | Split subject/content, auto-pick winner after N hours |
| **Suppression list** | Global unsubscribe/bounce/complaint list, auto-applied to all sends |
| **Re-engagement flows** | Auto-trigger "we miss you" to contacts inactive > 90 days |
| **Transactional + marketing separation** | Separate IPs/domains for transactional vs bulk |
| **One-click unsubscribe** | RFC 8058 `List-Unsubscribe-Post` header on all bulk sends |
| **Preview & spam score** | Pre-send SpamAssassin score check |
| **Link tracking** | Redirect all links through tracker, record clicks per contact |
| **Webhook events** | Push delivery events to external URLs (Stalwart webhook → botserver) |
---
## DB Tables to Add
```sql
email_delivery_events (id, campaign_id, recipient_id, event_type, provider, smtp_code, smtp_response, ts)
warmup_schedules (id, ip, started_at, current_day, daily_limit, status, paused_reason)
ip_reputation (id, ip, provider, delivered, bounced, complained, window_start)
advisor_recommendations (id, campaign_id, check_name, severity, message, created_at, dismissed)
ab_tests (id, campaign_id, variant_a, variant_b, split_pct, winner, decided_at)
suppression_list (id, org_id, email, reason, added_at)
```
---
## Files to Create
```
botserver/src/marketing/
├── warmup.rs — IP warmup engine + schedule
├── advisor.rs — recommendation engine
├── ip_router.rs — optimized IP selection
├── ab_test.rs — A/B test logic
├── suppression.rs — global suppression list
└── send_time.rs — send time optimization
```
---
## Existing Code to Extend
- `marketing/metrics.rs` → add time-series queries + provider breakdown
- `marketing/campaigns.rs` → add warmup_enabled, ab_test_id fields
- `email/tracking.rs` → already has open/click tracking, extend with provider parsing
- `core/shared/schema/` → add new tables above

91
prompts/con.md Normal file
View file

@ -0,0 +1,91 @@
# Config from Vault Plan - ALL COMPONENTS
## Goal
ALL component configs read from Vault at runtime instead of hardcoded `InternalUrls`.
## Current State
- Only `VAULT_ADDR` and `VAULT_TOKEN` in `.env`
- ALL other configs hardcoded in `InternalUrls` (urls.rs)
- Component credentials stored in Vault defaults but NOT read at runtime
## ALL Components to Update
| Component | Current Hardcoded | Vault Path | Keys Needed |
|-----------|-----------------|------------|-------------|
| **Drive** | `localhost:9100` | `secret/gbo/drive` | host, port, accesskey, secret |
| **Database** | `localhost:5432` | `secret/gbo/tables` | host, port, database, username, password |
| **Cache** | `localhost:6379` | `secret/gbo/cache` | host, port, password |
| **Directory** | `localhost:8300` | `secret/gbo/directory` | url, project_id, client_id, client_secret |
| **Email/SMTP** | `localhost:8025` | `secret/gbo/email` | smtp_host, smtp_port, smtp_user, smtp_password, smtp_from |
| **LLM** | `localhost:8081` | `secret/gbo/llm` | url, model, openai_key, anthropic_key, ollama_url |
| **LiveKit** | `localhost:7880` | `secret/gbo/meet` | url, app_id, app_secret |
| **VectorDB** | `localhost:6334` | `secret/gbo/vectordb` | url, api_key |
| **Embedding** | `localhost:8082` | `secret/gbo/embedding` | url |
| **Qdrant** | `localhost:6334` | `secret/gbo/qdrant` | url, api_key |
| **Forgejo** | `localhost:3000` | `secret/gbo/forgejo` | url, token |
| **Observability** | `localhost:8086` | `secret/gbo/observability` | url, org, bucket, token |
| **ALM** | `localhost:9000` | `secret/gbo/alm` | url, token, default_org |
| **Cloud** | - | `secret/gbo/cloud` | region, access_key, secret_key |
## Implementation Steps
### Step 1: Modify `config/mod.rs`
Change ALL configs to read from Vault.
**Before:**
```rust
let drive = DriveConfig {
server: InternalUrls::DRIVE.to_string(),
...
};
```
**After:**
```rust
let drive = DriveConfig {
server: get_vault_or_default("gbo/drive", "host", "localhost:9100"),
access_key: get_vault_or_default("gbo/drive", "accesskey", "minioadmin"),
secret_key: get_vault_or_default("gbo/drive", "secret", "minioadmin"),
};
```
Same pattern for Database, Cache, Email, LLM, etc.
### Step 2: Add Helper Function
Create in `secrets/mod.rs`:
```rust
pub fn get_vault_or_default(path: &str, key: &str, default: &str) -> String {
// Try to get from Vault at runtime
// Fallback to default if not found
}
```
### Step 3: Container Installer (`facade.rs`)
When running `botserver install <component> --container`:
1. Create container
2. Install component
3. **Store URL + credentials in Vault** (`secret/gbo/<component>`)
4. Botserver reads from Vault at runtime
### Step 4: Default Values
Keep defaults in `secrets/mod.rs` for fallback when Vault not available.
## Files to Modify
- `src/core/config/mod.rs` - Read ALL from Vault
- `src/core/secrets/mod.rs` - Add helper + keep defaults
- `src/core/package_manager/facade.rs` - Container installer stores in Vault
## Test Commands
```bash
# Store ANY component config in Vault (secure interactive)
botserver vault put gbo/drive
botserver vault put gbo/tables
botserver vault put gbo/cache
# Verify
botserver vault get gbo/drive
```
## Key Principle
**Only VAULT_ADDR and VAULT_TOKEN in .env!**
All other configs from Vault at runtime.

272
prompts/integratedsuite.md Normal file
View file

@ -0,0 +1,272 @@
# Integrated Suite — Conversational Interface Plan
> **Pattern:** Every suite app exposes its own `PROMPT.md` + internal tools.
> The shared chat bar activates app-specific context when the user is inside that app.
> WhatsApp campaigns is the first full example.
---
## Architecture
```
User (WhatsApp / Suite chat bar)
BotOrchestrator (core/bot/mod.rs)
detect active app context
load app PROMPT.md + app InternalTools
LLM with tools → tool_executor.rs
app data / actions
```
### Key existing pieces
| File | Role |
|---|---|
| `core/bot/mod.rs` | `get_session_tools()` + `ToolExecutor::execute_tool_call()` |
| `tasks/PROMPT.md` | Pattern for app-level LLM prompt |
| `marketing/whatsapp.rs` | WhatsApp campaign send/metrics |
| `marketing/campaigns.rs` | Campaign CRUD |
| `marketing/lists.rs` | Recipient lists |
| `botui/ui/suite/campaigns/` | Campaigns UI |
---
## Standard: Every Suite App
### 1. `PROMPT.md` per app folder
Location: `botserver/src/<app>/PROMPT.md`
```markdown
# <App> — Internal Tools Guide
You are the <App> assistant. When the user is in <App>, you have access to:
- tool: list_<entities>
- tool: create_<entity>
- tool: search_<entity>
- tool: <app_specific_action>
Rules:
- Always confirm destructive actions before executing
- Show results as structured summaries, not raw JSON
- If user uploads a file, parse it and confirm before acting
```
### 2. `tools.rs` per app
Location: `botserver/src/<app>/tools.rs`
Registers `Vec<Tool>` (LLM function-calling schema) + handler mapping.
Loaded by `get_session_tools()` when session's active app = this app.
### 3. App context detection
`core/bot/mod.rs` reads `session.active_app` (set by UI via `POST /api/session/context`).
Loads `<app>/PROMPT.md` as system prompt prefix + `<app>/tools.rs` tools.
---
## WhatsApp Campaigns — Full Conversational Flow
### Meta Rules (enforced in tools)
- Only approved Message Templates for marketing (non-session-initiated)
- 24h session window for free-form after user replies
- Media: image/video/document via Media Upload API before send
- Opt-out: always honor STOP, add to suppression list immediately
- Rate: respect per-phone-number rate limits (1000 msg/s business tier)
- Template category: MARKETING requires explicit opt-in from recipient
### Conversation Flow (WhatsApp → campaign creation)
```
User sends to bot number:
"I want to send a campaign"
Bot: "Great! Send me:
1. Your contact list (.xlsx or .csv)
2. The message text
3. An image (optional)
4. When to send (or 'now')"
User uploads contacts.xlsx
[tool: parse_contact_file]
→ extract phone numbers, names
→ validate E.164 format
→ show preview: "Found 342 contacts. First 3: +55..."
User sends message text
[tool: check_template_compliance]
→ check if free-form or needs approved template
→ if template needed: list available approved templates
→ suggest closest match
User sends image (optional)
[tool: upload_media]
→ upload to Meta Media API
→ return media_id
Bot: "Ready to send to 342 contacts at 14:00 today.
Preview: [image] Hello {name}, ...
Estimated cost: $X
Confirm? (yes/no)"
User: "yes"
[tool: create_and_schedule_campaign]
→ create campaign record
→ apply warmup limit if IP warming
→ schedule via TaskScheduler
```
### WhatsApp Campaign Tools (`marketing/whatsapp_tools.rs`)
```rust
// Tool definitions for LLM function calling
pub fn whatsapp_campaign_tools() -> Vec<Tool> {
vec![
Tool::new("parse_contact_file", "Parse uploaded xlsx/csv into contact list"),
Tool::new("list_templates", "List approved WhatsApp message templates"),
Tool::new("check_template_compliance", "Check if message needs approved template"),
Tool::new("upload_media", "Upload image/video to Meta Media API"),
Tool::new("preview_campaign", "Show campaign preview with cost estimate"),
Tool::new("create_and_schedule_campaign", "Create campaign and schedule send"),
Tool::new("get_campaign_status", "Get delivery/read metrics for a campaign"),
Tool::new("pause_campaign", "Pause an in-progress campaign"),
Tool::new("list_campaigns", "List recent campaigns with metrics"),
Tool::new("add_to_suppression", "Add number to opt-out list"),
]
}
```
### WhatsApp PROMPT.md (`marketing/WHATSAPP_PROMPT.md`)
```markdown
# WhatsApp Campaign Assistant
You help users create and manage WhatsApp marketing campaigns.
## Meta Platform Rules (MANDATORY)
- Marketing messages MUST use pre-approved templates outside 24h session window
- Always check opt-in status before adding to campaign
- Honor STOP/unsubscribe immediately via add_to_suppression tool
- Never send more than warmup daily limit if IP is warming up
- Image must be uploaded via upload_media before referencing in campaign
## Conversation Style
- Guide step by step: contacts → message → media → schedule → confirm
- Show cost estimate before confirming
- After send: proactively share open/read rates when available
## File Handling
- .xlsx/.csv → use parse_contact_file tool
- Images → use upload_media tool
- Always confirm parsed data before proceeding
```
---
## Integrated Suite Chat Bar — Standard
### How it works
1. User opens any suite app (CRM, Campaigns, Drive, etc.)
2. Chat bar at bottom activates with app context
3. `POST /api/session/context { app: "campaigns" }` sets `session.active_app`
4. BotOrchestrator loads `campaigns/PROMPT.md` + `campaigns/tools.rs`
5. User can ask natural language questions or trigger actions
### Examples per app
| App | Example query | Tool activated |
|---|---|---|
| **Campaigns** | "How did last week's campaign perform?" | `get_campaign_metrics` |
| **CRM** | "Show deals closing this month" | `list_deals` with filter |
| **Drive** | "Find the Q1 report" | `search_files` |
| **Tasks** | "Create a task to follow up with Acme" | `create_task` |
| **People** | "Who hasn't been contacted in 30 days?" | `list_contacts` with filter |
| **Mail** | "Summarize unread emails from clients" | `list_emails` + LLM summary |
| **Sheet** | "What's the total revenue in column D?" | `query_sheet` |
| **Learn** | "What does our refund policy say?" | `search_kb` |
---
## Implementation Plan
### Phase 1 — Infrastructure (1 sprint)
- [ ] `core/bot/mod.rs` — read `session.active_app`, load app PROMPT + tools
- [ ] `core/tool_context.rs` — app tool registry: `register_app_tools(app_name) -> Vec<Tool>`
- [ ] `POST /api/session/context` — set active app from UI
- [ ] Suite chat bar UI component (`botui/ui/suite/partials/chatbar.html`)
### Phase 2 — WhatsApp Campaigns (1 sprint)
- [ ] `marketing/whatsapp_tools.rs` — 10 tools above
- [ ] `marketing/WHATSAPP_PROMPT.md`
- [ ] `marketing/file_parser.rs` — xlsx/csv → contact list
- [ ] Meta warmup enforcement in send path
- [ ] Conversational campaign creation flow (state machine in session)
### Phase 3 — App-by-app rollout (1 app/sprint)
Priority order based on value:
1. CRM (deals, contacts, pipeline queries)
2. Campaigns (email + WhatsApp)
3. Tasks (create, assign, status)
4. Drive (search, summarize docs)
5. Mail (summarize, draft reply)
6. People (segment, find contacts)
7. Sheet (query, calculate)
8. Learn (KB search)
### Phase 4 — Cross-app intelligence
- [ ] Global search across all apps via single query
- [ ] "What happened today?" — aggregates activity across CRM + Mail + Tasks
- [ ] Proactive suggestions: "You have 3 deals closing this week and no follow-up tasks"
---
## File Structure to Create
```
botserver/src/
├── marketing/
│ ├── whatsapp_tools.rs ← NEW: LLM tool definitions + handlers
│ ├── WHATSAPP_PROMPT.md ← NEW: WhatsApp assistant system prompt
│ ├── file_parser.rs ← NEW: xlsx/csv → contacts
│ └── warmup.rs ← NEW: (from campaigns.md plan)
├── core/
│ ├── tool_registry.rs ← NEW: app → tools mapping
│ └── bot/
│ └── app_context.rs ← NEW: load app prompt + tools per session
├── crm/
│ ├── tools.rs ← NEW
│ └── PROMPT.md ← NEW
├── tasks/
│ └── tools.rs ← NEW (PROMPT.md exists)
└── <each app>/
├── tools.rs ← NEW per app
└── PROMPT.md ← NEW per app
botui/ui/suite/
└── partials/
└── chatbar.html ← NEW: shared chat bar component
```
---
## Chat Bar UI (`partials/chatbar.html`)
```html
<div id="suite-chatbar" class="chatbar">
<div id="chatbar-messages" hx-ext="ws" ws-connect="/ws/suite-chat"></div>
<form ws-send>
<input type="hidden" name="app_context" value="{{ active_app }}">
<input type="file" id="chatbar-file" name="file" accept=".xlsx,.csv,.png,.jpg,.pdf" style="display:none">
<button type="button" onclick="document.getElementById('chatbar-file').click()">📎</button>
<input type="text" name="message" placeholder="Ask anything about {{ active_app }}...">
<button type="submit"></button>
</form>
</div>
```
File uploads go to `POST /api/suite/upload` → stored in Drive → media_id passed to tool.

273
prompts/migrate.md Normal file
View file

@ -0,0 +1,273 @@
# Migration Plan: pragmatismo.com.br LXC → 63.141.255.9 Incus
## ✅ Progress Status (last updated 2026-03-17)
| Step | Status | Notes |
|---|---|---|
| Install Incus on dest | ✅ Done | v6.22 via zabbly repo |
| Install SSH key (no password) | ✅ Done | `/tmp/migrate_key` on local machine |
| `sudo incus admin init --minimal` | ✅ Done | dir pool created |
| `incus project create prod` | ⏳ Interrupted | Run manually (see Phase 1 below) |
| Host hardening (SSH) | ⏳ Not done | Run manually (see Phase 1 below) |
| Container migrations | ⏳ Not started | |
## ▶️ Resume From Here
SSH key is at `/tmp/migrate_key` (ephemeral — regenerate if rebooted):
```bash
# If /tmp/migrate_key is gone after reboot:
ssh-keygen -t ed25519 -f /tmp/migrate_key -N ""
ssh-copy-id -i /tmp/migrate_key.pub root@pragmatismo.com.br
# For dest, use paramiko or password once to push key again
```
Connect to destination:
```bash
ssh -i /tmp/migrate_key administrator@63.141.255.9
```
## Goals
- Move all containers from source (LXC + ZFS) to destination (Incus)
- Rename `pragmatismo-*``prod-*`
- Eliminate all host-mounted devices — each container owns its data internally under `/opt/gbo/`
- Storage pool uses `dir` backend: portable, zipable, Glacier-friendly
- Use **Incus projects** for tenant isolation and easy teleportation to other servers
---
## Why `dir` Storage Pool
- No ZFS/btrfs kernel modules needed
- Each container lives under `/var/lib/incus/storage-pools/default/containers/<name>/`
- The entire pool is a plain directory tree → `tar czf pool.tar.gz /var/lib/incus/storage-pools/default/` → upload to Glacier
- Incus projects make it trivial to `incus move --target` to another Incus server
---
## Incus Project Structure
```
incus project: prod ← all production containers (this migration)
incus project: staging ← future: staging environment
incus project: dev ← future: dev/test environment
```
Create on destination:
```bash
sudo incus project create prod --config features.images=true --config features.storage.volumes=true
sudo incus project switch prod
```
To teleport a container to another Incus server later:
```bash
# Add remote
incus remote add server2 https://<ip>:8443
# Move live container across servers (same project)
incus move prod-alm server2:prod-alm --project prod
```
---
## Container Rename Map
| Source (LXC) | Destination (Incus, project=prod) |
|---|---|
| pragmatismo-alm | prod-alm |
| pragmatismo-alm-ci | prod-alm-ci |
| pragmatismo-dns | prod-dns |
| pragmatismo-drive | prod-drive |
| pragmatismo-email | prod-email |
| pragmatismo-proxy | prod-proxy |
| pragmatismo-system | prod-system |
| pragmatismo-table-editor | prod-table-editor |
| pragmatismo-tables | prod-tables |
| pragmatismo-webmail | prod-webmail |
---
## Data Internalization Map
All external host mounts are removed. Data lives inside the container under `/opt/gbo/`.
| Container | Old host mount | New internal path | Source data to copy in |
|---|---|---|---|
| prod-alm | `/opt/gbo/conf` | `/opt/gbo/conf` | `/opt/gbo/tenants/pragmatismo/alm/` |
| prod-alm-ci | `/opt/gbo/data` | `/opt/gbo/data` | `/opt/gbo/tenants/pragmatismo/alm-ci/` |
| prod-dns | `/opt/gbo/conf` | `/opt/gbo/conf` | `/opt/gbo/tenants/pragmatismo/dns/` |
| prod-drive | `/opt/gbo/data` | `/opt/gbo/data` | `/opt/gbo/tenants/pragmatismo/drive/` |
| prod-email | `/opt/gbo/conf` | `/opt/gbo/conf` | `/opt/gbo/tenants/pragmatismo/email/` |
| prod-proxy | `/opt/gbo/conf` | `/opt/gbo/conf` | `/opt/gbo/tenants/pragmatismo/proxy/` |
| prod-system | `/opt/gbo/bin` | `/opt/gbo/bin` | `/opt/gbo/tenants/pragmatismo/system/` |
| prod-table-editor | `/opt/gbo/conf` | `/opt/gbo/conf` | `/opt/gbo/tenants/pragmatismo/table-editor/` |
| prod-tables | `/opt/gbo/data/postgres` | `/opt/gbo/data/postgres` | `/opt/gbo/tenants/pragmatismo/tables/` |
| prod-webmail | `/opt/gbo/data` | `/opt/gbo/data` | `/opt/gbo/tenants/pragmatismo/webmail/` |
### Notes on prod-tables (PostgreSQL)
- Old mount was `/etc/postgresql/14/main` — generalized to `/opt/gbo/data/postgres`
- Inside container: symlink or configure `data_directory = /opt/gbo/data/postgres` in `postgresql.conf`
- Copy: `rsync -a /opt/gbo/tenants/pragmatismo/tables/ <container>:/opt/gbo/data/postgres/`
### Notes on prod-drive (MinIO)
- Old mount was `/var/log/minio` (logs only) — generalize to `/opt/gbo/data/minio`
- Inside container: set `MINIO_VOLUMES=/opt/gbo/data/minio` in MinIO env/service file
- Copy: `rsync -a /opt/gbo/tenants/pragmatismo/drive/ <container>:/opt/gbo/data/minio/`
---
## Phase 1 — Prepare Destination (once)
```bash
# On 63.141.255.9 — run each line separately, they can hang if chained
sudo systemctl start incus
sudo incus admin init --minimal
sudo incus project create prod --config features.images=true --config features.storage.volumes=true
sudo usermod -aG incus-admin administrator
sudo incus list --project prod
# Harden SSH (no password auth, no root login)
sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl reload ssh
```
---
## Phase 2 — Migrate Each Container
Repeat for each container. Example: `alm-ci`
### On source (pragmatismo.com.br)
```bash
NAME=alm-ci
SRC=pragmatismo-${NAME}
# Stop, export rootfs, tar tenant data
lxc stop ${SRC}
lxc export ${SRC} /tmp/${SRC}.tar.gz # omit --optimized-storage (ZFS compat issues)
tar czf /tmp/${SRC}-data.tar.gz -C /opt/gbo/tenants/pragmatismo ${NAME}
# Transfer to destination
scp /tmp/${SRC}.tar.gz /tmp/${SRC}-data.tar.gz administrator@63.141.255.9:/tmp/
# Restart source (keep prod live during migration)
lxc start ${SRC}
```
### On destination (63.141.255.9)
```bash
NAME=alm-ci
SRC=pragmatismo-${NAME}
DEST=prod-${NAME}
INTERNAL_PATH=/opt/gbo/data # adjust per table above
# Import into prod project
sudo incus import /tmp/${SRC}.tar.gz --alias ${DEST} --project prod
# Remove any leftover device mounts
sudo incus config device remove ${DEST} $(sudo incus config device list ${DEST} 2>/dev/null) 2>/dev/null || true
# Start container
sudo incus start ${DEST} --project prod
# Push tenant data into container
mkdir -p /tmp/restore-${NAME}
tar xzf /tmp/${SRC}-data.tar.gz -C /tmp/restore-${NAME}
sudo incus exec ${DEST} --project prod -- mkdir -p ${INTERNAL_PATH}
sudo incus file push -r /tmp/restore-${NAME}/${NAME}/. ${DEST}${INTERNAL_PATH}/ --project prod
# Verify
sudo incus exec ${DEST} --project prod -- ls ${INTERNAL_PATH}
sudo incus exec ${DEST} --project prod -- systemctl status --no-pager | head -20
```
---
## Phase 3 — PostgreSQL Reconfiguration (prod-tables)
```bash
sudo incus exec prod-tables --project prod -- bash -c "
mkdir -p /opt/gbo/data/postgres
chown postgres:postgres /opt/gbo/data/postgres
# Update postgresql.conf
sed -i \"s|data_directory.*|data_directory = '/opt/gbo/data/postgres'|\" /etc/postgresql/14/main/postgresql.conf
systemctl restart postgresql
psql -U postgres -c '\l'
"
```
---
## Phase 4 — MinIO Reconfiguration (prod-drive)
```bash
sudo incus exec prod-drive --project prod -- bash -c "
mkdir -p /opt/gbo/data/minio
# Update service env
sed -i 's|MINIO_VOLUMES=.*|MINIO_VOLUMES=/opt/gbo/data/minio|' /etc/default/minio
systemctl restart minio
"
```
---
## Phase 5 — Validate & Cutover
```bash
sudo incus list --project prod
# Spot checks
sudo incus exec prod-tables --project prod -- psql -U postgres -c '\l'
sudo incus exec prod-proxy --project prod -- nginx -t
sudo incus exec prod-dns --project prod -- named-checkconf
sudo incus exec prod-drive --project prod -- curl -s http://localhost:9000/minio/health/live
# When all green: update DNS to 63.141.255.9
```
---
## Glacier Backup
The entire pool is a plain dir — backup is just:
```bash
# Full backup
tar czf /tmp/incus-prod-$(date +%Y%m%d).tar.gz /var/lib/incus/storage-pools/default/
# Upload to Glacier
aws s3 cp /tmp/incus-prod-$(date +%Y%m%d).tar.gz s3://your-glacier-bucket/ \
--storage-class DEEP_ARCHIVE
# Or per-container backup
tar czf /tmp/prod-alm-ci-$(date +%Y%m%d).tar.gz \
/var/lib/incus/storage-pools/default/containers/prod-alm-ci/
```
---
## Teleporting to Another Server (Future)
```bash
# Add new server as remote
sudo incus remote add server3 https://<new-server-ip>:8443 --accept-certificate
# Move container live (no downtime with CRIU if kernel supports it)
sudo incus move prod-alm server3:prod-alm --project prod
# Or copy (keep original running)
sudo incus copy prod-alm server3:prod-alm --project prod
```
---
## Rollback
- Source containers stay running throughout — only DNS cutover commits the migration
- Keep source containers stopped (not deleted) for 30 days after cutover

View file

@ -1,3 +0,0 @@
{
"contents": [{"role":"user","parts":[{"text":"hello"}]}]
}

View file

@ -1,9 +0,0 @@
{
"model": "gemini-1.5-flash",
"messages": [
{
"role": "user",
"content": "hello"
}
]
}

View file

@ -1,8 +0,0 @@
{
"contents": [
{
"role": "user",
"parts": [{"text":"hello"}]
}
]
}

BIN
rust_out

Binary file not shown.

View file

@ -1,129 +0,0 @@
#!/bin/bash
# General Bots Security Audit Script
# This script helps identify critical security issues in the codebase
set -e
echo "🔒 General Bots Security Audit"
echo "=============================="
echo ""
# Check for hardcoded secrets
echo "1. Checking for hardcoded secrets..."
if grep -r "password\s*=\s*\"" --include="*.rs" --include="*.toml" --include="*.json" . 2>/dev/null | grep -v "test" | grep -v "example" | head -10; then
echo "⚠️ WARNING: Found potential hardcoded passwords"
else
echo "✅ No obvious hardcoded passwords found"
fi
echo ""
# Check for unwrap/expect calls
echo "2. Checking for unwrap/expect calls..."
UNWRAP_COUNT=$(grep -r "\.unwrap()\|\.expect(" --include="*.rs" . 2>/dev/null | wc -l)
if [ "$UNWRAP_COUNT" -gt 0 ]; then
echo "⚠️ WARNING: Found $UNWRAP_COUNT unwrap/expect calls"
echo " Sample locations:"
grep -r "\.unwrap()\|\.expect(" --include="*.rs" . 2>/dev/null | head -5
else
echo "✅ No unwrap/expect calls found"
fi
echo ""
# Check for Command::new usage
echo "3. Checking for unsafe command execution..."
if grep -r "Command::new" --include="*.rs" . 2>/dev/null | grep -v "SafeCommand" | head -5; then
echo "⚠️ WARNING: Found potential unsafe command execution"
echo " Should use SafeCommand instead"
else
echo "✅ No unsafe Command::new calls found"
fi
echo ""
# Check for SQL injection patterns
echo "4. Checking for SQL injection patterns..."
if grep -r "format!.*SELECT\|format!.*INSERT\|format!.*UPDATE\|format!.*DELETE" --include="*.rs" . 2>/dev/null | grep -v "sanitize" | head -5; then
echo "⚠️ WARNING: Found potential SQL injection patterns"
echo " Should use sql_guard functions"
else
echo "✅ No obvious SQL injection patterns found"
fi
echo ""
# Check security headers in routes
echo "5. Checking for security middleware usage..."
if grep -r "security_headers_middleware\|csrf_middleware\|rate_limit_middleware" --include="*.rs" . 2>/dev/null | head -5; then
echo "✅ Security middleware found"
else
echo "⚠️ WARNING: No security middleware found in routes"
fi
echo ""
# Check for SecurityManager usage
echo "6. Checking for SecurityManager initialization..."
if grep -r "SecurityManager::new\|SecurityManager::initialize" --include="*.rs" . 2>/dev/null; then
echo "✅ SecurityManager usage found"
else
echo "⚠️ WARNING: SecurityManager not initialized"
fi
echo ""
# Check dependencies
echo "7. Checking dependencies..."
if command -v cargo-audit &> /dev/null; then
echo "Running cargo audit..."
cargo audit
else
echo "⚠️ Install cargo-audit: cargo install cargo-audit"
fi
echo ""
# Check for .env files in git
echo "8. Checking for secrets in git..."
if find . -name ".env" -type f | grep -v node_modules | grep -v target; then
echo "⚠️ WARNING: .env files found in repository"
echo " Secrets should be in /tmp/ only"
else
echo "✅ No .env files in repository"
fi
echo ""
# Check file permissions
echo "9. Checking critical file permissions..."
if [ -f "botserver-stack/conf/vault/init.json" ]; then
PERMS=$(stat -c "%a" "botserver-stack/conf/vault/init.json")
if [ "$PERMS" -gt 600 ]; then
echo "⚠️ WARNING: Vault init file permissions too open: $PERMS"
echo " Should be 600 or 400"
else
echo "✅ Vault init file permissions OK: $PERMS"
fi
fi
echo ""
# Summary
echo "📊 Security Audit Summary"
echo "========================"
echo ""
echo "Critical Issues to Address:"
echo "1. $UNWRAP_COUNT unwrap/expect calls need replacement"
echo "2. SecurityManager initialization missing"
echo "3. Security middleware may not be applied to all routes"
echo ""
echo "Next Steps:"
echo "1. Review TASKS.md for detailed remediation plan"
echo "2. Fix P1 issues first (SecurityManager, error handling)"
echo "3. Run cargo clippy and fix all warnings"
echo "4. Implement security testing"
echo ""
echo "For detailed tasks, see: TASKS.md"
echo "For quick checklist, see: SECURITY_CHECKLIST.md"

View file

@ -1,43 +0,0 @@
#!/bin/bash
curl -X POST http://localhost:8080/webhook/whatsapp/default \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=dummy" \
-d '{
"object": "whatsapp_business_account",
"entry": [
{
"id": "1234567890",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "552140402160",
"phone_number_id": "323250907549153"
},
"contacts": [
{
"profile": {
"name": "Test User"
},
"wa_id": "5511999999999"
}
],
"messages": [
{
"from": "5511999999999",
"id": "wamid.simulated_1",
"timestamp": "1625688536",
"text": {
"body": "cristo"
},
"type": "text"
}
]
},
"field": "messages"
}
]
}
]
}'

30
task.md
View file

@ -1,30 +0,0 @@
# Security Review Task List
## 1. Unsafe Unwraps in Production (Violates AGENTS.md Error Handling Rules)
The `AGENTS.md` explicitly forbids the use of `.unwrap()`, `.expect()`, `panic!()`, `todo!()`, and `unimplemented!()` in production code. A search of the codebase revealed several instances of `unwrap()` being used in non-test contexts.
**Vulnerable Locations:**
- `botserver/src/drive/drive_handlers.rs:269` - Contains a `.unwrap()` call during `Response::builder()` generation, which could panic in production.
- `botserver/src/basic/compiler/mod.rs` - Contains `unwrap()` usages outside test boundaries.
- `botserver/src/llm/llm_models/deepseek_r3.rs` - Contains `unwrap()` usages outside test boundaries.
- `botserver/src/botmodels/opencv.rs` - Test scopes use `unwrap()`, but please audit carefully for any leaks to production scope.
**Action:**
- Replace all `.unwrap()` occurrences with safe alternatives (`?`, `unwrap_or_default()`, or pattern matching with early returns) and use `ErrorSanitizer` to avoid panics.
## 2. Dependency Vulnerabilities (Found by cargo audit)
Running `cargo audit` uncovered a reported vulnerability inside the dependency tree.
**Vulnerable Component:**
- **Crate:** `glib`
- **Version:** `0.18.5`
- **Advisory ID:** `RUSTSEC-2024-0429`
- **Title:** Unsoundness in `Iterator` and `DoubleEndedIterator` impls for `glib::VariantStrIter`
- **Dependency Tree context:** It's pulled through `botdevice` and `botapp` via Tauri plugins and GTK dependencies.
**Action:**
- Review dependencies and upgrade the GTK/Glib ecosystem dependencies if patches are available, or evaluate the exact usage to assess the direct risk given the desktop GUI context.
## 3. General Posture Alignment
- Ensure all new state-changing endpoints are correctly shielded by the custom CSRF store (`redis_csrf_store.rs`). Verification is recommended as standard `tower-csrf` is absent from `Cargo.toml`.
- Confirm security headers (`Content-Security-Policy` via `headers.rs`) are indeed attached universally in `botserver` and not selectively omitted in new modules.

View file

@ -1,18 +0,0 @@
import { test, expect } from '@playwright/test';
test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});
test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Click the get started link.
await page.getByRole('link', { name: 'Get started' }).click();
// Expects page to have a heading with the name of Installation.
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
});

299
zap.md
View file

@ -1,299 +0,0 @@
# WhatsApp - Bot Salesianos
respeitar AGENTS.md
## Status: Operacional
| Campo | Valor |
|-------|-------|
| Bot ID | `32c579e5-609b-4a07-8599-4e0fccc4d764` |
| Phone | +15558293147 |
| Phone ID | 323250907549153 |
| Business ID | 1261667644771701 |
---
## Comandos
- `/clear` - Limpa histórico da conversa
---
## Streaming
1. Mensagens sem lista: enviar a cada 3 parágrafos
2. Mensagens com lista: **ISOLAR como mensagem única** (sem texto antes ou depois)
3. Limite máximo: 4000 caracteres por mensagem
### Exemplo de Agrupamento Correto
**Resposta completa do bot:**
```
Olá! 😊
Infelizmente, não tenho a informação específica sobre o horário de funcionamento da Escola Salesiana no momento.
Para obter essa informação, você pode:
1. *Entrar em contato com a secretaria* - Posso te ajudar a enviar uma mensagem perguntando sobre os horários
2. *Agendar uma visita* - Assim você conhece a escola pessoalmente e obtém todas as informações necessárias
Gostaria que eu te ajudasse com alguma dessas opções? Se quiser entrar em contato com a secretaria, preciso apenas de:
- Seu nome
- Telefone
- Email
- Sua pergunta sobre os horários
Ou, se preferir, posso agendar uma visita para você conhecer a escola! 🏫
O que prefere?
```
**Deve ser enviado como 5 mensagens separadas:**
**Mensagem 1:**
```
Olá! 😊
Infelizmente, não tenho a informação específica sobre o horário de funcionamento da Escola Salesiana no momento.
Para obter essa informação, você pode:
```
**Mensagem 2 (LISTA ISOLADA):**
```
1. *Entrar em contato com a secretaria* - Posso te ajudar a enviar uma mensagem perguntando sobre os horários
2. *Agendar uma visita* - Assim você conhece a escola pessoalmente e obtém todas as informações necessárias
```
**Mensagem 3:**
```
Gostaria que eu te ajudasse com alguma dessas opções? Se quiser entrar em contato com a secretaria, preciso apenas de:
```
**Mensagem 4 (LISTA ISOLADA):**
```
- Seu nome
- Telefone
- Email
- Sua pergunta sobre os horários
```
**Mensagem 5:**
```
Ou, se preferir, posso agendar uma visita para você conhecer a escola! 🏫
O que prefere?
```
**Regras:**
- ✅ Cada lista = **1 mensagem ISOLADA** (nunca misturar com texto)
- ✅ Texto antes da lista = mensagem separada
- ✅ Texto depois da lista = mensagem separada
- ✅ Listas nunca são quebradas no meio
---
## Testar Webhook (Simular Callback)
Script de teste em `/tmp/test_whatsapp.sh`:
```bash
#!/bin/bash
# Testa o webhook do WhatsApp simulando uma mensagem
BOT_ID="32c579e5-609b-4a07-8599-4e0fccc4d764"
FROM="5521972102162" # Número de teste
curl -X POST "http://localhost:8080/webhook/whatsapp/${BOT_ID}" \
-H "Content-Type: application/json" \
-d '{
"object": "whatsapp_business_account",
"entry": [{
"id": "1261667644771701",
"changes": [{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "15558293147",
"phone_number_id": "323250907549153"
},
"contacts": [{
"wa_id": "'${FROM}'",
"profile": { "name": "Teste Usuario" }
}],
"messages": [{
"id": "test_msg_'$(date +%s)'",
"from": "'${FROM}'",
"timestamp": "'$(date +%s)'",
"type": "text",
"text": { "body": "Olá, como posso ajudar?" }
}]
}
}]
}]
}'
```
Executar teste:
```bash
bash /tmp/test_whatsapp.sh
```
---
## Testar Comando /clear
```bash
BOT_ID="32c579e5-609b-4a07-8599-4e0fccc4d764"
FROM="5521972102162"
curl -X POST "http://localhost:8080/webhook/whatsapp/${BOT_ID}" \
-H "Content-Type: application/json" \
-d '{
"object": "whatsapp_business_account",
"entry": [{
"id": "1261667644771701",
"changes": [{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "15558293147",
"phone_number_id": "323250907549153"
},
"contacts": [{
"wa_id": "'${FROM}'",
"profile": { "name": "Teste Usuario" }
}],
"messages": [{
"id": "test_clear_'$(date +%s)'",
"from": "'${FROM}'",
"timestamp": "'$(date +%s)'",
"type": "text",
"text": { "body": "/clear" }
}]
}
}]
}]
}'
```
---
## Debug
```bash
# Verificar servidor
curl http://localhost:8080/health
# Monitorar logs
tail -f botserver.log | grep -iE "(whatsapp|Embedding)"
# Verificar sessões ativas (requer acesso ao banco)
# SELECT * FROM user_sessions WHERE bot_id = '32c579e5-609b-4a07-8599-4e0fccc4d764';
```
---
## Arquivos Relacionados
- Config: `/opt/gbo/data/salesianos.gbai/salesianos.gbot/config.csv`
- Handler: `botserver/src/whatsapp/mod.rs`
- Adapter: `botserver/src/core/bot/channels/whatsapp.rs`
- Cache: `botserver/src/llm/cache.rs`
---
## Pendências
1. **Implementar suporte a `/webhook/whatsapp/default`** (ver TODO abaixo)
2. Configurar webhook na Meta Business Suite para produção
3. Configurar SSL/TLS no servidor de produção
---
## 📋 TODO: Default Bot Routing
### Objetivo
Permitir que a URL `/webhook/whatsapp/default` funcione como roteador dinâmico de bots baseado em comandos de usuário.
### Comportamento Atual
- ✅ `/webhook/whatsapp/{uuid}` → Rota direta para bot específico
- ❌ `/webhook/whatsapp/default`**FALHA** (espera UUID, não aceita "default")
### Comportamento Desejado
1. `/webhook/whatsapp/default` → Rota para o bot default (`/opt/gbo/data/default.gbai/default.gbot`)
2. Quando usuário digita um `whatsapp-id` (ex: "cristo", "salesianos"):
- Sistema busca bot com essa propriedade no `config.csv`
- Mapeia `phone_number``bot_id` na sessão/cache
- Troca de bot para aquela sessão
3. Mensagens subsequentes daquele `phone_number` são roteadas para o bot mapeado
4. Se usuário digitar outro `whatsapp-id`, encerra sessão anterior e abre nova para o novo bot
### Arquivos a Modificar
#### 1. `botserver/src/whatsapp/mod.rs`
- **Linha ~178**: Modificar `verify_webhook` e `handle_webhook`
- Mudar `Path(bot_id): Path<Uuid>``Path(bot_id): Path<String>`
- Adicionar parsing: `"default"` → buscar UUID do bot default
- Manter parsing UUID para compatibilidade
#### 2. `botserver/src/whatsapp/mod.rs`
- **Nova função**: `resolve_bot_id(bot_id_str: &str, state: &AppState) -> Result<Uuid, Error>`
- Se `"default"` → retorna UUID do bot default via `get_default_bot()`
- Se UUID válido → retorna UUID
- Caso contrário → erro
#### 3. `botserver/src/whatsapp/mod.rs`
- **Nova função**: `check_whatsapp_id_routing(message_text: &str, state: &AppState) -> Option<Uuid>`
- Verifica se texto é um comando de troca de bot
- Busca em todos os bots por `whatsapp-id` no `config.csv`
- Retorna bot_id se encontrar match
#### 4. `botserver/src/whatsapp/mod.rs`
- **Modificar** `process_incoming_message`
- Antes de processar, verificar se mensagem é comando de roteamento
- Se for, atualizar mapeamento `phone``bot_id` no cache
- Se não for, usar mapeamento existente do cache
### Bots com whatsapp-id Configurado
- ✅ **cristo.gbot**: `whatsapp-id,cristo`
- ❓ **salesianos.gbot**: verificar se tem whatsapp-id
- ✅ **default.gbot**: não tem whatsapp-id (é o roteador)
### Implementação em Passos
**Passo 1**: Modificar handlers para aceitar "default"
```rust
// Antes
Path(bot_id): Path<Uuid>
// Depois
Path(bot_id_str): Path<String>
let bot_id = resolve_bot_id(&bot_id_str, &state)?;
```
**Passo 2**: Implementar `resolve_bot_id`
- Buscar `get_default_bot()` quando `bot_id_str == "default"`
- Parse UUID caso contrário
**Passo 3**: Implementar roteamento dinâmico
- Verificar cache: `phone_number``bot_id`
- Se não existir, usar bot_id do webhook
- Se mensagem for comando (whatsapp-id), atualizar cache
**Passo 4**: Testar
```bash
# Teste 1: URL com default
curl -X POST "http://localhost:8080/webhook/whatsapp/default" ...
# Teste 2: URL com UUID (deve continuar funcionando)
curl -X POST "http://localhost:8080/webhook/whatsapp/32c579e5-609b-4a07-8599-4e0fccc4d764" ...
# Teste 3: Roteamento por comando
# Enviar mensagem "cristo" → deve rotear para bot cristo
# Enviar mensagem "salesianos" → deve trocar para bot salesianos
```
### URLs de Teste
- Localtunnel: `https://bright-bananas-deny.loca.lt/webhook/whatsapp/default`
- Local: `http://localhost:8080/webhook/whatsapp/default`