# /copywrite

> Production copywriting skill for all 3 businesses (ACME Agency, ACME Agency, IA Outreach) across 5 platforms: Meta ads, Google Ads, landing pages, cold email, and email/newsletter.


# /copywrite

Platform-specific copy grounded in 12 expert principles. Always reads client context before writing. Always generates 3 variants with different hook types. Always applies the anti-AI sweep before outputting. Saves as a formatted Google Doc in the client's Drive Copywriting folder.

**Supported platforms:** `meta` | `google` | `landing` | `cold-email` | `email`

---

## Triggers

- `/copywrite meta "ACME Agency" --stage awareness --lang hr` — Meta awareness ads in Croatian
- `/copywrite google "ACME Agency" --intent commercial` — Google RSA asset set
- `/copywrite landing "ACME Agency" --lang de --funnel lead-gen` — German lead-gen landing page
- `/copywrite cold-email "ACME Agency" --icp "SaaS founders"` — Cold email sequence
- `/copywrite email "IA Outreach" --type broadcast --goal nurture` — Email broadcast
- If platform or client is missing, ask the user before proceeding

---

## Phase 0 — Context Load

**Always run this phase first, regardless of platform.**

### Step 0.1 — Parse inputs

Extract from the user's invocation:
- `platform` — meta | google | landing | cold-email | email
- `client` — the business or client name
- Any flags: `--stage`, `--lang`, `--funnel`, `--icp`, `--seq`, `--type`, `--goal`, `--intent`

If platform or client is missing, ask the user. Do not guess.

### Step 0.2 — Client context lookup

**For ACME Agency clients** (any name found in `ACME Agency/clients/clients.json`):
1. Read `ACME Agency/clients/clients.json` — get `slack_channel`, `drive_folder_id`, and any ad account IDs
2. Read `ACME Agency/clients/<ClientName>/CLIENT.md` — extract: business description, products/services, target audience, brand tone, market, USPs, competitors, pricing, conversion goal
3. Read `ACME Agency/clients/<ClientName>/brand-dna.md` if it exists — extract: voice adjectives, language, tone direction
4. Note: if `brand-dna.md` is missing, infer voice from CLIENT.md and website description

**For ACME Agency:**
1. Read `ACME Agency/CLAUDE.md` — full business context
2. Read `ACME Agency/brand-dna.md` if it exists
3. Slack channel: check `ACME Agency/clients/clients.json` for ACME Agency entry, or use `#ACME Agency` if not found

**For IA Outreach clients** (ACME Agency, etc.):
1. Read `ia-outreach/CLAUDE.md` — business context
2. Read `ia-outreach/clients/<ClientName>/CLAUDE.md` if it exists
3. Read all ICP files in `ia-outreach/clients/<ClientName>/icp/`
4. Slack channel: `#your-channel` unless noted otherwise

### Step 0.3 — Load existing copy artifacts (to avoid repeating angles)

**For Meta platform:**
- Read `ACME Agency/clients/<ClientName>/static_ads_manifest.json` if it exists
- Read `ACME Agency/clients/<ClientName>/static_ads_prompts.json` if it exists — scan headlines and hooks already in production
- Do NOT use a hook type already dominant in running ads

**For cold-email platform:**
- Read all files in `ia-outreach/clients/<ClientName>/sequences/` — note existing hooks, subject lines, CTAs

**For email platform:**
- Read recent email files in `ia-outreach/clients/<ClientName>/sequences/` if applicable

**For google/landing platforms:**
- CLIENT.md is sufficient — no artifact scanning needed

### Step 0.4 — Assemble the brief payload

You will hand all the context you've gathered (CLIENT.md notes, brand-dna, existing angles, platform, language, stage, etc.) to the `copywriter` agent in Phase 2. Do NOT read PRINCIPLES.md or the platform module file yourself — the agent will read them in its own context window. Your job in Phase 0 is gathering, not writing.

---

## Phase 2 — Delegate to the copywriter agent

Invoke the `copywriter` subagent via the **Task tool** with `subagent_type: "copywriter"`. Pass:

```
client: <client name>
business: ACME Agency | ACME Agency | ia-outreach
platform: meta-ad | google-rsa | landing-page | cold-email | newsletter
language: <hr | bs | de | en>
brief: <full brief assembled from Phase 0 — emotional driver candidates, audience, offer, USPs, mechanism, conversation in their mind, banned angles>
constraints: <character limits, must-include claims, banned words, tone constraints from CLIENT.md>
reference_files:
  - <absolute path to .claude/skills/copywrite/PRINCIPLES.md>
  - <absolute path to the platform-specific module file: .claude/skills/copywrite/META.md, GOOGLE.md, LANDING.md, COLD_EMAIL.md, or EMAIL.md>
  - <absolute path to CLIENT.md if it exists>
  - <absolute path to brand-dna.md if it exists>
variants: 3
```

The agent runs its **self-test loop** internally:
1. Picks angle (awareness level, big idea, emotional trigger, proof lever)
2. Drafts each variant
3. Tests each draft against `.claude/agents/copywriter.tests.md` (em-dashes, fragments, banned phrases, naturalness ≥ 8/10)
4. Revises and re-tests up to 5 iterations per variant
5. Returns when all tests pass OR after 5 iterations with explicit failures listed

The agent returns a structured payload:
- `iterations` per variant (1-5)
- `final_score` per variant (e.g. 9/10)
- `variant_a`, `variant_b`, `variant_c` — full Meta-ad-format copy
- `angle_notes` per variant — awareness level, big idea, emotional trigger, why it should work
- `fixed_in_revision` per variant — what the test loop caught
- `still_imperfect` — only if tests are still failing after 5 iterations

**Do NOT write copy yourself in this step.** If the agent's output isn't good enough, give it specific feedback and re-invoke. Don't hand-edit.

---

## Phase 3 — Output and Delivery

### Step 3.1 — Save locally

Save the full output to:
- ACME Agency clients: `ACME Agency/clients/<ClientName>/copy_<platform>_<YYYY-MM-DD>.md`
- ACME Agency: `ACME Agency/copy_<platform>_<YYYY-MM-DD>.md`
- IA Outreach clients: `ia-outreach/clients/<ClientName>/copy_<platform>_<YYYY-MM-DD>.md`

### Step 3.2 — Create Google Doc in Drive

Create a formatted Google Doc in the client's Drive folder under a `Copywriting` subfolder using `createFormattedDoc` from `ACME Agency/scripts/lib/google_docs.mjs` and `findOrCreateFolder` to create the subfolder if it doesn't exist.

```javascript
node --input-type=module <<'EOF'
import { createFormattedDoc, getAccessToken, findOrCreateFolder } from './ACME Agency/scripts/lib/google_docs.mjs';

const token = await getAccessToken();
const copywritingFolderId = await findOrCreateFolder(token, 'Copywriting', '<drive_folder_id>');

const { docUrl } = await createFormattedDoc(token, {
  folderId: copywritingFolderId,
  title: 'Copy — <ClientName> — <Platform> — <YYYY-MM-DD>',
  sections: [
    { type: 'title', text: 'Copy — <ClientName> — <Platform> — <YYYY-MM-DD>' },
    { type: 'subtitle', text: 'Kampanja: <campaign> | Stage: <stage> | Jezik: <lang>' },
    { type: 'spacer' },
    { type: 'h1', text: 'VARIANT A — <Hook Type>' },
    { type: 'bold', text: 'Headline: <headline>' },
    { type: 'body', text: '<primary text — each paragraph as separate body section>' },
    { type: 'bullets', items: ['CTA: <cta>', 'Hook Line: <hook line>'] },
    { type: 'spacer' }, { type: 'divider' }, { type: 'spacer' },
    { type: 'h1', text: 'VARIANT B — <Hook Type>' },
    // ... repeat for B and C
    { type: 'spacer' }, { type: 'divider' }, { type: 'spacer' },
    { type: 'h2', text: 'Notes' },
    { type: 'bullets', items: ['Hook types: A=..., B=..., C=...', 'Emotional driver: ...', 'Mechanism: ...', 'Avoided angles: ...'] },
  ],
});
console.log('Doc URL:', docUrl);
EOF
```

### Step 3.3 — Deliver via slack-reporter

Invoke the `slack-reporter` subagent via the **Task tool** with `subagent_type: "slack-reporter"`. Pass:

```
client: <client name>
channel: <resolved via getClientChannel(clientName) — channel ID>
type: copywrite
headline: "*Copywrite — <ClientName> — <Platform> — <YYYY-MM-DD>*"
sections:
  - title: "Variant A — <hook type from agent>"
    bullets:
      - <first 2-3 lines of variant A primary text, truncated>
  - title: "Variant B — <hook type from agent>"
    bullets:
      - <first 2-3 lines of variant B>
  - title: "Variant C — <hook type from agent>"
    bullets:
      - <first 2-3 lines of variant C>
  - title: "Info"
    bullets:
      - "Platform: <platform> | Stage: <stage> | Jezik: <lang>"
      - "Iterations: A=<n>, B=<n>, C=<n> | Naturalness: A=<x>/10, B=<x>/10, C=<x>/10"
      - "Emotional drivers: <comma-separated>"
links:
  - label: "Google Doc — puni copy"
    url: <docUrl from Step 3.2>
language: <hr | bs | de | en — match channel>
```

Do NOT call `postMessage()` from `lib/slack.mjs` directly anymore. The slack-reporter agent owns Slack delivery and enforces SLACK_REPORT_STANDARD.md.

### Step 3.4 — Ask for iteration

"Which variant do you prefer? Any changes to tone, hook angle, language, or length?"

---

## Verification (run AFTER Step 3.3 — confirm copy actually shipped)

Check ALL of these before declaring done:

- [ ] Copywriter agent returned 3 variants (or `variants` count from input — never fewer without explicit flag)
- [ ] Each variant has: primary text, headline (within char limit), description (within char limit if applicable), CTA
- [ ] Each variant's `final_score` ≥ 8/10 OR the agent explicitly listed `still_imperfect` failures
- [ ] All variants are in the requested language (verify with a simple regex/keyword sweep — Croatian should have š/đ/č/ž/ć somewhere, German should have Sie not du, etc.)
- [ ] Each variant uses a DIFFERENT hook type (no two variants on the same angle)
- [ ] Local file saved at `ACME Agency/clients/<Client>/copy_<platform>_<YYYY-MM-DD>.md` (or ACME Agency / ia-outreach equivalent)
- [ ] Google Doc created in `Copywriting` subfolder of client Drive AND `docUrl` is non-null
- [ ] Slack post via slack-reporter returned `ts` non-null with the doc URL embedded
- [ ] If `cold-email` platform: each variant has a P.S. line (T-EN4 from copywriter.tests.md)
- [ ] If `google` platform: every headline ≤ 30 chars, every description ≤ 90 chars (hard API limits)
- [ ] No variant contains em-dashes (—) for HR/BS — copywriter test loop should have caught these but verify

If any check fails, name the gap. The most common failure mode is the agent returning 2 variants when 3 were asked because variant 3 couldn't pass the test loop in 5 iterations — that's an acceptable scope reduction BUT must be flagged loudly, never silently delivered.

## Important Rules

- **All copy is generated by the `copywriter` agent in Phase 2** — the main session does NOT write copy itself; if you're tempted to hand-edit, you're doing it wrong. Re-invoke the agent with feedback instead.
- **PRINCIPLES.md and the platform module file are passed to the agent as `reference_files`** — the main session does not read them directly anymore.
- **The agent's self-test loop catches the anti-AI patterns** (em-dashes, fragments, banned phrases, naturalness) — those rules now live in `.claude/agents/copywriter.tests.md` and the skill no longer enforces them inline.
- **Always pass 3 variants** — never fewer
- **Slack delivery goes through `slack-reporter`** — never call `postMessage()` directly
- **For cold email**: the agent already knows plain text only, no HTML
- **For Google Ads**: the agent's tests enforce 30/90 char limits per headline/description
- **For landing pages**: the agent aligns the headline to the traffic source promise as part of its angle selection
- **Existing-angle scan still happens in the main session (Phase 0 Step 0.3)** — pass the scan results to the agent in the `brief` field so it knows what NOT to repeat

---

## Key Files

| File | Purpose |
|------|---------|
| `.claude/skills/copywrite/PRINCIPLES.md` | 12 master principles — read before every generation |
| `.claude/skills/copywrite/META.md` | Meta/Facebook ads module |
| `.claude/skills/copywrite/GOOGLE.md` | Google Ads RSA module |
| `.claude/skills/copywrite/LANDING.md` | Landing page module |
| `.claude/skills/copywrite/COLD_EMAIL.md` | Cold email sequence module |
| `.claude/skills/copywrite/EMAIL.md` | Email marketing/newsletter module |
| `ACME Agency/scripts/lib/google_docs.mjs` | `createFormattedDoc`, `findOrCreateFolder` |
| `ACME Agency/clients/clients.json` | Client lookup: Slack channel, Drive folder, account IDs |
| `ACME Agency/clients/<>/CLIENT.md` | Business context, audience, offer, competitors |
| `ACME Agency/clients/<>/brand-dna.md` | Voice profile, language, tone |
| `.claude/skills/SLACK_REPORT_STANDARD.md` | Slack report format rules |
