> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frogbot.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Dojo

> Share a FrogBot app on Dojo, pull one down, read its logs, and run it there with no setup.

The Dojo plugin adds the `share`, `pull`, `logs` and `logout` commands, and runs your app on Dojo with no setup: uploads go to the app's own storage, and AI goes through Dojo's gateway. Apps made with `create-frogbot-app` already list it.

## Install

```bash theme={"theme":"tokyo-night"}
pnpm add @frogbotai/plugin-dojo
```

```ts theme={"theme":"tokyo-night"}
import { dojo } from '@frogbotai/plugin-dojo'
import { buildConfig } from 'frogbot'

export default buildConfig({
  // ...
  plugins: [dojo()],
})
```

## Options

| Option | Type | Default | Description |
| - | - | - | - |
| `signIn` | `boolean` | `true` | Adds [Sign in with Dojo](#sign-in-with-dojo) on Dojo. Set `false` to leave the app's sign-in methods alone. |

## Commands

| Command | Arguments | Description |
| - | - | - |
| `share` | `--data`, `--no-data`, `--workspace`, `--name`, `--no-keys`, `--skip-key`, `--yes`, `--update-keys` | Uploads the app to Dojo, builds it and prints its live URL. See [`share`](https://docs.frogbot.ai/getting-started/cli#share). |
| `pull` | `<app>` | Downloads an app shared with you on Dojo into a new folder. See [`pull`](https://docs.frogbot.ai/getting-started/cli#pull). |
| `logs` | `<app>`, `--follow` | Prints an app's recent logs from Dojo, or follows them. See [`logs`](https://docs.frogbot.ai/getting-started/cli#logs). |
| `logout` | — | Signs the CLI out of Dojo. See [`logout`](https://docs.frogbot.ai/getting-started/cli#logout). |

In an app that lists `dojo()`, run them as [plugin commands](https://docs.frogbot.ai/getting-started/cli.md#plugin-commands):

```bash theme={"theme":"tokyo-night"}
npx frogbot share
```

The plugin also installs its own command, so the same four run without an app, or in an app that doesn't list `dojo()`. Pulling an app into an empty folder works this way:

```bash theme={"theme":"tokyo-night"}
npx @frogbotai/plugin-dojo pull deals
```

Run with no command or an unknown one, it prints `[frogbot] usage: npx @frogbotai/plugin-dojo <share|pull|logs|logout>` and exits with code `2`.

## On Dojo

Dojo adds this plugin itself when it builds an app, after the app's own plugins, so an app runs there without listing it. An app that lists `dojo()` gets it once, not twice. A listed `dojo()` also runs after every other plugin, wherever it is in `plugins`, so it sees the upload collections and AI providers they add.

Outside Dojo, `dojo()` only adds the commands and lists the badge and the sign-in buttons for the import map. On Dojo, where `DOJO=1`, it also changes:

* **Storage.** When the app sets no `storage`, every upload collection is stored in the app's bucket under its slug. Files stay private and are served through the app, so its access rules apply.
* **AI.** When every provider in `ai.providers` is a built-in one with no key, they are replaced by one `dojo` provider that calls Dojo's gateway. Model IDs such as `openai/gpt-5.4-mini` keep working. Chat, embeddings and images work through the gateway; transcription, speech and video need your own key. An app with no `ai` block, or with any provider key of its own, is left unchanged.
* **Jobs.** Dojo wakes the app to run due jobs. Everyone else gets the app's own `jobs.access.run`.
* **Sign-in.** The login page gets "Continue with Dojo". See [Sign in with Dojo](#sign-in-with-dojo).
* **Badge.** Every FrogBot page gets a small "Made with FrogBot · Share your own" link in the bottom-left corner. Visitors can close it for the rest of their browser session.

### Sign in with Dojo

On Dojo, the plugin adds a `dojo` method, labelled "Dojo", to the user collection's [`auth.signIn`](https://docs.frogbot.ai/authentication/sign-in), after the app's own methods. The user collection is the app's only auth collection, or the one `admin.user` names. Dojo people then sign in with their Dojo account, the way "Continue with Google" works:

* The first time someone signs in to an app, Dojo asks them once to share their name and email address with it. After that it's one click.
* Someone whose email already has an account signs in as that user.
* A new email gets an account only when the collection's [`access.create`](https://docs.frogbot.ai/authentication/sign-in#who-can-sign-up) allows it, so by default the button serves people who already have an account. Open sign-ups with `access: { create: () => true }`.
* While the collection has no users, the [first person](https://docs.frogbot.ai/authentication/sign-in.md#who-can-sign-up) to sign in gets an account, as with the create-first-user screen.

Turn it off with one line:

```ts theme={"theme":"tokyo-night"}
plugins: [dojo({ signIn: false })]
```

Dojo gives each app its own OAuth client, in `DOJO_OAUTH_CLIENT_ID`, `DOJO_OAUTH_CLIENT_SECRET` and `DOJO_URL`. Sign-in never stops the app from starting: when one of them is missing, or the collection can't take a sign-in method (see [Collection requirements](https://docs.frogbot.ai/authentication/sign-in.md#collection-requirements)), the plugin adds nothing and logs why at start, for example `[plugin-dojo] Sign in with Dojo is off for 'users': DOJO_URL is not set.` The same happens when the collection already has a method with the slug `dojo`.

An app with `sqliteAdapter({ transactionOptions: false })` fails to start once the method is added, because sign-in needs transactions. Remove that option, or use `dojo({ signIn: false })`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.