From d95bdf56698277f3b83d034317984e33e683c66a Mon Sep 17 00:00:00 2001 From: Mortal <98816321+1wascga@users.noreply.github.com> Date: Mon, 31 Aug 2026 09:44:38 -0700 Subject: [PATCH] fix(banner): make workflow self-contained (#473) Remove references to tools and sibling skills that are not bundled with banner-design. Add plugin, asset, and Claude CLI installation path-contract coverage. --- .claude/skills/banner-design/SKILL.md | 105 +++++------------- cli/assets/skills/banner-design/SKILL.md | 105 +++++------------- .../e2e/banner-design-path-contract.spec.ts | 66 +++++++++++ 3 files changed, 120 insertions(+), 156 deletions(-) create mode 100644 cli/tests/e2e/banner-design-path-contract.spec.ts diff --git a/.claude/skills/banner-design/SKILL.md b/.claude/skills/banner-design/SKILL.md index ee935a5..79fa5ee 100644 --- a/.claude/skills/banner-design/SKILL.md +++ b/.claude/skills/banner-design/SKILL.md @@ -1,6 +1,6 @@ --- name: banner-design -description: "Design banners for social media, ads, website heroes, creative assets, and print. Multiple art direction options with AI-generated visuals. Actions: design, create, generate banner. Platforms: Facebook, Twitter/X, LinkedIn, YouTube, Instagram, Google Display, website hero, print. Styles: minimalist, gradient, bold typography, photo-based, illustrated, geometric, retro, glassmorphism, 3D, neon, duotone, editorial, collage. Uses ui-ux-pro-max, frontend-design, ai-artist, ai-multimodal skills." +description: "Design banners for social media, ads, website heroes, creative assets, and print. Multiple art direction options with optional generated or supplied visuals. Actions: design, create, generate banner. Platforms: Facebook, Twitter/X, LinkedIn, YouTube, Instagram, Google Display, website hero, print. Styles: minimalist, gradient, bold typography, photo-based, illustrated, geometric, retro, glassmorphism, 3D, neon, duotone, editorial, collage." argument-hint: "[platform] [style] [dimensions]" license: MIT metadata: @@ -10,7 +10,7 @@ metadata: # Banner Design - Multi-Format Creative Banner System -Design banners across social, ads, web, and print formats. Generates multiple art direction options per request with AI-powered visual elements. This skill handles banner design only. Does NOT handle video editing, full website design, or print production. +Design banners across social, ads, web, and print formats. Generate multiple art direction options with CSS-built, user-supplied, or optionally generated visual elements. This skill handles banner design only. It does not handle video editing, full website design, or print production. ## When to Activate @@ -21,9 +21,9 @@ Design banners across social, ads, web, and print formats. Generates multiple ar - Event/print banner design - Creative asset generation for campaigns -## Prerequisites +## Available Resources -**Python:** This skill uses Python scripts. On Windows, use `python` instead of `python3` (e.g., `python scripts/search.py` instead of `python3 scripts/search.py`). +This workflow is self-contained: it requires no sibling skills or skill-relative scripts. Use `references/banner-sizes-and-styles.md` for the bundled size, safe-zone, and art-direction guidance. Browser research, image generation, and screenshot tooling are optional capabilities; when unavailable, use supplied assets, CSS-built visuals, and the runtime's standard preview or capture workflow. ## Workflow @@ -33,95 +33,44 @@ Collect via AskUserQuestion: 1. **Purpose** — social cover, ad banner, website hero, print, or creative asset? 2. **Platform/size** — which platform or custom dimensions? 3. **Content** — headline, subtext, CTA, logo placement? -4. **Brand** — existing brand guidelines? (check `docs/brand-guidelines.md`) +4. **Brand** — existing brand guidelines, logo files, colors, or typography? 5. **Style preference** — any art direction? (show style options if unsure) 6. **Quantity** — how many options to generate? (default: 3) ### Step 2: Research & Art Direction -1. Activate `ui-ux-pro-max` skill for design intelligence -2. Use Chrome browser to research Pinterest for design references: - ``` - Navigate to pinterest.com → search "[purpose] banner design [style]" - Screenshot 3-5 reference pins for art direction inspiration - ``` -3. Select 2-3 complementary art direction styles from references: - `references/banner-sizes-and-styles.md` +1. Read `references/banner-sizes-and-styles.md` for the target format, safe zone, and suitable styles. +2. If browser research is available and permitted, collect 3–5 references for composition and art-direction inspiration. Otherwise, work from the bundled reference and any examples supplied by the user. +3. Select 2–3 complementary art directions and state how each supports the banner's purpose. ### Step 3: Design & Generate Options For each art direction option: -1. **Create HTML/CSS banner** using `frontend-design` skill - - Use exact platform dimensions from size reference - - Apply safe zone rules (critical content in central 70-80%) - - Max 2 typefaces, single CTA, 4.5:1 contrast ratio - - Inject brand context via `inject-brand-context.cjs` +1. **Create the banner in HTML/CSS** + - Use the exact platform dimensions from the size reference + - Apply safe-zone rules (critical content in the central 70–80%) + - Use at most 2 typefaces, a single CTA, and text contrast of at least 4.5:1 + - Apply the user's supplied logo, colors, typography, and imagery; do not invent brand rules -2. **Generate visual elements** with `ai-artist` + `ai-multimodal` skills +2. **Choose a visual source** + - Prefer user-supplied or appropriately licensed assets when provided + - Use gradients, geometric forms, type, and other CSS-built visuals for a dependency-free result + - If the runtime provides an authorized image-generation capability, it may generate a background or illustration at the target aspect ratio + - Keep generated visual prompts free of text, letters, and words so final copy remains editable and accessible in HTML - **a) Search prompt inspiration** (6000+ examples in ai-artist): - ```bash - python3 .claude/skills/ai-artist/scripts/search.py "" - ``` - - **b) Generate with Standard model** (fast, good for backgrounds/patterns): - ```bash - .claude/skills/.venv/bin/python3 .claude/skills/ai-multimodal/scripts/gemini_batch_process.py \ - --task generate --model gemini-2.5-flash-image \ - --prompt "" --aspect-ratio \ - --size 2K --output assets/banners/ - ``` - - **c) Generate with Pro model** (4K, complex illustrations/hero visuals): - ```bash - .claude/skills/.venv/bin/python3 .claude/skills/ai-multimodal/scripts/gemini_batch_process.py \ - --task generate --model gemini-3-pro-image-preview \ - --prompt "" --aspect-ratio \ - --size 4K --output assets/banners/ - ``` - - **When to use which model:** - | Use Case | Model | Quality | - |----------|-------|---------| - | Backgrounds, gradients, patterns | Standard (Flash) | 2K, fast | - | Hero illustrations, product shots | Pro | 4K, detailed | - | Photorealistic scenes, complex art | Pro | 4K, best quality | - | Quick iterations, A/B variants | Standard (Flash) | 2K, fast | - - **Aspect ratios:** `1:1`, `16:9`, `9:16`, `3:4`, `4:3`, `2:3`, `3:2` - Match to platform - e.g., Twitter header = `3:1` (use `3:2` closest), Instagram story = `9:16` - - **Pro model prompt tips** (see `ai-artist` references/nano-banana-pro-examples.md): - - Be descriptive: style, lighting, mood, composition, color palette - - Include art direction: "minimalist flat design", "cyberpunk neon", "editorial photography" - - Specify no-text: "no text, no letters, no words" (text overlaid in HTML step) - -3. **Compose final banner** — overlay text, CTA, logo on generated visual in HTML/CSS +3. **Compose the final banner** — overlay the headline, supporting copy, CTA, and logo in HTML/CSS, then verify hierarchy, safe zones, contrast, and crop behavior at the exact target size ### Step 4: Export Banners to Images -After designing HTML banners, export each to PNG using `chrome-devtools` skill: +After designing the HTML banners: -1. **Serve HTML files** via local server (python http.server or similar) -2. **Screenshot each banner** at exact platform dimensions: - ```bash - # Export banner to PNG at exact dimensions - node .claude/skills/chrome-devtools/scripts/screenshot.js \ - --url "http://localhost:8765/banner-01-minimalist.html" \ - --width 1500 --height 500 \ - --output "assets/banners/{campaign}/{variant}-{size}.png" - ``` -3. **Auto-compress** if >5MB (Sharp compression built-in): - ```bash - # With custom max size threshold - node .claude/skills/chrome-devtools/scripts/screenshot.js \ - --url "http://localhost:8765/banner-02-gradient.html" \ - --width 1500 --height 500 --max-size 3 \ - --output "assets/banners/{campaign}/{variant}-{size}.png" - ``` +1. Preview each banner in an available browser at the exact target viewport. +2. Capture the banner element as PNG with the runtime's standard browser or screenshot capability. If capture is unavailable, deliver the HTML/CSS source and clearly mark PNG export as pending rather than naming an uninstalled tool. +3. Verify the exported pixel dimensions, safe-zone crop, font loading, and image quality. +4. If an exported file exceeds the platform limit, use an available image optimizer or reduce image quality and dimensions within the platform specification. -**Output path convention** (per `assets-organizing` skill): +**Output path convention:** ``` assets/banners/{campaign}/ ├── minimalist-1500x500.png @@ -139,7 +88,7 @@ assets/banners/{campaign}/ Present all exported images side-by-side. For each option show: - Art direction style name -- Exported PNG preview (use `ai-multimodal` skill to display if needed) +- Exported PNG preview, or an HTML/CSS preview when image capture is unavailable - Key design rationale - File path & dimensions @@ -185,7 +134,7 @@ Full 22 styles: `references/banner-sizes-and-styles.md` - **Typography**: max 2 fonts, min 16px body, ≥32px headline - **Text ratio**: under 20% for ads (Meta penalizes heavy text) - **Print**: 300 DPI, CMYK, 3-5mm bleed -- **Brand**: always inject via `inject-brand-context.cjs` +- **Brand**: apply only supplied, verified brand guidance and assets ## Security diff --git a/cli/assets/skills/banner-design/SKILL.md b/cli/assets/skills/banner-design/SKILL.md index ee935a5..79fa5ee 100644 --- a/cli/assets/skills/banner-design/SKILL.md +++ b/cli/assets/skills/banner-design/SKILL.md @@ -1,6 +1,6 @@ --- name: banner-design -description: "Design banners for social media, ads, website heroes, creative assets, and print. Multiple art direction options with AI-generated visuals. Actions: design, create, generate banner. Platforms: Facebook, Twitter/X, LinkedIn, YouTube, Instagram, Google Display, website hero, print. Styles: minimalist, gradient, bold typography, photo-based, illustrated, geometric, retro, glassmorphism, 3D, neon, duotone, editorial, collage. Uses ui-ux-pro-max, frontend-design, ai-artist, ai-multimodal skills." +description: "Design banners for social media, ads, website heroes, creative assets, and print. Multiple art direction options with optional generated or supplied visuals. Actions: design, create, generate banner. Platforms: Facebook, Twitter/X, LinkedIn, YouTube, Instagram, Google Display, website hero, print. Styles: minimalist, gradient, bold typography, photo-based, illustrated, geometric, retro, glassmorphism, 3D, neon, duotone, editorial, collage." argument-hint: "[platform] [style] [dimensions]" license: MIT metadata: @@ -10,7 +10,7 @@ metadata: # Banner Design - Multi-Format Creative Banner System -Design banners across social, ads, web, and print formats. Generates multiple art direction options per request with AI-powered visual elements. This skill handles banner design only. Does NOT handle video editing, full website design, or print production. +Design banners across social, ads, web, and print formats. Generate multiple art direction options with CSS-built, user-supplied, or optionally generated visual elements. This skill handles banner design only. It does not handle video editing, full website design, or print production. ## When to Activate @@ -21,9 +21,9 @@ Design banners across social, ads, web, and print formats. Generates multiple ar - Event/print banner design - Creative asset generation for campaigns -## Prerequisites +## Available Resources -**Python:** This skill uses Python scripts. On Windows, use `python` instead of `python3` (e.g., `python scripts/search.py` instead of `python3 scripts/search.py`). +This workflow is self-contained: it requires no sibling skills or skill-relative scripts. Use `references/banner-sizes-and-styles.md` for the bundled size, safe-zone, and art-direction guidance. Browser research, image generation, and screenshot tooling are optional capabilities; when unavailable, use supplied assets, CSS-built visuals, and the runtime's standard preview or capture workflow. ## Workflow @@ -33,95 +33,44 @@ Collect via AskUserQuestion: 1. **Purpose** — social cover, ad banner, website hero, print, or creative asset? 2. **Platform/size** — which platform or custom dimensions? 3. **Content** — headline, subtext, CTA, logo placement? -4. **Brand** — existing brand guidelines? (check `docs/brand-guidelines.md`) +4. **Brand** — existing brand guidelines, logo files, colors, or typography? 5. **Style preference** — any art direction? (show style options if unsure) 6. **Quantity** — how many options to generate? (default: 3) ### Step 2: Research & Art Direction -1. Activate `ui-ux-pro-max` skill for design intelligence -2. Use Chrome browser to research Pinterest for design references: - ``` - Navigate to pinterest.com → search "[purpose] banner design [style]" - Screenshot 3-5 reference pins for art direction inspiration - ``` -3. Select 2-3 complementary art direction styles from references: - `references/banner-sizes-and-styles.md` +1. Read `references/banner-sizes-and-styles.md` for the target format, safe zone, and suitable styles. +2. If browser research is available and permitted, collect 3–5 references for composition and art-direction inspiration. Otherwise, work from the bundled reference and any examples supplied by the user. +3. Select 2–3 complementary art directions and state how each supports the banner's purpose. ### Step 3: Design & Generate Options For each art direction option: -1. **Create HTML/CSS banner** using `frontend-design` skill - - Use exact platform dimensions from size reference - - Apply safe zone rules (critical content in central 70-80%) - - Max 2 typefaces, single CTA, 4.5:1 contrast ratio - - Inject brand context via `inject-brand-context.cjs` +1. **Create the banner in HTML/CSS** + - Use the exact platform dimensions from the size reference + - Apply safe-zone rules (critical content in the central 70–80%) + - Use at most 2 typefaces, a single CTA, and text contrast of at least 4.5:1 + - Apply the user's supplied logo, colors, typography, and imagery; do not invent brand rules -2. **Generate visual elements** with `ai-artist` + `ai-multimodal` skills +2. **Choose a visual source** + - Prefer user-supplied or appropriately licensed assets when provided + - Use gradients, geometric forms, type, and other CSS-built visuals for a dependency-free result + - If the runtime provides an authorized image-generation capability, it may generate a background or illustration at the target aspect ratio + - Keep generated visual prompts free of text, letters, and words so final copy remains editable and accessible in HTML - **a) Search prompt inspiration** (6000+ examples in ai-artist): - ```bash - python3 .claude/skills/ai-artist/scripts/search.py "" - ``` - - **b) Generate with Standard model** (fast, good for backgrounds/patterns): - ```bash - .claude/skills/.venv/bin/python3 .claude/skills/ai-multimodal/scripts/gemini_batch_process.py \ - --task generate --model gemini-2.5-flash-image \ - --prompt "" --aspect-ratio \ - --size 2K --output assets/banners/ - ``` - - **c) Generate with Pro model** (4K, complex illustrations/hero visuals): - ```bash - .claude/skills/.venv/bin/python3 .claude/skills/ai-multimodal/scripts/gemini_batch_process.py \ - --task generate --model gemini-3-pro-image-preview \ - --prompt "" --aspect-ratio \ - --size 4K --output assets/banners/ - ``` - - **When to use which model:** - | Use Case | Model | Quality | - |----------|-------|---------| - | Backgrounds, gradients, patterns | Standard (Flash) | 2K, fast | - | Hero illustrations, product shots | Pro | 4K, detailed | - | Photorealistic scenes, complex art | Pro | 4K, best quality | - | Quick iterations, A/B variants | Standard (Flash) | 2K, fast | - - **Aspect ratios:** `1:1`, `16:9`, `9:16`, `3:4`, `4:3`, `2:3`, `3:2` - Match to platform - e.g., Twitter header = `3:1` (use `3:2` closest), Instagram story = `9:16` - - **Pro model prompt tips** (see `ai-artist` references/nano-banana-pro-examples.md): - - Be descriptive: style, lighting, mood, composition, color palette - - Include art direction: "minimalist flat design", "cyberpunk neon", "editorial photography" - - Specify no-text: "no text, no letters, no words" (text overlaid in HTML step) - -3. **Compose final banner** — overlay text, CTA, logo on generated visual in HTML/CSS +3. **Compose the final banner** — overlay the headline, supporting copy, CTA, and logo in HTML/CSS, then verify hierarchy, safe zones, contrast, and crop behavior at the exact target size ### Step 4: Export Banners to Images -After designing HTML banners, export each to PNG using `chrome-devtools` skill: +After designing the HTML banners: -1. **Serve HTML files** via local server (python http.server or similar) -2. **Screenshot each banner** at exact platform dimensions: - ```bash - # Export banner to PNG at exact dimensions - node .claude/skills/chrome-devtools/scripts/screenshot.js \ - --url "http://localhost:8765/banner-01-minimalist.html" \ - --width 1500 --height 500 \ - --output "assets/banners/{campaign}/{variant}-{size}.png" - ``` -3. **Auto-compress** if >5MB (Sharp compression built-in): - ```bash - # With custom max size threshold - node .claude/skills/chrome-devtools/scripts/screenshot.js \ - --url "http://localhost:8765/banner-02-gradient.html" \ - --width 1500 --height 500 --max-size 3 \ - --output "assets/banners/{campaign}/{variant}-{size}.png" - ``` +1. Preview each banner in an available browser at the exact target viewport. +2. Capture the banner element as PNG with the runtime's standard browser or screenshot capability. If capture is unavailable, deliver the HTML/CSS source and clearly mark PNG export as pending rather than naming an uninstalled tool. +3. Verify the exported pixel dimensions, safe-zone crop, font loading, and image quality. +4. If an exported file exceeds the platform limit, use an available image optimizer or reduce image quality and dimensions within the platform specification. -**Output path convention** (per `assets-organizing` skill): +**Output path convention:** ``` assets/banners/{campaign}/ ├── minimalist-1500x500.png @@ -139,7 +88,7 @@ assets/banners/{campaign}/ Present all exported images side-by-side. For each option show: - Art direction style name -- Exported PNG preview (use `ai-multimodal` skill to display if needed) +- Exported PNG preview, or an HTML/CSS preview when image capture is unavailable - Key design rationale - File path & dimensions @@ -185,7 +134,7 @@ Full 22 styles: `references/banner-sizes-and-styles.md` - **Typography**: max 2 fonts, min 16px body, ≥32px headline - **Text ratio**: under 20% for ads (Meta penalizes heavy text) - **Print**: 300 DPI, CMYK, 3-5mm bleed -- **Brand**: always inject via `inject-brand-context.cjs` +- **Brand**: apply only supplied, verified brand guidance and assets ## Security diff --git a/cli/tests/e2e/banner-design-path-contract.spec.ts b/cli/tests/e2e/banner-design-path-contract.spec.ts new file mode 100644 index 0000000..0315387 --- /dev/null +++ b/cli/tests/e2e/banner-design-path-contract.spec.ts @@ -0,0 +1,66 @@ +import { access, mkdtemp, readFile, rm } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { expect, test } from '@playwright/test'; +import { generatePlatformFiles } from '../../src/utils/template.js'; + +const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../..'); +const skillFiles = [ + '.claude/skills/banner-design/SKILL.md', + 'cli/assets/skills/banner-design/SKILL.md', +]; +const unavailableDependencies = [ + 'frontend-design', + 'ai-artist', + 'ai-multimodal', + 'chrome-devtools', + 'assets-organizing', + 'docs/brand-guidelines.md', + 'scripts/search.py', + 'inject-brand-context.cjs', + 'gemini_batch_process.py', + 'screenshot.js', + 'nano-banana-pro-examples.md', +]; + +function extractLocalReferences(content: string): string[] { + return [...content.matchAll(/`((?:references|scripts)\/[\w./-]+)`/g)].map(match => match[1]); +} + +async function expectSelfContained(skillFile: string): Promise { + const content = await readFile(skillFile, 'utf8'); + + for (const dependency of unavailableDependencies) { + expect(content, dependency).not.toContain(dependency); + } + + const references = extractLocalReferences(content); + expect(references).toContain('references/banner-sizes-and-styles.md'); + for (const reference of references) { + await access(join(dirname(skillFile), reference)); + } +} + +for (const relativeSkillFile of skillFiles) { + test(`${relativeSkillFile} is self-contained`, async () => { + await expectSelfContained(join(repoRoot, relativeSkillFile)); + }); +} + +test('Claude CLI installation preserves the banner path contract', async () => { + const targetDir = await mkdtemp(join(tmpdir(), 'uipro-banner-')); + try { + await generatePlatformFiles(targetDir, 'claude'); + await expectSelfContained(join(targetDir, '.claude/skills/banner-design/SKILL.md')); + } finally { + await rm(targetDir, { recursive: true, force: true }); + } +}); + +test('the bundled banner skill matches the plugin source', async () => { + const [source, bundled] = await Promise.all( + skillFiles.map(skillFile => readFile(join(repoRoot, skillFile), 'utf8')), + ); + expect(bundled).toBe(source); +});