Skip to content

krites studio

What krites studio does

Start the local studio web UI — the primary surface for driving a shoot. It serves a Svelte single-page app embedded in the binary, over an HTTP + SSE API onto the same shoot files the CLI reads and writes.

Usage

krites studio [flags]

Flags

Flag Type Default What it does
--port int 0 Port to bind. 0 picks a free port
--host string 127.0.0.1 Loopback host to bind. Must be a loopback address

Plus the global flags on every command.

krites studio takes no --shoot flag

The studio is not scoped to one shoot the way the CLI commands are. It opens onto a library of shoots and you pick one in the UI, so there is nothing for --shoot to mean.

Passing it fails with unknown flag: --shoot.

To work on a folder that is not in the library yet, add it from the Shoots landing page — Browse… opens your native OS folder chooser on a desktop, or an in-app server-side folder browser over a headless session, and you can paste an absolute path into the field. Adding a shoot from the studio runs the same ingest that krites ingest does.

Where the library lives

~/.krites/shoots.yaml — a list of {id, name, path} entries. It is a studio-only concern, distinct from any individual shoot's .krites/ sidecar, and the CLI never reads it.

Removing a shoot from the studio forgets it from this list. It never deletes your files.

The studio refuses to bind anything but loopback

--host accepts localhost or any loopback IP. Anything else — 0.0.0.0, ::, a LAN address, a hostname — is rejected before the server starts:

--host "0.0.0.0" is not a loopback address: the studio is single-user
and localhost-only (R-API-1); LAN/remote access is out of scope

This is not a default you can override in configuration. Sharing a studio across a network is out of scope, not merely discouraged.

What --port 0 actually does

krites binds port zero once to have the OS allocate a free port, reads the real port number back, releases it, then starts the server on that concrete port. It needs a known port up front to record in the singleton lock, which is how krites launch finds a running studio.

When you name a port explicitly and it is already in use, the studio fails fast with a bind error rather than silently choosing another. With --port 0 that check is skipped, because there is nothing to collide with.

Only one studio at a time

The studio takes a singleton lock at <user config dir>/krites/studio.lock recording its PID and port. A second krites studio while one is live reports that the studio is already running, with the PID. Use krites launch to reopen the browser on the running one.

How the browser is authenticated

A 32-byte session token is minted once per launch and never printed or logged. Loading the SPA sets it as a krites_session cookie — HttpOnly, SameSite=Strict, path / — so there is no token in the URL or the shell history.

Every /api/* route requires that cookie or an equivalent Authorization: Bearer <token> header, and returns 401 without one. The one exception is GET /api/v1/version, left public so a launcher can probe liveness.

The full route list, the SSE contract and the request limits are in the studio API reference.

The studio does not shut down when you close the browser

It is a server, not a page. Closing the tab leaves it running; so does the launcher exiting. Stop it with Shutdown krites in the studio settings, which calls POST /api/v1/shutdown and drains gracefully.

Long-running jobs behave the same way: closing the tab does not cancel a cull or an export. They keep running and you can reattach when you come back.

A go install build serves a broken studio

The SPA is built by a go generate step and embedded at build time. go install and a bare go build skip that step and embed only a placeholder, so the studio starts but serves nothing usable.

Use a release archive, the packaged macOS app, or just build / just install. See Getting started.