Docs
CLI reference

CLI behavior and limits

File rules, limits, JSON output, exit codes, project metadata, and connection settings.

This page covers behavior that matters when you automate the CLI or troubleshoot a command. For command syntax and options, see the command reference.

Exit codes

CodeMeaning
0The command completed successfully.
1The command handled a runtime problem, such as a missing login, sync conflict, validation error, missing folder, or failed request.
2The command or option usage is invalid.

When you use --json, a handled failure also prints an error event with a stable error name and a readable message.

What syncs and what does not

init and push scan the connected folder. The following rules decide which files are included.

Always-excluded directories

These directory names are excluded at any depth:

node_modules
.git
.sandscape
.ssh
.aws
.gnupg

An ignore-file negation cannot include them.

Always-excluded credentials

The CLI excludes credential-shaped filenames at any depth:

.env
.env.*
*.pem
*.key
*.p12
*.pfx
id_rsa
id_rsa.pub
id_ed25519
id_ed25519.pub
.npmrc
.netrc
credentials.json

.env.example, .env.sample, and .env.template are allowed. An ignore-file negation cannot include any other credential-shaped file.

Root ignore files

The CLI reads .gitignore and .sandscapeignore from the project root. It supports:

  • comments and blank lines
  • negation with !
  • directory patterns such as dist/
  • root anchoring with a leading /
  • basename patterns that match at any depth
  • *, **, and ? wildcards

Character classes are not supported. Nested .gitignore files are not read.

Use .sandscapeignore when git should keep a file but Sandscape should not receive it.

The following top-level entries belong to the CLI or coding agents and are not uploaded:

.sandscape/
CLAUDE.md
AGENTS.md
.claude/
.agents/
.codex/
.cursor/

Symlinks are never followed or uploaded. The command prints the paths it skipped so you can replace a link with the real file when needed.

Deletions

The current sync protocol does not propagate deletions. push sends local additions and changes, but deleting a local file does not delete its Sandscape copy. pull downloads additions and changes from Sandscape, but it does not remove a local file that no longer appears there.

Limits

File and media limits

ItemLimit
One synced file50 MiB
One push500 MiB and 5,000 files
Gameplay video200 MiB; MP4, MOV, WebM, M4V, AVI, or MKV
Cover image10 MiB; PNG, JPEG, WebP, or GIF
Generated coversFirst 3 per game are free; free use is capped at 6 per user per day

Files stream to the server. The CLI does not place all file contents in one encoded request.

Publishing text limits

FieldLimit
Title200 characters
Tagline200 characters
Short description2,000 characters
Long description20,000 characters
Tags20 tags, up to 60 characters each
Cover generation direction2,000 characters

Connected folder layout

<game>/
  .sandscape/
    project.json    session ID, last synced version, and API origin
    design.json     game concept, style guide, assets, and plans
    manifest.json   path, checksum, version, and size for synced files
  CLAUDE.md         generated coding-agent guide
  AGENTS.md         the same guide under a second common filename
  .claude/skills/sandscape-cli/
  .agents/skills/sandscape-cli/
  index.html        browser entry point
  <game files>      your existing folder structure

The connected folder is the root Sandscape serves. index.html must remain at that root. Other files keep the same relative paths they have on your computer.

Do not edit .sandscape/manifest.json or .sandscape/project.json. clone, pull, and push maintain them.

.sandscape/design.json is a local snapshot of the design stored on Sandscape. It can include the concept, style guide, assets, development plan, animation plan, voices, preview scene, and integration notes. clone and pull update the snapshot. Local changes to it are not uploaded.

Version and conflict model

Sandscape assigns a version to each project. A connected folder records the version it last synced.

  • push succeeds only when the local recorded version matches the current Sandscape version. A successful push advances both.
  • If the local version is behind, pull before pushing.
  • If the local version is ahead, clone the project again into a fresh folder.
  • If the same file changed on both sides, pull stops before overwriting the local file. pull --force lets the Sandscape version replace it.

The CLI does not merge files automatically.

JSON output

Add --json when a script or coding agent needs structured output.

Transfer events

clone, pull, push, and init emit one JSON object per line:

{"event":"start","total":76,"kind":"download"}
{"event":"progress","done":12,"total":76,"path":"assets/img/hero.png","kind":"download"}
{"event":"done","total":76,"kind":"download"}
{"event":"info","message":"..."}
{"event":"warning","message":"..."}
{"event":"error","error":"not_authorized","message":"..."}

Every line parses independently. Progress events show that a large transfer is still moving.

Login events

login --json prints a verification event first. The final event is authorized or error.

{"event":"verification","verification_uri":"https://example/device","user_code":"ABCD-EFGH","verification_uri_complete":"https://example/device?code=ABCD-EFGH","expires_in":900,"interval":5}
{"event":"authorized","scopes":["cli"]}

The token never appears in JSON output.

Publish events

publish --json can emit:

  • phase as it checks readiness, saves a draft, uploads media, generates a cover, or publishes
  • progress during a media upload
  • readiness for --check
  • banner_generated with the image URL and remaining free generations
  • media_ready after a media-only command
  • prepared with the review URL
  • published with the game ID, short code, and available URLs
  • error when a step fails

list --json is the main exception to the event-stream format. It prints the complete project array as one JSON document.

File checksums

The CLI records SHA-256 checksums of the raw file bytes as lowercase hexadecimal. It checks every file downloaded by clone or pull before putting it in place.

Environment variables

VariablePurpose
SANDSCAPE_API_URLSelects the backend for login when --api-url is omitted. The selected origin is saved with the token.
SANDSCAPE_WEB_URLSets the frontend origin used to format the play URL after direct publishing. --web-url overrides it.

You do not need either variable for normal use.

Use trusted connection settings

The CLI sends its scoped token with authenticated requests. Use HTTPS for any remote backend. Plain HTTP is suitable only for a loopback address such as localhost during local development.

--api-url sends your token to the backend you specify. Use it only with a backend you trust. Authenticated requests do not follow redirects, and server-provided file paths are checked before the CLI reads or writes them.

CLI behavior and limits | Sandscape