by is the command-line client for Blockyard. It handles authentication, deployment, app management, and administration from your terminal.

Global flags#

FlagDescription
--jsonOutput machine-readable JSON (all commands)

When --json is set, all output (including errors) is printed as pretty-printed JSON. Errors use the shape {"error": "...", "message": "..."}.

Authentication#

by login#

Store credentials interactively. Opens a browser to create a Personal Access Token, then verifies it against the server.

by login
by login --server https://blockyard.example.com
FlagDescription
--server <url>Server URL (prompts interactively if omitted)

Credentials are saved to ~/.config/by/config.json (respects $XDG_CONFIG_HOME) with file mode 0600.

Environment variable override. Instead of by login, you can set both BLOCKYARD_URL and BLOCKYARD_TOKEN. When both are present they take precedence over the config file.


Deploying#

by deploy <path>#

Deploy a Shiny app to Blockyard. This is the primary workflow command — it detects dependencies, creates a bundle archive, uploads it, and optionally waits for the build to finish.

by deploy .
by deploy ./my-app --name dashboard --pin --wait
by deploy ./my-app --yes --wait
FlagDescription
--name <string>Override app name (default: directory basename)
--pinPin dependencies via renv::snapshot() (requires R + renv)
-y, --yesSkip the confirmation prompt
--waitWait for the build to complete and stream logs
--repositories <csv>R package repository URLs (comma-separated)

Dependency detection (in priority order):

  1. manifest.json exists — used as-is
  2. renv.lock exists — converted to manifest
  3. --pin flag — runs renv::snapshot(), then converts
  4. DESCRIPTION exists — builds an unpinned manifest
  5. Bare R scripts — uploaded without manifest

The command auto-detects the app entrypoint (app.R or server.R), computes SHA-256 checksums for all files, creates a gzip tar archive, and uploads it. If the app does not exist on the server yet, it is created automatically.

Example output:

Detected:
  Name:        dashboard
  Mode:        DESCRIPTION (entrypoint: app.R)
  Deps:        3 packages
  Repository:  https://cran.r-project.org

Deploy? [Y/n] y

Uploading bundle... done.

  App:       dashboard
  Bundle:    b1a2b3c4 (building)
  Task:      t9876...
  URL:       https://blockyard.example.com/app/dashboard/

by init <path>#

Generate a manifest.json without deploying. Useful for inspecting or committing the resolved manifest before deploying.

by init .
by init ./my-app --pin --repositories https://cran.r-project.org
FlagDescription
--pinPin dependencies via renv::snapshot()
--repositories <csv>R package repository URLs (comma-separated)

If manifest.json already exists, validates it and exits successfully (no new file is written). Does not support bare-script apps — at least a DESCRIPTION is required.


App management#

by list#

List all apps. Alias: by ls.

by list
by list --deleted
by ls --json
FlagDescription
--deletedInclude soft-deleted apps (admin only)

Example output:

NAME        TITLE                OWNER     STATUS    ENABLED
dashboard   Sales Dashboard      alice     running   yes
demo        Demo App             bob       stopped   yes

by get <app>#

Show details for a single app.

by get dashboard
by get dashboard --runtime
FlagDescription
--runtimeInclude live runtime data (workers, sessions, metrics)

Without --runtime, shows static metadata (ID, owner, status, enabled state, access mode, title, description, active bundle, resource limits, tags, creation date). With --runtime, appends worker table and session/view statistics.

by enable <app>#

Enable an app, allowing traffic to reach it.

by enable dashboard

by disable <app>#

Disable an app. Blocks new traffic and drains active sessions.

by disable dashboard

by delete <app>#

Soft-delete an app. Alias: by rm.

by delete demo
by rm demo --purge
FlagDescription
--purgePermanently delete (admin only; app must be soft-deleted first)

by restore <app>#

Restore a soft-deleted app.

by restore demo

by update <app>#

Update app metadata. At least one flag is required.

by update dashboard --title "Sales Dashboard v2"
by update dashboard --description "Regional sales metrics"
FlagDescription
--title <string>Display title
--description <string>Description text

Bundles#

by bundles <app>#

List all bundles for an app.

by bundles dashboard

Example output:

ID              STATUS    UPLOADED              DEPLOYED BY   PINNED
b1a2b3c4b1a2    success   2026-03-28T08:00:00Z  alice         yes
d5e6f7a8d5e6    success   2026-03-27T14:30:00Z  bob           no

by rollback <app> <bundle-id>#

Roll back to a previous bundle.

by rollback dashboard d5e6f7a8d5e6

Scaling#

by scale <app>#

Configure resource limits and autoscaling. At least one flag is required.

by scale dashboard --memory 1g --cpu 2.0
by scale dashboard --max-workers 4 --pre-warm 1
FlagDescription
--memory <string>Memory limit (e.g., 512m, 2g)
--cpu <float>CPU limit (e.g., 1.0, 2.5)
--max-workers <int>Maximum workers per app
--max-sessions <int>Maximum sessions per worker
--pre-warm <int>Pre-warmed standby workers

Only the flags you provide are updated; omitted fields are left unchanged.


Access control#

by access show <app>#

Show the access type and ACL entries for an app.

by access show dashboard

Example output:

Access type: acl

PRINCIPAL              KIND    ROLE           GRANTED BY
alice@example.com      user    collaborator   admin
bob@example.com        user    viewer         admin

by access set-type <app> <type>#

Set the access mode. Valid types:

TypeDescription
aclPer-user access control list
logged_inAny authenticated user
publicNo authentication required
by access set-type dashboard acl
by access set-type demo public

by access grant <app> <user>#

Grant a user access to an app.

by access grant dashboard bob@example.com
by access grant dashboard bob@example.com --role collaborator
FlagDescription
--role <string>Role to grant: viewer (default) or collaborator

by access revoke <app> <user>#

Revoke a user’s access.

by access revoke dashboard bob@example.com

Tags#

by tags list#

List all tags in the global pool.

by tags list

by tags create <tag>#

Create a tag (admin only).

by tags create production

by tags delete <tag>#

Delete a tag (admin only). Cascades — the tag is also removed from all apps.

by tags delete staging

by tags app-list <app>#

List tags attached to an app. Hidden from by tags --help but functional.

by tags app-list dashboard

by tags app-add <app> <tag>#

Attach a tag to an app. Hidden from by tags --help but functional.

by tags app-add dashboard production

by tags app-remove <app> <tag>#

Detach a tag from an app. Hidden from by tags --help but functional.

by tags app-remove dashboard staging

Dependencies#

by refresh <app>#

Refresh unpinned dependencies. Triggers a background task that re-resolves packages from configured repositories and streams the task logs.

by refresh dashboard
by refresh dashboard --rollback
FlagDescription
--rollbackRoll back to the previous dependency set instead

This is useful for apps deployed from a DESCRIPTION (unpinned) — it pulls the latest compatible package versions without requiring a new bundle upload.


Logs#

by logs <app>#

View or stream app logs.

by logs dashboard
by logs dashboard --follow
by logs dashboard --worker w-abc123 --follow
FlagDescription
-f, --followStream logs live (default: static snapshot)
-w, --worker <id>Worker ID (auto-selects most recent if omitted)

When multiple workers exist and --worker is not specified, the most recently started active worker is selected. If no active workers exist, the most recently ended worker is used.


User administration#

These commands require the admin system role.

by users list#

List all users.

by users list

Example output:

SUB                          NAME       EMAIL                ROLE       ACTIVE
google-oauth2|abc123         Alice      alice@example.com    admin      yes
google-oauth2|def456         Bob        bob@example.com      publisher  yes

by users update <sub>#

Update a user’s role or active status. At least one flag is required.

by users update "google-oauth2|def456" --role admin
by users update "google-oauth2|def456" --active=false
FlagDescription
--role <string>Set role: admin, publisher, or viewer
--active <bool>Enable or disable the user account (default: true)

Configuration#

The CLI stores credentials in ~/.config/by/config.json (or $XDG_CONFIG_HOME/by/config.json):

{
  "server": "https://blockyard.example.com",
  "token": "by_..."
}

Credential resolution order:

  1. BLOCKYARD_URL + BLOCKYARD_TOKEN environment variables (both required)
  2. Config file
  3. Error if neither is available