# CLI reference

The `splithub` package is the command line for people (prompts, menus) and for agents (flags, `--json`). Run it with `npx splithub` or install it as a dev dependency.

```bash
npx splithub                 # interactive menu
npx splithub <command> --help
```

Run commands from the app directory. `--json` requests machine-readable output; errors are written to stderr with exit code 1.

## Commands

| Command | Does |
|---|---|
| `init` | Writes `splithub.config.ts`, Next.js middleware and a self-hosted route where applicable, agent skills and MCP entries. Prints the provider snippet for you to add. `--mode cloud` signs in through a link; `--mode self` adds the ingest route and a store. |
| `create` | Adds an experiment to the config. Wizard without flags; `--kind value|component|redirect --id --variants a,b [--weights] [--goal] [--value k=v] [--match] [--to k=/path] [--status] [--traffic 50] [--max-visitors] [--start] [--end] [--description] --yes`. Scaffolds variant components for `component`. |
| `start <id>` / `pause <id>` / `finish <id>` | Changes `status` in the file and attempts the cloud override. Check the reported `live` result; the experiment must already be pushed and credentials available. |
| `status` | Every experiment with status, visitors, days and the verdict headline. |
| `results <id>` | Full verdict: sample, comparisons, CI, P(beat), SRM. |
| `review [<id>]` | AI reviews stored in the cloud (Pro): at start, on verdict changes or a weekly check, on finish, or on demand. |
| `push` | Uploads the normalized config to the cloud. The first push returns the public key and writes it into `storage.key`. Adopts missing dashboard-created experiments into the file. |
| `pull` | Adds missing dashboard-created experiments, including their flows, to the config file. Add any referenced goals yourself; existing entries are not overwritten. |
| `login` / `logout` / `whoami` | Connects a folder to a cloud project through a browser approval; shows the project and its public key. |
| `projects` | Lists local directories connected to cloud projects. |
| `dev` | Opens the app with `?sh_debug=1` and watches results. |
| `doctor` | Checks config, provider, middleware, route, code references, endpoint reachability, key. |
| `skills [--mcp]` | (Re)installs the agent skills; `--mcp` also writes `.mcp.json` and `.cursor/mcp.json`. |

## init in detail

```bash
npx splithub init --mode cloud --yes                 # link sign-in, then writes everything
npx splithub init --mode cloud --key pk_live_… --yes # public key known; add --no-login to skip browser sign-in
npx splithub init --mode self --db sqlite            # also: postgres | mysql | custom
npx splithub init --no-install --no-login            # files only
```

The public key ends up in `storage.key` from the first of: `--key`, the saved credentials of `login`, `SPLITHUB_API_KEY` in the environment (init asks the cloud which project it belongs to), or the first `push`. `init` prints where the key came from.

## Where results come from

| `storage.mode` | `status` / `results` read from | Auth |
|---|---|---|
| `self` | your app's handler on the local dev server (`localhost:3000` for Next.js, `5173` for Vite) or `--url` / `SPLITHUB_URL` | `--token` / `SPLITHUB_ADMIN_TOKEN` when the handler has `adminToken` |
| `cloud` | `https://go.splithub.io/v1` (or `--api` / `SPLITHUB_API`) | the key saved by `login`, `SPLITHUB_API_KEY`, or `--token sk_…` |

## Credentials

`login` prints a code and a URL. You approve it in the dashboard (and can create the project right there); the dashboard mints a project API key for that terminal and the CLI stores it per directory in `~/.config/splithub/credentials.json` (`%APPDATA%\splithub` on Windows). Nobody pastes a secret into a chat. CI and headless agents use `SPLITHUB_API_KEY=sk_…` from the project's Settings → API keys.

`pk_…` is public: it sends events and reads client config. `sk_…` reads results and pushes config: keep it out of git and out of the browser.

## Exit codes and JSON

`0` success, `1` error (message on stderr, including with `--json`). `status --json` returns `{ project, experiments: [{ experiment, kind, status, goal, description, exposures, visitors, days, verdict, headline, best }] }`; `results --json` returns the full `ExperimentResults` object described in [Statistics](/docs/statistics).
