oclaw/interfaces/admin/static/index.html
oliver 16169b3de2 fix(desktop): external gateway mode and start script alignment
- Add desktop env for non-embedded gateway (OCLAW_DESKTOP_EMBED_BACKEND, base URL, skip channel).
- Wire start_all/start_desktop to pass gateway URL when keeping existing gateway; fix root start_all flags.
- Prefer electron.cmd for background desktop launch; admin static theme presets and chat boot timeouts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-06 11:06:16 +08:00

141 lines
6.8 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>oliver</title>
<!-- Avoid render-blocking external fonts (can stall first paint ~30s on blocked networks). -->
<link rel="stylesheet" href="/admin/assets/styles.css" />
<link rel="stylesheet" href="/admin/assets/theme-deepseek.css" />
<link rel="stylesheet" href="/admin/assets/theme-presets.css" />
<style>
/* First paint before app.js runs: keep admin from showing a blank dark screen. */
.admin-boot-splash {
padding: 16px;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 14px;
background: rgba(255, 255, 255, 0.04);
color: var(--ds-text, #e8e8e8);
line-height: 1.5;
max-width: 520px;
}
.admin-boot-splash__title {
font-weight: 650;
display: flex;
gap: 10px;
align-items: center;
margin-bottom: 8px;
}
.admin-boot-splash__spinner {
width: 18px;
height: 18px;
border: 2px solid rgba(255, 255, 255, 0.15);
border-top-color: rgba(255, 255, 255, 0.75);
border-radius: 999px;
animation: admin-boot-spin 1s linear infinite;
flex: 0 0 auto;
}
@keyframes admin-boot-spin {
to {
transform: rotate(360deg);
}
}
.admin-boot-splash__muted {
opacity: 0.78;
font-size: 13px;
white-space: pre-wrap;
}
</style>
</head>
<body class="theme-ds-body">
<script src="/admin/assets/admin-theme.js"></script>
<div class="layout">
<aside class="sidebar">
<div class="brand">
<div class="brand__logoWrap">
<img class="brand__logo" src="/admin/assets/oliver.svg" alt="oliver logo" />
</div>
</div>
<nav class="nav">
<div class="nav__group">
<div class="nav__groupTitle">系统与运行</div>
<a class="nav__item" data-page="stack" href="#/stack" data-i18n="nav.stack">Runtime</a>
<a class="nav__item" data-page="session-monitor" href="#/session-monitor" data-i18n="nav.sessionMonitor">会话监控</a>
<a class="nav__item" data-page="workspace-paths" href="#/workspace-paths" data-i18n="nav.workspacePaths">工作区路径</a>
<a class="nav__item" data-page="attachments" href="#/attachments" data-i18n="nav.attachments">附件</a>
</div>
<div class="nav__group">
<div class="nav__groupTitle">模型与插件</div>
<a class="nav__item" data-page="models" href="#/models" data-i18n="nav.models">模型管理</a>
<a class="nav__item" data-page="api-grants" href="#/api-grants" data-i18n="nav.apiGrants">API 使用授权</a>
<a class="nav__item" data-page="plugins" href="#/plugins" data-i18n="nav.plugins">Plugins</a>
<a class="nav__item" data-page="skills" href="#/skills" data-i18n="nav.skills">Skills</a>
</div>
<div class="nav__group">
<div class="nav__groupTitle">治理与审计</div>
<a class="nav__item" data-page="memory" href="#/memory" data-i18n="nav.memory">Memory</a>
<a class="nav__item" data-page="audit" href="#/audit" data-i18n="nav.audit">Audit & Trace</a>
<a class="nav__item" data-page="admin-audit" href="#/admin-audit" data-i18n="nav.adminAudit">Admin Audit</a>
</div>
<div class="nav__group">
<div class="nav__groupTitle">用户与配置</div>
<a class="nav__item" data-page="users" href="#/users" data-i18n="nav.users">用户管理</a>
<a class="nav__item" data-page="profile" href="#/profile" data-i18n="nav.profile">设置</a>
</div>
<div class="nav__group">
<div class="nav__groupTitle">运维工具</div>
<a
class="nav__item"
href="http://127.0.0.1:5173/"
target="_blank"
rel="noopener noreferrer"
data-i18n="nav.netx"
>打开 netx 运维工具</a
>
</div>
</nav>
<div class="sidebar__footer">
<div class="muted" data-i18n="notice.noLogin">v1 无登录:请仅在内网访问</div>
</div>
</aside>
<main class="main">
<header class="topbar">
<div id="topTitle" class="topbar__title">Runtime</div>
<div class="topbar__actions">
<span id="authUser" class="muted"></span>
<label class="admin-theme-wrap" style="display: inline-flex; align-items: center; gap: 6px; margin-right: 4px">
<span class="muted" style="font-size: 12px" data-i18n="theme.label">配色</span>
<select id="adminThemeSelect" class="input input--compact" style="min-width: 132px; max-width: 200px; padding: 6px 8px" aria-label="theme">
<option value="deepseek" data-i18n="theme.deepseek">DeepSeek</option>
<option value="github" data-i18n="theme.github">GitHub</option>
<option value="nord" data-i18n="theme.nord">Nord</option>
<option value="dracula" data-i18n="theme.dracula">Dracula</option>
<option value="forest" data-i18n="theme.forest">Forest</option>
<option value="catppuccin" data-i18n="theme.catppuccin">Catppuccin</option>
<option value="light" data-i18n="theme.light">Light</option>
</select>
</label>
<a id="btnBackChat" class="btn" data-i18n="nav.chat" href="chat">对话</a>
<button id="btnLogout" class="btn" data-i18n="auth.logout">退出登录</button>
<button id="btnLang" class="btn">中文</button>
<button id="btnRefresh" class="btn" data-i18n="action.refresh">刷新</button>
</div>
</header>
<section id="content" class="content">
<div id="admin-boot-splash" class="admin-boot-splash" role="status" aria-live="polite">
<div class="admin-boot-splash__title">
<span class="admin-boot-splash__spinner" aria-hidden="true"></span>
<span>正在加载管理台…</span>
</div>
<div class="admin-boot-splash__muted">若长时间停留在此,请检查网络/代理是否拦截外部资源。</div>
</div>
</section>
</main>
</div>
<script
defer
src="/admin/assets/app.js?v=20260507-2"
onerror="(function(){var s=document.getElementById('admin-boot-splash');if(s){s.querySelector('.admin-boot-splash__title span:last-child').textContent='无法加载 app.js';s.querySelector('.admin-boot-splash__muted').textContent='请确认 /admin/assets/app.js 可访问。';}})()"
></script>
</body>
</html>