# BRICKS CLI

Command-line interface for BRICKS Workspace API with interactive mode support.

## Installation

```bash
# From the monorepo root
bun install

# Or install globally (after publishing)
npm install -g @fugood/bricks-cli
```

## Quick Start

```bash
# Login with a one-time passcode (recommended)
bricks auth login <passcode>

# Or login with your workspace token directly
bricks auth login-token -t <your-workspace-token>

# Check connection status
bricks auth status
bricks auth status --json

# Machine-readable environment check
bricks doctor --json

# List devices
bricks device list
bricks device resolve "Lobby"

# Start interactive mode
bricks interactive

# Change API endpoint (prod, beta, dev)
bricks config endpoint beta

# If Media Flow is enabled in your workspace
bricks media boxes
```

## Authentication Methods

### Method 1: One-Time Passcode (Recommended)

The easiest way to authenticate is using a one-time passcode:

1. Go to [BRICKS Controller](https://control.bricks.tools)
2. Navigate to Workspace Settings > API Token
3. Click "Create CLI Passcode"
4. Use the passcode in the CLI:
   ```bash
   bricks auth login <passcode>
   ```

The passcode is valid for 5 minutes and can only be used once. This method is more secure as you don't need to copy/paste long tokens.

### Method 2: Direct Token

You can also login with a workspace token directly:

1. Go to [BRICKS Controller](https://control.bricks.tools)
2. Navigate to Workspace Settings > API Token
3. Generate a new token with the required permissions
4. Use the token in the CLI:
   ```bash
   bricks auth login-token -t <your-workspace-token>
   ```

## Commands

### Authentication

```bash
# Login with one-time passcode (recommended)
bricks auth login <passcode> [-p profile-name]

# Login with token
bricks auth login-token -t <token> [-p profile-name]

# Check status
bricks auth status [-j|--json]

# List all profiles
bricks auth list

# Switch profile
bricks auth use <profile-name>

# Logout
bricks auth logout [-p profile-name] [--all]

# Set custom API URL
bricks auth set-url <url>
```

### Doctor

```bash
# Check config, auth, workspace reachability, MCP availability
bricks doctor
bricks doctor --json
```

### Self-update

```bash
# Update the CLI in-place. Auto-detects how it was installed (npm, bun,
# standalone binary) and runs the matching update command. Falls back to
# the binary installer if the primary method fails.
bricks update-cli         # prompts before updating
bricks update-cli -y      # non-interactive

# Force a channel
bricks update-cli --channel beta
```

### Configuration

```bash
# Show current endpoint configuration
bricks config endpoint

# Change API endpoint environment
bricks config endpoint prod   # Production (default): https://display.bricks.tools
bricks config endpoint beta   # Beta: https://display-beta.bricks.tools
bricks config endpoint dev    # Development: http://localhost:3001

# Show current configuration
bricks config show [-j|--json]
```

### Device Management

```bash
# List all devices
bricks device list [-k keyword] [-j|--json]

# Resolve a device name or ID
bricks device resolve <query> [-l limit] [-j|--json]

# Get device details
bricks device get <device-id> [-j|--json]

# Bind a new device with passcode
bricks device bind <passcode> [-n device-name]
bricks device bind <passcode> [--dry-run] [-j|--json]

# Control device
bricks device control <device-id> <type> [-p payload] [--dry-run] [-j|--json]
bricks device refresh <device-id> [--dry-run] [-j|--json]
bricks device clear-cache <device-id> [--dry-run] [-j|--json]
bricks device screenshot <device-id>

# Monitor devices (real-time polling)
bricks device monitor [-g group-id] [-i interval-seconds]
```

Control types: `refresh`, `clear-cache`, `take-screenshot`, `system-menu`, `system-menu-open`, `system-menu-close`, `debug-panel`, `debug-panel-open`, `debug-panel-close`, `logging-on`, `logging-off`, etc.

### Application Management

```bash
# List applications
bricks app list [-k keyword] [-j|--json]

# Resolve an application name or ID
bricks app resolve <query> [-l limit] [-j|--json]

# Get application details
bricks app get <app-id> [-c|--composed] [-j|--json]

# Update application
bricks app update <app-id> [-n name] [-d description] [-c config-json] [-f config-file] [--validate]

# Short edit application (requires valid shortIds from app config)
bricks app short-edit <app-id> -l '[{"shortId":"<subspace-short-id>","path":"property.name","content":"value"}]'

# Bind/unbind devices
bricks app bind <app-id> [-b device-ids] [-u device-ids]
bricks app bind <app-id> [-b device-ids] [-u device-ids] [--dry-run] [-j|--json]

# Trigger automation
bricks app trigger <app-id> <test-id> [--play|--stop] [--setup-at-launch]

# Preview a release without publishing
bricks app release <app-id> -c <config-path-or-json> [-n name] [--version version] [--changelogs text] [--dry-run] [-j|--json]
```

### Module Management

```bash
# List modules
bricks module list [-k keyword] [-j|--json]

# Resolve a module name or ID
bricks module resolve <query> [-l limit] [-j|--json]

# Get module details
bricks module get <module-id> [-j|--json]

# Update module
bricks module update <module-id> [-n name] [-d description] [-c config-json] [-f config-file] [--validate]

# Short edit module (requires valid shortIds from module config)
bricks module short-edit <module-id> -l '[{"shortId":"<subspace-short-id>","path":"property.name","content":"value"}]'

# Preview a release without publishing
bricks module release <module-id> -c <config-path-or-json> [-n name] [--version version] [--changelogs text] [--dry-run] [-j|--json]
```

### Device Group Management

```bash
# List device groups
bricks group list [-j|--json]

# Resolve a device group name or ID
bricks group resolve <query> [-l limit] [-j|--json]

# Get group details
bricks group get <group-id> [-j|--json]

# List devices in group with status
bricks group devices <group-id> [-j|--json]

# Dispatch action to all devices
bricks group dispatch <group-id> <action> [--dry-run] [-j|--json]
bricks group refresh <group-id> [--dry-run] [-j|--json]

# Monitor group (real-time polling)
bricks group monitor <group-id> [-i interval-seconds]
```

### Media Flow

Media Flow commands require:
- Workspace has Media Flow enabled (`Workspace Settings → Media Flow`).
- Your token includes `query_media_flow` permission (and `write_media_flow` for future upload/mutation features).

```bash
# List Media Flow boxes
bricks media boxes [-j|--json]

# Get a Media Flow box
bricks media box <box-id> [-j|--json]

# List files in a box
bricks media files <box-id> \
  [--types Image,Video,Audio] \
  [--user-tag <tag> ...] \
  [-l limit] [-o offset] [-j|--json]

# Get a Media Flow file (prints original + thumbnail URLs)
bricks media file <file-id> [-j|--json]
```

### Data Bank (Remote Properties)

Manage the workspace Data Bank: settings and space keys go through the Workspace API
(workspace token); property CRUD talks to the Data Bank API directly using a space key.
On the first property command the CLI issues a key via the Workspace API and saves it
to the active profile (`~/.bricks-cli/config.json`) — no manual setup needed.

```bash
# Workspace-level settings
bricks data status [-j|--json]       # also shows the stored CLI key (masked)
bricks data enable
bricks data disable

# Stored CLI key management
bricks data login [--name <keyName>] # (re)issue a key and save it to the profile
bricks data logout [--revoke]        # remove the stored key; --revoke also revokes it

# Space key management (human output masks key values; --json includes them)
bricks data keys list [-j|--json]
bricks data keys new <name> \
  [--expire-at <ISO date>] \          # between 1 hour and 90 days from now
  [--read <propId,...>] \             # limit readable properties
  [--write <propId,...>] \            # limit writable properties
  [-j|--json]
bricks data keys revoke <keyValue|name> [-y] [-j|--json]

# Property CRUD (Data Bank API, uses the stored key)
bricks data list [-k keyword] [-m InSubspace|Global] [-j|--json]
bricks data get <propertyId> [-j|--json]
bricks data set <propertyId> \
  [-v <json-or-string> | --value-file <path>] \
  [-d <definition-json> | --definition-file <path>] \
  [-m InSubspace|Global] [-t tag1,tag2] [-n "<update note>"] \
  [--no-upsert]  \                    # fail when the property does not exist
  [--no-notify]  \                    # skip notifying subscribed devices
  [--dry-run] [-j|--json]
bricks data remove <propertyId> [-y] [--dry-run] [-j|--json]
```

Notes:
- `set` is an upsert by default and notifies subscribed devices, the same as editing in the controller Bank page.
- When no `-v/--value-file` is given, `set` keeps the current value (useful to change only tags or the definition).
- `-v` parses the input as JSON and falls back to a plain string (`-v '{"a":1}'` → object, `-v hello` → string).
- Revoking the auto-provisioned `manager` / `used-by-device` keys rotates them instead of deleting them.
- The Data Bank endpoint is derived from the configured BRICKS endpoint
  (prod → `bank.bricks.tools`, beta → `bank-beta.bricks.tools`, dev → `localhost:8080`).
- Environment overrides for CI / custom setups: `BRICKS_BANK_SPACENAME` + `BRICKS_BANK_SPACEKEY`
  (skip the stored key) and `BRICKS_BANK_ENDPOINT` (custom Bank URL).

### Interactive Mode

```bash
# Start interactive TUI
bricks interactive
# or
bricks i
# or just run `bricks` from a TTY
```

The interactive mode provides a terminal UI built with [Ink](https://github.com/vadimdemedes/ink) for:
- Browsing devices and applications
- Controlling devices with a menu
- Viewing real-time status
- Browsing Media Flow boxes and files (when enabled)
- Quick navigation with keyboard

Controls:
- `↑/↓` or `j/k`: Navigate
- `Enter`: Select
- `Esc`: Go back
- `q`: Quit

When `bricks` is run without arguments in a non-TTY context such as Codex, CI, or shell pipelines, it prints help instead of launching Ink.

### Desktop ACP Bridge

Connect external ACP clients (e.g. [acpx](https://github.com/openclaw/acpx)) to the running CTOR Desktop app.

```bash
# Stdio mode (default) — pipes stdin/stdout ↔ ~/.bricks-project-desktop/acp.sock
bricks desktop-acp-bridge

# WebSocket mode — exposes the Unix socket as a WebSocket server
bricks desktop-acp-bridge --ws
bricks desktop-acp-bridge --ws --host 127.0.0.1 --port 8765
bricks desktop-acp-bridge --ws --auth-token <secret>
```

In WebSocket mode each client connection opens a dedicated bridge to the ACP Unix socket. Messages are exchanged as newline-delimited JSON-RPC: one WS text frame per JSON-RPC message. When `--auth-token` is set (or `BRICKS_DESKTOP_ACP_BRIDGE_TOKEN` is exported), the server requires the matching `Authorization: Bearer <token>` header on the WebSocket upgrade request.

> The default bind host is `0.0.0.0` — WebSocket mode is intended to expose ACP on the LAN. Always set `--auth-token` and only run on trusted networks. Use `--host 127.0.0.1` to restrict to localhost.

### Workspace Info

```bash
bricks workspace [-j|--json]
# or
bricks ws
```

## Configuration

Configuration is stored in `~/.bricks-cli/config.json`:
- Multiple profile support
- API endpoint configuration (prod/beta/dev)
- Token storage

Use `bricks config show` to view current settings, `bricks config endpoint` to switch environments, or `bricks doctor --json` for a machine-readable health check.

## License

UNLICENSED
