Some checks failed
BotServer CI / build (push) Failing after 13s
15 KiB
15 KiB
Vibe App Improvement Specification
Realistic Enhancements Based on Existing Architecture
Current State Analysis
Vibe is an AI-powered app builder with:
- ✅ Mantis Farm: Multi-agent system (Mantis #1-4 with EVOLVED/BRED/WILD states)
- ✅ Pipeline Stages: PLAN → BUILD → REVIEW → DEPLOY → MONITOR
- ✅ Canvas: Task node visualization with drag-and-drop
- ✅ Integrated Tools: Code editor, database schema, git, browser, terminal (via modals)
- ✅ Chat Interface: Real-time WebSocket with Mantis #1
- ✅ Deployment: Internal (GB Platform) and External (Forgejo ALM)
- ✅ MCP Panel: Model Context Protocol servers
- ✅ Backend:
/api/autotask/classifyendpoint for intent processing
🎯 Critical Improvements (Fix What's Broken)
1. Fix Task Node Rendering
Problem: Nodes don't persist after page refresh
Fix:
// Save nodes to localStorage
function saveCanvasState() {
localStorage.setItem('vibe_canvas_state', JSON.stringify({
nodes: taskNodes,
project: currentProject,
timestamp: Date.now()
}));
}
// Restore on load
function restoreCanvasState() {
const saved = localStorage.getItem('vibe_canvas_state');
if (!saved) return;
const state = JSON.parse(saved);
currentProject = state.project;
state.nodes.forEach((node, i) => {
setTimeout(() => {
addTaskNode(node.title, node.description, node.meta);
}, i * 200);
});
}
// Call on init
document.addEventListener('DOMContentLoaded', restoreCanvasState);
2. Make Editor Actually Editable
Problem: Editor modal loads but can't edit files
Fix:
<!-- Replace basic editor with Monaco -->
<div id="vibeEditorModal" class="vibe-editor-modal">
<div class="editor-header">
<span id="currentFileName">untitled.txt</span>
<div class="editor-actions">
<button onclick="saveFile()">💾 Save</button>
<button onclick="closeEditor()">✕</button>
</div>
</div>
<div id="monacoEditor" style="height: calc(100% - 50px);"></div>
</div>
<script src="/suite/js/vendor/monaco-editor/min/vs/loader.js"></script>
<script>
let editor;
function initMonaco() {
require.config({ paths: { vs: '/suite/js/vendor/monaco-editor/min/vs' } });
require(['vs/editor/editor.main'], function() {
editor = monaco.editor.create(document.getElementById('monacoEditor'), {
value: '',
language: 'javascript',
theme: 'vs-dark',
automaticLayout: true
});
});
}
async function saveFile() {
const content = editor.getValue();
const filename = document.getElementById('currentFileName').textContent;
await fetch('/api/vibe/file', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ filename, content })
});
vibeAddMsg('system', `✅ Saved ${filename}`);
}
</script>
3. Connect Database Schema Tool
Problem: Database modal shows but doesn't interact with actual DB
Fix:
async function loadDatabaseSchema() {
const response = await fetch('/api/vibe/schema');
const { tables } = await response.json();
const schemaView = document.getElementById('databaseSchemaView');
schemaView.innerHTML = tables.map(table => `
<div class="table-card">
<h4>${table.name}</h4>
<div class="columns">
${table.columns.map(col => `
<div class="column">
<span class="col-name">${col.name}</span>
<span class="col-type">${col.type}</span>
</div>
`).join('')}
</div>
</div>
`).join('');
}
async function createTable() {
const tableName = prompt('Table name:');
if (!tableName) return;
const response = await fetch('/api/vibe/schema/table', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: tableName,
columns: [
{ name: 'id', type: 'UUID PRIMARY KEY' },
{ name: 'created_at', type: 'TIMESTAMP DEFAULT NOW()' }
]
})
});
if (response.ok) {
vibeAddMsg('system', `✅ Created table ${tableName}`);
loadDatabaseSchema();
}
}
4. Fix Terminal Integration
Problem: Terminal doesn't execute commands
Fix:
// WebSocket for terminal
const terminalWs = new WebSocket(`ws://${location.host}/ws/terminal`);
const terminalOutput = document.getElementById('terminalOutput');
terminalWs.onmessage = (event) => {
const line = document.createElement('div');
line.textContent = event.data;
terminalOutput.appendChild(line);
terminalOutput.scrollTop = terminalOutput.scrollHeight;
};
function executeCommand(cmd) {
terminalWs.send(JSON.stringify({ command: cmd }));
}
document.getElementById('terminalInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
const cmd = e.target.value;
executeCommand(cmd);
e.target.value = '';
}
});
5. Make Git Status Actually Work
Problem: Git panel shows but doesn't show real status
Fix:
async function loadGitStatus() {
const response = await fetch('/api/vibe/git/status');
const { branch, changes } = await response.json();
document.getElementById('gitBranch').textContent = branch;
const changesList = document.getElementById('gitChanges');
changesList.innerHTML = changes.map(change => `
<div class="git-change ${change.status}">
<span class="change-status">${change.status}</span>
<span class="change-file">${change.file}</span>
</div>
`).join('');
}
async function gitCommit() {
const message = prompt('Commit message:');
if (!message) return;
await fetch('/api/vibe/git/commit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message })
});
vibeAddMsg('system', `✅ Committed: ${message}`);
loadGitStatus();
}
🚀 High-Value Additions
6. File Tree in Editor
What: Show project structure, click to open files
Implementation:
<div class="editor-sidebar">
<div class="file-tree" id="fileTree">
<!-- Populated dynamically -->
</div>
</div>
<script>
async function loadFileTree() {
const response = await fetch('/api/vibe/files');
const { files } = await response.json();
const tree = buildTree(files);
document.getElementById('fileTree').innerHTML = renderTree(tree);
}
function renderTree(node, level = 0) {
if (node.type === 'file') {
return `
<div class="tree-item file" style="padding-left: ${level * 16}px"
onclick="openFile('${node.path}')">
📄 ${node.name}
</div>
`;
}
return `
<div class="tree-item folder" style="padding-left: ${level * 16}px">
📁 ${node.name}
${node.children.map(child => renderTree(child, level + 1)).join('')}
</div>
`;
}
async function openFile(path) {
const response = await fetch(`/api/vibe/file?path=${encodeURIComponent(path)}`);
const content = await response.text();
editor.setValue(content);
document.getElementById('currentFileName').textContent = path.split('/').pop();
}
</script>
7. Keyboard Shortcuts
What: Cmd+S to save, Cmd+K for command palette
Implementation:
document.addEventListener('keydown', (e) => {
// Cmd/Ctrl + S: Save
if ((e.metaKey || e.ctrlKey) && e.key === 's') {
e.preventDefault();
saveFile();
}
// Cmd/Ctrl + K: Command palette
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
openCommandPalette();
}
// Cmd/Ctrl + B: Toggle sidebar
if ((e.metaKey || e.ctrlKey) && e.key === 'b') {
e.preventDefault();
toggleSidebar();
}
// Escape: Close modals
if (e.key === 'Escape') {
closeAllModals();
}
});
8. Quick Command Palette
What: Fuzzy search for all actions
Implementation:
<div id="commandPalette" class="command-palette" style="display: none;">
<input type="text" id="commandInput" placeholder="Type a command...">
<div class="command-results" id="commandResults"></div>
</div>
<script>
const commands = [
{ label: 'Save File', action: saveFile, shortcut: 'Cmd+S' },
{ label: 'New File', action: newFile, shortcut: 'Cmd+N' },
{ label: 'Open Terminal', action: () => openModal('terminal') },
{ label: 'Git Status', action: () => openModal('git') },
{ label: 'Database Schema', action: () => openModal('database') },
{ label: 'Deploy App', action: showDeploymentModal }
];
function openCommandPalette() {
document.getElementById('commandPalette').style.display = 'flex';
document.getElementById('commandInput').focus();
}
document.getElementById('commandInput').addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
const filtered = commands.filter(cmd =>
cmd.label.toLowerCase().includes(query)
);
document.getElementById('commandResults').innerHTML = filtered.map(cmd => `
<div class="command-item" onclick="executeCommand('${cmd.label}')">
<span>${cmd.label}</span>
<span class="shortcut">${cmd.shortcut || ''}</span>
</div>
`).join('');
});
</script>
9. Task Node Actions
What: Click node to see details, edit, or delete
Implementation:
function addTaskNode(title, description, meta) {
// ... existing code ...
node.onclick = () => showNodeDetails(nodeIdCounter);
return node;
}
function showNodeDetails(nodeId) {
const node = taskNodes.find(n => n.id === nodeId);
if (!node) return;
const modal = document.createElement('div');
modal.className = 'node-details-modal';
modal.innerHTML = `
<div class="modal-content">
<h3>${node.title}</h3>
<p>${node.description}</p>
<div class="node-files">
<h4>Files</h4>
${(node.meta.fileList || []).map(f => `<div>📄 ${f}</div>`).join('')}
</div>
<div class="node-actions">
<button onclick="editNode(${nodeId})">✏️ Edit</button>
<button onclick="deleteNode(${nodeId})">🗑️ Delete</button>
<button onclick="closeModal()">Close</button>
</div>
</div>
`;
document.body.appendChild(modal);
}
10. Deployment Status Tracking
What: Show real-time deployment progress
Implementation:
async function executeDeployment() {
const deployButton = document.getElementById('deployButton');
deployButton.textContent = 'Deploying...';
deployButton.disabled = true;
// Create progress tracker
const progressDiv = document.createElement('div');
progressDiv.className = 'deployment-progress';
progressDiv.innerHTML = `
<div class="progress-step active">📦 Building...</div>
<div class="progress-step">🚀 Deploying...</div>
<div class="progress-step">✅ Complete</div>
`;
document.querySelector('.vibe-deployment-panel').appendChild(progressDiv);
// WebSocket for deployment events
const deployWs = new WebSocket(`ws://${location.host}/ws/deployment`);
deployWs.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.step === 'building') {
updateProgressStep(0, 'active');
} else if (data.step === 'deploying') {
updateProgressStep(0, 'complete');
updateProgressStep(1, 'active');
} else if (data.step === 'complete') {
updateProgressStep(1, 'complete');
updateProgressStep(2, 'complete');
vibeAddMsg('bot', `✅ Deployed to: ${data.url}`);
deployButton.textContent = 'Deploy Now';
deployButton.disabled = false;
}
};
// Start deployment
const response = await fetch('/api/deployment/deploy', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(getDeploymentConfig())
});
}
🔧 Backend API Requirements
# File Operations
GET /api/vibe/files - List project files
GET /api/vibe/file?path=... - Get file content
POST /api/vibe/file - Save file
DELETE /api/vibe/file?path=... - Delete file
# Database
GET /api/vibe/schema - Get database schema
POST /api/vibe/schema/table - Create table
POST /api/vibe/schema/query - Execute SQL query
# Git
GET /api/vibe/git/status - Get git status
POST /api/vibe/git/commit - Commit changes
POST /api/vibe/git/push - Push to remote
# Terminal
WS /ws/terminal - Terminal WebSocket
# Deployment
POST /api/deployment/deploy - Deploy app
WS /ws/deployment - Deployment progress
📊 Database Schema
-- Store canvas state
CREATE TABLE vibe_projects (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
name VARCHAR(255),
canvas_state JSONB, -- nodes, connections
files JSONB, -- file tree
created_at TIMESTAMP,
updated_at TIMESTAMP
);
-- Track deployments
CREATE TABLE vibe_deployments (
id UUID PRIMARY KEY,
project_id UUID REFERENCES vibe_projects(id),
target VARCHAR(50), -- internal, external
status VARCHAR(50), -- building, deploying, complete, failed
url TEXT,
logs TEXT,
deployed_at TIMESTAMP
);
✅ Implementation Priority
Phase 1: Fix Broken Features (Week 1)
- ✅ Task node persistence
- ✅ Monaco editor integration
- ✅ Database schema viewer
- ✅ Terminal execution
- ✅ Git status display
Phase 2: Essential Features (Week 2)
- ✅ File tree navigation
- ✅ Keyboard shortcuts
- ✅ Command palette
- ✅ Node detail view
- ✅ Deployment tracking
Phase 3: Polish (Week 3)
- Error handling
- Loading states
- Empty states
- Responsive design
- Performance optimization
🧪 Testing Checklist
- Create new project
- Add task nodes to canvas
- Refresh page - nodes persist
- Open file in editor
- Edit and save file
- View database schema
- Execute terminal command
- Check git status
- Commit changes
- Deploy app (internal)
- Deploy app (external)
- Use keyboard shortcuts
- Search command palette
🎯 Success Metrics
- Canvas state persists across sessions
- Editor can open/edit/save files
- All tool modals are functional
- Deployment completes successfully
- No console errors
- Fast load time (< 2s)