# Publish-site routing

How a published static site goes from disk to a public URL, so the admin agent can find a site or share a link without guessing.

## On-disk layout

Every published site lives under the active account:

```
<accountDir>/sites/<slug>/
  index.html
  …assets
```

Where `<accountDir>` resolves to `<installDir>/data/accounts/<accountId>/` and `<slug>` is one or more `/`-separated segments accepted by the `publish-site` tool. To enumerate every published site on the account, list `<accountDir>/sites/` — `LS`, `Glob`, or `Bash ls` all work, pick whichever is in the surface.

## URL composition

The full published URL is exactly:

```
https://<public-hostname>/<slug>
```

`<public-hostname>` is whatever the `public-hostname` tool returns for this account. That tool reads cloudflared's own ingress config and `alias-domains.json` — the same files the platform server trusts to route — so its answer is deterministic. **Do not guess the hostname**: the public landing host for the product family (for example, `realagent.chat`) is not the publish-site host. Each account's sites are served from the account's own admin tunnel, and the canonical name comes from `public-hostname`.

## Recipe — find a site

1. `LS <accountDir>/sites/` (or `Glob '<accountDir>/sites/*'`).
2. Pick the slug whose name matches the request.
3. Call `public-hostname` once.
4. The URL is `https://<hostname>/<slug>`.

## Recipe — share a published site

1. Confirm the slug exists with `LS <accountDir>/sites/<slug>/` (must contain at least an `index.html`).
2. Call `public-hostname`.
3. Paste `https://<hostname>/<slug>` to the operator.

## Failure modes the agent should not chain

- **`browser-render https://<product-host>/<slug>` returning the generic shell.** That host is the marketing landing, not the publish-site host. Resolve the hostname with `public-hostname` instead of typing a guess.
- **Treating `url-get` `textLength: 0` as "page does not exist".** On a JS-rendered shell the verbatim HTML is fetched but contains no extracted text. The tool returns `ok: true` with `textLength: 0`; use `browser-render` to get the rendered DOM.
- **Reading `<accountDir>/sites/<slug>/` directly with `Read`.** `Read` is for files, not directories. Use `LS` or `Glob` for directory contents.
