---
name: unidesk-webdev
description: UniDesk Web 开发与浏览器验证技能。用户处理 UniDesk/HWLAB Cloud Web、Workbench、Performance 页、前端状态投影、Playwright、fake-server、web-probe、截图、响应式布局、Web E2E 回归或线上 Web bug 复测/提 issue 时使用。
---

# UniDesk WebDev

本技能是 UniDesk/HWLAB Web 开发、浏览器复测和 Playwright 回归的入口，并遵循 Skill(cli-spec)。需求真相源仍是 `project-management/PJ2026-01/specs/`；本技能只规定如何开发、采集、复现和验收。

## 快速规则

- 线上 Web bug、Workbench、Performance、前端状态投影、截图、fake-server 和 web-probe 任务必须先用本技能。
- Web-probe 正式 CLI 入口是 `bun scripts/cli.ts web-probe ...`；旧 `hwlab nodes web-probe` 已移除，只能按 CLI 提示迁移，不要在 issue 或长期文档中继续记录旧入口。
- 涉及 Web 哨兵、`web-probe sentinel`、`monitor.pikapython.com`、定期/周期巡检或新建巡检时，必须同时加载 `$unidesk-monitor`。
- 真实用户入口验证优先；源码检查、构建通过或截图局部正常不能替代原入口验收。
- 调试 HWLAB Cloud Web/Workbench 业务或功能 bug 时，使用 YAML 声明的 `--origin internal`；验收 public exposure、DNS、FRP、Caddy 或公网用户入口时，显式使用 `--origin public`。
- `--url` 只是 custom/local 一次性逃生口，与 `--origin` 互斥；禁止通过手写 URL 或 IP 选择内网/公网运行面。本地 fake-server、localhost、dist 静态服务和 custom URL 只能作为开发 preflight 证据。
- 禁止在本地或 master server 直接跑 `vue-tsc` / 前端全量 typecheck 作为默认验证；本地只做语法级检查和真实入口复测，完整类型检查交给 CI、PipelineRun 或明确指定的受控构建运行面。
- 桌面版 Web 截图、视觉复测和 web-probe 采样默认使用 `1920x1080` 视口；只有用户、issue 或 SPEC 明确指定其他尺寸时才覆盖，并在证据中写明覆盖原因。
- Web probe 命令和历史判定口径见 [references/web-probe.md](references/web-probe.md)；Playwright/fake-server 复现见 [references/playwright.md](references/playwright.md)。
- 前端改动遵循仓库既有设计系统、[references/design.md](references/design.md) 和 `$frontend-design` 全局 UI 规则；不要做营销式落地页替代真实工具页面。

## web-probe 证据规则

- 用户要求“离线调查”时，web-probe 只读取已有 observer/sentinel artifact、`observe collect` 和 `observe analyze` 报告；不得新开 `run/script/observe` 或触发新的 dashboard 验证。若 collect/analyze 难以定位 run、trace、sample、root-cause signal 或输出不可界定，先改进 analyzer/CLI 证据面，再继续业务结论。
- 用户要求“用 web-probe 做 smoke”时，`web-probe` 是取证工具，smoke 目标以用户/issue 指定的业务入口为准；例如目标是 Workbench 时，必须用 `web-probe run` 或 `web-probe observe start` + `observe command --type sendPrompt` 验证 Workbench 页面、会话、消息终态和 `observe analyze` 结果，不能改成只验证 web-probe 工具自身。只有用户明确说“验证 web-probe 自身/基础设施”时，才把 screenshot/script/observe 作为工具自检 smoke。
- HWLAB Web 业务/功能改动可先在已部署的 node/lane 上用 `--origin internal` 完成快速复测；涉及 public exposure 或公网用户入口的 closeout 再用 `--origin public` 独立验收。两者均必须由 owning YAML 解析，不得用临时 URL/IP 切换运行面。
- web-probe 发现 Workbench 请求风暴、浏览器卡死、内存上涨、submit/command 失败或投影缺失时，修复目标默认是 Workbench runtime/projection/read model 或业务代码；不得为了通过 smoke 去降低 Playwright/Chromium 能力、减少采样、自动刷新页面、关闭 freeze/memory 检测或把 blocker 降级。探针侧只能补证据、root cause 可见性和 YAML policy 接入。
- 交互式线上验收优先使用 `web-probe observe start`、`observe command`、`observe collect` 和 `observe analyze`；`web-probe script` 只作为一次性探测逃生口。重复出现的高频动作（折叠侧栏、关闭报告、切换全屏、导出低码率截图、采集布局指标）必须沉淀为 observe command 或 analyzer 能力。
- 截图取证必须优先配合页面的 RESTful 深链：截图命令应直接打开能恢复目标 source/file/task/report/session/run 和聚焦区域的 URL，再等待稳定 DOM 合约后截图。若目标页面缺少必要深链能力，不要先用脆弱点击/滚动流程硬截；应先增强前端深链与刷新恢复能力，再把截图能力接回 web-probe/observe/sentinel 命令。
- Issue closeout 引用 observer id、command id、stateDir/report SHA、screenshot SHA 和关键字段摘要；不要粘贴截图二进制、完整 JSON、Secret、cookie 或无界日志。
- 取证 drill-down 先用 `observe collect` / `observe analyze` 的 bounded view；需要截图路径、SHA、traceId 或 command detail 时优先查 `control.jsonl`、analysis 摘要或专用 artifact view，避免直接 `rg samples.jsonl`，因为页面快照是超长单行 JSON，容易触发输出截断和噪声。
- Workbench 三态/卡死离线调查优先用 `observe collect <id> --view workbench-triad --trace-id <trc_...>`，它把 DOM turn/message/trace rows、Final Response、Workbench REST terminal evidence、browser freeze blocker 和 analyzer findings 聚合到一个有界视图；只有需要样本细节时再用 `--finding` 或 `trace-frame` 下钻。
- `observe collect <id> --view turn-summary --command-id <cmd_...>` 必须按 commandId 精确返回单轮；不存在时保持结构化 `not-found`，禁止回退全量轮次。输出中 observer control 完成、turn submission 与异步 turn terminal 是三个独立证据字段，control completed 不等于业务 turn terminal。
- `workbench-triad` 的本地 `network.jsonl` 没有匹配响应时，结论必须写作 `artifact evidence missing`，并明确这不能证明业务 API 未发生；将 control artifact 中的 OTel trace reference 作为独立证据引用，再走 `$unidesk-otel` 受控诊断核验完整业务链路。
- `web-probe script` 结果首行固定返回 `UNIDESK_WEB_PROBE_COMMAND_PROMOTION_HINT <json>`，同时在结构化结果首字段返回 `commandPromotionHint`；一次性脚本在重复前必须沉淀为 repo-owned typed command。内置 generated command（例如 `web-probe opencode-smoke`）会明确返回可直接复用且不附加临时脚本 warning，禁止复制其生成脚本另起一次性入口。
- 沉淀后的 typed command 必须复用 observer start 时选中的 semantic origin；不得在 command 内嵌 URL/IP，也不得为 internal/public 各复制一份 command。
- Workbench 性能卡顿调查优先用 `observe command --type performanceCapture` + `observe analyze` + `observe collect --view performance-summary`；`performance-summary` 必须保持首屏 bounded，只输出 LongTask/LoAF/event-loop gap 摘要、CPU profile hotspots/stacks 和 sourceFiles，下钻完整 profile/report 时再显式读取 artifact。
- Project Management/MDTODO closeout 必须区分 `control` 页和被动 `observer` 页：显式 `observe command` 的 command result、control URL 和对应截图是用户动作证据；observer 周期刷新或 stop 后根路由空态只能作为对照信号，不能覆盖 command result。涉及报告的验收要同时记录 `reportPreviewVisible`、`reportFullscreenVisible`、报告 deep link 和截图 SHA。
- MDTODO → Workbench launch 验收必须引用 `launchWorkbenchFromMdtodo` 的 command result，确认文件/任务选择、Workbench session、launch/chat 状态和 OTel trace header；不要只凭页面最终停在 Workbench URL 判断通过。
- Workbench provider profile 验收使用 `observe command --type sendPrompt --provider <profile>` 时，command result 必须显示 `requestedProvider`、`providerSelection.selected`、`/v1/agent/chat` 202、traceId 和最终 `turn-summary`；只有 prompt 成功不够，必须确认浏览器控件实际选中目标 profile。
- Workbench Kafka 实时 fanout 的重复验收：
  - 使用 `observe command --type validateRealtimeFanout --profile <yaml-profile> --provider <provider> --text <first> --second-text <second>`；
  - connected、refresh/reconnect 和 capability 期望来自 owning YAML，可独立组合，禁止在命令中硬编码 live-only 或 refresh mode；
  - 每轮只把 `user`、`assistant` 和 `terminal` 对应的 AgentRun/HWLAB 事件族作为必需核心事件；
  - `tool_call`/`command_output` 与 HWLAB `tool`/`status` 是条件事件对，仅在实际出现时校验数量和 lineage；
  - 直接答复不得为了通过探针而合成工具事件，超时证据必须披露已经观测和仍然缺失的事件族；
  - refresh 启用时必须证明 retention 到 live handoff、正式 `user` event、`hwlab.event.v1` 同 envelope，以及主页面单一 EventSource 和同一 UI reducer 终态；
  - observer 后台维持两个独立 product subscriber 和三条 debug SSE；
  - 命令提交后按 `status <observer> --command-id <command>` 轮询，不得回退为长连接 `web-probe script`。
- Workbench 隔离 Kafka debug 重放使用 `observe command --type validateWorkbenchKafkaDebugReplay`：
  - 复用 observer 当前 session 和 semantic origin；
  - 按 owning YAML 校验 topic、独立 group prefix、请求静默窗口和产品/调试 SSE 路径；
  - 新 UI 优先报告 server/client 分层计数、typed phase/code、source-authority Trace 行和原始 HWLAB Event 有界计数；
  - 切换原始事件标签不得新建第二条产品 EventSource；
  - 旧 UI 缺少新 DOM 合同时保持明确的 `legacy-ui` 兼容证据。
- `observe analyze` 的 archive/history findings 可能包含旧样本或旧规则误判；关闭用户入口问题前同时核对最新 sample 字段、DOM 几何和截图。若 top-level findings、latest sample 和 archive red 冲突，说明冲突并补工具反馈 issue，不要只凭 archive red 或单张截图下结论。
- Workbench 产品 Trace 可读性验收使用 `observe command --type validateWorkbenchTraceReadability`：
  - 开关、运行卡片等待、展开、轮询和 DOM 稳定窗口全部来自独立 owning YAML；
  - 只在 `#conversation-list` 内定位当前产品 `WorkbenchMessageCard`；
  - 明确排除隔离 Kafka debug panel，禁止把隔离卡片行计入产品 Trace；
  - 必须先命中新运行卡片并按合法 traceId 固定定位，禁止回退旧终态卡片；
  - 在命令点击展开前记录 `openBefore` 与默认运行中可读性；
  - 命令可展开卡片补充诊断，但不得把强制展开后的可读性冒充默认通过；
  - 非窗口化 Trace 用行身份重叠验证保留；窗口化 Trace 用 event count 与 source sequence 边界前进验证；
  - 同一命令等待终态并输出 report SHA 与 screenshot SHA，失败时仍保留已采集阶段证据。

## 高频工作流

1. 先确认目标：repo、分支/lane、node、semantic origin（internal/public）、预期页面或 workflow。
2. 读取对应 SPEC 或 issue，明确验收口径；Workbench 和 Performance 页不要只凭局部 DOM 判断。
3. 用受控 CLI 或 Playwright wrapper 复现：优先 `bun scripts/cli.ts web-probe ...`，必要时用 `bun scripts/playwright-cli.ts ...`。
4. 修改前端代码后执行最小相关验证，再用同一原入口复测。
5. 需要关闭用户反馈/issue 时，记录真实入口证据、截图/trace/session 和失败或通过结论。

## 常用入口

```bash
bun scripts/cli.ts web-probe --help
bun scripts/playwright-cli.ts --help
bun scripts/cli.ts check --syntax-only
```

HWLAB Web probe、fixture 采集脱敏、Workbench/Performance 判定、Web E2E 和线上复测见 [references/web-probe.md](references/web-probe.md)；fake-server Playwright 见 [references/playwright.md](references/playwright.md)。

## 何时读取 reference

- 需要 HWLAB Web probe 采集、observe/analyze、sentinel 或线上截图时，读 [references/web-probe.md](references/web-probe.md)。
- 需要 fake-server 或 Playwright 复现时，读 [references/playwright.md](references/playwright.md)。
- 需要做 UniDesk/HWLAB 页面布局、Workbench/Project Management 设计或视觉验收时，读 [references/design.md](references/design.md)。
- 需要 Workbench/Performance 页判定口径时，读 [references/web-probe.md](references/web-probe.md)，不要凭经验补规则。
