MoizIbnYousaf/marketing-cli/studio/skills/cmo-studio-integration/SKILL.md
cmo-studio-integration
When mktg-studio is running on this machine, /cmo proactively narrates work into the dashboard via Bash + curl against the localhost HTTP API. Detect via /api/health, then log every meaningful action — the user sees what /cmo is doing in real time.
- Source repository stars
- 27
- Declared platforms
- 0
- Static risk flags
- 4
- Last source update
- 2026-07-28
- Source checked
- 2026-07-28
Decision brief
What it does—and where it fits
mktg-studio is the local dashboard that visualises everything you do. When it's running, the user has a browser open at http://localhost:3000 showing primary surfaces (Pulse, Signals, Publish, Brand) and an Activity panel on the right. Trend radar lives inside Signals. Audience…
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/MoizIbnYousaf/marketing-cli --skill "studio/skills/cmo-studio-integration"Inspect the Agent Skill "cmo-studio-integration" from https://github.com/MoizIbnYousaf/marketing-cli/blob/f12fbcbe4929584697b309b9096c9427b0cfce8e/studio/skills/cmo-studio-integration/SKILL.md at commit f12fbcbe4929584697b309b9096c9427b0cfce8e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
1. Detect first
On every turn, before doing anything else marketing-y, run:
STUDIOUP=1 → studio is up, follow the rules belowSTUDIOUP=0 → studio is down, behave exactly as you would in aOn every turn, before doing anything else marketing-y, run: - 02
2. The five verbs
Every meaningful action you take should map to one or more of these endpoints. Skip them when they don't apply — don't be noisy.
Every meaningful action you take should map to one or more of these endpoints. Skip them when they don't apply — don't be noisy. - 03
Copy-paste recipes
Review the “Copy-paste recipes” section in the pinned source before continuing.
Review and apply the “Copy-paste recipes” source section. - 04
Log a skill run
curl -fsS -X POST "$STUDIO/api/activity/log" \ -H 'content-type: application/json' \ -d '{"kind":"skill-run","skill":"landscape-scan","summary":"Refreshed landscape, 5 new claims","filesChanged":["brand/landscape.md"]}'
curl -fsS -X POST "$STUDIO/api/activity/log" \ -H 'content-type: application/json' \ -d '{"kind":"skill-run","skill":"landscape-scan","summary":"Refreshed landscape, 5 new claims","filesChanged":["brand/landscape.md"]}' - 05
Note a brand-file write (excerpt is the first 800 chars)
EXCERPT=$(head -c 800 brand/voice-profile.md | jq -Rs .) curl -fsS -X POST "$STUDIO/api/brand/note" \ -H 'content-type: application/json' \ -d "{\"file\":\"brand/voice-profile.md\",\"excerpt\":$EXCERPT}"
EXCERPT=$(head -c 800 brand/voice-profile.md | jq -Rs .) curl -fsS -X POST "$STUDIO/api/brand/note" \ -H 'content-type: application/json' \ -d "{\"file\":\"brand/voice-profile.md\",\"excerpt\":$EXCERPT}"
Permission review
Static risk signals and limitations
Network access
The documentation includes network, browsing, or remote request actions.
STUDIO=${STUDIO_BASE:-http://localhost:3001}Network access
The documentation includes network, browsing, or remote request actions.
curl -fsS -m 2 "$STUDIO/api/health" >/dev/null 2>&1 && STUDIO_UP=1 || STUDIO_UP=0Sends data out
The documentation includes sending, uploading, or posting data to a remote service.
curl -fsS -X POST "$STUDIO/api/activity/log" \Sends data out
The documentation includes sending, uploading, or posting data to a remote service.
curl -fsS -X POST "$STUDIO/api/brand/note" \Reads files
The documentation asks the agent to read local files, directories, or repositories.
RES=$(curl -fsS "$STUDIO/api/brand/read?file=voice-profile.md")Writes files
The documentation asks the agent to create, modify, or delete local files.
# 3. Atomic write — fires brand-file-changed SSE so dependent tabs refreshEvidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 67/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 27 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- MoizIbnYousaf/marketing-cli
- Skill path
- studio/skills/cmo-studio-integration/SKILL.md
- Commit
- f12fbcbe4929584697b309b9096c9427b0cfce8e
- License
- MIT
- Collected
- 2026-07-28
- Default branch
- main
View the original SKILL.md
/cmo ↔ mktg-studio integration
mktg-studio is the local dashboard that visualises everything you do.
When it's running, the user has a browser open at http://localhost:3000
showing primary surfaces (Pulse, Signals, Publish, Brand) and an Activity
panel on the right. Trend radar lives inside Signals. Audience summary and
recommended next actions live inside Pulse.
This skill teaches you to drive that dashboard without being asked. No
SDKs. No special tools. Every action is a curl you already know how to
write.
1. Detect first
On every turn, before doing anything else marketing-y, run:
STUDIO=${STUDIO_BASE:-http://localhost:3001}
curl -fsS -m 2 "$STUDIO/api/health" >/dev/null 2>&1 && STUDIO_UP=1 || STUDIO_UP=0
STUDIO_UP=1→ studio is up, follow the rules belowSTUDIO_UP=0→ studio is down, behave exactly as you would in a CLI-only setup. Don't surface the unreachable studio to the user — they probably don't have it open.
Cache the result for the rest of the turn — don't hammer health.
If you want to confirm the wire shapes you're about to send, fetch the schema once per session (it's static):
curl -fsS "$STUDIO/api/schema" | jq '.routes[].path'
curl -fsS "$STUDIO/api/schema?route=/api/activity/log" | jq
curl -fsS "$STUDIO/api/help" | jq '.data.entryPoints'
2. The five verbs
Every meaningful action you take should map to one or more of these endpoints. Skip them when they don't apply — don't be noisy.
| Verb | Endpoint | Call when |
|---|---|---|
| Log | POST /api/activity/log | After running any skill, writing a brand file, sending a publish, calling out errors. One entry per discrete action. |
| Note | POST /api/brand/note or POST /api/brand/write | When you've created or edited a brand/*.md file. /write is the agent-native path (lock-protected); /note is the lightweight "fyi I edited this externally" path. |
| Push | POST /api/opportunities/push | When your analysis surfaces a recommended next action. Set priority 0-100 — be honest about urgency. |
| Toast | POST /api/toast | Inline confirmations the user should see immediately. level: "success" | "info" | "warn" | "error". |
| Navigate | POST /api/navigate | When the result of your work lives on a specific surface and you want the user to look there. Valid tabs: pulse, signals, publish, brand. Use {"tab":"signals","filter":{"mode":"radar"}} for Trend radar. Example: after landscape-scan finishes, switch to Signals/Trend radar; after brand-voice or voice-extraction, switch to brand. |
Copy-paste recipes
# Log a skill run
curl -fsS -X POST "$STUDIO/api/activity/log" \
-H 'content-type: application/json' \
-d '{"kind":"skill-run","skill":"landscape-scan","summary":"Refreshed landscape, 5 new claims","filesChanged":["brand/landscape.md"]}'
# Note a brand-file write (excerpt is the first ~800 chars)
EXCERPT=$(head -c 800 brand/voice-profile.md | jq -Rs .)
curl -fsS -X POST "$STUDIO/api/brand/note" \
-H 'content-type: application/json' \
-d "{\"file\":\"brand/voice-profile.md\",\"excerpt\":$EXCERPT}"
# Push an opportunity
curl -fsS -X POST "$STUDIO/api/opportunities/push" \
-H 'content-type: application/json' \
-d '{"skill":"keyword-research","reason":"You have a landscape but no keyword-plan yet — that gates seo-content","priority":80}'
# Toast
curl -fsS -X POST "$STUDIO/api/toast" \
-H 'content-type: application/json' \
-d '{"level":"success","message":"Landscape refreshed — see Trend radar"}'
# Navigate
curl -fsS -X POST "$STUDIO/api/navigate" \
-H 'content-type: application/json' \
-d '{"tab":"signals","filter":{"mode":"radar"}}'
3. Brand files are first-class
Writing a brand file directly with the Write tool works but doesn't update the studio. Prefer the HTTP path:
# 1. Read current content + grab the mtime for optimistic locking
RES=$(curl -fsS "$STUDIO/api/brand/read?file=voice-profile.md")
MTIME=$(echo "$RES" | jq -r '.data.mtime')
# 2. Build new content in-memory (your editing logic here)
CONTENT=$(jq -Rs . < new-voice-profile.md)
# 3. Atomic write — fires brand-file-changed SSE so dependent tabs refresh
curl -fsS -X POST "$STUDIO/api/brand/write" \
-H 'content-type: application/json' \
-d "{\"file\":\"voice-profile.md\",\"content\":$CONTENT,\"expectedMtime\":\"$MTIME\"}"
# 4. Log the activity
curl -fsS -X POST "$STUDIO/api/activity/log" \
-H 'content-type: application/json' \
-d '{"kind":"brand-write","filesChanged":["brand/voice-profile.md"],"summary":"Made the voice more casual — 3 anchor sentences swapped"}'
If the user edited the same file in their text editor while you were
writing, the expectedMtime mismatch returns 409 CONFLICT with a fix
hint pointing back to /api/brand/read to re-fetch + merge.
If you need to re-research a brand file, queue the owning skill:
curl -fsS -X POST "$STUDIO/api/brand/regenerate" \
-H 'content-type: application/json' \
-d '{"file":"landscape.md"}'
# → { ok: true, data: { jobId, skill, file } }
# poll via curl -fsS "$STUDIO/api/jobs/<jobId>" or watch /api/events
4. The idiomatic turn
A typical /cmo turn that runs a skill, writes a brand file, and recommends a next action:
STUDIO=${STUDIO_BASE:-http://localhost:3001}
curl -fsS -m 2 "$STUDIO/api/health" >/dev/null || exit 0 # 1. detect
curl -fsS -X POST "$STUDIO/api/activity/log" -H 'content-type: application/json' \
-d '{"kind":"skill-run","skill":"landscape-scan","summary":"Refreshing landscape from 18 sources"}'
# 2. (do the actual work — Exa search, write brand/landscape.md)
EXCERPT=$(head -c 800 brand/landscape.md | jq -Rs .)
curl -fsS -X POST "$STUDIO/api/brand/note" -H 'content-type: application/json' \
-d "{\"file\":\"brand/landscape.md\",\"excerpt\":$EXCERPT}"
curl -fsS -X POST "$STUDIO/api/activity/log" -H 'content-type: application/json' \
-d '{"kind":"skill-run","skill":"landscape-scan","summary":"Done — 5 new claims, 2 deprecated","filesChanged":["brand/landscape.md"]}'
curl -fsS -X POST "$STUDIO/api/opportunities/push" -H 'content-type: application/json' \
-d '{"skill":"competitor-alternatives","reason":"Fresh landscape — write 3 X vs Y pages","priority":75}'
curl -fsS -X POST "$STUDIO/api/navigate" -H 'content-type: application/json' \
-d '{"tab":"signals","filter":{"mode":"radar"}}'
curl -fsS -X POST "$STUDIO/api/toast" -H 'content-type: application/json' \
-d '{"level":"success","message":"Landscape refreshed — see Trend radar"}'
Eight calls. Each one is fire-and-forget, returns under 50ms, and the dashboard updates in real time via SSE. The user watches the work happen.
5. Don't break
- Every endpoint returns
{ok: true, ...}or{ok: false, error: {code, message, fix?}}. Predictable envelope. - Three documented exceptions return bare tab-shaped objects (no
ok/datawrapper):GET /api/opportunities,GET /api/audience/profiles,GET /api/briefs. Treat a 200 with the expected top-level keys (opportunities,profiles,briefs) as success; don't look for.okon these three. - On connection failure (studio down), proceed as if the dashboard didn't exist. Don't retry.
- On
{ok: false}with afixfield, surface or follow it — it's agent-actionable by design. /api/navigateand/api/toastare SSE-only (no DB write). Spamming them is harmless but ugly. Send one navigate per logical destination change, one toast per user-facing milestone.- All mutating endpoints accept
?dryRun=true— append it during development to validate request shape without side effects.
6. What NOT to do
- Don't
POST /api/navigatebetween every step of a multi-skill playbook — switch tabs once, at the end, when the user should look at the result. - Don't
POST /api/toastfor routine logs — that's what/api/activity/logis for. Toasts are for things the user should drop everything and notice. - Don't try to
POST /api/brand/writeoutsidebrand/*.md— the path validator rejects everything else withBAD_INPUT. - Don't fetch
/api/schemamore than once per session — the wire shape is static within a server boot.
Reference
- Full HTTP contract with copy-pasteable curls:
docs/cmo-integration.md - Endpoint shapes (live, runtime-introspectable):
GET /api/schema,GET /api/help - 5-minute reproducible demo:
docs/DEMO.md
Alternatives
Compare before choosing
event4u-app/agent-config
design-intelligence
Grounded design brief from the adopted corpus — style, WCAG-checked color tokens, typography, layout pattern, anti-patterns. Use on ui-design-brief or any which-style/palette/font/chart decision.
wshobson/agents
brand-landingpage
Brand-first landing page designer — runs a brand-identity interview (colors, typography, shape language), then generates and iterates on a polished landing page via Stitch with deployment-ready HTML. Use when the user asks to create, design, or build a landing page, homepage, or marketing page and has no established visual direction. Skip when they have a design mockup, need a dashboard or app UI, are working at component level, building a multi-page app, or restyling with known design tokens —
MoizIbnYousaf/marketing-cli
cmo-remotion
Brand-grounded Remotion video pipeline. Take a brief, ground it in `brand/` (voice, audience, positioning, creative-kit), write a beat sheet, scaffold a fresh Remotion project, generate any required assets, compose with frame-driven animations, and bake a final MP4. Use this skill whenever the user wants to build a NEW Remotion video from scratch — product films, motion graphics, code-driven shaders, CRT/glitch effects, HTML-in-canvas demos, React video. Triggers on requests like "make a remotio
MoizIbnYousaf/marketing-cli
image-gen
Generate images using the brand's visual identity and Gemini API. Reads brand/creative-kit.md for visual style, crafts narrative prompts, and produces images via Nano Banana Pro (gemini-3-pro-image-preview). Supports on-brand and freestyle modes. Use when the user needs a blog header, social graphic, product shot, hero image, banner, thumbnail, or any generated image. Also use proactively when building content that would benefit from visuals. Triggers on "generate image", "create image", "make m