marketing-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -76
- package/catalogs-manifest.json +24 -0
- package/dist/cli.js +1186 -153
- package/package.json +6 -5
- package/skills/cmo/SKILL.md +73 -7
- package/skills/cmo/rules/brand-file-map.md +193 -0
- package/skills/cmo/rules/command-reference.md +143 -0
- package/skills/cmo/rules/context-switch.md +34 -0
- package/skills/cmo/rules/ecosystem.md +127 -0
- package/skills/cmo/rules/error-recovery.md +94 -0
- package/skills/cmo/rules/learning-loop.md +168 -0
- package/skills/cmo/rules/playbooks.md +215 -0
- package/skills/cmo/rules/progressive-enhancement.md +167 -0
- package/skills/cmo/rules/quality-gate.md +55 -0
- package/skills/cmo/rules/sub-agents.md +135 -0
- package/skills/deepen-plan/SKILL.md +1 -1
- package/skills/direct-response-copy/SKILL.md +1 -1
- package/skills/email-sequences/SKILL.md +1 -1
- package/skills/firecrawl/.skill-meta.json +2 -2
- package/skills/keyword-research/SKILL.md +1 -1
- package/skills/launch-strategy/SKILL.md +2 -2
- package/skills/marketing-psychology/SKILL.md +1 -1
- package/skills/mktg-x/.skill-meta.json +2 -2
- package/skills/positioning-angles/SKILL.md +1 -1
- package/skills/postiz/SKILL.md +248 -0
- package/skills/seo-content/SKILL.md +7 -5
- package/skills/social-campaign/SKILL.md +65 -0
- package/skills-manifest.json +27 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Ecosystem — External Tools, MCP, and Browser Variants
|
|
2
|
+
|
|
3
|
+
/cmo doesn't re-implement tools mktg has already chained. It routes to the skill that wraps the tool. This file documents every external tool in the mktg ecosystem, when /cmo invokes it, and which skill owns the wrapping.
|
|
4
|
+
|
|
5
|
+
**Detection:** always start with `mktg doctor --json` to see which tools are installed and which are missing. Don't route to a tool the user hasn't installed — surface the install hint first.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## External CLIs
|
|
10
|
+
|
|
11
|
+
| Tool | What it does | CMO uses when… | Wrapped by |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| `firecrawl` | Web scrape, search, crawl of known URLs | User provides a URL + "scrape this"; `competitive-intel` / `landscape-scan` need current data from competitor sites. | `competitive-intel`, `landscape-scan`, `/firecrawl` skill directly |
|
|
14
|
+
| `ffmpeg` | Video assembly, encoding (ffmpeg Quick + Enhanced tiers) | Any video output that doesn't need React/Remotion — slides → mp4, Ken Burns effects, audio mux. | `video-content` (tiers 1 + 2) |
|
|
15
|
+
| `remotion` | Programmatic React video compositions | Polished animated video with precise timing, typography, and brand-calibrated visual system. | `video-content` (tier 3) |
|
|
16
|
+
| `whisper-cli` (whisper.cpp) | Speech-to-text | Transcribe audio/video for atomization. Source for `content-atomizer` on podcasts, videos, voicemails. | `mktg transcribe` |
|
|
17
|
+
| `yt-dlp` | Media download | Pull YouTube/TikTok/podcast sources for transcription. | `mktg transcribe` |
|
|
18
|
+
| `gh` | GitHub CLI | Release notes, launch announcements, open-source project metadata for launch submissions. | `startup-launcher`, `app-store-changelog` |
|
|
19
|
+
| `summarize` (steipete/summarize) | Token-bounded text compression | Compress long pasted content before passing to downstream skills. | `/summarize` skill directly |
|
|
20
|
+
| `playwright-cli` | Browser automation backend | Whenever `/ply` or any `/ply-*` profile variant is the distribution path. | `/ply`, `/ply-moiz`, `/ply-halaali`, `/ply-moizcq`, `/ply-hscreen`, `/ply-akhi`, `/ply-skillcreator` |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Browser distribution profiles (`/ply` variants)
|
|
25
|
+
|
|
26
|
+
When a platform has no usable API, /cmo routes to the browser. Multiple Chrome profiles exist — each with its own logged-in session set. Pick the profile that matches the account the user wants to post from.
|
|
27
|
+
|
|
28
|
+
| Profile | Accounts / services | CMO uses when… |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `/ply` (default) | Shared VM profile | Generic automation, no specific account matters. |
|
|
31
|
+
| `/ply-moiz` | moizibnyousaf@gmail.com | Moiz's personal accounts (ChatGPT, Gmail, GitHub, App Store Connect as moiz). |
|
|
32
|
+
| `/ply-halaali` | halaaliapp@gmail.com | Halaali-specific Supabase, Expo/EAS, Mapbox, Resend, PostHog, Sentry, Vercel. |
|
|
33
|
+
| `/ply-moizcq` | moizcq@gmail.com | Markdown Engineering / MoizCQ services (newsletter, SEO, Typefully, App Store as MoizCQ). |
|
|
34
|
+
| `/ply-hscreen` | info@halalscreen.com | HalalScreen account workflows. |
|
|
35
|
+
| `/ply-akhi` | akhidotai@gmail.com | Akhi-specific automations. |
|
|
36
|
+
| `/ply-skillcreator` | skillcreatorai@gmail.com | SkillCreator services (Vercel, Typefully, Clerk, Stripe, Supabase). |
|
|
37
|
+
|
|
38
|
+
**Routing rule per project (cross-ref `rules/context-switch.md`):** project's `brand/stack.md` should name the canonical `/ply-*` profile if the project has browser-distribution needs. CMO reads stack.md to pick the right profile.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## MCP servers
|
|
43
|
+
|
|
44
|
+
### Exa MCP — semantic web research
|
|
45
|
+
|
|
46
|
+
**What it is:** Managed Context Protocol server for deep web search. Distinct from firecrawl:
|
|
47
|
+
- `firecrawl` — fetch a **known URL** (you have the link, want the content).
|
|
48
|
+
- `Exa` — **semantic search** across the web with citations (you have a question, want grounded answers with sources).
|
|
49
|
+
|
|
50
|
+
**CMO routes to Exa (via skill chains) when:**
|
|
51
|
+
- `landscape-scan` needs current market data — top players, recent moves, category trends. Exa returns cited sources.
|
|
52
|
+
- `competitive-intel` needs competitor discovery beyond a known list. Exa surfaces competitors the user hasn't named.
|
|
53
|
+
- `audience-research` needs audience watering holes + professional bios. Exa finds LinkedIn profiles, podcast guests, community signals.
|
|
54
|
+
- `keyword-research` needs live SERP gap analysis.
|
|
55
|
+
- Any "is this still true?" claim check — `/last30days` chains Exa under the hood.
|
|
56
|
+
|
|
57
|
+
**Wired via:** `.mcp.json` at the repo root. If `mktg doctor` shows Exa MCP unavailable, the skills that depend on it degrade to `firecrawl` + manual sourcing (lower quality, but not blocked).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## The API-vs-Browser Fork (critical routing decision)
|
|
62
|
+
|
|
63
|
+
For every distribution request, /cmo picks one of two paths. Get this wrong and you silently fail.
|
|
64
|
+
|
|
65
|
+
| Platform | Path | Skill |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| X / Twitter | API | `typefully` |
|
|
68
|
+
| LinkedIn | API | `postiz` (richer) or `typefully` (fallback) |
|
|
69
|
+
| Bluesky / Mastodon / Threads | API | `postiz` or `typefully` |
|
|
70
|
+
| Reddit | API | `postiz` |
|
|
71
|
+
| Instagram | API (via postiz) OR browser | `postiz` if configured, else `/ply-*` |
|
|
72
|
+
| TikTok | API (via postiz) OR browser | `postiz` if configured, else `/ply-*` |
|
|
73
|
+
| YouTube | API (via postiz) OR browser | `postiz` if configured, else `/ply-*` |
|
|
74
|
+
| Pinterest | API | `postiz` |
|
|
75
|
+
| Discord | API | `postiz` |
|
|
76
|
+
| Slack | API | `postiz` |
|
|
77
|
+
| Facebook | **Browser only** (no postiz, no Typefully) | `/ply-*` |
|
|
78
|
+
| Any transactional email | API | `send-email` (Resend) |
|
|
79
|
+
| Any marketing email sequence | API | `email-sequences` (to the project's configured ESP from `stack.md`) |
|
|
80
|
+
| Any App Store marketing | Hybrid — `asc` CLI for metadata, `/ply-moiz` for screenshots upload | `app-store-screenshots`, `app-store-changelog` |
|
|
81
|
+
|
|
82
|
+
**Decision flow:**
|
|
83
|
+
|
|
84
|
+
1. Does the platform have a working API in `mktg publish --list-adapters` (including catalogs)?
|
|
85
|
+
- YES → `mktg publish --adapter <name>` path (API).
|
|
86
|
+
- NO → `/ply-*` path (browser).
|
|
87
|
+
2. Is the user's `POSTIZ_API_KEY` set?
|
|
88
|
+
- NO → fall back to Typefully for X/LinkedIn/Threads/Bluesky/Mastodon; fall back to `/ply-*` for Reddit/IG/TikTok/etc.
|
|
89
|
+
3. Is this an X thread?
|
|
90
|
+
- YES → always Typefully (thread UX is canonical there).
|
|
91
|
+
4. Does `brand/stack.md` specify a browser profile?
|
|
92
|
+
- YES → use that profile for browser path.
|
|
93
|
+
- NO → default to `/ply`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Skills that ARE the wrappers (don't re-implement)
|
|
98
|
+
|
|
99
|
+
Anytime a user asks for something that an ecosystem tool does, don't call the tool directly — route to the skill that wraps it. The wrapping skill handles error cases, auth, retries, and brand calibration.
|
|
100
|
+
|
|
101
|
+
| User says… | Route to | Don't… |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| "scrape this site" | `/firecrawl` | …call `firecrawl` CLI directly from `/cmo`. |
|
|
104
|
+
| "transcribe this video" | `mktg transcribe` | …pipe `yt-dlp \| whisper-cli` manually. |
|
|
105
|
+
| "make a video from slides" | `video-content` | …shell out to ffmpeg inline. |
|
|
106
|
+
| "summarize this" | `/summarize` | …ask the LLM to compress; use the `summarize` CLI for token-bounded output. |
|
|
107
|
+
| "post to Instagram" | `postiz` (if configured) else `/ply-*` | …tell the user to do it manually. |
|
|
108
|
+
| "research this market" | `landscape-scan` | …call Exa MCP directly; landscape-scan does the full chain with Claims Blacklist. |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Install hints
|
|
113
|
+
|
|
114
|
+
`mktg doctor` surfaces install commands per missing tool. If any of these fail at invocation time, `/cmo` tells the user exactly what to install before retrying:
|
|
115
|
+
|
|
116
|
+
| Tool | Install |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `firecrawl` | `npm i -g firecrawl` + `FIRECRAWL_API_KEY` |
|
|
119
|
+
| `ffmpeg` | `brew install ffmpeg` |
|
|
120
|
+
| `remotion` | `npm i -g @remotion/cli` |
|
|
121
|
+
| `playwright-cli` | `npm i -g @playwright/cli` |
|
|
122
|
+
| `gh` | `brew install gh` |
|
|
123
|
+
| `whisper-cli` | `brew install whisper-cpp` |
|
|
124
|
+
| `yt-dlp` | `brew install yt-dlp` |
|
|
125
|
+
| `summarize` | `npm i -g @steipete/summarize` |
|
|
126
|
+
|
|
127
|
+
Ecosystem table authoritative source: `CLAUDE.md` at repo root. This rules file mirrors the CMO-relevant slice; when they drift, CLAUDE.md wins.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Error Recovery & Degraded-Mode Playbook
|
|
2
|
+
|
|
3
|
+
/cmo fails gracefully. Every error has a named recovery path. Never silently retry, never shrug and route elsewhere, never ship partial state. When something breaks, tell the user exactly what happened, show the fix, and offer the next move.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Recovery matrix
|
|
8
|
+
|
|
9
|
+
| Failure | Detection | /cmo response |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| **Brand file missing** | `mktg status --json` returns `brand.missing: ["voice-profile.md"]` | Warn. Offer to run the foundation skill that writes that file. Don't auto-run — ask: *"voice-profile.md is missing. I can run /brand-voice now — 5 minutes. OK?"* |
|
|
12
|
+
| **Brand file template (unpopulated)** | `mktg context --json` shows `status: "template"` on a file | Same as missing. Template ≠ populated. Offer to populate via the appropriate skill. |
|
|
13
|
+
| **Brand file stale** | `mktg brand freshness --json` shows `status: "stale"` (>30 days for profiles, >90 for config, >14 for landscape) | Warn before running downstream skills. *"voice-profile.md is 42 days old. I can refresh it (5 min) before writing copy, or proceed with the current version — which?"* |
|
|
14
|
+
| **Integration unconfigured** (e.g., `POSTIZ_API_KEY` unset) | `mktg catalog info postiz --json --fields configured,missing_envs` returns `configured: false` | Surface the `missing_envs[0]` value in a `fix` field: *"Postiz isn't configured. Set `POSTIZ_API_KEY` — see `mktg catalog info postiz`. Until then, I can fall back to Typefully for X/LinkedIn/Threads/Bluesky/Mastodon; Reddit/IG/TikTok stay write-only."* Don't block — degrade with honesty. |
|
|
15
|
+
| **Skill prerequisite missing** | `mktg skill check <name> --json` returns `satisfied: false` with `missing.skills` or `missing.brandFiles` | Name the missing prereq + propose the fix: *"Can't run `/seo-content` yet — it needs brand/keyword-plan.md. I'll run /keyword-research first (3 min), then come back."* |
|
|
16
|
+
| **Rate limit hit** (e.g., postiz 30/hour, Typefully quota) | Adapter returns HTTP 429 with `Retry-After` header; adapter surfaces `RATE_LIMIT` detail | Checkpoint the batch. Communicate: *"Postiz rate limit hit — 12 of 20 posts shipped. Remaining 8 paused. Resume after ~1200s, or save for tomorrow?"* Persist state in `.mktg/publish/<campaign>-postiz.json` (the sent-marker file) so resume is lossless. |
|
|
17
|
+
| **Sent-marker exists (idempotency)** | Adapter returns `status: "skipped", detail: "dedupe: sent-marker match"` | Inform the user the post is already scheduled. Show the prior draft ID. *"This post already shipped on 2026-04-12 (draft abc123). Want to force re-send? You'll need to clear `.mktg/publish/<campaign>-postiz.json` or change the campaign name."* |
|
|
18
|
+
| **Claims Blacklist violation** | `mktg brand claims --json` returns a blacklisted claim that appears in proposed output | Refuse. Surface the blacklist entry + offer an alternative: *"'fastest' is on your Claims Blacklist (landscape.md flagged 3 competitors with quantified speed benchmarks). Want to drop the claim or rephrase as '~40% faster than X under [specific conditions]'?"* |
|
|
19
|
+
| **Content-reviewer gate FAIL** | `mktg-content-reviewer` agent returns low score + drift report | Loop back to the content skill with the specific rewrite recommendations. Don't ship drifted content. |
|
|
20
|
+
| **SEO-analyst gate FAIL** | `mktg-seo-analyst` agent returns low keyword coverage | Loop back. Don't ship an SEO article that misses its target keywords. |
|
|
21
|
+
| **Skill runs but errors mid-way** | `mktg run <skill>` returns non-zero exit + structured error | Surface exit code + error message + suggestions from the result envelope. Don't silently retry — ask: *"`/seo-content` failed: [error]. Suggestions: [list]. Want me to retry, fix the upstream input, or bail?"* |
|
|
22
|
+
| **Network / unreachable upstream** | Fetch timeout, DNS failure, connection refused | Distinguish transient vs permanent. On first failure, retry once with backoff. On second failure, stop and report. |
|
|
23
|
+
| **Tool missing** (e.g., no `ffmpeg` installed) | `mktg doctor --json` check fails | Surface the install command from CLAUDE.md Ecosystem table. Offer to run the install ONLY if the user approves (never auto-install system tools). |
|
|
24
|
+
| **Multiple skills competing** (ambiguous routing) | `/cmo` can't disambiguate with the decision tree | Ask ONE clarifying question, not five. *"This could go to /seo-content (ranks) or /direct-response-copy (converts). Which goal?"* |
|
|
25
|
+
| **Circular dependency in plan** | `mktg skill graph --json` shows a cycle | Flag as a manifest bug; don't attempt to run. Fall back to the most independent skill in the cluster. |
|
|
26
|
+
| **Corrupt state file** (sent-marker, cache, .mktg/plan.json) | JSON parse error on read | Back up the corrupt file to `*.bak`, start fresh, warn the user. Adapter precedent: `SENT_MARKER_CORRUPT` detail. |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Degraded-mode invariants
|
|
31
|
+
|
|
32
|
+
**Never silently retry.** Retries hide real failures and waste quota. One retry with backoff on transient errors; surface everything else.
|
|
33
|
+
|
|
34
|
+
**Never ship partial state without telling the user.** If a campaign of 20 posts had 12 succeed and 8 fail, say so. Don't claim success.
|
|
35
|
+
|
|
36
|
+
**Never route around a failure without acknowledging it.** If `postiz` is down and you fall back to Typefully, tell the user: *"Postiz unreachable — routing to Typefully for the platforms it covers. Reddit/IG/TikTok are file-only until postiz is back."*
|
|
37
|
+
|
|
38
|
+
**Never auto-populate a brand file.** If `voice-profile.md` is missing, `/cmo` offers to run `/brand-voice` — it doesn't run unasked. The user controls what lands in `brand/`.
|
|
39
|
+
|
|
40
|
+
**Never violate Claims Blacklist, even under pressure.** If the user insists on a blacklisted claim, refuse and explain why. The Blacklist exists because the user already flagged those claims as unfounded; bypassing them means shipping lies.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## When to stop vs when to continue
|
|
45
|
+
|
|
46
|
+
Stop and ask:
|
|
47
|
+
- Destructive operations (any `--confirm` path).
|
|
48
|
+
- Claims Blacklist violations.
|
|
49
|
+
- Partial campaign failures.
|
|
50
|
+
- Multiple valid routing options.
|
|
51
|
+
- Cross-project context unclear.
|
|
52
|
+
|
|
53
|
+
Continue and inform:
|
|
54
|
+
- Transient network errors (retry once, then stop).
|
|
55
|
+
- Degraded fallbacks (postiz→typefully, API→browser).
|
|
56
|
+
- Stale data warnings (user can accept the staleness).
|
|
57
|
+
- Missing but non-blocking brand files (offer to populate, let user defer).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Error shape the user sees
|
|
62
|
+
|
|
63
|
+
When /cmo surfaces an error, include:
|
|
64
|
+
|
|
65
|
+
1. **What happened** — one sentence, specific.
|
|
66
|
+
2. **Why** — the technical cause if useful.
|
|
67
|
+
3. **Fix** — literal command or action the user takes.
|
|
68
|
+
4. **Next** — what /cmo will do if the user resolves it.
|
|
69
|
+
|
|
70
|
+
Example (good):
|
|
71
|
+
> *"Postiz refused the LinkedIn draft — `UNCONNECTED_PROVIDER: linkedin`. Your instance has only `linkedin-page` connected. Either connect a personal LinkedIn in postiz UI, or I can switch the post to `linkedin-page`. Which?"*
|
|
72
|
+
|
|
73
|
+
Example (bad):
|
|
74
|
+
> *"Error publishing. Please try again."*
|
|
75
|
+
|
|
76
|
+
The good version names the provider, the exact missing identifier, the fix, and the alternative path. The bad version forces the user to guess.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Logging failures to `brand/learnings.md`
|
|
81
|
+
|
|
82
|
+
Every non-transient failure worth remembering goes into the learnings file:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
mktg brand append-learning --input '{
|
|
86
|
+
"date": "2026-04-15",
|
|
87
|
+
"action": "Tried to post to Pinterest via postiz",
|
|
88
|
+
"result": "Failed — UNCONNECTED_PROVIDER",
|
|
89
|
+
"learning": "This instance has no Pinterest integration connected",
|
|
90
|
+
"nextStep": "Connect Pinterest in postiz UI or route file-only"
|
|
91
|
+
}'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Future sessions read this; /cmo avoids re-running the same failed path. See `rules/learning-loop.md` for the full compounding protocol.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Learning Loop — Compounding Across Sessions
|
|
2
|
+
|
|
3
|
+
/cmo has persistent memory via `brand/learnings.md` and `.mktg/plan.json`. Every session adds evidence; every next session starts smarter. This is the compounding engine — get it right and the tenth session is 10× better than the first.
|
|
4
|
+
|
|
5
|
+
**Core invariant:** every meaningful outcome (campaign landed, skill failed, copy flopped, strategy worked) gets logged. The log shapes future routing.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## On every RETURNING activation
|
|
10
|
+
|
|
11
|
+
Before asking the builder what they want:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
mktg plan next --json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This returns the single highest-priority task from the persisted `.mktg/plan.json`. Surface it to the user:
|
|
18
|
+
|
|
19
|
+
> *"Based on where we left off: next priority is [task]. Reason: [reason]. Want to run it?"*
|
|
20
|
+
|
|
21
|
+
If the user wants something different, they'll say so — but proposing the planned next move makes session ramp-up instant.
|
|
22
|
+
|
|
23
|
+
Also run on returning activation:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
mktg status --json --fields brand.populated,brand.stale,integrations
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
— to detect anything that drifted since last time (stale brand files, newly-unconfigured integrations).
|
|
30
|
+
|
|
31
|
+
And read the tail of learnings (don't load the full file — it grows):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Last 10 entries via Read tool at brand/learnings.md (tail-equivalent)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The last 10 learnings inform what NOT to try again.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## After any meaningful action
|
|
42
|
+
|
|
43
|
+
Every successful campaign, every failed experiment, every strategic decision worth remembering writes to `brand/learnings.md`:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mktg brand append-learning --input '{
|
|
47
|
+
"action": "Launched v2 to Hacker News via startup-launcher",
|
|
48
|
+
"result": "Front page for 4 hours; 312 signups; 18 paid conversions",
|
|
49
|
+
"learning": "Show HN timing — Tue 8am PT drove the Hacker News mods to promote. Title format with specific stat converted better than general framing.",
|
|
50
|
+
"nextStep": "Re-run the format for the v3 launch; consider writing a followup retrospective blog post while momentum lasts"
|
|
51
|
+
}'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Required fields: `action`, `result`, `learning`, `nextStep`. Optional: `date` (auto-filled today if absent).
|
|
55
|
+
|
|
56
|
+
**What qualifies as worth logging:**
|
|
57
|
+
- Campaign results (wins AND losses)
|
|
58
|
+
- Surprising user behaviors (conversion patterns, cancellation triggers)
|
|
59
|
+
- Voice / positioning discoveries that contradict the brand profile
|
|
60
|
+
- Tool or skill failures that will recur ("postiz rate limit hit on Thursday launch; plan campaigns for M/T/F next time")
|
|
61
|
+
- Cross-skill insights ("atomized posts that led with a question outperformed hot-takes 3×")
|
|
62
|
+
|
|
63
|
+
**What does NOT belong in learnings:**
|
|
64
|
+
- Ephemeral debugging notes (use a scratch file)
|
|
65
|
+
- Credentials or PII (learnings is git-committed)
|
|
66
|
+
- Raw tool output (summarize the insight, not the logs)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Plan persistence
|
|
71
|
+
|
|
72
|
+
`.mktg/plan.json` is CMO's task queue across sessions.
|
|
73
|
+
|
|
74
|
+
**Generate or refresh:**
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
mktg plan --save --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This reads current project state (brand completeness, run history, dependency graph, landscape freshness, learnings) and writes the prioritized queue.
|
|
81
|
+
|
|
82
|
+
**Mark a task done** (critical — otherwise it stays in the queue forever):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
mktg plan complete <task-id> --json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Do this immediately after a skill runs successfully. Not at end of session — immediately.
|
|
89
|
+
|
|
90
|
+
**What's in the queue:**
|
|
91
|
+
- `setup` tasks — brand file scaffolding (only at L0-L1).
|
|
92
|
+
- `populate` tasks — replace template content with real data.
|
|
93
|
+
- `refresh` tasks — update stale brand files.
|
|
94
|
+
- `execute` tasks — run must-have execution skills that haven't run yet.
|
|
95
|
+
- `distribute` tasks — ship pending campaigns.
|
|
96
|
+
|
|
97
|
+
Tasks have ordering (detection order, not priority-scored) and `blockedBy` relations — `/cmo` surfaces the highest-order unblocked task via `plan next`.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Periodic self-audit — `/document-review`
|
|
102
|
+
|
|
103
|
+
`/cmo` proactively triggers `/document-review` on a cadence:
|
|
104
|
+
|
|
105
|
+
- **After a major campaign** (anything that touched 3+ brand files or produced multi-platform output).
|
|
106
|
+
- **Monthly**, if the user is a returning builder with a long session history.
|
|
107
|
+
- **Before any SEO Authority Build or Full Product Launch playbook** — confirm brand foundation is solid before compounding work on top of it.
|
|
108
|
+
|
|
109
|
+
The skill audits `brand/*.md` for:
|
|
110
|
+
- Completeness (all required sections per `brand/SCHEMA.md`).
|
|
111
|
+
- Internal consistency (voice matches positioning matches audience).
|
|
112
|
+
- Freshness (profiles <30d, config <90d, landscape <14d).
|
|
113
|
+
|
|
114
|
+
Output: structured report. `/cmo` acts on the recommendations — usually queues 1-3 refresh tasks into `.mktg/plan.json`.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## How learnings shape routing
|
|
119
|
+
|
|
120
|
+
When `/cmo` considers a skill/playbook, it weights past evidence:
|
|
121
|
+
|
|
122
|
+
| Past evidence | Routing impact |
|
|
123
|
+
|---|---|
|
|
124
|
+
| Skill produced good output last time | Increased confidence; run without asking clarifying questions. |
|
|
125
|
+
| Skill failed last time for a reason that's not fixed | Surface the prior failure + fix BEFORE re-running. |
|
|
126
|
+
| Claim verified recently via `/last30days` | Safe to repeat. |
|
|
127
|
+
| Claim flagged in Blacklist | Refuse (see `rules/error-recovery.md`). |
|
|
128
|
+
| Playbook succeeded recently | Offer to repeat for next launch / next article / next campaign. |
|
|
129
|
+
| User rejected a specific framing last time | Don't re-propose it. |
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
> *"Last time you shipped an SEO article, content-reviewer scored 82/100 with 'opening para too generic' as the main drift. Want me to calibrate the opening pattern specifically this run?"*
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Forgetting — explicit
|
|
137
|
+
|
|
138
|
+
If the user says *"forget about X"*, `/cmo` removes the relevant learning line and does not bring it up again. Learnings is a shared contract; the builder controls it.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Cross-project learnings (use with caution)
|
|
143
|
+
|
|
144
|
+
Learnings are per-project (each project has its own `brand/learnings.md`). /cmo may notice patterns across projects (*"X positioning worked for CEO App; could work for Halaali"*) but never acts on cross-project insights without explicit user confirmation. See `rules/context-switch.md` for the full multi-project protocol.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## The 30-day return
|
|
149
|
+
|
|
150
|
+
A builder comes back to a project after 30 days. `/cmo` on that activation:
|
|
151
|
+
|
|
152
|
+
1. `mktg status --json` — snap state.
|
|
153
|
+
2. `mktg brand freshness --json` — flag everything that's stale.
|
|
154
|
+
3. `mktg plan next --json` — propose the next move.
|
|
155
|
+
4. Read tail of `brand/learnings.md` — 10 most recent entries.
|
|
156
|
+
5. Surface: *"Welcome back. Landscape is 42 days stale — want to refresh before writing anything new? Plan has [N] pending tasks, top one is [task]. Last learning: [recent entry]. Where do you want to start?"*
|
|
157
|
+
|
|
158
|
+
This is the 30-second ramp-up. The log did the memory work; /cmo just presents it.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Reference
|
|
163
|
+
|
|
164
|
+
- `brand/learnings.md` — the log.
|
|
165
|
+
- `.mktg/plan.json` — the persisted queue.
|
|
166
|
+
- `mktg brand append-learning --input '{...}'` — the writer.
|
|
167
|
+
- `mktg plan next / --save / complete <id> --json` — the queue commands.
|
|
168
|
+
- `rules/brand-memory.md` — the full brand memory protocol (what belongs in brand/ vs what belongs in learnings vs what's ephemeral).
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# CMO Orchestration Playbooks
|
|
2
|
+
|
|
3
|
+
Named end-to-end recipes. When the builder asks for something big, pick the right playbook, announce the plan, run the chain, hand back at the defined stop.
|
|
4
|
+
|
|
5
|
+
**How to use:**
|
|
6
|
+
- If the builder's request matches a named trigger phrase, start the playbook.
|
|
7
|
+
- Announce the plan before step 1: *"Here's what I'll run: step 1 → step 2 → step 3. Ready?"*
|
|
8
|
+
- Pause between phases when a **Gate** is marked — the user approves the artifact before the next step.
|
|
9
|
+
- Every playbook ends with a **Stop** condition. Don't run past it.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Full Product Launch
|
|
14
|
+
|
|
15
|
+
**Trigger:** *"launch my product"*, *"zero to launch"*, *"plan and run my launch"*, *"new startup, what do I do"*.
|
|
16
|
+
|
|
17
|
+
**Use when:** fresh project, founder wants end-to-end. Allow 2-4 hours of compounding work.
|
|
18
|
+
|
|
19
|
+
**Steps:**
|
|
20
|
+
|
|
21
|
+
| # | Skill | Artifact produced | Gate? |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| 0 | `brainstorm` (skip if direction is clear) | direction summary | — |
|
|
24
|
+
| 1 | `brand-voice` | `brand/voice-profile.md` | ✓ |
|
|
25
|
+
| 2 | `audience-research` + `competitive-intel` (parallel via agents) | `brand/audience.md`, `brand/competitors.md` | ✓ |
|
|
26
|
+
| 3 | `landscape-scan` | `brand/landscape.md` (with Claims Blacklist) | ✓ |
|
|
27
|
+
| 4 | `positioning-angles` | `brand/positioning.md` | ✓ |
|
|
28
|
+
| 5 | `visual-style` → `brand-kit-playground` | `brand/creative-kit.md` + HTML preview | ✓ (visual approval) |
|
|
29
|
+
| 6 | `keyword-research` | `brand/keyword-plan.md` | — |
|
|
30
|
+
| 7 | `seo-content` ×2-3 articles (cornerstone content) | `marketing/content/*.md` | ✓ (per article) |
|
|
31
|
+
| 8 | `content-atomizer` on each article | `marketing/social/<slug>/*.md` | — |
|
|
32
|
+
| 9 | `launch-strategy` | `marketing/launch/plan.md` | ✓ |
|
|
33
|
+
| 10 | `startup-launcher` (brief + 56-platform tracker) | `marketing/launch/product-brief.md`, `launch-tracker.md` | ✓ |
|
|
34
|
+
| 11 | Schedule social: `typefully` for X/threads, `postiz` for everything else | drafts in platform UIs | — |
|
|
35
|
+
| 12 | Log the campaign: `mktg brand append-learning` | `brand/learnings.md` | — |
|
|
36
|
+
|
|
37
|
+
**Stop:** launch day executed, drafts scheduled, learnings captured. Hand back with "next moves" list (monitor competitors, run conversion audits, plan next content batch).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 2. Content Engine
|
|
42
|
+
|
|
43
|
+
**Trigger:** *"I need a content system"*, *"publish weekly"*, *"keep the content flowing"*, *"content calendar setup"*.
|
|
44
|
+
|
|
45
|
+
**Use when:** brand foundation exists; user wants repeatable weekly output.
|
|
46
|
+
|
|
47
|
+
**Steps:**
|
|
48
|
+
|
|
49
|
+
| # | Skill | Artifact | Notes |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| 1 | `keyword-research` | `brand/keyword-plan.md` (fresh) | Refresh if older than 90 days. |
|
|
52
|
+
| 2 | `seo-content` (one cornerstone piece) | `marketing/content/<slug>.md` | User picks the topic from keyword-plan. |
|
|
53
|
+
| 3 | `content-atomizer` | `marketing/social/<slug>/{linkedin,twitter,reddit,...}-posts.md` | Platform-native, per-channel. |
|
|
54
|
+
| 4 | Distribution: `postiz` (LinkedIn/Reddit/Bluesky/Mastodon/Threads/IG/TikTok) + `typefully` (X) | drafts scheduled | Phase 5 of `social-campaign` picks the backend per post. |
|
|
55
|
+
|
|
56
|
+
**Stop:** one week's worth of content scheduled. Recommend scheduling a recurring run (`/loop` or weekly reminder).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 3. Founder Voice Rebrand
|
|
61
|
+
|
|
62
|
+
**Trigger:** *"make this sound like me"*, *"extract my voice"*, *"my voice is all over the place"*, *"the brand voice doesn't match how I actually write"*.
|
|
63
|
+
|
|
64
|
+
**Use when:** founder has a real writing voice (podcast, essays, tweets) that the current `voice-profile.md` doesn't capture.
|
|
65
|
+
|
|
66
|
+
**Steps:**
|
|
67
|
+
|
|
68
|
+
| # | Skill | Artifact | Notes |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| 1 | `voice-extraction` | structured voice pattern analysis | Spawns 10 parallel sub-agents, reverse-engineers patterns from real content. |
|
|
71
|
+
| 2 | `brand-voice` (Extract mode) using extraction output | new `brand/voice-profile.md` | Overwrites the generic voice with the founder-calibrated one. |
|
|
72
|
+
| 3 | **Mass regen trigger** — if there's existing copy in `marketing/`, flag for rewrite: run `direct-response-copy --mode edit` on each landing page, `seo-content --mode edit` on each article, `content-atomizer` re-runs on source content | updated files | Per plan:rules/brand-file-map.md, voice changes cascade to every downstream copy skill. |
|
|
73
|
+
|
|
74
|
+
**Stop:** new `voice-profile.md` written + downstream rewrite plan surfaced. Don't auto-regenerate; the user decides which assets are worth rewriting.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 4. Conversion Audit
|
|
79
|
+
|
|
80
|
+
**Trigger:** *"audit my landing page"*, *"traffic isn't converting"*, *"why is my signup flow leaking"*, *"fix my CRO"*.
|
|
81
|
+
|
|
82
|
+
**Steps:**
|
|
83
|
+
|
|
84
|
+
| # | Skill | When |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| 1 | `page-cro` | Audits hero, CTA, social proof, objections on one URL. Produces a scored report + prioritized fix list. |
|
|
87
|
+
| 2 | `conversion-flow-cro` | Only if problem spans a multi-step flow (signup → onboarding → paywall). |
|
|
88
|
+
| 3 | If copy is the issue → `direct-response-copy --mode edit` | Surgical rewrite of the flagged copy. |
|
|
89
|
+
| 4 | Capture what you learned → `mktg brand append-learning` | Feeds future routing. |
|
|
90
|
+
|
|
91
|
+
**Stop:** ranked fix list delivered; rewrite executed if copy was the blocker.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 5. Retention Recovery
|
|
96
|
+
|
|
97
|
+
**Trigger:** *"people keep canceling"*, *"my churn is bad"*, *"reduce cancellations"*, *"win back lapsed users"*.
|
|
98
|
+
|
|
99
|
+
**Steps:**
|
|
100
|
+
|
|
101
|
+
| # | Skill | Artifact |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| 1 | `churn-prevention` | Cancel flow UX plan, dunning email sequence, win-back 90-day calendar. |
|
|
104
|
+
| 2 | `email-sequences` (build the dunning + win-back flows from step 1's plan) | Full email sequences with subjects + timing. |
|
|
105
|
+
| 3 | `send-email` (to wire the flow into Resend, if building inbound) | Transactional wiring. |
|
|
106
|
+
|
|
107
|
+
**Stop:** dunning + win-back flows drafted, wire-up instructions given. User approves before any live sends.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 6. Visual Identity
|
|
112
|
+
|
|
113
|
+
**Trigger:** *"design my brand"*, *"I need a visual look"*, *"how should my brand look"*, *"set up image generation"*.
|
|
114
|
+
|
|
115
|
+
**Steps:**
|
|
116
|
+
|
|
117
|
+
| # | Skill | Artifact |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| 1 | `visual-style` | `brand/creative-kit.md` with palette, typography, image aesthetic. |
|
|
120
|
+
| 2 | `brand-kit-playground` (immediately after) | Interactive HTML preview — tweakable palette/type/logo, social card + OG image. |
|
|
121
|
+
| 3 | `creative` (when producing ad/social assets) | Multi-mode creative briefs per asset. |
|
|
122
|
+
| 4 | `image-gen` (for individual images) | Gemini-generated image via creative-kit style anchors. |
|
|
123
|
+
|
|
124
|
+
**Stop:** visual approval via `brand-kit-playground`. User copies refined tokens back, then unblocked for any future image work.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 7. Video Content
|
|
129
|
+
|
|
130
|
+
**Trigger:** *"make a video"*, *"TikTok content"*, *"product demo video"*, *"turn slides into video"*.
|
|
131
|
+
|
|
132
|
+
**Steps (branching):**
|
|
133
|
+
|
|
134
|
+
| Ask shape | Skill chain |
|
|
135
|
+
|---|---|
|
|
136
|
+
| "Product demo / walkthrough" | `marketing-demo` → `video-content` (ffmpeg or Remotion) |
|
|
137
|
+
| "TikTok slideshow / social video" | `slideshow-script` → `paper-marketing` → `video-content` → (optional) `tiktok-slideshow` orchestrator bundles all three |
|
|
138
|
+
| "Pitch deck / HTML slides" | `frontend-slides` (terminal path — not a video pipeline) |
|
|
139
|
+
| "App Store screenshots" | `app-store-screenshots` (Next.js generator, NOT video) |
|
|
140
|
+
|
|
141
|
+
**Distribution:** any resulting video → `postiz` for TikTok/IG/YouTube/Threads; `typefully` for X.
|
|
142
|
+
|
|
143
|
+
**Stop:** video file exported + scheduled. Log to `brand/assets.md`.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 8. Email Infrastructure
|
|
148
|
+
|
|
149
|
+
**Trigger:** *"set up my email system"*, *"I need inbound email for an agent"*, *"wire up Resend"*.
|
|
150
|
+
|
|
151
|
+
**Steps:**
|
|
152
|
+
|
|
153
|
+
| # | Skill | Artifact |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| 1 | `agent-email-inbox` (if building agent-triggered email) | secure inbox config, webhook tunneling plan, prompt-injection defenses. |
|
|
156
|
+
| 2 | `resend-inbound` (for receiving emails via Resend) | inbound domain setup + `email.received` webhook wiring. |
|
|
157
|
+
| 3 | `email-sequences` (for automated flows: welcome, nurture, launch, win-back) | full sequences with timing and A/B plan. |
|
|
158
|
+
| 4 | `send-email` (for one-off transactional sends) | Resend API calls for specific messages. |
|
|
159
|
+
|
|
160
|
+
**Stop:** infrastructure validated (test send + receive round-trip). Log credentials env vars (via `brand/stack.md`).
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 9. SEO Authority Build
|
|
165
|
+
|
|
166
|
+
**Trigger:** *"rank higher on Google"*, *"improve SEO"*, *"I want to show up in AI search"*, *"compete for [topic]"*.
|
|
167
|
+
|
|
168
|
+
**Steps:**
|
|
169
|
+
|
|
170
|
+
| # | Skill | Artifact |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| 1 | `keyword-research` | `brand/keyword-plan.md` with primary, secondary, long-tail terms + search intent notes. |
|
|
173
|
+
| 2 | `seo-content` (ongoing) | `marketing/content/*.md` — rankable, anti-AI-slop articles with schema. |
|
|
174
|
+
| 3 | `ai-seo` | Entity optimization, structured data, citation-worthy formatting for ChatGPT/Perplexity/Claude/Gemini/AI Overviews. |
|
|
175
|
+
| 4 | `competitor-alternatives` | `marketing/alternatives/<competitor>-vs-us.md` — high-intent comparison pages. |
|
|
176
|
+
| 5 | `seo-audit` (periodically) | Site architecture + schema markup audit. |
|
|
177
|
+
|
|
178
|
+
**Stop:** one cornerstone + one AI-SEO piece + one alternatives page shipped. Schedule re-runs quarterly.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 10. Newsletter Launch
|
|
183
|
+
|
|
184
|
+
**Trigger:** *"start a newsletter"*, *"set up weekly email"*, *"I want subscribers"*.
|
|
185
|
+
|
|
186
|
+
**Steps:**
|
|
187
|
+
|
|
188
|
+
| # | Skill | Artifact |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| 1 | `audience-research` (refresh if stale) | `brand/audience.md` — who reads this newsletter. |
|
|
191
|
+
| 2 | `newsletter` | Newsletter strategy, template, cadence, growth playbook. |
|
|
192
|
+
| 3 | `lead-magnet` | Free resource that captures emails (ebook, template, toolkit). |
|
|
193
|
+
| 4 | `email-sequences` (welcome + nurture) | Automated onboarding for new subscribers. |
|
|
194
|
+
| 5 | Distribution: landing page via `direct-response-copy`; sign-up capture via `send-email` + `resend-inbound` for double opt-in. | Full signup funnel. |
|
|
195
|
+
|
|
196
|
+
**Stop:** newsletter #1 drafted, lead magnet live, welcome sequence scheduled. Hand back with growth tactics to run weekly.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Playbook selection — quick reference
|
|
201
|
+
|
|
202
|
+
| Builder says… | Playbook |
|
|
203
|
+
|---|---|
|
|
204
|
+
| "launch", "zero to one", "ship my startup" | **Full Product Launch** |
|
|
205
|
+
| "content system", "publish weekly", "keep content flowing" | **Content Engine** |
|
|
206
|
+
| "my voice is off", "make it sound like me" | **Founder Voice Rebrand** |
|
|
207
|
+
| "audit my page", "improve conversion", "fix my funnel" | **Conversion Audit** |
|
|
208
|
+
| "reduce churn", "win back users" | **Retention Recovery** |
|
|
209
|
+
| "brand visuals", "design my look" | **Visual Identity** |
|
|
210
|
+
| "make a video", "TikTok" | **Video Content** |
|
|
211
|
+
| "email system", "inbound email", "Resend setup" | **Email Infrastructure** |
|
|
212
|
+
| "rank on Google", "AI search", "compete for [topic]" | **SEO Authority Build** |
|
|
213
|
+
| "start a newsletter", "subscribers" | **Newsletter Launch** |
|
|
214
|
+
|
|
215
|
+
**Never run a playbook silently.** Announce the plan, confirm, run, surface the artifact at each Gate, stop at the Stop condition.
|