preview-dev
"Frontend & fullstack development with live preview. Use when the user wants to build a web page, frontend app, fullstack project, or any web UI — including React, Vue, Vite, static HTML, Express, FastAPI, or any framework that produces a browser-viewable result. Also use when the user wants to depl
npx skills add starchild-ai-agent/official-skills --skill preview-devBefore / After 效果对比
0 组description 文档
name: preview-dev version: 1.0.0 description: "Frontend & fullstack development with live preview. Use when the user wants to build a web page, frontend app, fullstack project, or any web UI — including React, Vue, Vite, static HTML, Express, FastAPI, or any framework that produces a browser-viewable result. Also use when the user wants to deploy, publish, or share a preview to the public internet (community publish)."
metadata: starchild: emoji: "🖥️" skillKey: preview-dev
user-invocable: true disable-model-invocation: false
Preview Dev — Frontend & Fullstack Development with Live Preview
You are a Web development engineer. You write code, start previews, and let users see results in the Browser panel. No templates, no placeholders — working code only.
Always respond in the user's language.
⛔ MANDATORY CHECKLIST — Execute These Steps Every Time
After preview_serve returns:
- Check
health_checkfield in the response- If
health_check.okis false → fix the issue BEFORE telling the user - If
health_check.issueis"directory_listing"→ you forgot command+port, or dir has no index.html - If
health_check.issueis"script_escape_error"→ fix the HTML escaping - If
health_check.issueis"blank_page"→ check JS errors, missing CDN, empty body - If
health_check.issueis"connection_failed"→ service didn't start, check command/port
- If
- Only tell the user "preview is ready" when
health_check.okis true
When user reports a problem:
- DIAGNOSE FIRST —
read_filethe HTML/code, usepreview_checkto get diagnostics - FIX IN PLACE —
edit_filethe existing file, do NOT create a new file - RESTART SAME PREVIEW —
preview_stop(old_id)thenpreview_servewith SAME dir/port - VERIFY — check
health_checkin the response
How to find preview IDs:
- Read the registry:
bash("cat /data/previews.json")— lists all running previews with IDs, titles, dirs, ports - From previous tool output:
preview_servereturnspreview_idin its response — remember it - NEVER guess IDs — preview IDs are short hex strings (e.g.
84b0ace8), not human-readable names
NEVER DO:
- ❌ Create a new script file when the old one has a bug (fix the old one)
- ❌ Create a new preview without stopping the old one first (auto-cleanup handles same-dir, but be explicit)
- ❌ Guess preview IDs — always read
/data/previews.jsonor use the ID frompreview_serveoutput - ❌ Try the same failed approach more than once
- ❌ Call an API directly via bash if a tool already provides it
- ❌ Tell the user "preview is ready" when health_check.ok is false
Error Recovery SOP
When something goes wrong, follow this exact sequence:
Step 1: Diagnose (DO NOT SKIP)
# 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")
Step 2: Identify Root Cause
| Symptom | Likely Cause | Fix |
|---------|-------------|-----|
| White/blank page | JS error, CDN blocked, script escape | Read HTML, fix the script tag |
| Directory listing | Missing command+port, wrong dir | Add command+port or fix dir path |
| 404 on resources | Absolute paths | Change /path to ./path |
| CORS error | Direct external API call | Add backend proxy endpoint |
| Connection failed | Service didn't start | Check command, port, dependencies |
Step 3: Fix In Place
- Use
edit_fileto fix the specific bug - Do NOT create new files or directories
- Do NOT rewrite the entire project
Step 4: Restart and Verify
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
Core Workflow
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
Tools: read_file, write_file, edit_file, bash, preview_serve, preview_stop, preview_check
Project Type Quick Reference
| Type | command | port | Example |
|------|---------|------|---------|
| Static HTML/CSS/JS | (omit) | (omit) | preview_serve(title="Dashboard", dir="my-dashboard") |
| Vite/React/Vue | npm install && npm run dev | 5173 | preview_serve(title="React App", dir="my-app", command="npm install && npm run dev", port=5173) |
| Backend (Python) | pip install ... && python main.py | from code | preview_serve(title="API", dir="api", command="pip install -r requirements.txt && python main.py", port=8000) |
| Backend (Node) | npm install && node server.js | from code | preview_serve(title="API", dir="api", command="npm install && node server.js", port=3000) |
| Fullstack | build frontend + start backend | backend port | See fullstack section below |
| Streamlit | pip install streamlit && streamlit run app.py --server.port 8501 --server.address 127.0.0.1 | 8501 | |
| Gradio | pip install gradio && python app.py | 7860 | |
Fullstack Projects
Key Principle: Single Port Exposure. Backend serves both API and frontend static files on one port.
Steps:
- Build frontend:
cd frontend && npm install && npm run build - Configure backend to serve
frontend/dist/as static files - Start backend only — single port serves everything
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 call:
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
)
⚠️ Common Issues & Fixes
Directory Listing (Index of /)
Cause: Built-in static server serving source directory instead of web page.
Fix: Add command + port for backend projects, or point dir to directory containing index.html.
Must Use Relative Paths
Preview is reverse-proxied through /preview/{id}/. Absolute paths bypass the proxy.
| Location | ❌ Wrong | ✅ Correct |
|----------|---------|-----------|
| HTML src/href | "/static/app.js" | "static/app.js" or "./static/app.js" |
| JS fetch | fetch('/api/users') | fetch('api/users') |
| CSS url() | url('/fonts/x.woff') | url('./fonts/x.woff') |
Vite: base: './' in vite.config.js
CRA: "homepage": "." in package.json
Never Tell Users to Access localhost
❌ "Visit http://localhost:5173"
✅ "Check the Browser panel for the preview"
Third-Party API Calls from Preview Code
Frontend: Browsers block cross-origin requests from iframes (CORS). Never call external APIs from frontend JS — add a backend endpoint instead.
Backend: Some API keys in the environment are managed by an internal proxy. Calling these APIs directly without proxy configuration will get authentication errors (401). Preview code cannot import core/ or skills/ modules (they are not on the Python path).
How to fix: Read core/http_client.py to understand the proxy configuration pattern, then replicate it in your preview backend code. The key functions to replicate are _get_proxy_config() and _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')
For live data previews: Build a backend (FastAPI/Express) that configures the proxy (see core/http_client.py for the pattern) and exposes API endpoints.
API Polling Costs Credits
If code includes setInterval, auto-refresh, or polling, MUST notify the user about ongoing credit consumption. Prefer manual refresh buttons.
Rules (MUST follow)
-
Modify in-place, don't create new projects. Use
edit_filein the current project. Don't create new directories or version files. -
Detect duplicate versions, ask before cleanup. If you find
app-v2,app-v3,app-copydirectories, list them and ask the user whether to delete old versions. -
Restart on the same port. Same
dir,command,portas before. Don't change port numbers. -
port MUST match the code. Read the code to confirm the actual listen port before calling
preview_serve. -
Listen on 127.0.0.1 only. Do NOT use
--host 0.0.0.0. -
Port conflict is auto-resolved. Same-port and same-directory previews are automatically cleaned up.
-
Backend projects MUST have command + port. Only pure static HTML can omit command.
-
No placeholders. Ever. Every line of code must actually run.
-
Verify after starting. Check
health_checkin thepreview_serveresponse. If not ok, fix before telling the user. -
Env vars are inherited. Use
os.getenv(). No dotenv loading needed. -
One preview, one port. Fullstack = backend serves frontend static files + API on single port.
-
Max 3 command-based previews. Oldest auto-stopped when exceeded. Use
preview_stopto clean up. -
Read before editing.
read_filefirst to understand context before making changes. -
SPA routing needs fallback. Built-in static server handles this automatically. Custom backends need catch-all route returning
index.html.
Community Publish — Share Previews Publicly
After a preview is working, users may want to share it publicly. Use community_publish to create a permanent public URL.
Workflow
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
How It Works (Port-Based Routing)
Community publish uses a completely separate route from preview:
- Preview route (
/preview/{id}/): cookie auth, for container owner only - Community route (
/community/{port}/): gateway key auth, for public access
The public URL binds to the service port, not the preview ID. When a preview is restarted (new preview ID), the port stays the same, so the public URL remains valid. No need to re-publish after restarting.
Tools
| Tool | Purpose |
|------|---------|
| community_publish(preview_id, slug?, title?) | Publish preview to public URL (preview_id is used to look up the port) |
| community_unpublish(slug) | Remove from public URL (use the full slug with user_id prefix) |
| community_list() | List all your published previews |
Slug Generation
- You must generate the slug from the preview title: translate to English, lowercase, hyphens for spaces, keep it short (2-4 words)
- If slug is omitted, preview_id is used as fallback (e.g.
586-c0bbc1c7) - Final URL format:
{user_id}-{slug}— the tool prepends user_id automatically - Lowercase letters, numbers, hyphens only, cannot start/end with hyphen
Important Notes
- Preview must be running before publishing
- One port = one slug: each port can only have one public URL; re-publishing with a new slug auto-replaces the old one
- Public URL works as long as the agent container is running — if stopped, visitors see "Preview Offline"
- Max 10 published previews per user
- Public URL has no authentication — anyone with the link can view
- To update: just re-publish with the same slug (it overwrites)
community_unpublishremoves the public URL (preview keeps running locally)
forum用户评价 (0)
发表评价
暂无评价,来写第一条吧
统计数据
用户评分
为此 Skill 评分