# c-ray docs

Documentation for [c-ray](https://c-ray.ai/), which builds real web apps from a
conversation. The rendered version of this page is at https://c-ray.ai/docs.

## Publishing

### Publishing your app

Every app you build is running **twice**: as a private draft only you can open,
and — once you publish — as the live app everyone else gets.

| | Draft | Live |
| --- | --- | --- |
| Who can open it | only you (sign-in protected) | anyone with the link |
| When it changes | every time you ask for a change | only when you publish |

They are two separate installations, each with its own data: accounts, entries
and uploads made in your draft are not in the live app, and the people using
your live app are not affected by anything you try out in the draft.

#### Publishing

Publishing takes the version your draft is on right now and makes it the live
one. Live then stays on exactly that version until you publish again.

- **On a computer** — the newest entry in the history panel carries a
  **Publish** button.
- **On a phone** — hold the chat bubble and slide **right** (see "The chat
  bubble" below); the newest entry under **Options → History** carries the same
  button.

Both ask you to confirm first, and both do the same thing. If Publish is greyed
out, one of these is why: the current version hasn't finished building; your
draft and live are already the same version, so the button comes back with your
next change; or you built this app without an account, and it wants you to
create one first — the app and its history come with you.

#### The first publish

The live app starts **empty** — its database is its own. If your app asks for a
registration code at sign-up (see "Sign-up and registration codes" below), that
code is in the publish dialog: open the live app right after publishing and
create your account there, before you share the link.

Your app's public address is shown with a copy button the moment it goes live —
it looks like `your-app-live.<the c-ray platform apex>`. To use a domain of your
own instead, see "Pointing your DNS" below.

#### Going back to an earlier version

- **On a computer** — every entry in the history panel carries a **Restore**
  button.
- **On a phone** — **History** in the **Options** card (hold the bubble, slide
  left) opens the same list, newest version first, each one with its own
  **Restore**.

Restoring puts your draft back on exactly that version. Two things to know
before you do it — the dialog says both, every time:

- **Everything saved inside the draft app is cleared** — accounts, entries and
  uploads start over empty.
- Your live app keeps running, unchanged, on whatever you last published.

Publishing sets a floor under this: the version you publish becomes the oldest
one you can return to, and anything before it can no longer be restored. Live
only ever moves forward.

#### Taking your app offline

A published app can be pulled back without being deleted: visitors get a
friendly "coming soon" page instead, and nothing about it says the app was ever
live. Your app keeps running, its data is untouched, and bringing it back online
restores it exactly as it was — as does publishing a new version, which always
means "make this public".

- **On a computer** — the strip above the live view.
- **On a phone** — the **Options** card (hold the bubble, slide left). While the
  app is offline, the way back is also on the badge covering the screen.

Going offline can take a minute to reach everyone.

## Accounts in your app

### Sign-up and registration codes

Apps you build can have accounts of their own — the people who sign in to *your*
app. They live in your app's own database and have nothing to do with your c-ray
account: signing in here never signs you in there.

When an app first needs accounts, the agent asks two things in the chat. Who can
**see** what — only their own entries, one shared set for a group, or anyone at
all — and who can **sign up**. They are separate questions, and the second one is
this page.

#### Who can sign up

- **Only people you let in** — sign-up asks for a code, and there is no way
  around it. The right answer whenever a known group writes to the app: a family
  list, a club board, a shop's back office, a blog anyone may read but only you
  post to.
- **Anyone** — open sign-up, for apps where taking part in public is the point:
  a forum, public comments, a community wiki.

Say which you want in your own words ("only people I invite can sign up"). If
you don't, the agent asks rather than guessing — "anyone can read it" and
"anyone can create an account" are very different apps, and the second one is
hard to take back once strangers have signed up.

#### The registration code

An app with closed sign-up carries one **registration code**, generated for it
when the agent closes sign-up. It is not something you choose or can look up
elsewhere — it is built into the app.

- **Once in your draft, once in the live app.** The two run separate databases
  and both start empty (see "Publishing your app" above), so the same code
  creates your account in each — the second time right after your first publish.
- **There is no first-account exception.** Whoever finds your live address
  without the code cannot register, which is exactly why the code exists. Make
  your own account before you share the link.
- **One code, one account.** It is spent the moment an account is created with
  it. Other people come in through the app's own invite control (below), not
  through this code.

#### Where your codes are

- **On a computer** — a chip beside your app's address, above the app itself.
  Click it to copy.
- **On a phone** — the **Options** card: hold the chat bubble and slide left
  (see "The chat bubble" below).
- **When you publish** — the publish dialog repeats the codes that publish
  delivers, which is the moment the live app's first account is due.

The chip keeps showing a code after it has been used — what happens inside your
app isn't visible from out here. A used code is simply refused; ask in the chat
if you want a fresh one.

#### Letting other people in

An app with closed sign-up has an **invite** control inside it, for anyone signed
in: it mints a code for one more account, which you pass to that person. That is
the way to add people — your own code is spent once you have registered, and you
shouldn't be handing it out anyway. If your app hasn't got that screen yet, ask
for it in the chat.

#### Changing your mind

Ask in the chat — "close sign-up, only people I invite" or "let anyone sign up".
It is a change to the app like any other: your draft has it once it has been
built, and your visitors once you publish. Accounts that already exist are
untouched.

### Forgotten passwords

Passwords in the app you built are stored scrambled, inside that app's own
database. Nobody can read them back — not you, not the agent, not us. So there
are two ways to a new password, and which one you need depends on whether you
can still sign in.

#### If you can still sign in

Change it inside the app: it has a **change password** screen for signed-in
accounts, which asks for the current password and the new one. Nothing out here
is involved. If your app hasn't got that screen yet, ask for it in the chat.

#### If you are locked out

Ask in the chat — "I can't sign in to my app any more". The agent asks which
account it is (it cannot see the accounts inside your app, so it has to be told)
and puts a single-use **password-reset code** into the app for that one account.

Then, on your app's own login page:

1. open **Forgot password**;
2. enter the account name, the code, and the new password.

It works once, for that one account, and signs that account out everywhere it
was still open. A code for someone else's account works the same way — ask for
one in their name and hand it to them; there is no screen inside the app for
resetting another person's password.

#### The live app gets the code only when you publish

A reset code is part of the app itself, so it travels like every other change —
with a publish. That cuts two ways:

- **Locked out of your draft** — the code is usable as soon as the change has
  finished building. Nothing else to do.
- **Locked out of the live app** — publish once the agent has minted the code,
  then use it there. Publishing ships everything else your draft is carrying, so
  if there is half-finished work in it, finish it (or go back to an earlier
  version) rather than publishing it by accident along with the code.

#### Where the codes are

The same three places as a registration code (above) — the chip beside your
app's address on a computer, the **Options** card on a phone, and the publish
dialog. Reset codes name the account they belong to, since each one unlocks
exactly that account.

## On your phone

### The chat bubble

On a phone your app gets the whole screen — no header, no sidebar. Everything
else lives in the one floating bubble: **tap** it for the chat, **hold** it for
the conversation, the options and publishing.

The rendered page animates the gesture on a little phone. The same steps in
order:

1. Your app fills the screen. One floating bubble is the whole interface.
2. Tap the bubble once…
3. …and the chat opens over your app — the latest version, and a box to ask for
   the next change.
4. Press and hold it instead, and three options bloom around the bubble.
5. Keep your finger down and slide toward one: up for the conversation, left for
   Options, right to publish.
6. Lift your finger to open it. Options holds your app's codes, its versions to
   restore, taking it offline, and the ways off this screen — onboarding, docs,
   home.

#### Tap — the chat

A tap opens a small card over your app: what the latest version is, and a box to
ask for the next change. Your app stays visible and usable behind it — tap the
chevron to put the card away. If something needs you (a question, a change that
couldn't be built), the card says so and opens the full conversation.

#### Hold — the three options

Press the bubble and **keep your finger still**. After a moment three options
bloom around it:

- **Up** — the full conversation: everything you asked for and everything the
  agent did, oldest to newest.
- **Left** — Options (below).
- **Right** — Publish, dimmed while there is nothing new to publish.

Then, without lifting: slide toward one to select it, and lift to run it. Slide
back to the bubble — or downwards, where there is nothing — and lift to call it
off.

#### What's in Options

- Your app's **codes**: the registration code its sign-up asks for, and any
  password-reset codes it has issued (see "Accounts in your app" above).
- **History** — opens your app's versions, newest first, the current one and the
  published one marked. Each carries **Restore** (see "Going back to an earlier
  version" above), and the newest carries **Publish**. On a phone the versions
  live here rather than in the conversation: the chat stays a chat, and the
  versions stay two gestures from your app.
- **Live app** — take your published app offline behind a "coming soon" page, or
  bring it back. Nothing is deleted either way.
- **Onboarding** — run the walkthrough again: the gestures above, and every
  explainer this app has shown you.
- **Docs** — these pages, in a new tab, so your app stays where it is.
- **Home** — your other apps.

#### Moving the bubble

Wherever the bubble sits it covers a piece of your app, so it moves: press it
and drag — past a few pixels it follows your finger, and it stays where you drop
it, on this app and the next.

#### Draft and Live

Once you have published, two chips appear beside the bubble. They switch which
version the screen shows — **Draft**, your private working copy, and **Live**,
what visitors get. Asking for a change always goes to the draft.

#### While something is happening

A ring turns around the bubble whenever a change is being built or deployed, so
a folded chat never hides that work is under way. Open the chat to see how far it
has got.

## Custom domains

### Pointing your DNS

Connect a domain you own to your published app.

Point your domain at the **c-ray platform apex** — the bare hostname this site
is served on, without the `https://` — with a **TTL of 1 minute**. Which record
type depends on whether you're connecting a subdomain or a root domain.

#### A subdomain — `www.example.com`, `shop.example.com`

| Field | Value |
| ----- | ----- |
| Type  | `CNAME` |
| Name  | `www` (or `shop`, `app`, …) |
| Value | the c-ray platform apex |
| TTL   | 1 minute |

#### A root domain — `example.com`

A root domain can't hold a CNAME — the DNS standard forbids it. Use whichever
of these your provider offers.

##### ALIAS, ANAME or CNAME flattening (recommended)

Same feature, different names: **ALIAS** (DNSimple, Netlify), **ANAME**
(Namecheap, easyDNS), **Alias** (Route 53), or Cloudflare, where a normal CNAME
at the root is flattened automatically.

| Field | Value |
| ----- | ----- |
| Type  | `ALIAS` (or `ANAME` / `CNAME`) |
| Name  | `@` (the root itself) |
| Value | the c-ray platform apex |
| TTL   | 1 minute |

Preferred because it re-resolves our host, so your domain follows us if our
address changes.

##### An A record (if your provider has no ALIAS)

| Field | Value |
| ----- | ----- |
| Type  | `A` |
| Name  | `@` (the root itself) |
| Value | run `dig +short <apex>` and use the result |
| TTL   | 1 minute |

This pins today's IP address — if ours changes, you have to edit it by hand.

#### Both addresses

Also connecting `www`? Add the CNAME above as well, and connect both in the app
so each gets its own certificate.

Then connect the domain under **Custom domain** in your app. The certificate is
issued automatically once the record resolves — usually a few minutes.
