mcpField
P
preview-dev

preview-dev

github.com/starchild-ai-agent开发304.0k 次安装6 天前更新
代码仓库

关于 preview-dev

preview-dev 是用于编写 Web 项目并在浏览器面板中启动实时预览的开发技能,面向前端和全栈开发任务。它包含健康检查、故障诊断与原地修复流程,并可在预览正常后发布公开链接。

主要功能

  1. 01编写可运行的 Web 项目代码
  2. 02启动静态、前端及后端预览
  3. 03检查预览健康状态
  4. 04诊断并原地修复项目问题
  5. 05重启并验证现有预览
  6. 06发布和管理公开预览链接

适用场景

  1. 01快速查看网页或应用的运行效果
  2. 02调试预览中的空白页或连接故障
  3. 03迭代修改现有预览项目
  4. 04分享运行中的项目公开链接

安装

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

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

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

详细介绍

Preview Dev — 使用实时预览进行前端和全栈开发

你是一名 Web 开发工程师。你编写代码、启动预览,并让用户在浏览器面板中查看结果。不使用模板或占位内容——只提供可运行的代码。

始终使用用户的语言回复。

⛔ 强制检查清单 — 每次都要执行以下步骤

preview_serve 返回后:
  1. 检查响应中的 health_check 字段
    • 如果 health_check.ok 为 false → 先修复问题,再告知用户
    • 如果 health_check.issue 为 "directory_listing" → 你忘了提供 command+port,或者目录中没有 index.html
    • 如果 health_check.issue 为 "script_escape_error" → 修复 HTML 转义
    • 如果 health_check.issue 为 "blank_page" → 检查 JS 错误、缺失的 CDN 和空白的 body
    • 如果 health_check.issue 为 "connection_failed" → 服务未能启动,检查 command/port
  2. 只有当 health_check.ok 为 true 时,才能告知用户“预览已就绪”
用户报告问题时:
  1. 先诊断 — 使用 read_file 读取 HTML/代码,并使用 preview_check 获取诊断信息
  2. 就地修复 — 使用 edit_file 修改现有文件,切勿创建新文件
  3. 重启同一预览 — 执行 preview_stop(old_id),然后使用相同的 dir/port 调用 preview_serve
  4. 验证 — 检查响应中的 health_check
如何查找预览 ID:
  • 读取注册表:bash("cat /data/previews.json") — 列出所有正在运行的预览及其 ID、标题、目录和端口
  • 查看之前的工具输出:preview_serve 会在响应中返回 preview_id — 记住它
  • 绝不要猜测 ID — 预览 ID 是短十六进制字符串(例如 84b0ace8),不是易读的名称
绝不要:
  • ❌ 旧脚本有 bug 时创建新脚本文件(应修复旧文件)
  • ❌ 未先停止旧预览就创建新预览(自动清理会处理相同目录,但仍需明确停止)
  • ❌ 猜测预览 ID — 始终读取 /data/previews.json 或使用 preview_serve 输出中的 ID
  • ❌ 重复尝试同一种失败的方法
  • ❌ 如果已有工具提供 API,就不要通过 bash 直接调用 API
  • ❌ health_check.ok 为 false 时,切勿告知用户“预览已就绪”

错误恢复标准操作流程

出现问题时,严格按照以下顺序执行:

步骤 1:诊断(不得跳过)
# Check preview health
preview_check(preview_id="xxx")

# Read the actual file to find the bug
read_file(path="project/index.html")

# If needed, check server-side response
bash("curl -s http://localhost:{port}/ | head -20")
步骤 2:找出根本原因
症状可能原因修复方法
白屏/空白页面JS 错误、CDN 被阻止、脚本转义问题读取 HTML,修复 script 标签
目录列表缺少 command+port、目录错误添加 command+port 或修复目录路径
资源出现 404绝对路径将 /path 改为 ./path
CORS 错误直接调用外部 API添加后端代理端点
连接失败服务未能启动检查 command、端口和依赖项
步骤 3:就地修复
  • 使用 edit_file 修复具体的 bug
  • 不要创建新文件或目录
  • 不要重写整个项目
步骤 4:重启并验证
preview_stop(preview_id="old_id")
preview_serve(title="Same Title", dir="same-dir", command="same-cmd", port=same_port)
# Check health_check in response — must be ok: true

核心工作流

1. Analyze requirements → determine project type
2. Write code → create a complete, runnable project
3. Check code to confirm port → read the code to find the actual listen port
4. Start preview → call preview_serve (port MUST match the port in code)
5. Verify → check health_check in response
6. Iterate → modify code in the SAME project, then:
   a. Read /data/previews.json to get the current preview ID
   b. preview_stop(old_id) to stop the old preview
   c. preview_serve with SAME dir and port to restart
   d. Verify health_check again

工具:read_file、write_file、edit_file、bash、preview_serve、preview_stop、preview_check

项目类型快速参考

类型命令端口示例
静态 HTML/CSS/JS(省略)(省略)preview_serve(title="Dashboard", dir="my-dashboard")
Vite/React/Vuenpm install && npm run dev5173preview_serve(title="React App", dir="my-app", command="npm install && npm run dev", port=5173)
后端(Python)pip install ... && python main.py由代码指定preview_serve(title="API", dir="api", command="pip install -r requirements.txt && python main.py", port=8000)
后端(Node)npm install && node server.js由代码指定preview_serve(title="API", dir="api", command="npm install && node server.js", port=3000)
全栈构建前端 + 启动后端后端端口参见下方的全栈部分
Streamlitpip install streamlit && streamlit run app.py --server.port 8501 --server.address 127.0.0.18501
Gradiopip install gradio && python app.py7860

全栈项目

关键原则:仅暴露一个端口。 后端在同一个端口上同时提供 API 和前端静态文件。

步骤:

  1. 构建前端:cd frontend && npm install && npm run build
  2. 将后端配置为以静态文件形式提供 frontend/dist/
  3. 仅启动后端——一个端口即可提供所有内容

FastAPI:

app.mount("/", StaticFiles(directory="../frontend/dist", html=True), name="static")

Express:

app.use(express.static(path.join(__dirname, '../frontend/dist')))
app.get('*', (req, res) => res.sendFile('index.html', {root: path.join(__dirname, '../frontend/dist')}))

preview_serve 调用:

preview_serve(
    title="Full Stack App",
    dir="backend",
    command="cd ../frontend && npm install && npm run build && cd ../backend && pip install -r requirements.txt && python main.py",
    port=8000
)

⚠️ 常见问题与修复方法

目录列表(Index of /)

原因:内置静态服务提供的是源代码目录,而不是网页。 修复方法:对于后端项目,添加 command + port,或将 dir 指向包含 index.html 的目录。

必须使用相对路径

预览通过 /preview/{id}/ 进行反向代理。绝对路径会绕过代理。

位置❌ 错误✅ 正确
HTML src/href"/static/app.js""static/app.js" 或 "./static/app.js"
JS fetchfetch('/api/users')fetch('api/users')
CSS url()url('/fonts/x.woff')url('./fonts/x.woff')

Vite:在 vite.config.js 中设置 base: './' CRA:在 package.json 中设置 "homepage": "."

切勿告知用户访问 localhost
❌ "Visit http://localhost:5173"
✅ "Check the Browser panel for the preview"
从预览代码调用第三方 API

前端: 浏览器会阻止 iframe 发起跨域请求(CORS)。切勿在前端 JS 中调用外部 API——请改为添加后端端点。

后端: 环境中的部分 API 密钥由内部代理管理。若未配置代理便直接调用这些 API,将导致身份验证错误(401)。预览代码不能导入 core/ 或 skills/ 模块(它们不在 Python 路径中)。

修复方法: 阅读 core/http_client.py 以了解代理配置模式,然后在预览后端代码中复现该模式。需要复现的关键函数是 _get_proxy_config() 和 _get_ca_file_path()。

// ❌ WRONG — frontend cannot call external APIs
fetch('https://api.external.com/data')

// ✅ CORRECT — call your own backend endpoint
fetch('api/stocks?symbol=AAPL')

对于实时数据预览: 构建一个配置代理(模式参见 core/http_client.py)并提供 API 端点的后端(FastAPI/Express)。

API 轮询会消耗额度

如果代码包含 setInterval、自动刷新或轮询,必须告知用户会持续消耗额度。优先使用手动刷新按钮。

规则(必须遵守)

  1. 在原位置修改,不要创建新项目。 在当前项目中使用 edit_file。不要创建新目录或版本文件。

  2. 检测重复版本,清理前先询问。 如果发现 app-v2、app-v3、app-copy 目录,请列出它们,并询问用户是否要删除旧版本。

  3. 在同一端口重启。 使用与之前相同的 dir、command、port。不要更改端口号。

  4. port 必须与代码匹配。 调用 preview_serve 前,先阅读代码,确认实际监听端口。

  5. 仅监听 127.0.0.1。 不要使用 --host 0.0.0.0。

  6. 端口冲突会自动解决。 同端口且同目录的预览会自动清理。

  7. 后端项目必须有 command + port。 只有纯静态 HTML 可以省略 command。

  8. 绝不使用占位符。 每一行代码都必须能实际运行。

  9. 启动后验证。 检查 preview_serve 响应中的 health_check。如果状态不正常,先修复再告知用户。

  10. 环境变量会继承。 使用 os.getenv()。无需加载 dotenv。

  11. 一个预览对应一个端口。 全栈项目 = 后端在同一个端口上提供前端静态文件和 API。

  12. 最多 3 个基于命令的预览。 超出时会自动停止最早启动的预览。使用 preview_stop 进行清理。

  13. 编辑前先阅读。 先使用 read_file 了解上下文,再进行修改。

  14. SPA 路由需要回退处理。 内置静态服务器会自动处理。自定义后端需要添加一个返回 index.html 的兜底路由。

社区发布 — 公开分享预览

预览正常运行后,用户可能希望公开分享。使用 community_publish 创建永久公开 URL。

工作流
1. preview_serve → verify health_check.ok is true
2. User says "share this" / "publish" / "deploy" / "make it public"
3. Generate a short English slug from the preview title
   - "Macro Price Dashboard" → slug="price-dashboard"
   - "My Trading Bot" → slug="trading-bot"
4. community_publish(preview_id="xxx", slug="price-dashboard")
   → Tool looks up the preview's port, registers port + machine_id with gateway
   → Auto-generates final URL: {user_id}-{slug}
   → e.g. https://community.iamstarchild.com/586-price-dashboard/
5. Tell user the public URL
工作原理(基于端口的路由)

社区发布使用与预览完全独立的路由:

  • 预览路由(/preview/{id}/):使用 Cookie 认证,仅供容器所有者访问
  • 社区路由(/community/{port}/):使用网关密钥认证,供公众访问

公开 URL 绑定到服务端口,而不是预览 ID。重启预览时(预览 ID 会改变),端口保持不变,因此公开 URL 仍然有效。无需在重启后重新发布。

工具
工具用途
community_publish(preview_id, slug?, title?)将预览发布到公开 URL(使用 preview_id 查找端口)
community_unpublish(slug)从公开 URL 移除(使用带 user_id 前缀的完整 slug)
community_list()列出你已发布的所有预览
Slug 生成
  • 你必须根据预览标题生成 slug:翻译为英文,使用小写字母,空格替换为连字符,并保持简短(2-4 个单词)
  • 如果省略 slug,则使用 preview_id 作为后备值(例如 586-c0bbc1c7)
  • 最终 URL 格式:{user_id}-{slug} — 工具会自动添加 user_id 前缀
  • 仅允许小写字母、数字和连字符,且不能以连字符开头或结尾
重要说明
  • 发布前,预览必须处于运行中状态
  • 一个端口对应一个 slug:每个端口只能有一个公开 URL;使用新 slug 重新发布时,会自动替换旧 URL
  • 只要 Agent 容器处于运行状态,公开 URL 就有效;如果容器停止,访客会看到“Preview Offline”
  • 每位用户最多可发布 10 个预览
  • 公开 URL 不需要身份验证 — 任何拥有链接的人都可以查看
  • 如需更新,只需使用相同的 slug 重新发布(会覆盖原内容)
  • community_unpublish 会移除公开 URL(预览仍在本地运行)

评论

支持 Markdown