Install
$ agentstack add skill-citedy-adclaw-ads-dna ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Ads DNA: Brand DNA Extractor
Extracts brand identity from a website and saves it as brand-profile.json for use by /ads create, /ads generate, and /ads photoshoot.
Quick Reference
| Command | What it does | |---------|-------------| | /ads dna | Full brand extraction → brand-profile.json | | /ads dna https://acme.com --quick | Fast extraction (homepage only) |
Process
Step 1: Collect URL
If the user hasn't provided a URL, ask: > "What website URL should I analyze for brand DNA? (e.g. https://yoursite.com)"
Step 2: Fetch Pages
Use the browser tool (agent_browser or curl) to retrieve each page. For each URL, extract: > "Return all visible text content, the full contents of any ` blocks, inline > style= attributes, tags, Google Fonts @import URLs, and any og:image` > values found on this page."
Fetch in this order:
- Homepage (``)
- About page: try
/about, then/about-us, then/our-story - Product/Services page: try
/product, then/products, then/services
If --quick flag was provided: fetch the homepage only; skip steps 2 and 3.
If a secondary page returns a 404 or redirect error, continue with fewer pages and note: "Secondary pages unavailable; extraction based on homepage only. Confidence may be lower."
Step 2b: Capture Brand Screenshots
After fetching pages, capture 3 screenshots for comprehensive brand anchoring. These serve as visual style references during /ads generate; the same approach Pomelli uses to anchor ad images to the actual brand aesthetic.
Capture the following:
- Homepage hero section (above the fold) — use browser MCP tool to navigate and screenshot
- Product or services page — navigate to /products and screenshot
- About page (brand personality) — navigate to /about and screenshot
Save screenshots to ./brand-screenshots/{domain}_{page}.png. Use the agent_browser MCP or Playwright MCP for screenshots. If no browser MCP is available, skip screenshot capture and rely on text extraction.
If a page is not found or returns an error, skip it gracefully and continue with the remaining pages.
If --quick flag was provided: skip screenshot capture entirely.
If capture fails (Playwright not installed, network error, JS-heavy SPA that times out):
- Log:
"Screenshot capture skipped; run: python3 -m playwright install chromium" - Continue without screenshots
- Do NOT set the
screenshotsfield in brand-profile.json
Step 3: Extract Brand Elements
From the fetched HTML, extract:
Colors:
og:imagemeta tag → analyze dominant colors (note 2-3 prominent hex values)- CSS
background-coloronbody,header,.hero,.btn-primary - CSS
coloronh1,h2,.btn - CSS
border-colororbackgroundon.cta,.button - Identify: primary (most prominent brand color), secondary (supporting colors), background, text
Typography:
@import url(https://fonts.googleapis.com/...)→ extract font names from URL path- CSS
font-familyonh1,h2,body,.headline - If Google Fonts URL contains
family=Inter:wght@..., heading_font = "Inter"
Voice: Analyze hero headline, subheadline, About page intro, and CTA button text. Score each axis 1-10 using these heuristics:
| Signal | Score direction | |--------|----------------| | Uses "you/your" frequently | formalcasual → casual (+2) | | Uses technical jargon | expertaccessible → expert (-2) | | Short punchy sentences (≤8 words) | boldsubtle → bold (+2) | | Data/stats in hero | rationalemotional → rational (-2) | | "Transform", "revolutionize", "disrupt" | traditionalinnovative → innovative (+2) | | Customer testimonials lead | rationalemotional → emotional (+2) | | Industry awards, "trusted by X" | traditional_innovative → traditional (-1) |
Imagery style (from og:image and any visible hero image descriptions):
- Photography vs. illustration vs. flat design
- Subject matter (people, product, abstract, data)
- Composition style (clean/minimal vs. busy/editorial)
Forbidden elements (infer from brand positioning):
- Enterprise/B2B brands → add "cheesy stock photos", "consumer lifestyle imagery"
- Healthcare → add "unqualified medical claims", "before/after imagery"
- Finance → add "get rich quick imagery", "unrealistic wealth displays"
- Consumer brands → usually no forbidden elements
Step 4: Build brand-profile.json
Read ads-shared/references/brand-dna-template.md for the exact schema.
Construct the JSON object following the schema precisely. Use null for any field that cannot be confidently extracted; do not guess.
Example of a low-confidence field:
"typography": {
"heading_font": null,
"body_font": "system-ui",
"pairing_descriptor": "system default (Google Fonts not detected)"
}
Step 5: Write brand-profile.json
Write the JSON to ./brand-profile.json in the current working directory (where the user is running Claude Code).
If screenshots were captured successfully in Step 2b, include a screenshots field:
"screenshots": {
"homepage": "./brand-screenshots/{domain}_homepage.png",
"product": "./brand-screenshots/{domain}_product.png",
"about": "./brand-screenshots/{domain}_about.png"
}
Include only the screenshots that were successfully captured. If a page was not found or errored, omit that key. Omit the screenshots field entirely if Step 2b was skipped or all captures failed.
Step 6: Confirm and Summarize
Show the user:
✓ brand-profile.json saved to ./brand-profile.json
Brand DNA Summary:
Brand: [brand_name]
Voice: [descriptor 1], [descriptor 2], [descriptor 3]
Primary Color: [hex]
Typography: [heading_font] / [body_font]
Target: [age_range] [profession]
Screenshots: [N captured (homepage, product, about) in ./brand-screenshots/] OR [skipped]
Run `/ads create` to generate campaign concepts from this profile.
Visual Designer Integration
The visual-designer agent uses the most relevant screenshot per concept as a style reference when generating images via banana. For example, a product-focused concept references the product page screenshot, while a brand awareness concept references the homepage or about page screenshot.
Limitations
- Sparse content: Sites with <200 words of body text produce lower-confidence profiles.
Note: "Low confidence extraction; limited content available for analysis."
- Dynamic sites: JavaScript-rendered content may not be captured. Playwright is not
used by default. If the site appears to be SPA/React with no static HTML, note this.
- Multi-brand enterprises: This tool creates one profile per URL. Run separately
for each brand/product line.
- Dark mode sites: If body background is #333 or darker, swap background/text values.
- CSS-in-JS: Modern React sites may not have extractable CSS. Use og:image colors as fallback.
brand-profile.json Schema
{
"schema_version": "1.0",
"brand_name": "string",
"website_url": "string",
"extracted_at": "ISO-8601",
"voice": {
"formal_casual": 1-10,
"rational_emotional": 1-10,
"playful_serious": 1-10,
"bold_subtle": 1-10,
"traditional_innovative": 1-10,
"expert_accessible": 1-10,
"descriptors": ["adjective1", "adjective2", "adjective3"]
},
"colors": {
"primary": "#hexcode or null",
"secondary": ["#hex1", "#hex2"],
"forbidden": ["#hex or color name"],
"background": "#hexcode",
"text": "#hexcode"
},
"typography": {
"heading_font": "Font Name or null",
"body_font": "Font Name or system-ui",
"pairing_descriptor": "brief description"
},
"imagery": {
"style": "professional photography | illustration | flat design | mixed",
"subjects": ["subject1", "subject2"],
"composition": "brief description",
"forbidden": ["element1", "element2"]
},
"aesthetic": {
"mood_keywords": ["keyword1", "keyword2", "keyword3"],
"texture": "minimal | textured | mixed",
"negative_space": "generous | moderate | dense"
},
"brand_values": ["value1", "value2", "value3"],
"target_audience": {
"age_range": "e.g. 25-45",
"profession": "brief description",
"pain_points": ["pain1", "pain2"],
"aspirations": ["aspiration1", "aspiration2"]
}
}
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: citedy
- Source: citedy/adclaw
- License: Apache-2.0
- Homepage: https://pypi.org/project/adclaw/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.