@sellable/mcp 0.1.258 → 0.1.259

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.
@@ -28,11 +28,10 @@ Worker owns:
28
28
  - tracked-person post fetches
29
29
  - full-text matching by URL/activity ID
30
30
  - duplicate removal
31
- - follower-band and reach-normalized signal scoring
32
31
  - lead-magnet, giveaway, engagement-bait, and off-voice filtering
33
32
  - market belief mapping across kept and rejected examples
34
33
  - premise input extraction: real scenes, observed tensions, reader value, proof gaps
35
- - rendered hook opening measurement
34
+ - hook opening measurement
36
35
  - exact phrase-pattern extraction
37
36
  - body-structure extraction
38
37
  - rejected-example notes
@@ -55,14 +54,11 @@ Research packet:
55
54
  - market belief map: max 8 bullets
56
55
  - controversy candidates: max 8
57
56
  - premise inputs: max 8
58
- - hook reverse-engineering autopsies: max 12
59
57
  - full adapted hook blocks: max 12
60
- - angle territories tested: max 12
61
58
  - exact phrase patterns: max 20
62
59
  - body patterns: max 8
63
60
  - source URLs and author profile URLs
64
- - reach-normalized signal notes
65
- - rendered preview records
61
+ - preview measurements
66
62
  - confidence gaps
67
63
  - save recommendations
68
64
  ```
@@ -78,13 +74,6 @@ Use `mcp__sellable__search_engagement_posts` with practical constraints:
78
74
 
79
75
  - explicit `maxAgeDays: 120` by default so research covers the past 30-120 days, not only this week's posts
80
76
  - tighten to 30-60 days for trend-sensitive topics; widen only when the topic has low volume
81
- - when the user gives a follower range, pass it as `targetFollowerMin` and
82
- `targetFollowerMax` so the tool can expose reach-normalized signals and
83
- prioritize comparable creators
84
- - if a source hook looks promising but follower count is missing, use
85
- `mcp__sellable__fetch_linkedin_profile` on a bounded shortlist before calling
86
- the source a keeper; if profile fetch is unavailable or too slow, mark
87
- `follower_count_unavailable`
88
77
  - high enough engagement to matter
89
78
  - narrow enough to match the idea
90
79
  - enough result depth to see whether a creator has repeated winners, not just one viral outlier
@@ -93,19 +82,14 @@ Record every keyword, filter, search window, page, and result count.
93
82
 
94
83
  ## Weighted Signals
95
84
 
96
- Rank source posts with a weighted signal view. Do not sort by total engagement
97
- alone. Use the numeric score to decide which sources deserve study; do not let
98
- the number choose the final hook by itself.
85
+ Rank source posts with a weighted signal view. Do not sort by total engagement alone.
99
86
 
100
87
  Use this scoring shape:
101
88
 
102
89
  ```text
103
90
  hook_score =
104
91
  topic_fit
105
- + rendered_mobile_preview_strength
106
92
  + hook_clarity
107
- + content_pattern_replicability
108
- + reach_adjusted_evidence
109
93
  + creator_repeat_success
110
94
  + repost_share_strength
111
95
  + comment_quality
@@ -123,135 +107,6 @@ Guidance:
123
107
  - If share or repost data is unavailable, record `repost_data_unavailable` instead of inventing it.
124
108
  - Prefer creators with repeated high-performing posts in the same lane over one-off viral posts.
125
109
 
126
- ## Reach-Normalized Hook Scoring
127
-
128
- Raw engagement is not the clearest signal when source creators have wildly
129
- different audience sizes. A post from a 100k+ follower creator can win on
130
- distribution even when the hook is ordinary. A post from a creator near the
131
- user's follower range that overperforms is a clearer signal that LinkedIn and
132
- readers rewarded the hook/premise.
133
-
134
- This calculation is a source-quality filter, not the final creative decision.
135
- After reach is controlled, the LLM still chooses the hooks to steal based on the
136
- visible hook, rendered first-screen promise, content pattern, premise fit, and
137
- whether the idea can carry without the source creator's distribution.
138
-
139
- When the user gives a target range, default to that range. For example, if the
140
- user says "8k to 20k followers," call `mcp__sellable__search_engagement_posts`
141
- with:
142
-
143
- ```text
144
- targetFollowerMin: 8000
145
- targetFollowerMax: 20000
146
- ```
147
-
148
- If the user gives no range, use the user's known follower count from memory or
149
- ask only when the decision depends on it. If no follower count is available, use
150
- raw engagement as a fallback and mark `target_follower_band_unknown`.
151
-
152
- For every shortlisted source post, record:
153
-
154
- - `authorFollowerCount`
155
- - `targetFollowerBand`
156
- - `followerBandFit`: `in_target_band`, `below_target_band`,
157
- `above_target_band`, or `unknown`
158
- - `engagementPer1kFollowers`
159
- - `weightedEngagementPer1kFollowers`
160
- - `reachAdjustedScore`
161
- - `creatorBaselineMedianEngagement` when repeated posts from that creator are
162
- available
163
- - `baselineLift`: this post's engagement divided by the creator's recent median
164
- engagement in the same lane, or `creator_baseline_unavailable`
165
- - `confidence`: `high`, `medium`, or `low`
166
- - `normalizationNotes`
167
-
168
- Use this Harvest-compatible calculation when follower counts are available:
169
-
170
- ```text
171
- weightedEngagement =
172
- likes
173
- + (comments * 4)
174
- + (shares * 12)
175
-
176
- engagementPer1kFollowers =
177
- totalEngagement / authorFollowerCount * 1000
178
-
179
- weightedEngagementPer1kFollowers =
180
- weightedEngagement / authorFollowerCount * 1000
181
-
182
- reachPenaltyMultiplier =
183
- 1.00 when in target follower band
184
- 0.75 when below target band
185
- 0.65 when above target band but <= 2x target max
186
- 0.35 when above target band but <= 5x target max
187
- 0.15 when above target band and > 5x target max
188
- 0.40 when follower count is unknown
189
-
190
- reachAdjustedScore =
191
- weightedEngagementPer1kFollowers * reachPenaltyMultiplier
192
- ```
193
-
194
- When repeated posts from the same creator are available, calculate:
195
-
196
- ```text
197
- creatorBaselineMedianEngagement =
198
- median weightedEngagement across recent same-lane posts
199
-
200
- baselineLift =
201
- post weightedEngagement / creatorBaselineMedianEngagement
202
- ```
203
-
204
- Use this scoring shape when deciding which hooks to study:
205
-
206
- ```text
207
- hook_score =
208
- topic_fit
209
- + rendered_mobile_preview_strength
210
- + hook_clarity
211
- + same_follower_band_bonus
212
- + weighted_engagement_per_1k_followers
213
- + creator_baseline_lift
214
- + repost_share_strength
215
- + substantive_comment_quality
216
- + creator_repeat_success
217
- - celebrity_reach_penalty
218
- - tiny_sample_penalty
219
- - lead_magnet_penalty
220
- - engagement_bait_penalty
221
- - off_voice_penalty
222
- ```
223
-
224
- Rules:
225
-
226
- - Prefer in-band creators when the hook is strong and the engagement is real.
227
- - Use near-band creators as secondary evidence.
228
- - Penalize creators far above the target range, especially accounts above 5x
229
- the target max or above 100k followers when the target range is 8k-20k.
230
- - Do not automatically reject large-account posts; they can still teach body
231
- structure, topic heat, or category language. Do not treat them as primary hook
232
- proof unless they also overperform their creator baseline.
233
- - Large-account hooks can be selected only when the hook carries without the
234
- creator: the rendered mobile opening is strong, the premise is reusable by the
235
- user, the body pattern does not depend on celebrity authority, and the source
236
- either beats baseline or has unusually high reach-adjusted quality after the
237
- penalty.
238
- - Do not overvalue tiny-account anomalies. Very high engagement per follower
239
- with low absolute engagement is interesting but lower confidence.
240
- - When follower data is unavailable, do not invent it. Mark
241
- `follower_count_unavailable`, lower confidence, and rely more on creator repeat
242
- evidence, repost/share strength, comment quality, and rendered preview quality.
243
- - A source hook is strongest when it is in/near the target follower band, has
244
- real absolute engagement, beats the creator's apparent baseline, has
245
- share/comment quality, and passes rendered mobile preview.
246
-
247
- Final hook selection must explain both:
248
-
249
- - `whyTheHookCarries`: the visible words, specificity, tension, and first-screen
250
- promise that work independent of reach
251
- - `whyTheReachEvidenceIsTrustworthy`: follower-band fit, reach-adjusted score,
252
- baseline lift, share/comment quality, or why a large-account example is only
253
- secondary pattern evidence
254
-
255
110
  Penalize lead-magnet and engagement-bait mechanics unless the user explicitly asks for that style:
256
111
 
257
112
  - `comment "template"` / `comment "guide"` / `comment "playbook"`
@@ -263,104 +118,6 @@ Penalize lead-magnet and engagement-bait mechanics unless the user explicitly as
263
118
  - "like and comment"
264
119
  - broad giveaway framing that makes engagement inflate without proving the hook/body worked
265
120
 
266
- ## Hook Reverse Engineering Autopsy
267
-
268
- For any space or LinkedIn topic, do not stop at "this is a good hook." Reverse
269
- engineer why the opening earned attention, which shape can be reused, and which
270
- parts belong to the source and must not be copied.
271
-
272
- For each keeper source hook, record a `hookAutopsy`:
273
-
274
- ```text
275
- hookAutopsy:
276
- sourceHook: <exact visible opening used for analysis>
277
- renderedFirstScreen: <mobile and desktop visible blocks>
278
- sourceMechanism: <what the hook does structurally>
279
- openLoopType: none | hidden_payoff | contradiction | proof_gap | workflow_reveal | asset_reveal | story_gap
280
- clickQuestion: <the question a reader has before clicking see more>
281
- promisedPayoff: <what the body/video must deliver after the click>
282
- curiosityGap: <what is withheld and why that is fair>
283
- specificityAnchor: <tool, person, number, object, scene, or enemy named>
284
- tensionOpened: <belief, resentment, fear, status, cost, or contradiction>
285
- proofImplied: <what proof the source suggests in the first screen>
286
- whyItWorks: <specific words and structure, not a vibe label>
287
- whyItMightBeInflated: <reach, giveaway, celebrity, outrage, or topic heat>
288
- sourceShapeToKeep: <portable structure, written as a template>
289
- sourceWordsNotToCopy: <phrases, jokes, proof, or context owned by source>
290
- adaptationRule: <how to make it true for the user's idea and voice>
291
- ```
292
-
293
- Good `sourceShapeToKeep` examples:
294
-
295
- - "The best [desired asset] I have right now is not in [default tool]."
296
- - "I gave [system/person] one prompt: [specific request]."
297
- - "[Common vanity metric] is useless until it becomes [business outcome]."
298
- - "I built [familiar workflow] inside [new interface]."
299
- - "Most teams [surface behavior]. Then they miss [hidden opportunity]."
300
-
301
- Bad autopsies:
302
-
303
- - "contrarian hook"
304
- - "strong curiosity"
305
- - "good storytelling"
306
- - "viral format"
307
-
308
- Those labels are allowed only after the concrete shape, click question, and
309
- payoff obligation are recorded.
310
-
311
- ## Angle Exploration Before Drafting
312
-
313
- After selecting a premise, create a hook angle matrix before drafting the post.
314
- This is mandatory when the user asks to nail the hook, study hooks, explore a
315
- space, or write from a specific idea.
316
-
317
- Default matrix:
318
-
319
- - at least 8 angle territories for normal drafting
320
- - at least 12 angle territories when the user asks for "a ton of angles" or
321
- says the hook is the main constraint
322
- - at least 24 generated hooks across those territories for normal drafting
323
- - at least 40 generated hooks when the user explicitly asks to optimize hooks
324
-
325
- Angle territories should be materially different, not synonyms. Use territories
326
- such as:
327
-
328
- - enemy/tool contrast
329
- - hidden asset
330
- - first-person build proof
331
- - workflow reveal
332
- - contrarian category claim
333
- - mistake/confession
334
- - market timing
335
- - customer/operator pain
336
- - asset/free reveal without comment bait
337
- - specific person/company signal
338
- - before/after transformation
339
- - question hook
340
-
341
- For each territory, record:
342
-
343
- ```text
344
- angleTerritory:
345
- name:
346
- sourceShapesUsed:
347
- premiseTensionOpened:
348
- readerValueImplied:
349
- bestHook:
350
- mobileRenderedPreview:
351
- desktopRenderedPreview:
352
- clickQuestion:
353
- payoffAfterFold:
354
- whyThisAngleShouldWin:
355
- whyThisAngleShouldLose:
356
- proofNeeded:
357
- ```
358
-
359
- Do not write the post body until the winning hook territory is chosen. The post
360
- body must then pay off the selected hook quickly. If the best hook says the list
361
- is not in Apollo, the next lines must reveal where it is. If the hook says "I
362
- gave Sellable one prompt," the next lines must show the prompt or the demo.
363
-
364
121
  ## Market Belief Map
365
122
 
366
123
  Before selecting a hook or writing a draft, synthesize a market belief map from
@@ -441,54 +198,24 @@ Measure the visible opening for every shortlisted source post before extracting
441
198
  the hook pattern. This makes the study useful for LinkedIn, not just generally
442
199
  "good writing."
443
200
 
444
- Use `references/linkedin-preview-rendering.md`. LinkedIn does not publish exact
445
- "see more" cutoff rules. Character counts are diagnostics only. A source post
446
- or generated hook is not properly studied until it has a rendered mobile and
447
- desktop preview record.
448
-
449
- Default deterministic renderer for unpublished drafts and research comparison:
201
+ LinkedIn does not publish exact "see more" cutoff rules. Treat these as
202
+ conservative v1 planning budgets:
450
203
 
451
- ```text
452
- cssContractVersion: linkedin-preview-rendering/v1
453
- font size: 14px
454
- line height: 21px
455
- white space: pre-wrap
456
- overflow wrap: break-word
457
- mobile text width: 308px
458
- desktop text width: 582px
459
- review clamp: first 3 rendered text lines
460
- ```
204
+ - `pass`: opening hook is <= 110 chars including newlines, every nonblank line
205
+ is <= 45 chars, and the hook's core point lands before likely truncation.
206
+ - `warn`: opening hook is 111-140 chars including newlines, any nonblank line is
207
+ 46-55 chars, or blank lines create visual-line risk. Blank lines are allowed,
208
+ but they count as physical lines.
209
+ - `fail`: opening hook is > 140 chars including newlines, any nonblank line is
210
+ > 55 chars, or the hook's core point depends on text after likely truncation.
461
211
 
462
- Authenticated LinkedIn feed/composer screenshots are stronger evidence when
463
- available. If a screenshot is used, still record the wrapped lines and verdicts
464
- below so another agent can compare hooks without re-opening LinkedIn.
465
-
466
- Desktop preview has more room, but never let desktop fit compensate for a
467
- mobile `fail`.
212
+ Desktop preview has more room, so record it separately, but never let desktop
213
+ fit compensate for a mobile `fail`.
468
214
 
469
215
  For each source, record:
470
216
 
471
217
  - `sourceTextBasis`: `full_text`, `search_preview`, or `manual_user_source`
472
218
  - `openingTextUsed`
473
- - `renderedPreview`
474
- - `cssContractVersion`
475
- - `mobileRenderedPreviewBlock`
476
- - `desktopRenderedPreviewBlock`
477
- - `mobileRenderedLines`
478
- - `desktopRenderedLines`
479
- - `mobileRenderedLineCount`
480
- - `desktopRenderedLineCount`
481
- - `corePainProofOrCuriosityVisibleMobile`
482
- - `corePainProofOrCuriosityVisibleDesktop`
483
- - `corePointVisibleMobile`
484
- - `corePointVisibleDesktop`
485
- - `intentionalOpenLoop`
486
- - `specificClickQuestionVisible`
487
- - `payoffPlannedImmediatelyAfterClamp`
488
- - `seeMoreClickReason`
489
- - `clickQuestion`
490
- - `payoffAfterFold`
491
- - `pointAfterMobileClamp`
492
219
  - `charCountIncludingNewlines`
493
220
  - `physicalLineCount`
494
221
  - `contentLineCount`
@@ -501,28 +228,11 @@ For each source, record:
501
228
  - `desktopPreviewBudget`: `pass`, `warn`, or `fail`
502
229
  - `blankLineVisualRisk`
503
230
  - `corePointBeforeLikelyTruncation`
504
- - `openLoopType`
505
- - `renderedPreviewVerdict`: `pass`, `warn`, or `fail`
506
231
 
507
232
  If only a search preview is available, do not pretend the opening is complete.
508
233
  Record `sourceTextBasis: search_preview` and lower confidence when the hook
509
234
  appears cut off or body context is unavailable.
510
235
 
511
- Pass/warn/fail is based on rendered output:
512
-
513
- - `pass`: the mobile rendered preview shows the pain, proof, or curiosity by
514
- the end of the first 3 rendered lines, and either the core point is
515
- understandable without opening "see more" or an intentional open loop creates
516
- a specific click question with an immediate planned payoff.
517
- - `warn`: the mobile rendered preview creates useful curiosity but the core
518
- point or click question is slightly softened by wrapping, blank-line rhythm,
519
- or one missing context word. A compact fallback is required.
520
- - `fail`: the hook's real point appears after the first 3 mobile rendered
521
- lines without an intentional open-loop plan, the visible open loop is vague,
522
- the first rendered line is generic setup, blank lines consume the preview
523
- before the reader sees the point, or desktop fit is the only reason it looks
524
- good.
525
-
526
236
  ## Hook Extraction
527
237
 
528
238
  Extract structure and reusable language patterns, not copied prose. The goal is
@@ -535,13 +245,10 @@ For each shortlisted source post, record:
535
245
  - URL
536
246
  - author
537
247
  - author profile URL when available
538
- - author follower count and follower-band fit when available
539
248
  - engagement totals and available likes/comments/shares breakdown
540
- - reach-normalized metrics: engagement per 1k followers, weighted engagement
541
- per 1k followers, reach-adjusted score, baseline lift, and confidence
542
249
  - creator repeat evidence
543
250
  - visible hook text or preview
544
- - rendered preview fields from the section above
251
+ - opening preview measurement fields from the section above
545
252
  - hook mechanism
546
253
  - exact hook language patterns: reusable words, phrase shapes, contrast forms,
547
254
  sentence shapes, and transition moves
@@ -551,16 +258,10 @@ For each shortlisted source post, record:
551
258
  - proof/story dependency
552
259
  - lead magnet or engagement bait penalty
553
260
  - weighted signal notes
554
- - reach-normalized signal notes
555
261
  - replicability score
556
262
  - track person recommendation: `yes`, `no`, or `ask_user`
557
263
  - tracking reason when recommended
558
264
 
559
- Do not call a source hook a keeper because the full text is strong if the
560
- rendered mobile opening is weak. Study what a LinkedIn reader sees before
561
- "see more"; the body structure can still be useful, but the hook should not be
562
- copied into the hook pattern set.
563
-
564
265
  ## Specific Language Extraction
565
266
 
566
267
  For each keeper, extract the source's specific language mechanics in this
@@ -59,25 +59,10 @@ Hook research files must preserve:
59
59
  - source post URLs
60
60
  - author/profile URLs
61
61
  - engagement totals
62
- - author follower counts when available, target follower band, follower-band
63
- fit, engagement per 1k followers, weighted engagement per 1k followers,
64
- reach penalty multiplier, reach-adjusted score, baseline lift when available,
65
- why the hook carries independent of creator reach, and normalization
66
- confidence notes
67
62
  - full-text availability
68
63
  - source hook preview measurements, including text basis, char count including
69
64
  newlines, physical/content line counts, longest nonblank line, blank-line
70
65
  visual risk, and mobile/desktop preview budget status
71
- - rendered preview records for every kept source hook and adapted hook block,
72
- including literal mobile/desktop preview blocks, rendered line wraps, render
73
- basis, CSS contract version, text widths, first-screen promise visibility,
74
- core point visibility, and whether the point lands after the mobile clamp
75
- - hook reverse-engineering autopsies for kept source hooks, including source
76
- mechanism, open-loop type, click question, promised payoff, specificity
77
- anchor, source shape to keep, source words not to copy, and adaptation rule
78
- - hook angle matrix summary, including angle territories tested, top generated
79
- hooks, winning territory, runner-up territories, and why the winning angle
80
- beat the alternatives
81
66
  - extracted hook patterns
82
67
  - selected hook basis
83
68
 
@@ -98,12 +83,6 @@ Draft files must preserve:
98
83
  - draft body
99
84
  - validation receipt, including LinkedIn preview pass/warn/fail status and
100
85
  compact fallback when the selected hook carries a warning
101
- - selected hook reverse-engineering audit, hook angle matrix summary, and
102
- see-more click audit when the selected hook intentionally hides the payoff
103
- after the mobile fold
104
- - rendered mobile and desktop preview blocks for the selected hook; drafts
105
- cannot be ready when this rendered-preview audit is missing or fails mobile
106
- visibility
107
86
  - status: `draft`, `ready`, `needs_revision`, `published`, or `archived`
108
87
 
109
88
  Multiple drafts for the same idea are expected. Keep the `ideaId` stable and