@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`
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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
|
@@ -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
|