Context
AGENTS.md stack table: Meta Ads (MCP active, META_ADS_MCP_ACTIVE=true). .ralph/PROMPT-promotion.md § 3 specifies the draft payload shape. No code exists.
Goal
A lib/publish/meta-ads.ts module that takes a winner piece + persona + creative IDs and creates a paused Meta Ads campaign draft.
Acceptance criteria
Files
- New:
lib/publish/meta-ads.ts
data/promotions.jsonl (writer)
Depends on
- #classifier (consumer)
- #pieces-engine (frontmatter
provider_override.ads)
Context
AGENTS.md stack table: Meta Ads (MCP active,
META_ADS_MCP_ACTIVE=true)..ralph/PROMPT-promotion.md§ 3 specifies the draft payload shape. No code exists.Goal
A
lib/publish/meta-ads.tsmodule that takes a winner piece + persona + creative IDs and creates a paused Meta Ads campaign draft.Acceptance criteria
META_ADS_MCP_ACTIVEfrom env; throws clearly iffalsedraftCampaign(piece, persona, creativeIds)returns the campaign payloadOUTCOME_ENGAGEMENT(overridable via piece frontmatter).specs/clients/<client>/PERSONAS.md(persona by piece'spersona_id)DRY_RUN=true: writesoutputs/<client>/<date>/<piece-id>/ads-draft.json(per PROMPT-promotion.md § 3)DRY_RUN=false: calls the Meta Ads MCP (mcp__*__ads_create_campaign+ads_create_ad_set+ads_create_creative+ads_create_ad) — all pauseddata/promotions.jsonl(per DESIGN.md § Data Flow)Files
lib/publish/meta-ads.tsdata/promotions.jsonl(writer)Depends on
provider_override.ads)