
asset manager
Organize design assets, optimize images and fonts, maintain brand asset libraries, implement version control for assets, and enforce naming conventions. Keep design assets organized and production-ready.
- Installs
- 162
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/daffy0208/ai-dev-standards --skill asset-manager- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads asset manager automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Asset Manager
Keep design assets organized, optimized, and accessible.
Core Principle
Organized assets = faster development.
Assets should be:
- Easy to find
- Properly named
- Optimized for production
- Version controlled
- Consistently formatted
Phase 1: Asset Organization
Directory Structure
assets/
├── images/
│ ├── products/
│ ├── team/
│ ├── marketing/
│ └── ui/
├── icons/
│ ├── svg/
│ └── png/
├── fonts/
│ ├── primary/
│ └── secondary/
├── videos/
├── logos/
│ ├── svg/
│ ├── png/
│ └── variants/
└── brand/
├── colors.json
├── typography.json
└── guidelines.pdf
Naming Conventions
Images:
{category}-{description}-{size}.{format}
Examples:
product-hero-1920x1080.jpg
team-sarah-400x400.jpg
ui-background-pattern.png
Icons:
{icon-name}-{variant}.svg
Examples:
home-outline.svg
home-filled.svg
user-circle.svg
arrow-right.svg
Fonts:
{font-family}-{weight}.{format}
Examples:
Inter-Regular.woff2
Inter-Bold.woff2
Poppins-SemiBold.woff2
Automated Organization Script
// scripts/organize-assets.ts
import fs from 'fs/promises'
import path from 'path'
interface AssetRule {
pattern: RegExp
destination: string
}
const rules: AssetRule[] = [
{ pattern: /product-/i, destination: 'images/products' },
{ pattern: /team-/i, destination: 'images/team' },
{ pattern: /icon-/i, destination: 'icons/svg' },
{ pattern: /logo-/i, destination: 'logos' }
]
async function organizeAssets(sourceDir: string) {
const files = await fs.readdir(sourceDir)
for (const file of files) {
const sourcePath = path.join(sourceDir, file)
const stat = await fs.stat(sourcePath)
if (stat.isDirectory()) continue
// Find matching rule
const rule = rules.find(r => r.pattern.test(file))
if (rule) {
const destDir = path.join('assets', rule.destination)
await fs.mkdir(destDir, { recursive: true })
const destPath = path.join(destDir, file)
await fs.rename(sourcePath, destPath)
console.log(`Moved: ${file} → ${rule.destination}`)
}
}
console.log('Assets organized!')
}
organizeAssets('./unsorted-assets')
Phase 2: Image Optimization
Install Optimization Tools
npm install sharp imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo
Optimize Images Script
// scripts/optimize-images.ts
import sharp from 'sharp'
import imagemin from 'imagemin'
import imageminMozjpeg from 'imagemin-mozjpeg'
import imageminPngquant from 'imagemin-pngquant'
import imageminSvgo from 'imagemin-svgo'
import fs from 'fs/promises'
import path from 'path'
interface OptimizeOptions {
quality?: number
maxWidth?: number
formats?: ('jpg' | 'png' | 'webp' | 'avif')[]
}
async function optimizeImages(inputDir: string, outputDir: string, options: OptimizeOptions = {}) {
const { quality = 80, maxWidth = 2000, formats = ['jpg', 'png', 'webp'] } = options
const files = await fs.readdir(inputDir)
for (const file of files) {
const inputPath = path.join(inputDir, file)
const stat = await fs.stat(inputPath)
if (stat.isDirectory()) continue
const ext = path.extname(file).toLowerCase()
const name = path.basename(file, ext)
console.log(`Processing: ${file}`)
// Skip SVGs (handle separately)
if (ext === '.svg') {
await optimizeSVG(inputPath, outputDir)
continue
}
// Skip non-images
if (!['.jpg', '.jpeg', '.png'].includes(ext)) continue
// Read image
const image = sharp(inputPath)
const metadata = await image.metadata()
// Resize if too large
if (metadata.width && metadata.width > maxWidth) {
image.resize(maxWidth, null, {
withoutEnlargement: true,
fit: 'inside'
})
}
// Generate formats
for (const format of formats) {
const outputPath = path.join(outputDir, `${name}.${format}`)
if (format === 'jpg') {
await image.jpeg({ quality, mozjpeg: true }).toFile(outputPath)
} else if (format === 'png') {
await image.png({ quality, compressionLevel: 9 }).toFile(outputPath)
} else if (format === 'webp') {
await image.webp({ quality }).toFile(outputPath)
} else if (format === 'avif') {
await image.avif({ quality }).toFile(outputPath)
}
console.log(` ✓ Generated ${format}`)
}
}
console.log('Images optimized!')
}
async function optimizeSVG(inputPath: string, outputDir: string) {
const fileName = path.basename(inputPath)
const outputPath = path.join(outputDir, fileName)
await imagemin([inputPath], {
destination: outputDir,
plugins: [
imageminSvgo({
plugins: [
{ name: 'removeViewBox', active: false },
{ name: 'removeDimensions', active: true },
{ name: 'removeUselessStrokeAndFill', active: true }
]
})
]
})
console.log(` ✓ Optimized SVG`)
}
// Usage
optimizeImages('./assets/images/raw', './assets/images/optimized', {
quality: 85,
maxWidth: 1920,
formats: ['jpg', 'webp', 'avif']
})
Responsive Images Generator
// scripts/generate-responsive-images.ts
import sharp from 'sharp'
import fs from 'fs/promises'
import path from 'path'
const breakpoints = [
{ name: 'mobile', width: 640 },
{ name: 'tablet', width: 768 },
{ name: 'desktop', width: 1920 }
]
async function generateResponsiveImages(inputPath: string) {
const ext = path.extname(inputPath)
const name = path.basename(inputPath, ext)
const dir = path.dirname(inputPath)
for (const bp of breakpoints) {
const image = sharp(inputPath)
// Resize
image.resize(bp.width, null, {
withoutEnlargement: true,
fit: 'inside'
})
// Generate WebP
const webpPath = path.join(dir, `${name}-${bp.name}.webp`)
await image.webp({ quality: 80 }).toFile(webpPath)
console.log(` ✓ ${name}-${bp.name}.webp`)
// Generate AVIF
const avifPath = path.join(dir, `${name}-${bp.name}.avif`)
await image.avif({ quality: 80 }).toFile(avifPath)
console.log(` ✓ ${name}-${bp.name}.avif`)
}
console.log(`Generated responsive images for: ${name}`)
}
// Usage
generateResponsiveImages('./assets/images/hero.jpg')
Phase 3: Font Management
Font Optimization
// scripts/optimize-fonts.ts
import { exec } from 'child_process'
import { promisify } from 'util'
import fs from 'fs/promises'
import path from 'path'
const execAsync = promisify(exec)
async function optimizeFonts(inputDir: string, outputDir: string) {
const files = await fs.readdir(inputDir)
for (const file of files) {
const inputPath = path.join(inputDir, file)
const ext = path.extname(file).toLowerCase()
if (ext !== '.ttf' && ext !== '.otf') continue
const name = path.basename(file, ext)
console.log(`Processing: ${file}`)
// Convert to WOFF2 (best compression)
const woff2Path = path.join(outputDir, `${name}.woff2`)
await convertToWOFF2(inputPath, woff2Path)
console.log(` ✓ ${name}.woff2`)
// Convert to WOFF (fallback)
const woffPath = path.join(outputDir, `${name}.woff`)
await convertToWOFF(inputPath, woffPath)
console.log(` ✓ ${name}.woff`)
}
console.log('Fonts optimized!')
}
async function convertToWOFF2(input: string, output: string) {
// Requires woff2_compress tool
// Install: brew install woff2
await execAsync(`woff2_compress ${input}`)
const woff2File = input.replace(/\.(ttf|otf)$/, '.woff2')
await fs.rename(woff2File, output)
}
async function convertToWOFF(input: string, output: string) {
// Requires sfnt2woff tool
await execAsync(`sfnt2woff ${input}`)
const woffFile = input.replace(/\.(ttf|otf)$/, '.woff')
await fs.rename(woffFile, output)
}
optimizeFonts('./assets/fonts/raw', './assets/fonts/optimized')
Font Loading Strategy
/* fonts.css */
/* Preload critical fonts */
@font-face {
font-family: 'Inter';
src:
url('/fonts/Inter-Regular.woff2') format('woff2'),
url('/fonts/Inter-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap; /* Show fallback first */
}
@font-face {
font-family: 'Inter';
src:
url('/fonts/Inter-Bold.woff2') format('woff2'),
url('/fonts/Inter-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
font-display: swap;
}
Preload in HTML:
<head>
<!-- Preload critical fonts -->
<link rel="preload" href="/fonts/Inter-Regular.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Inter-Bold.woff2" as="font" type="font/woff2" crossorigin />
</head>
Phase 4: Asset Version Control
Git LFS Setup
# Install Git LFS
brew install git-lfs
git lfs install
# Track large files
git lfs track "*.psd"
git lfs track "*.ai"
git lfs track "*.sketch"
git lfs track "*.fig"
git lfs track "*.mp4"
git lfs track "*.mov"
git lfs track "assets/images/**/*.jpg"
git lfs track "assets/images/**/*.png"
# Add .gitattributes
git add .gitattributes
git commit -m "Configure Git LFS"
Asset Versioning System
// scripts/version-assets.ts
import fs from 'fs/promises'
import path from 'path'
import crypto from 'crypto'
interface AssetVersion {
path: string
hash: string
size: number
modified: string
version: number
}
class AssetVersionManager {
private versionFile = 'asset-versions.json'
private versions: Map<string, AssetVersion[]> = new Map()
async load() {
try {
const data = await fs.readFile(this.versionFile, 'utf-8')
const parsed = JSON.parse(data)
for (const [path, versions] of Object.entries(parsed)) {
this.versions.set(path, versions as AssetVersion[])
}
} catch (error) {
// File doesn't exist yet
}
}
async save() {
const data = Object.fromEntries(this.versions)
await fs.writeFile(this.versionFile, JSON.stringify(data, null, 2))
}
async trackAsset(filePath: string) {
const buffer = await fs.readFile(filePath)
const hash = crypto.createHash('sha256').update(buffer).digest('hex')
const stat = await fs.stat(filePath)
const versions = this.versions.get(filePath) || []
const lastVersion = versions[versions.length - 1]
// Check if changed
if (lastVersion && lastVersion.hash === hash) {
console.log(`No changes: ${filePath}`)
return
}
// Add new version
versions.push({
path: filePath,
hash,
size: stat.size,
modified: stat.mtime.toISOString(),
version: versions.length + 1
})
this.versions.set(filePath, versions)
console.log(`Tracked: ${filePath} (v${versions.length})`)
}
async trackDirectory(dirPath: string) {
const files = await fs.readdir(dirPath, { recursive: true })
for (const file of files) {
const filePath = path.join(dirPath, file.toString())
const stat = await fs.stat(filePath)
if (stat.isDirectory()) continue
await this.trackAsset(filePath)
}
}
}
// Usage
const manager = new AssetVersionManager()
await manager.load()
await manager.trackDirectory('./assets')
await manager.save()
Phase 5: Brand Asset Library
Brand Kit Structure
brand/
├── logos/
│ ├── primary/
│ │ ├── logo-full.svg
│ │ ├── logo-icon.svg
│ │ └── logo-wordmark.svg
│ ├── variations/
│ │ ├── logo-white.svg
│ │ ├── logo-black.svg
│ │ └── logo-inverted.svg
│ └── exports/
│ ├── png/
│ ├── pdf/
│ └── eps/
├── colors/
│ ├── colors.json
│ ├── colors.css
│ └── colors.scss
├── typography/
│ ├── fonts/
│ └── typography.json
└── guidelines/
├── brand-guidelines.pdf
├── logo-usage.pdf
└── color-usage.pdf
Brand Asset Manifest
// brand/manifest.ts
export interface BrandAssets {
version: string
lastUpdated: string
logos: LogoAsset[]
colors: ColorAsset[]
typography: TypographyAsset[]
}
export interface LogoAsset {
name: string
variants: {
full: string
icon: string
wordmark: string
}
formats: {
svg: string
png: { [size: string]: string }
pdf: string
}
}
export interface ColorAsset {
name: string
hex: string
rgb: { r: number; g: number; b: number }
usage: string
}
export interface TypographyAsset {
name: string
family: string
weights: number[]
formats: string[]
}
export const brandAssets: BrandAssets = {
version: '2.0.0',
lastUpdated: '2024-01-15',
logos: [
{
name: 'Primary Logo',
variants: {
full: '/brand/logos/logo-full.svg',
icon: '/brand/logos/logo-icon.svg',
wordmark: '/brand/logos/logo-wordmark.svg'
},
formats: {
svg: '/brand/logos/logo-full.svg',
png: {
'1x': '/brand/logos/exports/png/logo-full@1x.png',
'2x': '/brand/logos/exports/png/logo-full@2x.png',
'3x': '/brand/logos/exports/png/logo-full@3x.png'
},
pdf: '/brand/logos/exports/pdf/logo-full.pdf'
}
}
],
colors: [
{
name: 'Primary',
hex: '#0066cc',
rgb: { r: 0, g: 102, b: 204 },
usage: 'Primary actions, links, brand elements'
}
],
typography: [
{
name: 'Inter',
family: 'Inter',
weights: [400, 600, 700],
formats: ['woff2', 'woff']
}
]
}
Best Practices
1. Optimize for Web
- Images: Use WebP/AVIF with JPEG fallback
- Icons: Use SVG sprites for multiple icons
- Fonts: Use WOFF2 with WOFF fallback
- Videos: Compress and provide multiple formats
2. Lazy Loading
// Lazy load images
;<img src="placeholder.jpg" data-src="hero.jpg" loading="lazy" alt="Hero" />
// Or use Next.js Image
import Image from 'next/image'
;<Image src="/hero.jpg" width={1920} height={1080} placeholder="blur" alt="Hero" />
3. Asset CDN
// Use CDN for assets
const CDN_URL = process.env.CDN_URL || ''
export function getAssetUrl(path: string): string {
if (CDN_URL) {
return `${CDN_URL}${path}`
}
return path
}
// Usage
<img src={getAssetUrl('/images/hero.jpg')} alt="Hero" />
4. Automated Asset Pipeline
// scripts/asset-pipeline.ts
async function runAssetPipeline() {
console.log('Starting asset pipeline...')
// 1. Organize assets
await organizeAssets('./unsorted')
// 2. Optimize images
await optimizeImages('./assets/images/raw', './assets/images/optimized')
// 3. Generate responsive images
await generateResponsiveImages('./assets/images/optimized')
// 4. Optimize fonts
await optimizeFonts('./assets/fonts/raw', './assets/fonts/optimized')
// 5. Version assets
const manager = new AssetVersionManager()
await manager.load()
await manager.trackDirectory('./assets')
await manager.save()
console.log('Asset pipeline complete!')
}
runAssetPipeline()
Tools & Resources
Optimization Tools:
- Sharp - Image processing
- ImageOptim - Image compression
- SVGO - SVG optimization
- Squoosh - Online image compression
Font Tools:
- Glyphhanger - Font subsetting
- Transfonter - Font conversion
- FontForge - Font editor
Related Skills:
visual-designer- Design principlesfigma-developer- Export from Figmabrand-designer- Brand asset creation
Organized assets, optimized performance. 📦
FAQ
What does the asset manager skill do?
Organize design assets, optimize images and fonts, maintain brand asset libraries, implement version control for assets, and enforce naming conventions. Keep design assets organized and production-ready.
How do I install asset manager?
Run npx skills add https://github.com/daffy0208/ai-dev-standards --skill asset-manager in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/asset-manager/ (personal) or .claude/skills/asset-manager/ (project).
Which AI agents can use asset manager?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is asset manager safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains asset manager?
It is published by daffy0208 in daffy0208/ai-dev-standards. It has 162 recorded installs.
More from daffy0208/ai-dev-standards
animation-designer
daffy0208/ai-dev-standards
Expert in web animations, transitions, and motion design using Framer Motion and CSS
brand-designer
daffy0208/ai-dev-standards
Expert in brand identity, logo design, and visual brand systems
3d-visualizer
daffy0208/ai-dev-standards
Expert in Three.js, 3D graphics, and interactive 3D visualizations
data-visualizer
daffy0208/ai-dev-standards
Expert in creating charts, dashboards, and data visualizations using modern libraries
video-producer
daffy0208/ai-dev-standards
Expert in video playback, streaming, and video player customization
knowledge base manager
daffy0208/ai-dev-standards
Design, build, and maintain comprehensive knowledge bases. Bridges document-based (RAG) and entity-based (graph) knowledge systems. Use when building knowledge-intensive applications, managing organizational knowledge, or creating intelligent information systems.
Popular marketing & seo skills
reddit-automation
flowkit-labs/skills
Find Reddit threads where people are genuinely asking for what you offer, then draft short, genuinely helpful replies — disclosing your affiliation honestly and naming your product only when it truly answers the question. Two moves: discovery — scan the right subreddits for real needs (recommendation asks, expressed pain, competitor mentions) and rank the few threads where you can actually help; drafting — write from real experience, respect each community's self-promo rules, and keep a human in the loop to review and post. This markets on Reddit the honest way: contribute value, disclose who you are, never astroturf. Distilled from the playbook behind doany.ai's Reddit agent. Triggers on "find reddit opportunities", "reddit marketing", "reddit automation", "reply on reddit for my product", "reddit community engagement", "reddit lead gen", or any ask to turn Reddit threads into genuine, disclosed marketing replies.
twitter-automation
101-skills/superpowers
Automate Twitter/X with posting, engagement, and user management via inference.sh CLI. Apps: x/post-tweet, x/post-create (with media), x/post-like, x/post-retweet, x/dm-send, x/user-follow. Capabilities: post tweets, schedule content, like posts, retweet, send DMs, follow users, get profiles. Use for: social media automation, content scheduling, engagement bots, audience growth, X API. Triggers: twitter api, x api, tweet automation, post to twitter, twitter bot, social media automation, x automation, tweet scheduler, twitter integration, post tweet, twitter post, x post, send tweet
twitter-automation
magentosh/superpowers
Automate Twitter/X with posting, engagement, and user management via inference.sh CLI. Apps: x/post-tweet, x/post-create (with media), x/post-like, x/post-retweet, x/dm-send, x/user-follow. Capabilities: post tweets, schedule content, like posts, retweet, send DMs, follow users, get profiles. Use for: social media automation, content scheduling, engagement bots, audience growth, X API. Triggers: twitter api, x api, tweet automation, post to twitter, twitter bot, social media automation, x automation, tweet scheduler, twitter integration, post tweet, twitter post, x post, send tweet
twitter-automation
qu-skills/superpowers
Automate Twitter/X with posting, engagement, and user management via inference.sh CLI. Apps: x/post-tweet, x/post-create (with media), x/post-like, x/post-retweet, x/dm-send, x/user-follow. Capabilities: post tweets, schedule content, like posts, retweet, send DMs, follow users, get profiles. Use for: social media automation, content scheduling, engagement bots, audience growth, X API. Triggers: twitter api, x api, tweet automation, post to twitter, twitter bot, social media automation, x automation, tweet scheduler, twitter integration, post tweet, twitter post, x post, send tweet
product-launch-video
heygen-com/hyperframes
Turn a product or marketing URL, pasted script, or brief into a product launch / promo video — SaaS promos, feature reveals, product demos, app and company launches. Use when the user wants to market, launch, promote, or reveal a product; the default for any commercial URL. Site tours / showcases of a website route here too — the brief carries the show-it-as-is intent. Unclear → /hyperframes.
twitter-automation
skills-shell/superpowers
Automate Twitter/X with posting, engagement, and user management via inference.sh CLI. Apps: x/post-tweet, x/post-create (with media), x/post-like, x/post-retweet, x/dm-send, x/user-follow. Capabilities: post tweets, schedule content, like posts, retweet, send DMs, follow users, get profiles. Use for: social media automation, content scheduling, engagement bots, audience growth, X API. Triggers: twitter api, x api, tweet automation, post to twitter, twitter bot, social media automation, x automation, tweet scheduler, twitter integration, post tweet, twitter post, x post, send tweet