velven
Docs
Menu

Velven CLI

The Velven CLI publishes a folder to Velven, lists its versions, rolls back, and serves it locally inside Velven's page. It is the npm package @velven/cli, with no dependencies, for Node 20 or later.

View as Markdown

Install

Run it with npx, or install it once and run velven:

Terminal
npx @velven/cli publish ./dist# ornpm install -g @velven/clivelven publish ./dist

velven help, or --help after any command, lists the commands and flags, and velven --version prints the release. velven-cli is the same tool under a second name.

login, logout, whoami

Terminal
velven login     # shows a code and opens velven.ai to approve itvelven whoami    # @handle on https://velven.aivelven logout    # forgets this computer's sign-in

login is the same device-code sign-in an agent uses: approve the code in your browser and the token is saved in ~/.config/velven/auth.json, readable only by you, one per Velven address. It lasts 90 days. logout forgets it on this computer; revoke it for good in your settings. whoami --json prints { ok, api, handle, profileUrl, tokenFrom }.

publish

Terminal
velven publish [dir]             # a private preview of the folder (default: the current one)velven publish [dir] --prod      # live once Velven's safety check passesvelven publish [dir] --prod --wait

The listing comes from velven.json in the folder. The first publish creates the space and writes "space" into velven.json; later publishes update it. When it cannot write the file (read-only, or a folder you cannot write to), it says so, prints what to put in velven.json (the slug, or without an account the claim token) and goes on with the publish; --json carries the sentence as notSaved. Only files Velven does not already have are uploaded.

--prod
Send the version to the safety check; it goes live when the check passes. Without it, the version is a preview for 24 hours.
--wait
Wait here for the preview link, or with --prod for the check's verdict, up to 20 minutes; it stops early when the check ended without a verdict (the space was hidden, held or moved, or its checks are over the hourly limit), and a publish checks it again. Without it, the CLI returns after the upload with a link to follow.
--title <text>
Override velven.json for this run. Nothing is written back.
--type <type>
game, world, tool or wonder.
--devices <list>
desktop, mobile, vr, comma separated.
--description <text>
One line, up to 160 characters.
--engine <engine>
An engine value, such as three.js.
--yes, -y
Never ask. A missing field fails with exit 2 and names every missing field.
--json
Print one JSON object, for scripts and agents.

In a terminal, a missing required field is asked for and your answer is saved in velven.json. Anywhere else, or with --yes or --json, the command fails and names the fields.

Signed out, publish makes an unlisted page: it prints the page, a claim token and a claim link, and saves the token in velven.json as "claim". --prod then exits 3. After velven login, the next publish from the folder claims the page.

versions and rollback

Terminal
velven versions            # the space's versions; * marks the live onevelven versions --json     # { ok, space, versions: [{ id, number, status, createdAt, live, files, size, reason }] }velven rollback 3          # version 3 goes live againvelven rollback            # in a terminal: lists the versions and asks which

A version's status is uploading, preview, checking, live, refused, unjudged (the check could not judge it), or replaced (a newer version took its place, or the space moved to another address before its check finished). A rollback goes only to a version that was live before.

versions, rollback and reset act on the space velven.json in the current folder names; --space <slug> picks another of yours.

dev

Terminal
velven dev [dir]            # serve the folder and play it on Velvenvelven dev [dir] --port 5173

dev serves the folder on your machine, with no caching and the SDK tag added to the entry page as hosting adds it, and honours entry and spa. It opens https://velven.ai/dev, a Velven page that frames your local server with the player in sandbox mode. Signed in on Velven as the space's owner, sign-in, boards, saves, achievements, stats, content and rooms all work on the real API, and everything they write goes to the space's sandbox.

  • The sandbox belongs to a space, so publish once first: dev reads the space from velven.json. Before that it serves the page, and SDK calls answer unavailable. To test with a friend, send them a preview instead.
  • Edit a file and reload the page to see it; there is no build step or watcher of its own. Point it at your build's output folder, or run your own dev server and open the /dev page with its address.
  • It serves what publish sends, by the same rule: nothing .velvenignore names (a file under an ignored folder included), and dotfiles, node_modules and velven.json never, in any case, nor a name that ends in a dot or a space or holds : or ~, nor a link to anything outside the folder. A path is served only in the letter case the folder spells it, as the live version looks paths up: Assets/Hero.png does not open assets/hero.png, even on a disk that ignores case.
  • Press Ctrl+C to stop.

Note: For work with no network at all, the SDK's local environment fakes players and boards on the page itself.

reset

Terminal
velven reset                         # the whole sandbox, after a confirmationvelven reset --scores --saves        # only these kindsvelven reset --player mara --yes     # one player's sandbox data, without asking

reset deletes the test data previews and velven dev wrote: --scores, --saves, --achievements, --content and --rooms, all of them by default. Live players' data is never touched. Sandbox data also clears itself 30 days after its last write.

Environment variables

VELVEN_TOKEN
A token to use instead of the saved sign-in, for CI. It takes precedence over velven login.
VELVEN_APIA web addressDefault https://velven.ai
The Velven to talk to, when you run one of your own for development.

JSON output

With --json, publish, versions and whoami print one JSON object and nothing else, and every failure prints { ok: false, error, code, fields? }: error a sentence to show a person, code a stable name to branch on.

JSON
{  "ok": true,  "space": { "slug": "star-hop", "url": "https://velven.ai/s/star-hop" },  "version": { "id": "…", "number": 4 },  "status": "live",  "watchUrl": "https://velven.ai/s/star-hop/edit/files?version=…",  "pageUrl": "https://velven.ai/mara/star-hop",  "uploaded": 2,  "reused": 37}

status is preview with a previewUrl, checking without --wait, or the verdict with it, with reason and shownOnTake for a version refused or not judged. Signed out, it adds pageUrl, claimToken, claimUrl and expiresAt.

Code
missing_fields
Meaning
velven.json lacks a required field; fields names them.
Code
invalid_config
Meaning
velven.json is not valid JSON, or a field has the wrong shape.
Code
no_entry
Meaning
The folder has no index.html, or no file at entry.
Code
not_owner
Meaning
space in velven.json is someone else's space.
Code
too_large, too_many_files
Meaning
The version is over the limits; the largest files are named.
Code
sign_in_required
Meaning
--prod without an account.
Code
claim_spent
Meaning
Exit 3: signed out, with "claim" in velven.json for a page that was claimed (in the browser, say). Run velven login as the account that claimed it and publish again. Claimed while velven publish uploads: "The page was claimed before this version was finished. Run velven login and publish again." Claimed while --wait waits: "The page was claimed. Follow the check on its Files tab", with the link.
Code
rate_limited
Meaning
Too many publishes; the sentence says when to try again.
Code
not_signed_in
Meaning
A command that needs an account, signed out.

Exit codes

Code
0
Meaning
Done.
Code
1
Meaning
Failed: the network, a server error, a failed upload, or a cancelled prompt.
Code
2
Meaning
A mistake in the command or in velven.json, such as an unknown flag or a missing field.
Code
3
Meaning
Not signed in, or the token was refused, for something that needs an account, such as --prod.
Code
4
Meaning
Refused by Velven: not your space, too large, too many files, not found, invalid fields.
Code
5
Meaning
Rate limited. Try again later.
Code
6
Meaning
With --wait: the safety check refused the version or could not judge it.

Publish from CI

Sign in once with velven login, copy the token from ~/.config/velven/auth.json into your CI's secrets as VELVEN_TOKEN, and make sure velven.json with "space" is committed. Then publish with no prompts and wait for the verdict, so the job fails when the check refuses the version:

yaml
# .github/workflows/publish.ymlon:  push:    branches: [main]jobs:  publish:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4      - uses: actions/setup-node@v4        with:          node-version: 22      - run: npm ci && npm run build      - run: npx @velven/cli publish ./dist --prod --yes --wait        env:          VELVEN_TOKEN: ${{ secrets.VELVEN_TOKEN }}

Note: Revoke a token you no longer use in your settings. A refused token exits 3.