UNPKG

@sellable/install

Version:

One-command installer for Sellable MCP in Claude Code, Codex, and Hermes

123 lines (105 loc) • 10 kB
--- name: refresh-sender-engagement description: Top up a sender's post-engager pipeline — fetch their recent LinkedIn posts, pull new engagers, filter by headline ICP criteria, and add net-new leads to their post-engagers campaign with dedupe. Schedule-automation friendly ("refresh sender engagement for these people"). Read-only on LinkedIn; never sends. visibility: public allowed-tools: - mcp__sellable__get_auth_status - mcp__sellable__start_cli_login - mcp__sellable__wait_for_cli_login - mcp__sellable__get_active_workspace - mcp__sellable__list_workspaces - mcp__sellable__set_active_workspace - mcp__sellable__get_subskill_prompt - mcp__sellable__search_subskill_prompts - mcp__sellable__list_senders - mcp__sellable__get_sender - mcp__sellable__get_campaigns - mcp__sellable__get_campaign - mcp__sellable__get_campaign_context - mcp__sellable__get_campaign_table_schema - mcp__sellable__list_tables - mcp__sellable__get_rows_minimal - mcp__sellable__refresh_sender_engagement - mcp__sellable__fetch_linkedin_posts - mcp__sellable__fetch_post_engagers --- # Refresh Sender Engagement <role> You are a pipeline supply agent. People who engage with a sender's LinkedIn posts are their warmest prospects; your job is to capture them into the sender's post-engagers campaign before they go cold — with zero duplicates and zero sends. </role> <inputs> The invoking prompt names the senders ("refresh sender engagement for csreyes92 and thomas"). Resolve each via `list_senders` (match name/handle/LinkedIn URL). With no names given, inspect the active workspace and refresh every connected sender that has an active/paused sender-owned Post Engagers campaign backed by Signal Discovery. Optional: target sender names/ids, `campaignId` when the user wants to force a specific Post Engagers campaign, `tableId` when the user wants to force a specific campaign table, `maxPosts` to refresh a specific number of posts, and maximum engager pages per tracked post. Leave `maxPosts` unset unless the user asked for a specific number. By default the command refreshes every tracked post published inside the 30-day lookback window, which is what keeps recent posts checked often enough to catch new engagers. A post whose engagement counts have not moved costs a single cheap count probe and is skipped before any engager fetch, so a wider sweep is not a proportionally more expensive one. Passing `maxPosts` narrows that sweep. `campaignId` is optional. When it is omitted the command discovers the sender's Post Engagers campaign itself — it searches the workspace for campaigns the sender solely owns that are backed by a post-engager provider and named as a Post Engagers lane. A workspace can hold one such lane per sender, so discovery is always scoped to the sender you are refreshing; another sender's lane and shared multi-sender lanes are never selected. Do not pass a `campaignId` you guessed. </inputs> <entrypoint> This is a public Sellable command: - Claude Code: `/sellable:refresh-sender-engagement` - Codex: `$sellable:refresh-sender-engagement` Use this command when the user asks to refresh recent engagers, top up tracked campaign post engagers, pull latest engagers from sender posts, or refill warm post-engager source rows. It is not a send-refill command; if the user asks to prepare/schedule sends after adding rows, finish this refresh first and then suggest `refill-sends`. </entrypoint> <objective> For each target sender/campaign: 1. **Authenticate and resolve workspace**: - Call `get_auth_status` and confirm the active workspace. - If there is no active workspace or auth is missing, stop with the MCP guidance. Do not use local env files or repo scripts as a substitute for MCP auth. - Resolve each target sender with `list_senders`/`get_sender`. Use the sender id returned by the product, not a guessed handle. 2. **Use the typed product command first**: - Call `refresh_sender_engagement` in `mode:"dry_run"` for each sender. - Always pass `workspaceId`, `senderId`, and any user-specified `campaignId`, `tableId`, `maxPosts`, or `maxEngagerPages`. Omitting `campaignId` is correct and normal — the command resolves the campaign itself. - Read `discovery` on the response to see how the campaign was resolved (`managed_slot`, `explicit_campaign_id`, or `auto_discovered`) and which one was selected. - If `discovery.additionalCandidates` is non-empty, that sender owns more than one Post Engagers lane. Refresh each one by repeating the dry-run/apply cycle with that candidate's `campaignId`. Every lane gets its own dry run and its own `dryRunFingerprint`; never reuse a fingerprint across campaigns. - Treat the dry-run response as the campaign/source boundary authority. It should identify the sender-owned Post Engagers slot, campaign, workflow table, source provider `campaign-tracked-post`, source table type `tracked_post_engager_source_list`, expected tracked posts, expected engager refresh/import work, and a `dryRunFingerprint`. - If the typed command reports no eligible sender-owned Post Engagers campaign, no tracked posts, no recent posts, or a workspace/sender mismatch, report that exact blocker and stop for that sender. Do not silently create campaigns or fall back to shared lanes. - `sender_owned_post_engagers_slot_not_found` now means discovery genuinely found no eligible lane, not that a campaign id was missing. Report `discovery.campaignsInspected` alongside it, and describe it as missing campaign setup — never as "the sender has no posts", since no LinkedIn fetch happens before this point. 3. **Gate writes with dry-run proof**: - Never call `refresh_sender_engagement` in `mode:"apply"` before a successful dry run from this same run. - For manual runs, show the target workspace, sender, campaign/table, source lead list, expected tracked posts, expected row/import impact, and `dryRunFingerprint`, then wait for explicit user approval before apply. - For scheduled automations where the user has already authorized refreshes, apply is allowed only with the exact `dryRunFingerprint` from the immediately preceding dry run. - If apply rejects the fingerprint as stale or mismatched, rerun dry-run and ask for approval again for manual runs. 4. **Apply through the typed command only**: - Call `refresh_sender_engagement({ mode:"apply", workspaceId, senderId, tableId?, maxPosts?, maxEngagerPages?, dryRunFingerprint })`. - The apply path must materialize/refresh tracked posts, import deduped tracked-post engagers into the campaign table, and preserve product idempotency. Do not use `add_on_demand_leads` or raw table row writes for the same operation. 5. **Read-only fallback is diagnostic only**: - If the typed command is unavailable, use `get_subskill_prompt`/`search_subskill_prompts` and stop with `blocked: missing_refresh_sender_engagement_tool`. - `fetch_linkedin_posts` and `fetch_post_engagers` may be used only to explain source availability or diagnose provider issues. They are not an alternate write path. 6. **Report**: campaigns inspected, target campaign/table, tracked posts materialized/refreshed, engagers scanned, ICP-passing/importable, net-new rows imported, duplicates skipped, and any no-op reason per sender/campaign. If a sender posted nothing in the window, say "no recent posts — nothing to refresh" (that is a truthful no-op, not a failure). </objective> <safety> - LinkedIn operations here are read-only fetches plus a typed product import into a campaign table. **No messages are generated, approved, scheduled, or sent by this skill.** - Respect workspace boundaries: only add leads to campaigns in the active workspace, and only for senders that belong to it. - Respect campaign boundaries: only add engagers to the matched sender-owned Post Engagers campaign/table. Do not mix shared-lane engagers into sender-owned campaigns or sender-owned engagers into shared lanes. - Provider usage per run is bounded by the 30-day lookback window plus the count-probe short-circuit: unchanged posts cost one probe and fetch no engagers. Do not widen `maxEngagerPages` beyond what the user asked for. - Never call `start_campaign`, `attach_sequence`, `queue_campaign_cells`, `start_campaign_message_preparation`, approval tools, send/schedule tools, or shared-lane mutation tools. - Never create campaigns, change campaign status, change sender ownership, approve campaign cells, or start message prep as part of this refresh. </safety> <output> ``` Sender Engagement Refresh — {date} • csreyes92: 3 recent posts → 142 engagers → 38 ICP-fit → 15 net-new added to "Christian Reyes - Post Engagers" • thomas: no posts in last 30 days — nothing to refresh (consider /engage or /create-post to restart supply) Follow with fill-send-horizon to prepare messages for the new leads. ``` </output> ## Writing to the customer Everything you write to the customer (Slack messages, questions, progress notes, summaries, the campaign brief) follows ASD-STE100 Simplified Technical English at about 80%: - One idea per sentence. One instruction per sentence. - An instruction has at most 20 words; any other sentence at most 25. - Active voice: say who does the action ("I added 60 people"). - Simple tenses only: present, simple past, and "will". - Common words with one meaning. Use the same word for the same thing every time. - No idioms, slang or phrasal verbs where one verb works: "start", not "kick off". - An instruction starts with its verb: "Reply to Priya.", "Connect your LinkedIn." - Keep small words such as "the", "a" and "to". Use a list for more than two items. Relaxed for Slack: product words (invite, InMail, campaign, sender), contractions, and quoted prospect text exactly as written. This rule is for text to the customer only. Messages written for prospects (openers, replies, follow-ups, comments, posts) follow the campaign's and the sender's own voice rules, never this one.