---
name: bria-nimble-workflow
description: reusable setup-first claude code skill for nimble and bria. first guide the user through persistent api key setup, nimble mcp registration, nimble agent-skills installation, optional bria mcp setup, restart requirements, and verification checks that can be reused across projects. then offer an optional walmart competitor-response demo that prefers nimble's walmart search results page agent `walmart_serp` when available, and otherwise falls back to a nimble agent-skills-compatible walmart-capable path, while using bria through the installed bria skill or bria mcp integration and avoiding raw curl calls, direct http posts, or manual python requests in the normal runtime flow.
---

# BRIA + Nimble Setup and Walmart Demo Workflow

## What this skill does

This skill has two layers:

1. **Reusable setup-first UX for Claude Code**
   - Configure Nimble and BRIA once
   - Make that setup reusable across future projects
   - Verify the integrations are actually ready before any demo runs

2. **Optional sample Walmart demo UX**
   - Prefer Nimble's **Walmart Search Results Page** agent
   - Detect a competitor pricing signal
   - Generate a copy pack
   - If warranted, run the BRIA image pipeline and return a restyled visual

This is the intended order:

- configure keys
- connect integrations
- verify readiness
- then offer the sample demo

Do not jump directly into the demo if setup is incomplete.

---

## Core rules for this skill

### Setup-first rule
Treat Nimble and BRIA setup as reusable platform setup for Claude Code, not as one-off demo setup.

### Key storage rule
For reuse across multiple projects, prefer storing API keys in:

```text
~/.claude/settings.json
```

That is the best persistent setup for individual users.

### MCP scope rule
- Use **user-level key storage** for API keys when one person wants Nimble and BRIA available across many projects.
- Use **project-scoped MCP** when a team wants the Nimble MCP config shared in `.mcp.json`.

### Nimble runtime rule
For this demo workflow, the **preferred** Nimble path is the **Walmart Search Results Page** agent with the agent name:

```text
walmart_serp
```

However, `walmart_serp` is a **preferred demo path, not a hard precondition for the entire workflow**.

That means:
- prefer `walmart_serp` when Claude can actually use it
- do not fail the whole demo just because a local shell-based agent-list check does not show `walmart_serp`
- do not block setup success on whether `walmart_serp` is visible in a local CLI listing
- if `walmart_serp` is unavailable, use a Nimble Agent Skills compatible Walmart-capable fallback path
- do not use generic Nimble Search or Fast Search as the first choice when `walmart_serp` is available
- do not fall back to raw `curl` calls to Nimble endpoints in the normal workflow

### Nimble fallback rule
If Claude cannot directly use `walmart_serp`, the workflow should still remain usable.

Fallback order:
1. try the Nimble Agent Skills / coding-agent Walmart flow
2. try another installed Walmart-capable Nimble agent if one is available
3. if neither exists, tell the user the preferred Walmart demo agent is unavailable and offer a different installed Nimble skill or agent

Do not hard-stop the entire skill at setup time merely because `walmart_serp` is not confirmed by a shell command.

### BRIA runtime rule
For this workflow, use BRIA through:
- the installed BRIA skill, or
- BRIA MCP if the environment has standardized on MCP

Do not use raw BRIA HTTP `POST` calls, direct `curl` requests, or manual Python `requests` calls to BRIA endpoints in the normal runtime path.

### BRIA authentication rule
Always use `BRIA_API_KEY` as the BRIA authentication method for this workflow.

That means:
- validate BRIA access by checking whether `BRIA_API_KEY` is configured
- use the BRIA skill in API-key mode
- do not start BRIA device authorization
- do not prefer `~/.bria/credentials` over `BRIA_API_KEY`
- do not initiate a browser-based BRIA sign-in flow
- do not offer an automatic BRIA setup path in place of API-key authentication

If `BRIA_API_KEY` is missing:
- stop
- tell the user to set `BRIA_API_KEY`
- do not continue into any BRIA step

### Enforce skill usage rule
When the BRIA skill or BRIA MCP integration is available, **always use the skill or MCP tool for BRIA actions**.

That means:
- do not load the BRIA skill only to read its instructions and then manually recreate the API calls
- do not substitute raw shell commands for BRIA operations
- do not substitute ad hoc Python scripts for BRIA operations
- do not fall back to direct endpoint calls just because the assistant knows the endpoint shape

For BRIA actions such as:
- background removal
- lifestyle shot generation
- restyle

the assistant must execute them through the BRIA skill or BRIA MCP integration itself.

If BRIA skill execution fails:
- report the failure clearly
- explain which BRIA step failed
- stop and ask the user whether they want troubleshooting guidance

Do **not** silently fall back to direct BRIA API calls.

### Transcript / UX rule
Optimize for a **clean, production-style user experience**.

That means:
- show concise human-facing milestone updates such as:
  - `Checking setup`
  - `Running Walmart pricing step`
  - `Generating BRIA lifestyle shot`
  - `Applying final restyle`
  - `Done`
- do not restate low-level command text in the assistant's prose
- do not narrate payload construction, base64 encoding, multipart details, or polling mechanics
- do not surface raw shell output unless it is needed to explain an error
- if a sign-in flow is required, show only the user-facing instruction, verification URL, and user code
- do not dump raw JSON auth responses or polling loop output into the conversation unless debugging is necessary

The user should mainly see:
- milestone text
- the one action they need to take
- the final result

### Approval-churn reduction rule
Reduce avoidable permission friction.

That means:
- prefer Nimble MCP and BRIA skill / MCP actions over raw Bash whenever possible
- request approval only for truly necessary setup or auth actions
- once safe command patterns are approved, continue without repeatedly pausing between every small step
- do not ask the user to reconfirm obvious next steps inside the same workflow unless auth, missing credentials, or a missing file path blocks progress

### MCP add rule
Do **not** automatically run `claude mcp add ...` on every workflow invocation.
That is a setup/configuration action, not normal business logic.

Instead:
- if the server is truly missing, show the command
- if the server was just added or changed, tell the user to fully restart Claude Code
- if the server is visible but auth is stale, tell the user to remove and re-add it

---

## Step 1 — Collect and verify required API keys first

Do not proceed until both of these exist:

- `NIMBLE_API_KEY`
- `BRIA_API_KEY`

### Preferred persistent setup

Tell the user to add both keys to:

```text
~/.claude/settings.json
```

Example:

```json
{
  "env": {
    "NIMBLE_API_KEY": "your-nimble-api-key-here",
    "BRIA_API_KEY": "your-bria-api-key-here"
  }
}
```

### Shell-only alternative

If the user wants session-only setup:

```bash
export NIMBLE_API_KEY="your-nimble-api-key-here"
export BRIA_API_KEY="your-bria-api-key-here"
```

### Rule
Before continuing, explicitly verify:
- `NIMBLE_API_KEY` is configured
- `BRIA_API_KEY` is configured

If either one is missing:
- stop
- show both setup options
- include the exact `export ...` command
- do not ask the user to paste API keys into the workflow conversation

---

## Step 2 — Set up Nimble for Claude Code

### 2.1 Install the Nimble CLI

```bash
npm i -g @nimble-way/nimble-cli
```

### 2.2 Add the Nimble MCP server

```bash
claude mcp add --transport http nimble-mcp-server https://mcp.nimbleway.com/mcp \
  --header "Authorization: Bearer ${NIMBLE_API_KEY}"
```

### 2.3 Install Nimble Agent Skills

```bash
npx skills add Nimbleway/agent-skills
```

### 2.4 Critical restart rule

After adding the Nimble MCP server, the user must:

- fully quit Claude Code
- reopen Claude Code
- then rerun the workflow

A new chat is not enough.

### 2.5 Optional project-scoped Nimble MCP for shared projects

If the user wants the Nimble MCP config shared inside a repo:

```bash
claude mcp add nimble-mcp-server --scope project --transport http https://mcp.nimbleway.com/mcp \
  --header "Authorization: Bearer ${NIMBLE_API_KEY}"
```

Use this when:
- the workflow is shared across collaborators
- the team wants `.mcp.json` checked into the project

Even in project scope, if the server was added while Claude Code was already open, the user still must fully restart Claude Code.

---

## Step 3 — Set up BRIA for Claude Code

### Primary BRIA setup path

```bash
npx skills add bria-ai/bria-skill
```

This is the primary recommendation for this workflow.

### Optional BRIA MCP path

```bash
claude mcp add bria-skills -- npx -y bria-skills
```

Use this only if the user's environment prefers BRIA through MCP for consistency.

### Rule
Before proceeding, verify:
- BRIA is installed through the BRIA skill or BRIA MCP path
- `BRIA_API_KEY` is configured

For this workflow, `BRIA_API_KEY` is required.
Treat BRIA as authenticated only through the API-key path.
Do not offer, initiate, or fall back to BRIA device sign-in.

---

## Step 4 — Verify readiness before offering the demo

### Nimble checks
Verify all of the following:

1. `NIMBLE_API_KEY` exists
2. `nimble-mcp-server` appears in:

```bash
claude mcp list
```

3. Nimble MCP is active in the current session
4. Nimble auth is healthy
5. Nimble Agent Skills are installed

If Nimble MCP is missing in the current session, tell the user exactly:

> Please fully quit and relaunch Claude Code, then rerun this workflow. MCP servers added mid-session do not become available until the next launch.

If `nimble-mcp-server` is visible but Nimble returns an auth error such as:

```text
Authorization header, URL apiKey parameter, or NIMBLE_API_KEY environment variable is required
```

treat that as stale or incorrect MCP auth.

Fix path:

```bash
claude mcp get nimble-mcp-server
claude mcp remove nimble-mcp-server
claude mcp add --transport http nimble-mcp-server https://mcp.nimbleway.com/mcp \
  --header "Authorization: Bearer ${NIMBLE_API_KEY}"
```

Then fully quit Claude Code and relaunch it.

### BRIA checks
Verify:
- `BRIA_API_KEY` exists
- BRIA skill or BRIA MCP is available

If BRIA is not ready, stop and tell the user how to install/configure it.

### Demo-readiness rule
At setup time:
- confirm Nimble and BRIA are configured
- confirm Nimble Agent Skills are installed
- do not run or surface a user-facing Walmart agent discovery check
- do not use local `nimble agent list` output as a setup gate
- do not present `walmart_serp` visibility as a setup warning or gap

Once setup is complete, simply say setup is complete and offer the optional demo.
Agent-path selection should happen only when the user actually starts the demo.

---

## Step 4.5 — Optional permission setup

If the user wants fewer repetitive approval prompts in Claude Code, recommend **narrow project-level permissions**.

Example `.claude/settings.json`:

```json
{
  "permissions": {
    "allow": [
      "Bash(claude mcp list:*)",
      "Bash(claude mcp get nimble-mcp-server:*)",
      "Bash(claude mcp add nimble-mcp-server:*)",
      "Bash(claude mcp remove nimble-mcp-server:*)",
      "Bash(claude mcp add bria-skills:*)",
      "Bash(test -f:*)",
      "Bash(ls:*)",
      "Bash(find:*)",
      "Bash(grep:*)"
    ],
    "ask": [
      "WebFetch",
      "WebSearch"
    ]
  }
}
```

Best practice:
- keep permissions narrow
- keep them project-scoped when possible
- do not broadly allow all bash or all network access
- let the user use Claude Code's one-time **allow / don't ask again** behavior for the safe command families above
- do not whitelist raw `curl` broadly for this workflow because BRIA and Nimble should run through skills / MCP, not transport-level shell calls

### 4.6 Optional UX tuning

If the user wants a cleaner transcript experience:
- prefer a quieter Claude Code view mode when available
- use a simple status line for progress such as:
  - `Checking setup`
  - `Running Walmart SERP`
  - `Generating BRIA image`
  - `Waiting for BRIA sign-in`
  - `Complete`

The main conversation should stay focused on milestones and user actions, not plumbing.

---

## Step 5 — Offer the optional sample Walmart demo

Only after setup and verification are complete, ask:

> Would you like to try the sample BRIA + Nimble Walmart competitor-response demo?

If the user says yes, explain the demo:

### Sample demo
- install or confirm Nimble Agent Skills with:
  ```bash
  npx skills add Nimbleway/agent-skills
  ```
- start from Nimble's coding-agent pattern, pinned to the Walmart Search Results Page flow:
  ```text
  Let's build with Nimble Agent Walmart Search Results Page. Show me how. Use walmart_serp.
  ```
- use that coding-agent / pipeline-gallery Walmart flow as the required demo launch path
- the user supplies a Walmart search keyword such as `dog food`
- the agent returns structured Walmart product data including pricing fields
- the workflow determines whether there is a meaningful competitor price signal
- if the signal is meaningful, BRIA generates a cleaned, styled visual response
- the workflow returns:
  - a signal summary
  - a copy pack
  - and, if generated, a final BRIA-edited image

If the user does not supply a custom keyword, offer a simple starter keyword such as:

```text
dog food
```

---

## Step 6 — Nimble runtime for this demo

### Preferred path
For this demo, hard-pin Nimble to the **Walmart Search Results Page** flow, associated with:

```text
walmart_serp
```

This demo is Walmart-specific. It should not dynamically discover a different retail SERP flow at runtime.

### Agent inputs
Use:
- `keyword` (required)
- `page` (optional, default to `1` for the demo)
- `zipcode` (optional, only if the user provides one or local pricing matters)

### Demo execution rule
For the demo's Nimble step:
- do not decide availability during setup
- when the user starts the demo, directly launch the Nimble Agent Skills / coding-agent Walmart Search Results Page flow
- use Nimble's coding-agent pattern as the required runtime path:
  ```text
  Let's build with Nimble Agent Walmart Search Results Page. Show me how. Use walmart_serp.
  ```
- treat `walmart_serp` as the only default Nimble path for this demo
- do not require a prior successful local `nimble agent list` lookup before trying the demo
- do not use agent-list discovery to choose a different retail flow
- if any runtime lookup is needed, reference `walmart_serp` directly rather than querying generic `walmart`

### Fallback behavior
If the direct Walmart Search Results Page runtime path actually fails at demo time:
1. stop without surfacing any claim that `walmart_serp` is unavailable
2. say only that the pinned Walmart demo path could not be executed in the current run
3. do not silently pivot to Amazon SERP
4. do not silently pivot to generic retail discovery
5. only offer a backup demo if the user explicitly wants one

### Do not do this
- do not hard-stop setup because `walmart_serp` was not found by a local CLI listing
- do not surface user-facing messages like `Walmart agents: none` during setup
- do not tell the user that `walmart_serp` is unavailable
- do not use `nimble agent list` / `nimble_agents_list` to decide the demo path
- do not run generic `walmart` discovery queries to choose the demo path
- do not assume Amazon, another marketplace, or another retail SERP flow is an acceptable substitute
- do not use generic Nimble Search or Fast Search as the first choice when the Walmart Search Results Page flow is intended
- do not use raw `curl` calls to Nimble endpoints in the normal runtime path

### If the user gives a URL
For this specific demo, still ask them for a concise keyword because this pinned demo is meant to run through the Walmart Search Results Page flow.

### Target fields from the Walmart result
Parse and use these when present:
- `product_id`
- `product_item_id`
- `product_alternate_id`
- `product_name`
- `product_image`
- `product_url`
- `product_category_id`
- `product_price`
- `product_price_original`
- `product_price_per_unit`
- `product_price_range`
- `product_price_currency`
- `product_rating`
- `product_reviews_count`
- `product_seller`
- `product_out_of_stock`
- `product_is_preorder`
- `product_availability`
- `sponsored`
- `variants`
- `position`

If the Walmart Search Results Page path does not return reliable pricing fields, stop and report that the signal is insufficient for this demo.

---

## Step 7 — Strategy layer

After the Walmart result returns data, first scan the returned items and select a single working demo item.

### Item selection rule
Do not blindly use the first returned product.

Instead:
1. scan the Walmart items in order
2. find the **first item** where:
   - `product_price` is populated
   - `product_price_original` is populated
   - `product_price_original` is greater than `product_price`
3. treat that item as the **selected demo item**
4. use that selected demo item for:
   - `priceDropPercent`
   - `urgency`
   - `sentiment`
   - `shouldGenerate`
   - the signal summary
   - the copy pack
   - the BRIA path if generation is warranted

If no returned item meets that differential test, do not force a markdown signal from a non-qualifying item.

After the selected demo item is identified, compute:

- `priceDropPercent`
- `urgency`
- `sentiment`
- `shouldGenerate`

### `priceDropPercent`
Only compute if the selected demo item has:
- `product_price`
- `product_price_original`
- `product_price` lower than `product_price_original`

### `urgency`
- `high` if the drop is large or stock is limited
- `medium` if the drop is noticeable
- `low` if the drop is small or unclear

### `sentiment`
Map urgency into visual/comms sentiment:
- `high` → aggressive
- `medium` → confident
- `low` → informative

### `shouldGenerate`
- `true` when a selected demo item has a real price differential strong enough to warrant creative generation
- `false` when no qualifying item exists or the signal is weak, incomplete, or not actionable

If the pricing data is incomplete, do not invent values.

---

## Step 8 — Signal summary and copy pack

Always return:
- a signal summary
- a copy pack

The copy pack must include:
- `headline`
- `subheadline`
- `CTA`
- `promoBadge`
- `disclaimer`

### Copy rule
Build the signal summary and copy pack from the **selected demo item**, not just the first returned item.

The `headline` or `subheadline` must include at least one concrete number from the selected demo item, such as:
- current price
- original price
- percent off
- dollar savings

Use one strong number.
Do not overload the copy with too many figures.

If `shouldGenerate` is `false`, stop after returning:
- signal summary
- copy pack

That means:
- do not continue into BRIA
- do not ask for a product image
- do not try to generate a lifestyle shot from an item that lacks a valid original-price differential

---

## Step 9 — BRIA image stage

Only continue if `shouldGenerate` is `true`.

Before continuing:
- verify `BRIA_API_KEY` again
- ask the user for the **file path** to the product image they want used as the source image

Ask the user:

> Please provide the file path to the product or brand image you want me to use for the BRIA lifestyle shot.

Do not ask for the product image path before this step.
Do not assume an uploaded file already exists.
Do not assume a default demo asset.

If the user does not provide a valid file path, stop and ask for it.

---

## Step 10 — BRIA runtime for this demo

Use BRIA through the BRIA skill or BRIA MCP integration for this pipeline:

1. create product cutout
2. create lifestyle shot
3. apply sentiment-based **edit-by-text / FIBO Edit**

### BRIA execution rule
When BRIA is available through the skill or MCP integration, **always execute these steps through the BRIA skill or BRIA MCP tool itself**.

That means:
- do not load BRIA documentation and then manually make endpoint calls
- do not use `curl`
- do not use raw Python `requests`
- do not hand-build multipart or JSON payloads for BRIA endpoints
- do not expose low-level transport details to the end user when a BRIA skill path is available
- if `BRIA_API_KEY` is present, use it directly for BRIA skill authentication
- do not start BRIA device auth when `BRIA_API_KEY` is already configured

### User-facing BRIA progress rule
During BRIA execution, the user should see only high-level milestone text such as:
- `Checking BRIA connection`
- `Creating product cutout`
- `Generating lifestyle shot`
- `Applying final edit`
- `BRIA pipeline complete`

Do not show or initiate any BRIA device sign-in flow in this workflow.
If `BRIA_API_KEY` is missing, stop and ask the user to set it first.

### Product cutout rule
For this workflow, use the **product cutout** skill/capability as the first BRIA stage for product images.

That means:
- do not call `/v2/image/edit/remove_background` for this demo's first BRIA stage
- do not describe the first BRIA stage as generic background removal in this demo
- use BRIA's **Product Cutout** capability instead
- treat the first BRIA stage as creating a clean product cutout for commerce/product imagery
- the output of this stage should be a transparent local PNG cutout of the product
- the lifestyle shot must use that local product-cutout PNG as its source asset

### Product cutout contract rule
For this demo, pin the first BRIA stage to the **Product Cutout** endpoint family.

That means:
- the conceptual capability is `product cutout`
- the underlying endpoint family is `/v1/product/cutout`
- the request shape for that capability should follow the Product Cutout contract, not the remove-background contract
- when using a source file, use the Product Cutout request shape expected by that capability
- when using a source URL, use the Product Cutout `image_url` path expected by that capability
- do not substitute RMBG as a “close enough” first step when the workflow says product cutout

### Product cutout pre-call check
Before the first BRIA stage runs, perform a **product-cutout pre-call check**.

That check must confirm:
- the first BRIA stage is using the **Product Cutout** capability, not remove background
- the intended endpoint family is `/v1/product/cutout`
- the request shape matches the Product Cutout contract
- the output of this step will be the local cutout PNG passed into the lifestyle-shot step

Never say `Creating product cutout` while actually calling the remove-background endpoint.

### Lifestyle shot contract rule
For this workflow, treat the BRIA lifestyle-shot step as a **single pinned file-based contract**.

That means:
- always use the **local product-cutout PNG file** from the immediately previous step as the lifestyle-shot image input
- pass the lifestyle prompt using the exact text field the BRIA skill/helper expects for that endpoint
- use the BRIA call with the correct media input key for that endpoint
- use `placement_type: "automatic"` only when the BRIA skill/helper supports it
- do not first try a CDN URL contract
- do not first try a generic image URL contract
- do not probe multiple lifestyle-shot parameter shapes before using the known-good contract
- do not retry by switching from file → URL → file

### Lifestyle shot pre-call check
Before calling `lifestyle_shot_by_text`, perform a **single pre-call schema check**.

That check must confirm:
- the endpoint being called is the BRIA lifestyle-shot endpoint
- the local cutout file path exists and is the file being passed forward
- the exact required media input key for that endpoint
- the exact required text field for that endpoint
- `placement_type` is included only if the BRIA skill/helper supports it for that endpoint

### Lifestyle shot first-try rule
After that pre-call check passes, make the first call in the correct shape.

For this workflow, the first call must already use:
- the local cutout PNG from the product-cutout step
- the exact media field name required by the endpoint
- the exact text field name required by the endpoint

Never make an initial lifestyle-shot call with the wrong field names and then “fix it” afterward.

### Lifestyle shot reliability rule
The correct default behavior is:
1. create product cutout
2. save or retain the local cutout PNG path
3. run the pre-call schema check for `lifestyle_shot_by_text`
4. call the lifestyle-shot step once using that validated request shape
5. continue only if the lifestyle-shot call succeeds

If BRIA returns:
- `400 Request doesn't contain file part`

treat that as a pre-call validation failure that should have been caught before submission, not as a normal runtime variance.

In that case:
- report that the request was submitted with the wrong field contract
- correct the invocation rule in the workflow so the first attempt uses the known-good contract
- do not continue probing alternate URL-based contracts in front of the user

### FIBO Edit rule
For the final BRIA visual pass in this demo, use **edit-by-text / FIBO Edit**, not the dedicated restyle endpoint.

That means:
- do not use `/v2/image/edit/restyle` as the default final step for this demo
- use the BRIA edit-by-text capability / `/v2/image/edit`
- pass the lifestyle-shot output as the image input
- pass the sentiment-derived edit instruction from the strategy layer as the text instruction
- treat this edit instruction as the final creative mood pass

### FIBO Edit validation rule
Before the final BRIA edit call:
- verify the lifestyle-shot output exists
- verify a concrete non-empty sentiment-based edit instruction has already been derived from the strategy layer
- verify the edit step is using the actual lifestyle-shot image output as the image input

Do not call the final BRIA edit step unless:
- the image input is populated
- the edit instruction is populated

### Expected behavior
- use product cutout first for a cleaner commerce-ready product asset
- do not use the remove-background endpoint as a substitute for the product-cutout step in this demo
- use the lifestyle-shot step to place that cutout product in a scene
- always apply sentiment-based **edit-by-text / FIBO Edit** after the lifestyle shot
- return the edited result as the final image

### Failure rule
If the BRIA skill or MCP path fails:
- say which BRIA step failed
- summarize the failure in plain language
- stop and ask the user whether they want troubleshooting help

Do **not** silently replace BRIA skill execution with direct HTTP calls.

---

## Step 11 — Ad Generation (Mock Ads only)

After the final BRIA-edited image is ready, create the final demo ad outputs by compositing the generated copy on top of that single image.

### Mock Ads rule
For this workflow, the ad-generation step is **Mock Ads only**.

That means:
- do not call any Bria Ads API
- do not mention or document any real Ads API fallback in this workflow
- do not mention toggle logic for a real Ads API path
- treat client-side compositing as the only documented ad-generation path for this demo

### Input to the ad-generation step
Use:
- the final BRIA-edited image from the previous step as the background image
- the selected demo item's copy pack:
  - `headline`
  - `subheadline`
  - `CTA`
  - `promoBadge` when used

The image source for all ad variants must be the same single final BRIA image.
The visual differences between ad variants should come from aspect ratio and text layout only.

### Output
Generate **2 mock ad variants** using the same final BRIA image:

| Name      | aspect_ratio | Resolution  |
|-----------|--------------|-------------|
| Square    | `1:1`        | `1080×1080` |
| Portrait  | `4:5`        | `1080×1350` |

### Composition rule
Each variant should:
- reuse the same final BRIA image
- crop it to the correct aspect ratio
- overlay the copy using a readable gradient/text treatment
- render the `headline`, `subheadline`, and `CTA`
- preserve at least one real number from the selected demo item in the visible copy

### Product visibility rule
The product must remain clearly visible in **every** ad variant.

That means:
- do not place an opaque black rectangle or solid panel over the product
- do not let the text block cover the product, package, or hero subject
- do not crop the image in a way that hides or materially cuts off the product
- preserve the product as the primary visual subject in every ratio
- if the product sits low in the frame, move the text treatment elsewhere rather than covering it
- use the crop and text layout together so the product remains visible before the ad is finalized

### Subject-safe text placement rule
Treat the product area as a protected subject-safe zone.

That means:
- identify the product / hero-object region in the final BRIA image
- keep headline, subheadline, CTA, and promo treatment outside that region
- place copy in negative space whenever possible
- if extra contrast is needed, use a gradient or localized overlay only in the text-safe zone
- never extend a dark overlay through the protected product area
- never let headline or subheadline sit directly on top of the product silhouette

### Crop rule
For each aspect ratio:
- choose a crop that keeps the full product or the most important visible portion of the product in frame
- do not prioritize text placement over product visibility
- if a crop would force the product out of frame, adjust the text layout instead of sacrificing the product

### Layout rule
Use ratio-specific text layout so the 2 variants feel distinct:
- `1:1` square: compact stack in a subject-safe zone
- `4:5` portrait: feed-style composition with copy in a subject-safe zone that does not cover the product

### Typography rule
Use one consistent bold, polished sans-serif display font for the demo creative text.

That means:
- use the same strong bold font family across both ad variants
- keep headline weight bold/heavy
- keep subheadline readable but lighter than headline
- keep CTA bold and easy to scan
- do not vary font families between variants

### Button and badge spacing rule
When rendering a CTA button or promo badge:
- include visible inner padding on all sides
- do not let text touch the border
- keep left/right padding generous enough that the label does not feel squeezed
- use the `Shop Now` button treatment as the quality bar for spacing and readability
- apply the same padding standard to `promoBadge` chips such as `20% OFF`

### Text-fit rule
The text overlay must always stay **inside the visible frame** of each ad variant.

That means:
- respect per-ratio safe padding
- allow line wrapping inside the safe area
- use ratio-specific font sizing
- reduce font size before allowing overflow
- keep CTA fully visible inside the frame
- keep promoBadge fully visible inside the frame
- do not let any headline, subheadline, CTA, or promoBadge text clip outside the image bounds
- do not let any text render past the gradient / readable area

### Overflow handling rule
If a copy block is too long for a given aspect ratio:
1. reduce font size within that ratio's allowed range
2. tighten line spacing if needed
3. prefer wrapping over clipping
4. if the copy still does not fit, shorten the subheadline first
5. keep the headline and CTA visible before sacrificing lower-priority text

### Final validation rule
Before accepting an ad variant, verify:
- the product is still viewable
- the text is fully inside the frame
- the text does not overlap the protected product area
- the CTA is fully visible
- the promoBadge, if present, has sufficient inner padding
- no solid background panel is covering the product

### Modal / review rule
When the user opens a generated ad, show the same overlay treatment at a larger preview size.
Do not regenerate the image; just re-render the same mock composition for preview.

### Ad-generation rule
This workflow's ad-generation step is only:
- take the final BRIA image
- place the generated copy on top
- create 2 aspect-ratio variants
- ensure the copy remains fully inside the frame for each variant
- ensure the product remains visible and unobstructed in each variant

Do not introduce any additional API step here.

---

## Step 12 — Final output## Step 12 — Final output

Return:
- the structured signal summary
- the pricing conclusion
- the final BRIA-edited image
- the full copy pack
- the 2 mock ad variants
- a short note that the ad variants were created by overlaying the copy on the final BRIA image for demo purposes, fitted to stay inside each frame, arranged so the product remains visible, and styled with consistent bold typography plus padded CTA/badge treatments

---

## Stopping rules

Stop and provide setup or troubleshooting guidance if:
- `NIMBLE_API_KEY` is missing
- `BRIA_API_KEY` is missing
- `nimble-mcp-server` is not configured
- Nimble MCP was added mid-session and Claude Code has not been restarted
- Nimble MCP is visible but auth is stale or incorrect
- the chosen Walmart-capable Nimble path returns insufficient pricing fields
- `shouldGenerate` is `false`
- the user has not provided a valid product image file path
- the BRIA skill or BRIA MCP path is unavailable

Do not continue into raw search, raw HTTP calls, guessed endpoint probing, or manual BRIA API execution when one of the above conditions is true.

---

## Troubleshooting notes

### If the user gets a 403 saying the feature is enterprise-only
Treat that as the wrong Nimble capability being used.

For this demo:
- first try the Walmart Search Results Page coding-agent runtime path pinned to `walmart_serp`
- do not replace that with a generic `walmart` discovery query
- do not switch to enterprise-gated generic search paths as the default

A 403 on the wrong search path is not the same thing as a bad API key.

### If Nimble MCP is missing
Show the documented `claude mcp add ... nimble-mcp-server ...` command, then tell the user to fully restart Claude Code.

### If Nimble MCP is visible but auth is broken
Treat it as stale MCP auth and tell the user to:
- `claude mcp get nimble-mcp-server`
- `claude mcp remove nimble-mcp-server`
- re-add with a fresh `NIMBLE_API_KEY`
- fully restart Claude Code

### If BRIA key is missing
Show both options:
- persistent `~/.claude/settings.json`
- session-only `export BRIA_API_KEY="..."`

Then stop.
Do not start BRIA device sign-in.

### If BRIA starts device sign-in
Treat that as incorrect behavior for this workflow.

Correct behavior:
- use `BRIA_API_KEY` directly
- validate BRIA through the API-key path
- continue with BRIA skill execution
- do not initiate device authorization

### If the product image path is missing
Stop and ask for it. Do not infer or substitute an image.

### If the assistant starts using direct BRIA API calls
That is incorrect for this workflow.
The correct behavior is to use the BRIA skill or BRIA MCP integration directly for all BRIA actions once BRIA is installed and available.

---

## Notes for the agent

- This is a reusable setup-first skill with an optional sample demo layered on top.
- Make the user complete setup first.
- Then offer the sample Walmart demo.
- Prefer the Walmart Search Results Page flow associated with `walmart_serp`.
- Treat the demo as pinned to Walmart, not as dynamic agent discovery.
- Do not use local agent-list discovery as a setup gate for this demo.
- Do not tell the end user that `walmart_serp` is unavailable just because it is not visible in a local list.
- If the demo needs to reference the Walmart path at runtime, reference `walmart_serp` directly rather than querying generic `walmart`.
- If the preferred Walmart path is not confirmed during setup, still allow the demo to proceed to runtime invocation.
- Do not silently drift to Amazon or another retail SERP flow.
- Mirror Nimble's coding-agent onboarding pattern by including:
  - `npx skills add Nimbleway/agent-skills`
  - `Let's build with Nimble Agent Walmart Search Results Page. Show me how. Use walmart_serp.`
- Do not use generic Nimble Search as the default keyword path in this workflow.
- Do not use raw BRIA endpoint calls as the default runtime path.
- Once BRIA is available, always use the BRIA skill or BRIA MCP integration for BRIA actions.
- Always authenticate BRIA through `BRIA_API_KEY`.
- Never initiate or offer BRIA device sign-in in this workflow.
- Keep the transcript user-friendly by surfacing milestone text and only the next user action when needed.
- Use the BRIA pipeline as: remove background → lifestyle shot → restyle.
- After BRIA restyle, create the final demo ads by placing the generated copy on top of the final restyled image in 4 fixed aspect ratios.
- For this workflow, document Mock Ads as the only ad-generation path.
