Deploying and Versioning
Building an app produces a live preview that only you can see. Publishing turns it into a hosted application at a stable URL that your invited users can open. This page covers the publish flow, the states a deployment moves through, how to manage a deployment over its lifetime, and how the version history lets you undo any change.
Publishing an app
When you're ready, select Publish in the editor toolbar. The builder freezes the current code at the moment you click, then deploys it. You're returned to the home page so you can watch the deployment progress on the app's tile while the editor stops accepting edits — any further changes require an explicit republish.
Before a deploy starts, the builder checks several preconditions:
- A snapshot exists. The app must have at least one saved snapshot. Snapshots are taken automatically on every AI turn and edit, so making any change satisfies this.
- Every declared AI Employee slot is bound, and every required typed slot has a value. If not, publish is blocked and the missing-bindings modal opens so you can bind the slots and republish — see Configuration and bindings.
- Continuous integration is green. The app's repository runs checks (type-check, lint, test, and a Docker build) and publish refuses to deploy if they aren't passing. A failed check returns a message naming what failed; pending checks ask you to retry in a moment.
The display name and URL are read from the app server-side at publish time, so a renamed app always deploys at the right URL.
Authentication
A published app is reached through Ema's single sign-on: only signed-in Ema users who have a role on the app (see App Permissions) can open it. The app never builds its own login page — every request arrives carrying the real user's identity. There is no auth-mode picker in the publish flow today; Ema sign-on is applied automatically.
The deployment lifecycle
A deployment shows one of these statuses on the app tile and in the editor toolbar:
| Status | Meaning |
|---|---|
| Deploying | The app is being built and rolled out. Progresses through the deploy stages below. |
| Running | The app is live and reachable at its URL. |
| Stopped | The app has been stopped and scaled to zero. It's no longer reachable but can be started again. |
| Failed | The build or rollout failed. The error is shown on the tile; fix the cause and publish again (the tile offers a Retry action). |
Deploy stages
While a deployment is DEPLOYING, the Publish button reports the current stage so you have a live signal during the build (which can take several minutes):
- Building image… — the container image is being built from the app's source.
- Provisioning database… — the app's MongoDB database is created (first publish).
- Installing app… — the app is rolled out, with each declared slot injected as an environment variable and the app's Ema sign-on wired up.
- Starting up… — the platform waits for the app to pass its health check.
When all stages complete, the app is RUNNING and a View live action appears that opens the deployed app.
First publish makes you the App Manager. The first time an app is published, the publisher becomes its App Manager but doesn't yet have an in-app role. The builder offers a one-click panel to grant yourself a role so you can open the deployed app immediately. See App Permissions.
The app URL
Each app has a display name (free text, what users see in the builder) and a URL slug (the leftmost label of the hosted URL, globally unique). These are separate:
- Before the first publish, the slug auto-tracks the display name — rename the app and the slug follows.
- On the first successful publish, the slug freezes. After that, renaming the app no longer changes the URL.
- To change a frozen slug, use Edit next to the URL in App settings. The slug must be 3–30 characters, lowercase letters, digits, and hyphens only, with no leading, trailing, or consecutive hyphens. If the app is running, the live hostname swaps in a few seconds without a rebuild; if it's stopped, the change applies on the next publish.
When you change a published app's URL, the old hostname keeps redirecting to the new one for 90 days, then stops resolving. Update any external links before that window closes. App settings lists the retired URLs and the date each redirect expires.
Managing a deployment
Once an app is published, you manage its deployment from the home-page tile (overflow menu), the editor toolbar, or the app detail page:
| Action | Where | What it does |
|---|---|---|
| View live | Tile, editor toolbar, detail page | Opens the running app in a new tab, with access already set up for you. |
| Stop | Tile overflow menu | Scales the app to zero. It becomes STOPPED and users can't reach it until you start it again. |
| Start | Tile overflow menu, editor toolbar | Brings a stopped app back to RUNNING. |
| Retry | Tile overflow menu | Re-runs the deploy for an app whose last publish ended in FAILED. |
| Delete app | App settings → Danger zone | Permanently tears down the deployment, database, sessions, and preview links. Owner or tenant admin only. This cannot be undone. |
Republishing after a change
After an app is live, the editor still lets you keep building — but the deployed app keeps running the code and configuration from your last publish until you publish again.
- After a code change: the Publish button stays available. Select it to roll out a new version. If the sandbox code is identical to what's deployed, the button reads No changes and is disabled, so you can't ship a no-op.
- After a configuration change: if you edited slot bindings or values since the last publish but the code is unchanged, the button becomes Republish. Republishing rolls the running pod with the new configuration — no code rebuild needed. The Configuration tab also surfaces a republish banner when configuration has drifted from what's live.
You can't publish while the AI is mid-response. The button is disabled with a "wait for the AI to finish" hint until the current turn completes.
Version history
Every change to an app — AI turns, your manual edits, file creates, renames, and deletes — is committed to the app's git history. Open Version history from the editor toolbar to see the commit timeline, newest first. A fresh app always has at least one commit (the initial commit from the template).
From the timeline you can:
- View changes — open a commit's diff in the Changes view to see exactly what that commit touched.
- Restore this version — rewind the workspace to a chosen commit. History stays linear: restoring records a new forward
restorecommit on top of the current state rather than discarding later commits, so you can restore forward again to a newer version. After a restore, a snapshot is taken so the next session over the app starts from the restored state.
Restoring affects only your editing workspace and preview. It does not change what's deployed — publish again to roll the restored code out to the live app.
What's next
- App Permissions — manage who can open and administer the deployed app.
- The App Editor — back to building.