UNPKG

lanonasis-memory

Version:

Memory as a Service integration - AI-powered memory management with semantic search (Compatible with CLI v3.0.6+)

449 lines (447 loc) 20 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.activate = activate; exports.manageApiKeys = manageApiKeys; exports.createProject = createProject; exports.viewProjects = viewProjects; exports.deactivate = deactivate; const vscode = __importStar(require("vscode")); const MemoryTreeProvider_1 = require("./providers/MemoryTreeProvider"); const MemoryCompletionProvider_1 = require("./providers/MemoryCompletionProvider"); const ApiKeyTreeProvider_1 = require("./providers/ApiKeyTreeProvider"); const EnhancedMemoryService_1 = require("./services/EnhancedMemoryService"); const ApiKeyService_1 = require("./services/ApiKeyService"); const SecureApiKeyService_1 = require("./services/SecureApiKeyService"); let enhancedMemoryService; async function activate(context) { console.log('Lanonasis Memory Extension (Enhanced) is now active'); // Create output channel for logging const outputChannel = vscode.window.createOutputChannel('Lanonasis'); // Initialize secure API key service const secureApiKeyService = new SecureApiKeyService_1.SecureApiKeyService(context, outputChannel); await secureApiKeyService.initialize(); // Initialize enhanced memory service enhancedMemoryService = new EnhancedMemoryService_1.EnhancedMemoryService(secureApiKeyService); // Initialize API key service const apiKeyService = new ApiKeyService_1.ApiKeyService(secureApiKeyService); // Initialize tree providers const memoryTreeProvider = new MemoryTreeProvider_1.MemoryTreeProvider(enhancedMemoryService); const apiKeyTreeProvider = new ApiKeyTreeProvider_1.ApiKeyTreeProvider(apiKeyService); vscode.window.registerTreeDataProvider('lanonasisMemories', memoryTreeProvider); vscode.window.registerTreeDataProvider('lanonasisApiKeys', apiKeyTreeProvider); // Initialize completion provider const completionProvider = new MemoryCompletionProvider_1.MemoryCompletionProvider(enhancedMemoryService); context.subscriptions.push(vscode.languages.registerCompletionItemProvider({ scheme: 'file' }, completionProvider, '@', '#', '//')); // Set context variables vscode.commands.executeCommand('setContext', 'lanonasis.enabled', true); // Check authentication status and CLI capabilities await checkEnhancedAuthenticationStatus(); // Register commands const commands = [ vscode.commands.registerCommand('lanonasis.searchMemory', async () => { await searchMemories(); }), vscode.commands.registerCommand('lanonasis.createMemory', async () => { await createMemoryFromSelection(); }), vscode.commands.registerCommand('lanonasis.createMemoryFromFile', async () => { await createMemoryFromFile(); }), vscode.commands.registerCommand('lanonasis.authenticate', async () => { await authenticate(); }), vscode.commands.registerCommand('lanonasis.refreshMemories', async () => { memoryTreeProvider.refresh(); }), vscode.commands.registerCommand('lanonasis.openMemory', (memory) => { openMemoryInEditor(memory); }), vscode.commands.registerCommand('lanonasis.switchMode', async () => { await switchConnectionMode(); }), // Enhanced command for connection info vscode.commands.registerCommand('lanonasis.showConnectionInfo', async () => { await enhancedMemoryService.showConnectionInfo(); }), // API Key Management Commands vscode.commands.registerCommand('lanonasis.manageApiKeys', async () => { await manageApiKeys(apiKeyService); }), vscode.commands.registerCommand('lanonasis.createProject', async () => { await createProject(apiKeyService, apiKeyTreeProvider); }), vscode.commands.registerCommand('lanonasis.viewProjects', async () => { await viewProjects(apiKeyService); }), vscode.commands.registerCommand('lanonasis.refreshApiKeys', async () => { apiKeyTreeProvider.refresh(); }) ]; context.subscriptions.push(...commands); // Add enhanced service to subscriptions for proper cleanup context.subscriptions.push(enhancedMemoryService); // Show welcome message with CLI information if first time const isFirstTime = context.globalState.get('lanonasis.firstTime', true); if (isFirstTime) { await showEnhancedWelcomeMessage(); context.globalState.update('lanonasis.firstTime', false); } // Show upgrade message if migrating from basic service const hasSeenUpgrade = context.globalState.get('lanonasis.seenCliUpgrade', false); if (!hasSeenUpgrade) { await showCliUpgradeMessage(); context.globalState.update('lanonasis.seenCliUpgrade', true); } } async function checkEnhancedAuthenticationStatus() { const config = vscode.workspace.getConfiguration('lanonasis'); const apiKey = config.get('apiKey'); const authenticated = !!apiKey && apiKey.trim().length > 0; vscode.commands.executeCommand('setContext', 'lanonasis.authenticated', authenticated); if (!authenticated) { const result = await vscode.window.showInformationMessage('Lanonasis Memory: No API key configured. Would you like to set it up now?', 'Configure', 'Later'); if (result === 'Configure') { vscode.commands.executeCommand('lanonasis.authenticate'); } return; } // Check CLI capabilities const capabilities = enhancedMemoryService.getCapabilities(); if (capabilities?.cliAvailable && capabilities.goldenContract) { vscode.window.showInformationMessage('🚀 Lanonasis Memory: CLI v1.5.2+ detected! Enhanced performance active.', 'Show Details').then(selection => { if (selection === 'Show Details') { vscode.commands.executeCommand('lanonasis.showConnectionInfo'); } }); } else if (capabilities?.authenticated) { const installCLI = await vscode.window.showInformationMessage('💡 Lanonasis Memory: Install CLI v1.5.2+ for enhanced performance.', 'Install CLI', 'Learn More', 'Later'); if (installCLI === 'Install CLI') { vscode.env.openExternal(vscode.Uri.parse('https://www.npmjs.com/package/@lanonasis/cli')); } else if (installCLI === 'Learn More') { vscode.env.openExternal(vscode.Uri.parse('https://docs.lanonasis.com/cli')); } } } async function searchMemories() { const query = await vscode.window.showInputBox({ prompt: 'Search memories', placeHolder: 'Enter search query...' }); if (!query) return; try { await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Searching memories...', cancellable: false }, async () => { const results = await enhancedMemoryService.searchMemories(query); await showSearchResults(results, query); }); } catch (error) { vscode.window.showErrorMessage(`Search failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async function showSearchResults(results, query) { if (results.length === 0) { vscode.window.showInformationMessage(`No memories found for "${query}"`); return; } const items = results.map(memory => ({ label: memory.title, description: memory.type, detail: memory.content.substring(0, 100) + (memory.content.length > 100 ? '...' : ''), memory })); const selected = await vscode.window.showQuickPick(items, { placeHolder: `Found ${results.length} memories for "${query}"` }); if (selected) { openMemoryInEditor(selected.memory); } } async function createMemoryFromSelection() { const editor = vscode.window.activeTextEditor; const hasSelection = editor && !editor.selection.isEmpty; let memoryContent = ''; let titleSeed = 'Manual memory'; const metadata = { source: 'vscode-enhanced', extensionVersion: '1.3.0' }; if (hasSelection && editor) { memoryContent = editor.document.getText(editor.selection); const fileName = editor.document.fileName; const lineNumber = editor.selection.start.line + 1; titleSeed = `Code from ${fileName}:${lineNumber}`; metadata.fileName = fileName; metadata.lineNumber = lineNumber.toString(); metadata.origin = 'selection'; } else { const clipboard = await vscode.env.clipboard.readText(); memoryContent = await vscode.window.showInputBox({ prompt: 'Paste or type the context you want to save as a memory', value: clipboard ? clipboard.substring(0, 2000) : '', ignoreFocusOut: true, validateInput: (value) => value && value.trim().length > 0 ? undefined : 'Content is required to create a memory.' }) || ''; if (!memoryContent.trim()) { vscode.window.showWarningMessage('Add some text to create a memory.'); return; } titleSeed = `Manual memory (${new Date().toLocaleString()})`; metadata.origin = 'manual'; } const title = await vscode.window.showInputBox({ prompt: 'Memory title', value: titleSeed }); if (!title) return; const config = vscode.workspace.getConfiguration('lanonasis'); const defaultType = config.get('defaultMemoryType', 'context'); try { await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Creating memory...', cancellable: false }, async () => { await enhancedMemoryService.createMemory({ title, content: memoryContent, memory_type: defaultType, tags: ['vscode', 'enhanced', metadata.origin || 'selection'], metadata }); }); vscode.window.showInformationMessage(`Memory "${title}" created successfully`); vscode.commands.executeCommand('lanonasis.refreshMemories'); } catch (error) { vscode.window.showErrorMessage(`Failed to create memory: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async function createMemoryFromFile() { const editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showWarningMessage('No active editor'); return; } const content = editor.document.getText(); const fileName = editor.document.fileName; const title = await vscode.window.showInputBox({ prompt: 'Memory title', value: `File: ${fileName.split('/').pop()}` }); if (!title) return; const config = vscode.workspace.getConfiguration('lanonasis'); const defaultType = config.get('defaultMemoryType', 'context'); try { await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Creating memory from file...', cancellable: false }, async () => { await enhancedMemoryService.createMemory({ title, content, memory_type: defaultType, tags: ['vscode', 'file', 'enhanced'], metadata: { source: 'vscode-file-enhanced', fileName, fullPath: fileName, extensionVersion: '1.3.0' } }); }); vscode.window.showInformationMessage(`Memory "${title}" created from file`); vscode.commands.executeCommand('lanonasis.refreshMemories'); } catch (error) { vscode.window.showErrorMessage(`Failed to create memory: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async function authenticate() { const apiKey = await vscode.window.showInputBox({ prompt: 'Enter your Lanonasis API Key', placeHolder: 'Get your API key from api.lanonasis.com', password: true, ignoreFocusOut: true }); if (!apiKey) return; try { // Test the API key with enhanced service await enhancedMemoryService.testConnection(apiKey); // Save to configuration const config = vscode.workspace.getConfiguration('lanonasis'); await config.update('apiKey', apiKey, vscode.ConfigurationTarget.Global); // Refresh the client to pick up new configuration await enhancedMemoryService.refreshClient(); vscode.commands.executeCommand('setContext', 'lanonasis.authenticated', true); vscode.window.showInformationMessage('Successfully authenticated with Lanonasis Memory Service'); vscode.commands.executeCommand('lanonasis.refreshMemories'); // Check CLI capabilities after authentication setTimeout(async () => { await checkEnhancedAuthenticationStatus(); }, 1000); } catch (error) { vscode.window.showErrorMessage(`Authentication failed: ${error instanceof Error ? error.message : 'Invalid API key'}`); } } function openMemoryInEditor(memory) { const capabilities = enhancedMemoryService.getCapabilities(); const connectionInfo = capabilities?.cliAvailable ? (capabilities.mcpSupport ? 'CLI+MCP' : 'CLI') : 'API'; const content = `# ${memory.title}\n\n**Type:** ${memory.type}\n**Created:** ${new Date(memory.created_at).toLocaleString()}\n**Connection:** ${connectionInfo}\n\n---\n\n${memory.content}`; vscode.workspace.openTextDocument({ content, language: 'markdown' }).then(doc => { vscode.window.showTextDocument(doc); }); } async function showEnhancedWelcomeMessage() { const message = `Welcome to Lanonasis Memory Assistant v1.3! 🧠 Enhanced with CLI v1.5.2+ integration for better performance 🔍 Press Ctrl+Shift+M to search memories 📝 Select text and press Ctrl+Shift+Alt+M to create a memory 🌐 Intelligent routing via CLI/MCP when available 🚀 Automatic fallback to direct API when needed Get your API key from api.lanonasis.com to get started.`; const selection = await vscode.window.showInformationMessage(message, 'Get API Key', 'Install CLI', 'Configure'); if (selection === 'Get API Key') { vscode.env.openExternal(vscode.Uri.parse('https://api.lanonasis.com')); } else if (selection === 'Install CLI') { vscode.env.openExternal(vscode.Uri.parse('https://www.npmjs.com/package/@lanonasis/cli')); } else if (selection === 'Configure') { vscode.commands.executeCommand('lanonasis.authenticate'); } } async function showCliUpgradeMessage() { const selection = await vscode.window.showInformationMessage('🚀 Lanonasis Memory v1.3 now supports CLI integration for enhanced performance!\n\nInstall @lanonasis/cli v1.5.2+ to unlock faster operations and MCP support.', 'Install CLI', 'Learn More', 'Later'); if (selection === 'Install CLI') { vscode.env.openExternal(vscode.Uri.parse('https://www.npmjs.com/package/@lanonasis/cli')); } else if (selection === 'Learn More') { vscode.env.openExternal(vscode.Uri.parse('https://docs.lanonasis.com/cli/vscode')); } } async function switchConnectionMode() { const config = vscode.workspace.getConfiguration('lanonasis'); const currentUseGateway = config.get('useGateway', true); const currentPreferCLI = config.get('preferCLI', true); const options = [ { label: '🚀 Auto (CLI + Gateway)', description: 'Use CLI when available, fallback to Gateway (Recommended)', picked: currentPreferCLI && currentUseGateway, value: { preferCLI: true, useGateway: true } }, { label: '⚡ CLI Only', description: 'Use CLI v1.5.2+ for all operations', picked: currentPreferCLI && !currentUseGateway, value: { preferCLI: true, useGateway: false } }, { label: '🌐 Gateway Only', description: 'Use Onasis Gateway, no CLI integration', picked: !currentPreferCLI && currentUseGateway, value: { preferCLI: false, useGateway: true } }, { label: '🔗 Direct API', description: 'Connect directly to memory service', picked: !currentPreferCLI && !currentUseGateway, value: { preferCLI: false, useGateway: false } } ]; const selected = await vscode.window.showQuickPick(options, { placeHolder: 'Choose connection mode', ignoreFocusOut: true }); if (!selected) return; try { await config.update('useGateway', selected.value.useGateway, vscode.ConfigurationTarget.Global); await config.update('preferCLI', selected.value.preferCLI, vscode.ConfigurationTarget.Global); await enhancedMemoryService.refreshClient(); vscode.window.showInformationMessage(`Updated connection preferences. Testing...`); // Test the new connection await enhancedMemoryService.testConnection(); vscode.window.showInformationMessage(`✅ Connection mode updated successfully`); vscode.commands.executeCommand('lanonasis.refreshMemories'); // Show updated connection info setTimeout(() => { vscode.commands.executeCommand('lanonasis.showConnectionInfo'); }, 1000); } catch (error) { vscode.window.showErrorMessage(`Failed to switch mode: ${error instanceof Error ? error.message : 'Unknown error'}`); // Revert the settings await config.update('useGateway', currentUseGateway, vscode.ConfigurationTarget.Global); await config.update('preferCLI', currentPreferCLI, vscode.ConfigurationTarget.Global); await enhancedMemoryService.refreshClient(); } } // Import existing API key management functions from original extension // These remain the same as they don't need CLI integration async function manageApiKeys(apiKeyService) { // ... (implementation same as original) } async function createProject(apiKeyService, apiKeyTreeProvider) { // ... (implementation same as original) } async function viewProjects(apiKeyService) { // ... (implementation same as original) } function deactivate() { if (enhancedMemoryService) { enhancedMemoryService.dispose(); } } //# sourceMappingURL=enhanced-extension.js.map