Files
pikasTech-HWLAB/web/hwlab-cloud-web/index.html
T

331 lines
16 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>HWLAB 云工作台</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="/styles.css" />
<script type="module" src="/app.js"></script>
</head>
<body data-auth-state="checking">
<section class="login-shell" id="login-shell" data-auth-login aria-labelledby="login-title">
<div class="login-panel">
<div class="login-heading">
<p class="eyebrow">HWLAB</p>
<h1 id="login-title">云工作台登录</h1>
<p>请输入账号和密码。</p>
</div>
<form class="login-form" id="login-form" autocomplete="on">
<label>
<span>用户名</span>
<input id="login-username" name="username" type="text" autocomplete="username" inputmode="text" required />
</label>
<label>
<span>密码</span>
<input id="login-password" name="password" type="password" autocomplete="current-password" required />
</label>
<p class="login-error" id="login-error" role="alert" hidden></p>
<button class="login-submit" id="login-submit" type="submit">登录</button>
</form>
</div>
</section>
<main class="workbench-shell" data-app-shell data-help-route-policy="non-default-internal-help" data-internal-help-path="/help.md" hidden aria-hidden="true">
<aside class="activity-rail" id="activity-rail" aria-label="工作台活动栏">
<button class="rail-button active" type="button" data-route="workspace" title="工作台" aria-label="工作台">工作台</button>
<button class="rail-button" type="button" data-route="skills" title="Skills" aria-label="Skills">Skills</button>
<button class="rail-button" type="button" data-route="gate" title="内部复核" aria-label="内部复核">内部复核</button>
<button class="rail-button" type="button" data-route="help" title="使用说明" aria-label="使用说明">使用说明</button>
<span class="rail-spacer" aria-hidden="true"></span>
<button
class="rail-button sidebar-toggle"
id="left-sidebar-toggle"
type="button"
aria-controls="activity-rail"
aria-expanded="true"
aria-label="折叠左侧导航"
title="折叠左侧导航"
>收起</button>
</aside>
<div
class="resize-handle left-sidebar-resize"
id="left-sidebar-resize"
role="separator"
tabindex="0"
aria-label="拖拽调整左侧导航宽度"
aria-controls="activity-rail"
aria-orientation="vertical"
aria-valuemin="72"
aria-valuemax="180"
aria-valuenow="92"
title="拖拽调整左侧导航宽度;用左右方向键微调,Home/End 到最小或最大。"
></div>
<section class="center-workspace">
<section class="view workbench-view" id="workspace" data-view="workspace" aria-labelledby="workspace-title">
<div class="conversation-column">
<div class="workspace-panel conversation-panel">
<div class="panel-title-row">
<div>
<p class="eyebrow">Agent 工作区</p>
<h2 id="workspace-title">Agent 对话</h2>
</div>
<span class="state-tag tone-source" id="agent-chat-status">等待输入</span>
</div>
<details class="code-agent-summary tone-border-pending" id="code-agent-summary">
<summary>
<span class="code-agent-summary-icon tone-pending" id="code-agent-summary-icon" aria-hidden="true"></span>
<strong class="code-agent-summary-label tone-pending" id="code-agent-summary-label">探测中</strong>
<span class="code-agent-summary-capability" id="code-agent-summary-capability">未观测</span>
<span class="code-agent-summary-trace" id="code-agent-summary-trace">trace 未观测</span>
</summary>
<div class="code-agent-summary-detail" id="code-agent-summary-detail"></div>
</details>
<div class="conversation-list" id="conversation-list" aria-live="polite"></div>
</div>
</div>
</section>
<section class="view help-view" id="help" data-view="help" aria-labelledby="help-title" hidden>
<div class="workspace-panel help-panel">
<div class="panel-title-row">
<div>
<p class="eyebrow">内部说明</p>
<h2 id="help-title">使用说明</h2>
</div>
<span class="state-tag tone-dry-run" id="help-status">加载中</span>
</div>
<div id="help-content" class="help-content" aria-live="polite"></div>
</div>
</section>
<section class="view skills-view" id="skills" data-view="skills" aria-labelledby="skills-title" hidden>
<div class="workspace-panel skills-panel">
<div class="panel-title-row">
<div>
<p class="eyebrow">Skills</p>
<h2 id="skills-title">Skill 管理</h2>
</div>
<div class="skills-actions">
<span class="state-tag tone-source" id="skill-status">未加载</span>
<button class="command-button secondary" id="skill-refresh" type="button">刷新</button>
</div>
</div>
<div class="skills-layout">
<section class="skill-upload-panel" aria-label="上传 skill">
<form id="skill-upload-form" class="skill-upload-form">
<label class="skill-upload-drop">
<span>选择目录</span>
<input id="skill-upload-input" type="file" multiple webkitdirectory directory />
</label>
<button class="command-button" id="skill-upload-button" type="submit">上传</button>
</form>
<div id="skill-list" class="skill-list" aria-label="Skill 列表" aria-live="polite"></div>
</section>
<section class="skill-detail-panel" aria-label="Skill 文件">
<div class="panel-title-row skill-detail-head">
<div>
<p class="eyebrow">Skill Files</p>
<h3 id="skill-detail-title">未选择 skill</h3>
</div>
</div>
<div id="skill-tree" class="skill-tree" aria-label="Skill 文件树"></div>
</section>
<section class="skill-preview-panel" aria-label="SKILL.md 预览">
<div id="skill-preview" class="skill-preview" aria-live="polite">等待 SKILL.md。</div>
</section>
</div>
</div>
</section>
<section class="view gate-view" id="gate" data-view="gate" aria-labelledby="gate-title" hidden>
<header class="gate-header">
<div>
<p class="eyebrow">内部二级入口</p>
<h2 id="gate-title">内部复核</h2>
</div>
<span class="state-tag tone-source" id="gate-source-status">等待 live 后端</span>
</header>
<div class="gate-controls" aria-label="内部复核过滤控件">
<label>
<span>状态</span>
<select id="gate-status-filter">
<option value="all">全部</option>
<option value="通过">通过</option>
<option value="阻塞">阻塞</option>
<option value="失败">失败</option>
<option value="待验证">待验证</option>
<option value="信息">信息</option>
</select>
</label>
<label>
<span>搜索</span>
<input id="gate-search" type="search" placeholder="按类别、检查项、对象或 trace 搜索" autocomplete="off" />
</label>
<button class="command-button secondary" id="gate-refresh" type="button">刷新</button>
</div>
<div class="gate-table-wrap">
<table class="gate-table" aria-describedby="gate-source-status">
<thead>
<tr>
<th>类别</th>
<th>检查项</th>
<th>状态</th>
<th>归因对象</th>
<th>关键细节</th>
<th>证据/trace</th>
<th>更新时间</th>
<th>下一步</th>
</tr>
</thead>
<tbody id="gate-review-body">
<tr>
<td colspan="8">正在读取 live 后端聚合。</td>
</tr>
</tbody>
</table>
</div>
</section>
<form class="command-bar" id="command-form" aria-label="Agent 输入">
<label class="agent-timeout-control" for="code-agent-provider-profile">
<span>模型通道</span>
<select id="code-agent-provider-profile" aria-label="Code Agent 模型通道">
<option value="deepseek" selected>DeepSeek</option>
<option value="codex-api">Codex API</option>
</select>
</label>
<label class="agent-timeout-control" for="code-agent-timeout">
<span>无新事件超时</span>
<select id="code-agent-timeout" aria-label="Code Agent 无新事件超时">
<option value="180000">3 分钟</option>
<option value="300000">5 分钟</option>
<option value="600000">10 分钟</option>
<option value="900000">15 分钟</option>
<option value="1200000">20 分钟</option>
<option value="1800000" selected>30 分钟</option>
<option value="2400000">40 分钟</option>
</select>
</label>
<label class="agent-timeout-control" for="gateway-shell-timeout">
<span>Gateway 命令超时</span>
<select id="gateway-shell-timeout" aria-label="PC gateway shell 命令超时">
<option value="60000">1 分钟</option>
<option value="120000" selected>2 分钟</option>
<option value="180000">3 分钟</option>
<option value="300000">5 分钟</option>
<option value="600000">10 分钟</option>
</select>
</label>
<div class="input-shell">
<span class="prompt-mark">hwlab</span>
<textarea
id="command-input"
autocomplete="off"
rows="1"
placeholder="输入要发送给 Code Agent 的消息;不会直接触发硬件变更。"
></textarea>
</div>
<button class="command-button" id="command-send" type="submit">发送</button>
<button class="command-button secondary" id="command-clear" type="button">清空</button>
</form>
</section>
<aside class="right-sidebar" id="device-pod-sidebar" aria-label="Device Pod 摘要看板">
<div class="right-sidebar-control-row">
<button
class="right-sidebar-toggle"
id="right-sidebar-toggle"
type="button"
aria-controls="device-pod-sidebar"
aria-expanded="true"
aria-label="折叠右侧 Device Pod 看板"
title="折叠右侧 Device Pod 看板"
>收起看板</button>
<button class="logout-button" id="logout-button" type="button">退出</button>
</div>
<header class="sidebar-workbench-header">
<p class="eyebrow">用户工作台</p>
<h2>Agent 对话与 Device Pod 看板</h2>
<p id="route-path" class="route-path">当前浏览器会话只保存任务草稿,Device Pod 操作需通过受控后端流程。</p>
</header>
<div class="probe-card user-card" aria-live="polite">
<span class="metric-label">工作区状态</span>
<strong id="live-status" class="tone-pending">等待验证</strong>
<small id="live-detail">正在验证 hwlab-cloud-api /health/live、/v1、/v1/agent/chat 与 /v1/device-pods;未完成前不标为通过。</small>
<div class="live-build-summary" id="live-build-summary">
<button class="live-build-toggle" id="live-build-toggle" type="button" aria-haspopup="dialog" aria-expanded="false">
<span class="live-build-summary-label" id="live-build-latest">最新镜像构建时间:等待实时元数据</span>
</button>
</div>
<div class="live-build-list live-build-list-template" id="live-build-list" hidden aria-label="live HWLAB 微服务构建时间明细"></div>
</div>
<div
class="resize-handle right-sidebar-resize"
id="right-sidebar-resize"
role="separator"
tabindex="0"
aria-label="拖拽调整右侧 Device Pod 看板宽度"
aria-controls="device-pod-sidebar"
aria-orientation="vertical"
aria-valuemin="560"
aria-valuemax="740"
aria-valuenow="728"
title="拖拽调整右侧 Device Pod 看板宽度;用左右方向键微调,Home/End 到最小或最大。"
></div>
<section class="device-pod-status" aria-labelledby="device-pod-title">
<div class="panel-title-row">
<div>
<p class="eyebrow">Device Pod</p>
<h2 id="device-pod-title">设备目标看板</h2>
</div>
<span class="state-tag tone-source" id="device-pod-status-tag">未验证</span>
</div>
<div class="device-pod-selector-row">
<label for="device-pod-select">当前 Pod</label>
<select id="device-pod-select" aria-label="选择 Device Pod">
<option value="device-pod-71-freq">device-pod-71-freq</option>
</select>
</div>
<div id="device-pod-summary" class="device-pod-summary" data-static-source-fallback="FAKE">
<article class="summary-tile" data-device-detail="pod" data-device-title="Pod Summary" role="button" tabindex="0" aria-label="查看 Device Pod 摘要详情">
<span class="summary-title">Pod Summary</span>
<dl class="kv-list">
<div><dt>devicePodId</dt><dd id="device-pod-id">等待 /v1/device-pods</dd></div>
<div><dt>targetId</dt><dd id="device-pod-target">未观测</dd></div>
<div><dt>profile</dt><dd id="device-pod-profile">未观测</dd></div>
<div><dt>freshness</dt><dd id="device-pod-freshness">未观测</dd></div>
</dl>
</article>
</div>
</section>
<section class="device-pod-workspace">
<div id="device-pod-interfaces" class="device-pod-interfaces" aria-label="Device Pod 四要素摘要"></div>
<section class="device-event-panel" aria-labelledby="device-event-title">
<div class="event-toolbar">
<span id="device-event-title">事件流</span>
<button id="device-event-follow" type="button" aria-pressed="true">跟随</button>
<button id="device-event-jump" type="button" hidden>有 0 条新事件</button>
</div>
<div id="device-event-scroll" class="device-event-scroll" tabindex="0" aria-label="Device Pod 纯文本事件流">
<pre id="device-event-text">等待 /v1/device-pods 事件流。</pre>
</div>
</section>
</section>
<dialog class="device-detail-dialog" id="device-detail-dialog" aria-labelledby="device-detail-title">
<form method="dialog" class="device-detail-shell">
<header class="device-detail-head">
<h2 id="device-detail-title">Device Pod 详情</h2>
<button class="command-button secondary" value="close" type="submit">关闭</button>
</header>
<pre id="device-detail-body" class="device-detail-body"></pre>
</form>
</dialog>
</aside>
</main>
</body>
</html>