返回 Skills
nexu-io/open-design· Apache-2.0 内容可用

ecommerce-image-workflow

Reference-product ecommerce image workflow for generating a compact set of product-faithful main, feature, and lifestyle images from real product reference photos. V1 requires uploaded product imagery and intentionally defers brief-only concept generation and platform-specific batch exports.

安装

与 skills.sh 相同的 Command / Prompt 安装方式


name: ecommerce-image-workflow en_name: "Ecommerce Image Workflow" description: | Reference-product ecommerce image workflow for generating a compact set of product-faithful main, feature, and lifestyle images from real product reference photos. V1 requires uploaded product imagery and intentionally defers brief-only concept generation and platform-specific batch exports. triggers:

  • "ecommerce product images"
  • "product image set"
  • "product photography workflow"
  • "product main image"
  • "product feature shot"
  • "reference product commerce images"
  • "lifestyle product image"
  • "amazon product images"
  • "shopify product images"
  • "taobao product images" od: mode: image surface: image category: image-generation scenario: marketing preview: type: html entry: example.html design_system: requires: false example_prompt: | Use the Ecommerce Image Workflow to turn my uploaded product reference photo into a compact ecommerce image set: one main packshot, one feature highlight image, and one lifestyle scene. Preserve the exact product identity, color, material, logo placement, structure, and proportions.

Ecommerce Image Workflow

Create a compact ecommerce image set from real product reference imagery. This V1 skill is intentionally narrow: it supports reference-product mode only. If the user only describes a product and does not provide a product photo, ask for one and stop. Do not create a brief-only concept product in this version.

Resource map

ecommerce-image-workflow/
|-- SKILL.md
|-- example.html
`-- references/
    `-- checklist.md

What this skill produces

By default, generate three ecommerce-ready image assets for one product:

  1. Main image - clean product-first packshot on white or soft neutral background.
  2. Feature image - one selling point shown clearly with controlled callout space, without relying on tiny unreadable in-image text.
  3. Lifestyle image - product shown in a plausible use context while keeping the product faithful to the reference.

Also create:

  • image-manifest.json describing reference inputs, slots, prompts, outputs, aspect ratios, and fidelity notes.
  • ecommerce-gallery.html as a small preview gallery linking the generated files and summarizing the image roles.

Input contract

Required:

  • At least one uploaded product reference image in the active project.

Ask only for missing essentials:

  • Product name or short label if it is not obvious.
  • Main selling point if the feature image cannot be inferred safely.
  • Target marketplace or aspect only if the user asks for platform-specific framing.

Do not ask broad discovery questions. Keep the workflow moving.

Workflow

Step 0 - Confirm reference-product mode

Before planning, verify that the current project includes a real product reference image.

If no product image is available, reply:

Please upload at least one product reference image first. This V1 workflow preserves a real product from reference photos; brief-only concept generation is deferred to a later version.

Then stop.

Step 1 - Extract product identity anchors

Inspect the reference image and write a short internal identity lock:

  • Product category and form factor.
  • Shape and silhouette.
  • Primary colors and materials.
  • Logo, label, pattern, fasteners, ports, straps, handles, or other fixed details.
  • Scale cues and proportions.
  • What must not change.

Use these anchors in every generation prompt.

Step 2 - Build a three-slot shot plan

Create a compact shot plan before dispatch:

SlotDefault aspectGoal
main1:1Product-first marketplace image on white or soft neutral background
feature4:5One clear selling point with close-up detail or simple callout space
lifestyle4:5Realistic use context with the product still visually faithful

If the project metadata provides imageAspect, use it when the user expects a single aspect across the set. Otherwise use the slot defaults above.

Step 3 - Compose prompts with a fidelity lock

Every prompt must include this product fidelity instruction near the top:

Preserve the exact product identity from the reference image: shape,
silhouette, color, material, logo/label placement, visible construction
details, and proportions. Do not redesign the product. Do not add, remove,
or relocate product features.

Then add slot-specific instructions:

Main image prompt

  • Product centered and fully visible.
  • White, off-white, or very light grey background.
  • Soft studio lighting with clean shadow.
  • No props unless the user asked for them.
  • No in-frame marketing text.

Feature image prompt

  • Focus on one user-provided or safely inferred feature.
  • Use close-up composition, cutaway-style crop, or clean negative space for later designer-added labels.
  • Keep the product visually balanced in the frame. If no explicit callout structure is being generated, center the product. If label space is needed, offset the product only slightly and make the empty space feel intentional.
  • Do not invent certifications, performance numbers, materials, or claims.
  • Avoid tiny rendered text; leave label space instead.

Lifestyle image prompt

  • Use a realistic environment matched to the product category.
  • Keep the product the focal point.
  • Show human interaction only if it helps explain use and does not obscure the product.
  • Preserve product scale and structure.

Step 4 - Dispatch through the media contract

Use the unified Open Design media dispatcher. Do not call provider APIs or custom model commands directly.

For each slot, run the standard generate/wait loop:

# POSIX bash. Do not call provider APIs directly.
out=$("$OD_NODE_BIN" "$OD_BIN" media generate \
  --project "$OD_PROJECT_ID" \
  --surface image \
  --model "<imageModel from metadata>" \
  --aspect "<slot aspect or imageAspect from metadata>" \
  --image "<project-relative product reference image>" \
  --output "<product-slug>-<slot>.png" \
  --prompt "<full slot prompt>")
ec=$?
if [ "$ec" -ne 0 ]; then echo "$out" >&2; exit "$ec"; fi

last=$(printf '%s\n' "$out" | tail -1)
task_id=$(printf '%s\n' "$last" |
  python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('taskId',''))" 2>/dev/null)
since=$(printf '%s\n' "$last" |
  python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('nextSince',0))" 2>/dev/null)
since="${since:-0}"

while [ -n "$task_id" ]; do
  out=$("$OD_NODE_BIN" "$OD_BIN" media wait "$task_id" --since "$since")
  ec=$?
  last=$(printf '%s\n' "$out" | tail -1)
  since=$(printf '%s\n' "$last" |
    python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('nextSince',0))" 2>/dev/null)
  since="${since:-0}"
  if [ "$ec" -eq 0 ]; then
    task_id=""
  elif [ "$ec" -ne 2 ]; then
    echo "$out" >&2
    exit "$ec"
  fi
done

printf '%s\n' "$last"

The final line must be JSON with {"file": {"name": "...", ...}}. Record each final returned filename in image-manifest.json.

If the active image model or provider cannot use --image, stop and tell the user that this workflow needs a reference-capable image generation path for product fidelity.

Step 5 - Write image-manifest.json

After generation, create a project file named image-manifest.json:

{
  "workflow": "ecommerce-image-workflow",
  "mode": "reference-product",
  "productName": "Example product",
  "referenceImages": ["reference-product.png"],
  "fidelityNotes": [
    "Preserve product identity, color, material, construction, and proportions.",
    "Do not treat these outputs as platform-compliance proof without human review."
  ],
  "slots": [
    {
      "id": "main",
      "role": "marketplace packshot",
      "aspect": "1:1",
      "output": "example-product-main.png",
      "promptSummary": "Centered product-first packshot on a clean neutral background."
    },
    {
      "id": "feature",
      "role": "single feature highlight",
      "aspect": "4:5",
      "output": "example-product-feature.png",
      "promptSummary": "Close-up or negative-space composition for one verified selling point."
    },
    {
      "id": "lifestyle",
      "role": "usage context",
      "aspect": "4:5",
      "output": "example-product-lifestyle.png",
      "promptSummary": "Realistic scene with the product as the focal point."
    }
  ]
}

Keep the manifest honest. If a detail is unknown, write null or a short note instead of inventing claims.

Step 6 - Write ecommerce-gallery.html

Create a simple single-file HTML gallery that:

  • Shows the reference image first.
  • Shows the three generated slots with their role names.
  • Lists product-fidelity notes.
  • Links to image-manifest.json.
  • Uses system fonts and local project files only; no CDN imports.

Step 7 - Hand off

Reply with:

  • The generated filenames.
  • A one-sentence summary of the fidelity lock used.
  • A reminder that marketplace-specific compliance, final text overlays, and claim/legal review remain human review steps.

Do not emit an <artifact> tag.

Hard rules

  • V1 requires real product reference imagery. No brief-only concept products.
  • One product per run.
  • Default to exactly three slots: main, feature, lifestyle.
  • Preserve the product; do not redesign it.
  • Do not invent claims, certifications, measurements, ingredients, or performance data.
  • Use "$OD_NODE_BIN" "$OD_BIN" media generate; do not call provider APIs directly.
  • Always create image-manifest.json after generation.
  • Run references/checklist.md before handoff.

附带文件

example.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Ecommerce image workflow example</title>
    <style>
      :root {
        --bg: #f6f8fb;
        --ink: #17191c;
        --muted: #626b77;
        --line: #d7dee8;
        --panel: #ffffff;
        --panel-2: #eef3f8;
        --accent: #0f766e;
        --accent-2: #c2410c;
        --shadow: rgba(23, 25, 28, 0.1);
      }

      * {
        box-sizing: border-box;
      }

      html,
      body {
        margin: 0;
        min-height: 100%;
        background: var(--bg);
        color: var(--ink);
        font-family:
          ui-sans-serif,
          system-ui,
          -apple-system,
          BlinkMacSystemFont,
          "Segoe UI",
          sans-serif;
      }

      body {
        padding: 34px;
      }

      .shell {
        max-width: 1180px;
        margin: 0 auto;
      }

      .topline {
        display: flex;
        justify-content: space-between;
        gap: 24px;
        align-items: flex-start;
        padding-bottom: 24px;
        border-bottom: 1px solid var(--line);
      }

      .eyebrow {
        font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
        text-transform: uppercase;
        letter-spacing: 0.16em;
        font-size: 11px;
        color: var(--accent);
        margin: 0 0 12px;
      }

      h1 {
        font-family: Georgia, "Times New Roman", serif;
        font-size: clamp(38px, 6vw, 76px);
        line-height: 0.95;
        letter-spacing: 0;
        margin: 0;
        max-width: 760px;
        font-weight: 500;
      }

      .summary {
        max-width: 330px;
        color: var(--muted);
        font-size: 15px;
        line-height: 1.5;
        margin: 8px 0 0;
      }

      .meta-row {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        border-bottom: 1px solid var(--line);
      }

      .meta {
        padding: 18px 20px;
        border-right: 1px solid var(--line);
      }

      .meta:last-child {
        border-right: 0;
      }

      .meta span {
        display: block;
        font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
        font-size: 11px;
        text-transform: uppercase;
        letter-spacing: 0.12em;
        color: var(--muted);
        margin-bottom: 8px;
      }

      .meta strong {
        font-size: 18px;
        font-weight: 650;
      }

      .workflow {
        display: grid;
        grid-template-columns: 1.05fr 1.8fr;
        gap: 24px;
        margin-top: 28px;
      }

      .reference,
      .gallery-card,
      .manifest {
        background: var(--panel);
        border: 1px solid var(--line);
        border-radius: 8px;
        box-shadow: 0 18px 45px var(--shadow);
      }

      .reference {
        padding: 22px;
      }

      .label {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
        font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
        text-transform: uppercase;
        letter-spacing: 0.12em;
        font-size: 11px;
        color: var(--muted);
      }

      .status {
        color: var(--accent);
      }

      .product-stage {
        margin-top: 22px;
        min-height: 420px;
        border: 1px solid var(--line);
        background:
          linear-gradient(
            90deg,
            rgba(255, 255, 255, 0) 0 48%,
            rgba(15, 118, 110, 0.12) 48% 52%,
            rgba(255, 255, 255, 0) 52%
          ),
          var(--panel-2);
        display: grid;
        place-items: center;
        padding: 28px;
      }

      .product {
        width: min(230px, 72%);
        aspect-ratio: 0.76;
        position: relative;
        filter: drop-shadow(0 28px 26px rgba(23, 25, 28, 0.18));
      }

      .product::before {
        content: "";
        position: absolute;
        inset: 11% 12% 9%;
        background: #f8fafc;
        border: 2px solid #17191c;
        border-radius: 42% 42% 38% 38%;
      }

      .product::after {
        content: "";
        position: absolute;
        left: 28%;
        right: 28%;
        top: 27%;
        height: 12px;
        border-radius: 999px;
        background: var(--accent);
        box-shadow:
          0 32px 0 #22201c,
          0 64px 0 #d7dee8;
      }

      .strap {
        position: absolute;
        top: 22%;
        bottom: 18%;
        width: 26%;
        border: 2px solid #17191c;
        border-radius: 999px;
      }

      .strap.left {
        left: -4%;
        border-right: 0;
      }

      .strap.right {
        right: -4%;
        border-left: 0;
      }

      .note-list {
        margin: 20px 0 0;
        padding: 0;
        list-style: none;
        color: var(--muted);
        font-size: 14px;
        line-height: 1.5;
      }

      .note-list li {
        padding: 10px 0;
        border-top: 1px solid var(--line);
      }

      .gallery {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 18px;
      }

      .gallery-card {
        overflow: hidden;
      }

      .frame {
        min-height: 292px;
        border-bottom: 1px solid var(--line);
        display: grid;
        place-items: center;
        position: relative;
        background: #fbfcfe;
      }

      .frame.feature {
        background:
          linear-gradient(90deg, transparent 0 62%, rgba(15, 118, 110, 0.1) 62%),
          #fbfcfe;
      }

      .frame.lifestyle {
        background:
          linear-gradient(180deg, #eef6ff 0 52%, #cbd5e1 52%),
          #eef6ff;
      }

      .mini-product {
        width: 42%;
        aspect-ratio: 0.76;
        position: relative;
      }

      .mini-product::before {
        content: "";
        position: absolute;
        inset: 11% 12% 9%;
        background: #f8fafc;
        border: 2px solid #17191c;
        border-radius: 42% 42% 38% 38%;
      }

      .mini-product::after {
        content: "";
        position: absolute;
        left: 31%;
        right: 31%;
        top: 29%;
        height: 8px;
        border-radius: 999px;
        background: var(--accent);
        box-shadow:
          0 24px 0 #22201c,
          0 48px 0 #d7dee8;
      }

      .feature-line {
        position: absolute;
        right: 22px;
        width: 25%;
        height: 1px;
        background: var(--accent);
      }

      .feature-line.one {
        top: 94px;
      }

      .feature-line.two {
        top: 148px;
      }

      .feature-line.three {
        top: 202px;
      }

      .table {
        position: absolute;
        bottom: 46px;
        left: 18%;
        right: 18%;
        height: 14px;
        background: rgba(23, 25, 28, 0.16);
        border-radius: 999px;
      }

      .card-copy {
        padding: 18px;
      }

      .card-copy h2 {
        margin: 0 0 8px;
        font-size: 18px;
        line-height: 1.2;
      }

      .card-copy p {
        margin: 0;
        color: var(--muted);
        font-size: 14px;
        line-height: 1.5;
      }

      .manifest {
        margin-top: 18px;
        padding: 18px 20px;
        display: grid;
        grid-template-columns: auto 1fr auto;
        gap: 16px;
        align-items: center;
      }

      .manifest-mark {
        width: 42px;
        height: 42px;
        border: 1px solid var(--line);
        display: grid;
        place-items: center;
        font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
        color: var(--accent);
        background: #fbfcfe;
      }

      .manifest h2 {
        margin: 0 0 4px;
        font-size: 17px;
      }

      .manifest p {
        margin: 0;
        color: var(--muted);
        font-size: 14px;
      }

      .manifest code {
        font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
        color: var(--ink);
        font-size: 13px;
      }

      @media (max-width: 920px) {
        body {
          padding: 20px;
        }

        .topline,
        .workflow {
          grid-template-columns: 1fr;
          display: grid;
        }

        .summary {
          max-width: none;
        }

        .meta-row,
        .gallery {
          grid-template-columns: 1fr;
        }

        .meta {
          border-right: 0;
          border-bottom: 1px solid var(--line);
        }

        .manifest {
          grid-template-columns: 1fr;
        }
      }
    </style>
  </head>
  <body>
    <main class="shell">
      <header class="topline">
        <div>
          <p class="eyebrow">Reference product workflow</p>
          <h1>One product photo becomes a compact commerce image set.</h1>
        </div>
        <p class="summary">
          V1 keeps the product locked to a real reference image, then generates
          a main packshot, one feature highlight, and one lifestyle scene.
        </p>
      </header>

      <section class="meta-row" aria-label="Workflow metadata">
        <div class="meta">
          <span>Mode</span>
          <strong>reference-product</strong>
        </div>
        <div class="meta">
          <span>Scope</span>
          <strong>one product</strong>
        </div>
        <div class="meta">
          <span>Outputs</span>
          <strong>3 images + manifest</strong>
        </div>
      </section>

      <section class="workflow" aria-label="Generated ecommerce image workflow">
        <aside class="reference">
          <div class="label">
            <span>Uploaded reference</span>
            <span class="status">identity locked</span>
          </div>
          <div class="product-stage" aria-label="Stylized product reference">
            <div class="product">
              <span class="strap left"></span>
              <span class="strap right"></span>
            </div>
          </div>
          <ul class="note-list">
            <li>Preserve shape, color, material, construction, and proportions.</li>
            <li>Do not invent claims, certificates, or measurements.</li>
            <li>Final marketplace compliance and text overlays remain human review.</li>
          </ul>
        </aside>

        <div>
          <div class="gallery">
            <article class="gallery-card">
              <div class="frame">
                <div class="mini-product"></div>
              </div>
              <div class="card-copy">
                <h2>Main image</h2>
                <p>Clean packshot on a white or soft neutral background.</p>
              </div>
            </article>

            <article class="gallery-card">
              <div class="frame feature">
                <div class="mini-product"></div>
                <span class="feature-line one"></span>
                <span class="feature-line two"></span>
                <span class="feature-line three"></span>
              </div>
              <div class="card-copy">
                <h2>Feature image</h2>
                <p>One verified selling point with space for designer-added labels.</p>
              </div>
            </article>

            <article class="gallery-card">
              <div class="frame lifestyle">
                <div class="mini-product"></div>
                <span class="table"></span>
              </div>
              <div class="card-copy">
                <h2>Lifestyle image</h2>
                <p>A plausible use context with the product still faithful.</p>
              </div>
            </article>
          </div>

          <section class="manifest" aria-label="Manifest output">
            <div class="manifest-mark">{ }</div>
            <div>
              <h2>Manifest handoff</h2>
              <p>
                Each slot records role, aspect, output file, prompt summary, and
                fidelity notes.
              </p>
            </div>
            <code>image-manifest.json</code>
          </section>
        </div>
      </section>
    </main>
  </body>
</html>
references/checklist.md
# Ecommerce Image Workflow Checklist

Run this before handoff. P0 items must pass for the output to be usable.

## P0 - must pass

- [ ] **Reference image exists.** The workflow used at least one real uploaded
  product image. If no image was available, the run stopped and asked the user
  to upload one.
- [ ] **Reference-product mode only.** The output is not a brief-only concept
  product. Any brief-only request was deferred.
- [ ] **One product.** The run targets one product, not a SKU family or mixed catalog.
- [ ] **Product fidelity lock appears in every prompt.** Each generated slot
  prompt preserves shape, silhouette, color, material, logo/label placement,
  visible construction details, and proportions.
- [ ] **No redesign.** Prompts do not add, remove, relocate, recolor, or restyle
  product features. Product edit requests that change the product itself are
  out of scope for this V1 workflow and should be deferred to a follow-up
  workflow.
- [ ] **Three-slot scope.** The set is limited to main, feature, and lifestyle
  unless the user explicitly requested fewer.
- [ ] **Media dispatcher only.** Generation used
  `"$OD_NODE_BIN" "$OD_BIN" media generate`; no provider API or custom model
  command was called directly.
- [ ] **Reference image is passed to generation.** Each media command includes
  `--image <project-relative product reference image>` when the model supports
  reference images. If not supported, the workflow stops instead of pretending
  product fidelity is guaranteed.
- [ ] **No fabricated claims.** The feature image does not invent
  certifications, measurements, materials, ingredients, performance numbers,
  awards, or compliance promises.
- [ ] **No tiny rendered text dependency.** Prompts avoid relying on small
  in-image text for selling points; they leave clean label space when copy will
  be added later.
- [ ] **Manifest exists.** `image-manifest.json` records workflow name, mode,
  product name/label, reference images, slot ids, output filenames, aspects,
  and prompt summaries.
- [ ] **Gallery exists.** `ecommerce-gallery.html` shows the reference image
  first and the generated main, feature, and lifestyle slots.

## P1 - should pass

- [ ] **Slot roles are visually distinct.** Main is a clean packshot, feature is
  detail/benefit focused, lifestyle is contextual.
- [ ] **Backgrounds fit ecommerce use.** Main image uses white/off-white/light
  grey; feature and lifestyle avoid noisy backgrounds that hide product details.
- [ ] **Scale is plausible.** Product size and proportions remain credible across all slots.
- [ ] **Human interaction is controlled.** Hands/models do not hide the product
  or alter its construction.
- [ ] **File names are predictable.** Outputs use `<product-slug>-main.png`,
  `<product-slug>-feature.png`, and `<product-slug>-lifestyle.png` or similarly
  readable names.

## P2 - nice to have

- [ ] **Marketplace note included.** Handoff states that platform-specific
  crop/background/text rules remain a follow-up or human review step.
- [ ] **Variation path is clear.** Handoff suggests the next useful variant,
  such as a different lifestyle scene or a second feature focus.