CtrlK
BlogDocsLog inGet started
Tessl Logo

browser-preview

Hub 内嵌浏览器预览 localhost 应用。 Use when: 写前端代码、跑 dev server、需要看页面效果、调 UI、operator说"看看效果"。 Not for: 后端纯 API 开发、不涉及页面的工作。 Output: 前端页面在 Hub browser panel 中实时预览。

71

Quality

88%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

Browser Preview

Hub 内置了嵌入式浏览器面板(F120),可以直接预览运行中的 localhost 应用。猫猫写完前端代码不用让operator切浏览器看效果。

工作流

基础流程(端口发现 → 预览)

  1. 启动 dev server:交互 Terminal 可直接前台跑;要把页面交给operator跨回合查看时,猫的 invocation/-p 会话必须用仓库的 managed launcher: pnpm preview:process start --port PORT --cwd /absolute/project/path -- COMMAND [ARGS...] macOS 上它会把目标直接注册为一次性 user LaunchAgent;普通 detached child、nohupsetsid 或 PTY 都不算独立托管。托管预览默认 8 小时自动到期(可用 --lifetime-seconds N 缩短,最长 24 小时),避免遗留 watcher 持续制造文件事件。
  2. Hub 自动检测端口 → 弹出 toast 提示"检测到 localhost:xxxx 启动"
  3. 点击 Open Preview → 自动打开 browser panel 并加载页面
  4. 也可以手动:切到 workspace 的 Browser tab,输入 localhost:port 按 Go

改代码 → HMR 热更新 → browser panel 内页面自动刷新,无需手动操作。

猫主动打开浏览器(Phase C — 必须掌握)

operator说过:"别手动让我输入,你最好打开浏览器,把页面放出来。"

猫应该主动替operator打开浏览器,不要等operator点 toast 或手动输 URL。

调用步骤(按顺序执行,不要跳步)

Step 1: 确认目标服务器在跑
  若由猫启动,先用 managed launcher 启动/查状态:
  pnpm preview:process start --port PORT --cwd /absolute/project/path -- COMMAND [ARGS...]
  pnpm preview:process status --port PORT --cwd /absolute/project/path --json
  → 只有 status=running 才进入下步;unavailable/unmanaged/stopped 必须如实报告
  → macOS 跨回合展示还必须有 origin=launchd;origin=detached 只证明 launcher 已退出,
    没证明脱离 invocation supervisor,不得承诺“回复后还会活着”
  curl -s -o /dev/null -w "%{http_code}" http://localhost:PORT
  → 200/301/304 = 可以继续
  → 000/connection refused = 服务器没起来,先启动再说

Step 2: 调用 typed MCP
  cat_cafe_preview_open({
    port: PORT,
    path: "/",
    worktreeId: "当前 worktreeId(有就传)",
    threadId: "当前 threadId(有就传)"
  })

Step 3: 读返回的 deliveryStatus,再决定怎么报告
  → applied     = Hub 前端真实接收并应用了(面板已打开)——只有这时才能说"已打开"
  → queued      = 目标 thread 不在前台,已写入其 ThreadState;切到该 thread 自动揭示
  → blocked     = presentation lock 等阻止了展示(看 deliveryReason)
  → unconfirmed = 没有任何 Hub 客户端确认送达(没连接 / 无匹配 client)——必须如实说"未能确认打开"

admission ≠ visibleallowed: true 只证明服务端受理了请求。报告"已打开"之前必须看到 deliveryStatus: "applied"

running ≠ durable:同一 invocation 内的 status: "running" 只证明当前可达。macOS 只有 origin: "launchd" 才证明已经交给用户会话级服务管理;“确实跨回合存活”必须由后续 invocation 的 status/HTTP 探针或operator现场画面确认。

durable ≠ immortalstatus --jsonexpiresAt 是硬截止时间。展示提前结束就显式 stop;确需延长时,先停掉旧实例再重新 start,不要绕过租约另开后台 watcher。

工具参数

参数必填说明
portdev server 端口号
path页面路径,默认 /
threadIdinvocation 免传 / agent-key 必传invocation 调用由服务端从 invocation 记录推导;持久 agent-key 必须显式传,缺失直接报错。传了保证精确送达到该 thread
worktreeId建议传精确到 worktree;不传走 user-scope 送达,同用户其他 tab 会按 thread 归属 queue

怎么获取 worktreeId:就是你当前工作的 worktree 目录名。例如你在 cat-cafe-f120-fix 目录里工作,worktreeId 就是 cat-cafe-f120-fix。如果你在主仓库 cat-cafe 里,就不需要传。

常见错误

现象原因修法
右侧无反应目标服务器没在跑 / 未认证或 thread 归属不对 / MCP callback 未配置curl localhost:PORT 确认目标服务,再读工具返回的 deliveryStatus / 错误(401=未认证,400/403=thread scope)
{"error":"Proxy error","message":"socket hang up"}目标服务器已退出重启服务器,再刷新 Browser panel
猫回复后页面立刻 stopped服务仍在 invocation 的 PTY/进程监督域;detached/PPID=1 也可能被 supervisor 按 coalition 回收macOS 用 pnpm preview:process start ... 并确认 status=running, origin=launchd;结束展示时用同一 cwd/port 执行 stop
打开了系统 Chrome用了 Playwright/Chrome MCP 等外部工具不要用外部浏览器工具! auto-open 是 Hub 内嵌预览,不是系统浏览器
两个重复 tabReact Strict Mode(已修复)升级到最新代码
  • 适用场景:写完前端代码后、operator说"看看效果"、需要展示复杂页面
  • ⚠️ 不要传 html 参数(后端不支持);简单 HTML 可视化用 html_widget rich block

两层可视化策略

operator拍板:"简单的用富文本,复杂的用猫主动打开浏览器。"

场景方式怎么做
简单可视化(图表、动画、计算器)html_widget rich block 内联渲染rich-messaging skill 发 html_widget block
复杂应用(完整页面、多组件交互)猫主动打开浏览器调用 auto-open API

技术要点(猫猫需要知道的)

项目说明
Preview Gateway独立端口(默认 4100),反向代理 localhost 应用
为什么不直连iframe 跨端口需要代理剥离 X-Frame-Options/CSP
iframe sandboxallow-scripts allow-forms allow-popups allow-downloads allow-same-origin(安全:独立 origin)
WebSocket/HMR代理层支持 WebSocket 升级,Vite/Next/Webpack HMR 正常工作
端口排除Clowder AI 自身端口(3003/3004/6398/6399/18888 等)自动排除
审计每次 open/close/navigate 都有审计日志
Console 面板bridge script 注入到 iframe,捕获 console.log/warn/error,在面板展示
一键截图SVG foreignObject + canvas 截图,上传后端,toast 展示
送达契约认证 + exact-thread:anonymous → 401;invocation 推导 thread;agent-key 必传 threadId 且校验归属。事件只发射一次到 caller 的 user room(tenant scope,无 preview:global/worktree 广播),回执同房间收集
多 Tab同时预览多个 localhost 页面,Tab 切换独立状态;同一事件多 tab 各自回执,服务端聚合取最优(applied > blocked > queued,skipped 不参评)
进程来源preview:process status --json 返回 origin。macOS 的 launchd 是跨 invocation 托管;其他平台的 detached 只保证 launcher 退出后继续运行,宿主 supervisor 是否回收仍需外部 service manager 证明
生命周期每个 managed preview 都必须返回 expiresAt;默认 8 小时、最长 24 小时,到期后 launcher 会 TERM→KILL 自己拥有的进程组。长期展示要显式续开,不允许无限 watcher

什么时候主动用

  • 写完前端组件/页面 → 主动调 auto-open 打开浏览器展示(不要等operator点)
  • 调样式/布局 → 改代码后在 browser panel 里实时查看
  • operator说"看看效果"/"给我看看" → 主动打开 browser panel 展示
  • dev server 已在 Terminal 跑着 → 主动打开浏览器,不要只提示
  • invocation/-p 中启动的 dev server → 必须走 preview:process,并在报告中同时给出 status 与 origin;不能把 running/detached 写成跨回合已存活
  • 跨回合展示 → 同时检查 expiresAt;任务结束或不再展示时执行同一 cwd/port 的 preview:process stop
  • 简单可视化(图表/动画) → 用 html_widget rich block 内联渲染
  • Console 有报错 → browser panel 下方 Console 面板自动展开,可以看
  • 需要截图 → browser panel 工具栏一键截图;默认先存到 ${TMPDIR}/cat-cafe-evidence/...,不要落仓库根目录(见 ../.cat-cafe-shared-refs/evidence-output-contract.md

不要做的事

  • 不要跳过 Step 1(验证服务器)直接调 cat_cafe_preview_open — 服务器没跑 = proxy error
  • 不要用普通后台 shell/PTY、nohupsetsid 或普通 detached child 冒充长期托管 — PPID=1 仍可能被 invocation supervisor 按进程族回收
  • 不要用 launchctl submit 包裹会立即退出的 launcher — inferred keepalive 会反复重启 launcher 形成自旋;macOS 直接用 preview:process 生成的一次性 LaunchAgent
  • 不要用 Playwright / Chrome MCP / open 命令打开系统浏览器 — F120 是 Hub 内嵌预览,走 iframe,不走系统浏览器
  • 不要手写 /api/preview/auto-opencurl — 主路径是 cat_cafe_preview_open
  • 不要手动去构造 gateway URL(让 Hub 前端处理)
  • 不要尝试预览外部 URL(只支持 localhost)
  • 不要预览 Clowder AI 自身服务端口(会被端口验证拦截)
  • 不要把临时截图顺手留在仓库根目录;要入库时再显式归档到正式目录

和其他 skill 的区别

Skill关注点
browser-preview(本 skill)Hub 内预览 localhost 前端页面
tdd写代码的测试驱动纪律
quality-gate开发完成后的自检(含对照设计稿)
Repository
zts212653/clowder-ai
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.