npm package: @lobby-ws/cli
Description: CLI for verifying and publishing Lobby singleplayer and multiplayer hosted games
Latest version: 0.2.1

# Lobby CLI

CLI for verifying and publishing Lobby singleplayer and multiplayer hosted games.

## Install

```bash
npm install -g @lobby-ws/cli
```

Or run without installing:

```bash
npx @lobby-ws/cli@latest --help
```

## Usage

### Play apps

```bash
lobby login
lobby verify .
lobby publish .
lobby status my-app
lobby releases my-app
```

- `login`
  Authenticate this machine with Lobby.
- `verify`
  Validate a legacy singleplayer play-app manifest, artifact layout, and required Lobby hooks.
- `publish`
  Upload a legacy singleplayer play-app build and register a release with Lobby.
- `status`
  Show the current app state and active release in Lobby.
- `releases`
  List published releases for a play app.

Play auth is stored separately from external-games auth. A successful `lobby login` does not authenticate `lobby games ...` commands.

### External games

```bash
lobby games login
lobby games init . --singleplayer
lobby games init . --multiplayer
lobby games verify .
lobby games publish .
lobby games status my-game
lobby games releases my-game
```

- `games login`
  Authenticate this machine for external Games commands.
- `games init`
  Scaffold `lobby.game.json` for either a client-only singleplayer title or a managed-runtime multiplayer title.
- `games verify`
  Validate a game manifest and hosted artifact contract.
- `games publish`
  Upload the client build, register a release, and publish the server runtime when the game is multiplayer.
- `games status`
  Show the current game state and active release in Lobby.
- `games releases`
  List published releases for an external game.

External games default to `public` visibility unless the manifest explicitly overrides it.

`lobby.game.json` now carries the primary distinction explicitly:

- `gameplay.mode: "singleplayer"`
  Client-only hosted game, `identity.mode: "lobby_bootstrap"`, `matchmaking.mode: "none"`, no `server` block.
- `gameplay.mode: "multiplayer"`
  Managed-runtime game, `identity.mode: "lobby_player_exchange"`, `matchmaking.mode: "managed_fleet"`, required `server` block.

Optional presentation metadata can live in the manifest too:

- `description`
  Short store-style summary used by the Games directory and status responses.
- `media.cover_image`
  Relative path under `client.root` for the directory cover image. `lobby games verify` checks that it exists and is a supported image file.

External games now support two integration shapes during verification:

- generated `lobby/client/*.js` and `lobby/server/*.js` helper files
- SDK-backed integrations using `@lobby-ws/lobbyworks-sdk`

## Dev

`dev` publishing is a hidden internal override. It targets `dev.lobby.ws` instead of `lobby.ws`, but the backend still decides whether the signed CLI token is allowed to use it.

Example:

```bash
lobby games login --internal-env dev
lobby games verify . --internal-env dev
lobby games publish . --internal-env dev
```

## Typical External Game Flow

For an SDK-backed multiplayer external game repo:

```bash
lobby games login --internal-env dev
lobby games verify . --internal-env dev
lobby games publish . --internal-env dev
lobby games status my-game --internal-env dev
```

## Auth Scopes

There are two separate login scopes:

- `lobby login`
  For play-app commands
- `lobby games login`
  For external-games commands

If `games verify`, `games publish`, `games status`, or `games releases` return `401` or “Not authenticated”, refresh the games login specifically.

## SDK-Backed Game Integrations

The SDK is primarily for multiplayer managed-runtime integrations. Client-only singleplayer games usually only need a valid `lobby.game.json` plus hosted client assets.

The verifier accepts host repos that:

- import runtime helpers from `@lobby-ws/lobbyworks-sdk`
- use SDK-backed client bootstrap helpers such as `connectLobbyHostedGame()` or `resolveLobbyHostedConnection()`
- use SDK-backed server auth helpers such as `resolveLobbyPlayerFromRequest()`
- stop hardcoding `location.host + /ws`
- keep release asset resolution in the SDK/loader seam instead of gameplay code
- expose `/health`
- keep the external-games manifest and artifact layout valid

This is now the preferred path over copying helper files into `lobby/`.

## Docker Build Context Warning

If a game repo depends on the SDK with a parent-directory `file:` dependency such as:

```json
{
  "dependencies": {
    "@lobby-ws/lobbyworks-sdk": "file:../lobbyworks-sdk"
  }
}
```

that dependency will usually fail during Docker build if the SDK is outside the repo build context.

Use one of these instead:

- vendor the SDK inside the host repo as a workspace package
- publish the SDK and depend on a normal version

## Common Failure Modes

### `Not authenticated`

Cause:

- stale or missing CLI auth for the command scope you are using

Fix:

```bash
lobby games login --internal-env dev
```

### `ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND`

Cause:

- external game repo uses a `file:../...` dependency that is missing inside Docker build context

Fix:

- move the dependency inside the repo as a workspace package, or
- use a published package version

### `ERR_PNPM_OUTDATED_LOCKFILE`

Cause:

- dependency manifests changed without updating the lockfile

Fix:

- regenerate the lockfile before publishing

### Generated helper files reported missing

Cause:

- verifier is checking an older repo shape, or the integration is incomplete

Fix:

- either add the generated `lobby/` helper files, or
- complete the SDK-backed integration and use a CLI version that accepts SDK imports

## Publishing To npm

When the package is ready to publish:

```bash
npm publish --access public
```