{
  "schemaVersion": "1.0",
  "item": {
    "slug": "dev-serve",
    "name": "Dev Serve",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/BrennerSpear/dev-serve",
    "canonicalUrl": "https://clawhub.ai/BrennerSpear/dev-serve",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/dev-serve",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=dev-serve",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "scripts/dev-serve.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/dev-serve"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/dev-serve",
    "agentPageUrl": "https://openagent3.xyz/skills/dev-serve/agent",
    "manifestUrl": "https://openagent3.xyz/skills/dev-serve/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/dev-serve/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "dev-serve — One-Command Dev Server Hosting",
        "body": "Start a dev server in a tmux session and expose it via Caddy at <project>.YOUR_DOMAIN. One command up, one command down."
      },
      {
        "title": "Setup",
        "body": "Install the script:\ncp scripts/dev-serve.sh ~/.local/bin/dev-serve\nchmod +x ~/.local/bin/dev-serve\n\n\n\nSet your domain (one of):\n\nExport DEV_SERVE_DOMAIN in your shell profile\nOr edit the DOMAIN variable in the script\n\n\n\nRequirements:\n\nCaddy running with wildcard DNS + TLS (see caddy skill)\ntmux, jq, curl\nCaddy admin API on localhost:2019"
      },
      {
        "title": "CLI",
        "body": "dev-serve up <repo-path> [port]      # Start dev server + add Caddy route\ndev-serve down <name>                # Stop dev server + remove Caddy route\ndev-serve ls                         # List active dev servers\ndev-serve restart <name>             # Restart dev server (keep Caddy route)"
      },
      {
        "title": "How It Works",
        "body": "Derives subdomain from the repo folder name (~/projects/myapp → myapp.YOUR_DOMAIN)\nDetects the dev command from package.json scripts.dev (supports vite, next, nuxt, sveltekit)\nAuto-patches Vite allowedHosts if a vite config file exists\nStarts the dev server in a tmux session named dev-<name> with --host 0.0.0.0 --port <port>\nAdds a Caddy route + dashboard link to the Caddyfile\nReloads Caddy via admin API (no sudo, no restart)\nVerifies end-to-end: waits for the dev server to listen, then polls HTTPS until 2xx/3xx (up to 90s)"
      },
      {
        "title": "Examples",
        "body": "# Start with auto-assigned port (starts at 5200, skips used ports)\ndev-serve up ~/projects/myapp\n# → https://myapp.YOUR_DOMAIN\n\n# Explicit port\ndev-serve up ~/projects/myapp 5200\n\n# Override dev command\nDEV_CMD=\"bun dev\" dev-serve up ~/projects/myapp 5300\n\n# Stop and clean up\ndev-serve down myapp\n\n# List what's running\ndev-serve ls"
      },
      {
        "title": "Configuration",
        "body": "VariableDefaultDescriptionDEV_SERVE_DOMAIN(must be set)Your wildcard domain (e.g. mini.example.com)DEV_SERVE_STATE_DIR~/.config/dev-serveWhere state JSON is storedCADDYFILE~/.config/caddy/CaddyfilePath to your CaddyfileCADDY_ADMINhttp://localhost:2019Caddy admin API addressDEV_CMD(auto-detected)Override the dev server command"
      },
      {
        "title": "Port Convention",
        "body": "Permanent services: 3100 range (managed in Caddyfile directly)\nDev servers: 5200+ (managed by dev-serve, auto-assigned)"
      },
      {
        "title": "Vite allowedHosts",
        "body": "Vite blocks requests from unrecognized hostnames. dev-serve up automatically patches vite.config.ts (or .js/.mts/.mjs) to add the subdomain. If auto-patching fails, it prints the manual fix."
      },
      {
        "title": "Architecture",
        "body": "Browser (Tailscale / LAN / etc.)\n  → DNS: *.YOUR_DOMAIN → your server IP\n    → Caddy (HTTPS with auto certs)\n      → reverse_proxy localhost:<port>\n        → Dev server (in tmux session)"
      },
      {
        "title": "Companion Skills",
        "body": "caddy — Required. Sets up the Caddy reverse proxy with wildcard TLS."
      },
      {
        "title": "Troubleshooting",
        "body": "Dev server not starting:\n\ntmux attach -t dev-<name>    # see what happened\n\nCert not provisioning (curl exit 35):\nWait 30-60s for DNS-01 challenge. Check tail -20 /var/log/caddy-error.log.\n\nCaddy reload failed:\n\ncaddy reload --config ~/.config/caddy/Caddyfile --address localhost:2019\n\n403 from Vite:\nThe subdomain wasn't added to allowedHosts. Add it manually to your vite.config.ts:\n\nserver: { allowedHosts: ['myapp.YOUR_DOMAIN'] }"
      }
    ],
    "body": "dev-serve — One-Command Dev Server Hosting\n\nStart a dev server in a tmux session and expose it via Caddy at <project>.YOUR_DOMAIN. One command up, one command down.\n\nSetup\n\nInstall the script:\n\ncp scripts/dev-serve.sh ~/.local/bin/dev-serve\nchmod +x ~/.local/bin/dev-serve\n\n\nSet your domain (one of):\n\nExport DEV_SERVE_DOMAIN in your shell profile\nOr edit the DOMAIN variable in the script\n\nRequirements:\n\nCaddy running with wildcard DNS + TLS (see caddy skill)\ntmux, jq, curl\nCaddy admin API on localhost:2019\nCLI\ndev-serve up <repo-path> [port]      # Start dev server + add Caddy route\ndev-serve down <name>                # Stop dev server + remove Caddy route\ndev-serve ls                         # List active dev servers\ndev-serve restart <name>             # Restart dev server (keep Caddy route)\n\nHow It Works\nDerives subdomain from the repo folder name (~/projects/myapp → myapp.YOUR_DOMAIN)\nDetects the dev command from package.json scripts.dev (supports vite, next, nuxt, sveltekit)\nAuto-patches Vite allowedHosts if a vite config file exists\nStarts the dev server in a tmux session named dev-<name> with --host 0.0.0.0 --port <port>\nAdds a Caddy route + dashboard link to the Caddyfile\nReloads Caddy via admin API (no sudo, no restart)\nVerifies end-to-end: waits for the dev server to listen, then polls HTTPS until 2xx/3xx (up to 90s)\nExamples\n# Start with auto-assigned port (starts at 5200, skips used ports)\ndev-serve up ~/projects/myapp\n# → https://myapp.YOUR_DOMAIN\n\n# Explicit port\ndev-serve up ~/projects/myapp 5200\n\n# Override dev command\nDEV_CMD=\"bun dev\" dev-serve up ~/projects/myapp 5300\n\n# Stop and clean up\ndev-serve down myapp\n\n# List what's running\ndev-serve ls\n\nConfiguration\nVariable\tDefault\tDescription\nDEV_SERVE_DOMAIN\t(must be set)\tYour wildcard domain (e.g. mini.example.com)\nDEV_SERVE_STATE_DIR\t~/.config/dev-serve\tWhere state JSON is stored\nCADDYFILE\t~/.config/caddy/Caddyfile\tPath to your Caddyfile\nCADDY_ADMIN\thttp://localhost:2019\tCaddy admin API address\nDEV_CMD\t(auto-detected)\tOverride the dev server command\nPort Convention\nPermanent services: 3100 range (managed in Caddyfile directly)\nDev servers: 5200+ (managed by dev-serve, auto-assigned)\nVite allowedHosts\n\nVite blocks requests from unrecognized hostnames. dev-serve up automatically patches vite.config.ts (or .js/.mts/.mjs) to add the subdomain. If auto-patching fails, it prints the manual fix.\n\nArchitecture\nBrowser (Tailscale / LAN / etc.)\n  → DNS: *.YOUR_DOMAIN → your server IP\n    → Caddy (HTTPS with auto certs)\n      → reverse_proxy localhost:<port>\n        → Dev server (in tmux session)\n\nCompanion Skills\ncaddy — Required. Sets up the Caddy reverse proxy with wildcard TLS.\nTroubleshooting\n\nDev server not starting:\n\ntmux attach -t dev-<name>    # see what happened\n\n\nCert not provisioning (curl exit 35): Wait 30-60s for DNS-01 challenge. Check tail -20 /var/log/caddy-error.log.\n\nCaddy reload failed:\n\ncaddy reload --config ~/.config/caddy/Caddyfile --address localhost:2019\n\n\n403 from Vite: The subdomain wasn't added to allowedHosts. Add it manually to your vite.config.ts:\n\nserver: { allowedHosts: ['myapp.YOUR_DOMAIN'] }"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/BrennerSpear/dev-serve",
    "publisherUrl": "https://clawhub.ai/BrennerSpear/dev-serve",
    "owner": "BrennerSpear",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/dev-serve",
    "downloadUrl": "https://openagent3.xyz/downloads/dev-serve",
    "agentUrl": "https://openagent3.xyz/skills/dev-serve/agent",
    "manifestUrl": "https://openagent3.xyz/skills/dev-serve/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/dev-serve/agent.md"
  }
}