---
name: loom-cli
description: |
  Generate videos, images, and chat with LLMs via the `loom` CLI.
  No API keys needed — one email login gives access to video generation,
  image generation, and LLM chat through a unified platform.
  Use when the user wants to: create AI videos, generate images, chat with LLMs,
  check their balance/usage, download generation results, or manage profiles.
  Do NOT use for: code generation, web browsing, file management, system admin.
---

# loom CLI Skill

`loom` is a CLI for multi-modal AI generation. One login, no API key management.

## Installation

```bash
npm install -g loomgen
```

If `loom` is not installed, install it first. If already installed, check version:
```bash
loom --version
loom update          # update to latest
```

## First-Time Setup

```bash
loom login
```

This will:
1. Display a 6-character code in the terminal
2. Open a browser window automatically
3. User enters email → receives verification code → authorizes the device
4. Terminal shows "Login successful!"

Credentials are stored at `~/.loom/config.json`. Login persists for 30 days.

If login fails with "fetch failed", see [Network Troubleshooting](#network-troubleshooting) below.

## Command Router

Match user intent to command:

| User wants to... | Command | Reference |
|---|---|---|
| Chat with AI | `loom chat "prompt"` | [chat.md](reference/chat.md) |
| Generate a video | `loom gen video "prompt" --async` | [video.md](reference/video.md) |
| Generate an image | `loom gen image "prompt" --async` | [image.md](reference/image.md) |
| Check task status | `loom gen status <task_id>` | [status.md](reference/status.md) |
| List past tasks | `loom gen list` | [list.md](reference/list.md) |
| Download a result | `loom gen download <task_id> --output-path out.mp4` | [download.md](reference/download.md) |
| Check balance | `loom balance` | [billing.md](reference/billing.md) |
| View usage history | `loom billing history` | [billing.md](reference/billing.md) |
| Top up credits | `loom billing topup 100` | [billing.md](reference/billing.md) |
| List available models | `loom model list` | [models.md](reference/models.md) |
| Check login status | `loom whoami` | [config.md](reference/config.md) |
| Switch profile | `loom config use <name>` | [config.md](reference/config.md) |
| Add own API key | `loom config add-byok <name> --api-key xxx` | [byok.md](reference/byok.md) |

## Default Models

| Type | Model | Default | Notes |
|------|-------|---------|-------|
| Chat | doubao-seed-1-6-250615 | ✅ | Fast, supports reasoning |
| Video | doubao-seedance-1-5-pro-251215 | ✅ | 5s default, 480p |
| Image | doubao-seedream-4-0-250828 | ✅ | 1024x1024 default |

## Key Patterns for Agents

### 1. Always use `--output json` for programmatic parsing

```bash
# Human output (default)
loom gen video --async "a cat"
#   task_id: task_xxx
#   status:  queued

# JSON output (for agents)
loom --output json gen video --async "a cat"
#   {"task_id":"task_xxx","status":"queued"}
```

### 2. Video/Image generation is async — poll for completion

```bash
# Step 1: Submit
loom gen video --async "prompt" --output json
# Returns: {"task_id":"task_abc123","status":"queued"}

# Step 2: Poll until done
loom gen status task_abc123 --output json
# Returns: {"status":"processing","progress":"50%"}
# ... repeat until status="succeeded" or "failed"

# Step 3: Download
loom gen download task_abc123 --output-path video.mp4
```

### 3. Check balance before generating (costs credits)

```bash
loom balance
# Remaining: ¥9.414 (4707175 quota)

# Estimate cost without submitting
loom gen video --dry-run "prompt"
# Estimated cost: ¥1.925
```

### 4. Exit codes

| Code | Meaning | Action |
|------|---------|--------|
| 0 | Success | — |
| 1 | General error | Check error message |
| 2 | Auth failure | Run `loom login` |
| 3 | Parameter error | Check command syntax |
| 4 | Insufficient quota | Top up credits |
| 5 | Upstream failure | Retry or try later |

### 5. Streaming chat

```bash
# TTY (interactive): auto-streams
loom chat "write a poem"

# Script (non-TTY): use --no-stream for parseable output
loom chat --no-stream "write a poem"

# Force streaming in scripts
loom chat --stream "write a poem"
```

## Network Troubleshooting

If `loom` commands fail with `fetch failed` or `ECONNRESET`:

1. Run with diagnostics:
```bash
loom balance
# CLI will auto-print diagnostics panel with DNS check and fix suggestions
```

2. If the diagnostics show "proxy_dns_hijack" (IP starts with 198.18.x):
```bash
# Fix: pin the server IP in /etc/hosts
echo "121.43.135.83 loom.firstapi.ai" | sudo tee -a /etc/hosts
```

3. Or add a DIRECT rule in proxy tool (Clash/Surge):
```
DOMAIN,loom.firstapi.ai,DIRECT
```

## Common Workflows

### Generate and download a video

```bash
loom gen video --async "golden sunset over mountains, cinematic"
# → task_id: task_xxx

loom gen status task_xxx
# → status: processing, progress: 30%

# Wait ~30-60 seconds...

loom gen status task_xxx
# → status: succeeded

loom gen download task_xxx --output-path sunset.mp4
# → Downloaded 2.3MB to sunset.mp4
```

### Multi-turn chat with system prompt

```bash
loom chat \
  --system "You are a helpful coding assistant" \
  --message "user:What is recursion?" \
  --message "assistant:Recursion is a function calling itself..." \
  "Give me a Python example"
```

### Use BYOK (Bring Your Own Key)

```bash
# Register a BYOK profile
loom config add-byok mykey \
  --api-key ark-xxxxx \
  --base-url https://ark.cn-beijing.volces.com

# Switch to it
loom config use mykey

# Now loom chat uses your own key (no credits consumed)
loom chat "hello"

# Switch back to platform
loom config use default
```
