# Make Effects CLI Command-line interface for the Make Effects platform. Provides space management, website asset inspection, real-time event monitoring, media uploading, Forge generation control, and billing management. ## Quick Start Build the distributable CLI first: ```bash pnpm run build:cli dist/cli/makefx.mjs --version ``` ```bash # 1. Login first (if not already) makefx login # 2. Create or list spaces makefx spaces # List all spaces makefx spaces create "My Game Assets" --init # Create new space and bind this directory # 3. Bind this directory to a website space makefx init --space YOUR_SPACE_ID # 4. Listen to real-time events (in a separate terminal) makefx listen --space YOUR_SPACE_ID # 5. Upload image, audio, or video to create a new asset makefx upload hero.png --space YOUR_SPACE_ID --name "Hero Character" makefx upload theme.mp3 --space YOUR_SPACE_ID --name "Theme Music" --type audio makefx upload cutscene.mp4 --space YOUR_SPACE_ID --name "Cutscene" --type video # 6. Upload a variant to an existing asset makefx upload variant.jpg --space YOUR_SPACE_ID --asset ASSET_ID # 7. Generate through the website and download the completed image makefx generate "A market background" --name "Market" --type scene -o market.png # 8. Generate audio through website jobs and download the completed file makefx audio sfx generate "A short brass victory sting" --name "Victory Sting" -o audio/victory.wav # 9. Generate video through website jobs and download the completed file makefx video generate "A looping idle animation" --name "Idle Animation" --type animation -o video/idle.mp4 # 10. Inspect website assets and download an existing variant's media makefx assets makefx assets download VARIANT_ID -o references/variant.png ``` ## Commands Overview | Command | Description | |---------|-------------| | `login` | Authenticate with the API | | `logout` | Remove stored credentials | | `init` | Bind the current directory to a website space | | `spaces` | List, view, or create spaces | | `assets` | List/show/download assets; delete, rename, set-active | | `variants` | Delete, retry, star/unstar, and rate variants | | `usage` | Show platform storage and workflow consumption for a space | | `spend` | Show admin provider cost summaries | | `listen` | Connect to WebSocket and stream all events | | `upload` | Upload local media files and return Space IDs for chaining | | `generate` | Create a new asset through the website generation workflow | | `refine` | Refine an existing variant through the website generation workflow | | `derive` | Create a new asset from variant IDs and/or local image refs | | `batch` | Generate multiple images and write a debug local run manifest | | `audio` | Generate audio assets through website jobs | | `video` | Generate and refine video assets through website jobs | | `runs` | Debug-only local run manifest inspection and export | | `billing` | Billing sync status and management | --- ## Project Binding Bind a filesystem workspace to a website space: ```bash makefx init --space [--env production|stage|local] [--json] ``` This writes `.inventory/config.json` with only the target environment and space ID. It does not store assets, prompts, images, generation keys, or auth tokens. Forge commands use this binding when `--space` or `--env` are omitted. Explicit flags still override the project defaults. The CLI defaults to production when no initialized project or `--env` flag is present. Use `--env stage` for staging and `--local` for a local dev server. Pass `--json` to `init`, `spaces`, `spaces --details`, `spaces --id`, or `spaces create` when another agent or script needs stable machine-readable output. --- ## Spaces Manage your spaces (workspaces for organizing assets). ### List Spaces ```bash makefx spaces # Simple list makefx spaces --details # With asset counts makefx spaces --id # Details for specific space makefx spaces delete # Archive for support recovery makefx spaces inspect-deleted # Admin support inspection makefx spaces restore # Admin support restore ``` ### Create Space ```bash makefx spaces create "My Space Name" makefx spaces create --name "My Space Name" ``` ### Delete Space ```bash makefx spaces delete ``` Space deletion is recoverable during the retention window; it archives the space instead of immediately purging its data. Admins can inspect or restore archived spaces during that retention window: ```bash makefx spaces inspect-deleted makefx spaces restore ``` --- ## Asset Inventory Inspect the website-backed asset graph for the initialized project space: ```bash makefx assets makefx assets --json makefx assets show ASSET_ID makefx assets show ASSET_ID --json ``` Asset inspection displays each asset's `media_kind`; `assets show` also displays each variant's `media_kind`, generation provenance, and provider metadata from Space state. Download an existing completed variant or legacy image key to a local file: ```bash makefx assets download VARIANT_ID -o references/variant.png makefx assets download images/space/variant.png -o references/variant.png makefx assets download VARIANT_ID -o audio/theme.mp3 ``` Generic `media/...` artifacts must be downloaded by variant ID so the website can authorize the space membership before resolving the R2 key. `assets` read commands call the website API every time. They do not scan local files, create a local asset database, or sync state into `.inventory`; the website remains the source of truth. Use `--space`, `--env`, or `--local` to override the project binding when needed. ## Platform Usage Inspect platform-side storage and workflow consumption for the initialized project space: ```bash makefx usage makefx usage --from 2026-06-01 --to 2026-06-30 makefx usage --json ``` The command calls `GET /api/spaces/:id/usage/summary` with the same authenticated space membership checks as asset reads. Human-readable output highlights current storage bytes, workflow runs, and delivered media bytes; `--json` returns the full summary including usage-type and media-kind breakdowns. ## Provider Cost Admins can inspect raw provider cost recorded in the provider usage ledger: ```bash makefx spend makefx spend --from 2026-06-01 --to 2026-06-30 makefx spend --user-id 42 --provider gemini --media-kind image makefx spend --json ``` The command calls `GET /api/billing/spend/summary` and requires an authenticated admin session. Human-readable output includes total provider cost, entry counts, unpriced entry counts, and breakdowns by provider, model, media kind, and meter. ## Managing Assets and Variants Mutating commands talk to the space over the same authenticated WebSocket the web app uses, and broadcast their result to every connected client. Each command opens a short-lived connection, performs one operation, waits for the space to confirm it, and exits. ```bash # Asset-level operations makefx assets delete ASSET_ID # delete an asset and its variants makefx assets rename ASSET_ID "New Name" # rename an asset makefx assets set-active ASSET_ID VARIANT_ID # choose the active variant # Variant-level operations makefx variants delete VARIANT_ID # delete a single variant makefx variants retry VARIANT_ID # retry a failed variant generation makefx variants star VARIANT_ID # star (curation) makefx variants unstar VARIANT_ID # unstar makefx variants rate VARIANT_ID approved # rate approved | rejected ``` Notes: - `assets delete` and `variants delete` require space-owner permission; the other mutations require editor permission. Permission and not-found errors are reported with the server's reason. - `variants retry` only works on `failed` variants and re-queues the original recipe. It returns once the variant is re-queued (status `pending`); watch progress with `assets show ASSET_ID` or `listen`. - Deleting the active variant reassigns the asset's active variant automatically (to another completed variant when one exists). --- ## Listen Mode Connect to a space's WebSocket and stream all events in real-time. Useful for debugging, monitoring, and understanding the event flow. ```bash makefx listen --space # Pretty-printed output makefx listen --space --json # Raw JSON (for piping) ``` **Example output:** ``` Connected! Listening for events... Press Ctrl+C to exit [14:32:01.123] sync:state Assets: 5, Variants: 12, Lineage: 3 [14:32:15.456] generate:started Request: abc123-def456 Job: xyz789 for Silver Warrior [asset_123] [14:32:25.789] variant:updated Variant: xyz789 [completed] [14:32:25.801] job:completed Job: xyz789 → completed (variant: xyz789) ``` **Event types displayed:** - `sync:state` - Initial state sync - `asset:created/updated/deleted` - Asset changes - `variant:created/updated/deleted` - Variant changes - `generate:started/result` - Generation workflow events - `refine:started/result` - Refinement workflow events - `chat:response` - Chat responses - `job:progress/completed/failed` - Job status changes - `presence:update` - User presence changes - `lineage:created/severed` - Variant lineage changes --- ## Upload Upload one image, audio, or video file to create a new asset or add a variant to an existing asset. Upload can also attach external provenance and immutable lineage from existing variants in the same file-oriented command. Local filenames are only local paths; after upload, use the Space asset IDs and variant IDs returned by `--json` for scripts and follow-up commands. ### Create New Asset ```bash makefx upload --name [--space ] [options] ``` ### Add Variant to Existing Asset ```bash makefx upload --asset [--space ] ``` **Arguments:** | Argument | Required | Description | |----------|----------|-------------| | `` | Yes | Path to image, audio, or video file | | `--space ` | No | Target space ID; defaults from initialized project | | `--asset ` | * | Target asset ID (upload as new variant) | | `--name ` | * | New asset name (creates asset + variant) | | `--type ` | No | Asset type for new assets (default: `character`) | | `--media-kind ` | No | Optional explicit kind: `image`, `audio`, or `video` | | `--prompt ` | No | Prompt provenance for uploaded media | | `--model ` | No | Model provenance for uploaded media | | `--provider ` | No | Provider provenance for uploaded media | | `--provider-metadata ` | No | Provider metadata JSON object | | `--generation-provenance ` | No | Extra provenance JSON object | | `--source-variant ` | No | Existing Space variant IDs to record as upload lineage sources; accepts one ID or comma-separated IDs | | `--source-variants ` | No | Alias for `--source-variant` | | `--relation-type ` | No | Lineage type: `derived`, `refined`, or `forked` (default: `derived`) | | `--active-variant-behavior ` | No | `if-missing`, `set-active`, or `keep` | | `--json` | No | Print machine-readable upload output with returned Space IDs | | `--env ` | No | `production`, `stage`, or `local` (default: `production`) | | `--local` | No | Shortcut for `--env local` | \* Either `--asset` or `--name` is required. **Supported formats:** `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.mp3`, `.m4a`, `.aac`, `.wav`, `.ogg`, `.flac`, `.mp4`, `.m4v`, `.mov`, `.webm` (max 10MB). `.webm` uploads default to video. **Examples:** ```bash # Create a new character asset from an image makefx upload hero.png --space abc123 --name "Hero Character" # Create with specific type makefx upload sword.png --space abc123 --name "Sword" --type item # Add a variant to an existing asset makefx upload variant.jpg --space abc123 --asset def456 # Upload audio and video assets makefx upload theme.mp3 --space abc123 --name "Theme Music" --type audio makefx upload cutscene.mp4 --space abc123 --name "Opening Cutscene" --type video # Upload one externally produced file with provenance and lineage makefx upload paintover.png --space abc123 --asset def456 \ --prompt "cleaner silhouette" \ --provider local-tool \ --provider-metadata '{"seed":42}' \ --generation-provenance '{"workflow":"paintover-v1"}' \ --source-variant var789 \ --relation-type refined \ --active-variant-behavior set-active # Upload a ready scene render with multiple source parents makefx upload cocina.png --space abc123 --name "Cocina" --type scene \ --source-variants anna_variant,roman_variant,bg_variant # Upload against local dev server makefx upload hero.png --space abc123 --name "Hero" --local # Capture returned Space IDs for follow-up commands base_json=$(makefx upload base.png --space abc123 --name "Hero Base" --json) base_asset=$(printf '%s' "$base_json" | jq -r '.variant.asset_id') base_variant=$(printf '%s' "$base_json" | jq -r '.variant.id') makefx upload paintover.png --space abc123 --asset "$base_asset" \ --source-variant "$base_variant" \ --relation-type refined \ --json ``` Upload no longer accepts collection or manual relation flags. It creates an asset or variant, records immutable lineage with `--source-variant`, and leaves visual organization to the Space canvas. --- ## Forge Generation The CLI can act as a ForgeTray controller for an existing website space. The website remains authoritative for assets, variants, recipes, lineage, and R2 storage; the CLI sends generation requests and downloads completed media. The top-level `generate`, `refine`, `derive`, and `batch` commands are image-only and send `mediaKind: "image"`. Video commands live under the explicit `video` namespace. ```bash makefx generate "A watercolor background of Russafa market" \ --name "Russafa Market Background" \ --type scene \ -o backgrounds/russafa-market.png makefx refine \ --variant VARIANT_ID \ "make it evening, warmer lights" \ -o backgrounds/russafa-market-evening.png makefx derive \ --refs ./lucia.png,VARIANT_BACKGROUND_ID \ --name "Lucia in Market Scene" \ --type scene \ "Use image 1 as the character and image 2 as the background" \ -o keyframes/lucia-market-001.png makefx batch "Three cinematic keyframes in Russafa market" \ --name "Russafa Market Keyframe" \ --type scene \ --count 3 \ --output-dir keyframes/russafa-market ``` `derive --refs` accepts existing variant IDs and local image paths. Local images are mirrored into `.inventory/mirrors.json` for the current Space. If the same file content was already mirrored and the recorded variant still exists in the Space as a completed compatible variant, the CLI reuses that variant ID without uploading another reference asset. If the same path now contains different content, the CLI stops instead of silently reusing the old reference or silently creating a duplicate. Generation commands download completed media and write debug-only `.inventory/runs/.json` at the initialized project root, with local paths, website asset/variant IDs, media keys, media kind, prompt, refs, command options, timestamps, run success, and failed variant errors. These manifests are not a source of truth and must not drive asset selection or assembly. Image manifests also retain the legacy `images` keyframe array for troubleshooting older local tooling. Single-output generation commands also print the created variant ID as soon as the Space accepts the request. If the CLI process exits or times out before the provider finishes, follow that existing Space variant instead of starting a new job: ```bash makefx generate --follow VARIANT_ID -o backgrounds/russafa-market.png makefx audio sfx generate --follow VARIANT_ID -o audio/item-pickup.wav makefx video generate --follow VARIANT_ID -o video/idle.mp4 ``` Follow mode reads the current Space state, returns immediately for completed or failed variants, or waits for the same `variant:updated` lifecycle events used by normal generation. On completion it downloads the media and writes the usual debug run manifest from the durable variant recipe. Pass `--timeout ` to override the default wait window. ## Audio Generation Audio controller commands use the same website Space Durable Object and GenerationWorkflow job lifecycle as image generation. They send `mediaKind: "audio"` and download the completed variant through the authenticated variant media endpoint. Canonical audio commands make the Forge Tray mode explicit: `speech`, `dialogue`, `music`, or `sfx`. The CLI sends the matching canonical asset type and `mediaKind: "audio"`. ```bash makefx audio voices makefx audio speech generate "Podcast narration for the level intro" \ --name "Intro Narration" \ --voice voice_narrator \ -o audio/intro-narration.wav makefx audio dialogue generate --input scripts/blacksmith-dialogue.txt \ --name "Blacksmith Dialogue" \ --voice voice_default \ --dialogue-voices voice_blacksmith,voice_player \ -o audio/blacksmith-dialogue.wav makefx audio music batch "Three 20 second low-intensity dungeon music beds" \ --name "Dungeon Bed" \ --count 3 \ --output-dir audio/dungeon-beds makefx audio music generate "A 30 second bright orchestral menu loop" \ --provider lyria \ --name "Menu Loop" \ -o audio/menu-loop.wav makefx audio sfx generate "A crisp inventory item pickup sound effect" \ --name "Item Pickup" \ -o audio/item-pickup.wav ``` Dialogue and speech prompts can also be passed as direct multiline shell text. `--input ` is the practical path for reusable dialogue scripts, with one `Speaker: line` entry per line for multi-speaker dialogue. Use `makefx audio voices` to list the connected ElevenLabs account's voice library. It prints `voiceId` values for `--voice` and `--dialogue-voices`; `--json` returns the raw `{ available, voices }` response. `--voice` selects the speech voice and also acts as a fallback for dialogue speakers whose ordered slot is blank or omitted. `--dialogue-voices ` maps voice IDs to dialogue speakers by first appearance in the script. Music uses the server default provider unless `--provider lyria` or `--provider elevenlabs` is supplied. The provider option is valid only for `audio music` commands. Audio generation currently does not accept `--refs`, `derive`, or `refine` commands. Audio batch downloads completed files into the requested directory and writes debug local run manifests. ## Video Generation Video controller commands use the same website Space Durable Object and GenerationWorkflow job lifecycle as image and audio generation. They send `mediaKind: "video"` and download the completed variant through the authenticated variant media endpoint. ```bash makefx video generate "A looping idle animation" \ --name "Idle Animation" \ --type animation \ --model veo-3.1 \ --duration 6 \ --resolution 1080p \ --tier fast \ -o video/idle.mp4 makefx video refine \ --variant VIDEO_VARIANT_ID \ "make the motion snappier" \ -o video/idle-snappy.mp4 makefx video derive \ --refs IMAGE_VARIANT_ID,VIDEO_VARIANT_ID \ --name "Attack Animation" \ --type animation \ --model omni-flash \ "animate the pose into a short attack" \ -o video/attack.mp4 makefx video derive \ --first-frame KEYFRAME_START_VARIANT_ID \ --last-frame KEYFRAME_END_VARIANT_ID \ --name "Camera Move" \ --type animation \ "slow dolly from the doorway to the desk" \ -o video/camera-move.mp4 ``` `video derive --refs` accepts completed image variant IDs, completed video variant IDs, and local image paths. Local image paths use the same mirror registry as image refs: matching mirrored content reuses the recorded variant, while changed files stop with guidance to upload or reference intentionally. For Veo 3.1 first/last-frame generation, prefer `--first-frame ` and `--last-frame ` on `video generate` or `video derive`. These flags accept completed image variant IDs and local image paths. The CLI mirrors local files as image references, resolves both flags to ordered `referenceVariantIds`, and sends those IDs to the Space job. The backend then expands the first resolved image to Veo's top-level `image` parameter and the second resolved image to `config.lastFrame`. `--last-frame` requires `--first-frame`, and frame flags cannot be combined with `--refs`; use `--refs` when you want generic Veo reference images instead of first/last-frame inputs. Video batch generation is not exposed because website batch jobs reject `mediaKind: "video"`. Pass `--model veo-3.1|omni-flash` to choose the video model explicitly. Veo is the default and supports first/last-frame control plus `--resolution`, `--duration`, `--tier`, and `--audio`. `omni-flash` maps to `gemini-omni-flash-preview` and accepts prompt, references, and `--aspect`; the CLI rejects Veo-only flags for Omni before creating a Space job. By default, Veo requests ask for native synchronized audio. Current Veo models do not support `--no-audio`; the CLI rejects it before creating a Space job. Pass `--audio` explicitly when the soundtrack matters, and describe dialogue, SFX, score, or ambience in the prompt. Pass `--aspect 16:9|9:16`, `--resolution 720p|1080p|4k`, `--duration 4|6|8`, and `--tier generate|fast|lite` to select the Veo output controls for that request; those choices are stored in the variant recipe and preserved on retry. The `lite` tier supports `720p` and `1080p`; use `generate` or `fast` for `4k`. ## Run Manifests ```bash makefx runs --debug makefx runs show --latest --debug makefx runs show RUN_ID --debug --json makefx runs export --latest --debug --format media -o media-run.json makefx runs export --latest --debug --format remotion -o keyframes.json ``` `runs` reads local `.inventory/runs` manifests from the initialized project root and does not call generation APIs. It requires `--debug` because local manifests are troubleshooting traces, not product state. The default `media` export is a compact JSON debug view with ordered media paths, absolute paths resolved from the original command working directory, website IDs/URLs, prompt, refs, and failed variant errors. Image runs also include an ordered `images` keyframe array for existing local tools. Use `--format remotion` only when debugging an older keyframe pipeline that expects the legacy `remotion-keyframes` format marker. See [cli-generation.md](./cli-generation.md) for the full command reference. --- ## Billing View billing sync status, run Polar operational checks, and reconcile one customer billing period against Polar meter usage plus local charge, provider cost, and platform usage ledgers. ```bash makefx billing status makefx billing check makefx billing reconcile --user-id 42 makefx billing retry-failed ``` --- ## Troubleshooting ### "Not logged in" Error ```bash makefx login ``` ### "Token expired" Error ```bash makefx login ```