267 lines
11 KiB
HTML
267 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Web Console — Nexus One AI</title>
|
|
<link rel="stylesheet" href="style.css?v=4">
|
|
<style>
|
|
.console-wrap { background:#0D1117; border-radius:14px; overflow:hidden; border:1px solid #30363D; margin-bottom:24px; }
|
|
.console-bar { background:#161B22; padding:10px 16px; display:flex; align-items:center; gap:10px; border-bottom:1px solid #30363D; }
|
|
.console-dots { display:flex; gap:6px; }
|
|
.dot { width:12px; height:12px; border-radius:50%; }
|
|
.dot.red { background:#FF5F57; }
|
|
.dot.yel { background:#FFBD2E; }
|
|
.dot.grn { background:#28C840; }
|
|
.console-title { font-size:12px; color:#8B949E; font-family:monospace; flex:1; text-align:center; }
|
|
.console-frame { width:100%; height:600px; border:none; display:block; background:#0D1117; }
|
|
|
|
.ttyd-status { display:flex; align-items:center; gap:10px; padding:14px 18px; background:rgba(251,191,36,.08); border:1px solid #FED7AA; border-radius:10px; margin-bottom:24px; }
|
|
.ttyd-status.ok { background:rgba(34,197,94,.08); border-color:rgba(134,239,172,.2); }
|
|
.ttyd-dot { width:10px; height:10px; border-radius:50%; background:#F59E0B; flex-shrink:0; }
|
|
.ttyd-dot.ok { background:#22C55E; }
|
|
.ttyd-status-text { font-size:13px; color:#78350F; }
|
|
.ttyd-status.ok .ttyd-status-text { color:#15803D; }
|
|
|
|
.setup-card { background:var(--navy2); border:1px solid var(--bdr); border-radius:14px; padding:24px 28px; margin-bottom:20px; }
|
|
.setup-card h3 { font-size:16px; font-weight:700; margin-bottom:12px; color:var(--ink); }
|
|
.setup-card p { font-size:13px; color:var(--med); margin-bottom:12px; line-height:1.6; }
|
|
pre.setup-cmd { background:#0D1117; color:#E6EDF3; border-radius:8px; padding:14px 16px; font-size:12px; font-family:monospace; overflow-x:auto; margin:0 0 10px; line-height:1.7; }
|
|
.copy-btn { background:rgba(255,255,255,.03); border:1px solid var(--bdr); border-radius:6px; padding:5px 12px; font-size:11px; font-weight:600; cursor:pointer; font-family:inherit; color:var(--med); float:right; margin-bottom:6px; transition:all .15s; }
|
|
.copy-btn:hover { border-color:var(--teal); color:var(--teal); }
|
|
|
|
.conn-btn { background:var(--teal); color:var(--ink); border:none; border-radius:8px; padding:9px 20px; font-size:13px; font-weight:600; cursor:pointer; font-family:inherit; }
|
|
.conn-btn:hover { background:#0B7A70; }
|
|
</style>
|
|
</head>
|
|
<body data-role="admin">
|
|
|
|
<header class="topnav">
|
|
<a href="index.html" class="brand">Nexus One <span>AI</span></a>
|
|
<nav>
|
|
<a href="index.html">Home</a>
|
|
<a href="quickstart.html">Quick Start</a>
|
|
<a href="prompts.html">Prompt Library</a>
|
|
<a href="usecases.html">Use Cases</a>
|
|
<span class="nav-sep"></span>
|
|
<div class="nav-dropdown">
|
|
<button class="nav-drop-btn">Help ▾</button>
|
|
<div class="nav-drop-menu">
|
|
<span class="nav-drop-cat">LEARN /</span>
|
|
<a href="quickstart.html">Quick Start</a>
|
|
<a href="models.html">Models</a>
|
|
<span class="nav-drop-cat">SUPPORT /</span>
|
|
<a href="troubleshooting.html">Troubleshoot</a>
|
|
<a href="faq.html">FAQ</a>
|
|
<span class="nav-drop-cat">MORE /</span>
|
|
<a href="glossary.html">Glossary</a>
|
|
<a href="whats-new.html">What's New</a>
|
|
</div>
|
|
</div>
|
|
<div class="nav-dropdown">
|
|
<button class="nav-drop-btn active">Admin ▾</button>
|
|
<div class="nav-drop-menu nav-drop-menu-wide">
|
|
<span class="nav-drop-cat">DOCS /</span>
|
|
<a href="security.html">Security & Privacy</a>
|
|
<a href="admin.html">Admin Guide</a>
|
|
<span class="nav-drop-cat">MONITOR /</span>
|
|
<a href="dashboard.html">Dashboard</a>
|
|
<a href="analytics.html">Usage Analytics</a>
|
|
<a href="audit.html">Audit Log</a>
|
|
<a href="feedback.html">Feedback & Ratings</a>
|
|
<span class="nav-drop-cat">MANAGE /</span>
|
|
<a href="users.html">Users</a>
|
|
<a href="teams.html">Teams</a>
|
|
<a href="models-admin.html">Model Manager</a>
|
|
<a href="training.html">Training</a>
|
|
<a href="knowledge.html">Knowledge Base</a>
|
|
<span class="nav-drop-cat">TOOLS /</span>
|
|
<a href="apikeys.html">API Keys</a>
|
|
<a href="benchmark.html">Benchmarking</a>
|
|
<a href="model-compare.html">Model Compare</a>
|
|
<a href="api-playground.html">API Playground</a>
|
|
<a href="guardrails.html">Guardrails</a>
|
|
<a href="rag-quality.html">RAG Quality</a>
|
|
<a href="router.html">Model Router</a>
|
|
<a href="connectors.html">Connectors</a>
|
|
<span class="nav-drop-cat">SYSTEM /</span>
|
|
<a href="console.html" class="active">Console</a>
|
|
<a href="settings.html">Settings</a>
|
|
</div>
|
|
</div>
|
|
<div class="nav-dropdown">
|
|
<button class="nav-drop-btn">AI Tools ▾</button>
|
|
<div class="nav-drop-menu">
|
|
<span class="nav-drop-cat">INTELLIGENCE /</span>
|
|
<a href="documents.html">Document Intelligence</a>
|
|
<a href="chat-multi.html">Multimodal Chat</a>
|
|
<a href="prompt-studio.html">Prompt Studio</a>
|
|
<a href="meeting.html">Meeting Assistant</a>
|
|
<span class="nav-drop-cat">AUTOMATION /</span>
|
|
<a href="agents.html">Agent Builder</a>
|
|
<a href="schedules.html">Scheduled Jobs</a>
|
|
<a href="workflows.html">Workflow Automation</a>
|
|
<span class="nav-drop-cat">QUALITY /</span>
|
|
<a href="evals.html">AI Eval Suite</a>
|
|
<a href="chatrooms.html">Chat Rooms</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<a href="notifications.html" style="position:relative">🔔</a>
|
|
<span class="badge" data-brand="tier">Basic Tier</span>
|
|
<div id="nav-org-logo" class="nav-org-logo"></div>
|
|
</header>
|
|
|
|
<div class="page-hero">
|
|
<div class="label">Admin · Console</div>
|
|
<h1>Web Terminal</h1>
|
|
<p>Browser-based shell access to the Nexus One AI node via ttyd. Admin-only. All commands are logged.</p>
|
|
</div>
|
|
|
|
<div class="content">
|
|
|
|
<div class="ttyd-status" id="ttyd-status">
|
|
<div class="ttyd-dot" id="ttyd-dot"></div>
|
|
<div class="ttyd-status-text" id="ttyd-status-text">Checking ttyd connection…</div>
|
|
<button class="conn-btn" onclick="retryConnect()" style="margin-left:auto">Retry</button>
|
|
</div>
|
|
|
|
<div class="console-wrap" id="console-wrap" style="display:none">
|
|
<div class="console-bar">
|
|
<div class="console-dots">
|
|
<div class="dot red"></div>
|
|
<div class="dot yel"></div>
|
|
<div class="dot grn"></div>
|
|
</div>
|
|
<div class="console-title">cezen-node — bash</div>
|
|
</div>
|
|
<iframe class="console-frame" id="console-frame" src="" allow="clipboard-read; clipboard-write"></iframe>
|
|
</div>
|
|
|
|
<div id="setup-section">
|
|
<div class="setup-card">
|
|
<h3>ttyd Not Detected</h3>
|
|
<p>The web terminal requires <strong>ttyd</strong> running on port <strong>7681</strong>. Follow the steps below to install and start it. Once running, click Retry above.</p>
|
|
|
|
<button class="copy-btn" onclick="copyCmd('cmd-install')">Copy</button>
|
|
<pre class="setup-cmd" id="cmd-install"># Install ttyd
|
|
sudo apt install -y ttyd
|
|
|
|
# Create a dedicated console user (restricted shell)
|
|
sudo useradd -m -s /bin/bash cezen-console
|
|
sudo passwd cezen-console</pre>
|
|
|
|
<button class="copy-btn" onclick="copyCmd('cmd-service')">Copy</button>
|
|
<pre class="setup-cmd" id="cmd-service"># /etc/systemd/system/cezen-ttyd.service
|
|
[Unit]
|
|
Description=Cezen Web Terminal (ttyd)
|
|
After=network.target
|
|
|
|
[Service]
|
|
ExecStart=/usr/bin/ttyd --port 7681 --interface 127.0.0.1 \
|
|
--credential admin:CezenConsole2024! \
|
|
login -f cezen-console
|
|
Restart=always
|
|
User=root
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target</pre>
|
|
|
|
<button class="copy-btn" onclick="copyCmd('cmd-enable')">Copy</button>
|
|
<pre class="setup-cmd" id="cmd-enable">sudo systemctl daemon-reload
|
|
sudo systemctl enable --now cezen-ttyd
|
|
# Verify
|
|
sudo systemctl status cezen-ttyd</pre>
|
|
|
|
<p style="margin-top:16px;font-size:12px;color:var(--lt)">⚠️ ttyd is bound to 127.0.0.1 only. Nginx proxies <code>/console/</code> to <code>localhost:7681</code> so it is accessible through this portal without exposing the port directly.</p>
|
|
</div>
|
|
|
|
<div class="setup-card">
|
|
<h3>Nginx Proxy Config</h3>
|
|
<p>Add this to your Nginx site config so <code>/console/</code> tunnels to ttyd and <code>/api/</code> routes to the FastAPI backend.</p>
|
|
<button class="copy-btn" onclick="copyCmd('cmd-nginx')">Copy</button>
|
|
<pre class="setup-cmd" id="cmd-nginx">location /console/ {
|
|
proxy_pass http://127.0.0.1:7681/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_read_timeout 86400;
|
|
}
|
|
|
|
location /api/ {
|
|
proxy_pass http://127.0.0.1:8080;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
}</pre>
|
|
<button class="copy-btn" onclick="copyCmd('cmd-nginx2')">Copy</button>
|
|
<pre class="setup-cmd" id="cmd-nginx2">sudo nginx -t && sudo systemctl reload nginx</pre>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<footer>
|
|
<p>Nexus One AI · Powered by Cezen · Basic Tier</p>
|
|
</footer>
|
|
|
|
<script>
|
|
const TTYD_URL = '/console/';
|
|
|
|
async function checkTtyd() {
|
|
try {
|
|
const res = await fetch(TTYD_URL, { method:'HEAD', signal: AbortSignal.timeout(3000) });
|
|
if (res.ok || res.status === 401) {
|
|
setConnected();
|
|
} else {
|
|
setDisconnected();
|
|
}
|
|
} catch {
|
|
setDisconnected();
|
|
}
|
|
}
|
|
|
|
function setConnected() {
|
|
const st = document.getElementById('ttyd-status');
|
|
const dot = document.getElementById('ttyd-dot');
|
|
const txt = document.getElementById('ttyd-status-text');
|
|
st.classList.add('ok');
|
|
dot.classList.add('ok');
|
|
txt.textContent = 'ttyd is running — terminal ready';
|
|
document.getElementById('console-wrap').style.display = '';
|
|
document.getElementById('setup-section').style.display = 'none';
|
|
document.getElementById('console-frame').src = TTYD_URL;
|
|
}
|
|
|
|
function setDisconnected() {
|
|
const st = document.getElementById('ttyd-status');
|
|
const dot = document.getElementById('ttyd-dot');
|
|
const txt = document.getElementById('ttyd-status-text');
|
|
st.classList.remove('ok');
|
|
dot.classList.remove('ok');
|
|
txt.textContent = 'ttyd not detected on /console/ — see setup instructions below';
|
|
document.getElementById('console-wrap').style.display = 'none';
|
|
document.getElementById('setup-section').style.display = '';
|
|
}
|
|
|
|
function retryConnect() {
|
|
document.getElementById('ttyd-status-text').textContent = 'Checking…';
|
|
checkTtyd();
|
|
}
|
|
|
|
function copyCmd(id) {
|
|
const txt = document.getElementById(id).innerText;
|
|
navigator.clipboard.writeText(txt).then(() => {
|
|
const btn = event.target;
|
|
btn.textContent = 'Copied!';
|
|
setTimeout(() => { btn.textContent = 'Copy'; }, 1500);
|
|
});
|
|
}
|
|
|
|
checkTtyd();
|
|
</script>
|
|
<script src="auth.js"></script>
|
|
<script src="branding.js"></script>
|
|
</body>
|
|
</html>
|