@sellable/install 0.1.194 → 0.1.196

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 CHANGED
@@ -70,15 +70,18 @@ source-scout agents.
70
70
  Use the same public entrypoints in both hosts:
71
71
 
72
72
  - Claude Code: `/sellable:create-campaign`
73
+ - Claude Code: `/sellable:create-ab-test`
73
74
  - Claude Code: `/sellable:foundation`
74
75
  - Claude Code: `/sellable:content`
75
76
  - Claude Code: `/sellable:create-post`
76
77
  - Codex: `$sellable:create-campaign`
78
+ - Codex: `$sellable:create-ab-test`
77
79
  - Codex: `$sellable:foundation`
78
80
  - Codex: `$sellable:content`
79
81
  - Codex: `$sellable:create-post`
80
82
  - Codex Desktop plugin: `sellable@sellable`
81
83
  - Codex visible skill: `Sellable Create Campaign`
84
+ - Codex visible skill: `Sellable Create A/B Test`
82
85
  - Codex visible skill: `Sellable Foundation`
83
86
  - Codex visible skill: `Sellable Content`
84
87
  - Codex visible skill: `Sellable Create Post`
@@ -180,6 +180,7 @@ function printCreateCommandHint() {
180
180
  console.log("");
181
181
  printAgentBox("Using Claude Code?", "claude", [
182
182
  { label: "Campaign", command: "/sellable:create-campaign" },
183
+ { label: "A/B Test", command: "/sellable:create-ab-test" },
183
184
  { label: "Foundation", command: "/sellable:foundation" },
184
185
  { label: "Content", command: "/sellable:content" },
185
186
  { label: "Post", command: "/sellable:create-post" },
@@ -188,6 +189,7 @@ function printCreateCommandHint() {
188
189
  console.log("");
189
190
  printAgentBox("Using Codex?", "codex", [
190
191
  { label: "Campaign", command: "$sellable:create-campaign" },
192
+ { label: "A/B Test", command: "$sellable:create-ab-test" },
191
193
  { label: "Foundation", command: "$sellable:foundation" },
192
194
  { label: "Content", command: "$sellable:content" },
193
195
  { label: "Post", command: "$sellable:create-post" },
@@ -601,6 +603,8 @@ const CREATE_CAMPAIGN_ALLOWED_TOOLS = [
601
603
  "mcp__sellable__search_prospeo",
602
604
  "mcp__sellable__search_prospeo_companies",
603
605
  "mcp__sellable__confirm_prospeo_company_accounts",
606
+ "mcp__sellable__search_harvest_jobs",
607
+ "mcp__sellable__confirm_harvest_job_companies",
604
608
  "mcp__sellable__search_signals",
605
609
  "mcp__sellable__fetch_post_engagers",
606
610
  "mcp__sellable__enrich_with_prospeo",
@@ -1194,6 +1198,40 @@ then retry \`get_subskill_prompt\`.
1194
1198
  `;
1195
1199
  }
1196
1200
 
1201
+ function createAbTestSkillMd() {
1202
+ try {
1203
+ const here = dirname(fileURLToPath(import.meta.url));
1204
+ const templatePath = join(
1205
+ here,
1206
+ "..",
1207
+ "skill-templates",
1208
+ "create-ab-test.md"
1209
+ );
1210
+ if (existsSync(templatePath)) {
1211
+ return readFileSync(templatePath, "utf8");
1212
+ }
1213
+ } catch {
1214
+ // fall through to hardcoded fallback below
1215
+ }
1216
+ return `---
1217
+ name: create-ab-test
1218
+ description: Create a Sellable campaign A/B test from a clean source lead list.
1219
+ visibility: public
1220
+ allowed-tools:
1221
+ - mcp__sellable__get_auth_status
1222
+ - mcp__sellable__get_active_workspace
1223
+ - mcp__sellable__get_campaign
1224
+ - mcp__sellable__prepare_campaign_ab_test
1225
+ - mcp__sellable__load_csv_linkedin_leads
1226
+ - mcp__sellable__wait_for_lead_list_ready
1227
+ ---
1228
+
1229
+ # Sellable Create A/B Test
1230
+
1231
+ Use \`prepare_campaign_ab_test\` to create clean A/B split lead lists and review-copy campaigns. Do not call \`export_table_csv\` from generated campaign workflow tables as lead source data, and do not call \`start_campaign\`.
1232
+ `;
1233
+ }
1234
+
1197
1235
  function genericSellableSkillMd({ name, title, description }) {
1198
1236
  return `---
1199
1237
  name: ${name}
@@ -1369,7 +1407,7 @@ then retry \`get_subskill_prompt\`.
1369
1407
  function createPostSkillMd() {
1370
1408
  return `---
1371
1409
  name: create-post
1372
- description: Capture rough LinkedIn post ideas, develop a valuable premise, research current hooks and market beliefs, then save validated drafts in the user's voice.
1410
+ description: Capture rough LinkedIn post ideas, develop a valuable premise, research current hooks and audience tension, then save validated drafts in the user's voice.
1373
1411
  allowed-tools:
1374
1412
  - mcp__sellable__get_auth_status
1375
1413
  - mcp__sellable__get_subskill_prompt
@@ -1380,9 +1418,15 @@ allowed-tools:
1380
1418
  - mcp__sellable__get_post_idea
1381
1419
  - mcp__sellable__list_post_ideas
1382
1420
  - mcp__sellable__save_hook_research
1421
+ - mcp__sellable__calculate_linkedin_hook_preview
1422
+ - mcp__sellable__render_linkedin_post_preview
1383
1423
  - mcp__sellable__save_post_draft
1424
+ - mcp__sellable__update_post_draft
1425
+ - mcp__sellable__list_post_draft_iterations
1384
1426
  - mcp__sellable__get_post_draft
1385
1427
  - mcp__sellable__mark_post_published
1428
+ - mcp__sellable__get_published_post
1429
+ - mcp__sellable__update_published_post_metrics
1386
1430
  - mcp__sellable__list_published_posts
1387
1431
  - mcp__sellable__search_engagement_posts
1388
1432
  - mcp__sellable__fetch_linkedin_posts
@@ -1395,7 +1439,7 @@ allowed-tools:
1395
1439
 
1396
1440
  Use this as the customer-facing entrypoint for the Sellable \`create-post\`
1397
1441
  workflow. It captures raw LinkedIn post ideas, preserves the user's source
1398
- wording, researches currently working hooks, extracts market beliefs, develops
1442
+ wording, researches currently working hooks, extracts audience tension, develops
1399
1443
  a premise with story/tension/reader value, validates proof/voice/AI tells, and
1400
1444
  saves drafts under \`~/.sellable/content/linkedin/**\`.
1401
1445
 
@@ -1631,6 +1675,12 @@ function codexPluginSkills() {
1631
1675
  skillMd: createCampaignSkillMd(),
1632
1676
  soulMd: createCampaignSoulMd(),
1633
1677
  },
1678
+ {
1679
+ dir: "sellable-create-ab-test",
1680
+ displayName: "Sellable Create A/B Test",
1681
+ description: "Create clean A/B campaign review copies",
1682
+ skillMd: createAbTestSkillMd(),
1683
+ },
1634
1684
  {
1635
1685
  dir: "sellable-content",
1636
1686
  displayName: "Sellable Content",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.194",
3
+ "version": "0.1.196",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: create-ab-test
3
+ description: Create a Sellable campaign A/B test from a clean source lead list.
4
+ visibility: public
5
+ allowed-tools:
6
+ - mcp__sellable__get_auth_status
7
+ - mcp__sellable__get_active_workspace
8
+ - mcp__sellable__get_campaign
9
+ - mcp__sellable__get_campaign_context
10
+ - mcp__sellable__get_campaign_navigation_state
11
+ - mcp__sellable__get_campaign_messages_preview
12
+ - mcp__sellable__prepare_campaign_ab_test
13
+ - mcp__sellable__load_csv_linkedin_leads
14
+ - mcp__sellable__wait_for_lead_list_ready
15
+ - mcp__sellable__get_table_rows
16
+ - mcp__sellable__get_rows_minimal
17
+ ---
18
+
19
+ # Sellable Create A/B Test
20
+
21
+ Use this workflow when the user asks to create an A/B campaign test, split a
22
+ campaign into variants, duplicate a campaign for copy testing, or compare two
23
+ campaign-message approaches from the same source list.
24
+
25
+ ## Opening Contract
26
+
27
+ Start by identifying the source campaign, the one variable being tested, and
28
+ the clean source lead origin. Then prepare the split and stop for review. The
29
+ goal is two review-copy campaigns with clean split source lists, not a launched
30
+ campaign.
31
+
32
+ ## Required Flow
33
+
34
+ 1. Confirm the source campaign ID or resolve it with `get_campaign`.
35
+ 2. Confirm the A/B variable in plain language. Keep variant B as the explicit
36
+ change and leave variant A as the control unless the user names an A change.
37
+ 3. Verify the campaign has a clean source lead list. A clean source list is a
38
+ lead-list table, not the generated campaign workflow table.
39
+ 4. Call `prepare_campaign_ab_test` with `dryRun: true` first.
40
+ 5. Review split counts, duplicate/skipped counts, campaign names, and variant
41
+ brief deltas with the user.
42
+ 6. Only after review, call `prepare_campaign_ab_test` without `dryRun` using the
43
+ same `idempotencyKey` if one was returned or supplied.
44
+ 7. Return the A and B campaign IDs, split lead-list IDs, counts, and the
45
+ explicit note that both campaigns are `not_started`.
46
+
47
+ ## Anti-Patterns
48
+
49
+ - Do not call `export_table_csv` from an enriched/generated campaign workflow
50
+ table as the lead source for A/B splitting.
51
+ - Do not reimport workflow output columns such as `ICP Score`, `Passes Rubric`,
52
+ `Generate Message`, `Message`, `Approved`, scheduling, status, result, or
53
+ error columns.
54
+ - Do not use broad workflow-table selectors to split decorated campaign rows.
55
+ - Do not call `start_campaign`, approve launch, attach senders for launch, or
56
+ trigger live sends in this workflow.
57
+
58
+ ## Clean Source Fallback
59
+
60
+ If the source campaign has no clean source lead list, or the source list is
61
+ polluted with workflow/output columns, ask for the original CSV or clean source
62
+ list. Use `load_csv_linkedin_leads`; it strips Sellable workflow columns if a
63
+ contaminated CSV is supplied, then creates a clean lead list. After the clean
64
+ source is confirmed, retry `prepare_campaign_ab_test`.
65
+
66
+ ## Output Contract
67
+
68
+ Report:
69
+
70
+ - source campaign ID
71
+ - source lead-list ID
72
+ - split strategy and counts
73
+ - duplicate/skipped lead counts
74
+ - A review campaign ID and split lead-list ID
75
+ - B review campaign ID and split lead-list ID
76
+ - variant difference
77
+ - `launchState: not_started` for both campaigns
@@ -29,6 +29,8 @@ allowed-tools:
29
29
  - mcp__sellable__search_prospeo
30
30
  - mcp__sellable__search_prospeo_companies
31
31
  - mcp__sellable__confirm_prospeo_company_accounts
32
+ - mcp__sellable__search_harvest_jobs
33
+ - mcp__sellable__confirm_harvest_job_companies
32
34
  - mcp__sellable__search_signals
33
35
  - mcp__sellable__fetch_post_engagers
34
36
  - mcp__sellable__enrich_with_prospeo
@@ -107,6 +109,22 @@ page before importing, call `list_dnc_entries`. Confirm the active workspace
107
109
  name and ID in the response before any write. This is Sellable's workspace DNC
108
110
  list used by DNC Check.
109
111
 
112
+ ## A/B Campaign Requests
113
+
114
+ If the user explicitly asks to create an A/B test, split an existing campaign
115
+ into variants, duplicate a campaign for copy testing, or compare two campaign
116
+ message approaches from the same source list, route them to
117
+ `create-ab-test` instead of improvising inside this create-campaign workflow.
118
+
119
+ Workflow/campaign table exports are decorated outputs for operator review and
120
+ debugging. They are not source lead lists for A/B splitting or campaign
121
+ duplication. Do not use `export_table_csv` from an enriched/generated campaign
122
+ table and then reimport it as leads. If the user only has a contaminated CSV,
123
+ `load_csv_linkedin_leads` strips Sellable workflow columns such as `ICP Score`,
124
+ `Passes Rubric`, `Generate Message`, `Message`, and `Approved`, but the
125
+ preferred A/B path is the dedicated `create-ab-test` workflow using
126
+ `prepare_campaign_ab_test`.
127
+
110
128
  ## Opening Turn Contract
111
129
 
112
130
  On the first visible response after this skill is invoked, do not narrate
@@ -227,6 +245,14 @@ are likely. Sales Nav is useful for recent LinkedIn activity, role/title
227
245
  precision, and referral paths, but it does not provide hiring-by-role filters;
228
246
  say that distinction plainly in the source-plan gate.
229
247
 
248
+ When the brief asks for current LinkedIn job-post intent, such as companies
249
+ hiring Power BI developers this month, use Harvest jobs as the account source:
250
+ `search_harvest_jobs -> confirm_harvest_job_companies -> search_prospeo`.
251
+ First write and review the Harvest job artifact. Then confirm selected Harvest
252
+ job IDs into a `domainFilterId`; Prospeo remains the people-search provider.
253
+ Do not paste LinkedIn company URLs as domains. Do not fetch full job details for
254
+ every search row by default; selected batches only.
255
+
230
256
  For company lookalikes, best-customer lookalikes, "companies like X",
231
257
  lookalike accounts, companies that use AI, companies with API/SSO/Chrome
232
258
  extension, news/award/integration/key-customer filters, or account discovery