| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>API Configuration - NeuralOutlaw</title> |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://unpkg.com/feather-icons"></script> |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=Orbitron:wght@400;500;700;900&display=swap'); |
| |
| body { |
| font-family: 'JetBrains Mono', monospace; |
| overflow-x: hidden; |
| } |
| |
| .cyber-gradient { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| } |
| |
| .matrix-bg { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| z-index: -1; |
| opacity: 0.1; |
| } |
| |
| .glitch-text { |
| position: relative; |
| display: inline-block; |
| } |
| |
| .glitch-text::before, |
| .glitch-text::after { |
| content: attr(data-text); |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| } |
| |
| .glitch-text::before { |
| left: 2px; |
| text-shadow: -1px 0 #ff00ff; |
| animation: glitch-1 2s infinite linear alternate-reverse; |
| } |
| |
| .glitch-text::after { |
| left: -2px; |
| text-shadow: 1px 0 #00ffff; |
| animation: glitch-2 3s infinite linear alternate-reverse; |
| } |
| |
| @keyframes glitch-1 { |
| 0% { clip-path: inset(20% 0 65% 0); } |
| 20% { clip-path: inset(60% 0 5% 0); } |
| 40% { clip-path: inset(30% 0 45% 0); } |
| 60% { clip-path: inset(75% 0 15% 0); } |
| 80% { clip-path: inset(10% 0 70% 0); } |
| 100% { clip-path: inset(45% 0 35% 0); } |
| } |
| |
| @keyframes glitch-2 { |
| 0% { clip-path: inset(65% 0 20% 0); } |
| 20% { clip-path: inset(5% 0 60% 0); } |
| 40% { clip-path: inset(45% 0 30% 0); } |
| 60% { clip-path: inset(15% 0 75% 0); } |
| 80% { clip-path: inset(70% 0 10% 0); } |
| 100% { clip-path: inset(35% 0 45% 0); } |
| } |
| |
| .terminal-window { |
| background: rgba(0, 0, 0, 0.8); |
| border: 1px solid #00ffff; |
| box-shadow: 0 0 20px rgba(0, 255, 255, 0.5); |
| border-radius: 8px; |
| overflow: hidden; |
| } |
| |
| .terminal-header { |
| background: rgba(0, 0, 0, 0.9); |
| padding: 8px 15px; |
| border-bottom: 1px solid #00ffff; |
| } |
| |
| .terminal-body { |
| padding: 20px; |
| color: #00ff00; |
| font-family: 'JetBrains Mono', monospace; |
| max-height: 600px; |
| overflow-y: auto; |
| } |
| |
| .terminal-prompt { |
| color: #00ffff; |
| } |
| |
| .cyber-button { |
| background: linear-gradient(45deg, #ff00ff, #00ffff); |
| border: none; |
| color: black; |
| font-weight: bold; |
| padding: 12px 24px; |
| border-radius: 4px; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .cyber-button:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(255, 0, 255, 0.4); |
| } |
| |
| .cyber-button:active { |
| transform: translateY(0); |
| } |
| |
| .api-input { |
| background: rgba(0, 0, 0, 0.7); |
| border: 1px solid #00ffff; |
| color: #00ff00; |
| padding: 12px; |
| border-radius: 4px; |
| font-family: 'JetBrains Mono', monospace; |
| width: 100%; |
| font-size: 14px; |
| } |
| |
| .api-input:focus { |
| outline: none; |
| border-color: #ff00ff; |
| box-shadow: 0 0 10px rgba(255, 0, 255, 0.3); |
| } |
| |
| |
| ::-webkit-scrollbar { |
| width: 8px; |
| } |
| |
| ::-webkit-scrollbar-track { |
| background: rgba(0, 0, 0, 0.3); |
| } |
| |
| ::-webkit-scrollbar-thumb { |
| background: #00ffff; |
| border-radius: 4px; |
| } |
| |
| ::-webkit-scrollbar-thumb:hover { |
| background: #ff00ff; |
| } |
| |
| .success-message { |
| background: rgba(0, 255, 0, 0.1); |
| border: 1px solid #00ff00; |
| color: #00ff00; |
| padding: 10px; |
| border-radius: 4px; |
| margin-top: 10px; |
| } |
| |
| .error-message { |
| background: rgba(255, 0, 0, 0.1); |
| border: 1px solid #ff0000; |
| color: #ff0000; |
| padding: 10px; |
| border-radius: 4px; |
| margin-top: 10px; |
| } |
| </style> |
| </head> |
| <body class="bg-black text-white"> |
| |
| <canvas id="matrix" class="matrix-bg"></canvas> |
| |
| |
| <div id="vanta-bg"></div> |
| |
| |
| <nav class="fixed w-full z-50 bg-black bg-opacity-80 backdrop-blur-md border-b border-cyan-500"> |
| <div class="container mx-auto px-4 py-3 flex justify-between items-center"> |
| <div class="flex items-center"> |
| <h1 class="text-xl font-bold cyber-gradient bg-clip-text text-transparent glitch-text" data-text="NeuralOutlaw">NeuralOutlaw</h1> |
| </div> |
| <div class="flex space-x-6"> |
| <a href="index.html" class="text-cyan-300 hover:text-pink-500 transition-colors">Home</a> |
| <a href="coder.html" class="text-cyan-300 hover:text-pink-500 transition-colors">AI Coder</a> |
| <a href="api.html" class="text-cyan-300 hover:text-pink-500 transition-colors">API Config</a> |
| <a href="requests.html" class="text-cyan-300 hover:text-pink-500 transition-colors">Shadow Requests</a> |
| <a href="about.html" class="text-cyan-300 hover:text-pink-500 transition-colors">About</a> |
| </div> |
| </div> |
| </nav> |
| |
| |
| <section class="min-h-screen flex items-center justify-center pt-16 pb-20 px-4"> |
| <div class="container mx-auto max-w-4xl"> |
| <h1 class="text-4xl md:text-5xl font-bold text-center mb-8 glitch-text" data-text="API CONFIGURATION">API CONFIGURATION</h1> |
| <p class="text-lg text-cyan-300 text-center mb-12">Configure your API keys for enhanced NeuralOutlaw functionality</p> |
| |
| <div class="terminal-window"> |
| <div class="terminal-header flex items-center"> |
| <div class="flex space-x-2"> |
| <div class="w-3 h-3 rounded-full bg-red-500"></div> |
| <div class="w-3 h-3 rounded-full bg-yellow-500"></div> |
| <div class="w-3 h-3 rounded-full bg-green-500"></div> |
| </div> |
| <div class="flex-1 text-center text-sm">api_config_terminal</div> |
| </div> |
| <div class="terminal-body"> |
| <div class="mb-6"> |
| <h3 class="text-xl font-bold text-cyan-300 mb-4">API Configuration Panel</h3> |
| <p class="text-gray-300 mb-4">Enter your API keys below to unlock full NeuralOutlaw capabilities. Your keys are stored locally in your browser.</p> |
| |
| <div class="space-y-6"> |
| |
| <div> |
| <label for="openaiKey" class="block text-cyan-300 mb-2"> |
| <i data-feather="key" class="inline w-4 h-4 mr-2"></i> |
| OpenAI API Key |
| </label> |
| <input |
| type="password" |
| id="openaiKey" |
| class="api-input" |
| placeholder="sk-..." |
| value="" |
| /> |
| <p class="text-gray-400 text-sm mt-1">Required for advanced code generation features</p> |
| <div id="openaiStatus" class="hidden"></div> |
| </div> |
| |
| |
| <div> |
| <label for="githubKey" class="block text-cyan-300 mb-2"> |
| <i data-feather="github" class="inline w-4 h-4 mr-2"></i> |
| GitHub Personal Access Token |
| </label> |
| <input |
| type="password" |
| id="githubKey" |
| class="api-input" |
| placeholder="ghp_..." |
| value="" |
| /> |
| <p class="text-gray-400 text-sm mt-1">Optional: For GitHub integration and repository operations</p> |
| <div id="githubStatus" class="hidden"></div> |
| </div> |
| |
| |
| <div> |
| <label for="customEndpoint" class="block text-cyan-300 mb-2"> |
| <i data-feather="server" class="inline w-4 h-4 mr-2"></i> |
| Custom API Endpoint |
| </label> |
| <input |
| type="text" |
| id="customEndpoint" |
| class="api-input" |
| placeholder="https://api.yourservice.com/v1" |
| value="" |
| /> |
| <p class="text-gray-400 text-sm mt-1">Optional: Your custom API endpoint for specialized services</p> |
| <div id="endpointStatus" class="hidden"></div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="flex gap-4 mb-6"> |
| <button id="saveBtn" class="cyber-button flex-1"> |
| <i data-feather="save" class="inline w-4 h-4 mr-2"></i> |
| Save Configuration |
| </button> |
| <button id="testBtn" class="cyber-button flex-1 bg-gradient-to-r from-purple-500 to-pink-500"> |
| <i data-feather="wifi" class="inline w-4 h-4 mr-2"></i> |
| Test Connection |
| </button> |
| <button id="clearBtn" class="cyber-button flex-1 bg-gradient-to-r from-red-500 to-orange-500"> |
| <i data-feather="trash-2" class="inline w-4 h-4 mr-2"></i> |
| Clear All |
| </button> |
| </div> |
| |
| |
| <div id="statusDisplay" class="hidden"> |
| <div class="border-t border-cyan-800 pt-4"> |
| <h4 class="text-lg font-bold text-cyan-300 mb-2">Connection Status</h4> |
| <div id="statusContent" class="space-y-2"></div> |
| </div> |
| </div> |
| |
| |
| <div class="border-t border-cyan-800 pt-4 mt-6"> |
| <h4 class="text-lg font-bold text-cyan-300 mb-2">Current Configuration</h4> |
| <div class="bg-black bg-opacity-50 p-4 rounded border border-cyan-800"> |
| <pre id="configDisplay" class="text-sm text-green-400">Loading configuration...</pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mt-8 terminal-window"> |
| <div class="terminal-header flex items-center"> |
| <div class="flex space-x-2"> |
| <div class="w-3 h-3 rounded-full bg-red-500"></div> |
| <div class="w-3 h-3 rounded-full bg-yellow-500"></div> |
| <div class="w-3 h-3 rounded-full bg-green-500"></div> |
| </div> |
| <div class="flex-1 text-center text-sm">api_instructions</div> |
| </div> |
| <div class="terminal-body"> |
| <h3 class="text-xl font-bold text-cyan-300 mb-4">API Setup Instructions</h3> |
| <div class="space-y-4"> |
| <div> |
| <h4 class="font-bold text-pink-500 mb-2">OpenAI API Key:</h4> |
| <ol class="list-decimal list-inside text-gray-300 space-y-1 text-sm"> |
| <li>Visit <a href="https://platform.openai.com/api-keys" class="text-cyan-300 hover:underline" target="_blank">OpenAI API Keys</a></li> |
| <li>Sign in to your OpenAI account</li> |
| <li>Click "Create new secret key"</li> |
| <li>Copy the key and paste it above</li> |
| <li>Save the configuration</li> |
| </ol> |
| </div> |
| <div> |
| <h4 class="font-bold text-pink-500 mb-2">GitHub Token:</h4> |
| <ol class="list-decimal list-inside text-gray-300 space-y-1 text-sm"> |
| <li>Go to <a href="https://github.com/settings/tokens" class="text-cyan-300 hover:underline" target="_blank">GitHub Settings → Developer settings → Personal access tokens</a></li> |
| <li>Generate new token with appropriate permissions</li> |
| <li>Copy the token and paste it above</li> |
| </ol> |
| </div> |
| <div class="text-yellow-400 text-sm"> |
| <i data-feather="alert-triangle" class="inline w-4 h-4 mr-1"></i> |
| <strong>Security Note:</strong> API keys are stored locally in your browser and never transmitted to our servers. |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| |
| <footer class="py-8 px-4 border-t border-cyan-900 bg-black bg-opacity-80"> |
| <div class="container mx-auto text-center"> |
| <p class="text-gray-400">NeuralOutlaw Coder AI 🦹 - Pushing the boundaries of AI-assisted development</p> |
| <p class="text-gray-500 text-sm mt-2">Use responsibly. The creators are not responsible for any unauthorized usage.</p> |
| </div> |
| </footer> |
|
|
| <script> |
| |
| VANTA.GLOBE({ |
| el: "#vanta-bg", |
| mouseControls: true, |
| touchControls: true, |
| gyroControls: false, |
| minHeight: 200.00, |
| minWidth: 200.00, |
| scale: 1.00, |
| scaleMobile: 1.00, |
| color: 0x00ffff, |
| backgroundColor: 0x0, |
| size: 0.8 |
| }); |
| |
| |
| const canvas = document.getElementById('matrix'); |
| const ctx = canvas.getContext('2d'); |
| |
| function resizeCanvas() { |
| canvas.width = window.innerWidth; |
| canvas.height = window.innerHeight; |
| } |
| |
| resizeCanvas(); |
| window.addEventListener('resize', resizeCanvas); |
| |
| const chars = "01"; |
| const charArray = chars.split(""); |
| const fontSize = 14; |
| const columns = canvas.width / fontSize; |
| const drops = []; |
| |
| for(let x = 0; x < columns; x++) { |
| drops[x] = 1; |
| } |
| |
| function drawMatrix() { |
| ctx.fillStyle = "rgba(0, 0, 0, 0.04)"; |
| ctx.fillRect(0, 0, canvas.width, canvas.height); |
| |
| ctx.fillStyle = "#0f0"; |
| ctx.font = fontSize + "px monospace"; |
| |
| for(let i = 0; i < drops.length; i++) { |
| const text = charArray[Math.floor(Math.random() * charArray.length)]; |
| ctx.fillText(text, i * fontSize, drops[i] * fontSize); |
| |
| if(drops[i] * fontSize > canvas.height && Math.random() > 0.975) { |
| drops[i] = 0; |
| } |
| |
| drops[i]++; |
| } |
| } |
| |
| setInterval(drawMatrix, 35); |
| |
| |
| class APIConfig { |
| constructor() { |
| this.config = this.loadConfig(); |
| this.initializeForm(); |
| this.bindEvents(); |
| this.updateConfigDisplay(); |
| } |
| |
| loadConfig() { |
| const saved = localStorage.getItem('neuraloutlaw_api_config'); |
| return saved ? JSON.parse(saved) : { |
| openaiKey: '', |
| githubKey: '', |
| customEndpoint: '' |
| }; |
| } |
| |
| saveConfig() { |
| localStorage.setItem('neuraloutlaw_api_config', JSON.stringify(this.config)); |
| this.showMessage('Configuration saved successfully!', 'success'); |
| this.updateConfigDisplay(); |
| } |
| |
| initializeForm() { |
| document.getElementById('openaiKey').value = this.config.openaiKey; |
| document.getElementById('githubKey').value = this.config.githubKey; |
| document.getElementById('customEndpoint').value = this.config.customEndpoint; |
| } |
| |
| bindEvents() { |
| document.getElementById('saveBtn').addEventListener('click', () => this.handleSave()); |
| document.getElementById('testBtn').addEventListener('click', () => this.testConnections()); |
| document.getElementById('clearBtn').addEventListener('click', () => this.clearConfig()); |
| |
| |
| ['openaiKey', 'githubKey', 'customEndpoint'].forEach(field => { |
| document.getElementById(field).addEventListener('input', (e) => { |
| this.config[field] = e.target.value; |
| }); |
| }); |
| } |
| |
| handleSave() { |
| this.saveConfig(); |
| } |
| |
| async testConnections() { |
| const statusDisplay = document.getElementById('statusDisplay'); |
| const statusContent = document.getElementById('statusContent'); |
| |
| statusDisplay.classList.remove('hidden'); |
| statusContent.innerHTML = '<div class="text-cyan-300">Testing connections...</div>'; |
| |
| const results = []; |
| |
| |
| if (this.config.openaiKey) { |
| results.push(await this.testOpenAI()); |
| } else { |
| results.push({ service: 'OpenAI', status: 'skipped', message: 'No API key provided' }); |
| } |
| |
| |
| if (this.config.githubKey) { |
| results.push(await this.testGitHub()); |
| } else { |
| results.push({ service: 'GitHub', status: 'skipped', message: 'No token provided' }); |
| } |
| |
| |
| if (this.config.customEndpoint) { |
| results.push(await this.testCustomEndpoint()); |
| } else { |
| results.push({ service: 'Custom Endpoint', status: 'skipped', message: 'No endpoint provided' }); |
| } |
| |
| |
| statusContent.innerHTML = results.map(result => ` |
| <div class="flex items-center justify-between p-2 border border-cyan-800 rounded"> |
| <span class="text-cyan-300">${result.service}</span> |
| <span class="${result.status === 'success' ? 'text-green-400' : result.status === 'error' ? 'text-red-400' : 'text-yellow-400'}"> |
| ${result.status === 'success' ? '✅ Connected' : result.status === 'error' ? '❌ Failed' : '⏸️ Skipped'} |
| </span> |
| <span class="text-gray-400 text-sm">${result.message}</span> |
| </div> |
| `).join(''); |
| } |
| |
| async testOpenAI() { |
| try { |
| const response = await fetch('https://api.openai.com/v1/models', { |
| headers: { |
| 'Authorization': `Bearer ${this.config.openaiKey}` |
| } |
| }); |
| |
| if (response.ok) { |
| return { service: 'OpenAI', status: 'success', message: 'API key is valid' }; |
| } else { |
| return { service: 'OpenAI', status: 'error', message: 'Invalid API key' }; |
| } |
| } catch (error) { |
| return { service: 'OpenAI', status: 'error', message: 'Connection failed' }; |
| } |
| } |
| |
| async testGitHub() { |
| try { |
| const response = await fetch('https://api.github.com/user', { |
| headers: { |
| 'Authorization': `token ${this.config.githubKey}`, |
| 'Accept': 'application/vnd.github.v3+json' |
| } |
| }); |
| |
| if (response.ok) { |
| const user = await response.json(); |
| return { service: 'GitHub', status: 'success', message: `Connected as ${user.login}` }; |
| } else { |
| return { service: 'GitHub', status: 'error', message: 'Invalid token' }; |
| } |
| } catch (error) { |
| return { service: 'GitHub', status: 'error', message: 'Connection failed' }; |
| } |
| } |
| |
| async testCustomEndpoint() { |
| try { |
| const response = await fetch(this.config.customEndpoint, { |
| method: 'GET', |
| mode: 'cors' |
| }); |
| |
| if (response.ok) { |
| return { service: 'Custom Endpoint', status: 'success', message: 'Endpoint is reachable' }; |
| } else { |
| return { service: 'Custom Endpoint', status: 'error', message: `HTTP ${response.status}` }; |
| } |
| } catch (error) { |
| return { service: 'Custom Endpoint', status: 'error', message: 'Cannot reach endpoint' }; |
| } |
| } |
| |
| clearConfig() { |
| if (confirm('Are you sure you want to clear all API configurations?')) { |
| this.config = { |
| openaiKey: '', |
| githubKey: '', |
| customEndpoint: '' |
| }; |
| localStorage.removeItem('neuraloutlaw_api_config'); |
| this.initializeForm(); |
| this.updateConfigDisplay(); |
| this.showMessage('Configuration cleared!', 'success'); |
| } |
| } |
| |
| updateConfigDisplay() { |
| const display = document.getElementById('configDisplay'); |
| const maskedConfig = { |
| ...this.config, |
| openaiKey: this.config.openaiKey ? '••••' + this.config.openaiKey.slice(-4) : 'Not set', |
| githubKey: this.config.githubKey ? '••••' + this.config.githubKey.slice(-4) : 'Not set', |
| customEndpoint: this.config.customEndpoint || 'Not set' |
| }; |
| display.textContent = JSON.stringify(maskedConfig, null, 2); |
| } |
| |
| showMessage(message, type) { |
| const statusDiv = document.getElementById('openaiStatus'); |
| statusDiv.className = type === 'success' ? 'success-message' : 'error-message'; |
| statusDiv.textContent = message; |
| statusDiv.classList.remove('hidden'); |
| |
| setTimeout(() => { |
| statusDiv.classList.add('hidden'); |
| }, 3000); |
| } |
| } |
| |
| |
| document.addEventListener('DOMContentLoaded', () => { |
| new APIConfig(); |
| }); |
| |
| |
| feather.replace(); |
| </script> |
| </body> |
| </html> |