# Create a new app (/docs/start/new-app)



Start here when you have an idea and no app yet, such as a waitlist that moves people up for inviting friends, or a journey that rewards your Discord regulars with roles. By the end you'll have a working app, online at a staging address you can share, and an agent that knows how to change it.

An organization administrator creates the project: describe the idea in Console, then build with the hosted agent there, or hand the project to your developer or coding agent. Teammates who aren't administrators work in the projects an administrator gives them access to. The terminal steps further down are for them. Everything runs on test data until a person approves going live.

```mermaid
flowchart LR
    A["Console project"] --> B["Agent intake"]
    B --> C["Login and checkout"]
    C --> D["Dev preview"]
    D --> E["Staged preview"]
```

You need a Domino account. To work in your own editor, also install a coding agent such as Codex or Claude.

> [!DEV]
> Working outside Console also needs Node.js 24, Git, and pnpm.

## Describe your project [#describe-your-project]

Open [Console](https://console.domino.run), create a project, and choose **Create something new**. Pick a starter under **Start from**, then describe who it is for and what people should do. Domino saves the brief and prepares a private repository from that starter, with your project name already in the app and your brief in `CAMPAIGN.md`. It then stages that untouched starter: its app goes online at your staging URL, and its sample quests, leaderboards, and collections are published to **Test**. Nothing is published to **Live**. If **Deployments** shows no build, [stage](/docs/build/staging) the starter yourself.

| Starter            | Begins as                                                                                                                                 |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Campaign tour      | A neutral quest app with a guided tour of every quest kind. The default, and the blank canvas for anything.                               |
| Classic questboard | The familiar Domino portal: quests in a grid grouped by section, a claim page, points, and a leaderboard.                                 |
| Waitlist           | A pre-launch page. People join, see their place in line, and move up by inviting friends.                                                 |
| Referral program   | Invite links, rewards when friends join and qualify, milestones, a top referrers board, and a Referrals dashboard.                        |
| Discord activation | A step-by-step journey that turns new Discord members into regulars, rewarded with roles.                                                 |
| Loyalty program    | Members join a campaign, earn points from its steps, become members of a group, and spend points on offers, one of them for members only. |
| API                | A headless Worker with typed routes and interactive API docs, for plugging Domino into your own product.                                  |

Every starter works before your agent changes anything, and comes with an `AGENTS.md` that tells your agent what the starter is for and how to adapt it.

* **Telegram sign-in.** The starters with a sign-in form show a [Telegram](/docs/build/telegram) button where Domino configures Telegram Login.
* **Before signing in.** The classic starter shows its quests to visitors who haven't signed in: each quest's title, instructions, and rewards, read-only, with a prompt to sign in to start. Paused and hidden quests stay out. Signed-out visitors see the quests in the starter's own sections; the collections you arrange in Console appear once they sign in.
* **Who is signed in.** The classic starter shows the member's own email address, when they have one, in its account menu and on its Settings page.
* **Quest presentation.** The campaign starter shows each quest's image, its ordered steps with links, and hints about which account or wallet to link. It shows collections with their images and descriptions, in the published quest order. You can edit these in Console. A step's link explains what to do; the quest's check still decides completion. See [quest presentation](/docs/build/first-quest#add-participant-presentation) and [collections](/docs/concepts/collections).

> [!DEV] Starter layout
> Starters install the SDK and CLI from npm at the same exact version, with a lockfile for repeatable installs. They do not bundle package archives. Existing projects upgrade their dependencies explicitly; a platform deployment does not silently change them.
>
> Every starter has the same layout: the Worker in `server/`, the points ledger in `ledgers.ts`, and `AGENTS.md`. The starters with a member app add pages in `src/` and quests in `quests/`. The API starter is headless: it has no pages and no quests. The classic starter reads the signed-in email from `useMe()`.
>
> Starter authoring modules declare stable resource keys once and pass the typed handles returned by `defineLedger`, `defineQuest`, and `defineTracker` wherever another resource refers to them. Keep those imports when adapting a starter; do not reconstruct a resource reference from its key or stored identifier.
>
> The campaign starter reads quest presentation from the member experience. Author defaults in quest or type `presentation` and collection slots in `relay.json`; the quest evaluator determines completion.

Console shows data from the selected project. Use the **Test** or **Live** menu in the header to choose its environment. In **Test**, a new project shows its starter's sample resources once the first build finishes. **Live** stays empty until you publish there.

## Build in Console [#build-in-console]

Open **Developers → Build** in **Test** to chat with the hosted agent beside your app's preview. Describe a change and watch it appear in the preview. [Build in Playground](/docs/build/playground) covers threads, checkpoints, attachments, element selection, and staging from Console.

## Hand it to your agent [#hand-it-to-your-agent]

Choose **Open in your agent** in Console and copy the instructions into your coding agent. Ask it to read the project brief and use the Domino skill. For example:

> [!PROMPT]
> Use the Domino skill. First ask me for any missing brand name, website or reference, campaign goal, audience, desired actions, and reason to participate. Wait for my answers before research or design. Then propose a visual direction and campaign brief and wait for my confirmation before implementation. Check which features are supported and give me a preview where I can sign in and complete the main quest.

> [!NOTE] A project that already has work
> When the project has quests published in **Test** that aren't archived, or staging builds, the copied instructions skip intake and discovery. The agent signs in, checks out the repository, reads the project's agent instructions, README, and `CAMPAIGN.md`, reviews its quests, releases, and builds, then summarizes what exists and asks what to change next. It treats the saved brief as confirmed unless you say otherwise. The Playground's **Start from the brief** shows only while the project has neither. If Console can't check, it offers **Check again** in place of the instructions.

### 1. Answer the intake questions [#1-answer-the-intake-questions]

The agent starts with a few questions when your brief is empty or missing these basics. It waits for your answers before connecting or designing.

You can say that you have no website or ask it to help create a new brand. The project name and starter content do not determine your brand.

### 2. Approve the CLI login [#2-approve-the-cli-login]

Your agent sends the login code first, followed by the sign-in link. Copy the code, open the link, and enter the code in Console to approve the CLI connection. The code works for 15 minutes; if it expires, ask your agent to run `domino login` again. Approve only a code your own agent just sent: the page shows when, from which country and by what client the request came.

The CLI waits for approval and saves its credential automatically. Your agent then checks out the repository and installs its dependencies. Keep credentials out of chat.

### 3. Confirm the brand and campaign [#3-confirm-the-brand-and-campaign]

After intake, the agent researches the available context and presents a brand sample and campaign proposal. It waits for your explicit confirmation, then saves the agreed brief before implementing.

A website URL is a useful starting point; you do not need to write a full brand guide.

## Set up from a terminal [#set-up-from-a-terminal]

Developers can do the same from a terminal. Check out a project created in Console:

```sh
npx -y @domino-sdk/relay-cli@latest login
npx -y @domino-sdk/relay-cli@latest checkout YOUR_PROJECT
cd YOUR_PROJECT
npx --yes pnpm@10.34.5 install --frozen-lockfile
pnpm exec domino doctor --remote --json
pnpm exec domino dev
```

* **Choose the project.** Use the project's ID or slug, as `domino whoami --json` lists them, in place of `YOUR_PROJECT`, or run `domino checkout` without an identifier to choose from your accessible test projects in the terminal.
* **Or create one here.** `domino create YOUR_PROJECT --template waitlist` creates the project and its repository from a starter and checks it out. Without `--template`, a terminal asks you to choose; scripts get the campaign tour. Template IDs: `campaign`, `classic`, `waitlist`, `referral`, `discord`, `loyalty`, `api`.
* **Use the project's CLI.** After checkout, use the CLI installed in that project so it matches the starter.
* **Follow checkout's install command.** Use the exact `packageManager.installCommand` printed by checkout if its pin differs from this example. Wait for installation to finish before running diagnostics.

### Where the connection comes from [#where-the-connection-comes-from]

Checkout stores this project's connection in `.git/domino.json`, separate from credentials and committed starter defaults. `doctor` reports the effective connection in `scope` and the source of each value in `scopeSources`.

| Precedence | Source                                                                                                 |
| ---------- | ------------------------------------------------------------------------------------------------------ |
| 1          | Command flags                                                                                          |
| 2          | Environment variables                                                                                  |
| 3          | The Git connection file, `.git/domino.json`. Linked worktrees share their Git common directory's file. |
| 4          | `relay.json`                                                                                           |

### Recover from a failed setup [#recover-from-a-failed-setup]

| Failure                | What to do                                                                                                                                                                                                                                                  |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Repository setup fails | Keep the saved project and retry setup.                                                                                                                                                                                                                     |
| Checkout fails         | Retain its Git message and `details` output. A repository marked ready by the API can still fail a Git fetch; the CLI reports both facts without assuming the cause. Retry the same checkout once, then give the diagnostics to the operator if it repeats. |

> [!WARNING] Do not start over
> Creating another project is not a recovery step. After a failed checkout, do not install dependencies in the parent directory.

## Try your app [#try-your-app]

Open the HTTPS preview URL printed by `domino dev`. Sign in as a member, complete the main action, and refresh to check that progress remains.

Before your agent changes anything, the starter shows its sample experience with realistic placeholder content. The campaign tour has five sample quests, one for each way Domino can recognize an activity, and a deliberately neutral look, so your agent can give it your campaign's brand without undoing another one. The other starters come with a finished design of their own that your agent restyles from one stylesheet.

Starters with sample quests test them in `tests/quests.test.ts`. `pnpm test` runs those tests on your computer, without a preview or sign-in, so your agent can check each quest change before you try it. See [Test quests locally](/docs/build/testing).

> [!NOTE] This preview runs on your computer
> You can share that URL with a coworker while the dev process is running. Your computer must stay online. Closing the process takes the preview offline.

## Keep a preview online [#keep-a-preview-online]

Ask your agent to reconcile its work with the latest `main`, run the checks, and merge and push the intended changes to `main`. Then run `domino stage --commit <sha> --json` for that integrated commit. Share the URL returned by the successful build; [Stage and share](/docs/build/staging) covers builds and who can open staging. The [source and release workflow](/docs/reference/hosted#source-and-release-workflow) covers starting and resuming work.

| Action         | What it does                                                                             |
| -------------- | ---------------------------------------------------------------------------------------- |
| `domino dev`   | Serves a preview from your computer while the process runs.                              |
| Git push       | Saves code.                                                                              |
| `domino stage` | Builds and serves the code. Uses test data and stays online after you close your laptop. |
| Quest Studio   | Reviews and publishes Console-authored quests in test. A promotion carries them to live. |

Publish code-defined behavior to test with `domino deploy --environment test`. For live, use the [reviewed publication workflow](/docs/build/publishing#publish-behavior-to-live): the CLI prepares a request, then a person with publish permission approves it in Console.

Next: [Development and previews](/docs/build/development), and [Hosted apps](/docs/concepts/hosting) for how previews, staging, and your app's server fit together.

## Add automatic or repeatable activity [#add-automatic-or-repeatable-activity]

The starter follows these display rules. Keep them when customizing the app:

* **Automatic quests** render as status and progress, without a claim or retry button.
* **Hidden quests** are excluded from member navigation.
* **Repeatable quests** display a completion count.
* **`completed`** means a member has completed a quest at least once, not that a keyed quest has ended.

Install the `discord-announcements` snippet for an automatic integration example. Configure its channel and publication cutoff, then [connect Discord](/docs/build/integrations#automatic-announcement-reactions). Use Console **Quests** to inspect its trigger, visibility, budgets, and delivery coverage in test.

## Terminal output and scripts [#terminal-output-and-scripts]

Commands show readable text by default. Results go to stdout; prompts, progress, and errors go to stderr. The exit status is 0 on success, 1 on failure, 2 for a mistyped command or option, 3 when a change may have taken effect without confirmation, and 130 when you cancel (143 when stopped with SIGTERM). Scripts and agents should pass `--json` and branch on the exit status and the error's `code`; the [CLI automation contract](/docs/reference/automation) lists every code and result shape.

| Command or flag                      | Output                                                                           |
| ------------------------------------ | -------------------------------------------------------------------------------- |
| `domino whoami`                      | Your identity and accessible projects.                                           |
| `--json`                             | One JSON result on stdout, or one JSON error with a stable `code` on stderr.     |
| `domino api`                         | Raw API access. Always returns JSON.                                             |
| `domino build`                       | Resource counts for the build.                                                   |
| `domino build --out deployment.json` | Saves the bundle.                                                                |
| `domino build --json`                | Prints the complete payload.                                                     |
| `domino build --hosting-artifacts`   | Writes the quest and catalog artifacts a hosted build needs to `.domino-build/`. |

### Project selection [#project-selection]

`checkout`, `init`, `status`, `quests`, `releases`, `builds`, and `logs` offer project selection when no project is configured.

* **Select explicitly** with `--project ID`.
* **Prompts turn off** with `--json`, `--no-interactive`, CI, and redirected input or stderr.
* **Without prompts,** a single accessible project is selected automatically; multiple projects require an explicit identifier.
* **Scope follows your organization.** Selection uses the effective organization scope.
* **Cancel** a picker with `q` or Ctrl-C.
* **Nothing is saved.** A selected project applies only to the current command; inspection commands do not save connection files.

### More terminal choices [#more-terminal-choices]

| Command                 | In a terminal                                                                                                                                                                                                                                                                                        | To skip the questions                                                                                                                                                                   |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `domino create`         | Enter a project name and destination directory. If no organization is configured or returned for the current session, choose from organizations in your accessible projects. If that list is empty, enter an organization ID. Then choose a starter. Access remains limited by your sign-in session. | Supply a name, `--directory`, `--organization`, and `--template`. Without `--template`, scripts get the campaign tour.                                                                  |
| `domino logs`           | Choose a recent build by status, creation time, commit, and build ID. An empty history directs you to stage a pushed commit first.                                                                                                                                                                   | Run `domino logs BUILD_ID --json` in scripts.                                                                                                                                           |
| `domino agents install` | Choose Codex, Claude, or both.                                                                                                                                                                                                                                                                       | `--agent codex`, `--agent claude`, or `--agent both`. Noninteractive installation keeps the default of both agents.                                                                     |
| `deploy` and `stage`    | Show the target and ask for confirmation.                                                                                                                                                                                                                                                            | `--yes` skips that confirmation without disabling other pickers. `--json`, `--no-interactive`, CI, and redirected input or stderr retain noninteractive execution without confirmation. |

See [Publishing and previews](/docs/build/publishing) for what each command changes.

## Collect text and post links [#collect-text-and-post-links]

The campaign starter can ask members for a short answer or a link, such as the URL of their post on X. It shows the matching input, checks it against the quest's published limits, and keeps the member's original answer when sending or checking it is retried. Other starters and existing apps add these inputs themselves.

A link a member sends is a claim, not proof. A quest about an X post should check that the post exists and that the member's own linked X account wrote it before awarding points.

> [!DEV]
> Declare `evidence.text()` or `evidence.url()` on the quest, and configure text length limits or exact allowed URL hosts in quest code. Other starters and existing apps must declare the interactions they support and add the corresponding controls.
>
> For an X post quest, offer X account linking, parse the link with `xPostId`, read it with `ctx.x.post({ postId })` (which returns `null` when the post does not exist), and compare the author with the linked account. See [X verification examples](/docs/build/integrations#start-from-a-complete-x-quest) and [text and URL submissions](/docs/reference/verification#text-and-url-submissions).

## Recover an uncertain redemption [#recover-an-uncertain-redemption]

The campaign starter displays offer cards when the project publishes offers. A redemption whose
answer is lost shows **Retry the same redemption**. Keep the page open and use that button to
check the original action instead of spending again with a new key. See
[Retry after an uncertain answer](/docs/reference/participant-api#retry-after-an-uncertain-answer)
for the SDK helper and recovery after a reload.
