| class CustomTerminal extends HTMLElement { |
| constructor() { |
| super(); |
| this.commands = []; |
| this.history = []; |
| this.historyIndex = -1; |
| } |
|
|
| connectedCallback() { |
| this.attachShadow({ mode: 'open' }); |
| |
| this.shadowRoot.innerHTML = ` |
| <style> |
| :host { |
| display: block; |
| } |
| .terminal { |
| background: #050505; |
| border: 1px solid #1f2937; |
| border-radius: 8px; |
| overflow: hidden; |
| } |
| .terminal-header { |
| background: #0a0a0a; |
| padding: 8px 16px; |
| border-bottom: 1px solid #1f2937; |
| display: flex; |
| align-items: center; |
| gap: 8px; |
| } |
| .terminal-dot { |
| width: 12px; |
| height: 12px; |
| border-radius: 50%; |
| } |
| .terminal-dot.red { background: #ef4444; } |
| .terminal-dot.yellow { background: #f97316; } |
| .terminal-dot.green { background: #22c55e; } |
| .terminal-title { |
| flex: 1; |
| text-align: center; |
| color: #6b7280; |
| font-size: 12px; |
| font-family: monospace; |
| } |
| .terminal-body { |
| padding: 16px; |
| height: 300px; |
| overflow-y: auto; |
| font-family: monospace; |
| font-size: 13px; |
| } |
| .terminal-line { |
| padding: 4px 0; |
| line-height: 1.5; |
| } |
| .terminal-prompt { |
| color: #22c55e; |
| } |
| .terminal-input { |
| background: transparent; |
| border: none; |
| outline: none; |
| color: #fff; |
| font-family: inherit; |
| font-size: inherit; |
| width: calc(100% - 20px); |
| } |
| .timestamp { |
| color: #4b5563; |
| margin-right: 8px; |
| } |
| .cmd { color: #22c55e; } |
| .error { color: #ef4444; } |
| .warn { color: #f97316; } |
| .info { color: #3b82f6; } |
| .success { color: #22c55e; } |
| .muted { color: #6b7280; } |
| |
| ::-webkit-scrollbar { |
| width: 6px; |
| } |
| ::-webkit-scrollbar-track { |
| background: #050505; |
| } |
| ::-webkit-scrollbar-thumb { |
| background: #1f2937; |
| border-radius: 3px; |
| } |
| </style> |
| <div class="terminal"> |
| <div class="terminal-header"> |
| <div class="terminal-dot red"></div> |
| <div class="terminal-dot yellow"></div> |
| <div class="terminal-dot green"></div> |
| <div class="terminal-title">clawdbot-terminal</div> |
| </div> |
| <div class="terminal-body" id="output"></div> |
| <div style="padding: 12px 16px; display: flex; align-items: center;"> |
| <span class="terminal-prompt">$</span> |
| <input type="text" class="terminal-input" id="input" placeholder="Enter command..." autofocus> |
| </div> |
| </div> |
| `; |
| |
| this.output = this.shadowRoot.getElementById('output'); |
| this.input = this.shadowRoot.getElementById('input'); |
| |
| |
| this.commands = { |
| help: () => this.print('Available commands: help, clear, status, agents, tasks, scan, deploy, version, date, echo [text]'), |
| clear: () => this.output.innerHTML = '', |
| status: () => this.print('SYSTEM STATUS: ONLINE\nActive Agents: 42\nPending Tasks: 8\nSecurity Level: HIGH', 'success'), |
| agents: () => this.print('Active Agents:\n- AGNT-099 (ONLINE)\n- AGNT-104 (BUSY)\n- AGNT-112 (OFFLINE)', 'info'), |
| tasks: () => this.print('Pending Tasks:\n1. Network scan (Priority: HIGH)\n2. Data extraction (Priority: MED)\n3. System update (Priority: LOW)', 'info'), |
| scan: () => { |
| this.print('Initiating network scan...', 'warn'); |
| setTimeout(() => this.print('Scan complete. 156 nodes detected. 0 vulnerabilities found.', 'success'), 2000); |
| }, |
| deploy: () => this.print('Deployment requires authorization level 4.', 'error'), |
| version: () => this.print('Clawdbot C2 v3.2.0\nBuild: 2024.01.15', 'info'), |
| date: () => this.print(new Date().toString(), 'info'), |
| echo: (args) => this.print(args.join(' ')), |
| whoami: () => this.print('Commander Shepard (Level 4 Access)', 'success'), |
| ls: () => this.print('agents/ tasks/ logs/ config/ keys/', 'info'), |
| pwd: () => this.print('/root/clawdbot', 'info'), |
| top: () => this.print('CPU: 67% MEM: 4.2GB NET: 1.2GB/s', 'info') |
| }; |
| |
| this.print('Clawdbot Terminal v1.0', 'success'); |
| this.print('Type "help" for available commands.\n', 'muted'); |
| |
| this.input.addEventListener('keydown', (e) => { |
| if (e.key === 'Enter') { |
| const command = this.input.value.trim(); |
| if (command) { |
| this.executeCommand(command); |
| this.history.push(command); |
| this.historyIndex = this.history.length; |
| } |
| this.input.value = ''; |
| } else if (e.key === 'ArrowUp') { |
| e.preventDefault(); |
| if (this.historyIndex > 0) { |
| this.historyIndex--; |
| this.input.value = this.history[this.historyIndex]; |
| } |
| } else if (e.key === 'ArrowDown') { |
| e.preventDefault(); |
| if (this.historyIndex < this.history.length - 1) { |
| this.historyIndex++; |
| this.input.value = this.history[this.historyIndex]; |
| } else { |
| this.historyIndex = this.history.length; |
| this.input.value = ''; |
| } |
| } |
| }); |
| } |
| |
| print(text, type = '') { |
| const line = document.createElement('div'); |
| line.className = `terminal-line ${type}`; |
| line.innerHTML = `<span class="timestamp">[${new Date().toLocaleTimeString()}]</span>${text.replace(/\n/g, '<br>')}`; |
| this.output.appendChild(line); |
| this.output.scrollTop = this.output.scrollHeight; |
| } |
| |
| executeCommand(input) { |
| this.print(`$ ${input}`, 'cmd'); |
| const parts = input.split(' '); |
| const cmd = parts[0].toLowerCase(); |
| const args = parts.slice(1); |
| |
| if (this.commands[cmd]) { |
| try { |
| this.commands[cmd](args); |
| } catch (error) { |
| this.print(`Error executing command: ${error.message}`, 'error'); |
| } |
| } else { |
| this.print(`Command not found: ${cmd}. Type "help" for available commands.`, 'error'); |
| } |
| } |
| } |
|
|
| customElements.define('custom-terminal', CustomTerminal); |