Claude-code-plugins-plus-skills adobe-core-workflow-a
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/adobe-pack/skills/adobe-core-workflow-a" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-skills-adobe-core-workflow-a && rm -rf "$T"
manifest:
plugins/saas-packs/adobe-pack/skills/adobe-core-workflow-a/SKILL.mdsource content
Adobe Core Workflow A — Firefly Services
Overview
Primary creative workflow using Adobe Firefly v3 APIs: text-to-image generation, generative fill (inpainting), and image expansion (outpainting). These are the most common Firefly Services operations for marketing asset automation.
Prerequisites
- Completed
with Firefly API scopes (adobe-install-auth
)firefly_api,ff_apis
installed, or direct REST access@adobe/firefly-apis- Pre-signed cloud storage URLs for input/output images (S3, Azure Blob, or Dropbox)
Instructions
Step 1: Text-to-Image Generation (Synchronous)
// src/workflows/firefly-generate.ts import { getAccessToken } from '../adobe/client'; interface FireflyGenerateOptions { prompt: string; negativePrompt?: string; width?: number; // 1024, 1472, 1792, 2048 height?: number; n?: number; // 1-4 images contentClass?: 'art' | 'photo'; style?: { presets?: string[]; // e.g., ['digital_art', 'cinematic'] strength?: number; // 0-100 }; } interface FireflyOutput { outputs: Array<{ image: { url: string }; seed: number; }>; } export async function generateImage(opts: FireflyGenerateOptions): Promise<FireflyOutput> { const token = await getAccessToken(); const body: Record<string, any> = { prompt: opts.prompt, n: opts.n || 1, size: { width: opts.width || 1024, height: opts.height || 1024 }, contentClass: opts.contentClass || 'photo', }; if (opts.negativePrompt) body.negativePrompt = opts.negativePrompt; if (opts.style?.presets) { body.styles = { presets: opts.style.presets }; } const response = await fetch('https://firefly-api.adobe.io/v3/images/generate', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'x-api-key': process.env.ADOBE_CLIENT_ID!, 'Content-Type': 'application/json', }, body: JSON.stringify(body), }); if (!response.ok) { const err = await response.text(); throw new Error(`Firefly generate failed (${response.status}): ${err}`); } return response.json(); }
Step 2: Async Generation (for High Volume)
// For production pipelines, use async endpoint to avoid HTTP timeouts export async function generateImageAsync(opts: FireflyGenerateOptions) { const token = await getAccessToken(); const response = await fetch('https://firefly-api.adobe.io/v3/images/generate-async', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'x-api-key': process.env.ADOBE_CLIENT_ID!, 'Content-Type': 'application/json', }, body: JSON.stringify({ prompt: opts.prompt, n: opts.n || 1, size: { width: opts.width || 1024, height: opts.height || 1024 }, }), }); const { jobId, statusUrl, cancelUrl } = await response.json(); console.log(`Firefly async job: ${jobId}`); // Poll for completion let result: any; while (true) { await new Promise(r => setTimeout(r, 2000)); const poll = await fetch(statusUrl, { headers: { 'Authorization': `Bearer ${token}`, 'x-api-key': process.env.ADOBE_CLIENT_ID!, }, }); result = await poll.json(); if (result.status === 'succeeded' || result.status === 'failed') break; } if (result.status === 'failed') throw new Error(`Async generation failed: ${result.error}`); return result; }
Step 3: Generative Fill (Inpainting)
// Fill a masked region of an image with AI-generated content export async function generativeFill( imageUrl: string, maskUrl: string, prompt: string ): Promise<FireflyOutput> { const token = await getAccessToken(); const response = await fetch('https://firefly-api.adobe.io/v3/images/fill', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'x-api-key': process.env.ADOBE_CLIENT_ID!, 'Content-Type': 'application/json', }, body: JSON.stringify({ image: { source: { url: imageUrl } }, mask: { source: { url: maskUrl } }, prompt, n: 1, }), }); if (!response.ok) throw new Error(`Fill failed: ${response.status}`); return response.json(); }
Step 4: Image Expansion (Outpainting)
// Expand an image to a larger canvas size with AI-generated surroundings export async function expandImage( imageUrl: string, targetWidth: number, targetHeight: number, prompt?: string ): Promise<FireflyOutput> { const token = await getAccessToken(); const response = await fetch('https://firefly-api.adobe.io/v3/images/expand', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'x-api-key': process.env.ADOBE_CLIENT_ID!, 'Content-Type': 'application/json', }, body: JSON.stringify({ image: { source: { url: imageUrl } }, size: { width: targetWidth, height: targetHeight }, ...(prompt && { prompt }), n: 1, }), }); if (!response.ok) throw new Error(`Expand failed: ${response.status}`); return response.json(); }
Output
- AI-generated images from text prompts (sync or async)
- Inpainted regions via generative fill with mask
- Expanded/outpainted images to larger canvas sizes
- Temporary URLs for generated images (download within 24h)
Error Handling
| Error | Cause | Solution |
|---|---|---|
prompt rejected | Content policy violation | Remove trademarks, real people, or explicit content from prompt |
| Missing scope | Add Firefly API to Developer Console project |
| Image too large for fill/expand | Resize input to max 4096x4096 |
| Rate limited | Use async endpoint; honor header |
| Transient Firefly error | Retry with backoff; check status.adobe.com |
Resources
Next Steps
For PDF document workflows, see
adobe-core-workflow-b.