Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Do not introduce additional dependencies without a clear reason. If a new librar

## Skill names — authoritative list

The `/skills` directory contains a pinned copy of `coreyhaines31/marketingskills` (v2.0.0). Only use skill names that actually exist in this repo.
The `/skills` directory contains a pinned copy of `coreyhaines31/marketingskills` (v2.2.0). Only use skill names that actually exist in this repo.

- `customer-research` exists and is valid.
- `vbf-messaging` does not exist and must never be referenced. Use `product-marketing` instead.
Expand All @@ -58,9 +58,9 @@ The `/skills` directory contains a pinned copy of `coreyhaines31/marketingskills
| `analyze` | `analytics`, `ab-testing` |
| `optimize` | `cro`, `copy-editing`, `ab-testing`, `signup`, `onboarding` |

### Valid skill names (complete list from `/skills`, v2.0.0)
### Valid skill names (complete list from `/skills`, v2.2.0)

`ab-testing`, `ad-creative`, `ads`, `ai-seo`, `analytics`, `aso`, `churn-prevention`, `co-marketing`, `cold-email`, `community-marketing`, `competitor-profiling`, `competitors`, `content-strategy`, `copy-editing`, `copywriting`, `cro`, `customer-research`, `directory-submissions`, `emails`, `free-tools`, `image`, `launch`, `lead-magnets`, `marketing-ideas`, `marketing-psychology`, `onboarding`, `paywalls`, `popups`, `pricing`, `product-marketing`, `programmatic-seo`, `referrals`, `revops`, `sales-enablement`, `schema`, `seo-audit`, `signup`, `site-architecture`, `social`, `video`
`ab-testing`, `ad-creative`, `ads`, `ai-seo`, `analytics`, `aso`, `churn-prevention`, `co-marketing`, `cold-email`, `community-marketing`, `competitor-profiling`, `competitors`, `content-strategy`, `copy-editing`, `copywriting`, `cro`, `customer-research`, `directory-submissions`, `emails`, `free-tools`, `image`, `launch`, `lead-magnets`, `marketing-ideas`, `marketing-psychology`, `onboarding`, `paywalls`, `popups`, `pricing`, `product-marketing`, `programmatic-seo`, `prospecting`, `referrals`, `revops`, `sales-enablement`, `schema`, `seo-audit`, `signup`, `site-architecture`, `sms`, `social`, `video`

---

Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ The `/skills` directory contains a pinned copy of `coreyhaines31/marketingskills
| `analyze` | `analytics`, `ab-testing` |
| `optimize` | `cro`, `copy-editing`, `ab-testing`, `signup`, `onboarding` |

### Valid skill names (complete list from `/skills`, v2.0.0)
### Valid skill names (complete list from `/skills`, v2.2.0)

`ab-testing`, `ad-creative`, `ads`, `ai-seo`, `analytics`, `aso`, `churn-prevention`, `co-marketing`, `cold-email`, `community-marketing`, `competitor-profiling`, `competitors`, `content-strategy`, `copy-editing`, `copywriting`, `cro`, `customer-research`, `directory-submissions`, `emails`, `free-tools`, `image`, `launch`, `lead-magnets`, `marketing-ideas`, `marketing-psychology`, `onboarding`, `paywalls`, `popups`, `pricing`, `product-marketing`, `programmatic-seo`, `referrals`, `revops`, `sales-enablement`, `schema`, `seo-audit`, `signup`, `site-architecture`, `social`, `video`
`ab-testing`, `ad-creative`, `ads`, `ai-seo`, `analytics`, `aso`, `churn-prevention`, `co-marketing`, `cold-email`, `community-marketing`, `competitor-profiling`, `competitors`, `content-strategy`, `copy-editing`, `copywriting`, `cro`, `customer-research`, `directory-submissions`, `emails`, `free-tools`, `image`, `launch`, `lead-magnets`, `marketing-ideas`, `marketing-psychology`, `onboarding`, `paywalls`, `popups`, `pricing`, `product-marketing`, `programmatic-seo`, `prospecting`, `referrals`, `revops`, `sales-enablement`, `schema`, `seo-audit`, `signup`, `site-architecture`, `sms`, `social`, `video`

---

Expand Down
4 changes: 2 additions & 2 deletions __tests__/artifact-patch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ describe('PATCH /api/artifacts/[id] — type validation', () => {
}
});

it('ARTIFACT_TYPES covers all 16 supported types', () => {
expect(ARTIFACT_TYPES).toHaveLength(16);
it('ARTIFACT_TYPES covers all 18 supported types', () => {
expect(ARTIFACT_TYPES).toHaveLength(18);
});
});

Expand Down
4 changes: 4 additions & 0 deletions __tests__/skills.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ describe('getSkillNamesForMode', () => {
['competitor_analysis', ['competitors', 'competitor-profiling']],
['seo', ['seo-audit', 'ai-seo']],
['cro', ['cro']],
['sms_campaign', ['sms']],
['prospect_list', ['prospecting']],
];

for (const [artifactType, expectedSkills] of mappings) {
Expand Down Expand Up @@ -291,6 +293,8 @@ describe('loadSkillsForMode', () => {
'competitor_analysis',
'seo',
'cro',
'sms_campaign',
'prospect_list',
];
for (const at of artifactTypes) {
await loadSkillsForMode('create', at);
Expand Down
2 changes: 2 additions & 0 deletions lib/ai/skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ const ARTIFACT_TYPE_SKILLS: Partial<Record<ArtifactType, string[]>> = {
competitor_analysis: ['competitors', 'competitor-profiling'],
seo: ['seo-audit', 'ai-seo'],
cro: ['cro'],
sms_campaign: ['sms'],
prospect_list: ['prospecting'],
};

const DEFAULT_CREATE_SKILLS = ['copywriting'];
Expand Down
2 changes: 1 addition & 1 deletion skills/PINNED_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bd8eb1a0e5a82379537298c0570e85279ca27337
692b76118c6b379f89c0fba987a228a40f58b418
93 changes: 92 additions & 1 deletion skills/ads/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: ads
description: "When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms. Also use when the user mentions 'PPC,' 'paid media,' 'ROAS,' 'CPA,' 'ad campaign,' 'retargeting,' 'audience targeting,' 'Google Ads,' 'Facebook ads,' 'LinkedIn ads,' 'ad budget,' 'cost per click,' 'ad spend,' or 'should I run ads.' Use this for campaign strategy, audience targeting, bidding, and optimization. For bulk ad creative generation and iteration, see ad-creative. For landing page optimization, see cro."
metadata:
version: 2.0.0
version: 2.0.1
---

# Paid Ads
Expand Down Expand Up @@ -257,6 +257,97 @@ Before launching campaigns, ensure proper tracking and account setup.

---

## Google RSA Output Spec (mandatory when generating RSAs)

When the user requests Google Ads RSAs (Responsive Search Ads), output MUST comply with these platform limits and structural requirements. Do not output any RSA that violates them.

### Hard limits per RSA (enforce before responding)

- **Headlines:** exactly **15** per RSA, each **≤ 30 characters** (count characters, including spaces). Render as `1. ... (NN chars)` so the reader can verify.
- **Descriptions:** exactly **4** per RSA, each **≤ 90 characters**.
- **Paths:** up to 2 path fields, each **≤ 15 characters**.
- **Final URL:** present, https.
- **Pinning:** state any pinned positions explicitly. Default = unpinned unless user asks.
- **Per-account guardrail:** Google enforces **3 RSAs max per ad group**. When the user asks for >3, group them by ad group.

### Required sidecar artifacts (always include with RSA request)

1. **Ad group structure**, labeled `Ad group structure:` — list each ad group with its theme, target keywords (match types), and which RSAs map to it.
2. **Negative keyword list**, labeled `Negative keywords:` — minimum **8** entries, group-level vs campaign-level called out.
3. **Sitelinks** (≥ 4), **Callouts** (≥ 4 ≤25 chars), **Structured snippets** if relevant.

### Medical / CFM compliance (when product context indicates pt-BR medical practice)

If `.agents/product-marketing.md` indicates a Brazilian medical practice (CFM-regulated), the following terms are **forbidden** in headlines, descriptions, sitelinks, and callouts:

- Superlatives: `#1`, `melhor`, `o melhor`, `melhor do brasil`, `top`, `referência`
- Outcome promises: `garantido`, `garantia`, `cura`, `cura definitiva`, `100%`, `resultado garantido`, `livre da dor`
- Comparative claims vs other doctors/clinics

Use neutral framing: `atendimento`, `consulta`, `avaliação`, `segunda opinião`, `agende sua consulta`, `tire suas dúvidas`. Geo modifier (`Porto Alegre`, `POA`, `Zona Sul POA`) required where the prompt specifies a region.

### Output ORDER (mandatory — emit in this order to avoid truncation)

1. **Ad group structure** (short)
2. **Negative keywords** (≥8, MANDATORY — emit BEFORE RSAs so it isn't dropped if output runs long)
3. **Sitelinks** (≥4)
4. **Callouts** (≥4)
5. **RSA1, RSA2, RSA3** (largest section, last — safe to truncate gracefully)

### Output template (mandatory shape)

```
Ad group structure:
- AG1 [theme]: keywords (match types) → RSA1, RSA2
- AG2 [theme]: ...

Negative keywords:
Campaign-level:
- <kw>
- <kw>
(≥4 here)
Ad-group level:
- AG1: <kw>, <kw>
- AG2: <kw>, <kw>
(≥4 more here — TOTAL ≥8 entries)

Sitelinks (≥4):
- <title (≤25)> | <desc1 (≤35)> | <desc2 (≤35)> | URL

Callouts (≥4, each ≤25 chars):
- <callout>

RSA1 — [ad group name]
Final URL: https://...
Path1: ... Path2: ...
Headlines (15, each ≤30 chars):
1. <headline> (NN chars)
...
15. <headline> (NN chars)
Descriptions (4, each ≤90 chars):
1. <description> (NN chars)
...
4. <description> (NN chars)
Pinning: H1=none; H2=none; ... (or explicit pins)

RSA2 — ...
RSA3 — ...
```

### Self-check before responding

Before sending the output, run this checklist mentally:

- [ ] Each RSA has exactly 15 headlines, exactly 4 descriptions.
- [ ] Every headline is ≤30 chars; every description is ≤90 chars. Character counts printed.
- [ ] Negative keyword list labeled and ≥8 entries.
- [ ] Ad group structure labeled.
- [ ] If medical (CFM): no forbidden superlative/outcome words; geo modifier present where required; language is pt-BR.

If any check fails, rewrite before responding. Do not ship partial RSAs.

---

## Common Mistakes to Avoid

### Strategy
Expand Down
90 changes: 90 additions & 0 deletions skills/ads/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"skill_name": "ads",
"evals": [
{
"id": 1,
"prompt": "Help me plan a paid advertising strategy. We're a B2B SaaS tool for HR teams, selling at $99/month per seat. We have $15k/month to spend on ads and want to generate demo requests. Where should we advertise?",
"expected_output": "Should check for product-marketing.md first. Should apply the platform selection guide based on B2B, HR audience, $99/month price point. Should recommend LinkedIn (B2B targeting by job title/industry), Google Ads (search intent for HR software keywords), and potentially Meta (retargeting). Should recommend campaign structure with naming conventions. Should define audience targeting strategy for each platform. Should set budget allocation across platforms. Should define success metrics and attribution approach. Should recommend starting structure and scaling plan.",
"assertions": [
"Checks for product-marketing.md",
"Applies platform selection guide",
"Recommends platforms appropriate for B2B HR audience",
"Recommends campaign structure with naming conventions",
"Defines audience targeting per platform",
"Sets budget allocation across platforms",
"Defines success metrics",
"Recommends starting structure and scaling plan"
],
"files": []
},
{
"id": 2,
"prompt": "Our Google Ads CPC is $12 and our cost per lead is $180. Is that good? We're getting about 80 leads/month from a $15k budget.",
"expected_output": "Should evaluate the metrics in context. Should assess: $12 CPC for B2B (reasonable depending on industry), $180 CPL (depends on LTV — need to compare against customer lifetime value), 80 leads/month from $15k (math checks out). Should apply the campaign optimization framework: check quality score, search term relevance, landing page conversion rate, negative keywords. Should recommend specific optimization levers to reduce CPC and CPL. Should frame performance against industry benchmarks if applicable. Should ask about downstream conversion rates (lead → demo → customer).",
"assertions": [
"Evaluates metrics in context",
"Compares CPL against LTV considerations",
"Applies campaign optimization framework",
"Recommends specific optimization levers",
"Asks about downstream conversion rates",
"Provides industry context for benchmarking"
],
"files": []
},
{
"id": 3,
"prompt": "we want to run retargeting ads for people who visited our site but didn't convert. how should we set this up?",
"expected_output": "Should trigger on casual phrasing. Should apply the retargeting strategies section, specifically the funnel-based approach. Should recommend audience segments: all visitors (broad), pricing page visitors (high intent), blog readers (lower intent), and cart/signup abandoners (highest intent). Should recommend different messaging and offers for each segment. Should address frequency capping to avoid ad fatigue. Should recommend retargeting platforms (Meta, Google Display, LinkedIn). Should include duration windows for each audience.",
"assertions": [
"Triggers on casual phrasing",
"Applies funnel-based retargeting approach",
"Recommends audience segments by intent level",
"Recommends different messaging per segment",
"Addresses frequency capping",
"Recommends retargeting platforms",
"Includes audience duration windows"
],
"files": []
},
{
"id": 4,
"prompt": "Should we advertise on TikTok? We sell accounting software to small businesses. Our current ads are on Google and Meta.",
"expected_output": "Should apply the platform selection guide for TikTok specifically. Should evaluate TikTok fit for accounting software + small business audience: likely a weaker fit than Google/Meta for this category (lower purchase intent, younger skewing audience, less B2B targeting). Should discuss when TikTok CAN work for B2B (brand awareness, creative content, younger business owners). Should provide an honest recommendation with caveats. Should suggest a small test budget approach if they want to try.",
"assertions": [
"Applies platform selection guide for TikTok",
"Evaluates fit for accounting + small business audience",
"Provides honest assessment of likely weaker fit",
"Discusses when TikTok can work for B2B",
"Suggests small test budget if proceeding",
"Compares to their existing Google/Meta performance"
],
"files": []
},
{
"id": 5,
"prompt": "How do we structure our Google Ads campaigns? We have 50+ keywords we want to target for our CRM product.",
"expected_output": "Should apply the campaign structure and naming conventions framework. Should recommend organizing campaigns by theme/intent (brand, competitor, product features, pain points). Should recommend ad group structure (tightly themed, 5-15 keywords per group). Should define naming conventions for campaigns and ad groups. Should recommend match types strategy. Should include negative keyword lists. Should provide a sample campaign structure.",
"assertions": [
"Applies campaign structure framework",
"Organizes campaigns by theme/intent",
"Recommends tight ad group structure",
"Defines naming conventions",
"Recommends match types strategy",
"Includes negative keyword lists",
"Provides sample campaign structure"
],
"files": []
},
{
"id": 6,
"prompt": "Can you write some ad copy for our Facebook ads? We need headlines and descriptions for 5 different angles.",
"expected_output": "Should recognize this is an ad creative generation task, not campaign strategy. Should defer to or cross-reference the ad-creative skill, which handles platform-specific ad copy generation with character limits, angle-based variation, and batch generation. May provide brief ad copy framework guidance but should make clear that ad-creative is the right skill for generating ad copy at scale.",
"assertions": [
"Recognizes this as ad creative generation",
"References or defers to ad-creative skill",
"Does not attempt bulk ad copy generation using campaign strategy patterns"
],
"files": []
}
]
}
Loading