Delegate independent tasks to specialized agents working concurrently with isolated context.
Business Forge Engineer
Especialista en Business Forge: gestión de assets post-magia, Fusion Engine y generación de visuales.
SKILL.md
Full skill instructions
Business Forge Engineer - Platform AI Solutions
1. Concepto: The Business Forge
Filosofía
El Business Forge es el estudio post-magia donde los usuarios refinan y utilizan los assets generados por el proceso de "Hacer Magia".
Capacidades
- Canvas: Visualizar assets generados (branding, scripts, ROI, visuals)
- Smart Catalog: Browser de productos brutos de Tienda Nube
- Fusion Engine: Generación de imágenes publicitarias on-demand
- Reality vs Dream Mode: Overlay de producto real sobre fondo IA
Arquitectura
Frontend (BusinessForge.tsx)
↓
Tab System (Canvas | Smart Catalog)
↓
Canvas → GET /admin/assets (filtrado por type)
↓
Smart Catalog → GET /admin/products
↓
Fusion Engine → POST /admin/generate-image
↓
Google Imagen 3 → Visual Asset
2. Frontend: Tab System
BusinessForge Component
const BusinessForge: React.FC = () => {
const [activeTab, setActiveTab] = useState<'canvas' | 'catalog'>('canvas');
const [assets, setAssets] = useState<Asset[]>([]);
const [products, setProducts] = useState<Product[]>([]);
useEffect(() => {
if (activeTab === 'canvas') {
loadAssets();
} else {
loadProducts();
}
}, [activeTab]);
const loadAssets = async () => {
const data = await useApi<Asset[]>({
method: 'GET',
url: '/admin/assets'
});
setAssets(data);
};
const loadProducts = async () => {
const data = await useApi<Product[]>({
method: 'GET',
url: '/admin/products'
});
setProducts(data);
};
return (
<div className="forge-container">
{/* Tab Navigation */}
<div className="tabs">
<button
className={activeTab === 'canvas' ? 'active' : ''}
onClick={() => setActiveTab('canvas')}
>
🎨 Canvas
</button>
<button
className={activeTab === 'catalog' ? 'active' : ''}
onClick={() => setActiveTab('catalog')}
>
📦 Smart Catalog
</button>
</div>
{/* Content */}
<div className="forge-content">
{activeTab === 'canvas' ? (
<CanvasView assets={assets} />
) : (
<CatalogView products={products} />
)}
</div>
</div>
);
};
3. Canvas View (Assets Generados)
Filtrado por Tipo
const CanvasView: React.FC<{ assets: Asset[] }> = ({ assets }) => {
const [filter, setFilter] = useState<AssetType>('all');
const filteredAssets = filter === 'all'
? assets
: assets.filter(a => a.type === filter);
return (
<div className="canvas-view">
{/* Filtros */}
<div className="filters">
<button onClick={() => setFilter('all')}>All</button>
<button onClick={() => setFilter('branding')}>🧬 Branding</button>
<button onClick={() => setFilter('scripts')}>📝 Scripts</button>
<button onClick={() => setFilter('roi')}>💰 ROI</button>
<button onClick={() => setFilter('visuals')}>🎨 Visuals</button>
</div>
{/* Asset Grid */}
<div className="asset-grid">
{filteredAssets.map(asset => (
<AssetCard key={asset.id} asset={asset} />
))}
</div>
</div>
);
};
Asset Card (Polymorphic Renderer)
const AssetCard: React.FC<{ asset: Asset }> = ({ asset }) => {
const renderContent = () => {
switch (asset.type) {
case 'branding':
return <BrandingAsset content={asset.content} />;
case 'scripts':
return <ScriptsAsset content={asset.content} />;
case 'roi':
return <ROIAsset content={asset.content} />;
case 'visuals':
return <VisualsAsset content={asset.content} />;
default:
return <JSONView data={asset.content} />;
}
};
return (
<div className="asset-card">
<div className="asset-header">
<h3>{asset.type}</h3>
<span className="timestamp">
{new Date(asset.created_at).toLocaleDateString()}
</span>
</div>
<div className="asset-body">
{renderContent()}
</div>
</div>
);
};
Branding Asset
const BrandingAsset: React.FC<{ content: BrandingContent }> = ({ content }) => {
return (
<div className="branding-asset">
<div className="section">
<h4>MISIÓN</h4>
<p>{content.mission}</p>
</div>
<div className="section">
<h4>VISIÓN</h4>
<p>{content.vision}</p>
</div>
<div className="section">
<h4>VOZ DE MARCA</h4>
<p>{content.voice}</p>
</div>
<div className="section">
<h4>VALORES</h4>
<ul>
{content.values.map((v, i) => (
<li key={i}>{v}</li>
))}
</ul>
</div>
<div className="color-palette">
<h4>PALETA DE COLORES</h4>
<div className="colors">
{content.color_palette.map((color, i) => (
<div
key={i}
className="color-swatch"
style={{ backgroundColor: color }}
title={color}
/>
))}
</div>
</div>
</div>
);
};
Visuals Asset (Social Posts)
const VisualsAsset: React.FC<{ content: VisualsContent }> = ({ content }) => {
return (
<div className="visuals-grid">
{content.social_posts.map((post, i) => (
<FusionItem key={i} post={post} />
))}
</div>
);
};
4. Fusion Engine (Generación On-Demand)
FusionItem Component
interface FusionPost {
product_id: string;
product_name: string;
image_url: string; // URL de la imagen generada por IA
base_image?: string; // URL original del producto (para overlay)
prompt_used: string;
}
const FusionItem: React.FC<{ post: FusionPost }> = ({ post }) => {
const [viewMode, setViewMode] = useState<'dream' | 'reality'>('dream');
return (
<div className="fusion-item">
<div className="image-container">
{viewMode === 'dream' ? (
// Imagen pura de IA (puede alucinar detalles)
<img src={post.image_url} alt={post.product_name} />
) : (
// Overlay: fondo IA + producto real
<div className="reality-overlay">
<img
src={post.image_url}
className="background"
alt="AI Background"
/>
<img
src={post.base_image}
className="product-overlay"
alt={post.product_name}
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
maxWidth: '60%',
maxHeight: '60%',
mixBlendMode: 'multiply'
}}
/>
</div>
)}
</div>
<div className="fusion-controls">
<button
onClick={() => setViewMode(viewMode === 'dream' ? 'reality' : 'dream')}
>
{viewMode === 'dream' ? '🌟 Dream' : '✨ Reality'}
</button>
</div>
<div className="product-info">
<h4>{post.product_name}</h4>
<p className="prompt-hint">{post.prompt_used}</p>
</div>
</div>
);
};
Generar Nueva Imagen (Fusion Button)
const ProductCard: React.FC<{ product: Product }> = ({ product }) => {
const [generating, setGenerating] = useState(false);
const handleIgniteFusion = async () => {
setGenerating(true);
try {
const prompt = `
Professional advertising shot of ${product.name}.
Luxury aesthetic, soft lighting, minimal background.
High-end product photography, studio quality.
`;
const response = await useApi({
method: 'POST',
url: '/admin/generate-image',
data: {
prompt: prompt,
image_url: product.image_url
}
});
if (response.status === 'success') {
// Guardar en assets
await saveGeneratedVisual(response.url, product);
alert('Visual generated!');
}
} catch (error) {
alert('Generation failed');
} finally {
setGenerating(false);
}
};
return (
<div className="product-card">
<img src={product.image_url} alt={product.name} />
<h3>{product.name}</h3>
<p>${product.price}</p>
<button
onClick={handleIgniteFusion}
disabled={generating}
className="fusion-btn"
>
{generating ? 'Generating...' : '🔥 Ignite Fusion'}
</button>
</div>
);
};
5. Backend: Fusion Engine
generate-image Endpoint
# orchestrator_service/app/api/v1/endpoints/forge.py
@router.post("/admin/generate-image")
async def generate_image(
payload: ImageGenerationRequest,
current_user = Depends(verify_admin_token)
):
"""
Genera imagen publicitaria usando Google Imagen 3
"""
tenant_id = await resolve_tenant(current_user.id)
# Validar credencial de Google
google_key = await get_tenant_credential(
tenant_id=tenant_id,
category="google",
name="API_KEY"
)
if not google_key:
raise HTTPException(
status_code=400,
detail="Google API key not configured"
)
# Opcionalmente, descargar imagen base para context
base_image_data = None
if payload.image_url:
img_response = await httpx.get(payload.image_url)
base_image_data = img_response.content
# Llamar a Google Imagen 3
try:
response = await httpx.post(
"https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0:generate",
headers={
"Authorization": f"Bearer {google_key}",
"Content-Type": "application/json"
},
json={
"prompt": payload.prompt,
"num_images": 1,
"aspect_ratio": "1:1",
"safety_filter": "medium"
},
timeout=60.0
)
if response.status_code != 200:
raise HTTPException(
status_code=response.status_code,
detail=f"Google Imagen API error: {response.text}"
)
data = response.json()
generated_url = data['images'][0]['url']
return {
"status": "success",
"url": generated_url
}
except Exception as e:
logger.error(f"Image generation failed: {str(e)}")
raise HTTPException(
status_code=500,
detail=f"Generation failed: {str(e)}"
)
6. Smart Catalog (Product Browser)
Catalog View
const CatalogView: React.FC<{ products: Product[] }> = ({ products }) => {
const [categoryFilter, setCategoryFilter] = useState<string | null>(null);
// Extraer categorías únicas
const categories = Array.from(
new Set(products.map(p => p.category).filter(Boolean))
);
const filteredProducts = categoryFilter
? products.filter(p => p.category === categoryFilter)
: products;
return (
<div className="catalog-view">
{/* Filtro de categorías */}
<div className="category-filters">
<button
className={!categoryFilter ? 'active' : ''}
onClick={() => setCategoryFilter(null)}
>
All Products
</button>
{categories.map(cat => (
<button
key={cat}
className={categoryFilter === cat ? 'active' : ''}
onClick={() => setCategoryFilter(cat)}
>
{cat}
</button>
))}
</div>
{/* Grid de productos */}
<div className="product-grid">
{filteredProducts.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
</div>
);
};
7. Persistencia de Assets
Backend: Assets Endpoint
@router.get("/admin/assets")
async def list_assets(
current_user = Depends(verify_admin_token),
type_filter: Optional[str] = None,
session: AsyncSession = Depends(get_session)
):
"""
Lista assets generados
"""
tenant_id = await resolve_tenant(current_user.id)
# Query base
stmt = select(BusinessAsset).where(
BusinessAsset.tenant_id == tenant_id
)
# Filtro opcional por tipo
if type_filter:
stmt = stmt.where(BusinessAsset.type == type_filter)
# Ordenar por más reciente
stmt = stmt.order_by(BusinessAsset.created_at.desc())
result = await session.execute(stmt)
assets = result.scalars().all()
return [
{
"id": a.id,
"type": a.type,
"content": a.content,
"created_at": a.created_at.isoformat()
}
for a in assets
]
Guardar Visual Generado
@router.post("/admin/assets", status_code=201)
async def save_asset(
payload: AssetCreate,
current_user = Depends(verify_admin_token),
session: AsyncSession = Depends(get_session)
):
tenant_id = await resolve_tenant(current_user.id)
asset = BusinessAsset(
tenant_id=tenant_id,
type=payload.type,
content=payload.content
)
session.add(asset)
await session.commit()
await session.refresh(asset)
return {
"id": asset.id,
"status": "saved"
}
8. Reality vs Dream Mode (CSS Magic)
CSS Implementation
/* Reality Mode: Overlay */
.reality-overlay {
position: relative;
width: 100%;
aspect-ratio: 1 / 1;
overflow: hidden;
}
.reality-overlay .background {
width: 100%;
height: 100%;
object-fit: cover;
filter: brightness(0.9); /* Oscurecer ligeramente fondo */
}
.reality-overlay .product-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 60%;
max-height: 60%;
object-fit: contain;
mix-blend-mode: multiply; /* Mezclar con fondo */
filter: drop-shadow(0 10px 30px rgba(0,0,0,0.3)); /* Sombra realista */
}
9. Export & Download
Exportar Asset
const exportAsset = async (asset: Asset) => {
if (asset.type === 'visuals') {
// Descargar imagen
const imageUrl = asset.content.social_posts[0].image_url;
const link = document.createElement('a');
link.href = imageUrl;
link.download = `visual_${asset.id}.jpg`;
link.click();
} else {
// Descargar JSON
const blob = new Blob(
[JSON.stringify(asset.content, null, 2)],
{ type: 'application/json' }
);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `${asset.type}_${asset.id}.json`;
link.click();
}
};
10. Troubleshooting
"No se ve la imagen generada"
Causa: URL de Google Imagen tiene CORS restrictivo
Solución: Proxy la imagen a través del backend o guardarla en storage
"Fusion falla silenciosamente"
Causa: Google API quota excedida
Solución: Verificar quota en Google Cloud Console
"Overlay no se ve bien"
Causa: Imagen original tiene fondo blanco (no transparente)
Solución: Usar productos con PNGs transparentes o aplicar remove-bg
"Assets no cargan"
Causa: tenant_id incorrecto
Solución: Verificar resolve_tenant en backend
11. Checklist de Implementación
Frontend
- Tab system (Canvas / Catalog)
- Asset grid con filtros
- Polymorphic asset renderer
- Fusion button funcional
- Reality vs Dream toggle
- Category filters en Catalog
- Export/Download assets
Backend
- GET /admin/assets (con filtros)
- POST /admin/generate-image
- GET /admin/products (desde TiendaNube)
- POST /admin/assets (guardar generados)
- Google Imagen 3 integration
- Validación de credenciales
Visuals
- Branding asset renderer
- Scripts asset renderer
- ROI asset renderer
- Social posts grid
- CSS overlay effect
- Product cards con imagen
Tip: Para mejores resultados en Fusion, usar prompts específicos con estilo deseado (ej: "minimalist white background", "luxury studio lighting").
More Other skills
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
internal-comms
A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
Fundamental design principles for writing maintainable, testable Python code.
responsive-design
Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.
Generate Playwright tests from scenarios using interactive browser exploration and validation.
Automated website exploration and test case generation using Playwright.
Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.
gdpr-data-handling
GDPR-compliant data handling with consent management, data subject rights, and privacy controls.
Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.
refactor-plan
Detailed multi-file refactor planning with safety checks and rollback guidance.
