# Apps and databases on ghosty.page

> Your agent publishes full-stack apps (Express, Next, React Router…) at <slug>.ghosty.page, each with its own libSQL database, its real state through site_status and checkpoints to take the database back to an earlier point.

URL: https://www.ghosty.studio/en/docs/apps

Your agent publishes full-stack apps (Express, Next, React Router…) at `<slug>.ghosty.page`. You need no hosting account and no keys: ask for it in the chat and the agent builds it, publishes it and gives you the link.

## Publish an app

The agent uses the `site_publish` tool (from code, the SDK: `publishSite({ title, app: { dir, repo? } })`).

- **Blue/green deploy.** The new version is built on the side and only goes live once it is ready. If the build fails, the previous version keeps serving.
- **Many apps per account.** An account can have several apps and several sites. The agent lists them all with `site_status` and `todas: true`.
- **Answer with evidence.** `site_publish` returns `aplicado` and `verificado`: the HTTP status and the real `<title>` read from the live link. The agent only says "done" with that evidence.

## With your GitHub repo

With `repo`, the code lives in your GitHub. Each push to the main branch of **that** app's repo publishes it again in 1–3 minutes. In any other repo, the agent works with a branch and a PR.

## Real state: `site_status`

`site_status` is the platform's truth about each app:

- The app's box (2 vCPU / 2 GB) and whether it is awake.
- The commit being served and the one being built ("redeploy in progress").
- The full error of the last failed build (the previous version keeps serving).
- The database and its tables.
- The **names** of the environment variables (never their values).
- The expiry date.
- With `log: true`, also the tail of the build log and the process log.

## Each app's database

Each app has its own libSQL database, `app-<slug>`:

- It reaches the app in `DATABASE_URL` and `DATABASE_AUTH_TOKEN` (also with the `TURSO_*` aliases).
- It survives every new publish.
- It shows up in [/app/dbs](https://www.ghosty.studio/app/dbs).
- The agent that published the app reads and writes it with `db_select` and `db_exec`.

## Checkpoints: take the database back to an earlier point

Before the first write of each turn to any database, the platform saves a checkpoint.

- `db_checkpoints {base}` lists the checkpoints: time, reason and how many rows each table had.
- `db_restore {base, checkpoint}` takes the database back to that point, after you approve it.
- Restoring first saves another checkpoint, so it can be undone too.
- The last 30 per database or the ones from the last 14 days are kept.
- Very large databases (over 50 MB) get no checkpoint, and the agent tells you before writing.

Example:

> **You:** Load the 40 catalog products I sent you into production.
>
> **Agent:** Done: 40 new rows in `productos` of `app-tienda-luna`. A checkpoint was saved before writing (12:04, 0 products).
>
> **You:** Wrong file, undo it.
>
> **Agent:** I'll take `app-tienda-luna` back to the 12:04 checkpoint (0 products). Do you approve?
>
> **You:** Yes.
>
> **Agent:** Done. `productos` has 0 rows again. I saved another checkpoint before restoring, in case you want the 40 back.

Also from other places:

| Where | How |
|---|---|
| Screen | `/app/dbs/<id>` → **Checkpoints** → **Go back to this point** |
| API | `GET /api/v2/agents/{id}/dbs/{db}/checkpoints` lists; `POST` with `{ "checkpointId": "..." }` restores |
| CLI | `ghosty dbs checkpoints <db>` and `ghosty dbs restore <db> <id>` |

## Environment variables

`site_env` (in the SDK, `setSiteEnv(slug, { set, unset })`) adds or removes variables and restarts the app without rebuilding it. They are stored encrypted and never go to the repo.

## Free plan and Pinned sites

Apps follow the same rule as sites: on the Free plan they pause after 30 days without changes. **Pinned sites** ($49 USD a year, includes up to 3 sites) keeps them published. Details in [Sites](/en/docs/cli/commands#sites).
