Find your landing page message
Connect a product’s value to a specific audience and write a clear first-screen message.
Generate AI videos and AI images on fabbo.ai by driving a real Chromium browser session with Playwright. Use this skill WHENEVER the user asks to create an AI video, generate an AI image, make a text-to-video, image-to-video, text-to-image, or produce visual content — including phrasings like "ma...
---
name: fabbo-ai-generator
description: Generate AI videos and AI images on fabbo.ai by driving a real Chromium browser session with Playwright. Use this skill WHENEVER the user asks to create an AI video, generate an AI image, make a text-to-video, image-to-video, text-to-image, or produce visual content — including phrasings like "make a video of a dragon flying", "generate an image of a sunset over Tokyo", "animate this photo", "turn this picture into a video", or any mention of fabbo, fabbo.ai, Veo, Sora, Kling, Wan, Luma, Midjourney, Nano Banana, Runway. Do NOT require the user to say "use fabbo" explicitly — if they want an AI video or image and this skill is installed, use it. The skill reuses an existing fabbo.ai browser login via a persistent profile, so the user only signs in once.
---
# fabbo-ai-generator
Generate AI videos and AI images by driving the fabbo.ai web UI in a real Chromium instance. Supports text-to-video, image-to-video, text-to-image, reference-to-video, frame-to-video, and image editing. Downloads the result to disk and returns both the remote URL and local path so you can preview it, attach it to the conversation, or post-process it.
## Why drive a real browser?
fabbo.ai's public API isn't exposed yet, and generation is tied to the signed-in user's credit balance. Driving the real UI via Playwright:
- Works against production with no backdoor
- Respects the user's account (credits, plan, history, private/public visibility)
- Stays correct even as the fabbo.ai backend evolves
The tradeoff is we need a persistent browser profile so the user logs in once. After that, sessions are reused automatically and the script runs unattended.
## Prerequisites
- **Node.js 20 or newer** — check with `node --version`
- **A fabbo.ai account** with enough credits for whatever the user wants to generate
- **Playwright's Chromium build** — installed automatically on first run of `scripts/login.js`
## First-time setup (once per machine)
```bash
cd <path-to-this-skill>
npm install
node scripts/login.js
```
`login.js` downloads Playwright's Chromium if needed, opens a visible browser window at fabbo.ai, and waits for you to sign in. Use Google, email, or whichever provider the user prefers. Once you see your avatar in the header, press Enter in the terminal — the session is now persisted under `~/.cache/fabbo-ai-generator/browser-profile/` and will be reused automatically.
Verify it worked:
```bash
node scripts/check.js
```
If the output says `logged_in: true`, you're done. If it says `logged_in: false`, rerun `login.js`.
## Running a generation
The main entry point is `scripts/generate.js`. It's designed to be called once per generation:
```bash
node scripts/generate.js \
--prompt "A neon cyberpunk city at night, drone flying between skyscrapers, cinematic" \
--mode text-to-video
```
### Flags
| Flag | Values | Default | Notes |
| -------------- | ---------------------------------------------------------------------------------------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--prompt` | any text, up to 2000 chars | **required** | The generation prompt |
| `--mode` | `text-to-video`, `image-to-video`, `reference-to-video`, `frame-to-video`, `text-to-image`, `image-editor` | `text-to-video` | What to generate. `image-to-video` is an alias for `text-image-to-video` with an image attached. |
| `--image` | path to a local image | _none_ | Reference image. Required for `image-editor` and for `*-to-video` / `*-to-image` modes when the selected model is image-only. Repeat the flag for multi-image modes. |
| `--output-dir` | directory path | `./fabbo-output` | Where the downloaded media file is saved |
| `--timeout` | seconds | `600` | Max time to wait for generation to finish |
| `--headless` | flag | unset | Run Chromium without a visible window. Omit when debugging. |
| `--base-url` | URL | `https://fabbo.ai` | Override for dev/staging environments |
### Output format
On success, `generate.js` prints a single JSON object to stdout and exits 0:
```json
{
"status": "success",
"prompt": "A neon cyberpunk city at night...",
"mode": "text-to-video",
"mediaType": "video",
"url": "https://static.fabbo.ai/.../output.mp4",
"localPath": "/abs/path/fabbo-output/2026-04-11T12-30-45_video.mp4",
"durationMs": 45120
}
```
On failure, stdout contains a JSON object and the process exits non-zero:
```json
{
"status": "error",
"errorCode": "not_logged_in",
"message": "Session expired. Run `node scripts/login.js` again."
}
```
Possible `errorCode` values:
- `not_logged_in` — cookie/session expired, user needs to rerun login
- `insufficient_credits` — account is out of credits, tell the user to top up at fabbo.ai
- `generation_failed` — fabbo.ai returned an error during generation; `message` has the detail
- `timeout` — generation didn't finish within `--timeout`; video tasks can take several minutes
- `prompt_too_long` — prompt exceeded 2000 characters
- `image_required` — selected mode needs an `--image` but none was passed
- `selector_not_found` — fabbo.ai's UI shape has drifted; see `references/troubleshooting.md`
- `browser_launch_failed` — Playwright couldn't start Chromium; usually a missing install
**Always parse the JSON**. The process prints nothing else on stdout, so a `JSON.parse` on the stdout string is safe.
## How to use this skill in a conversation
When the user asks for an AI video or image:
1. **Pick a mode.** Default to `text-to-video` for video requests and `text-to-image` for image requests. Use `image-to-video` (or `text-image-to-video` with `--image`) when the user attaches or references a photo they want animated.
2. **Shape the prompt.** fabbo.ai prompts behave like any diffusion/video prompt — describe the subject, style, lighting, camera, mood. Keep under 2000 characters. If the user gives a bare idea like "a dragon", flesh it out with visual details before submitting (you can ask the user first if they care about control).
3. **Run `generate.js`** with `--prompt` (and `--image` / `--mode` as needed). Use `--headless` unless you want to watch it run.
4. **Parse the stdout JSON.**
5. **On success:** tell the user the file is at `localPath`, mention the public `url`, and — if the CLI you're running in supports it — attach or inline the media.
6. **On error:** handle per `errorCode`. For `not_logged_in`, tell the user the one command to run. For `insufficient_credits`, link them to fabbo.ai's pricing. For `generation_failed`, surface `message` verbatim and offer to retry with a tweaked prompt.
### Examples of mode choice
**Text to video (default):**
```bash
node scripts/generate.js \
--prompt "A golden retriever running on a beach at sunset, slow motion, cinematic lighting, 8k"
```
**Text to image:**
```bash
node scripts/generate.js \
--prompt "Isometric cutaway of a cozy sci-fi reading nook, warm lamp light, houseplants, detailed" \
--mode text-to-image
```
**Image to video (animate a still):**
```bash
node scripts/generate.js \
--prompt "Camera slowly pushes in, leaves rustling in the wind, cinematic" \
--mode image-to-video \
--image ~/Desktop/forest.jpg
```
**Reference to video (multi-image guidance):**
```bash
node scripts/generate.js \
--prompt "Same character, now dancing in a neon club" \
--mode reference-to-video \
--image ./character-front.jpg \
--image ./character-side.jpg
```
## How the script works (mental model for debugging)
A one-paragraph summary so you can reason about failures without reading the code:
1. Launch Chromium with a persistent context rooted at `~/.cache/fabbo-ai-generator/browser-profile/`. That directory is the session store — deleting it forces a re-login.
2. `goto` the base URL. fabbo.ai's homepage hosts the main generator (`HeroGenerator` → `GeneratorInput`).
3. Wait for the prompt textarea to appear (placeholder: _"Enter your idea to generate"_).
4. If `--mode` differs from the current default, click the Radix Select trigger in the generator toolbar and pick the target mode by visible label.
5. If `--image` was passed, call `setInputFiles` on the hidden `<input type="file">` inside the upload slot — the component accepts this as a drop-in fallback for its modal picker.
6. Fill the textarea, then click the circular submit button (the rounded-full button with an ArrowUp icon inside the form).
7. Race four outcomes until one wins:
- A `<video src>` or `<img alt="Generated">` appears in the result card → **success**
- A sign-in modal opens → **not_logged_in**
- A toast containing "insufficient credits" appears → **insufficient_credits**
- An error state renders inside the result card → **generation_failed**
- `--timeout` elapses → **timeout**
8. On success, fetch the media URL with Node's built-in `fetch` and stream it to `--output-dir`.
All selectors live in `scripts/lib/selectors.js`. When fabbo.ai's UI drifts, that's the only file to touch.
## Troubleshooting
See `references/troubleshooting.md` for Playwright install issues, session expiry, selector drift, model-selector quirks, and how to debug failed runs by rerunning with `--headless` omitted.
## Bundled resources
- `scripts/generate.js` — main driver; invoke once per generation
- `scripts/login.js` — one-time interactive login that seeds the persistent profile
- `scripts/check.js` — verifies the session is still valid (prints `logged_in: true/false`)
- `scripts/lib/browser.js` — shared Playwright launcher (persistent context)
- `scripts/lib/selectors.js` — all DOM selectors + English mode labels in one place
- `scripts/lib/args.js` — minimal CLI argument parser (uses Node's built-in `util.parseArgs`)
- `package.json` — declares the single dependency (`playwright`)
- `references/troubleshooting.md` — read when things break
---
name: fabbo-ai-generator
description: Generate AI videos and AI images on fabbo.ai by driving a real Chromium browser session with Playwright. Use this skill WHENEVER the user asks to create an AI video, generate an AI image, make a text-to-video, image-to-video, text-to-image, or produce visual content — including phrasings like "make a video of a dragon flying", "generate an image of a sunset over Tokyo", "animate this photo", "turn this picture into a video", or any mention of fabbo, fabbo.ai, Veo, Sora, Kling, Wan, Luma, Midjourney, Nano Banana, Runway. Do NOT require the user to say "use fabbo" explicitly — if they want an AI video or image and this skill is installed, use it. The skill reuses an existing fabbo.ai browser login via a persistent profile, so the user only signs in once.
---
# fabbo-ai-generator
Generate AI videos and AI images by driving the fabbo.ai web UI in a real Chromium instance. Supports text-to-video, image-to-video, text-to-image, reference-to-video, frame-to-video, and image editing. Downloads the result to disk and returns both the remote URL and local path so you can preview it, attach it to the conversation, or post-process it.
## Why drive a real browser?
fabbo.ai's public API isn't exposed yet, and generation is tied to the signed-in user's credit balance. Driving the real UI via Playwright:
- Works against production with no backdoor
- Respects the user's account (credits, plan, history, private/public visibility)
- Stays correct even as the fabbo.ai backend evolves
The tradeoff is we need a persistent browser profile so the user logs in once. After that, sessions are reused automatically and the script runs unattended.
## Prerequisites
- **Node.js 20 or newer** — check with `node --version`
- **A fabbo.ai account** with enough credits for whatever the user wants to generate
- **Playwright's Chromium build** — installed automatically on first run of `scripts/login.js`
## First-time setup (once per machine)
```bash
cd <path-to-this-skill>
npm install
node scripts/login.js
```
`login.js` downloads Playwright's Chromium if needed, opens a visible browser window at fabbo.ai, and waits for you to sign in. Use Google, email, or whichever provider the user prefers. Once you see your avatar in the header, press Enter in the terminal — the session is now persisted under `~/.cache/fabbo-ai-generator/browser-profile/` and will be reused automatically.
Verify it worked:
```bash
node scripts/check.js
```
If the output says `logged_in: true`, you're done. If it says `logged_in: false`, rerun `login.js`.
## Running a generation
The main entry point is `scripts/generate.js`. It's designed to be called once per generation:
```bash
node scripts/generate.js \
--prompt "A neon cyberpunk city at night, drone flying between skyscrapers, cinematic" \
--mode text-to-video
```
### Flags
| Flag | Values | Default | Notes |
| -------------- | ---------------------------------------------------------------------------------------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--prompt` | any text, up to 2000 chars | **required** | The generation prompt |
| `--mode` | `text-to-video`, `image-to-video`, `reference-to-video`, `frame-to-video`, `text-to-image`, `image-editor` | `text-to-video` | What to generate. `image-to-video` is an alias for `text-image-to-video` with an image attached. |
| `--image` | path to a local image | _none_ | Reference image. Required for `image-editor` and for `*-to-video` / `*-to-image` modes when the selected model is image-only. Repeat the flag for multi-image modes. |
| `--output-dir` | directory path | `./fabbo-output` | Where the downloaded media file is saved |
| `--timeout` | seconds | `600` | Max time to wait for generation to finish |
| `--headless` | flag | unset | Run Chromium without a visible window. Omit when debugging. |
| `--base-url` | URL | `https://fabbo.ai` | Override for dev/staging environments |
### Output format
On success, `generate.js` prints a single JSON object to stdout and exits 0:
```json
{
"status": "success",
"prompt": "A neon cyberpunk city at night...",
"mode": "text-to-video",
"mediaType": "video",
"url": "https://static.fabbo.ai/.../output.mp4",
"localPath": "/abs/path/fabbo-output/2026-04-11T12-30-45_video.mp4",
"durationMs": 45120
}
```
On failure, stdout contains a JSON object and the process exits non-zero:
```json
{
"status": "error",
"errorCode": "not_logged_in",
"message": "Session expired. Run `node scripts/login.js` again."
}
```
Possible `errorCode` values:
- `not_logged_in` — cookie/session expired, user needs to rerun login
- `insufficient_credits` — account is out of credits, tell the user to top up at fabbo.ai
- `generation_failed` — fabbo.ai returned an error during generation; `message` has the detail
- `timeout` — generation didn't finish within `--timeout`; video tasks can take several minutes
- `prompt_too_long` — prompt exceeded 2000 characters
- `image_required` — selected mode needs an `--image` but none was passed
- `selector_not_found` — fabbo.ai's UI shape has drifted; see `references/troubleshooting.md`
- `browser_launch_failed` — Playwright couldn't start Chromium; usually a missing install
**Always parse the JSON**. The process prints nothing else on stdout, so a `JSON.parse` on the stdout string is safe.
## How to use this skill in a conversation
When the user asks for an AI video or image:
1. **Pick a mode.** Default to `text-to-video` for video requests and `text-to-image` for image requests. Use `image-to-video` (or `text-image-to-video` with `--image`) when the user attaches or references a photo they want animated.
2. **Shape the prompt.** fabbo.ai prompts behave like any diffusion/video prompt — describe the subject, style, lighting, camera, mood. Keep under 2000 characters. If the user gives a bare idea like "a dragon", flesh it out with visual details before submitting (you can ask the user first if they care about control).
3. **Run `generate.js`** with `--prompt` (and `--image` / `--mode` as needed). Use `--headless` unless you want to watch it run.
4. **Parse the stdout JSON.**
5. **On success:** tell the user the file is at `localPath`, mention the public `url`, and — if the CLI you're running in supports it — attach or inline the media.
6. **On error:** handle per `errorCode`. For `not_logged_in`, tell the user the one command to run. For `insufficient_credits`, link them to fabbo.ai's pricing. For `generation_failed`, surface `message` verbatim and offer to retry with a tweaked prompt.
### Examples of mode choice
**Text to video (default):**
```bash
node scripts/generate.js \
--prompt "A golden retriever running on a beach at sunset, slow motion, cinematic lighting, 8k"
```
**Text to image:**
```bash
node scripts/generate.js \
--prompt "Isometric cutaway of a cozy sci-fi reading nook, warm lamp light, houseplants, detailed" \
--mode text-to-image
```
**Image to video (animate a still):**
```bash
node scripts/generate.js \
--prompt "Camera slowly pushes in, leaves rustling in the wind, cinematic" \
--mode image-to-video \
--image ~/Desktop/forest.jpg
```
**Reference to video (multi-image guidance):**
```bash
node scripts/generate.js \
--prompt "Same character, now dancing in a neon club" \
--mode reference-to-video \
--image ./character-front.jpg \
--image ./character-side.jpg
```
## How the script works (mental model for debugging)
A one-paragraph summary so you can reason about failures without reading the code:
1. Launch Chromium with a persistent context rooted at `~/.cache/fabbo-ai-generator/browser-profile/`. That directory is the session store — deleting it forces a re-login.
2. `goto` the base URL. fabbo.ai's homepage hosts the main generator (`HeroGenerator` → `GeneratorInput`).
3. Wait for the prompt textarea to appear (placeholder: _"Enter your idea to generate"_).
4. If `--mode` differs from the current default, click the Radix Select trigger in the generator toolbar and pick the target mode by visible label.
5. If `--image` was passed, call `setInputFiles` on the hidden `<input type="file">` inside the upload slot — the component accepts this as a drop-in fallback for its modal picker.
6. Fill the textarea, then click the circular submit button (the rounded-full button with an ArrowUp icon inside the form).
7. Race four outcomes until one wins:
- A `<video src>` or `<img alt="Generated">` appears in the result card → **success**
- A sign-in modal opens → **not_logged_in**
- A toast containing "insufficient credits" appears → **insufficient_credits**
- An error state renders inside the result card → **generation_failed**
- `--timeout` elapses → **timeout**
8. On success, fetch the media URL with Node's built-in `fetch` and stream it to `--output-dir`.
All selectors live in `scripts/lib/selectors.js`. When fabbo.ai's UI drifts, that's the only file to touch.
## Troubleshooting
See `references/troubleshooting.md` for Playwright install issues, session expiry, selector drift, model-selector quirks, and how to debug failed runs by rerunning with `--headless` omitted.
## Bundled resources
- `scripts/generate.js` — main driver; invoke once per generation
- `scripts/login.js` — one-time interactive login that seeds the persistent profile
- `scripts/check.js` — verifies the session is still valid (prints `logged_in: true/false`)
- `scripts/lib/browser.js` — shared Playwright launcher (persistent context)
- `scripts/lib/selectors.js` — all DOM selectors + English mode labels in one place
- `scripts/lib/args.js` — minimal CLI argument parser (uses Node's built-in `util.parseArgs`)
- `package.json` — declares the single dependency (`playwright`)
- `references/troubleshooting.md` — read when things break
Imported from the listed AgentSkill.sh category. Complete supplied package files and notices are retained. Includes source scripts; review them before use. Required external tools and credentials are not installed. No bundled code was executed during import. Individual agent task behavior has not been tested.