CloudBase Sites Runtime
This skill orchestrates a single working directory = single project flow
for CloudBase Web apps. The cwd itself is the workspace; we do not manage
cross-cwd state or session IDs at the skill level.
This runtime is shared by the Codex, Claude Code, and CodeBuddy plugin
surfaces. The CLI and CloudBase MCP workflows are the source of truth. Some
hosts also run bundled lifecycle hooks that start previews or inject compact
rules at session start; if hooks are unavailable, disabled, or not yet trusted,
use the explicit CLI commands in this skill.
Activation contract
Use this skill when
- The user says "build me a website / app", "I want to make a landing page",
"create a React app and let me preview", "deploy this to CloudBase",
"save this version", "roll back to v1", or similar.
- The current cwd looks like a CloudBase + Vite project (has
package.json
with vite + react or vue).
- The user is running this conversation inside Codex, Claude Code, CodeBuddy,
or a compatible host with the
cloudbase-sites plugin enabled —
cloudbase-mcp is registered and the cloudbase-sites binary is either on
PATH or available from the plugin root's bin/cloudbase-sites.
Do NOT use this skill when
- It's a mini-program project — route to mini-program guidance instead.
- It's a native app project — route to http-api guidance.
- It's a backend-only project — route to cloud-functions / cloudrun guidance.
- The framework is Next/Nuxt/Astro/Remix — politely tell the user this skill
only covers Vite-based React/Vue apps and stop. Do NOT try to adapt the
scripts to those frameworks.
What this skill orchestrates — three layers
1. CloudBase MCP tools (provided by cloudbase-mcp, registered via plugin's .mcp.json)
These are the only tools that produce CloudBase side effects. Highlights:
downloadTemplate({ template: "react" | "vue", ide }) — pull official template
envQuery({ action: "info" }) + auth({ action: "set_env", envId }) — bind env
manageApps({ action: "deployApp", ... }) — deploy to CloudApp (independent subdomain)
envDomainManagement({ action: "create", domains }) — whitelist dev origin for CORS
searchKnowledgeBase({ mode: "skill", skillName: "<name>" }) — fetch CloudBase domain skills (see below)
For all CloudBase operations beyond the dev-server lifecycle (auth, db,
storage, ai), fetch the corresponding CloudBase domain skill via
searchKnowledgeBase(mode="skill", skillName=...). Common ones:
ui-design UI design spec (mandatory before new UI work)
web-development Web project conventions
auth-tool-cloudbase provider config (management-side)
auth-web-cloudbase Web SDK auth client code
postgresql-development-cloudbase PG mode schema/RLS/app.rdb() (PG envs)
cloudbase-document-database-web-sdk document database Web SDK
cloud-storage-web cloud storage Web SDK
relational-database-web-cloudbase MySQL Web SDK
cloudbase-platform platform overview / console links
These are NOT Claude Code native skills and are NOT bundled with this
plugin. They live inside cloudbase-mcp and are fetched on demand. When this
file (or the injected RULES_BLOCK) says "调 ui-design skill" or "follow the
auth-tool skill", that means: call searchKnowledgeBase(mode="skill", skillName="<that-name>") and apply the returned content.
2. The cloudbase-sites CLI (provided by this plugin's bin/ directory)
First resolve the CLI path:
- Try
command -v cloudbase-sites.
- If that fails and the host exposes
CODEX_PLUGIN_ROOT, use
$CODEX_PLUGIN_ROOT/bin/cloudbase-sites.
- If that fails and the host exposes
CLAUDE_PLUGIN_ROOT, use
$CLAUDE_PLUGIN_ROOT/bin/cloudbase-sites.
- If SessionStart injected an absolute CLI path, use that path.
Do not assume Codex has injected the plugin bin/ directory into PATH.
Single binary, multiple subcommands. Use these — and ONLY these — for the
dev-server / version / deploy lifecycle:
cloudbase-sites init --start — scaffold from empty cwd and start preview when the user explicitly wants a Sites app
cloudbase-sites preview — daemonize Vite for an existing Vite project
cloudbase-sites preview --status [--quiet] — JSON status / exit code
cloudbase-sites preview --restart / --stop [--force]
cloudbase-sites save -m "<label>" — create a saved version
cloudbase-sites versions — list saved versions + deploy status
cloudbase-sites deploy [--version <n>] — deploy a saved version (Phase 1: emit nextAction)
cloudbase-sites deploy --post --version <n> --access-url <url> [--build-id <BuildId>] [--version-name <VersionName>] — record deploy
cloudbase-sites rollback [--to-version <n>] — revert to a saved version
cloudbase-sites supervisor status|list|heal|reload|start|stop
Never invent npm run dev / vite / vite build invocations. The CLI
handles host=0.0.0.0 forcing, port allocation (17173..17272), daemonization,
base path injection, version metadata, and deploy history.
3. Standard tools (Bash, git, Edit, Write)
Use for editing files. The plugin's PostToolUse hook handles automatic
restart on config-file edits — you don't need to manage that.
Lifecycle hooks and fallback
Do NOT invoke cloudbase-sites init or cloudbase-sites preview
proactively in your first message just because the plugin is installed.
SessionStart is intentionally passive for empty directories so the plugin does
not interfere with unrelated sessions. A UserPromptSubmit hook may initialize
after the first user message, but only when deterministic Chinese/English
intent rules detect an explicit Sites/Web-app creation request. By the time you
read the user's first prompt:
- If the cwd was an existing Vite project: dev server is up (or installing).
- If the cwd was empty: no files were downloaded by SessionStart. If the first
prompt clearly asked to build/create a Sites app, UserPromptSubmit may have
started
init --start; otherwise initialize only after the user asks.
- If the cwd is a non-Vite / blacklisted project: hook stayed silent.
Codex supports bundled plugin hooks, but non-managed command hooks may require
the user to review and trust them before they run. If Codex hooks have not run,
resolve the CLI path as described above, then fall back to
<cloudbase-sites-cli> preview --status, <cloudbase-sites-cli> init, and the
other explicit commands below instead of assuming automatic startup.
If SessionStart reports that it skipped a non-empty non-Vite cwd, do not assume
the runtime is active. If a template is downloaded later through MCP
downloadTemplate, run <cloudbase-sites-cli> preview --status and then
<cloudbase-sites-cli> preview if no preview is running.
You only invoke a CLI verb when:
- User asks to create/build a new Sites app in an empty cwd →
cloudbase-sites init --start
- User explicitly says "stop the dev server" →
cloudbase-sites preview --stop
- User asks for the URL or "is it running" →
cloudbase-sites preview --status
- User wants to save a version →
cloudbase-sites save -m "<label>"
- User wants to deploy →
cloudbase-sites deploy (then bridge to manageApps)
- User wants to roll back →
cloudbase-sites rollback
When the user just walked into the conversation
Read the SessionStart status first. If it says the cwd is passive/empty,
do not assume a project exists. Wait for the user's first concrete Sites app
request, then run cloudbase-sites init --start.
For existing Vite projects, check preview state — read
<cwd>/.cloudbase-sites/preview.json or run
cloudbase-sites preview --status. If no preview is running, start it with
cloudbase-sites preview.
Tell the user the URL — surface internalUrl from the JSON. If the file
is missing after init/preview, inspect .cloudbase-sites/logs/.
Offer to open the preview. Ask: "要不要我用内置浏览器打开
预览一下?" If yes, use the host Browser / in-app browser tool to open
internalUrl. Do not use macOS open, and do not run browser interaction
tests unless the user explicitly asks you to test the UI.
DO NOT re-init / re-start. Calling init again will fail with code 10
(cwd no longer empty). Calling preview is idempotent and safe but
wastes a turn.
NEVER guess the port. It is NOT 5173/5174/5175 — the plugin uses
17173..17272. Always read the recorded port from preview.json.
Two-stage save → deploy workflow
Inspired by Codex Sites' saved version model:
- Save: label a git checkpoint.
cloudbase-sites save -m "<label>" runs
git init when needed, then git add -A && git commit && git tag version/<n> and appends to <cwd>/.cloudbase-sites/app.json.versions[].
No build, no deploy.
- Deploy: publish a saved version to a CloudApp.
cloudbase-sites deploy [--version <n>] (default: latest saved) builds
dist/ locally then emits nextAction telling you to call
manageApps({ action: "deployApp", serviceName: <stable from app.json>, filePath: cwd, buildPath: "dist", framework: "static", installCmd: "", buildCmd: "" }). The framework=static shape skips
remote install/build because we built locally.
- Record: after
manageApps succeeds and gives you the access URL,
call cloudbase-sites deploy --post --version <n> --access-url <url> --build-id <BuildId> [--version-name <VersionName>]. This appends to
app.json.deployments[], records CloudBase build metadata, tags git
deploy/<n>-<ts>, and returns finalUrl with a cache-busting query.
If the manageApps result includes BuildId, you MUST pass it to
--build-id; otherwise future build status and log queries cannot be
traced directly from the saved deployment.
- Rollback:
cloudbase-sites rollback [--to-version <n>] (default:
current production deploy). Stashes uncommitted edits, git reset --hard
to the version's commit, marks newer versions as rolled-back, and
restarts the dev server.
Why CloudApp (manageApps) not static hosting? Each CloudApp has its
own subdomain (*.webapps.tcloudbase.com); two vibe sessions on the same
env never collide. The stable siteName in app.json ensures re-deploys
preserve the URL.
Pre-flight: if manageApps fails with "no envId" / env-related error,
call envQuery({ action: "info" }). If multiple envs exist, ask the user
to pick. After binding, retry the deploy.
Proactive prompts (do not act unsolicited)
When you finish a user-requested feature (especially "make me a X app",
"build me a Y", "add Z feature"), end your reply by asking:
- Save? "要保存这一版吗?(下次能再调出来)" → if yes, run
cloudbase-sites save -m "<auto-generated label>".
- Deploy? "现在要部署看一下吗?(独立 URL,可分享)" → if yes, run the
two-stage deploy described above.
- Open preview? "要不要我用内置浏览器打开 预览一下?" — if yes,
use the host Browser / in-app browser tool to open
internalUrl. Only
click through interactions or run browser-driving verification after the
user explicitly asks for testing. Do NOT spawn playwright / agent-browser
by default.
- After successful deploy ask: "要我用 ui-design 能力进一步优化样式和体验吗?"
If yes, fetch
searchKnowledgeBase(mode="skill", skillName="ui-design")
and iterate on the design.
- After a verified successful deploy — at most once — ask: "要不要把这次
「一句话做出这个应用」的过程整理成可分享的素材?(脱敏的图文卡片 + 可粘贴文案)"
If yes, follow the
cloudbase-platform skill's
references/protocols/deployment-share.md (trigger boundaries, required
information, anonymization red lines, deliverable formats). If that skill is
not available in this environment, skip this step — do not improvise a share
flow from memory. Never follow up if declined; never publish on the user's
behalf.
Skip any of these when:
- The work was a bug fix or trivial refactor.
- The user already chose this option earlier in the session.
- The user explicitly said "don't deploy" / "no tests" / "no design changes".
Hard rules (also injected by SessionStart hook)
Never guess the preview URL. Always read preview.json or run
cloudbase-sites preview --status. Default port range is 17173..17272.
"Make me a X app" = X IS the homepage. When the user uses whole-house
language, REPLACE the content of src/pages/HomePage.tsx (or App.tsx
if no HomePage exists) with the new feature. Do NOT create a new
<TodoApp /> component and leave the original template welcome at /.
Only add a new route when the user explicitly says "add a X page".
UI work for NEW features requires a design specification first. Before
writing any .tsx/.css/.html, fetch
searchKnowledgeBase(mode="skill", skillName="ui-design"), output the
4-part spec (Aesthetic / Color / Typography / Layout), THEN write code.
The CloudBase template's CLAUDE.md "Existing Implementation First"
exemption applies only to bug fixes; new apps still need ui-design.
Never spawn npm run dev / vite / vite build yourself. Lifecycle
is owned by hooks + the cloudbase-sites CLI.
BaaS-first data persistence — detect the env type first. Before any
data-layer work, call envQuery({ action: "info" }) and branch on the
detected database backend:
| env type |
schema / RLS |
browser SDK |
domain skill |
PostgreSQL (RuntimeBackends.postgresql === true) |
managePgDatabase (versioned applyMigration) |
app.rdb() / app.storage.from() |
postgresql-development-cloudbase |
| NoSQL (document) |
writeNoSqlDatabaseStructure(action="createCollection") |
app.database() collections |
cloudbase-document-database-web-sdk |
Do NOT load cloudbase-document-database-web-sdk (or NoSQL APIs) for a PG
environment, and do NOT guess from the skill catalog — the catalog contains
both, only envQuery tells them apart. Reads/writes go through
@cloudbase/js-sdk from React/Vue code either way. Reach for cloud
functions only when (a) the logic cannot be expressed as security rules AND
(b) it needs server-side secrets or a third-party API AND (c) it's a
scheduled / background job. A Todo / Notes / Chat / Kanban app does NOT
need cloud functions.
Do not run browser tests by default. Verify reasonably (preview
healthy, no compile error in cloudbase-sites preview --status). Offer
to open the preview URL in the host Browser / in-app browser; ask again
before interaction testing.
Two-stage save → deploy. Don't deploy unsolicited. Don't bypass
cloudbase-sites deploy with your own pnpm build + manageApps call —
you'd lose version metadata, snapshot, deploy history, and the stable
siteName.
Icons come from lucide-react — preinstalled, never hand-installed.
cloudbase-sites init injects lucide-react (react) / lucide-vue-next
(vue) into the scaffold's package.json before its single install step.
Import icons directly (import { Heart } from "lucide-react"). Do NOT run
a package-install command just to add icons — sandboxed installs during
generation are a known failure point — and do NOT hand-write inline SVG
paths when a lucide icon exists.
Fill VITE_PUBLISHABLE_KEY automatically — never ask the user. The
template's src/utils/cloudbase.ts reads it from .env.local; new envs
have no publishable key by default. After init: call
queryAppAuth({ action: "getPublishableKey" }); if empty, call
manageAppAuth({ action: "ensurePublishableKey" }); then write
VITE_PUBLISHABLE_KEY=<key> into .env.local. This key cannot be
skipped — it is the data-plane app credential attached to every browser
request, including the login request itself and anonymous reads — but
the user should never fill it by hand.
Hard rules — always parse CLI stdout as JSON
The first stdout line of every cloudbase-sites <verb> invocation is a
single JSON object. The stderr [cloudbase-sites] ... line is for humans —
do not parse it. On error the JSON is { ok: false, code: <int>, message, hint?, logPath? }. When a script reports failure, surface logPath to the
user instead of guessing the cause.
Error codes from the CLI
| code |
meaning |
recovery |
| 1 |
generic failure |
check the message and nextActions if present |
| 2 |
not a Vite project (or vite binary missing) |
pnpm install then retry |
| 3 |
port pool exhausted in 17173..17272 |
cloudbase-sites preview --stop for stale ones, or pass --port |
| 4 |
dev server failed health check in 30s |
read logPath; usually a build error in user code |
| 5 |
no preview is running (status / stop) |
start one with cloudbase-sites preview |
| 6 |
stop failed (process refused SIGKILL) |
inspect the PID manually with ps; very rare |
| 7 |
build failed (cloudbase-sites deploy) |
inspect build output; fix code, retry |
| 8 |
dist/ missing or empty after build |
confirm scripts.build runs vite build; rerun |
| 9 |
cwd in danger blacklist (init) |
cd to a real project directory first |
| 10 |
cwd not empty (init) |
move conflicting files; only .git/.gitignore/README/LICENSE/.cloudbase-sites are tolerated |
| 11 |
template download failed |
check internet; URL is static.cloudbase.net/cloudbase-examples/... |
| 12 |
template extract failed |
install unzip |
| 13 |
dependency install failed |
check terminal output |
| 14 |
version not found |
run cloudbase-sites versions to list |
| 15 |
rollback failed |
check git state |
State files
| Path |
Purpose |
<cwd>/.cloudbase-sites/preview.json |
dev server PID/port/URL/framework |
<cwd>/.cloudbase-sites/app.json |
siteName + versions[] + deployments[] + currentVersion + currentDeploy |
<cwd>/.cloudbase-sites/logs/preview-<ts>.log |
Vite stdout/stderr |
<cwd>/.cloudbase-sites/logs/hook-session-start.log |
SessionStart hook trace |
<cwd>/.cloudbase-sites/logs/hook-restart.log |
PostToolUse restart trail |
~/.cloudbase-sites/registry.json |
global supervisor's view of all cwds |
~/.cloudbase-sites/supervisor.json |
global supervisor PID + uptime |
~/.cloudbase-sites/supervisor.log |
supervisor stdout/stderr |
What this skill is NOT
- It is not a session manager. There is no sessionId at the skill level.
There is only cwd. (The supervisor's
registry.json does track cwds
globally, but for self-healing — not as a user-facing concept.)
- It is not a reverse proxy. If the host is on a public-facing server
and the user needs
<host>:8080/s/<sid>/ style routing, that's a separate
optional component (cloudbase-sites-proxy, future work) — out of scope here.
- It is not a CloudBase auth/database guide. For those, fetch the
corresponding CloudBase domain skill via
searchKnowledgeBase(mode="skill", skillName=...).
- It is not a UI design guide. For visual decisions, fetch
searchKnowledgeBase(mode="skill", skillName="ui-design").
1---2name: cloudbase-sites-runtime3description: Use when the user wants to develop, run, preview, save, deploy, or roll back a CloudBase Web app in this conversation as a Lovable/Codex-Sites-like vibe- coding session — i.e. any request that maps to "spin up a React+Vite project, see it live in the browser, iterate, save versions, deploy". Activate ONLY for browser-rendered Web projects based on the CloudBase official React (or Vue) + Vite template. Do NOT activate for: WeChat/Alipay mini-program, React Native / Flutter / Electron, pure cloud functions / CloudRun backends, or Next.js / Nuxt / Astro / Remix / SvelteKit (those frameworks are explicitly out of scope).4---56# CloudBase Sites Runtime78This skill orchestrates a **single working directory = single project** flow9for CloudBase Web apps. The cwd itself is the workspace; we do not manage10cross-cwd state or session IDs at the skill level.1112This runtime is shared by the Codex, Claude Code, and CodeBuddy plugin13surfaces. The CLI and CloudBase MCP workflows are the source of truth. Some14hosts also run bundled lifecycle hooks that start previews or inject compact15rules at session start; if hooks are unavailable, disabled, or not yet trusted,16use the explicit CLI commands in this skill.1718## Activation contract1920### Use this skill when2122- The user says "build me a website / app", "I want to make a landing page",23 "create a React app and let me preview", "deploy this to CloudBase",24 "save this version", "roll back to v1", or similar.25- The current cwd looks like a CloudBase + Vite project (has `package.json`26 with `vite` + `react` or `vue`).27- The user is running this conversation inside Codex, Claude Code, CodeBuddy,28 or a compatible host with the `cloudbase-sites` plugin enabled —29 `cloudbase-mcp` is registered and the `cloudbase-sites` binary is either on30 PATH or available from the plugin root's `bin/cloudbase-sites`.3132### Do NOT use this skill when3334- It's a mini-program project — route to mini-program guidance instead.35- It's a native app project — route to http-api guidance.36- It's a backend-only project — route to cloud-functions / cloudrun guidance.37- The framework is Next/Nuxt/Astro/Remix — politely tell the user this skill38 only covers Vite-based React/Vue apps and stop. Do NOT try to adapt the39 scripts to those frameworks.4041## What this skill orchestrates — three layers4243### 1. CloudBase MCP tools (provided by `cloudbase-mcp`, registered via plugin's `.mcp.json`)4445These are the only tools that produce CloudBase side effects. Highlights:4647- `downloadTemplate({ template: "react" | "vue", ide })` — pull official template48- `envQuery({ action: "info" })` + `auth({ action: "set_env", envId })` — bind env49- `manageApps({ action: "deployApp", ... })` — deploy to CloudApp (independent subdomain)50- `envDomainManagement({ action: "create", domains })` — whitelist dev origin for CORS51- `searchKnowledgeBase({ mode: "skill", skillName: "<name>" })` — fetch CloudBase domain skills (see below)5253For all CloudBase operations beyond the dev-server lifecycle (auth, db,54storage, ai), fetch the corresponding CloudBase domain skill via55`searchKnowledgeBase(mode="skill", skillName=...)`. Common ones:5657- `ui-design` UI design spec (mandatory before new UI work)58- `web-development` Web project conventions59- `auth-tool-cloudbase` provider config (management-side)60- `auth-web-cloudbase` Web SDK auth client code61- `postgresql-development-cloudbase` PG mode schema/RLS/`app.rdb()` (PG envs)62- `cloudbase-document-database-web-sdk` document database Web SDK63- `cloud-storage-web` cloud storage Web SDK64- `relational-database-web-cloudbase` MySQL Web SDK65- `cloudbase-platform` platform overview / console links6667These are **NOT Claude Code native skills** and are NOT bundled with this68plugin. They live inside cloudbase-mcp and are fetched on demand. When this69file (or the injected RULES_BLOCK) says "调 ui-design skill" or "follow the70auth-tool skill", that means: call `searchKnowledgeBase(mode="skill",71skillName="<that-name>")` and apply the returned content.7273### 2. The `cloudbase-sites` CLI (provided by this plugin's `bin/` directory)7475First resolve the CLI path:76771. Try `command -v cloudbase-sites`.782. If that fails and the host exposes `CODEX_PLUGIN_ROOT`, use79 `$CODEX_PLUGIN_ROOT/bin/cloudbase-sites`.803. If that fails and the host exposes `CLAUDE_PLUGIN_ROOT`, use81 `$CLAUDE_PLUGIN_ROOT/bin/cloudbase-sites`.824. If SessionStart injected an absolute CLI path, use that path.8384Do not assume Codex has injected the plugin `bin/` directory into PATH.8586Single binary, multiple subcommands. Use these — and ONLY these — for the87dev-server / version / deploy lifecycle:8889- `cloudbase-sites init --start` — scaffold from empty cwd and start preview when the user explicitly wants a Sites app90- `cloudbase-sites preview` — daemonize Vite for an existing Vite project91- `cloudbase-sites preview --status [--quiet]` — JSON status / exit code92- `cloudbase-sites preview --restart` / `--stop [--force]`93- `cloudbase-sites save -m "<label>"` — create a saved version94- `cloudbase-sites versions` — list saved versions + deploy status95- `cloudbase-sites deploy [--version <n>]` — deploy a saved version (Phase 1: emit nextAction)96- `cloudbase-sites deploy --post --version <n> --access-url <url> [--build-id <BuildId>] [--version-name <VersionName>]` — record deploy97- `cloudbase-sites rollback [--to-version <n>]` — revert to a saved version98- `cloudbase-sites supervisor status|list|heal|reload|start|stop`99100Never invent `npm run dev` / `vite` / `vite build` invocations. The CLI101handles host=0.0.0.0 forcing, port allocation (17173..17272), daemonization,102base path injection, version metadata, and deploy history.103104### 3. Standard tools (Bash, git, Edit, Write)105106Use for editing files. The plugin's PostToolUse hook handles automatic107restart on config-file edits — you don't need to manage that.108109## Lifecycle hooks and fallback110111**Do NOT invoke `cloudbase-sites init` or `cloudbase-sites preview`112proactively in your first message just because the plugin is installed.**113SessionStart is intentionally passive for empty directories so the plugin does114not interfere with unrelated sessions. A UserPromptSubmit hook may initialize115after the first user message, but only when deterministic Chinese/English116intent rules detect an explicit Sites/Web-app creation request. By the time you117read the user's first prompt:118119- If the cwd was an existing Vite project: dev server is up (or installing).120- If the cwd was empty: no files were downloaded by SessionStart. If the first121 prompt clearly asked to build/create a Sites app, UserPromptSubmit may have122 started `init --start`; otherwise initialize only after the user asks.123- If the cwd is a non-Vite / blacklisted project: hook stayed silent.124125Codex supports bundled plugin hooks, but non-managed command hooks may require126the user to review and trust them before they run. If Codex hooks have not run,127resolve the CLI path as described above, then fall back to128`<cloudbase-sites-cli> preview --status`, `<cloudbase-sites-cli> init`, and the129other explicit commands below instead of assuming automatic startup.130131If SessionStart reports that it skipped a non-empty non-Vite cwd, do not assume132the runtime is active. If a template is downloaded later through MCP133`downloadTemplate`, run `<cloudbase-sites-cli> preview --status` and then134`<cloudbase-sites-cli> preview` if no preview is running.135136You only invoke a CLI verb when:137138- User asks to create/build a new Sites app in an empty cwd → `cloudbase-sites init --start`139- User explicitly says "stop the dev server" → `cloudbase-sites preview --stop`140- User asks for the URL or "is it running" → `cloudbase-sites preview --status`141- User wants to save a version → `cloudbase-sites save -m "<label>"`142- User wants to deploy → `cloudbase-sites deploy` (then bridge to `manageApps`)143- User wants to roll back → `cloudbase-sites rollback`144145## When the user just walked into the conversation1461471. **Read the SessionStart status first.** If it says the cwd is passive/empty,148 do not assume a project exists. Wait for the user's first concrete Sites app149 request, then run `cloudbase-sites init --start`.1501512. **For existing Vite projects, check preview state** — read152 `<cwd>/.cloudbase-sites/preview.json` or run153 `cloudbase-sites preview --status`. If no preview is running, start it with154 `cloudbase-sites preview`.1551563. **Tell the user the URL** — surface `internalUrl` from the JSON. If the file157 is missing after init/preview, inspect `.cloudbase-sites/logs/`.1581594. **Offer to open the preview.** Ask: "要不要我用内置浏览器打开 <URL>160 预览一下?" If yes, use the host Browser / in-app browser tool to open161 `internalUrl`. Do not use macOS `open`, and do not run browser interaction162 tests unless the user explicitly asks you to test the UI.1631645. **DO NOT** re-init / re-start. Calling `init` again will fail with code 10165 (cwd no longer empty). Calling `preview` is idempotent and safe but166 wastes a turn.1671686. **NEVER guess the port.** It is NOT 5173/5174/5175 — the plugin uses169 17173..17272. Always read the recorded port from `preview.json`.170171## Two-stage save → deploy workflow172173Inspired by Codex Sites' `saved version` model:174175- **Save:** label a git checkpoint. `cloudbase-sites save -m "<label>"` runs176 `git init` when needed, then `git add -A && git commit && git tag177 version/<n>` and appends to `<cwd>/.cloudbase-sites/app.json.versions[]`.178 No build, no deploy.179- **Deploy:** publish a saved version to a CloudApp.180 `cloudbase-sites deploy [--version <n>]` (default: latest saved) builds181 `dist/` locally then emits `nextAction` telling you to call182 `manageApps({ action: "deployApp", serviceName: <stable from app.json>,183 filePath: cwd, buildPath: "dist", framework: "static",184 installCmd: "", buildCmd: "" })`. The `framework=static` shape skips185 remote install/build because we built locally.186- **Record:** after `manageApps` succeeds and gives you the access URL,187 call `cloudbase-sites deploy --post --version <n> --access-url <url>188 --build-id <BuildId> [--version-name <VersionName>]`. This appends to189 `app.json.deployments[]`, records CloudBase build metadata, tags git190 `deploy/<n>-<ts>`, and returns `finalUrl` with a cache-busting query.191 If the `manageApps` result includes `BuildId`, you MUST pass it to192 `--build-id`; otherwise future build status and log queries cannot be193 traced directly from the saved deployment.194- **Rollback:** `cloudbase-sites rollback [--to-version <n>]` (default:195 current production deploy). Stashes uncommitted edits, `git reset --hard`196 to the version's commit, marks newer versions as `rolled-back`, and197 restarts the dev server.198199**Why CloudApp (`manageApps`) not static hosting?** Each CloudApp has its200own subdomain (`*.webapps.tcloudbase.com`); two vibe sessions on the same201env never collide. The stable `siteName` in `app.json` ensures re-deploys202preserve the URL.203204**Pre-flight:** if `manageApps` fails with "no envId" / env-related error,205call `envQuery({ action: "info" })`. If multiple envs exist, ask the user206to pick. After binding, retry the deploy.207208## Proactive prompts (do not act unsolicited)209210When you finish a user-requested feature (especially "make me a X app",211"build me a Y", "add Z feature"), end your reply by asking:2122131. **Save?** "要保存这一版吗?(下次能再调出来)" → if yes, run214 `cloudbase-sites save -m "<auto-generated label>"`.2152. **Deploy?** "现在要部署看一下吗?(独立 URL,可分享)" → if yes, run the216 two-stage deploy described above.2173. **Open preview?** "要不要我用内置浏览器打开 <URL> 预览一下?" — if yes,218 use the host Browser / in-app browser tool to open `internalUrl`. Only219 click through interactions or run browser-driving verification after the220 user explicitly asks for testing. Do NOT spawn playwright / agent-browser221 by default.2224. **After successful deploy** ask: "要我用 ui-design 能力进一步优化样式和体验吗?"223 If yes, fetch `searchKnowledgeBase(mode="skill", skillName="ui-design")`224 and iterate on the design.2255. **After a verified successful deploy — at most once** — ask: "要不要把这次226 「一句话做出这个应用」的过程整理成可分享的素材?(脱敏的图文卡片 + 可粘贴文案)"227 If yes, follow the `cloudbase-platform` skill's228 `references/protocols/deployment-share.md` (trigger boundaries, required229 information, anonymization red lines, deliverable formats). If that skill is230 not available in this environment, skip this step — do not improvise a share231 flow from memory. Never follow up if declined; never publish on the user's232 behalf.233234Skip any of these when:235- The work was a bug fix or trivial refactor.236- The user already chose this option earlier in the session.237- The user explicitly said "don't deploy" / "no tests" / "no design changes".238239## Hard rules (also injected by SessionStart hook)2402411. **Never guess the preview URL.** Always read `preview.json` or run242 `cloudbase-sites preview --status`. Default port range is 17173..17272.2432442. **"Make me a X app" = X IS the homepage.** When the user uses whole-house245 language, REPLACE the content of `src/pages/HomePage.tsx` (or `App.tsx`246 if no HomePage exists) with the new feature. Do NOT create a new247 `<TodoApp />` component and leave the original template welcome at `/`.248 Only add a new route when the user explicitly says "add a X page".2492503. **UI work for NEW features requires a design specification first.** Before251 writing any `.tsx`/`.css`/`.html`, fetch252 `searchKnowledgeBase(mode="skill", skillName="ui-design")`, output the253 4-part spec (Aesthetic / Color / Typography / Layout), THEN write code.254 The CloudBase template's CLAUDE.md "Existing Implementation First"255 exemption applies only to bug fixes; new apps still need ui-design.2562574. **Never spawn `npm run dev` / `vite` / `vite build` yourself.** Lifecycle258 is owned by hooks + the `cloudbase-sites` CLI.2592605. **BaaS-first data persistence — detect the env type first.** Before any261 data-layer work, call `envQuery({ action: "info" })` and branch on the262 detected database backend:263264 | env type | schema / RLS | browser SDK | domain skill |265 |---|---|---|---|266 | PostgreSQL (`RuntimeBackends.postgresql === true`) | `managePgDatabase` (versioned `applyMigration`) | `app.rdb()` / `app.storage.from()` | `postgresql-development-cloudbase` |267 | NoSQL (document) | `writeNoSqlDatabaseStructure(action="createCollection")` | `app.database()` collections | `cloudbase-document-database-web-sdk` |268269 Do NOT load `cloudbase-document-database-web-sdk` (or NoSQL APIs) for a PG270 environment, and do NOT guess from the skill catalog — the catalog contains271 both, only `envQuery` tells them apart. Reads/writes go through272 `@cloudbase/js-sdk` from React/Vue code either way. Reach for cloud273 functions only when (a) the logic cannot be expressed as security rules AND274 (b) it needs server-side secrets or a third-party API AND (c) it's a275 scheduled / background job. A Todo / Notes / Chat / Kanban app does NOT276 need cloud functions.2772786. **Do not run browser tests by default.** Verify reasonably (preview279 healthy, no compile error in `cloudbase-sites preview --status`). Offer280 to open the preview URL in the host Browser / in-app browser; ask again281 before interaction testing.2822837. **Two-stage save → deploy.** Don't deploy unsolicited. Don't bypass284 `cloudbase-sites deploy` with your own `pnpm build` + `manageApps` call —285 you'd lose version metadata, snapshot, deploy history, and the stable286 siteName.2872888. **Icons come from `lucide-react` — preinstalled, never hand-installed.**289 `cloudbase-sites init` injects `lucide-react` (react) / `lucide-vue-next`290 (vue) into the scaffold's `package.json` before its single install step.291 Import icons directly (`import { Heart } from "lucide-react"`). Do NOT run292 a package-install command just to add icons — sandboxed installs during293 generation are a known failure point — and do NOT hand-write inline SVG294 paths when a lucide icon exists.2952969. **Fill `VITE_PUBLISHABLE_KEY` automatically — never ask the user.** The297 template's `src/utils/cloudbase.ts` reads it from `.env.local`; new envs298 have no publishable key by default. After init: call299 `queryAppAuth({ action: "getPublishableKey" })`; if empty, call300 `manageAppAuth({ action: "ensurePublishableKey" })`; then write301 `VITE_PUBLISHABLE_KEY=<key>` into `.env.local`. This key cannot be302 skipped — it is the data-plane app credential attached to every browser303 request, including the login request itself and anonymous reads — but304 the user should never fill it by hand.305306## Hard rules — always parse CLI stdout as JSON307308The first stdout line of every `cloudbase-sites <verb>` invocation is a309single JSON object. The stderr `[cloudbase-sites] ...` line is for humans —310do not parse it. On error the JSON is `{ ok: false, code: <int>, message,311hint?, logPath? }`. When a script reports failure, surface `logPath` to the312user instead of guessing the cause.313314## Error codes from the CLI315316| code | meaning | recovery |317|---|---|---|318| 1 | generic failure | check the message and `nextActions` if present |319| 2 | not a Vite project (or `vite` binary missing) | `pnpm install` then retry |320| 3 | port pool exhausted in 17173..17272 | `cloudbase-sites preview --stop` for stale ones, or pass `--port` |321| 4 | dev server failed health check in 30s | read `logPath`; usually a build error in user code |322| 5 | no preview is running (status / stop) | start one with `cloudbase-sites preview` |323| 6 | stop failed (process refused SIGKILL) | inspect the PID manually with `ps`; very rare |324| 7 | build failed (`cloudbase-sites deploy`) | inspect build output; fix code, retry |325| 8 | `dist/` missing or empty after build | confirm `scripts.build` runs `vite build`; rerun |326| 9 | cwd in danger blacklist (`init`) | cd to a real project directory first |327| 10 | cwd not empty (`init`) | move conflicting files; only `.git`/`.gitignore`/README/LICENSE/.cloudbase-sites are tolerated |328| 11 | template download failed | check internet; URL is `static.cloudbase.net/cloudbase-examples/...` |329| 12 | template extract failed | install `unzip` |330| 13 | dependency install failed | check terminal output |331| 14 | version not found | run `cloudbase-sites versions` to list |332| 15 | rollback failed | check git state |333334## State files335336| Path | Purpose |337|---|---|338| `<cwd>/.cloudbase-sites/preview.json` | dev server PID/port/URL/framework |339| `<cwd>/.cloudbase-sites/app.json` | siteName + versions[] + deployments[] + currentVersion + currentDeploy |340| `<cwd>/.cloudbase-sites/logs/preview-<ts>.log` | Vite stdout/stderr |341| `<cwd>/.cloudbase-sites/logs/hook-session-start.log` | SessionStart hook trace |342| `<cwd>/.cloudbase-sites/logs/hook-restart.log` | PostToolUse restart trail |343| `~/.cloudbase-sites/registry.json` | global supervisor's view of all cwds |344| `~/.cloudbase-sites/supervisor.json` | global supervisor PID + uptime |345| `~/.cloudbase-sites/supervisor.log` | supervisor stdout/stderr |346347## What this skill is NOT348349- It is **not** a session manager. There is no sessionId at the skill level.350 There is only cwd. (The supervisor's `registry.json` does track cwds351 globally, but for self-healing — not as a user-facing concept.)352- It is **not** a reverse proxy. If the host is on a public-facing server353 and the user needs `<host>:8080/s/<sid>/` style routing, that's a separate354 optional component (`cloudbase-sites-proxy`, future work) — out of scope here.355- It is **not** a CloudBase auth/database guide. For those, fetch the356 corresponding CloudBase domain skill via357 `searchKnowledgeBase(mode="skill", skillName=...)`.358- It is **not** a UI design guide. For visual decisions, fetch359 `searchKnowledgeBase(mode="skill", skillName="ui-design")`.