@sellable/install 0.1.133 → 0.1.135
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/bin/sellable-install.mjs +44 -40
- package/package.json +1 -1
- package/skill-templates/create-campaign.md +62 -65
package/bin/sellable-install.mjs
CHANGED
|
@@ -714,15 +714,23 @@ to the campaign yet. The gate should say:
|
|
|
714
714
|
approves me to look for the best places to find buyers. I won't add anyone
|
|
715
715
|
yet."
|
|
716
716
|
|
|
717
|
+
After brief approval, introduce the step in plain customer language: "Brief
|
|
718
|
+
approved. Next, we'll choose where to find buyers. I won't add anyone yet."
|
|
719
|
+
Do not say "lead-source scouting", "source scouting", or "not importing leads"
|
|
720
|
+
in the customer-facing transition.
|
|
721
|
+
Use this vocabulary ladder: "buyers" means the target market; "people to
|
|
722
|
+
check" means raw reactions/comments before fit is known; "prospects" means
|
|
723
|
+
likely usable people after fit; "leads" means campaign rows.
|
|
724
|
+
|
|
717
725
|
Use a customer-facing shape like:
|
|
718
726
|
|
|
719
727
|
\`\`\`text
|
|
720
728
|
## Find Buyers Plan
|
|
721
729
|
|
|
722
730
|
I recommend starting with people already talking on LinkedIn about [plain
|
|
723
|
-
topic]. That should help us find
|
|
731
|
+
topic]. That should help us find people who already care about [plain problem].
|
|
724
732
|
|
|
725
|
-
I'll check whether there are enough
|
|
733
|
+
I'll check whether there are enough likely prospects there. If not, I'll try
|
|
726
734
|
[plain fallback] next.
|
|
727
735
|
|
|
728
736
|
Approving this means I can look for the best places to find buyers. I won't add
|
|
@@ -733,7 +741,8 @@ Do not surface blanket source heuristics as product copy. Make the
|
|
|
733
741
|
recommendation specific to the campaign. If LinkedIn engagement is recommended,
|
|
734
742
|
name the exact post themes you will search in plain language, such as "Power BI
|
|
735
743
|
dashboards they don't trust" or "teams trying to agree on the right KPIs."
|
|
736
|
-
Avoid using "Signal Discovery", "source scouting", "
|
|
744
|
+
Avoid using "Signal Discovery", "lead-source scouting", "source scouting",
|
|
745
|
+
"lane", "provider",
|
|
737
746
|
"precision/scale tradeoff", "evidence quality", "pilot volume", "workflow
|
|
738
747
|
pain", or "ICP" in customer-facing chat; those are internal labels. If relevant public
|
|
739
748
|
conversations look unlikely, recommend the specific Sales Nav or Prospeo path
|
|
@@ -758,12 +767,12 @@ precision, and referral paths, but it does not provide hiring-by-role filters;
|
|
|
758
767
|
say that distinction plainly in the source-plan gate.
|
|
759
768
|
|
|
760
769
|
After scouting, ask for a second approval on the concrete source action. For
|
|
761
|
-
LinkedIn engagement (\`signal-discovery\` internally),
|
|
762
|
-
posts
|
|
763
|
-
|
|
770
|
+
LinkedIn engagement (\`signal-discovery\` internally), use plain language:
|
|
771
|
+
selected posts, people we can check, likely prospects, what the first
|
|
772
|
+
review will inspect, cleanup risk, and fallback. N must be the smallest
|
|
764
773
|
right-content post set that clears the source target, not the default 3
|
|
765
774
|
promoted sample posts. For Sales Nav or Prospeo, name the specific approved
|
|
766
|
-
import
|
|
775
|
+
import path and source lead count.
|
|
767
776
|
Do not call \`import_leads\` or \`confirm_lead_list\` until this second approval is
|
|
768
777
|
granted.
|
|
769
778
|
|
|
@@ -782,7 +791,7 @@ the campaign table and return the initial campaign-table execution slice rows.
|
|
|
782
791
|
For campaign-attached Signal Discovery sampling, promote/select the exact posts
|
|
783
792
|
with \`select_promising_posts\` before \`fetch_post_engagers\` so the user can see
|
|
784
793
|
which posts are being sampled in the watched app. The watch guide should say
|
|
785
|
-
that we are
|
|
794
|
+
that we are checking people from these posts to confirm the right people are
|
|
786
795
|
actually engaging and the source is viable.
|
|
787
796
|
|
|
788
797
|
Every approval gate must include live campaign access after the readable inline
|
|
@@ -945,48 +954,44 @@ explicit client prospect identity in the invocation, do one lightweight lookup
|
|
|
945
954
|
first:
|
|
946
955
|
|
|
947
956
|
- LinkedIn profile: call \`mcp__sellable__fetch_linkedin_profile\`.
|
|
948
|
-
-
|
|
949
|
-
|
|
957
|
+
- Non-profile URLs or company-page inputs are not enough to start this flow; ask
|
|
958
|
+
again for the person's LinkedIn profile URL.
|
|
950
959
|
- Existing client prospect id: use it directly and do one company/profile lookup
|
|
951
|
-
only if a URL
|
|
960
|
+
only if a LinkedIn profile URL is also available.
|
|
952
961
|
|
|
953
962
|
Then summarize what you found in one or two lines and ask the user to confirm
|
|
954
|
-
the current company/focus before continuing
|
|
955
|
-
|
|
963
|
+
the current company/focus before continuing. Do not mention connected sender
|
|
964
|
+
availability in this confirmation.
|
|
956
965
|
|
|
957
966
|
If the user did not provide the launch identity, ask in normal chat for the
|
|
958
|
-
LinkedIn profile URL
|
|
959
|
-
|
|
967
|
+
LinkedIn profile URL. Do not ask them to choose an input type with the structured
|
|
968
|
+
question tool:
|
|
960
969
|
|
|
961
970
|
\`\`\`text
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
What is your LinkedIn profile URL? If you do not have it handy, send your
|
|
965
|
-
company website instead. I’ll research the person and company from that, then
|
|
966
|
-
ask you to correct anything stale before we pick the target, offer, proof, and
|
|
967
|
-
lead source.
|
|
971
|
+
What is your LinkedIn profile URL?
|
|
968
972
|
\`\`\`
|
|
969
973
|
|
|
970
|
-
After the user pastes a URL
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
974
|
+
After the user pastes a LinkedIn profile URL, call
|
|
975
|
+
\`mcp__sellable__fetch_linkedin_profile\` and infer the current or most recent
|
|
976
|
+
company from the profile. If they paste a non-profile URL or company page
|
|
977
|
+
instead, ask again for the person's LinkedIn profile URL. Retain the profile URL as
|
|
978
|
+
\`senderLinkedinUrl\` for \`create_campaign\`; if a \`clientProspectId\` is available,
|
|
979
|
+
pass that instead.
|
|
976
980
|
|
|
977
|
-
After the user confirms the company/focus,
|
|
978
|
-
|
|
979
|
-
strategy hardens:
|
|
981
|
+
After the user confirms the company/focus, ask the full setup intake before
|
|
982
|
+
inferred strategy hardens:
|
|
980
983
|
|
|
981
984
|
\`\`\`text
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
+
Who should we target first?
|
|
986
|
+
What offer should this campaign lead with?
|
|
987
|
+
What is the strongest credibility signal we can lead with?
|
|
988
|
+
How should we find prospects: find prospects for me, use a CSV of LinkedIn
|
|
989
|
+
profiles, or use a CSV of company domains?
|
|
985
990
|
\`\`\`
|
|
986
991
|
|
|
987
992
|
The setup questions should use the confirmed company context so they do not feel
|
|
988
|
-
generic. When you present a recommendation, introduce it as based on
|
|
989
|
-
research you just did and keep it editable.
|
|
993
|
+
generic. When you present a researched recommendation, introduce it as based on
|
|
994
|
+
the research you just did and keep it editable.
|
|
990
995
|
|
|
991
996
|
Before the identity gate, use this customer-facing shape:
|
|
992
997
|
|
|
@@ -1371,9 +1376,8 @@ any leads are imported or anything can send.
|
|
|
1371
1376
|
Good identity setup:
|
|
1372
1377
|
|
|
1373
1378
|
\`\`\`text
|
|
1374
|
-
I’ll ask for the LinkedIn profile URL first
|
|
1375
|
-
|
|
1376
|
-
anything stale before we pick the target, offer, proof, and lead source.
|
|
1379
|
+
I’ll ask for the LinkedIn profile URL first. Then we’ll confirm who to target,
|
|
1380
|
+
what to offer, what proof to lead with, and how to find prospects.
|
|
1377
1381
|
\`\`\`
|
|
1378
1382
|
|
|
1379
1383
|
Bad:
|
|
@@ -1386,8 +1390,8 @@ Better:
|
|
|
1386
1390
|
|
|
1387
1391
|
\`\`\`text
|
|
1388
1392
|
I found Christian Reyes connected here. Is that you, and is this campaign for
|
|
1389
|
-
Sellable? If not,
|
|
1390
|
-
|
|
1393
|
+
Sellable? If not, send the LinkedIn profile URL for the person this campaign is
|
|
1394
|
+
for.
|
|
1391
1395
|
\`\`\`
|
|
1392
1396
|
|
|
1393
1397
|
Bad:
|
package/package.json
CHANGED
|
@@ -110,8 +110,8 @@ clear business decisions, tradeoffs, and approval gates. Use product language:
|
|
|
110
110
|
Approval and safety copy should be tasteful. State what the current approval
|
|
111
111
|
covers once, in one short sentence, then move on. Do not append repeated
|
|
112
112
|
"nothing starts / no leads import / no sending" disclaimers to routine progress
|
|
113
|
-
updates. Use customer-facing gate language like "Next, we'll
|
|
114
|
-
|
|
113
|
+
updates. Use customer-facing gate language like "Next, we'll choose where to
|
|
114
|
+
find buyers" or "Next gate: selected-post scrape" instead
|
|
115
115
|
of internal terms like "source scouting" or long negative lists.
|
|
116
116
|
|
|
117
117
|
When explaining source decisions, show the concrete counts behind the
|
|
@@ -143,15 +143,23 @@ to the campaign yet. The gate should say:
|
|
|
143
143
|
approves me to look for the best places to find buyers. I won't add anyone
|
|
144
144
|
yet."
|
|
145
145
|
|
|
146
|
+
After brief approval, introduce the step in plain customer language: "Brief
|
|
147
|
+
approved. Next, we'll choose where to find buyers. I won't add anyone yet."
|
|
148
|
+
Do not say "lead-source scouting", "source scouting", or "not importing leads"
|
|
149
|
+
in the customer-facing transition.
|
|
150
|
+
Use this vocabulary ladder: "buyers" means the target market; "people to
|
|
151
|
+
check" means raw reactions/comments before fit is known; "prospects" means
|
|
152
|
+
likely usable people after fit; "leads" means campaign rows.
|
|
153
|
+
|
|
146
154
|
Use a customer-facing shape like:
|
|
147
155
|
|
|
148
156
|
```text
|
|
149
157
|
## Find Buyers Plan
|
|
150
158
|
|
|
151
159
|
I recommend starting with people already talking on LinkedIn about [plain
|
|
152
|
-
topic]. That should help us find
|
|
160
|
+
topic]. That should help us find people who already care about [plain problem].
|
|
153
161
|
|
|
154
|
-
I'll check whether there are enough
|
|
162
|
+
I'll check whether there are enough likely prospects there. If not, I'll try
|
|
155
163
|
[plain fallback] next.
|
|
156
164
|
|
|
157
165
|
Approving this means I can look for the best places to find buyers. I won't add
|
|
@@ -162,7 +170,8 @@ Do not surface blanket source heuristics as product copy. Make the
|
|
|
162
170
|
recommendation specific to the campaign. If LinkedIn engagement is recommended,
|
|
163
171
|
name the exact post themes you will search in plain language, such as "Power BI
|
|
164
172
|
dashboards they don't trust" or "teams trying to agree on the right KPIs."
|
|
165
|
-
Avoid using "Signal Discovery", "source scouting", "
|
|
173
|
+
Avoid using "Signal Discovery", "lead-source scouting", "source scouting",
|
|
174
|
+
"lane", "provider",
|
|
166
175
|
"precision/scale tradeoff", "evidence quality", "pilot volume", "workflow
|
|
167
176
|
pain", or "ICP" in customer-facing chat; those are internal labels. If relevant public
|
|
168
177
|
conversations look unlikely, recommend the specific Sales Nav or Prospeo path
|
|
@@ -214,29 +223,26 @@ For LinkedIn engagement, the customer-facing approval card must use the exact
|
|
|
214
223
|
action shape "Approve scraping N recommended LinkedIn posts?" and the chat
|
|
215
224
|
summary should be a compact `## Source Recommendation` block with:
|
|
216
225
|
|
|
217
|
-
- goal: about 300
|
|
218
|
-
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
activity instead of scraping noisy engagers. Do not use the 10% floor as the
|
|
226
|
+
- goal: about 300 likely prospects
|
|
227
|
+
- people to check: use sample math first. If there is no stronger sample, use
|
|
228
|
+
about 1,500 people who reacted or commented from the 20% starting estimate.
|
|
229
|
+
- good-sign floor: keep LinkedIn posts only when at least 10% of the first
|
|
230
|
+
sample looks like real prospects; below that, move to active LinkedIn profiles
|
|
231
|
+
instead of scraping noisy reactions. Do not use the 10% floor as the
|
|
224
232
|
scrape-count denominator when the actual sample rate is higher.
|
|
225
|
-
-
|
|
226
|
-
|
|
227
|
-
- a selected-post table with post author/topic, why it fits,
|
|
228
|
-
|
|
229
|
-
- total
|
|
230
|
-
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
headline-fit rate falls below 10%, or if the source sample is vendor-heavy,
|
|
235
|
-
agency-heavy, or off-ICP
|
|
233
|
+
- first review: after the source list exists, add confirmed source rows to the
|
|
234
|
+
campaign and review the first 15 leads before scaling
|
|
235
|
+
- a selected-post table with post author/topic, why it fits, public activity,
|
|
236
|
+
and people we can check
|
|
237
|
+
- total public activity and likely prospect pool
|
|
238
|
+
- next step: build the source list, add it to the campaign, and review the
|
|
239
|
+
first 15 leads before scaling
|
|
240
|
+
- fallback: switch to active LinkedIn profiles if the first sample is too noisy
|
|
241
|
+
or has too few prospects
|
|
236
242
|
|
|
237
243
|
When the user has not supplied a source and multiple source angles are viable,
|
|
238
244
|
scout those angles as independent branches when the host can actually do it:
|
|
239
|
-
LinkedIn
|
|
245
|
+
LinkedIn posts / people reacting or commenting (internal `signal-discovery`
|
|
240
246
|
provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
|
|
241
247
|
domains, hiring filters, or broad verified-contact expansion when relevant. In
|
|
242
248
|
Codex, explicitly spawn the named custom scouts
|
|
@@ -257,7 +263,7 @@ only an internal approval proof.
|
|
|
257
263
|
For campaign-attached Signal Discovery sampling, promote/select the exact posts
|
|
258
264
|
with `select_promising_posts` before `fetch_post_engagers` so the user can see
|
|
259
265
|
which posts are being sampled in the watched app. The watch guide should say
|
|
260
|
-
that we are
|
|
266
|
+
that we are checking people from these posts to confirm the right people are
|
|
261
267
|
actually engaging and the source is viable.
|
|
262
268
|
|
|
263
269
|
After confirmed source rows exist in the campaign table, use the same registry pattern for
|
|
@@ -445,48 +451,44 @@ explicit client prospect identity in the invocation, do one lightweight lookup
|
|
|
445
451
|
first:
|
|
446
452
|
|
|
447
453
|
- LinkedIn profile: call `mcp__sellable__fetch_linkedin_profile`.
|
|
448
|
-
-
|
|
449
|
-
|
|
454
|
+
- Non-profile URLs or company-page inputs are not enough to start this flow; ask
|
|
455
|
+
again for the person's LinkedIn profile URL.
|
|
450
456
|
- Existing client prospect id: use it directly and do one company/profile lookup
|
|
451
|
-
only if a URL
|
|
457
|
+
only if a LinkedIn profile URL is also available.
|
|
452
458
|
|
|
453
459
|
Then summarize what you found in one or two lines and ask the user to confirm
|
|
454
|
-
the current company/focus before continuing
|
|
455
|
-
|
|
460
|
+
the current company/focus before continuing. Do not mention connected sender
|
|
461
|
+
availability in this confirmation.
|
|
456
462
|
|
|
457
463
|
If the user did not provide the launch identity, ask in normal chat for the
|
|
458
|
-
LinkedIn profile URL
|
|
459
|
-
|
|
464
|
+
LinkedIn profile URL. Do not ask them to choose an input type with the structured
|
|
465
|
+
question tool:
|
|
460
466
|
|
|
461
467
|
```text
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
What is your LinkedIn profile URL? If you do not have it handy, send your
|
|
465
|
-
company website instead. I’ll research the person and company from that, then
|
|
466
|
-
ask you to correct anything stale before we pick the target, offer, proof, and
|
|
467
|
-
lead source.
|
|
468
|
+
What is your LinkedIn profile URL?
|
|
468
469
|
```
|
|
469
470
|
|
|
470
|
-
After the user pastes a URL
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
471
|
+
After the user pastes a LinkedIn profile URL, call
|
|
472
|
+
`mcp__sellable__fetch_linkedin_profile` and infer the current or most recent
|
|
473
|
+
company from the profile. If they paste a non-profile URL or company page
|
|
474
|
+
instead, ask again for the person's LinkedIn profile URL. Retain the profile URL as
|
|
475
|
+
`senderLinkedinUrl` for `create_campaign`; if a `clientProspectId` is available,
|
|
476
|
+
pass that instead.
|
|
476
477
|
|
|
477
|
-
After the user confirms the company/focus,
|
|
478
|
-
|
|
479
|
-
strategy hardens:
|
|
478
|
+
After the user confirms the company/focus, ask the full setup intake before
|
|
479
|
+
inferred strategy hardens:
|
|
480
480
|
|
|
481
481
|
```text
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
Who should we target first?
|
|
483
|
+
What offer should this campaign lead with?
|
|
484
|
+
What is the strongest credibility signal we can lead with?
|
|
485
|
+
How should we find prospects: find prospects for me, use a CSV of LinkedIn
|
|
486
|
+
profiles, or use a CSV of company domains?
|
|
485
487
|
```
|
|
486
488
|
|
|
487
489
|
The setup questions should use the confirmed company context so they do not feel
|
|
488
|
-
generic. When you present a recommendation, introduce it as based on
|
|
489
|
-
research you just did and keep it editable.
|
|
490
|
+
generic. When you present a researched recommendation, introduce it as based on
|
|
491
|
+
the research you just did and keep it editable.
|
|
490
492
|
|
|
491
493
|
### Sufficient Intake Bypass
|
|
492
494
|
|
|
@@ -514,9 +516,9 @@ If the invocation or any later user message explicitly asks for "yolo mode",
|
|
|
514
516
|
me", "use best estimates", or "just run it", enable YOLO mode for the rest of
|
|
515
517
|
the run. Treat YOLO as `interactionMode: "autonomous"` plus an intake policy:
|
|
516
518
|
|
|
517
|
-
- If the campaign subject is missing, ask only for the LinkedIn profile URL
|
|
518
|
-
|
|
519
|
-
|
|
519
|
+
- If the campaign subject is missing, ask only for the LinkedIn profile URL in
|
|
520
|
+
normal chat; do not continue from a non-profile URL and do not ask buyer, offer,
|
|
521
|
+
proof, source, or filter setup questions before the LinkedIn URL.
|
|
520
522
|
- Treat any freeform directions already provided, or added later by the user, as
|
|
521
523
|
operator directions for the rest of the run. If directions conflict, the newest
|
|
522
524
|
user direction wins.
|
|
@@ -675,9 +677,7 @@ updates.
|
|
|
675
677
|
```text
|
|
676
678
|
You're in — {activeWorkspaceName} workspace, ready to roll.
|
|
677
679
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
e.g. https://www.linkedin.com/in/client-handle or https://example.com
|
|
680
|
+
What is your LinkedIn profile URL?
|
|
681
681
|
```
|
|
682
682
|
|
|
683
683
|
- If `isReturningUser === false`, prepend ONE line confirming the new
|
|
@@ -686,17 +686,14 @@ updates.
|
|
|
686
686
|
```text
|
|
687
687
|
You're set up — your {activeWorkspaceName} workspace is ready.
|
|
688
688
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
e.g. https://www.linkedin.com/in/client-handle or https://example.com
|
|
689
|
+
What is your LinkedIn profile URL?
|
|
692
690
|
```
|
|
693
691
|
|
|
694
692
|
No other lines. No "all set", no "signed in", no other acknowledgement.
|
|
695
693
|
|
|
696
|
-
After the user pastes the URL, proceed with the
|
|
697
|
-
setup in the v2 subskill prompt. Resolve
|
|
698
|
-
`fetch_linkedin_profile
|
|
699
|
-
when possible, and mark the client/company research gate with
|
|
694
|
+
After the user pastes the LinkedIn profile URL, proceed with the
|
|
695
|
+
identity-first campaign setup in the v2 subskill prompt. Resolve it with
|
|
696
|
+
`fetch_linkedin_profile` and mark the client/company research gate with
|
|
700
697
|
`complete_sender_research` when that protocol is required.
|
|
701
698
|
|
|
702
699
|
3. If auth is not OK with `error.type === "workspace"` (token valid, no active
|