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
|
# 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**
|
> **⚠️ 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.
|
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.
|
>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
|
## 🔐 Security Directives - MANDATORY
|
||||||
|
|
||||||
### 1. Error Handling - NO PANICS IN PRODUCTION
|
### 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",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"jsonwebtoken": "^9.0.3",
|
||||||
|
"node-fetch": "^3.3.2",
|
||||||
"ws": "^8.19.0"
|
"ws": "^8.19.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -42,6 +44,65 @@
|
||||||
"undici-types": "~7.16.0"
|
"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": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
"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": "^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": {
|
"node_modules/playwright": {
|
||||||
"version": "1.58.2",
|
"version": "1.58.2",
|
||||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz",
|
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz",
|
||||||
|
|
@ -89,6 +279,38 @@
|
||||||
"node": ">=18"
|
"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": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||||
|
|
@ -96,6 +318,15 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/ws": {
|
||||||
"version": "8.19.0",
|
"version": "8.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
},
|
},
|
||||||
"scripts": {},
|
"scripts": {},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"jsonwebtoken": "^9.0.3",
|
||||||
|
"node-fetch": "^3.3.2",
|
||||||
"ws": "^8.19.0"
|
"ws": "^8.19.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
108
reset.sh
108
reset.sh
|
|
@ -1 +1,109 @@
|
||||||
|
#!/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
|
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
|
cargo build -p botui
|
||||||
|
|
||||||
echo "Starting botserver..."
|
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 " PID: $!"
|
||||||
|
|
||||||
echo "Starting botui..."
|
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 " PID: $!"
|
||||||
|
|
||||||
echo "Done. Logs: tail -f botserver.log botui.log"
|
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:
|
dependencies:
|
||||||
undici-types "~7.16.0"
|
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:
|
playwright-core@1.58.2:
|
||||||
version "1.58.2"
|
version "1.58.2"
|
||||||
resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz"
|
resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz"
|
||||||
|
|
@ -30,11 +149,26 @@ playwright@1.58.2:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "2.3.2"
|
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:
|
undici-types@~7.16.0:
|
||||||
version "7.16.0"
|
version "7.16.0"
|
||||||
resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz"
|
resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz"
|
||||||
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
|
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:
|
ws@^8.19.0:
|
||||||
version "8.19.0"
|
version "8.19.0"
|
||||||
resolved "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz"
|
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