@sellable/install 0.1.195 → 0.1.197
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" },
|
|
@@ -618,6 +620,9 @@ const CREATE_CAMPAIGN_ALLOWED_TOOLS = [
|
|
|
618
620
|
"mcp__sellable__select_campaign_cells",
|
|
619
621
|
"mcp__sellable__queue_campaign_cells",
|
|
620
622
|
"mcp__sellable__wait_for_campaign_processing",
|
|
623
|
+
"mcp__sellable__start_prepare_campaign_messages",
|
|
624
|
+
"mcp__sellable__get_prepare_campaign_messages_status",
|
|
625
|
+
"mcp__sellable__cancel_prepare_campaign_messages",
|
|
621
626
|
"mcp__sellable__revise_message_template_and_rerun",
|
|
622
627
|
"mcp__sellable__update_campaign_brief",
|
|
623
628
|
"mcp__sellable__update_campaign",
|
|
@@ -1196,6 +1201,40 @@ then retry \`get_subskill_prompt\`.
|
|
|
1196
1201
|
`;
|
|
1197
1202
|
}
|
|
1198
1203
|
|
|
1204
|
+
function createAbTestSkillMd() {
|
|
1205
|
+
try {
|
|
1206
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
1207
|
+
const templatePath = join(
|
|
1208
|
+
here,
|
|
1209
|
+
"..",
|
|
1210
|
+
"skill-templates",
|
|
1211
|
+
"create-ab-test.md"
|
|
1212
|
+
);
|
|
1213
|
+
if (existsSync(templatePath)) {
|
|
1214
|
+
return readFileSync(templatePath, "utf8");
|
|
1215
|
+
}
|
|
1216
|
+
} catch {
|
|
1217
|
+
// fall through to hardcoded fallback below
|
|
1218
|
+
}
|
|
1219
|
+
return `---
|
|
1220
|
+
name: create-ab-test
|
|
1221
|
+
description: Create a Sellable campaign A/B test from a clean source lead list.
|
|
1222
|
+
visibility: public
|
|
1223
|
+
allowed-tools:
|
|
1224
|
+
- mcp__sellable__get_auth_status
|
|
1225
|
+
- mcp__sellable__get_active_workspace
|
|
1226
|
+
- mcp__sellable__get_campaign
|
|
1227
|
+
- mcp__sellable__prepare_campaign_ab_test
|
|
1228
|
+
- mcp__sellable__load_csv_linkedin_leads
|
|
1229
|
+
- mcp__sellable__wait_for_lead_list_ready
|
|
1230
|
+
---
|
|
1231
|
+
|
|
1232
|
+
# Sellable Create A/B Test
|
|
1233
|
+
|
|
1234
|
+
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\`.
|
|
1235
|
+
`;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1199
1238
|
function genericSellableSkillMd({ name, title, description }) {
|
|
1200
1239
|
return `---
|
|
1201
1240
|
name: ${name}
|
|
@@ -1371,7 +1410,7 @@ then retry \`get_subskill_prompt\`.
|
|
|
1371
1410
|
function createPostSkillMd() {
|
|
1372
1411
|
return `---
|
|
1373
1412
|
name: create-post
|
|
1374
|
-
description: Capture rough LinkedIn post ideas, develop a valuable premise, research current hooks and
|
|
1413
|
+
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.
|
|
1375
1414
|
allowed-tools:
|
|
1376
1415
|
- mcp__sellable__get_auth_status
|
|
1377
1416
|
- mcp__sellable__get_subskill_prompt
|
|
@@ -1382,9 +1421,15 @@ allowed-tools:
|
|
|
1382
1421
|
- mcp__sellable__get_post_idea
|
|
1383
1422
|
- mcp__sellable__list_post_ideas
|
|
1384
1423
|
- mcp__sellable__save_hook_research
|
|
1424
|
+
- mcp__sellable__calculate_linkedin_hook_preview
|
|
1425
|
+
- mcp__sellable__render_linkedin_post_preview
|
|
1385
1426
|
- mcp__sellable__save_post_draft
|
|
1427
|
+
- mcp__sellable__update_post_draft
|
|
1428
|
+
- mcp__sellable__list_post_draft_iterations
|
|
1386
1429
|
- mcp__sellable__get_post_draft
|
|
1387
1430
|
- mcp__sellable__mark_post_published
|
|
1431
|
+
- mcp__sellable__get_published_post
|
|
1432
|
+
- mcp__sellable__update_published_post_metrics
|
|
1388
1433
|
- mcp__sellable__list_published_posts
|
|
1389
1434
|
- mcp__sellable__search_engagement_posts
|
|
1390
1435
|
- mcp__sellable__fetch_linkedin_posts
|
|
@@ -1397,7 +1442,7 @@ allowed-tools:
|
|
|
1397
1442
|
|
|
1398
1443
|
Use this as the customer-facing entrypoint for the Sellable \`create-post\`
|
|
1399
1444
|
workflow. It captures raw LinkedIn post ideas, preserves the user's source
|
|
1400
|
-
wording, researches currently working hooks, extracts
|
|
1445
|
+
wording, researches currently working hooks, extracts audience tension, develops
|
|
1401
1446
|
a premise with story/tension/reader value, validates proof/voice/AI tells, and
|
|
1402
1447
|
saves drafts under \`~/.sellable/content/linkedin/**\`.
|
|
1403
1448
|
|
|
@@ -1633,6 +1678,12 @@ function codexPluginSkills() {
|
|
|
1633
1678
|
skillMd: createCampaignSkillMd(),
|
|
1634
1679
|
soulMd: createCampaignSoulMd(),
|
|
1635
1680
|
},
|
|
1681
|
+
{
|
|
1682
|
+
dir: "sellable-create-ab-test",
|
|
1683
|
+
displayName: "Sellable Create A/B Test",
|
|
1684
|
+
description: "Create clean A/B campaign review copies",
|
|
1685
|
+
skillMd: createAbTestSkillMd(),
|
|
1686
|
+
},
|
|
1636
1687
|
{
|
|
1637
1688
|
dir: "sellable-content",
|
|
1638
1689
|
displayName: "Sellable Content",
|
package/package.json
CHANGED
|
@@ -0,0 +1,99 @@
|
|
|
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 campaign idea and the one variable being tested. A
|
|
28
|
+
source campaign and clean source lead list are both optional: use an existing
|
|
29
|
+
campaign when the user already has one, use a clean source lead list when leads
|
|
30
|
+
are already available, or use only the idea by writing a campaign name and base
|
|
31
|
+
brief for A. The tool creates A first, duplicates A into B, applies the B delta,
|
|
32
|
+
and stops for review. The goal is two review-copy campaigns, not a launched
|
|
33
|
+
campaign.
|
|
34
|
+
|
|
35
|
+
## Required Flow
|
|
36
|
+
|
|
37
|
+
1. Decide the source mode:
|
|
38
|
+
- Existing campaign mode: confirm the source campaign ID or resolve it with
|
|
39
|
+
`get_campaign`.
|
|
40
|
+
- Idea-first mode: write a proper campaign name and base campaign brief from
|
|
41
|
+
the user's idea. If the user also has leads, confirm the clean source
|
|
42
|
+
lead-list ID or use `load_csv_linkedin_leads` first.
|
|
43
|
+
2. Confirm the A/B variable in plain language. Keep variant B as the explicit
|
|
44
|
+
change and leave variant A as the control unless the user names an A change.
|
|
45
|
+
3. If a source lead list is supplied, verify it is clean. A clean source list is
|
|
46
|
+
a lead-list or signal-lead-list table, not the generated campaign workflow
|
|
47
|
+
table.
|
|
48
|
+
4. Call `prepare_campaign_ab_test` with `dryRun: true` first.
|
|
49
|
+
5. Review split counts, duplicate/skipped counts, campaign names, and variant
|
|
50
|
+
brief deltas with the user.
|
|
51
|
+
6. Only after review, call `prepare_campaign_ab_test` without `dryRun` using the
|
|
52
|
+
same `idempotencyKey` if one was returned or supplied.
|
|
53
|
+
7. Return the A and B campaign IDs, split lead-list IDs, counts, and the
|
|
54
|
+
explicit note that both campaigns are `not_started`.
|
|
55
|
+
|
|
56
|
+
## Tool Inputs
|
|
57
|
+
|
|
58
|
+
Use one of these shapes:
|
|
59
|
+
|
|
60
|
+
- Existing campaign mode: pass `sourceCampaignId`, `variantName`,
|
|
61
|
+
`variantBriefDelta`, and any optional split or A-variant fields.
|
|
62
|
+
- Idea-first mode: omit `sourceCampaignId`, pass `campaignName`,
|
|
63
|
+
`campaignBrief`, `variantName`, and `variantBriefDelta`. If a clean lead list
|
|
64
|
+
is available, also pass `sourceLeadListId`; otherwise leave it out. The tool
|
|
65
|
+
creates the A campaign, then duplicates A to create B and applies the B brief
|
|
66
|
+
delta.
|
|
67
|
+
|
|
68
|
+
## Anti-Patterns
|
|
69
|
+
|
|
70
|
+
- Do not call `export_table_csv` from an enriched/generated campaign workflow
|
|
71
|
+
table as the lead source for A/B splitting.
|
|
72
|
+
- Do not reimport workflow output columns such as `ICP Score`, `Passes Rubric`,
|
|
73
|
+
`Generate Message`, `Message`, `Approved`, scheduling, status, result, or
|
|
74
|
+
error columns.
|
|
75
|
+
- Do not use broad workflow-table selectors to split decorated campaign rows.
|
|
76
|
+
- Do not call `start_campaign`, approve launch, attach senders for launch, or
|
|
77
|
+
trigger live sends in this workflow.
|
|
78
|
+
|
|
79
|
+
## Clean Source Fallback
|
|
80
|
+
|
|
81
|
+
If the source campaign has no clean source lead list, or the source list is
|
|
82
|
+
polluted with workflow/output columns, ask for the original CSV or clean source
|
|
83
|
+
list. Use `load_csv_linkedin_leads`; it strips Sellable workflow columns if a
|
|
84
|
+
contaminated CSV is supplied, then creates a clean lead list. If no clean source
|
|
85
|
+
is available, continue in idea-first mode without `sourceLeadListId`.
|
|
86
|
+
|
|
87
|
+
## Output Contract
|
|
88
|
+
|
|
89
|
+
Report:
|
|
90
|
+
|
|
91
|
+
- source campaign ID, or note that the A campaign was created as the source
|
|
92
|
+
campaign when no source campaign was provided
|
|
93
|
+
- source lead-list ID when supplied
|
|
94
|
+
- split strategy and counts when a source lead list was supplied
|
|
95
|
+
- duplicate/skipped lead counts when a source lead list was supplied
|
|
96
|
+
- A review campaign ID and split lead-list ID when supplied
|
|
97
|
+
- B review campaign ID and split lead-list ID when supplied
|
|
98
|
+
- variant difference
|
|
99
|
+
- `launchState: not_started` for both campaigns
|
|
@@ -46,6 +46,9 @@ allowed-tools:
|
|
|
46
46
|
- mcp__sellable__select_campaign_cells
|
|
47
47
|
- mcp__sellable__queue_campaign_cells
|
|
48
48
|
- mcp__sellable__wait_for_campaign_processing
|
|
49
|
+
- mcp__sellable__start_prepare_campaign_messages
|
|
50
|
+
- mcp__sellable__get_prepare_campaign_messages_status
|
|
51
|
+
- mcp__sellable__cancel_prepare_campaign_messages
|
|
49
52
|
- mcp__sellable__revise_message_template_and_rerun
|
|
50
53
|
- mcp__sellable__update_campaign_brief
|
|
51
54
|
- mcp__sellable__update_campaign
|
|
@@ -89,6 +92,18 @@ When filters are chosen, save rubrics, get filter approval, then wait for
|
|
|
89
92
|
message-template approval before enrichment/filtering or Generate Message cells.
|
|
90
93
|
After filter approval, Filter Leads should show `Filters saved + waiting for
|
|
91
94
|
message approval` until the template is approved.
|
|
95
|
+
After message approval, use `start_prepare_campaign_messages` for target-ready
|
|
96
|
+
message preparation such as "prepare 100 messages, checking up to 300 rows".
|
|
97
|
+
Treat `campaignId` as `CampaignOffer.id`, keep the default
|
|
98
|
+
`approvalMode:"mark_ready"` unless the user explicitly asks to flip Approved
|
|
99
|
+
cells, and poll `get_prepare_campaign_messages_status` for checked rows,
|
|
100
|
+
prepared/approved count, target, row budget remaining, and stop reason. Low
|
|
101
|
+
level selector/queue tools are diagnostics and recovery only for this lane. If
|
|
102
|
+
the user asks to stop preparation, the target is wrong, or status shows the
|
|
103
|
+
wrong campaign/table, call `cancel_prepare_campaign_messages`; otherwise do not
|
|
104
|
+
cancel a healthy prepare run.
|
|
105
|
+
Never call `start_campaign` from Prepare Messages; final launch remains a
|
|
106
|
+
separate explicit user greenlight.
|
|
92
107
|
Use Template is the default message path; AI Generated is only an explicit
|
|
93
108
|
opt-out.
|
|
94
109
|
|
|
@@ -109,6 +124,22 @@ page before importing, call `list_dnc_entries`. Confirm the active workspace
|
|
|
109
124
|
name and ID in the response before any write. This is Sellable's workspace DNC
|
|
110
125
|
list used by DNC Check.
|
|
111
126
|
|
|
127
|
+
## A/B Campaign Requests
|
|
128
|
+
|
|
129
|
+
If the user explicitly asks to create an A/B test, split an existing campaign
|
|
130
|
+
into variants, duplicate a campaign for copy testing, or compare two campaign
|
|
131
|
+
message approaches from the same source list, route them to
|
|
132
|
+
`create-ab-test` instead of improvising inside this create-campaign workflow.
|
|
133
|
+
|
|
134
|
+
Workflow/campaign table exports are decorated outputs for operator review and
|
|
135
|
+
debugging. They are not source lead lists for A/B splitting or campaign
|
|
136
|
+
duplication. Do not use `export_table_csv` from an enriched/generated campaign
|
|
137
|
+
table and then reimport it as leads. If the user only has a contaminated CSV,
|
|
138
|
+
`load_csv_linkedin_leads` strips Sellable workflow columns such as `ICP Score`,
|
|
139
|
+
`Passes Rubric`, `Generate Message`, `Message`, and `Approved`, but the
|
|
140
|
+
preferred A/B path is the dedicated `create-ab-test` workflow using
|
|
141
|
+
`prepare_campaign_ab_test`.
|
|
142
|
+
|
|
112
143
|
## Opening Turn Contract
|
|
113
144
|
|
|
114
145
|
On the first visible response after this skill is invoked, do not narrate
|
|
@@ -939,7 +970,8 @@ updates.
|
|
|
939
970
|
observation state,
|
|
940
971
|
`auto-execute-messaging` after at least one row passes and initial campaign-row
|
|
941
972
|
messages are being generated or reviewed, `awaiting-user-greenlight` only
|
|
942
|
-
after generated campaign-row messages are approved
|
|
973
|
+
after generated campaign-row messages are approved and the Prepare Messages
|
|
974
|
+
job has reported compact checked/prepared/stop status, `settings` for sender
|
|
943
975
|
selection, `sequence` after sender attach, and `send` once the recommended
|
|
944
976
|
sequence is attached. Do not advance the step backward.
|
|
945
977
|
7. Keep `selectedLeadListId` as the source list and `workflowTableId` as the
|