Compare commits
2 commits
7d4708b516
...
abedde3af7
| Author | SHA1 | Date | |
|---|---|---|---|
| abedde3af7 | |||
| 9fc33725b7 |
16 changed files with 9275 additions and 5 deletions
931
.gemini/tasks/multiagent-task-ui-plan.md
Normal file
931
.gemini/tasks/multiagent-task-ui-plan.md
Normal file
|
|
@ -0,0 +1,931 @@
|
|||
# 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)
|
||||
48
AGENTS.md
48
AGENTS.md
|
|
@ -1,5 +1,7 @@
|
|||
# General Bots AI Agent Guidelines
|
||||
|
||||
8080 is server 3000 is client ui
|
||||
To test web is http://localhost:3000 (botui!)
|
||||
Use apenas a lingua culta.
|
||||
> **⚠️ CRITICAL SECURITY WARNING**
|
||||
I AM IN DEV ENV, but sometimes, pasting from PROD, do not treat my env as prod! Just fix, to me and push to CI. So I can test in PROD, for a while.
|
||||
>Use Playwrigth MCP to start localhost:3000/<bot> now.
|
||||
|
|
@ -37,6 +39,50 @@ See botserver/src/drive/local_file_monitor.rs to see how to load from /opt/gbo/d
|
|||
|
||||
---
|
||||
|
||||
## 🔄 Reset Process Notes
|
||||
|
||||
### reset.sh Behavior
|
||||
- **Purpose**: Cleans and restarts the development environment
|
||||
- **Timeouts**: The script can timeout during "Step 3/4: Waiting for BotServer to bootstrap"
|
||||
- **Bootstrap Process**: Takes 3-5 minutes to install all components (Vault, PostgreSQL, Valkey, MinIO, Zitadel, LLM)
|
||||
|
||||
### Common Issues
|
||||
1. **Script Timeout**: reset.sh waits for "Bootstrap complete: admin user" message
|
||||
- If Zitadel isn't ready within 60s, admin user creation fails
|
||||
- Script continues waiting indefinitely
|
||||
- **Solution**: Check botserver.log for "Bootstrap process completed!" message
|
||||
|
||||
2. **Zitadel Not Ready**: "Bootstrap check failed (Zitadel may not be ready)"
|
||||
- Directory service may need more than 60 seconds to start
|
||||
- Admin user creation deferred
|
||||
- Services still start successfully
|
||||
|
||||
3. **Services Exit After Start**:
|
||||
- botserver/botui may exit after initial startup
|
||||
- Check logs for "dispatch failure" errors
|
||||
- Check Vault certificate errors: "tls: failed to verify certificate: x509"
|
||||
|
||||
### Manual Service Management
|
||||
```bash
|
||||
# If reset.sh times out, manually verify services:
|
||||
ps aux | grep -E "(botserver|botui)" | grep -v grep
|
||||
curl http://localhost:8080/health
|
||||
tail -f botserver.log botui.log
|
||||
|
||||
# Restart services manually:
|
||||
./restart.sh
|
||||
```
|
||||
|
||||
### Reset Verification
|
||||
After reset completes, verify:
|
||||
- ✅ PostgreSQL running (port 5432)
|
||||
- ✅ Valkey cache running (port 6379)
|
||||
- ✅ BotServer listening on port 8080
|
||||
- ✅ BotUI listening on port 3000
|
||||
- ✅ No errors in botserver.log
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security Directives - MANDATORY
|
||||
|
||||
### 1. Error Handling - NO PANICS IN PRODUCTION
|
||||
|
|
|
|||
737
BOTCODER_ANALYSIS.md
Normal file
737
BOTCODER_ANALYSIS.md
Normal file
|
|
@ -0,0 +1,737 @@
|
|||
# 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.
|
||||
955
BOTCODER_HYBRID_ARCHITECTURE.md
Normal file
955
BOTCODER_HYBRID_ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,955 @@
|
|||
# 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.
|
||||
1202
TASK_V2.md
Normal file
1202
TASK_V2.md
Normal file
File diff suppressed because it is too large
Load diff
877
UNIFIED_PLAN.md
Normal file
877
UNIFIED_PLAN.md
Normal file
|
|
@ -0,0 +1,877 @@
|
|||
# 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)
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 0b1b17406db9d4cc91c1a29cf549398e72fd111a
|
||||
Subproject commit 2c92a81302e1e2c5c533fd585e69a2b5beaace89
|
||||
231
package-lock.json
generated
231
package-lock.json
generated
|
|
@ -9,6 +9,8 @@
|
|||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"node-fetch": "^3.3.2",
|
||||
"ws": "^8.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -42,6 +44,65 @@
|
|||
"undici-types": "~7.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/data-uri-to-buffer": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fetch-blob": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20 || >= 14.13"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fetch-blob": "^3.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
|
|
@ -57,6 +118,135 @@
|
|||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
|
||||
"integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jws": "^4.0.1",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
|
||||
"integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "^1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||
"deprecated": "Use your platform's native DOMException instead",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz",
|
||||
|
|
@ -89,6 +279,38 @@
|
|||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||
|
|
@ -96,6 +318,15 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/web-streams-polyfill": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
|
||||
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.19.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"node-fetch": "^3.3.2",
|
||||
"ws": "^8.19.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
110
reset.sh
110
reset.sh
|
|
@ -1 +1,109 @@
|
|||
rm -rf botserver-stack/ ./work/ .env
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
#######################################
|
||||
# General Bots Development Environment Reset Script
|
||||
# Description: Cleans and restarts the development environment
|
||||
# Usage: ./reset.sh
|
||||
#######################################
|
||||
|
||||
# Color codes for output
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly NC='\033[0m' # No Color
|
||||
|
||||
# Log function
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
# Trap errors and cleanup
|
||||
cleanup_on_error() {
|
||||
log_warning "Script encountered an error"
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap cleanup_on_error ERR
|
||||
|
||||
log_info "Starting environment reset..."
|
||||
echo ""
|
||||
|
||||
# Step 1: Clean up existing installations
|
||||
log_info "Step 1/4: Cleaning up existing installation..."
|
||||
rm -rf botserver-stack/ ./work/ .env
|
||||
log_success "Cleanup complete"
|
||||
echo ""
|
||||
|
||||
# Step 2: Build and restart services
|
||||
log_info "Step 2/4: Building and restarting services..."
|
||||
./restart.sh
|
||||
log_success "Services restarted"
|
||||
echo ""
|
||||
|
||||
# Step 3: Wait for bootstrap
|
||||
log_info "Step 3/4: Waiting for BotServer to bootstrap (this may take a minute)..."
|
||||
|
||||
# Tail the log starting from now, so we only see the new run
|
||||
tail -n 0 -f botserver.log | while read line; do
|
||||
# Show bootstrap-related messages
|
||||
if [[ "$line" == *"GENERAL BOTS - INITIAL SETUP"* ]]; then
|
||||
SHOW=1
|
||||
log_info "Bootstrap process started..."
|
||||
fi
|
||||
|
||||
if [[ "$SHOW" == "1" ]]; then
|
||||
echo "$line"
|
||||
elif [[ "$line" == *"Checking if bootstrap is needed"* ]] || \
|
||||
[[ "$line" == *"No admin user found"* ]] || \
|
||||
[[ "$line" == *"Created admin user"* ]] || \
|
||||
[[ "$line" == *"Created default organization"* ]] || \
|
||||
[[ "$line" == *"Starting"* ]] || \
|
||||
[[ "$line" == *"Installing"* ]]; then
|
||||
echo "$line"
|
||||
fi
|
||||
|
||||
# Stop tracking when bootstrap completes
|
||||
if [[ "$line" == *"Bootstrap complete: admin user"* ]] || \
|
||||
[[ "$line" == *"Skipping bootstrap"* ]]; then
|
||||
pkill -P $$ tail || true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
log_success "Bootstrap complete"
|
||||
echo ""
|
||||
|
||||
# Step 4: Final confirmation
|
||||
log_info "Step 4/4: Verifying services..."
|
||||
sleep 2
|
||||
|
||||
if pgrep -f "botserver" > /dev/null; then
|
||||
log_success "BotServer is running"
|
||||
else
|
||||
log_warning "BotServer may not be running properly"
|
||||
fi
|
||||
|
||||
if pgrep -f "botui" > /dev/null; then
|
||||
log_success "BotUI is running"
|
||||
else
|
||||
log_warning "BotUI may not be running properly"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
log_success "✅ Reset complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "You can now access:"
|
||||
echo " - BotUI Desktop: Check the BotUI window or logs"
|
||||
echo " - Logs: tail -f botserver.log botui.log"
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ cargo build -p botserver
|
|||
cargo build -p botui
|
||||
|
||||
echo "Starting botserver..."
|
||||
./target/debug/botserver --noconsole > botserver.log 2>&1 &
|
||||
RUST_LOG=trace ./target/debug/botserver --noconsole > botserver.log 2>&1 &
|
||||
echo " PID: $!"
|
||||
|
||||
echo "Starting botui..."
|
||||
BOTSERVER_URL="http://localhost:9000" ./target/debug/botui > botui.log 2>&1 &
|
||||
BOTSERVER_URL="http://localhost:8080" ./target/debug/botui > botui.log 2>&1 &
|
||||
echo " PID: $!"
|
||||
|
||||
echo "Done. Logs: tail -f botserver.log botui.log"
|
||||
|
|
|
|||
740
sec.md
Normal file
740
sec.md
Normal file
|
|
@ -0,0 +1,740 @@
|
|||
# VibeCode Complete Implementation Roadmap
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Current Status:** BotUI's backend is **80% complete** with powerful LLM-driven code generation. The frontend needs professional tools to match Claude Code's capabilities.
|
||||
|
||||
**What Works (Backend):**
|
||||
- ✅ LLM-powered app generation (AppGenerator: 3400+ lines)
|
||||
- ✅ Multi-agent pipeline (Orchestrator: Plan → Build → Review → Deploy → Monitor)
|
||||
- ✅ Real-time WebSocket progress
|
||||
- ✅ Database schema generation
|
||||
- ✅ File generation (HTML, CSS, JS, BAS)
|
||||
- ✅ Designer AI (runtime modifications with undo/redo)
|
||||
- ✅ chromiumoxide dependency ready for browser automation
|
||||
|
||||
**What's Missing (Frontend):**
|
||||
- ❌ Monaco/CodeMirror editor (just textarea now)
|
||||
- ❌ Database UI (no schema visualizer)
|
||||
- ❌ Git operations UI
|
||||
- ❌ Browser automation engine (using Rust + chromiumoxide)
|
||||
- ❌ Multi-file editing workspace
|
||||
- ❌ Enhanced terminal
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ USER REQUEST │
|
||||
│ "I want a full CRM system" │
|
||||
└────────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ VIBE BUILDER UI │
|
||||
│ - Agent cards (Mantis #1-4) │
|
||||
│ - Task nodes visualization │
|
||||
│ - WebSocket real-time updates │
|
||||
│ - Live chat overlay │
|
||||
│ - Code editor (Monaco) ← Phase 1 │
|
||||
│ - Browser automation panel ← Phase 4 │
|
||||
│ - Database schema visualizer ← Phase 2 │
|
||||
│ - Git operations UI ← Phase 3 │
|
||||
└────────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ BOTSERVER (Rust Backend) │
|
||||
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
||||
│ │ Orchestrator│ │AppGenerator│ │Designer AI │ │
|
||||
│ │ (5 agents) │ │(LLM-driven)│ │(modifications)│ │
|
||||
│ └────────────┘ └────────────┘ └────────────┘ │
|
||||
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
||||
│ │ Browser │ │ Git │ │ Terminal │ │
|
||||
│ │ Automation │ │ Operations │ │ Service │ │
|
||||
│ │(chromiumoxide)│ │(git2) │ │(xterm.js) │ │
|
||||
│ └────────────┘ └────────────┘ └────────────┘ │
|
||||
└────────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ GENERATED OUTPUT │
|
||||
│ - PostgreSQL tables │
|
||||
│ - HTML pages with HTMX │
|
||||
│ - CSS styling │
|
||||
│ - JavaScript │
|
||||
│ - BASIC tools/schedulers │
|
||||
│ - E2E tests (Playwright) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### 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()`
|
||||
|
||||
```rust
|
||||
pub struct BrowserSession {
|
||||
id: String,
|
||||
browser: Arc<chromiumoxide::Browser>,
|
||||
page: Arc<Mutex<chromiumoxide::Page>>,
|
||||
created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl BrowserSession {
|
||||
pub async fn new(headless: bool) -> Result<Self>;
|
||||
pub async fn navigate(&self, url: &str) -> Result<()>;
|
||||
pub async fn click(&self, selector: &str) -> Result<()>;
|
||||
pub async fn fill(&self, selector: &str, text: &str) -> Result<()>;
|
||||
pub async fn screenshot(&self) -> Result<Vec<u8>>;
|
||||
pub async fn execute(&self, script: &str) -> Result<Value>;
|
||||
}
|
||||
```
|
||||
|
||||
2. **Action Recorder**
|
||||
- `botserver/src/browser/recorder.rs`
|
||||
- `RecordedAction` - Navigate, Click, Fill, Wait, Assert
|
||||
- `ActionRecorder` - Record/stop/export
|
||||
- Export as Playwright test
|
||||
|
||||
```rust
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RecordedAction {
|
||||
pub timestamp: i64,
|
||||
pub action_type: ActionType,
|
||||
pub selector: Option<String>,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
impl ActionRecorder {
|
||||
pub fn start(&mut self);
|
||||
pub fn stop(&mut self) -> Vec<RecordedAction>;
|
||||
pub fn export_test_script(&self) -> String;
|
||||
}
|
||||
```
|
||||
|
||||
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`
|
||||
```javascript
|
||||
let currentSessionId = null;
|
||||
let isRecording = false;
|
||||
let recordedActions = [];
|
||||
|
||||
async function initBrowser() {
|
||||
const resp = await fetch('/api/browser/session', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ headless: false })
|
||||
});
|
||||
currentSessionId = (await resp.json()).id;
|
||||
}
|
||||
|
||||
async function browserNavigate(url) {
|
||||
if (isRecording) {
|
||||
recordedActions.push({
|
||||
type: 'navigate',
|
||||
value: url,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
}
|
||||
await executeAction('navigate', { url });
|
||||
}
|
||||
|
||||
async function browserClick(selector) {
|
||||
if (isRecording) {
|
||||
recordedActions.push({
|
||||
type: 'click',
|
||||
selector: selector,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
}
|
||||
await executeAction('click', { selector });
|
||||
}
|
||||
|
||||
async function exportTest() {
|
||||
const resp = await fetch(`/api/browser/session/${currentSessionId}/record/export`);
|
||||
const data = await resp.json();
|
||||
|
||||
// Download test file
|
||||
const blob = new Blob([data.script], { type: 'text/javascript' });
|
||||
const a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(blob);
|
||||
a.download = `test-${Date.now()}.spec.js`;
|
||||
a.click();
|
||||
}
|
||||
```
|
||||
|
||||
- `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
|
||||
|
||||
**Usage Example:**
|
||||
```javascript
|
||||
// In Vibe UI
|
||||
openBrowserPanel();
|
||||
toggleRecording(); // Start recording
|
||||
browserNavigate('http://localhost:3000/my-crm');
|
||||
browserClick('#create-btn');
|
||||
browserFill('#name', 'Test');
|
||||
browserClick('#save-btn');
|
||||
toggleRecording(); // Stop recording
|
||||
exportTest(); // Download test-123.spec.js
|
||||
```
|
||||
|
||||
**Generated Test Output:**
|
||||
```javascript
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Recorded test', async ({ page }) => {
|
||||
await page.goto('http://localhost:3000/my-crm');
|
||||
await page.click('#create-btn');
|
||||
await page.fill('#name', 'Test');
|
||||
await page.click('#save-btn');
|
||||
});
|
||||
```
|
||||
|
||||
**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
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
js/
|
||||
editor.js
|
||||
database.js
|
||||
git.js
|
||||
browser.js
|
||||
terminal.js
|
||||
templates.js
|
||||
css/
|
||||
editor.css
|
||||
database.css
|
||||
git.css
|
||||
browser.css
|
||||
terminal.css
|
||||
templates.css
|
||||
```
|
||||
|
||||
**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
|
||||
```
|
||||
|
||||
### 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)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
---
|
||||
|
||||
## Rollout Plan
|
||||
|
||||
### 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)
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### 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 already has a **powerful backend** capable of generating full applications via LLM. The main gaps are in the **frontend user experience**.
|
||||
|
||||
Once these 7 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 browser automation** (chromiumoxide)
|
||||
✅ **Professional development environment**
|
||||
|
||||
The biggest advantage: VibeCode can already **generate working CRMs** via the LLM pipeline. These phases add the **professional UI tools** to make it a complete development environment.
|
||||
|
||||
**Total Estimated Effort:** 98-126 hours (~3-4 weeks with 1 developer)
|
||||
134
yarn.lock
134
yarn.lock
|
|
@ -16,6 +16,125 @@
|
|||
dependencies:
|
||||
undici-types "~7.16.0"
|
||||
|
||||
buffer-equal-constant-time@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz"
|
||||
integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
|
||||
|
||||
data-uri-to-buffer@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz"
|
||||
integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
|
||||
|
||||
ecdsa-sig-formatter@1.0.11:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
|
||||
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
fetch-blob@^3.1.2, fetch-blob@^3.1.4:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz"
|
||||
integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
|
||||
dependencies:
|
||||
node-domexception "^1.0.0"
|
||||
web-streams-polyfill "^3.0.3"
|
||||
|
||||
formdata-polyfill@^4.0.10:
|
||||
version "4.0.10"
|
||||
resolved "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz"
|
||||
integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
|
||||
dependencies:
|
||||
fetch-blob "^3.1.2"
|
||||
|
||||
jsonwebtoken@^9.0.3:
|
||||
version "9.0.3"
|
||||
resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz"
|
||||
integrity sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==
|
||||
dependencies:
|
||||
jws "^4.0.1"
|
||||
lodash.includes "^4.3.0"
|
||||
lodash.isboolean "^3.0.3"
|
||||
lodash.isinteger "^4.0.4"
|
||||
lodash.isnumber "^3.0.3"
|
||||
lodash.isplainobject "^4.0.6"
|
||||
lodash.isstring "^4.0.1"
|
||||
lodash.once "^4.0.0"
|
||||
ms "^2.1.1"
|
||||
semver "^7.5.4"
|
||||
|
||||
jwa@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz"
|
||||
integrity sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==
|
||||
dependencies:
|
||||
buffer-equal-constant-time "^1.0.1"
|
||||
ecdsa-sig-formatter "1.0.11"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
jws@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz"
|
||||
integrity sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==
|
||||
dependencies:
|
||||
jwa "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
lodash.includes@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz"
|
||||
integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==
|
||||
|
||||
lodash.isboolean@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz"
|
||||
integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==
|
||||
|
||||
lodash.isinteger@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz"
|
||||
integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==
|
||||
|
||||
lodash.isnumber@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz"
|
||||
integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==
|
||||
|
||||
lodash.isplainobject@^4.0.6:
|
||||
version "4.0.6"
|
||||
resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz"
|
||||
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
|
||||
|
||||
lodash.isstring@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz"
|
||||
integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
|
||||
|
||||
lodash.once@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz"
|
||||
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
node-domexception@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz"
|
||||
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
|
||||
|
||||
node-fetch@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz"
|
||||
integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==
|
||||
dependencies:
|
||||
data-uri-to-buffer "^4.0.0"
|
||||
fetch-blob "^3.1.4"
|
||||
formdata-polyfill "^4.0.10"
|
||||
|
||||
playwright-core@1.58.2:
|
||||
version "1.58.2"
|
||||
resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz"
|
||||
|
|
@ -30,11 +149,26 @@ playwright@1.58.2:
|
|||
optionalDependencies:
|
||||
fsevents "2.3.2"
|
||||
|
||||
safe-buffer@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
semver@^7.5.4:
|
||||
version "7.7.4"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz"
|
||||
integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==
|
||||
|
||||
undici-types@~7.16.0:
|
||||
version "7.16.0"
|
||||
resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz"
|
||||
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
|
||||
|
||||
web-streams-polyfill@^3.0.3:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz"
|
||||
integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==
|
||||
|
||||
ws@^8.19.0:
|
||||
version "8.19.0"
|
||||
resolved "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz"
|
||||
|
|
|
|||
440
zit.md
Normal file
440
zit.md
Normal file
|
|
@ -0,0 +1,440 @@
|
|||
# Zitadel OAuth Client Automatic Creation - Action Plan
|
||||
|
||||
## Current Status (March 1, 2026)
|
||||
|
||||
### ✅ FIXED: Health Check & Proxy Issues
|
||||
|
||||
**Problems Fixed:**
|
||||
1. Zitadel health checks used port **9000** but Zitadel runs on port **8300**
|
||||
2. BotUI proxy used `https://localhost:9000` but BotServer runs on `http://localhost:8080`
|
||||
3. Directory base URL used port 9000 instead of 8300
|
||||
|
||||
**Files Fixed:**
|
||||
1. `botserver/src/core/bootstrap/bootstrap_utils.rs` - Health check port 9000 → 8300
|
||||
2. `botserver/src/core/package_manager/installer.rs` - ZITADEL_EXTERNALPORT and check_cmd 9000 → 8300
|
||||
3. `botserver/src/core/directory/api.rs` - Health check URL to port 8300
|
||||
4. `botlib/src/http_client.rs` - DEFAULT_BOTSERVER_URL to http://localhost:8080
|
||||
5. `botserver/src/core/urls.rs` - DIRECTORY_BASE to port 8300
|
||||
|
||||
**Results:**
|
||||
- ✅ Zitadel health check: 2 seconds (was 300 seconds)
|
||||
- ✅ BotUI proxy: correct routing to BotServer
|
||||
- ✅ Bootstrap completes successfully
|
||||
- ✅ No more 502 Bad Gateway errors
|
||||
|
||||
### ❌ REMAINING: OAuth Client Not Created
|
||||
|
||||
**Problem:**
|
||||
```json
|
||||
{
|
||||
"error": "Authentication service not configured",
|
||||
"details": "OAuth client credentials not available"
|
||||
}
|
||||
```
|
||||
|
||||
**Root Cause:**
|
||||
- File `botserver-stack/conf/system/directory_config.json` is **MISSING**
|
||||
- Bootstrap cannot extract Zitadel credentials from logs
|
||||
- OAuth client creation fails
|
||||
- Login fails
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Why the Previous Fix Failed
|
||||
|
||||
The commit `86cfccc2` (Jan 6, 2026) added:
|
||||
- `extract_initial_admin_from_log()` to parse Zitadel logs
|
||||
- Password grant authentication support
|
||||
- Directory config saving
|
||||
|
||||
**But it doesn't work because:**
|
||||
1. **Zitadel doesn't log credentials** in the expected format
|
||||
2. Log parsing returns `None`
|
||||
3. Without credentials, OAuth client creation fails
|
||||
4. Config file is never created
|
||||
5. **Chicken-and-egg problem persists**
|
||||
|
||||
### The Real Solution
|
||||
|
||||
**Instead of parsing logs, the bootstrap should:**
|
||||
1. **Generate admin credentials** using `generate_secure_password()`
|
||||
2. **Create admin user in Zitadel** using Zitadel's Management API
|
||||
3. **Use those exact credentials** to create OAuth client
|
||||
4. **Save config** to `botserver-stack/conf/system/directory_config.json`
|
||||
5. **Display credentials** to user via console and `~/.gb-setup-credentials`
|
||||
|
||||
## Automatic Solution Design
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
Bootstrap Flow (First Run):
|
||||
1. Start Zitadel service
|
||||
2. Wait for Zitadel to be ready (health check)
|
||||
3. Check if directory_config.json exists
|
||||
- If YES: Load config, skip creation
|
||||
- If NO: Proceed to step 4
|
||||
4. Generate admin credentials (username, email, password)
|
||||
5. Create admin user in Zitadel via Management API
|
||||
6. Create OAuth application via Management API
|
||||
7. Save directory_config.json to botserver-stack/conf/system/
|
||||
8. Display credentials to user
|
||||
9. Continue bootstrap
|
||||
|
||||
Bootstrap Flow (Subsequent Runs):
|
||||
1. Start Zitadel service
|
||||
2. Wait for Zitadel to be ready
|
||||
3. Check if directory_config.json exists
|
||||
- If YES: Load config, verify OAuth client
|
||||
- If NO: Run first-run flow
|
||||
4. Continue bootstrap
|
||||
```
|
||||
|
||||
### Key Changes Required
|
||||
|
||||
#### 1. Fix `setup_directory()` in `mod.rs`
|
||||
|
||||
**Current approach (broken):**
|
||||
```rust
|
||||
// Try to extract credentials from log
|
||||
let credentials = extract_initial_admin_from_log(&log_path);
|
||||
if let Some((email, password)) = credentials {
|
||||
// Use credentials
|
||||
}
|
||||
```
|
||||
|
||||
**New approach:**
|
||||
```rust
|
||||
// Check if config exists
|
||||
let config_path = PathBuf::from("botserver-stack/conf/system/directory_config.json");
|
||||
if config_path.exists() {
|
||||
// Load existing config
|
||||
return load_config(&config_path);
|
||||
}
|
||||
|
||||
// Generate new credentials
|
||||
let username = "admin";
|
||||
let email = "admin@localhost";
|
||||
let password = generate_secure_password();
|
||||
|
||||
// Create admin user in Zitadel
|
||||
let setup = DirectorySetup::new_with_credentials(
|
||||
base_url,
|
||||
Some((email.clone(), password.clone()))
|
||||
);
|
||||
|
||||
let admin_user = setup.create_admin_user(username, email, &password).await?;
|
||||
|
||||
// Create OAuth client
|
||||
let oauth_client = setup.create_oauth_application().await?;
|
||||
|
||||
// Save config
|
||||
let config = DirectoryConfig {
|
||||
base_url,
|
||||
admin_token: admin_user.pat_token,
|
||||
client_id: oauth_client.client_id,
|
||||
client_secret: oauth_client.client_secret,
|
||||
// ... other fields
|
||||
};
|
||||
|
||||
save_config(&config_path, &config)?;
|
||||
|
||||
// Display credentials to user
|
||||
print_bootstrap_credentials(&config, &password);
|
||||
|
||||
Ok(config)
|
||||
```
|
||||
|
||||
#### 2. Add `create_admin_user()` to `DirectorySetup`
|
||||
|
||||
```rust
|
||||
impl DirectorySetup {
|
||||
pub async fn create_admin_user(
|
||||
&self,
|
||||
username: &str,
|
||||
email: &str,
|
||||
password: &str,
|
||||
) -> Result<AdminUser> {
|
||||
// Use Zitadel Management API to create user
|
||||
// Endpoint: POST /management/v1/users/human
|
||||
|
||||
let user_payload = json!({
|
||||
"userName": username,
|
||||
"profile": {
|
||||
"firstName": "Admin",
|
||||
"lastName": "User"
|
||||
},
|
||||
"email": {
|
||||
"email": email,
|
||||
"isEmailVerified": true
|
||||
},
|
||||
"password": password,
|
||||
"passwordChangeRequired": false
|
||||
});
|
||||
|
||||
let response = self.client
|
||||
.post(format!("{}/management/v1/users/human", self.base_url))
|
||||
.json(&user_payload)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
// Extract user ID and create PAT token
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Ensure Directory Creation in `save_config()`
|
||||
|
||||
```rust
|
||||
fn save_config(path: &Path, config: &DirectoryConfig) -> Result<()> {
|
||||
// Create parent directory if it doesn't exist
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.map_err(|e| anyhow!("Failed to create config directory: {}", e))?;
|
||||
}
|
||||
|
||||
// Write config
|
||||
let json = serde_json::to_string_pretty(config)?;
|
||||
fs::write(path, json)
|
||||
.map_err(|e| anyhow!("Failed to write config file: {}", e))?;
|
||||
|
||||
info!("Saved Directory configuration to {}", path.display());
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Update Config File Path
|
||||
|
||||
**Old path:** `config/directory_config.json`
|
||||
**New path:** `botserver-stack/conf/system/directory_config.json`
|
||||
|
||||
Update all references in:
|
||||
- `botserver/src/core/package_manager/mod.rs`
|
||||
- `botserver/src/core/bootstrap/bootstrap_manager.rs`
|
||||
- `botserver/src/main_module/bootstrap.rs`
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Step 1: Create Admin User via API
|
||||
|
||||
**File:** `botserver/src/core/package_manager/setup/directory_setup.rs`
|
||||
|
||||
Add method to create admin user:
|
||||
```rust
|
||||
pub async fn create_admin_user(
|
||||
&self,
|
||||
username: &str,
|
||||
email: &str,
|
||||
password: &str,
|
||||
) -> Result<AdminUser> {
|
||||
// Implementation using Zitadel Management API
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: Update setup_directory()
|
||||
|
||||
**File:** `botserver/src/core/package_manager/mod.rs`
|
||||
|
||||
Replace log parsing with direct user creation:
|
||||
```rust
|
||||
pub async fn setup_directory() -> Result<DirectoryConfig> {
|
||||
let config_path = PathBuf::from("botserver-stack/conf/system/directory_config.json");
|
||||
|
||||
// Check existing config
|
||||
if config_path.exists() {
|
||||
return load_config(&config_path);
|
||||
}
|
||||
|
||||
// Generate credentials
|
||||
let password = generate_secure_password();
|
||||
let email = "admin@localhost";
|
||||
let username = "admin";
|
||||
|
||||
// Create admin and OAuth client
|
||||
let setup = DirectorySetup::new(base_url);
|
||||
let admin = setup.create_admin_user(username, email, &password).await?;
|
||||
let oauth = setup.create_oauth_application(&admin.token).await?;
|
||||
|
||||
// Save config
|
||||
let config = DirectoryConfig { /* ... */ };
|
||||
save_config(&config_path, &config)?;
|
||||
|
||||
// Display credentials
|
||||
print_credentials(username, email, &password);
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Fix save_config()
|
||||
|
||||
**File:** `botserver/src/core/package_manager/setup/directory_setup.rs`
|
||||
|
||||
Ensure parent directory exists:
|
||||
```rust
|
||||
async fn save_config_internal(&self, config: &DirectoryConfig) -> Result<()> {
|
||||
let path = PathBuf::from("botserver-stack/conf/system/directory_config.json");
|
||||
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
let json = serde_json::to_string_pretty(config)?;
|
||||
fs::write(&path, json)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Remove Log Parsing
|
||||
|
||||
**File:** `botserver/src/core/package_manager/mod.rs`
|
||||
|
||||
Delete or deprecate `extract_initial_admin_from_log()` function - it's not reliable.
|
||||
|
||||
## Config File Structure
|
||||
|
||||
**Location:** `botserver-stack/conf/system/directory_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"base_url": "http://localhost:8300",
|
||||
"default_org": {
|
||||
"id": "<organization_id>",
|
||||
"name": "General Bots",
|
||||
"domain": "localhost"
|
||||
},
|
||||
"default_user": {
|
||||
"id": "<user_id>",
|
||||
"username": "admin",
|
||||
"email": "admin@localhost",
|
||||
"password": "",
|
||||
"first_name": "Admin",
|
||||
"last_name": "User"
|
||||
},
|
||||
"admin_token": "<personal_access_token>",
|
||||
"project_id": "<project_id>",
|
||||
"client_id": "<oauth_client_id>",
|
||||
"client_secret": "<oauth_client_secret>"
|
||||
}
|
||||
```
|
||||
|
||||
## Expected Bootstrap Flow
|
||||
|
||||
### First Run (No Config)
|
||||
|
||||
```
|
||||
[Bootstrap] Starting Zitadel/Directory service...
|
||||
[Bootstrap] Directory service started, waiting for readiness...
|
||||
[Bootstrap] Zitadel/Directory service is responding
|
||||
[Bootstrap] No directory_config.json found, initializing new setup
|
||||
[Bootstrap] Generated admin password: Xk9#mP2$vL5@nQ8&
|
||||
[Bootstrap] Creating admin user in Zitadel...
|
||||
[Bootstrap] Admin user created: admin@localhost
|
||||
[Bootstrap] Creating OAuth application...
|
||||
[Bootstrap] OAuth client created: client_id=123456789
|
||||
[Bootstrap] Saved Directory configuration to botserver-stack/conf/system/directory_config.json
|
||||
|
||||
╔════════════════════════════════════════════════════════════╗
|
||||
║ 🔐 ADMIN LOGIN - READY TO USE ║
|
||||
╠════════════════════════════════════════════════════════════╣
|
||||
║ ║
|
||||
║ Username: admin ║
|
||||
║ Password: Xk9#mP2$vL5@nQ8& ║
|
||||
║ Email: admin@localhost ║
|
||||
║ ║
|
||||
║ 🌐 LOGIN NOW: http://localhost:3000/suite/login ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════════════════╝
|
||||
|
||||
[Bootstrap] OAuth client created successfully
|
||||
[Bootstrap] Bootstrap process completed!
|
||||
```
|
||||
|
||||
### Subsequent Runs (Config Exists)
|
||||
|
||||
```
|
||||
[Bootstrap] Starting Zitadel/Directory service...
|
||||
[Bootstrap] Directory service started, waiting for readiness...
|
||||
[Bootstrap] Zitadel/Directory service is responding
|
||||
[Bootstrap] Loading existing Directory configuration
|
||||
[Bootstrap] OAuth client verified: client_id=123456789
|
||||
[Bootstrap] Bootstrap process completed!
|
||||
```
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Delete existing `botserver-stack/conf/system/directory_config.json`
|
||||
- [ ] Run `./reset.sh` or restart botserver
|
||||
- [ ] Verify admin user created in Zitadel
|
||||
- [ ] Verify OAuth application created in Zitadel
|
||||
- [ ] Verify `directory_config.json` exists with valid credentials
|
||||
- [ ] Verify credentials displayed in console
|
||||
- [ ] Verify `~/.gb-setup-credentials` file created
|
||||
- [ ] Test login with displayed credentials
|
||||
- [ ] Verify login returns valid token
|
||||
- [ ] Restart botserver again
|
||||
- [ ] Verify config is loaded (not recreated)
|
||||
- [ ] Verify login still works
|
||||
|
||||
## Files to Modify
|
||||
|
||||
1. **`botserver/src/core/package_manager/mod.rs`**
|
||||
- Update `setup_directory()` to generate credentials
|
||||
- Remove `extract_initial_admin_from_log()` or mark deprecated
|
||||
- Update config path to `botserver-stack/conf/system/directory_config.json`
|
||||
|
||||
2. **`botserver/src/core/package_manager/setup/directory_setup.rs`**
|
||||
- Add `create_admin_user()` method
|
||||
- Update `save_config_internal()` to create parent directories
|
||||
- Update config path
|
||||
|
||||
3. **`botserver/src/core/bootstrap/bootstrap_manager.rs`**
|
||||
- Update config path reference
|
||||
- Ensure proper error handling
|
||||
|
||||
4. **`botserver/src/main_module/bootstrap.rs`**
|
||||
- Update `init_directory_service()` to use new path
|
||||
|
||||
## Benefits of This Approach
|
||||
|
||||
1. **Fully Automatic** - No manual steps required
|
||||
2. **Reliable** - Doesn't depend on log parsing
|
||||
3. **Secure** - Generates strong passwords
|
||||
4. **Repeatable** - Works on every fresh install
|
||||
5. **User-Friendly** - Displays credentials clearly
|
||||
6. **Persistent** - Config saved in version-controlled location
|
||||
7. **Fast** - No waiting for log file parsing
|
||||
|
||||
## Migration from Old Setup
|
||||
|
||||
If `~/.gb-setup-credentials` exists but `directory_config.json` doesn't:
|
||||
|
||||
1. **Option A:** Use existing credentials
|
||||
- Read credentials from `~/.gb-setup-credentials`
|
||||
- Create OAuth client with those credentials
|
||||
- Save to `directory_config.json`
|
||||
|
||||
2. **Option B:** Create new setup
|
||||
- Ignore old credentials
|
||||
- Generate new admin password
|
||||
- Update or replace old credentials file
|
||||
- Save to `directory_config.json`
|
||||
|
||||
**Recommendation:** Option A (use existing credentials if available)
|
||||
|
||||
## Summary
|
||||
|
||||
**Problem:** OAuth client not created because bootstrap can't extract Zitadel credentials from logs.
|
||||
|
||||
**Solution:** Generate credentials programmatically, create admin user via API, create OAuth client, save config automatically.
|
||||
|
||||
**Result:** Fully automatic, reliable bootstrap that creates all necessary credentials and configuration without manual intervention.
|
||||
|
||||
**Timeline:**
|
||||
- Implementation: 2-4 hours
|
||||
- Testing: 1 hour
|
||||
- Total: 3-5 hours
|
||||
|
||||
**Priority:** HIGH - Blocking login functionality
|
||||
Loading…
Add table
Reference in a new issue