2026-09-23 13:53:00 +08:00
|
|
|
|
# 公网 Agent 页(`AgentView.vue`)设计方案 v2
|
|
|
|
|
|
|
2026-09-24 19:03:05 +08:00
|
|
|
|
> **时效说明(2026-09-24)**:文中「顶部下拉选服务端」的结构已被 v1.2.6 的**左列表 + 右详情**取代(页面标题也改为「公网服务端」),现状见 `docs/frp-server-list-merge-plan.md`。
|
|
|
|
|
|
|
2026-09-23 13:53:00 +08:00
|
|
|
|
> 本文按 `breezell-design` 两遍流程产出,核心是**先列清功能、再谈设计**:
|
|
|
|
|
|
> 第二节把本页应有的 **27 项能力**逐条落位(含 5 处当前页面看不到的能力),第四节按功能分区。
|
|
|
|
|
|
>
|
|
|
|
|
|
> 取代 `docs/agent-view-design.md`(v1 只做了结构搬家,未解决"功能不可见"问题);
|
|
|
|
|
|
> 也取代 `docs/agent-view-refactor-plan.md`。更新日期:2026-09-23
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 一、Pass 1a:栈与设计系统检测
|
|
|
|
|
|
|
|
|
|
|
|
| 检测项 | 实际值 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| 框架 | Vue 3 + `<script setup lang="ts">` + Vite 6 |
|
|
|
|
|
|
| 组件库 | **naive-ui**(`n-button` `n-select` `n-tabs` `n-modal` `n-popconfirm` `n-alert` `n-spin` `n-icon` `n-tag` `n-tooltip` `n-form`) |
|
|
|
|
|
|
| 图标 | `@vicons/ionicons5` |
|
2026-10-01 16:54:35 +08:00
|
|
|
|
| 令牌系统 | `web/src/styles/variables.css`:`:root` + `html.dark` 双主题,`--havline-*` 前缀 |
|
|
|
|
|
|
| 共享组件 | `PageHeader` `HavlineCard` `StatCard` `StatusBadge` `EmptyState` `LoadError` |
|
2026-09-23 13:53:00 +08:00
|
|
|
|
| 工具 | `utils/format.ts`(`formatBytes/formatRate/formatDate/formatRelativeTime/…`)、`utils/status.ts`(`StatusKind`) |
|
|
|
|
|
|
|
2026-10-01 16:54:35 +08:00
|
|
|
|
**结论**:沿用既有体系(naive-ui + `--havline-*` + 共享组件),**不引入**第二套框架/令牌。
|
2026-09-23 13:53:00 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 二、功能总清单(Capability Inventory)
|
|
|
|
|
|
|
|
|
|
|
|
> 设计原则:**没有隐式功能**。每项能力都要有固定位置、可见状态、明确反馈;
|
|
|
|
|
|
> 能做的显示按钮,不能做的显示**原因**(禁用 + 提示),而不是隐藏。
|
|
|
|
|
|
|
|
|
|
|
|
| # | 能力 | 数据来源 | 当前状态 | 新设计位置 | 可见性形态 |
|
|
|
|
|
|
| --- | --- | --- | --- | --- | --- |
|
|
|
|
|
|
| A | 选择公网服务端 | `listFrpServers`(agent/ssh 已配置) | 已有 | `PageHeader#actions` | 下拉选择 |
|
|
|
|
|
|
| B | Agent 连通性 | `getFrpAgentStatus` 成败 | 已有 | ① 运行状态 | 三态:在线 / 未连接 / 未加载 |
|
|
|
|
|
|
| C | Agent 地址 | `server.agent_url` | 已有 | ① 运行状态卡副标题 | 等宽文本 |
|
|
|
|
|
|
| D | Agent 版本 | `agent_version` | 已有 | ② 环境与依赖 | 等宽文本 |
|
|
|
|
|
|
| E | **Agent 凭据是否已配置** | `server.agent_configured` | **未展示** | ② 环境与依赖 | StatusBadge:已配置 / 未配置 |
|
|
|
|
|
|
| F | frps 运行状态 | `frps_active` | 已有 | ① 运行状态 | 在线 / 未运行 |
|
|
|
|
|
|
| G | frps 已安装版本 | `frps_version` | 已有 | ① + ② | 文本 / 徽标 |
|
|
|
|
|
|
| H | frps 二进制路径 | `frps_binary` | 已有 | ② 环境与依赖 | 等宽 + 换行 |
|
|
|
|
|
|
| I | frps 配置文件路径 | `frps_config_path` | 已有 | ② 环境与依赖 | 等宽 + 换行 |
|
|
|
|
|
|
| J | frps 启动命令 | `frps_unit_exec` | 已有 | ② 环境与依赖 | 等宽 + 换行 |
|
|
|
|
|
|
| K | frps 开机自启 | `frps_enabled` | 已有 | ② 环境与依赖 | StatusBadge |
|
|
|
|
|
|
| L | frps 管理面板入口 | `dashboard_addr/port` → `dashboardURL` | 有(未配置时**按钮隐藏**) | ③ frps 控制 | **常显**;未配置时禁用 + tooltip 指向配置位置 |
|
|
|
|
|
|
| M | 端口监听 80/443/7000/8080 | `ports` | 仅 80/443 卡 + 7000 字段(**8080 未展示**) | ① 运行状态「端口」卡 | 四端口全列:`80✓ 443✓ 7000✗ 8080✗` |
|
|
|
|
|
|
| N | **已注册反代路由数** | `routes[]` | **未展示** | ① 运行状态 | 「反代路由 N 条」+ 折叠列表 |
|
|
|
|
|
|
| O | **最后一次检查时间** | `checked_at` | **未展示** | `PageHeader` 副标题 | 「检查于 x 前」(`formatRelativeTime`) |
|
|
|
|
|
|
| P | **Nginx 可用性(本页完全未展示)** | `nginx_ok/missing/running/version/path/conf_dir/error` | **未展示**(在公网反代页) | ② 环境与依赖「Nginx」组 | 徽标 + 版本 + 路径 + 配置目录 + 错误原文 + 跳转 |
|
|
|
|
|
|
| Q | 启动 / 停止 frps | `frpsServerActionRaw(start/stop)` | 已有 | ③ frps 控制 | 按状态互斥的按钮 |
|
|
|
|
|
|
| R | 重启 frps | `frpsServerActionRaw(restart)` | 已有 | ③ frps 控制 | 按钮 |
|
|
|
|
|
|
| S | 下发 frps 配置 | `pushFrpConfigToAgent` | 已有(散在另一卡) | ③ frps 控制 | 按钮 |
|
|
|
|
|
|
| S2 | 查看即将下发的 frps 配置 | `getFrpFRPSConfig` | 本页未提供 | ③ frps 控制(紧跟下发按钮) | 按钮 + 只读弹窗(等宽代码块 + 复制) |
|
|
|
|
|
|
| T | 安装 / 升级 frps | `installFrpServer` + `listFrpReleases` | 已有 | ③ frps 控制 | 版本下拉 + 按钮(列表空时禁用) |
|
|
|
|
|
|
| U | 探测环境 | `probeFrpAgent` | 已有 | ④ Agent 生命周期 | 按钮 |
|
|
|
|
|
|
| V | 安装 / 升级 Agent | `installFrpAgent` | 已有 | ④ Agent 生命周期 | 按钮 |
|
|
|
|
|
|
| W | 卸载(保留数据 / 含数据) | `uninstallFrpAgent(keepData)` | 已有(危险无确认) | ④ Agent 生命周期 | 两按钮,含数据**带二次确认** |
|
|
|
|
|
|
| X | SSH 诊断 | `sshDiagnoseFrpAgent` | 已有 | ④ Agent 生命周期 | 按钮 |
|
|
|
|
|
|
| Y | frps 最近日志 | `frps_log_tail` | 已有(独立卡) | ⑤ 输出与日志 Tab | 日志块 + 空态 |
|
|
|
|
|
|
| Z | 操作输出(7 类) | 各接口返回 | 已有(单一 `agentOutput`) | ⑤ 输出与日志 Tab | 时间线:来源 + 时间 + 成败 |
|
|
|
|
|
|
| AA | 公网反代管理入口 | `getFrpAgentRouteCandidates` / `RouteHealth` | 有(整卡只放跳转) | 入口行 + ① 反代路由卡 | 「N 条规则 · 健康 X/Y」+ 跳转 `/public-proxy` |
|
|
|
|
|
|
|
|
|
|
|
|
### 本次必须补齐的 5 处(数据已返回,页面没显示)
|
|
|
|
|
|
|
|
|
|
|
|
| 项 | 数据字段 | 为什么重要 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| E | `agent_configured` | 决定"能不能连上 agent",是排障第一问 |
|
|
|
|
|
|
| M(8080) | `ports["8080"]` | frps vhost 端口是否在听,直接对应反代回源 |
|
|
|
|
|
|
| N | `routes[]` | 一眼看出 VPS 上已注册几条反代 |
|
|
|
|
|
|
| O | `checked_at` | 判断状态是不是陈旧的(页面 10 秒轮询,用户需要知道数据新鲜度) |
|
|
|
|
|
|
| P | `nginx_*` 七字段 | 反代的前置依赖;本页不显示就只能跳到另一页才能发现"没装 Nginx" |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 三、设计方向与令牌(Pass 1b)
|
|
|
|
|
|
|
|
|
|
|
|
**方向:机架面板(controlled density)**——像看一排机架指示灯:状态永远第一眼可见,操作收进分区按钮带,输出以时间线呈现;克制、无装饰、密度优先。
|
|
|
|
|
|
|
|
|
|
|
|
- **Layout**:状态区(4 列稳定网格)→ 环境与依赖(两列)→ 控制/生命周期(两列)→ 输出与日志(整宽);左对齐,无居中大标题、无渐变、无装饰插图。
|
|
|
|
|
|
- **Signature**:**四色状态点行 + 操作输出时间线**。
|
|
|
|
|
|
|
|
|
|
|
|
**Color(5 个语义令牌,全部复用现有)**
|
|
|
|
|
|
|
|
|
|
|
|
| 语义 | 令牌 | 用于 | 判定 |
|
|
|
|
|
|
| --- | --- | --- | --- |
|
2026-10-01 16:54:35 +08:00
|
|
|
|
| 正常 | `--havline-brand`(`-soft`/`-text`) | 在线、运行中、监听中、成功输出 | 无需干预 |
|
|
|
|
|
|
| 待处理 | `--havline-warning` | frps 未运行、端口未监听、frps 未安装、开机自启未启用 | 可一键恢复 |
|
|
|
|
|
|
| 需人工干预 | `--havline-error` | Agent 未连接、Nginx 缺失、操作失败、卸载确认 | 需排查/不可逆 |
|
|
|
|
|
|
| 中性 | `--havline-text-secondary` / `--havline-text-muted` | 字段名、说明、时间、空态 | — |
|
|
|
|
|
|
| 引导 | `--havline-info`(`-soft`) | 页面级引导(反代入口等) | 非故障 |
|
2026-09-23 13:53:00 +08:00
|
|
|
|
|
|
|
|
|
|
规则:一屏 error ≤ 1 处;warning 只用于"有目标状态但未达成",不用于"没数据"。亮/暗由 `variables.css` 覆盖,**页面零硬编码色值**。
|
|
|
|
|
|
|
|
|
|
|
|
**Type(沿用项目字体,显式声明)**
|
|
|
|
|
|
|
2026-10-01 16:54:35 +08:00
|
|
|
|
- 正文 `--havline-font`,等宽 `--havline-mono`。skill 禁用 system-ui 系默认栈,但本项目已有设计系统,按 **"MATCH it, never add a second"** 继续使用;换字体属全局决策(改 `variables.css` + 全站回归),不在本页范围。
|
|
|
|
|
|
- 页内 4 档字号 / 3 档字重:数值词条 18px/700(`.stat-card__value--sm`)、数值数字 30px/700/`-0.03em`、字段名与卡标签 12–13px/600、说明与时间 12–12.5px/400;路径/命令/版本/日志走 `--havline-mono` 12.5–13px。
|
2026-09-23 13:53:00 +08:00
|
|
|
|
|
2026-10-01 16:54:35 +08:00
|
|
|
|
**Spacing & Radius**:只用 `--havline-space-1…6` 与 `--havline-radius(-sm)`、`--havline-shadow`;禁止魔数;内联尺寸一律改类(`.agent-select` / `.frps-version-select`)。
|
2026-09-23 13:53:00 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 四、页面分区与线框(按功能分区)
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
┌ PageHeader 公网 Agent · 检查于 12 秒前 [服务端 ▾] [刷新] ┐
|
|
|
|
|
|
├ n-alert 状态提示(互斥一条:error 未连接 / warning frps 未运行)
|
|
|
|
|
|
├ 入口行 公网反代:3 条规则 · 健康 2/3 → /public-proxy
|
|
|
|
|
|
├ ① 运行状态 section[aria-label=运行状态] 4 列稳定网格
|
|
|
|
|
|
│ ● Agent 连接 ● frps 服务 ● 反代路由 ● 端口监听
|
|
|
|
|
|
│ 在线/未连接 运行中/未运行 3 条 80✓ 443✓
|
|
|
|
|
|
│ <agent 地址> <frps 版本> 健康 2/3 已生效 7000✓ 8080✗
|
2026-10-01 16:54:35 +08:00
|
|
|
|
├ ② 环境与依赖(Havline Agent | Nginx | frps 运行时,三列并排)
|
|
|
|
|
|
│ Havline Agent Nginx(本页新增) frps 运行时
|
2026-09-23 13:53:00 +08:00
|
|
|
|
│ 版本 / 地址 可用性徽标 / 版本 二进制 / 版本
|
|
|
|
|
|
│ 凭据:已配置 ✓ 可执行路径 / 配置目录 配置路径
|
|
|
|
|
|
│ [探测环境] 错误原文(红) 启动命令 / 开机自启
|
|
|
|
|
|
│ → 去「公网反代」处理
|
|
|
|
|
|
├ ③+④ 两列并排(左:Agent 生命周期(SSH) / 右:frps 控制)
|
|
|
|
|
|
│ 左 [探测环境] [安装/升级 Agent] [SSH 诊断] 右 [启动|停止] [重启] [管理面板]
|
|
|
|
|
|
│ [卸载(保留数据)] [卸载(含数据) ← 二次确认] [下发配置] [版本 ▾] [安装/升级]
|
|
|
|
|
|
└ ⑤ 输出与日志 n-tabs:操作时间线(来源+时间+成败,aria-live) | frps 日志
|
|
|
|
|
|
空态 EmptyState · [清空]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
分区原则:
|
|
|
|
|
|
|
|
|
|
|
|
1. **每项能力都有固定位置**(对照第二节清单);按钮常显,不可用时**禁用 + 说明原因**,绝不隐藏;
|
|
|
|
|
|
2. 状态区只读 / 控制区只写 / 输出区只展示,三段物理分离;
|
|
|
|
|
|
3. 新增的「环境与依赖」把三件前置条件(Agent 凭据、Nginx、frps 运行时)集中可见——排障时最先要看的就是这三项。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 五、组件与状态矩阵(Pass 2 规格)
|
|
|
|
|
|
|
|
|
|
|
|
| 元素 | default | hover | pressed | focused | disabled | loading |
|
|
|
|
|
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
|
|
|
|
| `n-button`(主/次/危险) | 库默认 | 库默认 | 库默认 | 库默认焦点环(键盘实测) | `busy !== null && busy !== 本动作` | `busy === '动作名'` |
|
|
|
|
|
|
| 服务端选择器 | 库默认 | 库默认 | — | 库默认 | 无服务端时禁用 | — |
|
|
|
|
|
|
| `n-tabs`(输出/日志) | 库默认 | 库默认 | 库默认 | 库默认(←/→ 可切换) | — | — |
|
|
|
|
|
|
| `n-popconfirm`(卸载含数据) | warning 触发器 | 库默认 | 库默认 | 库默认 | busy 时禁用 | 确认后走按钮 loading |
|
|
|
|
|
|
| `.stat-card`(只读) | 令牌底色 | **有意不加 hover** | — | 非交互不可聚焦 | — | 骨架 / `—` |
|
|
|
|
|
|
| 「管理面板」(未配管理接口) | **常显但禁用** | — | — | — | 是(tooltip 指向配置位置) | — |
|
|
|
|
|
|
| 「安装/升级 frps」(版本列表未加载) | **常显但禁用** | — | — | — | 是(提示「正在获取官方版本列表…」) | 列表加载中 |
|
|
|
|
|
|
|
|
|
|
|
|
**内容状态(区分"没数据"与"拿不到数据")**
|
|
|
|
|
|
|
|
|
|
|
|
| 场景 | 呈现 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| 尚未拉取 | 数值位 `—`,副标题「读取中…」 |
|
|
|
|
|
|
| 首次拉取中 | `n-spin` 包裹状态区(仅首次,轮询不显示) |
|
|
|
|
|
|
| 拉取失败 | 数值位「未连接」+ 顶部 `error` alert(含「探测环境」动作) |
|
|
|
|
|
|
| 无已注册路由 / 无日志 | `EmptyState`(不再渲染「暂无日志」字符串) |
|
|
|
|
|
|
| 操作失败 | 时间线中该条 `ok=false` 标红 + `message.error` |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 六、动效与无障碍
|
|
|
|
|
|
|
|
|
|
|
|
**动效**:首屏一次性 `fade-up`(`translateY(4px)→0`,160ms),仅 `onMounted` 触发一次;`prefers-reduced-motion: reduce` 全禁用;除此之外不做散点微动效(不加卡片 hover 位移/脉冲)。
|
|
|
|
|
|
|
2026-10-01 16:54:35 +08:00
|
|
|
|
**无障碍**:状态区 `<section aria-label="运行状态">`;装饰图标 `aria-hidden`;按钮均有可读文本;输出区 `aria-live="polite"`;Tab 顺序 = 选择器 → 刷新 → 状态区(跳过只读)→ 各分区按钮带 → tabs;对比度实测 AA(`--havline-brand/warning/error/text-muted` 在 `--havline-surface` 上,亮+暗各一遍);≤760px 按钮 `min-height: 44px`;响应式 `1200+ / 900–1199 / ≤900 / ≤760`(运行状态 4→2→1 列;环境与依赖三列 →≤1199 降 2 列 →≤900 单列,且三列时卡片内短字段(版本/徽标)双列并排、长路径与命令整行,控制卡片高度),**320px 无横向溢出**。
|
2026-09-23 13:53:00 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 七、状态与数据流(含前一轮复核发现的 3 处缺陷修复)
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
// 1) 切换服务端必须重置,避免串台
|
|
|
|
|
|
watch(selectedId, () => {
|
|
|
|
|
|
opOutput.value = []
|
|
|
|
|
|
agentStatus.value = null
|
|
|
|
|
|
statusLoaded.value = false
|
|
|
|
|
|
agentStatusOk.value = false
|
|
|
|
|
|
void refreshAll()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 2) 三态区分:未加载 / 加载中 / 失败
|
|
|
|
|
|
const statusLoaded = ref(false) // 是否成功拉取过
|
|
|
|
|
|
const statusLoading = ref(false) // 首次加载中
|
|
|
|
|
|
|
|
|
|
|
|
// 3) 按动作粒度 loading,轮询静默
|
|
|
|
|
|
type Action = 'probe' | 'agent-install' | 'agent-uninstall' | 'diagnose'
|
|
|
|
|
|
| 'frps-start' | 'frps-stop' | 'frps-restart' | 'frps-install' | 'push-config'
|
|
|
|
|
|
const busy = ref<Action | null>(null)
|
|
|
|
|
|
async function run<T>(action: Action, fn: () => Promise<T>) {
|
|
|
|
|
|
if (busy.value) return // 安全网:按钮已 disabled
|
|
|
|
|
|
busy.value = action
|
|
|
|
|
|
try { return await fn() } finally { busy.value = null }
|
|
|
|
|
|
}
|
|
|
|
|
|
async function refreshAll(options: { silent?: boolean } = { silent: true }) { /* 轮询不触碰 busy */ }
|
|
|
|
|
|
|
|
|
|
|
|
// 4) 输出时间线:来源 + 时间 + 成败,上限 20 条
|
|
|
|
|
|
interface OpOutput { at: string; source: string; text: string; ok: boolean }
|
|
|
|
|
|
const opOutput = ref<OpOutput[]>([])
|
|
|
|
|
|
function pushOutput(source: string, text: string, ok = true) {
|
|
|
|
|
|
opOutput.value = [{ at: new Date().toISOString(), source, text, ok }, ...opOutput.value].slice(0, 20)
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**提示规则**:状态提示互斥且最多一条(`error` 未连接 > `warning` frps 未运行);「公网反代入口」不占 alert 位,独立成入口行。
|
|
|
|
|
|
**轮询**:10 秒;`document.visibilityState === 'hidden'` 时跳过;`onBeforeUnmount` 清理定时器。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 八、本页不做(Never)
|
|
|
|
|
|
|
|
|
|
|
|
- 不引入第二套 UI 框架 / 令牌 / 全局样式;不改全局字体与令牌;
|
|
|
|
|
|
- 不用硬编码色值与魔数间距;不做渐变、居中大标题、统一灰卡片等 slop 模式;
|
|
|
|
|
|
- 统计卡不加装饰性 hover / 位移 / 脉冲;
|
|
|
|
|
|
- 不把页面级操作塞进正文卡片(统一进 `PageHeader#actions`);
|
|
|
|
|
|
- **不隐藏功能**:任何能力要么可用,要么可见地禁用并给出原因;
|
|
|
|
|
|
- 不改后端与 agent(纯前端单文件)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 九、验收清单
|
|
|
|
|
|
|
2026-10-01 16:54:35 +08:00
|
|
|
|
- [ ] 复用项目真实栈与令牌(naive-ui + `--havline-*` + 共享组件),未新增第二套
|
2026-09-23 13:53:00 +08:00
|
|
|
|
- [ ] 单一设计方向(机架面板)落地,颜色/间距/圆角全走令牌,无 banned 字体引入
|
|
|
|
|
|
- [ ] 交互状态齐全:hover / pressed / **focused(键盘实测)** / disabled / loading / empty / error
|
|
|
|
|
|
- [ ] 无障碍:对比度 AA(亮+暗)、可见焦点环、键盘可完成全部操作、`aria-live` 播报、图标 `aria-hidden`
|
|
|
|
|
|
- [ ] 最窄 320px 无横向溢出;≤760px 按钮 ≥44px
|
|
|
|
|
|
- [ ] **功能可见性:逐条对照第二节 A–AA,每项都有明确位置;E / M(8080) / N / O / P 五项新增展示已落地;不存在隐藏功能**
|
|
|
|
|
|
- [ ] 回归:切换服务端不串台;仅被点按钮 loading;轮询不闪;危险操作有二次确认;`vue-tsc` 0 错误 + `vite build` 成功
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 十、与既有文档关系与工作量
|
|
|
|
|
|
|
|
|
|
|
|
| 文档 | 关系 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `docs/agent-view-design.md`(v1) | 被本文取代(v1 只是结构搬家,未解决"功能不可见");确认后可删除 |
|
|
|
|
|
|
| `docs/agent-view-refactor-plan.md` | 被本文取代 |
|
2026-10-01 16:54:35 +08:00
|
|
|
|
| 工作区 skill `havline-page-ui` | 页面 UI 通用标准;本文是它在「公网 Agent」页的具体化 |
|
2026-09-23 13:53:00 +08:00
|
|
|
|
|
|
|
|
|
|
工作量:**单文件改动(`web/src/views/AgentView.vue`)**,约 5–6 小时(含 5 处能力补齐、状态机重构、无障碍与响应式)。
|
2026-10-01 16:54:35 +08:00
|
|
|
|
验证:`npx vue-tsc --noEmit` + `npx vite build`,再同步 `web/dist → cmd/havline/web/dist` 后 `go build ./...`。
|