# BILD CLI

Command-line tool for managing BILDIT CMS Templates. Upload, transpile, version, and manage template components for React and Next.js applications.

## Installation

### Global Installation (Recommended)

Install the CLI globally to use it from anywhere:

```bash
npm install -g bild-cli
```

After installation, you can use the `bild` command from any directory:

```bash
bild --help
```

### Local Installation

Install the CLI locally in your project:

```bash
npm install bild-cli
```

When installed locally, use it via `npx`:

```bash
npx bild --help
```

Or add it to your `package.json` scripts:

```json
{
  "scripts": {
    "bild": "bild"
  }
}
```

Then run:

```bash
npm run bild --help
```

### Requirements

- Node.js version 20 or higher
- npm or yarn package manager

## Quick Start

1. **Install the CLI:**
   ```bash
   npm install -g bild-cli
   ```

2. **Initialize configuration:**
   ```bash
   bild init
   ```

3. **Authenticate with BILDIT CMS:**
   ```bash
   bild login <cms-url>
   # Example: bild login https://your-cms-instance.web.app
   ```

4. **List available apps:**
   ```bash
   bild app list
   ```

5. **Add a template:**
   ```bash
   bild library add hero.jsx --app-id <app-id> --template-id hero --image ./preview.png
   ```

## Usage

### Using npm

After installing globally with `npm install -g bild-cli`, you can use `bild` from any directory:

```bash
bild --help
bild app list
bild library add my-component.jsx
```

### Using npx (without installation)

You can also use the CLI without installing it globally:

```bash
npx bild-cli --help
npx bild-cli app list
npx bild-cli library add my-component.jsx
```

### Using as npm script

Add to your `package.json`:

```json
{
  "scripts": {
    "bild": "bild",
    "bild:add": "bild library add",
    "bild:update": "bild library update",
    "bild:list": "bild app list"
  }
}
```

Then run:

```bash
npm run bild --help
npm run bild:add hero.jsx --app-id my-app
npm run bild:list
```

## Commands

### `bild init`

Initialize the configuration file (`~/.bild.json`) with default settings.

```bash
bild init
```

Prompts for:
- BILDIT CMS instance URL
- Default App ID (optional)
- Default API Key (optional)
- React version

### `bild login [url]`

Authenticate with BILDIT CMS using OAuth. Opens a browser for authentication.

```bash
bild login
bild login https://your-cms-instance.web.app
```

The authentication token is stored securely using the system keychain.

### `bild library add <files...>`

Add/create a new template in BILDIT CMS (Templates). Supports individual files or folders.

```bash
# Add single file (will prompt for missing info)
bild library add hero.jsx

# Add file with all options
bild library add hero.jsx \
  --app-id <app-id> \
  --template-id hero \
  --code-type jsx \
  --type Homepage \
  --name HeroStandard \
  --description "Hero banner component" \
  --image ./preview.png

# Add multiple files
bild library add hero.jsx footer.jsx --app-id <app-id>

# Add all files from a folder
bild library add ./components --app-id <app-id>
```

**Options:**
- `--app-id <id>` - App ID (uses defaultAppId from config if not provided)
- `--template-id <id>` - Template ID (extracted from filename if not provided)
- `--code-type <type>` - Code type: jsx, tsx, or html (detected from file extension)
- `--type <type>` - Template type (default: "Homepage")
- `--description <desc>` - Description for the template
- `--name <name>` - Display name (defaults to template ID)
- `--image <url>` - Image URL or local file path (will be uploaded if local file)

**Aliases:** `bild library create` (same as `add`)

### `bild library pull [output-dir]`

Export all templates for the current app to disk. Each item is written under a **type** folder (spaces normalized to underscores), with source as `{templateId}.{js|jsx|ts|tsx|html}` and metadata as `{templateId}.json` (name, description, type, image URL, codeType, appType, templateId).

```bash
bild library pull
bild library pull ./my-templates --app-id my-app
bild library pull --output ./exports --app-id my-app
```

**Options:**
- `--app-id <id>` - App ID (uses defaultAppId from config if not provided)
- `--output <dir>` - Output directory (overrides positional `output-dir`; default `./template-library`)

### `bild library list` / `bild library ls`

List templates for the app. By default prints a compact table of **Template ID** and **Name** columns (the Template ID is what you pass to `bild library update` and `bild library delete`). Use **`--verbose`** for the full listing (extra fields such as template name when it differs, description, type, code type, app type, custom flag)—this replaces the former `bild list-code-libs` command.

```bash
bild library list
bild library ls --app-id my-app
bild library list --verbose
bild library list --verbose --app-id my-app
```

**Options:**
- `--app-id <id>` - App ID (uses defaultAppId from config if not provided)
- `-v`, `--verbose` - Show full detail per item

### `bild library update <files...>`

Update an existing template in BILDIT CMS.

```bash
# Update (will prompt to select item if template-id not provided)
bild library update hero.jsx

# Update with template-id (no prompt)
bild library update hero.jsx --template-id herostandard7

# Update with all options
bild library update hero.jsx \
  --template-id herostandard7 \
  --app-id <app-id> \
  --code-type jsx \
  --type Homepage \
  --name HeroStandard \
  --image ./preview-new.png
```

**Options:**
- `--app-id <id>` - App ID (uses defaultAppId from config if not provided)
- `--template-id <id>` - Template ID: the template name, or the value in the **Template ID** column from `bild library list` (if not provided, you will be prompted; for values that start with a hyphen, use e.g. `--template-id=-…` or quotes)
- `--root <dir>` - Batch update: walk a template library export folder tree from `bild library pull` (`{type}/{templateId}.{ext}` + `{templateId}.json`) and push every item
- `--code-type <type>` - Code type: jsx, tsx, or html (detected from file extension)
- `--type <type>` - Template type (keeps existing if not provided)
- `--description <desc>` - Description (keeps existing if not provided)
- `--name <name>` - Display name (keeps existing if not provided)
- `--image <url>` - Image URL or local file path (keeps existing if not provided)

```bash
# Batch update everything under an exported tree
bild library update --root ./template-library --app-id my-app
```

**Supported file types:**
- `.js`, `.jsx`, `.ts`, `.tsx`, `.html`
- Template files (`.template.jsx`)

**What happens during upload:**
1. File is read and code type is detected
2. Code is linted (ESLint + Tailwind validation)
3. Code is transpiled for Next.js/React compatibility
4. Screenshot is captured (if no image provided)
5. Template is created/updated in CMS
6. New version is created automatically

### `bild library delete [template-id]`

Delete a template from the app. Pass the same **Template ID** as in `bild library list` (first column), or use `--template-id` when the value starts with a hyphen.

```bash
bild library delete cl_abc123 --app-id my-app
bild library delete --template-id=-OrFkw6Pb8ZeCuMkx-Cg --app-id my-app
bild library delete -- -OrFkw6Pb8ZeCuMkx-Cg --app-id my-app
```

**Options:**
- `--app-id <id>` - App ID (uses defaultAppId from config if not provided)
- `--template-id <id>` - Template ID (optional if you pass it as the positional argument; use this form when the value starts with `-`)
- `-y`, `--yes` - Skip the confirmation prompt

### `bild app list`

List all available apps and websites in the BILDIT CMS.

```bash
bild app list
```

Displays:
- App/Website ID
- Name
- Type (App for React Native, Website for React/Next.js)
- Description (if available)

### `bild use`

Select and set a default app or website from the available list.

```bash
bild use
```

This will:
1. Fetch all available apps and websites
2. Show an interactive list to select from
3. Update your `~/.bild.json` config with the selected app ID

### `bild library copy <template-id>`

Copy a template from one app to one or more target apps.

```bash
# Copy to single target app
bild library copy herostandard7 --from PaintingBanner --to belk-dev-web

# Copy to multiple target apps
bild library copy herostandard7 --from PaintingBanner --to app1 app2 app3
```

**Options:**
- `--from <app-id>` - Source app ID (required)
- `--to <app-ids...>` - Target app ID(s) (required, can specify multiple)

**Note:** The template-id argument must come before the options.

### `bild banner update <template-id>`

Update banners that use a specific template with the latest version.

```bash
# Update all future-dated unpublished banners
bild banner update herostandard7 --app-id <app-id>

# Update banners within date range
bild banner update herostandard7 \
  --app-id <app-id> \
  --start-date 2024-01-01 \
  --end-date 2024-12-31

# Override published banner restriction
bild banner update herostandard7 \
  --app-id <app-id> \
  --override
```

**Options:**
- `--app-id <id>` - App ID (required)
- `--start-date <date>` - Start date filter (ISO format)
- `--end-date <date>` - End date filter (ISO format)
- `--override` - Update published banners (default: only unpublished)

**Banner filtering:**
- Only updates banners that use the specified template ID
- Only updates unpublished banners (unless `--override` is used)
- Only updates banners with future-dated schedules
- Respects date range filters if provided

### `bild template` (v2, default)

**V2** commands are for **pure JavaScript / JSX** files you publish to **Templates** (no BILDIT `$()` template preprocessing). No `--legacy` flag is required.

#### `bild template init <name>`

Scaffold a minimal starter **v2** component (plain JSX, no `$()` fields).

```bash
bild template init hero-standard           # writes hero-standard.jsx
bild template init hero-standard --ts      # writes hero-standard.tsx
```

#### `bild template validate <file>`

Lint + transpile the file **without** `$()` preprocessing (matches how v2 uploads are validated).

```bash
bild template validate Hero.jsx
bild template validate Hero.jsx --no-lint --quiet
```

#### `bild template from-jsx <file>`

Copy a JSX/TSX file to an output path for upload (no `$()` codemod). Default output: `<name>.export.<ext>` next to the source.

```bash
bild template from-jsx hero.jsx
bild template from-jsx hero.jsx --out ./ready/Hero.jsx --strict
```

#### `bild template pull [template-id]`

Download raw source from the CMS (works for v1 or v2 libraries).

```bash
bild template pull herostandard7 --app-id my-app
bild template pull --out ./pulled/hero.tsx
```

---

### `bild template legacy` (v1, `$()` syntax)

**V1** BILDIT templates use `$(field:Type="default")` syntax. The codemod and preprocess path live under **`template legacy`**.

#### `bild template legacy from-jsx <file>`

Rewrite JSX/TSX into a self-contained BILDIT `$()` template (inline CSS, deps extraction, field tagging). Same behavior as the former top-level `template from-jsx`.

```bash
bild template legacy from-jsx hero.jsx
bild template legacy from-jsx hero.jsx --dry-run
bild template legacy from-jsx hero.jsx --css-mode style-tag --strict
bild template legacy from-jsx hero.jsx --deps-file ../my-site/src/cmsDependencies.ts
```

**Options:** `--out`, `--css-mode`, `--naming`, `--site-path`, `--deps-file`, `--deps-alias`, `--dry-run`, `--strict`, `--no-verify` (see previous docs; defaults unchanged).

A sidecar `.bild/<name>.field-map.json` is written next to the source for repeat runs.

#### `bild template legacy validate <file>`

Preprocess `$()` → lint + transpile (same path as `library add` for v1 templates).

```bash
bild template legacy validate hero.template.tsx
```

#### `bild template legacy init <name>`

Scaffold a starter file with example `$(...)` fields (RichText, Color, String).

```bash
bild template legacy init hero-standard
```

#### `bild template legacy pull [template-id]`

Same as `bild template pull` (raw download from CMS).

## Configuration

Configuration is stored in `~/.bild.json`:

```json
{
  "cmsUrl": "https://your-cms-instance.web.app",
  "defaultAppId": "your-app-id",
  "defaultApiKey": "your-api-key",
  "reactVersion": "18.2.0",
  "sitePath": "/path/to/your/site",
  "cmsDependenciesFile": "src/cmsDependencies.ts",
  "cmsDependenciesImportAlias": "@/cmsDependencies",
  "cssMode": "hybrid",
  "namingStrategy": "camelComponent"
}
```

**Template-related keys:**
- `sitePath` - Path to the consumer site where `cmsDependencies` lives.
- `cmsDependenciesFile` - Path (relative to `sitePath`) to the deps file that receives relocated utilities.
- `cmsDependenciesImportAlias` - Import alias written into templates (typically a `tsconfig.json` path alias).
- `cssMode` - Default CSS resolution mode for `template legacy from-jsx`.
- `namingStrategy` - Default field naming strategy.

`bild template from-jsx` / `from-tsx` (and `template legacy from-jsx`) keep **npm package imports** (e.g. `lucide-react`) as normal `import { … } from "pkg"` lines in the template. Only **relative** and **`@/…`** imports are pulled into `cmsDependencies`.

## Features

### Code Transpilation

Code is automatically transpiled using Babel to ensure compatibility with Next.js and React applications. Supports:
- JavaScript (`.js`)
- JSX (`.jsx`)
- TypeScript (`.ts`, `.tsx`)
- HTML (`.html`)

### Linting

Integrated linting checks:
- ESLint with React/JSX rules
- Tailwind CSS class validation
- Template syntax validation (`$(variable:Type)`)

### Screenshot Capture

Automatically captures screenshots of template components using Playwright:
- Maximum width: 500px
- Maintains aspect ratio
- Supports URL or local file rendering

### Version Management

Automatic versioning:
- Versions are auto-incremented (v1, v2, v3...)
- Stored at `/apps/{appId}/codelibs/{id}/versions/{versionId}` on the CMS (template library REST API uses the `codelibs` path segment; the record id is the **Template ID** shown in `bild library list`)
- Each version includes raw code, compiled code, and preview image

## Error Handling

The CLI provides user-friendly error messages for common issues:
- Authentication errors
- API errors
- Validation errors
- File not found errors

## Examples

### Add a new template

```bash
bild library add src/components/HeroStandard.jsx \
  --app-id my-app \
  --template-id herostandard \
  --code-type jsx \
  --type Homepage \
  --name HeroStandard \
  --image ./hero-preview.png
```

### Update an existing template

```bash
bild library update src/components/HeroStandard.jsx \
  --template-id herostandard7 \
  --app-id my-app \
  --image ./hero-preview-new.png
```

### Copy component across apps

```bash
bild library copy herostandard7 --from app1 --to app2 app3 app4
```

### Update banners for upcoming campaign

```bash
bild banner update herostandard7 \
  --app-id my-app \
  --start-date 2024-02-01 \
  --end-date 2024-02-29
```

### List available apps and websites

```bash
bild app list
```

### List templates for an app

```bash
bild library list --app-id my-app
bild library list --verbose --app-id my-app
```

### Set default app

```bash
bild use
# Follow the interactive prompt to select an app
```

## Troubleshooting

### Authentication Issues

If you encounter authentication errors:
1. Run `bild login` again to refresh your token
2. Ensure the CMS URL is correct
3. Check that your browser can access the CMS instance

### CMS / backend access issues

Some commands require direct CMS or backend access. If you encounter errors:
- Ensure your authentication token has proper permissions
- Verify the database / realtime URL format your instance expects
- Check that the app ID exists in the CMS

### Transpilation Errors

If code fails to transpile:
- Check for syntax errors in your code
- Ensure all imports are valid
- Verify React version compatibility

## Contributing

This CLI tool follows the BILDIT CMS contributing guidelines for code quality and linting standards.

## License

ISC

