> ## Documentation Index
> Fetch the complete documentation index at: https://arkor-92aeef0e-eng-615.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Studio

> The local web UI for starting training runs, watching them stream, chatting with finished models, and publishing them at *.arkor.app URLs.

Studio is the local web UI you get when you run `arkor dev`. It is not a separate service to sign into; it boots on your machine, talks to the same Arkor CLI process, and goes away when you stop the dev server.

## What Studio is for

Four jobs:

1. **Start a training run.** A "Run training" button submits the job to the managed backend by spawning `arkor start` under the hood. `arkor start` runs the existing `.arkor/build/index.mjs` artifact (and only auto-builds it when missing); see the dev-loop note below for how Studio keeps that artifact fresh.
2. **See training happen.** A jobs list with live status, a loss chart that updates as the run streams in, and a tail of training events. You can leave it open in a tab while you work on other things.
3. **Try a finished model.** A Playground page lets you pick the base model or the final adapter from any completed job and chat with it. The Playground does not load intermediate checkpoints; for mid-run inference, use [`onCheckpoint`](/concepts/lifecycle) callbacks in your trainer.
4. **Publish a model behind a `*.arkor.app` URL.** An Endpoints page creates a per-deployment subdomain that serves OpenAI-compatible chat completions for a chosen adapter or base model, plus the API keys that authenticate calls to it. The same actions are available programmatically via [`CloudApiClient`](/sdk/deployments). Studio is the interactive surface; the SDK is the lower-level one.

A note on the dev loop: Studio runs a [Rolldown](https://rolldown.rs) watcher over `src/arkor/` and pushes rebuild notifications to the SPA over a Server-Sent Events stream (`/api/dev/events`). Edit a file, save, and the Run training button updates with the new trainer name without a refresh. If a training run is in flight, the Studio compares the new bundle's cloud-side `JobConfig` hash to the one captured when the run was spawned:

* **Same hash (only callbacks changed).** The runner is signalled with SIGUSR2; it re-imports the rebuilt artifact and rotates the trainer's callback cell in place via an internal HMR brand. The cloud-side training run is untouched, no GPU time is wasted, and the SPA shows a brief "Callbacks hot-swapped" indicator.
* **Different hash (model / dataset / hyperparameters changed).** The runner is signalled with SIGTERM; the trainer's internal early-stop entry point lets the next checkpoint upload finish before issuing `cancel()`, then the SPA re-spawns the run with the rebuilt artifact. The previous Cloud-side job reaches `cancelled` after the checkpoint is uploaded, so the partial work is preserved as an artifact.

If you want this "stop after the next checkpoint" behaviour from your own code (rather than from the dev loop), build it on top of the public [`abortSignal` + `cancel()`](/sdk/trainer-control#abortsignal) pair. The [Early stopping recipe](/cookbook/early-stopping) walks through it.

## Where Studio runs

When you start `arkor dev`, the CLI:

1. Boots a Hono server on `127.0.0.1:4000` (use `-p` to change the port).
2. Serves a Vite + React SPA from the same origin so the UI talks to the CLI through `/api/*` on loopback.
3. Issues a per-launch CSRF token (saved to `~/.arkor/studio-token` with mode `0600`) and requires every request to present it.

The server only binds to loopback and rejects requests with a non-loopback `Host` header. There is no public URL, no inbound connection, and the token rotates every time you start `arkor dev`. You can run Studio safely on a shared dev machine without worrying about exposing your training data.

## How Studio fits with the managed backend

Studio is just a viewer for what your CLI is doing. The CLI talks to the managed backend over authenticated HTTPS; Studio asks the CLI (over loopback) what to render.

```
Studio (browser tab)
   │  /api/* on loopback, CSRF-token gated
   ▼
arkor CLI (your machine)
   │  authenticated HTTPS
   ▼
Arkor managed backend (training, inference)
```

That separation is why Studio works without you logging into anything in the browser: the CLI already has your credentials in `~/.arkor/credentials.json`, and Studio inherits them by virtue of running locally.

If `~/.arkor/credentials.json` is missing, the entry point decides what to do. **`arkor dev`** bootstraps an anonymous session at launch and prints a one-line hint pointing at `arkor login --oauth` so you can upgrade to a real account whenever you want; it never auto-launches the OAuth flow. The one outage case where it does not bootstrap is when `/v1/auth/cli/config` itself is unreachable on first run: the same transport error is rethrown and `arkor dev` exits fast (see [`arkor dev`](/cli/dev) for the exact recovery story). The **Studio server's lazy bootstrap** (when an `/api/*` request arrives before credentials are on disk) does the same anonymous fallback. To use an account session, run `arkor login --oauth` separately before (or after) clicking around in Studio; the credentials file is shared, so Studio picks up the account session on its next request.

## What you actually see

The current views are intentionally small:

* **Jobs.** Status, name, created time, and ID, polled every few seconds.
* **Job detail.** Loss chart, log tail (most recent events), and live status. Streamed via Server-Sent Events so it stays current without manual refresh.
* **Playground.** Adapter selector (base model or the final adapter from any completed job), a chat UI, and a streaming response. Calls flow through the CLI, then to the managed inference endpoint. The Playground only lists jobs that have finished. To run inference against an intermediate checkpoint while a run is still in flight, use [`onCheckpoint`](/concepts/lifecycle) callbacks instead.
* **Endpoints.** A per-deployment `*.arkor.app` URL bound to an adapter or base model, plus the API keys that authenticate it. Slug, target (final adapter / specific checkpoint / base model), auth mode, and key issue / revoke are all in the same view; deeper operations (re-targeting an existing deployment, custom run retention, bulk scripting) stay on the [SDK](/sdk/deployments).

A walkthrough of each view (Run training, Job detail, Playground, Endpoints) lives in the [Studio](/studio/overview) section.

## When not to use Studio

Studio is a development tool. It runs on your machine, only on loopback, and only while `arkor dev` is up. For production usage of a fine-tuned model you would call `infer` from your own application code (or wire it into whatever serving layer you ship), not point users at Studio.
