diff --git a/.agents/skills/unidesk-webdev/SKILL.md b/.agents/skills/unidesk-webdev/SKILL.md index 3c530a41..83003c5b 100644 --- a/.agents/skills/unidesk-webdev/SKILL.md +++ b/.agents/skills/unidesk-webdev/SKILL.md @@ -13,7 +13,8 @@ description: UniDesk Web 开发与浏览器验证技能。用户处理 UniDesk/H - 防分叉原则:Web/Workbench 修复必须先确定唯一 authority、唯一 API 契约和唯一状态投影入口;不得写成“当字段缺失/请求失败/状态不符/超时/刷新后,再改走另一个 endpoint、旧 workspace/conversation 模型、localStorage、trace polling、result polling、GET read-through repair、内部 manager、legacy route 或测试专用后门”。字段缺失、状态滞后或投影不完整时,修 schema、projector、read model 或正式 mutation 源头;代码里只能保留单一路径内的输入规范化、校验和错误暴露,不能用 `A ?? B`、`if missing then fallback`、兼容分支或双写双读把缺口遮住。 - 禁止状态竞争行为:不得在代码、API、reducer、read model、fake-server 或测试中保留两个事实源,再用“覆盖、压过、override、优先级、优先采用、以 A 为准否则 B、A 赢过 B”等仲裁规则决定展示状态;这就是条件分叉和竞争投影。必须先定义唯一投影对象、唯一归属字段和唯一生成时机,让 UI/API 只消费该投影对象的单一状态;其他原始字段只能作为审计输入、诊断字段或待收敛数据,不能参与展示状态仲裁。 - 无多路径、无 fallback:这是本技能的核心原则。Web、CLI、fake-server 和线上 web-probe 必须复用同一套 API 契约、同一 route/session/conversation/trace authority 和同一状态投影;不得为了让测试通过增加第二套 dispatcher、localStorage 真相、workspace snapshot 真相、内部 manager 调用、旧 lane 端口、raw request、临时兼容路径或“测试专用后门”。 -- Workbench GET 纯读投影:`GET /v1/workbench/*` 只能读取已持久化的 Workbench 投影事实并组装摘要;不得在 GET 中调用 AgentRun、Code Agent 或其他上游执行面做同步、补事件、修 trace、finalize terminal、改 running/completed 或写 message/session。投影滞后必须显式暴露 `projectionStatus`、`lastProjectedSeq`、`sourceRunId`、`blocker` 或等价诊断字段,并由后台 projector/finalizer 或显式 mutation/repair 处理;刷新页面、切换 session 或打开详情不能成为事实推进入口。 +- 严禁事后 repair / 0repair:Web、Workbench、fake-server 和 web-probe 不得通过 reload、切换 session、realign、`sessionRepair`、workspace selection repair、active tab repair、GET read-through、SSE gap repair、localStorage truth 或测试 helper 自动点击,把已经分裂的 route/session/message/trace 状态补成看起来正确。合法页面必须在首次进入、刷新、deep link、session 切换和 SSE 重连时按同一权威自然收敛;不一致必须暴露为 blocker/diagnostic,并修 schema、projector、read model、reducer 或 route authority 源头。允许 session-bound hydrate/gap-fill 只写目标 session 自己的 cache/read model,不得改变 active selection、URL 或当前消息区。 +- Workbench GET 纯读投影:`GET /v1/workbench/*` 只能读取已持久化的 Workbench 投影事实并组装摘要;不得在 GET 中调用 AgentRun、Code Agent 或其他上游执行面做同步、补事件、修 trace、finalize terminal、改 running/completed 或写 message/session。投影滞后必须显式暴露 `projectionStatus`、`lastProjectedSeq`、`sourceRunId`、`blocker` 或等价诊断字段,并由后台 projector/finalizer 或显式受控 mutation 处理;刷新页面、切换 session 或打开详情不能成为事实推进入口。 - fake-server 不是第二后端:它只按正式 API 契约重放脱敏 fixture 和必要边界变形。未 mock 的 `/auth/*`、`/v1/*`、`/health*` 请求应失败并暴露 path;不得访问 live Cloud API、AgentRun、HWPOD、数据库或 Kubernetes 作为通过条件。 - 真实数据优先:fixture seed 优先从目标 node/lane 的受控真实样本采集。合成 fixture 只补真实样本难以稳定覆盖的边界,并标明 `derivedFrom` 与 `syntheticReason`。 - 原入口闭环:fake-server Playwright 用例负责可重复红灯和源码回归;线上 `hwlab nodes web-probe` 负责同一 node/lane public origin 的 P4 原入口验收。二者不能互相替代。 @@ -66,6 +67,7 @@ JS - Workbench 有 SSE/长轮询时不要用 `networkidle` 判断通过;用明确 DOM/API 条件,如 final URL、route conversationId、active tab、message card、trace row 或 workspace `selectedConversationId`。 - Playwright `page.evaluate` 只能传一个可序列化参数;多个值包成对象,或用 `safeEvaluate(fn, { a, b })`。 - 脚本中用 `recordStep(name, data)` 保存关键 DOM/API partial evidence;API 批量探测优先用 `fetchApiMatrix(paths)`,单个 API 失败不应让后续证据丢失。 +- web-probe 只能观察、截图和断言,不得用 `sessionRepair`、`realignFreshSession`、自动点击 session、reload 循环或 workspace selection repair 作为通过条件。发现 `routeSessionId`、`activeSessionId`、`activeConversationId`、message session 或 trace session 不一致时,必须记录 mismatch 并失败;截图和 API 摘要是证据,不是修复动作。 - 失败证据至少保留 `failureKind`、`errorMessage`、`scriptSha256`、`runDir`、`lastUrl`、`lastScreenshot`、`probe.summary` 和 `reportPath`/`reportSha256`;默认失败截图是 `failure.png`。 ## Fake-Server Playwright @@ -110,6 +112,7 @@ Workbench 至少覆盖: - terminal failure、blocked、canceled 都是最终结果;若 API 返回可读 error/blocker,final response 展示区必须直接显示,不能只放在 trace rows 或详情面板中。 - session 切换验收必须覆盖点击态和持久化恢复态:选择目标 session、确认 workspace `selectedConversationId` 持久化、刷新后同一 session 仍 active。 - completed turn / Trace 重放 / deep link 验收必须用 fresh browser context 或等价 fresh login 直接打开 `/workbench/sessions/?projectId=`,不能只用同页 reload。 +- 0repair 验收必须用 fresh context 直达 session/deep link,或从当前 session 显式切换到目标 session;不得依赖测试 helper 选择、reload、切走再切回、`sessionRepair` 或 `realignFreshSession` 修正页面后再判通过。旧 session 的延迟 detail、turn、trace、SSE 或 refreshSessions 晚到,只能更新该 session cache/list,不能改变 active URL、active tab、current messages 或 composer。 - Trace 实时性要用间隔采样,区分“加载中”和“思考中”;终态卡片不得继续保留“思考中”空态。 - 用户反馈“当前 session 不刷新、切走再切回才刷新”时,证据必须成对采集:直达目标 URL、原地等待、切到其他 session、切回目标 session 的 DOM 截图;同时记录 `/v1/workbench/workspace`、conversation list with `includeConversationId`、conversation detail、turn snapshot 和 trace page 的状态。issue 正文要明确这是事件投影/重放问题,不能只登记成普通 deep link 或单接口 404。