# Cursor Extension → Vibn Integration Guide ## Overview This guide explains how to connect your Cursor extension to send session data to Vibn's Firebase backend. --- ## Architecture Flow ``` Cursor Extension ↓ User codes & uses AI ↓ Extension captures: - Model used - Tokens consumed - Files modified - Time elapsed ↓ Extension sends POST request to Vibn API ↓ Vibn verifies API key ↓ Stores session in Firebase ↓ User sees data in Vibn dashboard ``` --- ## 1. Extension Configuration ### Add Settings to Extension Users need to configure two settings in your Cursor extension: ```typescript // extension settings (package.json or settings UI) { "vibn.apiKey": { "type": "string", "default": "", "description": "Your Vibn API key (get it from vibnai.com/connections)" }, "vibn.apiUrl": { "type": "string", "default": "https://vibnai.com/api", "description": "Vibn API endpoint" } } ``` --- ## 2. Extension Code Changes ### A. Get User's API Key ```typescript import * as vscode from 'vscode'; function getVibnApiKey(): string | undefined { const config = vscode.workspace.getConfiguration('vibn'); return config.get('apiKey'); } function getVibnApiUrl(): string { const config = vscode.workspace.getConfiguration('vibn'); return config.get('apiUrl') || 'https://vibnai.com/api'; } ``` ### B. Send Session Data to Vibn ```typescript interface SessionData { projectId?: string; // Optional: link to a specific project startTime: string; // ISO 8601 timestamp endTime?: string; // ISO 8601 timestamp (if session ended) duration?: number; // seconds model: string; // e.g., "claude-sonnet-4", "gpt-4", etc. tokensUsed: number; cost: number; // USD filesModified: string[]; // Array of file paths conversationSummary?: string; // Optional: summary of what was done } async function sendSessionToVibn(sessionData: SessionData): Promise { const apiKey = getVibnApiKey(); const apiUrl = getVibnApiUrl(); if (!apiKey) { console.warn('Vibn API key not configured'); return false; } try { const response = await fetch(`${apiUrl}/sessions/track`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ apiKey, sessionData, }), }); if (!response.ok) { const error = await response.json(); console.error('Failed to send session to Vibn:', error); return false; } const result = await response.json(); console.log('Session tracked:', result.sessionId); return true; } catch (error) { console.error('Error sending session to Vibn:', error); return false; } } ``` ### C. Example Usage ```typescript // When a session starts const sessionStart = { startTime: new Date().toISOString(), model: 'claude-sonnet-4', tokensUsed: 0, cost: 0, filesModified: [], }; // When a session ends or periodically const sessionEnd = { ...sessionStart, endTime: new Date().toISOString(), duration: 1800, // 30 minutes tokensUsed: 45000, cost: 1.35, // $1.35 filesModified: [ '/src/components/Button.tsx', '/src/utils/helpers.ts', ], conversationSummary: 'Updated Button component styling and added helper functions', }; await sendSessionToVibn(sessionEnd); ``` --- ## 3. Dual Database Support (Transition Period) During migration, send data to both PostgreSQL (current) and Vibn (new): ```typescript async function trackSession(sessionData: SessionData) { // Send to PostgreSQL (existing) await sendToPostgreSQL(sessionData); // Send to Vibn (new) await sendSessionToVibn(sessionData); } ``` This allows: - Existing users to continue working - New Vibn users to get data immediately - Gradual migration path --- ## 4. API Endpoint Details ### Endpoint ``` POST https://vibnai.com/api/sessions/track ``` ### Request Body ```json { "apiKey": "vibn_abc123def456...", "sessionData": { "projectId": "optional-project-id", "startTime": "2025-01-15T10:30:00.000Z", "endTime": "2025-01-15T11:00:00.000Z", "duration": 1800, "model": "claude-sonnet-4", "tokensUsed": 45000, "cost": 1.35, "filesModified": [ "/src/components/Button.tsx", "/src/utils/helpers.ts" ], "conversationSummary": "Updated Button component styling" } } ``` ### Response (Success - 200) ```json { "success": true, "sessionId": "abc123def456", "message": "Session tracked successfully" } ``` ### Response (Error - 401) ```json { "error": "Invalid or inactive API key" } ``` ### Response (Error - 500) ```json { "error": "Failed to track session", "details": "Error message here" } ``` --- ## 5. Testing ### Local Development ```bash # Use localhost for testing POST http://localhost:3000/api/sessions/track ``` ### Production ```bash # Use production URL POST https://vibnai.com/api/sessions/track ``` ### Test API Key For development, users can get their API key from: ``` http://localhost:3000/marks-account/connections ``` or in production: ``` https://vibnai.com/[workspace]/connections ``` --- ## 6. Error Handling ### Invalid API Key - User sees: "Vibn API key is invalid. Please check your settings." - Extension: Disable Vibn integration silently, fall back to PostgreSQL only ### Network Error - User sees: Nothing (don't interrupt their work) - Extension: Queue sessions locally, retry later ### Rate Limiting - If we add rate limiting later, queue and retry with exponential backoff --- ## 7. User Experience ### Good UX: - ✅ Silent background syncing - ✅ No interruptions to coding - ✅ Optional notification when first session is tracked - ✅ Status indicator in extension (optional) ### Bad UX: - ❌ Blocking user while sending data - ❌ Showing errors for every failed request - ❌ Requiring manual sync --- ## 8. Security Best Practices ### DO: - ✅ Store API key in VSCode settings (encrypted by VS Code) - ✅ Use HTTPS for all requests - ✅ Validate API key before each request - ✅ Include timeout on requests (5-10 seconds) ### DON'T: - ❌ Log API keys to console - ❌ Store API keys in plaintext files - ❌ Send API keys in URL parameters - ❌ Retry forever on failure --- ## 9. Migration Strategy ### Phase 1: Dual Write (Now) - Send to both PostgreSQL and Vibn - No user impact - Validate Vibn is receiving data correctly ### Phase 2: Gradual Rollout - New users only use Vibn - Existing users continue with PostgreSQL - Migration tool for old data (optional) ### Phase 3: Vibn Only - Deprecate PostgreSQL - All users on Vibn - Extension only sends to Vibn --- ## 10. Example: Complete Integration ```typescript // vibn-integration.ts import * as vscode from 'vscode'; export class VibnIntegration { private apiKey: string | undefined; private apiUrl: string; private queuedSessions: SessionData[] = []; constructor() { this.loadConfig(); this.startPeriodicSync(); } private loadConfig() { const config = vscode.workspace.getConfiguration('vibn'); this.apiKey = config.get('apiKey'); this.apiUrl = config.get('apiUrl') || 'https://vibnai.com/api'; } async trackSession(sessionData: SessionData): Promise { if (!this.apiKey) { console.log('Vibn not configured, skipping'); return; } try { const response = await fetch(`${this.apiUrl}/sessions/track`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: this.apiKey, sessionData, }), signal: AbortSignal.timeout(10000), // 10 second timeout }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const result = await response.json(); console.log('Session tracked:', result.sessionId); } catch (error) { console.warn('Failed to send to Vibn, queuing:', error); this.queuedSessions.push(sessionData); } } private startPeriodicSync() { setInterval(() => this.retryQueuedSessions(), 60000); // Every minute } private async retryQueuedSessions() { if (this.queuedSessions.length === 0) return; const session = this.queuedSessions.shift(); if (session) { await this.trackSession(session); } } } // Export singleton export const vibnIntegration = new VibnIntegration(); ``` --- ## Need Help? - Check Vibn Dashboard: `https://vibnai.com/[workspace]/connections` - API Docs: `https://vibnai.com/docs/api` - Support: `support@vibnai.com` --- ## Summary 1. ✅ User gets API key from Vibn connections page 2. ✅ User adds API key to Cursor extension settings 3. ✅ Extension sends session data to Vibn API 4. ✅ Vibn validates API key and stores data in Firebase 5. ✅ User sees real-time data in Vibn dashboard Simple, secure, and non-intrusive! 🚀