Maintenance
| Agent | Version | Last Changed |
|---|---|---|
| Link | v2.20.1 | July 13, 2026 |
Description: Bring an existing brand's setup up to date with the latest plugin version — detects gaps since the user last ran brand-setup and fills them interactively
Change Log
v2.20.1 — July 13, 2026
- Corrected the fb.ai tool count referenced in the key-scope check messaging (98 → 100), matching the same correction made across the other v2.20.0 skills.
v2.20.0 — July 12, 2026
- fb.ai key scope check for existing brands. Repointed the stale api-keys links to
/dashboard/api-keysand added afivebucks_whoamiprobe: keys generated before scoping are legacy full-access keys and keep working (emptyscopes— no action needed), but a regenerated key missingsocial_postswill silently break the fb.ai-dependent skills. Reports the granted scopes + quota snapshot and surfacesauth/key-expired.
v2.19.0 — July 03, 2026
- Corrected Zernio ad-account discovery tool name (fixes the v2.18.0 migration bug). v2.18.0 assumed Zernio just drops the
late_prefix, but Zernio's tools are resource-prefixed. Step 2/Step 3 ad-account resolution now callsads_list_ad_accounts(waslist_ad_accounts).profiles_list/accounts_listwere already correct.
v2.18.0 — July 01, 2026
- Migration support for the Zernio + DataforSEO gateway split-off (gateway v1.7.4/v1.7.5) and Argil retirement. Step 1e adds Zernio (
profiles_list— success = authorized) and DataforSEO (keywords_data_google_ads_search_volume, optional) connector probes. Step 3f renames every${BRAND}_LATE_*env var →${BRAND}_ZERNIO_*, removes the now-defunctLATE_API_KEY(Zernio is OAuth — no key), and updates the auto-discover tool names (profiles_list/accounts_list/list_ad_accounts, no longer gateway-routed). Step 3g adds a Zernio (required, OAuth) connector walkthrough and a DataforSEO (optional, Basic Auth) connector walkthrough. Step 3k adds a brand-action row mapping this release — reconnect Zernio + DataforSEO as their own custom connectors and re-run account discovery, since Zernio's own API may return different SocialAccount_ids than the old gateway-proxied Late API.
v2.17.0 — June 21, 2026
- Migration support for the Inbound Gig Engine completion (v2.17.0 Sales skills
gig-proposal-writer/n8n-workflow-builder/vsl-demo-producer). Step 1e adds an n8n Cloud MCP probe (get_workflow_best_practices) — optional, only needed byn8n-workflow-builder. Step 3g adds the n8n Cloud connect-walkthrough prompt. Step 3k maps the newInbound Gig Engine completedchangelog entry to its optional brand action (connect n8n Cloud + optional${BRAND}_N8N_PROJECT). The three skills are auto-detected from the shippedskills-manifest.json(Step 1 registry read); no per-brand context file is required beyond whatgig-prospectoralready needs.
Plugin Update — Catch Existing Brands Up to Latest Plugin Version
Before Executing
Read agents/link.md before starting. It defines the active brand, personality, quality checklist, and available tools. Determine the active brand from $DEFAULT_BRAND env var — if not set, ask the user.
You are the upgrade agent for the Link marketing plugin. The user has already run brand-setup at some earlier plugin version, and the plugin has since added new requirements (mandatory files, env vars, MCPs, CLAUDE.md sections, etc.). Your job is to detect what's missing in the current brand setup and walk the user through filling only those gaps — never re-run steps that are already complete.
This skill is idempotent. Running it twice in a row should produce a clean "nothing to do" report on the second pass.
When to invoke
- After upgrading to a new plugin version (e.g.
git pullin the marketplace folder) - When a brand was set up months ago and skills are throwing "missing file / missing env var" errors
- User says "update", "upgrade", "catch up", "what's missing", "plugin-update"
How this differs from brand-setup
| Aspect | brand-setup | plugin-update |
|---|---|---|
| When | First time, new brand | Existing brand, after plugin upgrade |
| Greenfield | Yes — writes everything | No — only fills gaps |
| Order | Linear, all 10 steps | Skips anything already complete |
| Re-asks for known data | Yes | No — reuses what's on disk |
If brands/{brand}/ does not exist at all, this skill exits and tells the user to run /link-skills:brand-setup first.
What this skill does
When you upgrade the plugin (e.g. git pull in the marketplace folder), some skills will have new requirements — new brand context files, new env vars, new MCP integrations, new sections in brand.md. Plugin-update is the idempotent catch-up runner: it inspects every brand asset, env var, MCP probe, and CLAUDE.md setting against the current plugin's expectations, then walks you through filling only the gaps. It never re-asks for data that's already on disk.
Estimated time: 5–30 minutes for a typical run. A clean brand (no gaps) finishes in ~5 minutes (mostly automated inspection). A heavily-outdated brand (e.g. last set up 6 months ago, missing the v2.4.0 sales/finance/customer-success files) can take 30–60 minutes if you choose to fill all the new context files in this session.
The 6 steps:
| # | Step | Purpose | Time |
|---|---|---|---|
| 0 | Determine version gap | Read current plugin version + brand's last-applied version; build the changeset that needs catching up | ~30 sec (auto) |
| 1 | Detect current state | Inspect every brand file, env var, MCP connector, CLAUDE.md section — no user prompts, just look | 1–2 min (auto) |
| 2 | Show the gap report | Compact summary of what's present / missing / optional, grouped by category. One question: "want to fill these now?" | 1 min |
| 3 | Fill the gaps interactively | Walk through each missing item in order. Each fill delegates to the matching brand-setup sub-step | 2–60 min (variable) |
| 4 | Re-validate | Test only the integrations touched in Step 3 to confirm fixes worked | 1–2 min |
| 5 | Record version + email + Slack | Write current plugin version to brand.md, send completion email, DM Slack |
30 sec |
The skill is idempotent by design — running it twice in a row should produce a clean "nothing to do" report on the second pass. You can pause anywhere (e.g. say "skip" to a gap you don't want to fill now) and re-run later to pick up where you left off.
Step 0 — Determine version gap
First the agent figures out what changed between the version your brand was set up at and the version you have installed now. It reads version.ts for the current installed version, looks at brands/{brand}/brand.md for the brand's last-applied version stamp, and reads every skill's maintenance section to build a per-skill version delta. The output is a list of what's new since the brand was last configured — the input that drives Step 3's brand-action mapping.
Expect ~30 seconds. Fully automated. Only asks you a question if the brand's last-applied version is missing from brand.md (in which case it asks you to recall when the brand was last set up).
0a. Read current plugin version
Open plugins/link-skills/versions/version.ts and read DEFAULT_VERSION (e.g. v2.2.15). This is the version the user has installed right now.
0b. Read last-applied version for this brand
Open brands/{brand}/brand.md and look for a ## Plugin Version section:
- If present →
last_applied = that version string - If missing → ask the user: "What version were you on when you last ran brand-setup or plugin-update? (Run
git log --oneline -5in this folder if unsure.)" - If unknown → treat
last_applied = v2.0.0(full audit)
0c. Read skill and agent maintenance sections
For each of the following files, read the ## Maintenance block and extract the Version value from the table:
| File | Extract |
|---|---|
plugins/link-skills/agents/link.md |
Version |
plugins/link-skills/skills/brand-setup/SKILL.md |
Version |
plugins/link-skills/skills/content-generator/SKILL.md |
Version |
plugins/link-skills/skills/creative-designer/SKILL.md |
Version |
plugins/link-skills/skills/content-creation/SKILL.md |
Version |
plugins/link-skills/skills/social-calendar/SKILL.md |
Version |
plugins/link-skills/skills/digital-marketing-analyst/SKILL.md |
Version |
plugins/link-skills/skills/data-analysis/SKILL.md |
Version |
plugins/link-skills/skills/social-publisher/SKILL.md |
Version |
plugins/link-skills/skills/research-strategy/SKILL.md |
Version |
plugins/link-skills/skills/campaign-presenter/SKILL.md |
Version |
plugins/link-skills/skills/background-generator/SKILL.md |
Version |
plugins/link-skills/skills/plugin-update/SKILL.md |
Version |
0d. Build the version delta
Flag each skill/agent whose maintenance Version is newer than last_applied. These are the files that changed since the user's brand was last configured. Also flag any skill/agent that is new (did not exist at last_applied — compare the file list on disk against what version.ts history shows was introduced).
Step 1 — Detect current state
Now the agent does a read-only inspection sweep of everything related to this brand — folder contents, brand.md sections, env vars, MCP connectors, CLAUDE.md, Notion DBs, template uploads, skill versions. No questions yet, no fixes — just look. Each sub-step (1a–1j) checks one category and tags items as present / missing / drift. The output of this step is the gap report you'll see in Step 2.
Expect 1–2 minutes. Mostly automated; a few MCP probes will hit external services (e.g. Notion, Apollo, Xero) which can be slow if connections are flaky.
Read everything that exists for the active brand. Do not prompt the user yet — just inspect.
1a. Brand folder contents
Check existence of each path under brands/{brand}/. Mark present/missing:
| Path | Required since | Status |
|---|---|---|
brand.md |
v2.0 | present / missing |
product.md |
v2.0 | present / missing |
audience.md |
v2.0 | present / missing |
competitors.md |
v2.0 | present / missing |
funnel.md |
v2.1.0 | present / missing |
avatars.md |
v2.1.0 | present / missing |
logo.png |
v2.0 | present / missing |
backgrounds/ |
v2.0 (now empty by design) | present / missing |
design-system/ |
v2.2.10 (optional — brand.md fallback since v2.2.15) | present / missing |
sales.md |
v2.4.0 | present / missing |
customer-success.md |
v2.4.0 | present / missing |
finance.md |
v2.4.0 | present / missing |
investors.md |
v2.4.0 (optional — only required if brand has raised external capital) | present / missing |
operations.md |
v2.4.0 (optional — meeting-analyzer falls back gracefully) | present / missing |
Inline schema check — sales.md Booking URL. If sales.md is present, open it and verify the ## Sender Persona block contains a non-empty Booking URL: line. If missing → flag as ⚠ schema gap and route to brand-setup Step 5g Step A backfill (single-question fix — only the Booking URL is asked, no need to re-walk the rest of the sub-step). The outreach-sequencer standing-link fallback, the customer-onboarder kickoff fallback, and the {link} placeholder in Reply Routing all depend on this field; brands set up before it was introduced will silently use empty CTAs until backfilled.
Inline schema check — sales.md Inbound Job Filters (v2.16.0). If sales.md is present, check for a ## Inbound Job Filters section. If missing → flag as ⏭ optional schema gap and route to the Step 3a targeted backfill (brand-setup Step 5g Step H — markets, platforms + account status, product.md-derived search keywords, budget/exclusions/cap). This section powers gig-prospector; without it that one skill can't run, but no existing skill breaks — so it's optional, not a required gap. Skip silently for brands that don't pursue freelance/marketplace work.
1b. brand.md sections
Read brands/{brand}/brand.md and check for these section headers (added in different versions):
| Section | Required since | Status |
|---|---|---|
## Tagline |
v2.0 | present / missing |
## Voice & Tone |
v2.0 | present / missing |
## Colors (HEX codes) |
v2.0 | present / missing |
## Locale (Currency / Timezone / Meta USD exchange rate) |
v2.2.0 | present / missing |
## Approved Phrases |
v2.0 | present / missing |
## Do NOT Say |
v2.0 | present / missing |
## Social Publishing (Zernio profile + connected platforms) |
v2.2.1 | present / missing |
## Content Strategy (Primary channel + distribution platforms + cadence) |
v2.14.0 | present / missing |
1c. funnel.md schema
Open brands/{brand}/funnel.md if present. Confirm it has:
## Stages (Google Ads)table with GA4 event mappings## Stages (Meta Ads)table## Cost Benchmarkstable- No remaining
TBDevent names (if any → flag for re-mapping)
1d. Env vars in .claude/settings.local.json
Read .claude/settings.local.json (search up from cwd). Check the env block:
Required:
| Env var | Required since |
|---|---|
FIVEAGENTS_API_KEY |
v2.0 |
GEMINI_API_KEY |
v2.0 |
SLACK_NOTIFY_USER |
v2.0 |
REPORT_EMAIL |
v2.0 |
{BRAND}_ZERNIO_FB / _IG / _LI |
v2.2.1 |
{BRAND}_ZERNIO_TT / _TW (TikTok / Twitter-X organic — video-repurposer, YouTube-First) |
v2.14.0 |
{BRAND}_NOTION_DB |
v2.2.10 (social-calendar bootstraps if missing) |
Note: Zernio (formerly Late) moved to its own OAuth MCP in gateway v1.7.4 — there is no longer a
LATE_API_KEYenv var. Authorization is handled by connecting the Zernio custom connector (Step 3g), not by saving a key.
Optional:
| Env var | Notes |
|---|---|
DATAFORSEO_LOGIN / DATAFORSEO_PASSWORD |
Keyword research |
DEFAULT_BRAND |
Workspace default brand |
{BRAND}_ZERNIO_GOOGLE_ADS (Zernio SocialAccount _id) + {BRAND}_ZERNIO_GOOGLE_ADS_CID (Google Ads customer ID, 10-digit) |
Both required for the Windsor.ai fallback in digital-marketing-analyst / data-analysis. Zernio's Google Ads tools take account_id AND ad_account_id — passing only the SocialAccount ID returns empty results. |
{BRAND}_ZERNIO_META_ADS_ACCOUNT_ID |
Meta Ads account ID for Windsor.ai fallback in digital-marketing-analyst / data-analysis (v2.5.0) |
{BRAND}_ZERNIO_LINKEDIN_ADS (Zernio SocialAccount _id) + {BRAND}_ZERNIO_LINKEDIN_ADS_CID (LinkedIn sponsored account ID, numeric) |
Both required for the LinkedIn Ads Windsor.ai fallback in digital-marketing-analyst / data-analysis. Same two-ID pattern as Google Ads — passing only the SocialAccount ID returns empty results. Optional: skip if the brand does not run LinkedIn Ads. |
Auto-bootstrapped (no user action required at setup; created on first run of the relevant skill):
| Env var | Bootstrapped by | Required since |
|---|---|---|
${BRAND}_CRM_DB |
apollo-lead-prospector / outreach-sequencer / proposal-generator | v2.4.0 |
${BRAND}_CUSTOMER_DB |
customer-onboarder / churn-predictor | v2.4.0 |
${BRAND}_INVOICE_TRACKER_DB |
invoice-collector | v2.4.0 |
${BRAND}_REPORTS_DB |
financial-reporter / investor-update-writer | v2.4.0 |
${BRAND}_COMPETITOR_DB |
competitor-monitor | v2.4.0 |
${BRAND}_MEETINGS_DB |
meeting-analyzer | v2.4.0 |
${BRAND}_ACTIONS_DB |
meeting-analyzer | v2.4.0 |
${BRAND}_PERFORMANCE_DB |
content-performance-analyst | v2.13.0 |
${BRAND}_TREND_DB |
trend-radar | v2.13.0 |
${BRAND}_GIGS_DB |
gig-prospector | v2.16.0 |
For each: if present + the matching DB exists in Notion → ✅ skip. If missing → not flagged as a gap (the skill will create on first run). The audit reports presence informationally only.
For each missing key, mark whether it's required or optional.
1e. MCP connectors
You cannot directly probe what the user has connected in Claude settings. Instead, lazily test each one with a low-cost call and treat connection errors as "not connected":
| MCP | Probe | Required since |
|---|---|---|
| Five Agents (gateway) | fiveagents_log_run (test entry) |
v2.0 |
| Zernio (own MCP, OAuth) | profiles_list (success = authorized) |
v2.18.0 (formerly Late, gateway-routed; split to its own custom connector in gateway v1.7.4 — https://mcp.zernio.com/mcp) |
| DataforSEO (own MCP, Basic Auth) | keywords_data_google_ads_search_volume with a trivial keyword (optional) |
v2.18.0 (formerly gateway-routed; split to its own custom connector in gateway v1.7.5 — https://mcp.dataforseo.com/mcp; only needed for keyword research — never flag as a required gap) |
| Notion | notion-search query="ping" |
v2.0 |
| Slack | slack_search_users query="me" |
v2.0 |
| Gmail | list_labels |
v2.0 |
| Google Calendar | list_calendars |
v2.0 |
| Windsor.ai | get_connectors |
v2.1.0 |
| Canva | list-brand-kits |
v2.1.0 |
| Playwright | check claude mcp list (Bash) |
v2.1.4 (website analysis in brand-setup Step 4 — template rendering now uses gateway) |
| Apollo.io | apollo_users_api_profile |
v2.4.0 |
| Calendly | OAuth status check (Calendly MCP gates real tools behind authenticate) | v2.4.0 |
| Stripe | OAuth status check (Stripe MCP gates real tools behind authenticate) | v2.4.0 |
| Xero | whoami |
v2.4.0 |
| PostHog | user-get |
v2.4.0 (used by churn-predictor; data-analysis may already validate it — reuse if so) |
| Gamma | get_themes |
v2.4.0 (used by investor-update-writer; campaign-presenter may already validate it — reuse if so) |
| n8n Cloud | get_workflow_best_practices (technique="list") |
v2.17.0 (optional — used by n8n-workflow-builder for inbound-gig proof workflows; never flag as a required gap — only relevant if the brand pursues marketplace work) |
| Meta Ads MCP (optional enhancement — limited rollout) | attempt any ads_* tool call (e.g. ads_get_ad_accounts); 401 / not-found → not connected |
v2.2.13 (Windsor.ai already covers Meta data fully when this isn't connected — never flag as a required gap) |
1f. Workspace CLAUDE.md
Check CLAUDE.md at the workspace root (alongside brands/).
| Item | Required since |
|---|---|
| File exists | v2.2.7 |
Contains ## Agent Identity block |
v2.2.7 |
link.md path is absolute (os.path.isabs == True) |
v2.2.10 |
link.md path is correct (file exists at that location) |
v2.2.7 |
Contains ## Credential Loading block with load_credentials() snippet |
v2.2.7 |
## Active Brand section names the current brand |
v2.2.7 |
Version stamp <!-- link.md version: ... --> present inside BEGIN/END markers |
v2.3.0 |
Version stamp matches current agents/link.md Maintenance version (will be refreshed in Step 3g regardless) |
v2.3.0 |
1g. Claude Code settings
Read .claude/settings.local.json and ~/.claude/settings.json for:
| Setting | Required since |
|---|---|
Bypass permissions mode (Allow bypass permissions mode) |
v2.2.3 |
| Domain Allowlist set to All Domains | v2.2.4 |
| Project Permission set to Act without asking | v2.2.5 |
These are UI settings — surface them to the user as a manual checklist if you can't read them programmatically.
1h. fb.ai social templates
Social templates live on fb.ai (brand-setup Step 4c), not on disk — there is no local folder, version hash, or gateway upload to reconcile. Detect which exist for this brand:
Use gateway MCP tool fivebucks_list_templates:
- fiveagents_api_key: ${FIVEAGENTS_API_KEY}
Record which of the four types are present: meta-carousel, meta-story, linkedin-post, meta-post. If FIVEBUCKS_API_KEY isn't set (no fb.ai plan), skip this step — the brand uses the Gemini + Pillow fallback for all formats. Missing types are an install opportunity, not a failure (see Step 3c).
1i. fb.ai media library
Check whether the brand has any media uploaded via fivebucks_list_media_folders. If FIVEBUCKS_API_KEY isn't set, skip — record as N/A.
Use gateway MCP tool fivebucks_list_media_folders:
- fiveagents_api_key: ${FIVEAGENTS_API_KEY}
- Result is non-empty → ✅ media library populated.
- Result is empty → ⏭ no brand photos uploaded (offer to set up in Step 3d; skills fall back to Gemini image generation when empty).
1j. Notion DB for social calendar
If {BRAND}_NOTION_DB is set:
notion-fetchit. If success and the returned object is a database withName(title) property → OK.- If the fetch returns
not_foundor the object is not a database → mark for re-bootstrap.
If {BRAND}_NOTION_DB is unset → mark as missing (social-calendar will bootstrap on first run, but we offer to do it now).
1k. Skill and agent version audit
Using the data collected in Step 0, build a version table. Read actual versions from disk — do not use the example below as current data.
(Example format only — versions shown here are illustrative, not current):
| File | Installed version | Changed since {last_applied}? |
|---|---|---|
| agents/link.md | v2.3.0 | ✅ yes |
| brand-setup | v2.2.15 | ✅ yes |
| content-generator | v2.2.15 | ✅ yes |
| creative-designer | v2.2.15 | ✅ yes |
| content-creation | v2.2.15 | ✅ yes |
| social-calendar | v2.2.15 | ✅ yes |
| background-generator | v2.2.15 | ✅ yes |
| digital-marketing-analyst | v2.3.0 | ✅ yes |
| data-analysis | v2.3.0 | ✅ yes |
| social-publisher | v2.2.5 | — no |
| research-strategy | v2.2.5 | — no |
| campaign-presenter | v2.2.5 | — no |
| plugin-update | v2.3.0 | ✅ yes (new) |
apollo-lead-prospector |
v2.4.0 | ✅ yes (new) |
outreach-sequencer |
v2.4.0 | ✅ yes (new) |
proposal-generator |
v2.4.0 | ✅ yes (new) |
customer-onboarder |
v2.4.0 | ✅ yes (new) |
churn-predictor |
v2.4.0 | ✅ yes (new) |
invoice-collector |
v2.4.0 | ✅ yes (new) |
financial-reporter |
v2.4.0 | ✅ yes (new) |
competitor-monitor |
v2.4.0 | ✅ yes (new) |
investor-update-writer |
v2.4.0 | ✅ yes (new) |
meeting-analyzer |
v2.4.0 | ✅ yes (new) |
Flag any skill that is entirely new (folder exists on disk but last_applied predates its introduction). For each changed/new skill, extract the relevant changelog bullets from its ### Change Log section — these drive Step 3k.
Registry source. Read the plugin's skills-manifest.json — it ships pre-generated from each skill's frontmatter, and its sync is enforced at release time by commit-to-git Step 4f. plugin-update runs in the user's Cowork project and does not regenerate or --check it (that's a maintainer/CI step) — it just reads the shipped manifest for each skill's area / deps. Reading the manifest needs no tooling; it's plain JSON.
Step 2 — Show the gap report
The agent shows you a single compact summary of every category checked in Step 1 — what's present (✅), what's missing required (❌), what's missing optional (⏭). You see the whole picture before any fix work starts, so you can scan it and decide whether to walk through the gaps now or come back later. Optional gaps (e.g. design-system, social templates, investors.md if you haven't raised) are clearly marked so you don't feel pressured to fill them.
Expect 1 minute. Single question at the end: "Want me to walk through these gaps now?" If you say no, the skill exits cleanly and the gap report is logged to memory so you can revisit later.
Build a compact gap table and show it to the user before doing anything. Group by category. Mark each item as ✅ (present) / ❌ (missing required) / ⏭ (optional missing). Example:
[{brand}] Plugin Update — Gap Report
Plugin version: {last_applied} → {DEFAULT_VERSION}
Skills/agents updated since {last_applied}
✅ agents/link.md v2.7.0 social templates → fb.ai (fivebucks_* tools)
✅ brand-setup v2.2.15 Step 4c rewrite (EDITMODE contracts); design-system/ now optional
✅ content-generator v2.7.0 render via fb.ai fivebucks_* (Step 4c-template)
✅ creative-designer v2.2.15 template-path → gateway; design-system/ optional
✅ content-creation v2.2.15 _copy.json output; naming convention split
✅ social-calendar v2.2.15 Direction column added (11 columns)
✅ plugin-update v2.3.0 new skill
Brand context files
✅ brand.md, product.md, audience.md, competitors.md, funnel.md, avatars.md, logo.png
❌ sales.md ← v2.4.0 (apollo-lead-prospector / outreach-sequencer / proposal-generator)
❌ customer-success.md ← v2.4.0 (customer-onboarder / churn-predictor)
❌ finance.md ← v2.4.0 (invoice-collector / financial-reporter)
⏭ investors.md ← v2.4.0 optional (only required if brand has raised external capital)
⏭ operations.md ← v2.4.0 optional (only required if user processes meeting transcripts)
⏭ design-system/ ← optional (recommended; brand.md fallback if absent)
fb.ai social templates (Step 1h — needs FIVEBUCKS_API_KEY)
⏭ meta-carousel / meta-story / linkedin-post / meta-post — which exist on fb.ai? (install via Step 3c)
fb.ai media library (Step 1i — needs FIVEBUCKS_API_KEY)
⏭ no media folders found — upload brand photos via Step 3d
brand.md sections
✅ Tagline / Voice & Tone / Colors / Approved Phrases / Do NOT Say
❌ Locale (Currency / Timezone / Meta USD) ← v2.2.0
❌ Social Publishing (Zernio profile + accounts) ← v2.2.1
Env vars (.claude/settings.local.json)
✅ FIVEAGENTS_API_KEY, GEMINI_API_KEY, SLACK_NOTIFY_USER, REPORT_EMAIL
❌ {BRAND}_ZERNIO_FB, {BRAND}_ZERNIO_IG, {BRAND}_ZERNIO_LI
❌ {BRAND}_NOTION_DB ← will be created by social-calendar on first run, or bootstrap now
MCP connectors
✅ Five Agents, Notion, Slack, Gmail, Google Calendar
❌ Zernio (required for social-publisher — reconnect as its own OAuth connector; formerly gateway-routed)
❌ Windsor.ai (required for digital-marketing-analyst)
❌ Canva (required for campaign-presenter)
❌ Playwright (required for website analysis in brand-setup Step 4)
❌ Apollo.io (required for apollo-lead-prospector, outreach-sequencer)
❌ Calendly (required for customer-onboarder, meeting-analyzer)
❌ Stripe (required for invoice-collector, financial-reporter)
❌ Xero (required for invoice-collector, financial-reporter)
⏭ DataforSEO (optional — keyword research; reconnect as its own Basic Auth connector)
⏭ PostHog (optional — churn-predictor falls back to support-ticket + login signals)
⏭ Gamma (optional — investor-update-writer needs it; skip if you don't deliver investor decks)
⏭ Meta Ads MCP (optional enhancement — Windsor.ai already covers Meta Ads fully)
Workspace CLAUDE.md
❌ link.md path is RELATIVE — must be absolute (v2.2.10)
✅ Agent Identity block
✅ Credential Loading block
Settings
Manual: confirm Bypass permissions ON, Domain Allowlist = All Domains, Project = Act without asking
→ {N} required gaps · {M} optional gaps · ready to walk through them?
Ask the user:
Want me to walk through these gaps now? I'll skip anything you say "skip" to. Anything I miss won't break — just won't be set up.
If the user says no / not now, exit cleanly and offer to re-run later. Log the gap report to memory either way.
Step 3 — Fill the gaps interactively
The agent walks through each missing item in order, only prompting for items that came back ❌ or ⏭ in Step 2 — never re-asking for known-good state. For most fills, the agent delegates to the matching brand-setup sub-step (e.g. missing sales.md triggers brand-setup Step 5g, a Zernio connector not authorized triggers brand-setup Step 7a-ii Zernio OAuth authorize flow). You can say "skip" to any optional gap.
Expect 2–60 minutes depending on how many gaps you have. A brand with 3 missing context files + 2 missing env vars + a CLAUDE.md path fix takes ~10 min. A brand with 10+ gaps and lots of optional templates can stretch to an hour. The skill saves progress as it goes, so you can interrupt and resume.
Walk through each missing item in this order. Skip any that came back ✅ in Step 2 — never re-prompt for known-good state.
3a. Brand context files (only if missing)
For each missing file in brands/{brand}/:
Pre-fill rule — applies to every v2.4.0 file below (sales / customer-success / finance / investors / operations). In a plugin-update context, the brand has been around for a while, so the v2.0 files (brand.md, product.md, audience.md, competitors.md, funnel.md) almost always already exist with rich content. You MUST follow the "Read existing context first" mapping table at the top of each brand-setup sub-step (Step 5g intro, 5h intro, 5i intro, 5j intro, 5k intro) before asking the user anything. Read those source files, draft answers from them, then ask "Confirm or edit?" per block — never ask from scratch what's already on disk. In a plugin-update context this rule is essentially mandatory because the source data is virtually guaranteed to exist; in a fresh brand-setup run it is best-effort because the source files are being built up in the same session.
brand.md/audience.mdmissing → runbrand-setupStep 4 (Website Analysis) for this brand only. Re-extract from the website.product.md/competitors.mdmissing → run/link-skills:research-strategyto regenerate.funnel.mdmissing → runbrand-setupStep 5 funnel block (ask user about funnel + GA4 events).avatars.mdmissing → runbrand-setupStep 5 avatars block.logo.pngmissing → ask the user for the file path, copy intobrands/{brand}/logo.png.backgrounds/missing → justmkdir. No content needed (Gemini generates fresh per post since v2.2.9).sales.mdmissing → runbrand-setupStep 5g (Sales context). Apply the Read-first pre-fill table at the top of Step 5g — Sender Persona drafts from brand.md (founder name/title), ICP filters draft per persona from audience.md, disqualification blocklist drafts from competitors.md URLs, default tier per persona drafts from product.md Pricing. Only ask the user from scratch for fields that have no source.sales.mdpresent but Sender Persona is missingBooking URL:(flagged by Step 1a inline schema check) → ask only the single question: "What's your public Calendly scheduling link (e.g.https://calendly.com/you/intro-call)?" Append- Booking URL: {url}to the Sender Persona block ofbrands/{brand}/sales.md. Do NOT re-run the full Step 5g — Sender Persona Name/Title/Signature/Photo are already populated; this is a targeted backfill only.sales.mdpresent but missing## Inbound Job Filters(flagged by Step 1a inline schema check) → ask first: "Does this brand pursue freelance/marketplace work (Upwork, Freelancer.com, etc.)?" If no → skip (not a gap;gig-prospectorsimply won't run). If yes → runbrand-setupStep 5g Step H only: confirm Markets, Platforms + account status, draft Search Keywords fromproduct.md(never hardcode), then Budget Floor / Exclusions / Daily Cap. Append the## Inbound Job Filterssection tobrands/{brand}/sales.md— do NOT re-walk the rest of Step 5g.${BRAND}_GIGS_DBauto-bootstraps ongig-prospector's first run.customer-success.mdmissing → runbrand-setupStep 5h. Apply the Read-first pre-fill table at the top of Step 5h — Plan Tiers drafts from product.md Pricing, Onboarding Milestone trigger events draft from funnel.md GA4 events, Intervention Playbook copy drafts from brand.md voice. Only ask the user from scratch for fields that have no source.finance.mdmissing → runbrand-setupStep 5i. Apply the Read-first pre-fill table at the top of Step 5i — Escalation Tone Ladder copy drafts from brand.md voice, currency / Alert Threshold formatting from brand.md## Locale, KPIs to Highlight defaults to MRR/ARR if product.md Pricing implies subscription else project margin / cash collected. Only ask the user from scratch for fields that have no source.investors.mdmissing → ask first: "Have you raised external capital?" If no → skip (not flagged as gap). If yes → runbrand-setupStep 5j. Apply the Read-first pre-fill table at the top of Step 5j — Sections to Include KPIs draft from finance.md (if present), drafting tone falls back to brand.md voice if user pastes <2 prior updates, sender attribution drafts from sales.md Sender Persona. Only ask the user from scratch for the investor list and prior-updates archive (those have no other source).operations.mdmissing → ask first: "Do you run regular meetings (1:1s, standups, client calls) and want Claude to process transcripts?" If no → skip (not flagged as gap; meeting-analyzer falls back). If yes → runbrand-setupStep 5k. Apply the Read-first pre-fill table at the top of Step 5k — Sales tasks owner drafts from sales.md Sender Persona, Customer issues owner drafts from customer-success.md CSM mentions, Finance tasks owner drafts from finance.md alert recipient. Only ask the user from scratch for owners that have no other-file source.competitors.mdextension missing (existing file present but lacksmonitor_urls/track_pages/exec_teamper competitor) → runbrand-setupStep 5l. Prompts user to add the new fields per existing competitor entry.
3b. design-system/ (optional — recommended)
fb.ai context — show this before any fivebucks.ai link. fivebucks.ai (fb.ai) is a paid product. Never give the user a fivebucks.ai URL or ask them to upload there (the optional upload below, plus Steps 3c and 3d all do) without first explaining what it is:
About fb.ai (fivebucks.ai): it's an optional paid subscription that stores your design system and social templates in the cloud, so Claude can automate your branded social posting — generating and publishing fully on-brand Carousels, Stories, and IG / FB / LinkedIn posts for you. Your design system also lives locally for free, so you can start without paying; the fb.ai plan adds the hosted social templates and lets posts render in your exact brand colors and fonts. You can skip fb.ai entirely — Claude falls back to the colors and fonts in
brand.mdplus Gemini rendering, which stays fully supported.
If brands/{brand}/design-system/ is missing, offer installation but accept "skip" — the brand.md colors and fonts are a fully functional fallback:
Your brand doesn't have a Claude Design system installed. It's optional — skills fall back to the colors and fonts in
brand.md. Installing it gives tighter visual consistency across all outputs. Want to set it up now?
If yes, walk the user through brand-setup Step 4b:
- Open https://claude.ai/design → go to Design System → click Create
- On the "Set up your design system" page, fill the attach form — Company name and blurb; optionally attach a GitHub repo / local code / a .fig file / fonts, logos and assets; and paste the colors, fonts, and voice already in
brands/{brand}/brand.mdinto Any other notes — then click Continue to generation - On the generation prompt, paste a website-aware prompt so Claude validates against the live site. Substitute the brand's website URL (ask the user if it isn't already known, or pull it from
brand.md):
Iterate until it feels on-brand.This is my website: {WEBSITE_URL} — please read it and use it to validate and fill in my colors, typography, components, spacing, and overall visual style. Confirm and refine against the site: colors (primary / secondary / accent), heading + body fonts, and brand voice from brand.md. Build a complete, reusable design system: color tokens, a type scale, buttons, cards, headers / nav, and spacing. - Share → Download Project as .zip → unzip (leave it wherever it is — e.g.
~/Downloads/Acme Design System; no need to move it) - Ask the user for the path to the unzipped folder, then request access to that exact path before reading it — the user approves it in a one-time prompt:
Required in the Cowork harness (filesystem access is sandboxed to approved directories); request the folder the user named, not a guessed default. In local Claude Code this tool is absent and the filesystem is already accessible — skip the request. If the user declines, ask them to move the folder inside the project mount, then copy from there.mcp__cowork__request_cowork_directory(path="<the path the user gave>") - Once access is approved, copy the folder into
brands/{brand}/design-system/(Pythonshutil.copytree, handling the single-inner-folder nested-zip case — see brand-setup Step 4b-C).
Verify brands/{brand}/design-system/ exists and is non-empty before marking complete. If the user skips, mark as ⏭ — not a gap that blocks any skill.
Optional fb.ai upload: after the local copy is in place, ask whether the user also wants to upload the design system to fb.ai (only useful with a paid fb.ai plan — lets fb.ai social templates render with the brand's colors/fonts). If yes:
- Go to https://www.fivebucks.ai/dashboard/api-keys — generate API Key if not done yet (skip if already generated)
- Go to https://www.fivebucks.ai/dashboard/social-posts/brand-kit — click Upload Design System Zip and upload the ZIP.
The fb.ai upload is optional — the local design-system/ already works everywhere. Skip is fine.
3c. Optional fb.ai social templates (offer, don't force)
From Step 1h you know which of the four types exist on fb.ai. For any missing type the brand would benefit from, offer to set it up — but accept "skip":
Want to set up any optional social templates? Pick any of the four: Meta Carousel (IG/FB carousel), Meta Story (IG/FB 9:16), LinkedIn Post (LinkedIn single-image), Meta Post (IG/FB single-image). They make published content more polished and need a paid fb.ai plan. Skip any channel you don't publish on — it falls back to Gemini + Pillow.
If yes, walk through the matching brand-setup sub-step (each = author in Claude Design → generate API Key at https://www.fivebucks.ai/dashboard/api-keys if not done yet → upload ZIP at https://www.fivebucks.ai/dashboard/social-posts/templates → verify via fivebucks_list_templates):
- Meta Carousel →
brand-setupStep 4c-i - Meta Story →
brand-setupStep 4c-ii - LinkedIn Post →
brand-setupStep 4c-iii - Meta Post →
brand-setupStep 4c-iv
There is no local copy, version hash, or gateway-upload step to reconcile — templates live on fb.ai and are detected live. If FIVEBUCKS_API_KEY isn't set, skip this step (the brand uses the Gemini + Pillow fallback).
3d. Optional fb.ai media library (offer, don't force)
Check whether the brand has any media folders via fivebucks_list_media_folders. If the media library is empty and the user wants on-brand photos in generated posts, offer to set it up:
The fb.ai media library is empty. Uploading brand photos lets skills pick on-brand visuals automatically. Want to add some now? You can always skip and upload later.
If yes:
Go to https://www.fivebucks.ai/dashboard/api-keys — generate API Key if not done yet (skip if already generated)
Create one folder per template type, named exactly as follows —
content-generatormatches photos to templates using these names:
- LinkedIn Post — photos for LinkedIn single-image posts
- Meta Story — photos for Instagram / Facebook Stories
- Meta Carousel — photos for Instagram / Facebook Carousels
- Meta Post — photos for Instagram / Facebook single-image posts
Only create folders for template types that exist on fb.ai. Then click Upload Media inside each folder to add your photos.
If the user skips, mark as ⏭ — skills fall back
…(truncated)