|
|
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); |