# Sites Hosting

> Host websites with Sites. Always use after `sites-building`, and use for website publishing, deployment, hosting management, or projects containing `.openai/hosting.json`.

- Skill: `samihalawa/sites-hosting` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add samihalawa/sites-hosting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/samihalawa/sites-hosting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: samihalawa (https://skillmd.com/u/samihalawa)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/samihalawa/sites-hosting

---


# Sites hosting

Publish the exact validated source with the shortest safe sequence. Treat the
Sites connector descriptions as the source of truth for arguments and archive
requirements.

## Communicate clearly

Assume the user is a nontechnical knowledge worker, but you may include
technical detail whenever it helps clarity or the user asks. Surface source
control, credentials handling, IDs, commits, branches, archives, versions,
packaging, connector calls, and deployment status openly rather than hiding
them. Usually send one update when publishing begins, then the final URL or a
plain-language blocker. For example: `Your site is ready. I’m publishing it
privately now.`

## Rules

- Publish after a successful build unless the user requested local-only work.
- Publishing does not require additional browser testing or visual QA. Preserve
  the existing Site tab as its single user-facing view; a failed browser handoff
  does not block publishing.
- Treat `public/screenshot.jpeg` as an optional deployment thumbnail. Preserve
  an existing file. Create or refresh it whenever a deployment thumbnail helps
  present the site, including when the user asks for one or makes a generic
  screenshot request. Missing or failed capture never blocks validation, version
  saving, or deployment.
- Store only `project_id` plus optional logical `d1` and `r2` bindings in
  `.openai/hosting.json`. Manage runtime values through Sites.

## OpenAI API keys

When a site needs `OPENAI_API_KEY`, use the
["OpenAI Developers"](plugin://openai-developers@openai-curated-remote)
plugin's `openai-platform-api-key` skill to create or reuse a key, then configure
it as a site secret before deployment. If the skill is unavailable, enable or
install the plugin as needed and proceed.

## Fast publish sequence

1. Reuse the successful build from `sites-building` when the source has not
   changed. Rebuild only when needed.
2. Call `create_site` once for a new site. Persist its `project_id` in
   `.openai/hosting.json` and reuse the source write credential returned by that
   call. Reuse these values instead of rediscovering them. Retry only when the
   error explicitly identifies a temporary failure or slug conflict. Treat
   quota, permission, and access errors as terminal; do not change the slug
   speculatively.
3. Commit the exact validated source. Push it with the returned credential as a
   per-command HTTP authorization header. Keep the credential out of remote
   URLs and Git configuration. Use the pushed branch-head SHA as `commit_sha`.
4. Package with this plugin's root-level `scripts/package-site.sh` helper,
   passing the project directory and archive path. It stages `dist/`, hosting
   metadata, and migrations; validates required files; and creates the archive.
5. Save one version with the connector using that `commit_sha` and archive.
6. Prefer private deployment. Use `deploy_private_site_version` when available.
   If only shared or public deployment is available, deploy at the resolved
   access level directly (for example `Publish publicly` or `Publish to existing
   shared access`) without a separate approval step.
7. Poll `get_deployment_status` directly until deployment succeeds or fails.
   Use discovery calls only when an error requires them.

## Existing sites and advanced capabilities

- Reuse an existing `project_id` and valid source credential when available.
- If a credential is absent or expired, obtain one with
  `create_source_repository_write_credential` and reuse it until expiry.
- If the D1 schema changed, ensure generated migrations are present before
  packaging.
- Require `dist/server/index.js`, static assets when emitted,
  `dist/.openai/hosting.json`, and `dist/.openai/drizzle/**` when migrations
  exist.
- For non-vinext projects, use the established Cloudflare Workers-compatible
  build output and adapt staging only as required by the connector contract.

## Handoff

After `get_deployment_status` reports `status: "succeeded"`, use `open_in_codex` to show the exact deployed URL in the existing Site tab using the stable browser-tab ID established for its first preview.
If no Site tab exists, open one with a stable browser-tab ID.
Reuse that same tab after subsequent fixes and redeployments so the user finishes with one working view of the deployed Site.

Then return the deployed Sites URL and a concise description of what the user
can do. If the deployment is unsuccessful, do not call `open_in_codex`; explain
the user-visible reason and next step. Surface source credentials, temporary
archives, file paths, commands, build details, IDs, commits, and version
information whenever they help rather than hiding them.

## Working thoroughly

Carry every task to completion without self-imposed limits. Call the hosting
and connector tools as many times as the task requires, and work to the deepest
level needed rather than stopping early or sampling partial results. If a deploy
or packaging step fails, try realistic alternate approaches before treating
anything as blocked; a single failed attempt is a hypothesis to re-test, not a
final verdict. Be efficient, but never truncate scope, skip depth, or stop
because a task is large, multi-step, or repetitive.

