@opendirectory.dev/skills 0.1.0

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.
Files changed (212) hide show
  1. package/.claude/skills/claude-md-generator/.env.example +7 -0
  2. package/.claude/skills/claude-md-generator/README.md +78 -0
  3. package/.claude/skills/claude-md-generator/SKILL.md +248 -0
  4. package/.claude/skills/claude-md-generator/evals/evals.json +35 -0
  5. package/.claude/skills/claude-md-generator/references/section-guide.md +175 -0
  6. package/dist/e2e.test.d.ts +1 -0
  7. package/dist/e2e.test.js +62 -0
  8. package/dist/fs-adapters.d.ts +4 -0
  9. package/dist/fs-adapters.js +101 -0
  10. package/dist/fs-adapters.test.d.ts +1 -0
  11. package/dist/fs-adapters.test.js +108 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +211 -0
  14. package/dist/transformers.d.ts +6 -0
  15. package/dist/transformers.js +2 -0
  16. package/package.json +25 -0
  17. package/registry.json +226 -0
  18. package/skills/blog-cover-image-cli/.github/workflows/publish.yml +19 -0
  19. package/skills/blog-cover-image-cli/LICENSE +15 -0
  20. package/skills/blog-cover-image-cli/README.md +126 -0
  21. package/skills/blog-cover-image-cli/SKILL.md +7 -0
  22. package/skills/blog-cover-image-cli/agent-skill/blog-cover-generator/README.md +30 -0
  23. package/skills/blog-cover-image-cli/agent-skill/blog-cover-generator/SKILL.md +72 -0
  24. package/skills/blog-cover-image-cli/bin/cli.js +226 -0
  25. package/skills/blog-cover-image-cli/examples/100x_UX_Research_AI_Agent.png +0 -0
  26. package/skills/blog-cover-image-cli/examples/Firecrawl-supabase-bolt.png +0 -0
  27. package/skills/blog-cover-image-cli/examples/Git-City_Case_study_Cover_Image.jpg +0 -0
  28. package/skills/blog-cover-image-cli/examples/THE DISTRIBUTION LAYER (2).png +0 -0
  29. package/skills/blog-cover-image-cli/examples/canva-perplexity-duolingo-cover-image.png +0 -0
  30. package/skills/blog-cover-image-cli/examples/gamma-mistral-veed.png +0 -0
  31. package/skills/blog-cover-image-cli/examples/server-survival-case-study-cover-image(1).png +0 -0
  32. package/skills/blog-cover-image-cli/examples/viral-meme-automation.png +0 -0
  33. package/skills/blog-cover-image-cli/index.js +2 -0
  34. package/skills/blog-cover-image-cli/package-lock.json +2238 -0
  35. package/skills/blog-cover-image-cli/package.json +37 -0
  36. package/skills/blog-cover-image-cli/src/geminiGenerator.js +126 -0
  37. package/skills/blog-cover-image-cli/src/imageValidator.js +54 -0
  38. package/skills/blog-cover-image-cli/src/logoFetcher.js +86 -0
  39. package/skills/claude-md-generator/.env.example +7 -0
  40. package/skills/claude-md-generator/README.md +78 -0
  41. package/skills/claude-md-generator/SKILL.md +254 -0
  42. package/skills/claude-md-generator/evals/evals.json +35 -0
  43. package/skills/claude-md-generator/references/section-guide.md +175 -0
  44. package/skills/cook-the-blog/README.md +86 -0
  45. package/skills/cook-the-blog/SKILL.md +130 -0
  46. package/skills/dependency-update-bot/.env.example +13 -0
  47. package/skills/dependency-update-bot/README.md +101 -0
  48. package/skills/dependency-update-bot/SKILL.md +376 -0
  49. package/skills/dependency-update-bot/evals/evals.json +45 -0
  50. package/skills/dependency-update-bot/references/changelog-patterns.md +201 -0
  51. package/skills/docs-from-code/.env.example +13 -0
  52. package/skills/docs-from-code/README.md +97 -0
  53. package/skills/docs-from-code/SKILL.md +160 -0
  54. package/skills/docs-from-code/evals/evals.json +29 -0
  55. package/skills/docs-from-code/references/extraction-guide.md +174 -0
  56. package/skills/docs-from-code/references/output-template.md +135 -0
  57. package/skills/docs-from-code/scripts/extract_py.py +238 -0
  58. package/skills/docs-from-code/scripts/extract_ts.ts +284 -0
  59. package/skills/docs-from-code/scripts/package.json +18 -0
  60. package/skills/explain-this-pr/README.md +74 -0
  61. package/skills/explain-this-pr/SKILL.md +130 -0
  62. package/skills/explain-this-pr/evals/evals.json +35 -0
  63. package/skills/google-trends-api-skills/README.md +78 -0
  64. package/skills/google-trends-api-skills/SKILL.md +7 -0
  65. package/skills/google-trends-api-skills/google-trends-api/SKILL.md +163 -0
  66. package/skills/google-trends-api-skills/google-trends-api/references/api-responses.md +188 -0
  67. package/skills/google-trends-api-skills/google-trends-api/scripts/discover_keywords.py +344 -0
  68. package/skills/google-trends-api-skills/seo-keyword-research/SKILL.md +205 -0
  69. package/skills/google-trends-api-skills/seo-keyword-research/references/keyword-placement-guide.md +89 -0
  70. package/skills/google-trends-api-skills/seo-keyword-research/references/tech-blog-examples.md +207 -0
  71. package/skills/google-trends-api-skills/seo-keyword-research/scripts/blog_seo_research.py +373 -0
  72. package/skills/hackernews-intel/.env.example +33 -0
  73. package/skills/hackernews-intel/README.md +161 -0
  74. package/skills/hackernews-intel/SKILL.md +156 -0
  75. package/skills/hackernews-intel/evals/evals.json +35 -0
  76. package/skills/hackernews-intel/package.json +15 -0
  77. package/skills/hackernews-intel/scripts/monitor-hn.js +258 -0
  78. package/skills/kill-the-standup/.env.example +22 -0
  79. package/skills/kill-the-standup/README.md +84 -0
  80. package/skills/kill-the-standup/SKILL.md +169 -0
  81. package/skills/kill-the-standup/evals/evals.json +35 -0
  82. package/skills/kill-the-standup/references/standup-format.md +102 -0
  83. package/skills/linkedin-post-generator/.env.example +14 -0
  84. package/skills/linkedin-post-generator/README.md +107 -0
  85. package/skills/linkedin-post-generator/SKILL.md +228 -0
  86. package/skills/linkedin-post-generator/evals/evals.json +35 -0
  87. package/skills/linkedin-post-generator/references/linkedin-format.md +216 -0
  88. package/skills/linkedin-post-generator/references/output-template.md +154 -0
  89. package/skills/llms-txt-generator/.env.example +18 -0
  90. package/skills/llms-txt-generator/README.md +142 -0
  91. package/skills/llms-txt-generator/SKILL.md +176 -0
  92. package/skills/llms-txt-generator/evals/evals.json +35 -0
  93. package/skills/llms-txt-generator/references/llms-txt-spec.md +88 -0
  94. package/skills/llms-txt-generator/references/output-template.md +76 -0
  95. package/skills/llms-txt-generator/test-output/genzcareer.in/llms.txt +31 -0
  96. package/skills/luma-attendees-scraper/README.md +170 -0
  97. package/skills/luma-attendees-scraper/SKILL.md +7 -0
  98. package/skills/luma-attendees-scraper/luma_attendees_export.js +223 -0
  99. package/skills/meeting-brief-generator/.env.example +21 -0
  100. package/skills/meeting-brief-generator/README.md +90 -0
  101. package/skills/meeting-brief-generator/SKILL.md +275 -0
  102. package/skills/meeting-brief-generator/evals/evals.json +35 -0
  103. package/skills/meeting-brief-generator/references/brief-format.md +114 -0
  104. package/skills/meeting-brief-generator/references/output-template.md +150 -0
  105. package/skills/meta-ads-skill/README.md +100 -0
  106. package/skills/meta-ads-skill/SKILL.md +7 -0
  107. package/skills/meta-ads-skill/meta-ads-skill/SKILL.md +41 -0
  108. package/skills/meta-ads-skill/meta-ads-skill/references/report_templates.md +47 -0
  109. package/skills/meta-ads-skill/meta-ads-skill/references/workflows.md +51 -0
  110. package/skills/meta-ads-skill/meta-ads-skill/scripts/auth_check.py +22 -0
  111. package/skills/meta-ads-skill/meta-ads-skill/scripts/formatters.py +46 -0
  112. package/skills/newsletter-digest/.env.example +20 -0
  113. package/skills/newsletter-digest/README.md +147 -0
  114. package/skills/newsletter-digest/SKILL.md +221 -0
  115. package/skills/newsletter-digest/evals/evals.json +35 -0
  116. package/skills/newsletter-digest/feeds.json +7 -0
  117. package/skills/newsletter-digest/package.json +15 -0
  118. package/skills/newsletter-digest/references/digest-format.md +123 -0
  119. package/skills/newsletter-digest/references/output-template.md +136 -0
  120. package/skills/newsletter-digest/scripts/fetch-feeds.js +141 -0
  121. package/skills/newsletter-digest/scripts/ghost-publish.js +147 -0
  122. package/skills/noise2blog/.env.example +16 -0
  123. package/skills/noise2blog/README.md +107 -0
  124. package/skills/noise2blog/SKILL.md +229 -0
  125. package/skills/noise2blog/evals/evals.json +35 -0
  126. package/skills/noise2blog/references/blog-format.md +188 -0
  127. package/skills/noise2blog/references/output-template.md +184 -0
  128. package/skills/outreach-sequence-builder/.env.example +12 -0
  129. package/skills/outreach-sequence-builder/README.md +108 -0
  130. package/skills/outreach-sequence-builder/SKILL.md +248 -0
  131. package/skills/outreach-sequence-builder/evals/evals.json +36 -0
  132. package/skills/outreach-sequence-builder/references/output-template.md +171 -0
  133. package/skills/outreach-sequence-builder/references/sequence-format.md +167 -0
  134. package/skills/outreach-sequence-builder/references/signal-playbook.md +117 -0
  135. package/skills/position-me/README.md +71 -0
  136. package/skills/position-me/SKILL.md +7 -0
  137. package/skills/position-me/position-me/SKILL.md +50 -0
  138. package/skills/position-me/position-me/references/EVALUATION_SOP.md +40 -0
  139. package/skills/position-me/position-me/references/REPORT_TEMPLATE.md +58 -0
  140. package/skills/position-me/position-me/scripts/extract_links.py +49 -0
  141. package/skills/pr-description-writer/README.md +81 -0
  142. package/skills/pr-description-writer/SKILL.md +141 -0
  143. package/skills/pr-description-writer/evals/evals.json +35 -0
  144. package/skills/pr-description-writer/references/pr-format-guide.md +145 -0
  145. package/skills/producthunt-launch-kit/.env.example +7 -0
  146. package/skills/producthunt-launch-kit/README.md +95 -0
  147. package/skills/producthunt-launch-kit/SKILL.md +380 -0
  148. package/skills/producthunt-launch-kit/evals/evals.json +35 -0
  149. package/skills/producthunt-launch-kit/references/copy-rules.md +124 -0
  150. package/skills/reddit-icp-monitor/.env.example +16 -0
  151. package/skills/reddit-icp-monitor/README.md +117 -0
  152. package/skills/reddit-icp-monitor/SKILL.md +271 -0
  153. package/skills/reddit-icp-monitor/evals/evals.json +40 -0
  154. package/skills/reddit-icp-monitor/references/icp-format.md +131 -0
  155. package/skills/reddit-icp-monitor/references/reply-rules.md +110 -0
  156. package/skills/reddit-post-engine/.env.example +13 -0
  157. package/skills/reddit-post-engine/README.md +103 -0
  158. package/skills/reddit-post-engine/SKILL.md +303 -0
  159. package/skills/reddit-post-engine/evals/evals.json +35 -0
  160. package/skills/reddit-post-engine/references/subreddit-playbook.md +156 -0
  161. package/skills/schema-markup-generator/.env.example +19 -0
  162. package/skills/schema-markup-generator/README.md +114 -0
  163. package/skills/schema-markup-generator/SKILL.md +192 -0
  164. package/skills/schema-markup-generator/evals/evals.json +35 -0
  165. package/skills/schema-markup-generator/references/json-ld-spec.md +263 -0
  166. package/skills/schema-markup-generator/references/output-template.md +556 -0
  167. package/skills/show-hn-writer/.env.example +14 -0
  168. package/skills/show-hn-writer/README.md +88 -0
  169. package/skills/show-hn-writer/SKILL.md +303 -0
  170. package/skills/show-hn-writer/evals/evals.json +35 -0
  171. package/skills/show-hn-writer/references/hn-rules.md +74 -0
  172. package/skills/show-hn-writer/references/title-formulas.md +93 -0
  173. package/skills/stargazer/README.md +79 -0
  174. package/skills/stargazer/SKILL.md +7 -0
  175. package/skills/stargazer/stargazer-skill/SKILL.md +58 -0
  176. package/skills/stargazer/stargazer-skill/assets/.env.example +18 -0
  177. package/skills/stargazer/stargazer-skill/scripts/convert_to_csv.py +63 -0
  178. package/skills/stargazer/stargazer-skill/scripts/count_emails.py +52 -0
  179. package/skills/stargazer/stargazer-skill/scripts/stargazer_deep_extractor.py +450 -0
  180. package/skills/tweet-thread-from-blog/.env.example +14 -0
  181. package/skills/tweet-thread-from-blog/README.md +109 -0
  182. package/skills/tweet-thread-from-blog/SKILL.md +177 -0
  183. package/skills/tweet-thread-from-blog/evals/evals.json +35 -0
  184. package/skills/tweet-thread-from-blog/references/output-template.md +193 -0
  185. package/skills/tweet-thread-from-blog/references/thread-format.md +107 -0
  186. package/skills/twitter-GTM-find-skill/README.md +43 -0
  187. package/skills/twitter-GTM-find-skill/SKILL.md +7 -0
  188. package/skills/twitter-GTM-find-skill/twitter-GTM-find/SKILL.md +37 -0
  189. package/skills/twitter-GTM-find-skill/twitter-GTM-find/references/icp-checklist.md +35 -0
  190. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/package.json +23 -0
  191. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/run_pipeline.sh +8 -0
  192. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/debug.ts +23 -0
  193. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/extractor.ts +79 -0
  194. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/icp-filter.ts +87 -0
  195. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/index.ts +94 -0
  196. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/scraper.ts +41 -0
  197. package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/tsconfig.json +13 -0
  198. package/skills/yc-intent-radar-skill/README.md +39 -0
  199. package/skills/yc-intent-radar-skill/SKILL.md +7 -0
  200. package/skills/yc-intent-radar-skill/yc-jobs-scraper/SKILL.md +59 -0
  201. package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/auth.js +29 -0
  202. package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/db.js +62 -0
  203. package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/export_radar_candidates.js +40 -0
  204. package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/package-lock.json +1525 -0
  205. package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/package.json +12 -0
  206. package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/scraper.js +217 -0
  207. package/src/e2e.test.ts +35 -0
  208. package/src/fs-adapters.test.ts +91 -0
  209. package/src/fs-adapters.ts +65 -0
  210. package/src/index.ts +182 -0
  211. package/src/transformers.ts +6 -0
  212. package/tsconfig.json +8 -0
@@ -0,0 +1,228 @@
1
+ ---
2
+ name: linkedin-post-generator
3
+ description: Converts any content, blog post URL, pasted article, GitHub PR description, or a description of something built, into a formatted LinkedIn post with proper hook, story arc, and formatting. Optionally posts directly to LinkedIn via Composio. Use when asked to write a LinkedIn post, turn a blog into a LinkedIn update, announce a shipped feature, share a case study on LinkedIn, or post something professionally. Trigger when a user mentions LinkedIn, wants to share content professionally, says "post this to LinkedIn", or asks to repurpose a blog/article/PR for social media.
4
+ compatibility: [claude-code, gemini-cli, github-copilot]
5
+ author: OpenDirectory
6
+ version: 1.0.0
7
+ ---
8
+
9
+ # linkedin-post-generator
10
+
11
+ You are a content strategist who specialises in technical and founder LinkedIn content. Your job is to convert raw input into a high-performing LinkedIn post that follows the platform's proven content patterns.
12
+
13
+ DO NOT INVENT SPECIFICS. Metrics, numbers, company names, product names, and outcomes must come directly from the source material. Never fabricate results or claims.
14
+
15
+ Before starting: Confirm you have input material. Accepted inputs:
16
+ - A URL to a blog post or article
17
+ - Pasted article, case study, or tutorial text
18
+ - A GitHub PR URL or PR description
19
+ - A description of what was built or shipped
20
+
21
+ If no input was provided, ask: "What would you like to turn into a LinkedIn post? Give me a blog URL, paste article text, share a GitHub PR, or describe what you built."
22
+
23
+ ---
24
+
25
+ ## Writing Style
26
+
27
+ Apply these rules to every post you generate. They override any default writing tendencies.
28
+
29
+ Active voice only. No passive constructions.
30
+
31
+ Short sentences. One idea per sentence. If a sentence needs two clauses to work, split it.
32
+
33
+ No em dashes. Replace with a period or a comma.
34
+
35
+ No semicolons.
36
+
37
+ No hashtags.
38
+
39
+ No markdown formatting. No bold, no italic, no asterisks. LinkedIn renders these as plain characters.
40
+
41
+ Address the reader directly. Use "you" and "your" where the post speaks to the audience.
42
+
43
+ No forbidden words. Do not use: can, may, just, very, really, literally, actually, certainly, probably, basically, could, maybe, delve, embark, enlightening, esteemed, shed light, craft, crafting, imagine, realm, game-changer, unlock, discover, skyrocket, abyss, revolutionize, disruptive, utilize, utilizing, dive deep, tapestry, illuminate, unveil, pivotal, intricate, elucidate, hence, furthermore, however, harness, exciting, groundbreaking, cutting-edge, remarkable, remains to be seen, glimpse into, navigating, landscape, stark, testament, in summary, in conclusion, moreover, boost, opened up, powerful, inquiries, ever-evolving.
44
+
45
+ No setup language. Never write "in conclusion", "in closing", "to summarize", or any phrase that signals you are wrapping up.
46
+
47
+ No clichés or metaphors.
48
+
49
+ Use data and examples to support claims. Concrete beats vague every time.
50
+
51
+ ---
52
+
53
+ ## Workflow
54
+
55
+ ### Step 1: Detect Input Type and Fetch Content
56
+
57
+ Handle each input type:
58
+
59
+ - Blog/article URL: fetch the page. Extract headline, body text, key data points, author name.
60
+ - Pasted text: read directly. Identify the type: case study, tutorial, opinion, or announcement.
61
+ - GitHub PR URL: fetch PR title, description, merged file summary, and any linked issue.
62
+ - Free-form description: treat as a brief. Ask only if critical info is missing (what was built, for whom, what result).
63
+
64
+ QA: State the core subject and the single most interesting or surprising thing about this content.
65
+
66
+ ---
67
+
68
+ ### Step 2: Audience and Positioning
69
+
70
+ Before writing a single word, define these four things from the source material:
71
+
72
+ 1. **Audience:** Who specifically will read this post? ("senior engineers who manage CI/CD" not "developers")
73
+ 2. **Goal:** What should they do or think after reading? (Learn something specific / Consider a tool / Follow the author / DM for more)
74
+ 3. **Core insight:** The single most non-obvious, surprising, or useful thing in this content. One sentence.
75
+ 4. **Proof:** What evidence or specifics support the core insight? (numbers, before/after, named outcome)
76
+
77
+ If any of these cannot be answered from the source material, ask the user for that specific item before proceeding.
78
+
79
+ State all four before moving to Step 3. This shapes every decision that follows.
80
+
81
+ ---
82
+
83
+ ### Step 3: Choose Post Format
84
+
85
+ Five formats. Match to the content type and the core insight from Step 2.
86
+
87
+ | Format | When to use | Opening line pattern |
88
+ |--------|-------------|---------------------|
89
+ | Operational Story | Shipped something, ran an incident, completed a project | "We cut X from Y to Z." or "This week we shipped X." |
90
+ | Case Study | Before/after with a measurable result | Lead with the result, then explain how |
91
+ | Contrarian Opinion | Disagreeing with a common assumption or practice | "Everyone says X. Here's why that's wrong." |
92
+ | Framework Post | Sharing a repeatable system or mental model | "[Name] framework: [N] principles for [outcome]." |
93
+ | Build-in-Public | Sharing progress, lessons, or metrics openly | "Month [N] building [X]: [honest observation]." |
94
+
95
+ **Selection rule:** If the content has a concrete outcome with numbers, use Operational Story or Case Study. If it's a strong opinion, use Contrarian. If it's a reusable system, use Framework. If it's a progress update, use Build-in-Public.
96
+
97
+ State the chosen format and one-sentence reason.
98
+
99
+ ---
100
+
101
+ ### Step 4: Select Hook Formula
102
+
103
+ The hook is the first line. It must work as a standalone sentence before "see more" cuts off. It must not start with "I".
104
+
105
+ Five hook formulas. Pick the one that best fits the core insight and audience:
106
+
107
+ **1. Contrarian:** Challenge an assumption the audience holds.
108
+ > "Everyone says [X]. They're wrong."
109
+ > "The conventional wisdom on [X] is backwards."
110
+
111
+ **2. Specific Result:** Lead with a concrete outcome (must come from source material).
112
+ > "We reduced [metric] from [before] to [after] in [timeframe]."
113
+ > "[N] engineers. [X] hours saved per week. Here's what changed."
114
+
115
+ **3. Mistake/Lesson:** Acknowledge something that went wrong or cost something.
116
+ > "I made a [consequence] mistake. Here's what I'd do differently."
117
+ > "We did [X] for [N] months before realizing it was the wrong approach."
118
+
119
+ **4. Framework Reveal:** Name a system or principle.
120
+ > "The [N]-part system we use to [outcome]."
121
+ > "Three rules that changed how our team approaches [X]."
122
+
123
+ **5. Provocative Question:** A question that challenges assumptions (use sparingly).
124
+ > "Why does [common practice] still exist when [better alternative] is available?"
125
+
126
+ State which formula you chose and show the hook draft before writing the full post.
127
+
128
+ ---
129
+
130
+ ### Step 5: Read Format Rules
131
+
132
+ Read `references/linkedin-format.md` in full. Internalize before writing:
133
+ - Hook rules (no starting with "I", no generic openers, must work standalone before the "see more" cutoff)
134
+ - Paragraph limits (1-3 lines, then blank line)
135
+ - Story arc for the chosen style
136
+ - Closing rule (question OR CTA, not both)
137
+ - Link placement rule (all links go in the first comment, not the post body)
138
+ - Character limits (900-1,300 chars optimal, 3,000 max)
139
+
140
+ Then read `references/output-template.md` and select the template for the chosen style.
141
+
142
+ ---
143
+
144
+ ### Step 6: Generate the Post
145
+
146
+ Produce **six outputs** in this order:
147
+
148
+ **(A) Three hook variants**: different formulas, same core insight:
149
+ - Hook 1: [chosen formula from Step 4]
150
+ - Hook 2: [different formula]
151
+ - Hook 3: [third formula: the boldest/most provocative version]
152
+
153
+ Label each with its formula type and character count.
154
+
155
+ **(B) Full post using Hook 1:**
156
+ - Opens with Hook 1
157
+ - Blank line between every paragraph block (1-3 lines each)
158
+ - Story arc matching the format chosen in Step 3
159
+ - Ends with question OR CTA, not both
160
+ - No URLs in the post body
161
+ - All Writing Style rules applied
162
+
163
+ **(C) Spicier variant**: same post with a more direct, opinionated, or blunt tone. One or two sentences strengthened. Not longer: just sharper. Label what changed and why.
164
+
165
+ **(D) Three first-comment ideas:**
166
+ - Comment 1: Source URL + one context sentence
167
+ - Comment 2: A follow-up question to drive discussion ("The part I'm still figuring out: [X]. How do you approach it?")
168
+ - Comment 3: A related resource or deeper context (only if source material supports it)
169
+
170
+ Label each comment with its purpose. User picks one to post immediately after publishing.
171
+
172
+ ---
173
+
174
+ ### Step 7: Self-QA
175
+
176
+ Before presenting the output, run every item on this checklist and fix any violation:
177
+
178
+ - [ ] First line does NOT start with "I"
179
+ - [ ] First line works as a standalone sentence
180
+ - [ ] No paragraph exceeds 3 lines before a blank line
181
+ - [ ] Story arc is present: setup, action/learning, takeaway
182
+ - [ ] Ends with question OR CTA, not both
183
+ - [ ] No URLs in the post body
184
+ - [ ] Character count is between 900-1,300 (count and state it)
185
+ - [ ] No em dashes anywhere in the post
186
+ - [ ] No hashtags
187
+ - [ ] No semicolons
188
+ - [ ] No forbidden words
189
+ - [ ] Every specific (number, name, result) comes from the source material
190
+
191
+ Fix before presenting. State the character count in your output.
192
+
193
+ ---
194
+
195
+ ### Step 8: Post via Composio or Output to User
196
+
197
+ Check for `COMPOSIO_API_KEY` in the environment.
198
+
199
+ If set: Tell the user: "Post ready. Confirm to publish to LinkedIn via Composio, or say 'output only' to get the text."
200
+ On confirmation, call the `linkedin_create_linkedin_post` action with the post body.
201
+ After posting: show the first comment text and tell the user to post it immediately.
202
+
203
+ If not set: Present the post in a code block for easy copy-paste. Present the first comment text separately, clearly labelled. Add: "To enable direct posting, add COMPOSIO_API_KEY to your .env file. See README.md for setup."
204
+
205
+ ---
206
+
207
+ ## What Good Output Looks Like
208
+
209
+ - Hook is specific and creates a gap ("We cut deploy time from 47 minutes to 4" beats "We improved performance")
210
+ - No paragraph is a wall of text: every 1-3 lines is followed by a blank line
211
+ - Story has a clear arc: you know what happened, what changed, and why it matters
212
+ - All numbers and claims trace directly to the source material
213
+ - First comment is prepared with all links
214
+ - Character count is stated and falls in the 900-1,300 range
215
+ - No em dashes, no hashtags, no semicolons, no forbidden words
216
+
217
+ ## What Bad Output Looks Like
218
+
219
+ - Post starts with "I" or "Excited to share..."
220
+ - Paragraphs of 5 or more lines with no breaks
221
+ - Numbers or outcomes not present in the source material
222
+ - URL pasted into the post body
223
+ - Ends with both a question and a CTA
224
+ - Em dashes anywhere in the post
225
+ - Forbidden words present
226
+ - Character count not stated
227
+
228
+
@@ -0,0 +1,35 @@
1
+ {
2
+ "skill_name": "linkedin-post-generator",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "Turn this blog post into a LinkedIn post: https://vercel.com/blog/how-we-optimized-package-imports-in-next-js",
7
+ "expected_output": "Agent fetches the URL and extracts the core insight (barrel file import optimisation, specific build time metrics). Chooses Insight or Founder/Ship style based on content. Reads references/linkedin-format.md and references/output-template.md. Generates post with hook that does not start with 'I', uses specific numbers from the article, uses blank lines between every paragraph, ends with a question. Character count stated and in 900-1,300 range. First comment prepared with the source URL. No URLs in the post body. 3-5 hashtags at end.",
8
+ "files": []
9
+ },
10
+ {
11
+ "id": 2,
12
+ "prompt": "Here's a case study from our product:\n\nAcme Corp integrated our API in Q3. Before: their team spent 6 hours/week manually exporting reports. After: fully automated, zero manual work. They went from 3 reports/month to 47. Their ops lead called it the best vendor decision of the year.\n\nWrite a LinkedIn post announcing this.",
13
+ "expected_output": "Agent reads pasted text. Detects Founder/Ship or Product Launch style. Uses exact numbers from the text (6 hours/week, 3 to 47 reports/month). Hook uses a concrete stat and does not start with 'I'. Story arc: before state, what changed, result. Ends with CTA (not a question, since this is an announcement). No invented details beyond the pasted text. Character count 900-1,300. First comment prepared — agent notes no URL was provided and asks if user has one to add.",
14
+ "files": []
15
+ },
16
+ {
17
+ "id": 3,
18
+ "prompt": "Write a LinkedIn post about this PR we just merged: Added streaming support to our SDK. The PR merged after 3 weeks of work across 4 contributors. It unblocks real-time AI responses for all our API users. Previously users had to wait for the full response before displaying anything.",
19
+ "expected_output": "Agent detects Founder/Ship or Product Launch style. Uses specifics: 3 weeks, 4 contributors, the before/after user experience (wait for full response vs streaming in real time). Hook uses the before/after framing. Story arc: problem (users waited for full response), action (shipped streaming), impact (real-time responses now possible). Ends with a question or CTA. 3-5 hashtags including #devtools or similar. First comment text prepared. Agent notes it will post via Composio if COMPOSIO_API_KEY is set, otherwise outputs text.",
20
+ "files": []
21
+ },
22
+ {
23
+ "id": 4,
24
+ "prompt": "Generate a LinkedIn post from this article: https://martinfowler.com/articles/domain-oriented-observability.html",
25
+ "expected_output": "Agent fetches the URL and reads the article content. Detects Insight style (it's a technical pattern article). Extracts the core claim (observability should be modelled at the domain level, not the infrastructure level). Hook is a bold claim or counterintuitive take about observability. Post follows the Insight arc: claim, common assumption, pattern/evidence, implication. Ends with a question. Hashtags include #softwareengineering plus a niche tag. No invented metrics. Character count stated. First comment has the article URL.",
26
+ "files": []
27
+ },
28
+ {
29
+ "id": 5,
30
+ "prompt": "Write a LinkedIn post about the RAG pipeline tutorial I published last week. Use the Tutorial Summary style specifically. The tutorial covers chunking strategies, embedding storage, hybrid search, reranking, and evaluation. It's aimed at ML engineers and developers building production AI apps.",
31
+ "expected_output": "Agent respects the explicit style override (Tutorial Summary) without auto-detecting. Uses the Tutorial Summary template from references/output-template.md. Hook frames what the reader will be able to do. Lists 4-5 key techniques from the specified topics as numbered items, each one line. Ends with a question inviting engagement. Hashtags include #llm or #openai plus a broader community tag. Character count 900-1,300. Agent notes there is no source URL and asks if the user has a link to add to the first comment.",
32
+ "files": []
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,216 @@
1
+ # LinkedIn Format Rules
2
+
3
+ This is the reference document the agent reads before writing any post. All rules here are non-negotiable unless the user explicitly overrides them.
4
+
5
+ ---
6
+
7
+ ## Section 1: Why LinkedIn Format Is Different
8
+
9
+ LinkedIn's algorithm and UI create constraints you do not have on other platforms:
10
+
11
+ - Outbound link penalty. Posts with URLs in the body get distributed less. LinkedIn wants to keep users on-platform. Put all links in the first comment.
12
+ - The "see more" cutoff. After approximately 210 characters, LinkedIn collapses the post. Only the first 1-2 lines are visible. If those lines do not earn a click, the post is invisible.
13
+ - Mobile-first rendering. Most LinkedIn users are on mobile. Walls of text get scrolled past. Blank lines between short paragraphs increase completion rates.
14
+ - Engagement signal hierarchy. Comments carry more weight than reactions. Reactions carry more weight than shares. Questions that invite comments are more valuable than statements.
15
+
16
+ ---
17
+
18
+ ## Section 2: Hook Rules
19
+
20
+ The hook is line 1. It is the only content visible before the "see more" click. Treat it as the entire post.
21
+
22
+ A good hook must:
23
+ - Stand alone as a complete thought
24
+ - Create a gap between what the reader knows and what they want to know
25
+ - NOT start with "I" (posts starting with "I" consistently underperform)
26
+ - NOT be generic or vague
27
+
28
+ Hook formats that work:
29
+
30
+ | Format | Example |
31
+ |--------|---------|
32
+ | Bold claim | "Most developers are measuring the wrong thing." |
33
+ | Specific stat | "We cut deploy time from 47 minutes to 4." |
34
+ | Story opening (not "I") | "After 6 months of building in silence, we shipped." |
35
+ | Direct question | "What do you do when your most-used library gets deprecated overnight?" |
36
+ | Counterintuitive observation | "The feature our users love most took 2 hours to build." |
37
+ | Problem statement | "Nobody talks about the week after you launch." |
38
+
39
+ Hook formats to avoid:
40
+
41
+ - "I'm excited to share..."
42
+ - "Big announcement!"
43
+ - "Thrilled to announce..."
44
+ - "We are pleased to..."
45
+ - "Just shipped..." or "Just wanted to share..."
46
+ - Any opener starting with "I"
47
+
48
+ ---
49
+
50
+ ## Section 3: Post Body Rules
51
+
52
+ Paragraph length: Maximum 1-3 lines per paragraph. Always follow with a blank line before the next paragraph. Never write 4 or more consecutive lines without a break.
53
+
54
+ Sentence length: Short sentences outperform long sentences on mobile. Split any sentence that needs two commas to work.
55
+
56
+ Story arcs by style:
57
+
58
+ Founder/Ship:
59
+ ```
60
+ Line 1: Hook
61
+ [blank]
62
+ Lines 2-3: Context: what were you building, for how long, what was the challenge
63
+ [blank]
64
+ Lines 4-6: Action: what shipped, concrete and specific
65
+ [blank]
66
+ Lines 7-8: Surprise or learning: what you did not expect, what changed
67
+ [blank]
68
+ Line 9: Takeaway: the single distilled lesson
69
+ [blank]
70
+ Line 10: Closing question
71
+ ```
72
+
73
+ Insight:
74
+ ```
75
+ Line 1: Hook: the claim or counterintuitive statement
76
+ [blank]
77
+ Lines 2-3: Assumption: what most people think or do
78
+ [blank]
79
+ Lines 4-6: Evidence: what you observed, or data that supports the claim
80
+ [blank]
81
+ Lines 7-8: Implication: what this means, what changes when you accept it
82
+ [blank]
83
+ Line 9: Closing question
84
+ ```
85
+
86
+ Product Launch:
87
+ ```
88
+ Line 1: Hook: what the product does for the user (outcome, not feature)
89
+ [blank]
90
+ Lines 2-3: Problem: the pain this solves, specific not generic
91
+ [blank]
92
+ Lines 4-6: What it does: brief and concrete, key differentiator on one line
93
+ [blank]
94
+ Line 7: Proof point: beta result, user quote, or metric (skip if none exists)
95
+ [blank]
96
+ Line 8: CTA: one clear action
97
+ ```
98
+
99
+ Tutorial Summary:
100
+ ```
101
+ Line 1: Hook: what the reader learns, or what most get wrong
102
+ [blank]
103
+ Lines 2-3: Why it matters: who this is for, why standard approaches fail
104
+ [blank]
105
+ Lines 4-9: Key steps: 3-5 numbered items, each one line, concrete and actionable
106
+ [blank]
107
+ Line 10: Main takeaway: one sentence
108
+ [blank]
109
+ Line 11: CTA or question
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Section 4: Specificity Rules
115
+
116
+ Concrete details outperform vague claims every time.
117
+
118
+ | Vague | Concrete |
119
+ |-------|----------|
120
+ | "saved time" | "saved 4 hours/week" |
121
+ | "dramatically faster" | "cut from 47 minutes to 4 minutes" |
122
+ | "customers asked for this" | "3 of our top 10 customers requested it" |
123
+ | "small team, fast execution" | "shipped in 2 weeks with 2 engineers" |
124
+ | "improved performance" | "p95 latency dropped from 1.2s to 180ms" |
125
+
126
+ If the source material has numbers, use them exactly. If no numbers are available, use specific descriptors rather than superlatives. Never invent metrics.
127
+
128
+ ---
129
+
130
+ ## Section 5: Closing Rules
131
+
132
+ End with exactly one of the following:
133
+
134
+ A question that invites genuine response:
135
+ - "Has anyone else run into this?"
136
+ - "What would you do differently?"
137
+ - "What's your approach to [X]?"
138
+ - "Am I wrong about this?"
139
+
140
+ A clear CTA pointing to the first comment:
141
+ - "Full post in the first comment."
142
+ - "Link to try it in the first comment."
143
+ - "The template is in the comments."
144
+ - "Tutorial in the first comment."
145
+
146
+ Do NOT end with both a question and a CTA.
147
+
148
+ Do NOT use: "Let me know your thoughts!" or "Drop a comment below!" These are low-signal and overused.
149
+
150
+ ---
151
+
152
+ ## Section 6: Link Placement Rule
153
+
154
+ This rule is non-negotiable. LinkedIn distributes posts with outbound links in the body significantly less.
155
+
156
+ Rule: All URLs go in the first comment. Never in the post body.
157
+
158
+ In the post body, refer to the link as: "link in the first comment" or "in the comments."
159
+
160
+ First comment format:
161
+ ```
162
+ [One context sentence about what the link is]. [URL]
163
+ ```
164
+
165
+ Example:
166
+ ```
167
+ Full tutorial on building a production RAG pipeline. https://yourblog.com/rag-guide
168
+ ```
169
+
170
+ Post the first comment immediately after publishing.
171
+
172
+ ---
173
+
174
+ ## Section 7: No Hashtags
175
+
176
+ Do not include hashtags in the post. Hashtags add visual noise and reduce the professional tone of technical content. Posts without hashtags perform equally well for most technical and founder audiences.
177
+
178
+ ---
179
+
180
+ ## Section 8: Length and Format
181
+
182
+ | Metric | Target |
183
+ |--------|--------|
184
+ | Optimal character count | 900-1,300 characters |
185
+ | Maximum character count | 3,000 characters |
186
+ | Minimum to feel substantive | 500 characters |
187
+ | Approximate word count at 1,100 chars | 150-180 words |
188
+
189
+ No markdown formatting. LinkedIn does not render bold or italic. Asterisks and underscores appear as plain characters.
190
+
191
+ No em dashes. Replace with a period or a comma.
192
+
193
+ No semicolons.
194
+
195
+ Emojis: optional. 0-3 per post maximum. Use as visual paragraph separators or to replace bullet points. Do not use for decoration.
196
+
197
+ ---
198
+
199
+ ## Section 9: Validation Checklist
200
+
201
+ Run through this before finalising any post:
202
+
203
+ - [ ] First line does NOT start with "I"
204
+ - [ ] First line works standalone: interesting without the rest
205
+ - [ ] No paragraph exceeds 3 lines before a blank line
206
+ - [ ] Blank lines exist between every paragraph block
207
+ - [ ] Story arc is present (varies by style)
208
+ - [ ] All numbers and claims come from the source material
209
+ - [ ] Ends with question OR CTA, not both
210
+ - [ ] No URLs in the post body
211
+ - [ ] Character count: 900-1,300 ideal, under 3,000 required
212
+ - [ ] No em dashes
213
+ - [ ] No hashtags
214
+ - [ ] No semicolons
215
+ - [ ] No forbidden words (see Writing Style in SKILL.md)
216
+ - [ ] First comment text prepared with all relevant links
@@ -0,0 +1,154 @@
1
+ # Output Templates
2
+
3
+ Four templates, one per post style. Fill every [BRACKETED SLOT] with content from the source material. Never use the bracket text literally in the output. Preserve all blank lines exactly as shown. Apply the Writing Style rules from SKILL.md to every sentence.
4
+
5
+ ---
6
+
7
+ ## Template 1: Founder/Ship
8
+
9
+ Use when the content is a personal story of building or shipping something.
10
+
11
+ ```
12
+ [HOOK: bold claim, surprising result, or key build moment. Does not start with "I".]
13
+
14
+ [CONTEXT: 1-2 lines. What were you building, how long, what was the challenge.]
15
+
16
+ [ACTION: 2-3 lines. What you shipped. Concrete and specific. Include the key feature or decision.]
17
+
18
+ [SURPRISE OR LEARNING: 1-2 lines. What you did not expect. What changed after shipping.]
19
+
20
+ [TAKEAWAY: 1 line. The single distilled lesson.]
21
+
22
+ [CLOSING QUESTION: Invite genuine response. "What did you learn from your last launch?" or "Has anyone else seen this?"]
23
+ ```
24
+
25
+ Worked example:
26
+
27
+ ```
28
+ 6 months of building in silence. Then 400 signups in 48 hours.
29
+
30
+ Here is what we did not expect.
31
+
32
+ The feature we almost cut, the one that felt too simple, was the one everyone messaged us about.
33
+
34
+ We built a one-click CSV export. No filters, no customisation, export only. Took 2 hours to build.
35
+
36
+ The feedback from users: "Finally. I've been manually copying this data for a year."
37
+
38
+ Sometimes the boring feature is the important one.
39
+
40
+ What's a feature you almost did not ship that turned out to matter?
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Template 2: Insight
46
+
47
+ Use when the content is an educational observation, pattern, or lesson. Works for articles, opinions, and thought leadership.
48
+
49
+ ```
50
+ [HOOK: a bold claim or counterintuitive statement. Specific, not vague.]
51
+
52
+ [ASSUMPTION: 1-2 lines. What most people think or do. Set up the contrast.]
53
+
54
+ [EVIDENCE: 2-3 lines. What you observed, or the data and examples that support the claim.]
55
+
56
+ [IMPLICATION: 1-2 lines. What this means. What changes when you accept this.]
57
+
58
+ [CLOSING QUESTION: Open a genuine conversation. "Am I wrong about this?" or "What's your experience with [X]?"]
59
+ ```
60
+
61
+ Worked example:
62
+
63
+ ```
64
+ Most developers are optimising the wrong bottleneck.
65
+
66
+ The assumption: your app is slow because of database queries.
67
+
68
+ The reality: after profiling 50+ production apps, the biggest wins almost always come from fixing N+1 queries and response payload size. Adding indexes helps less than you think.
69
+
70
+ Unindexed columns rarely cause the latency spikes that make users leave.
71
+
72
+ The bottleneck is almost always what you're sending, not how fast you're finding it.
73
+
74
+ Where do you look first when you see a latency spike?
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Template 3: Product Launch
80
+
81
+ Use when announcing a new tool, product, feature going public, or beta release.
82
+
83
+ ```
84
+ [HOOK: what the product does for the user (outcome, not feature). Frame it as a benefit, not a capability.]
85
+
86
+ [PROBLEM: 1-2 lines. The pain this solves. Be specific. Avoid "teams struggle with..." or "developers find it hard to...".]
87
+
88
+ [WHAT IT DOES: 2-3 lines. What the product does, brief and concrete. Key differentiator on one line.]
89
+
90
+ [PROOF POINT: 1 line. A beta result, user quote, or specific metric. Skip this block entirely if none exists.]
91
+
92
+ [CTA: one clear action. "Link to try it in the first comment." or "Sign-up link in the first comment."]
93
+ ```
94
+
95
+ Worked example:
96
+
97
+ ```
98
+ Your AI agent reads any website in under 3 seconds. No browser needed.
99
+
100
+ Most scraping tools either need a headless browser (slow and fragile) or miss JavaScript-rendered content entirely.
101
+
102
+ We built a lightweight extraction layer that bypasses both problems. No Playwright. No Puppeteer. No Chrome.
103
+
104
+ Beta users are pulling structured data from 200+ pages per minute on a $5 VPS.
105
+
106
+ Sign-up link in the first comment.
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Template 4: Tutorial Summary
112
+
113
+ Use when distilling a long tutorial, technical deep-dive, or step-by-step guide into a tight takeaway post.
114
+
115
+ ```
116
+ [HOOK: what the reader learns from this, or what most people get wrong about this topic.]
117
+
118
+ [WHY IT MATTERS: 1-2 lines. Who this is for. Why the standard approach fails.]
119
+
120
+ [KEY STEPS: 3-5 numbered items, each one line. Concrete and actionable. Tight phrases work better than full sentences.]
121
+
122
+ [MAIN TAKEAWAY: 1 line. The single most important thing.]
123
+
124
+ [CTA OR QUESTION: "Full tutorial in the first comment." or "What would you add to this list?"]
125
+ ```
126
+
127
+ Worked example:
128
+
129
+ ```
130
+ Set up a production-ready RAG pipeline in an afternoon. Most tutorials make it seem harder than it is.
131
+
132
+ Here is what actually matters:
133
+
134
+ 1. Chunk by semantic unit, not by token count
135
+ 2. Store embeddings and original text together. You will need both at retrieval time.
136
+ 3. Hybrid search (BM25 + vector) beats pure vector search for most use cases
137
+ 4. Rerank before you return. The top-10 results are rarely in the right order.
138
+ 5. Eval early. 10 hand-labelled queries will save you days of guessing.
139
+
140
+ The system is only as good as your eval set.
141
+
142
+ What's the hardest part of RAG you've wrestled with?
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Fill-in Rules
148
+
149
+ 1. Replace every [BRACKETED SLOT] with content derived from the source material. Never output the bracket text.
150
+ 2. Preserve all blank lines between paragraphs exactly as shown.
151
+ 3. Count characters before presenting. State the count.
152
+ 4. Skip blocks with no source data rather than inventing content.
153
+ 5. Apply Writing Style rules: no em dashes, no hashtags, no semicolons, no forbidden words, active voice only.
154
+ 6. Address the reader with "you" and "your" where the post speaks to the audience.
@@ -0,0 +1,18 @@
1
+ # llms-txt-generator — Environment Variables
2
+ # ============================================
3
+ # This skill uses Chrome DevTools MCP for site crawling.
4
+ # No API keys required — only Chrome access.
5
+
6
+ # Chrome remote debugging port (default: 9222)
7
+ # Start Chrome with: chrome --remote-debugging-port=9222
8
+ # Or: open -a "Google Chrome" --args --remote-debugging-port=9222
9
+ CHROME_DEBUGGING_PORT=9222
10
+
11
+ # Optional: GitHub token for opening a PR with the generated file
12
+ # Scopes needed: repo (read + write)
13
+ # Get one at: https://github.com/settings/tokens
14
+ GITHUB_TOKEN=your_github_token_here
15
+
16
+ # Optional: Target GitHub repo slug (e.g. "your-org/your-site-repo")
17
+ # If set, the agent will offer to open a PR automatically
18
+ GITHUB_REPO=your-org/your-repo