mcpField
B
browser-preview

browser-preview

github.com/starchild-ai-agent开发304.6k 次安装1 周前更新
代码仓库

关于 browser-preview

browser-preview 是一项说明预览服务启动后如何在界面中查看和排查问题的技能,面向使用 Preview 面板的用户与 Agent。它提供运行服务登记、历史查询和资源路径排错流程,并明确用户应通过预览 URL 访问,而不是 localhost。

主要功能

  1. 01说明 Preview 面板操作
  2. 02查询运行服务与历史记录
  3. 03诊断预览服务状态
  4. 04排查静态资源绝对路径
  5. 05提供预览重启流程

适用场景

  1. 01找回消失的预览标签
  2. 02排查白屏或资源加载失败
  3. 03从历史记录重启项目预览

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/starchild-ai-agent/official-skills --skill browser-preview

安装后在 Claude Code 中输入/browser-preview确认已加载。

详细介绍

浏览器预览

你已经了解 preview_serve 和 preview_stop。本技能补上了其中的空缺:preview_serve 返回 URL 后会发生什么——用户实际上如何查看预览。

什么是预览面板

前端右侧有一个面板,包含两个标签页:文件和预览。预览标签页会在 iframe 中渲染预览 URL。调用 preview_serve 时,前端会自动打开一个加载该 URL 的预览标签页。(作业现在由独立的模态框管理,可从左侧边栏访问,不再位于右侧面板中。)

要点:

  • 每次调用 preview_serve 都会创建一个预览标签页
  • URL 格式:https://<host>/preview/{id}/
  • 预览面板有一个 ⋮ 菜单(右上角),其中显示“运行中的服务”列表
  • 用户可以关闭预览标签页,但不会停止后端服务
  • 后端服务停止后,预览标签页会显示错误页面

⚠️ 关键:切勿让用户访问 localhost

用户的浏览器无法访问 localhost 或 127.0.0.1。 这些地址指向服务器容器,而非用户的计算机。预览架构使用反向代理:

User's Browser → https://<host>/preview/{id}/path → (reverse proxy) → 127.0.0.1:{port}/path

规则:

  • 切勿让用户访问 http://localhost:{port} 或 http://127.0.0.1:{port}——他们无法访问
  • 始终引导用户访问预览 URL:/preview/{id}/(或完整 URL https://<host>/preview/{id}/)
  • curl http://localhost:{port} 仅用于你自己的服务器端诊断——切勿建议用户用它来“测试”预览
  • 预览运行时,告诉用户:“检查预览面板,或刷新预览面板”
  • 如果需要向用户提供 URL,请使用 preview_serve 返回的 url 字段(格式:/preview/{id}/)

⚠️ 静态资源必须使用相对路径

由于预览位于 /preview/{id}/ 下,HTML/JS/CSS 中的绝对路径会失效。反向代理会在转发到后端前移除 /preview/{id} 前缀,但浏览器会从域名根目录解析绝对路径。

问题示例:


<script src="/static/app.js"></script>


<script src="static/app.js"></script>
<script src="./static/app.js"></script>

需要修复的常见模式:

错误(绝对路径)修复后(相对路径)
"/static/app.js""static/app.js" 或 "./static/app.js"
"/api/users""api/users" 或 "./api/users"
"/images/logo.png""images/logo.png" 或 "./images/logo.png"
url('/fonts/x.woff')url('./fonts/x.woff')
fetch('/data.json')fetch('data.json')

检查路径出现的所有位置:

  1. HTML 的 src、href 属性
  2. JavaScript 的 fetch()、XMLHttpRequest、动态导入
  3. CSS 的 url() 引用
  4. JavaScript 字符串字面量(例如模板字符串或字符串拼接中的 '/static/')
  5. 框架配置文件(例如 publicPath、base、assetPrefix)

⚠️ 请彻底检查——常见情况是修复了 CSS 的 url(),却漏掉了 JS 字符串字面量中的 '/static/'(使用单引号)。请搜索所有文件类型中绝对路径的所有出现位置。

⚠️ 请勿浏览文件系统来调试预览

切勿查看 preview/、output/ 等工作区目录或其他随机文件夹来了解预览状态。这些是用户数据,不是预览服务状态。

唯一可信的信息来源:

  1. 注册表文件:/data/previews.json(运行中的服务)
  2. 历史记录文件:/data/preview_history.json(所有过往服务)
  3. preview_serve / preview_stop 工具
  4. 通过 curl 检查端口(仅限服务器端,用于诊断)

请勿使用 ls/find 检查工作区目录来诊断预览问题。请勿调用 list_scheduled_tasks 等无关工具。请专注于预览问题。

分步操作:诊断预览问题

用户报告任何预览面板问题时,请严格按以下顺序操作:

第 1 步:读取注册表(运行中的服务)
cat /data/previews.json 2>/dev/null || echo "NO_REGISTRY"

⚠️ 你的 bash CWD 是 /data/workspace/。注册表位于 /data/previews.json(绝对路径,在上一级目录)。请始终使用绝对路径。

JSON 结构:

{
  "previews": [
    {"id": "f343befc", "title": "My App", "dir": "/data/workspace/my-project", "command": "npm run dev", "port": 9080, "is_builtin": false}
  ]
}
步骤 2:根据注册表状态分支

如果注册表中有条目 → 转到步骤 3(验证服务) 如果注册表为空或不存在 → 转到步骤 4(检查历史记录)

步骤 3:注册表中有条目 — 验证并修复

对于注册表中的每个预览,检查端口是否在服务端响应(这是你的诊断操作,不是给用户做的):

curl -s -o /dev/null -w "%{http_code}" http://localhost:{port}

如果端口有响应(200):

  • 服务正在运行。告诉用户:
    • “你有一个正在运行的服务:{title}”
    • “点击 Preview 面板右上角的 ⋮ 菜单,然后在 RUNNING SERVICES 列表中点击该服务以重新打开”
    • Preview URL:/preview/{id}/
  • 如果用户说 ⋮ 菜单为空或没有显示该服务 → 前端同步丢失。通过重新创建来修复:preview_stop(id),然后使用注册表中的信息调用 preview_serve(dir, title, command)。这会强制前端重新注册标签页。

如果端口没有响应:

  • 进程已崩溃,但注册表条目仍存在。重新创建:
    preview_stop(id="{id}")
    preview_serve(dir="{dir}", title="{title}", command="{command}")
    
步骤 4:没有正在运行的服务 — 先检查历史记录,再扫描工作区

没有正在运行的服务时,使用两层查找来寻找用户可以预览的项目:

第一层:读取预览历史记录(首选 — 快速且准确)
cat /data/preview_history.json 2>/dev/null || echo "NO_HISTORY"

JSON 结构:

{
  "history": [
    {
      "id": "f343befc",
      "title": "Trading System",
      "dir": "/data/workspace/my-project",
      "command": "python main.py",
      "port": 8000,
      "is_builtin": false,
      "created_at": 1709100000.0,
      "last_started_at": 1709200000.0
    }
  ]
}

preview_stop 不会删除历史记录条目 — 它们会在重启后保留。只有在项目目录不再存在时,条目才会自动清理。

如果历史记录中有条目:

  • 向用户列出所有历史记录条目,包括标题、目录和上次启动时间
  • 询问他们想重启哪个项目
  • 使用历史记录条目中的 dir、title 和 command 调用 preview_serve

如果用户说历史记录中缺少某个项目 → 转到第二层。

第二层:扫描工作区(备用 — 历史记录为空或不完整时)
find /data/workspace -maxdepth 2 \( -name "package.json" -o -name "index.html" -o -name "*.html" -o -name "app.py" -o -name "main.py" -o -name "vite.config.*" \) -not -path "*/node_modules/*" -not -path "*/skills/*" -not -path "*/memory/*" -not -path "*/prompt/*" -not -path "*/.git/*" 2>/dev/null

然后:

  1. 列出发现的项目并简要描述
  2. 询问用户想预览哪个项目
  3. 使用相应目录调用 preview_serve

不要只说“没有正在运行的服务”就此打住。 务必先检查历史记录,再进行扫描,并提供可选项。

快速参考

用户说你的操作
“标签页消失了” / “tab 不见了”步骤 1 → 2 → 3 或 4
“空白页” / “白屏”检查端口(服务端);如果无响应 → 重新创建;如果有响应 → 检查绝对路径问题
“没有更新” / “内容没更新”建议点击 Preview 标签页中的刷新按钮,或重新创建预览
“端口冲突” / “端口冲突”preview_stop 旧服务 → preview_serve 新服务
“看不到服务” / “⋮ 菜单为空”调用 preview_stop + preview_serve,强制重新注册
“我的项目在哪” / “我构建了什么”读取 /data/preview_history.json 并列出条目
“资源加载失败” / “JS/CSS 404”检查绝对路径(/static/、/api/),将其改为相对路径

你无法执行的操作

  • 无法直接打开、关闭或刷新 Preview 标签页(前端 UI)
  • 无法强制刷新 iframe
  • 无法读取 iframe 中显示的内容

无法执行某项操作时,告诉用户需要手动执行的操作(例如,“在 Preview 标签页中点击刷新”)。如果手动操作无效,则使用 preview_stop + preview_serve 重新创建预览。

应避免的常见错误

  1. ❌ 告诉用户“访问 http://localhost:18791/” — 用户无法访问 localhost
  2. ❌ 说“刷新 localhost 上的页面” — 对用户来说毫无意义
  3. ❌ 只修复 CSS url() 路径,却漏掉含有绝对路径的 JS 字符串字面量
  4. ❌ 忘记检查所有文件类型(HTML、JS、CSS、配置)中的绝对路径
  5. ✅ 面向用户时始终使用 /preview/{id}/ 作为 URL
  6. ✅ 仅将 curl localhost:{port} 用于你自己的服务端诊断
  7. ✅ 修复路径后,调用 preview_stop + preview_serve 重启,然后告诉用户检查 Preview 面板

评论

支持 Markdown