@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.
- package/.claude/skills/claude-md-generator/.env.example +7 -0
- package/.claude/skills/claude-md-generator/README.md +78 -0
- package/.claude/skills/claude-md-generator/SKILL.md +248 -0
- package/.claude/skills/claude-md-generator/evals/evals.json +35 -0
- package/.claude/skills/claude-md-generator/references/section-guide.md +175 -0
- package/dist/e2e.test.d.ts +1 -0
- package/dist/e2e.test.js +62 -0
- package/dist/fs-adapters.d.ts +4 -0
- package/dist/fs-adapters.js +101 -0
- package/dist/fs-adapters.test.d.ts +1 -0
- package/dist/fs-adapters.test.js +108 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +211 -0
- package/dist/transformers.d.ts +6 -0
- package/dist/transformers.js +2 -0
- package/package.json +25 -0
- package/registry.json +226 -0
- package/skills/blog-cover-image-cli/.github/workflows/publish.yml +19 -0
- package/skills/blog-cover-image-cli/LICENSE +15 -0
- package/skills/blog-cover-image-cli/README.md +126 -0
- package/skills/blog-cover-image-cli/SKILL.md +7 -0
- package/skills/blog-cover-image-cli/agent-skill/blog-cover-generator/README.md +30 -0
- package/skills/blog-cover-image-cli/agent-skill/blog-cover-generator/SKILL.md +72 -0
- package/skills/blog-cover-image-cli/bin/cli.js +226 -0
- package/skills/blog-cover-image-cli/examples/100x_UX_Research_AI_Agent.png +0 -0
- package/skills/blog-cover-image-cli/examples/Firecrawl-supabase-bolt.png +0 -0
- package/skills/blog-cover-image-cli/examples/Git-City_Case_study_Cover_Image.jpg +0 -0
- package/skills/blog-cover-image-cli/examples/THE DISTRIBUTION LAYER (2).png +0 -0
- package/skills/blog-cover-image-cli/examples/canva-perplexity-duolingo-cover-image.png +0 -0
- package/skills/blog-cover-image-cli/examples/gamma-mistral-veed.png +0 -0
- package/skills/blog-cover-image-cli/examples/server-survival-case-study-cover-image(1).png +0 -0
- package/skills/blog-cover-image-cli/examples/viral-meme-automation.png +0 -0
- package/skills/blog-cover-image-cli/index.js +2 -0
- package/skills/blog-cover-image-cli/package-lock.json +2238 -0
- package/skills/blog-cover-image-cli/package.json +37 -0
- package/skills/blog-cover-image-cli/src/geminiGenerator.js +126 -0
- package/skills/blog-cover-image-cli/src/imageValidator.js +54 -0
- package/skills/blog-cover-image-cli/src/logoFetcher.js +86 -0
- package/skills/claude-md-generator/.env.example +7 -0
- package/skills/claude-md-generator/README.md +78 -0
- package/skills/claude-md-generator/SKILL.md +254 -0
- package/skills/claude-md-generator/evals/evals.json +35 -0
- package/skills/claude-md-generator/references/section-guide.md +175 -0
- package/skills/cook-the-blog/README.md +86 -0
- package/skills/cook-the-blog/SKILL.md +130 -0
- package/skills/dependency-update-bot/.env.example +13 -0
- package/skills/dependency-update-bot/README.md +101 -0
- package/skills/dependency-update-bot/SKILL.md +376 -0
- package/skills/dependency-update-bot/evals/evals.json +45 -0
- package/skills/dependency-update-bot/references/changelog-patterns.md +201 -0
- package/skills/docs-from-code/.env.example +13 -0
- package/skills/docs-from-code/README.md +97 -0
- package/skills/docs-from-code/SKILL.md +160 -0
- package/skills/docs-from-code/evals/evals.json +29 -0
- package/skills/docs-from-code/references/extraction-guide.md +174 -0
- package/skills/docs-from-code/references/output-template.md +135 -0
- package/skills/docs-from-code/scripts/extract_py.py +238 -0
- package/skills/docs-from-code/scripts/extract_ts.ts +284 -0
- package/skills/docs-from-code/scripts/package.json +18 -0
- package/skills/explain-this-pr/README.md +74 -0
- package/skills/explain-this-pr/SKILL.md +130 -0
- package/skills/explain-this-pr/evals/evals.json +35 -0
- package/skills/google-trends-api-skills/README.md +78 -0
- package/skills/google-trends-api-skills/SKILL.md +7 -0
- package/skills/google-trends-api-skills/google-trends-api/SKILL.md +163 -0
- package/skills/google-trends-api-skills/google-trends-api/references/api-responses.md +188 -0
- package/skills/google-trends-api-skills/google-trends-api/scripts/discover_keywords.py +344 -0
- package/skills/google-trends-api-skills/seo-keyword-research/SKILL.md +205 -0
- package/skills/google-trends-api-skills/seo-keyword-research/references/keyword-placement-guide.md +89 -0
- package/skills/google-trends-api-skills/seo-keyword-research/references/tech-blog-examples.md +207 -0
- package/skills/google-trends-api-skills/seo-keyword-research/scripts/blog_seo_research.py +373 -0
- package/skills/hackernews-intel/.env.example +33 -0
- package/skills/hackernews-intel/README.md +161 -0
- package/skills/hackernews-intel/SKILL.md +156 -0
- package/skills/hackernews-intel/evals/evals.json +35 -0
- package/skills/hackernews-intel/package.json +15 -0
- package/skills/hackernews-intel/scripts/monitor-hn.js +258 -0
- package/skills/kill-the-standup/.env.example +22 -0
- package/skills/kill-the-standup/README.md +84 -0
- package/skills/kill-the-standup/SKILL.md +169 -0
- package/skills/kill-the-standup/evals/evals.json +35 -0
- package/skills/kill-the-standup/references/standup-format.md +102 -0
- package/skills/linkedin-post-generator/.env.example +14 -0
- package/skills/linkedin-post-generator/README.md +107 -0
- package/skills/linkedin-post-generator/SKILL.md +228 -0
- package/skills/linkedin-post-generator/evals/evals.json +35 -0
- package/skills/linkedin-post-generator/references/linkedin-format.md +216 -0
- package/skills/linkedin-post-generator/references/output-template.md +154 -0
- package/skills/llms-txt-generator/.env.example +18 -0
- package/skills/llms-txt-generator/README.md +142 -0
- package/skills/llms-txt-generator/SKILL.md +176 -0
- package/skills/llms-txt-generator/evals/evals.json +35 -0
- package/skills/llms-txt-generator/references/llms-txt-spec.md +88 -0
- package/skills/llms-txt-generator/references/output-template.md +76 -0
- package/skills/llms-txt-generator/test-output/genzcareer.in/llms.txt +31 -0
- package/skills/luma-attendees-scraper/README.md +170 -0
- package/skills/luma-attendees-scraper/SKILL.md +7 -0
- package/skills/luma-attendees-scraper/luma_attendees_export.js +223 -0
- package/skills/meeting-brief-generator/.env.example +21 -0
- package/skills/meeting-brief-generator/README.md +90 -0
- package/skills/meeting-brief-generator/SKILL.md +275 -0
- package/skills/meeting-brief-generator/evals/evals.json +35 -0
- package/skills/meeting-brief-generator/references/brief-format.md +114 -0
- package/skills/meeting-brief-generator/references/output-template.md +150 -0
- package/skills/meta-ads-skill/README.md +100 -0
- package/skills/meta-ads-skill/SKILL.md +7 -0
- package/skills/meta-ads-skill/meta-ads-skill/SKILL.md +41 -0
- package/skills/meta-ads-skill/meta-ads-skill/references/report_templates.md +47 -0
- package/skills/meta-ads-skill/meta-ads-skill/references/workflows.md +51 -0
- package/skills/meta-ads-skill/meta-ads-skill/scripts/auth_check.py +22 -0
- package/skills/meta-ads-skill/meta-ads-skill/scripts/formatters.py +46 -0
- package/skills/newsletter-digest/.env.example +20 -0
- package/skills/newsletter-digest/README.md +147 -0
- package/skills/newsletter-digest/SKILL.md +221 -0
- package/skills/newsletter-digest/evals/evals.json +35 -0
- package/skills/newsletter-digest/feeds.json +7 -0
- package/skills/newsletter-digest/package.json +15 -0
- package/skills/newsletter-digest/references/digest-format.md +123 -0
- package/skills/newsletter-digest/references/output-template.md +136 -0
- package/skills/newsletter-digest/scripts/fetch-feeds.js +141 -0
- package/skills/newsletter-digest/scripts/ghost-publish.js +147 -0
- package/skills/noise2blog/.env.example +16 -0
- package/skills/noise2blog/README.md +107 -0
- package/skills/noise2blog/SKILL.md +229 -0
- package/skills/noise2blog/evals/evals.json +35 -0
- package/skills/noise2blog/references/blog-format.md +188 -0
- package/skills/noise2blog/references/output-template.md +184 -0
- package/skills/outreach-sequence-builder/.env.example +12 -0
- package/skills/outreach-sequence-builder/README.md +108 -0
- package/skills/outreach-sequence-builder/SKILL.md +248 -0
- package/skills/outreach-sequence-builder/evals/evals.json +36 -0
- package/skills/outreach-sequence-builder/references/output-template.md +171 -0
- package/skills/outreach-sequence-builder/references/sequence-format.md +167 -0
- package/skills/outreach-sequence-builder/references/signal-playbook.md +117 -0
- package/skills/position-me/README.md +71 -0
- package/skills/position-me/SKILL.md +7 -0
- package/skills/position-me/position-me/SKILL.md +50 -0
- package/skills/position-me/position-me/references/EVALUATION_SOP.md +40 -0
- package/skills/position-me/position-me/references/REPORT_TEMPLATE.md +58 -0
- package/skills/position-me/position-me/scripts/extract_links.py +49 -0
- package/skills/pr-description-writer/README.md +81 -0
- package/skills/pr-description-writer/SKILL.md +141 -0
- package/skills/pr-description-writer/evals/evals.json +35 -0
- package/skills/pr-description-writer/references/pr-format-guide.md +145 -0
- package/skills/producthunt-launch-kit/.env.example +7 -0
- package/skills/producthunt-launch-kit/README.md +95 -0
- package/skills/producthunt-launch-kit/SKILL.md +380 -0
- package/skills/producthunt-launch-kit/evals/evals.json +35 -0
- package/skills/producthunt-launch-kit/references/copy-rules.md +124 -0
- package/skills/reddit-icp-monitor/.env.example +16 -0
- package/skills/reddit-icp-monitor/README.md +117 -0
- package/skills/reddit-icp-monitor/SKILL.md +271 -0
- package/skills/reddit-icp-monitor/evals/evals.json +40 -0
- package/skills/reddit-icp-monitor/references/icp-format.md +131 -0
- package/skills/reddit-icp-monitor/references/reply-rules.md +110 -0
- package/skills/reddit-post-engine/.env.example +13 -0
- package/skills/reddit-post-engine/README.md +103 -0
- package/skills/reddit-post-engine/SKILL.md +303 -0
- package/skills/reddit-post-engine/evals/evals.json +35 -0
- package/skills/reddit-post-engine/references/subreddit-playbook.md +156 -0
- package/skills/schema-markup-generator/.env.example +19 -0
- package/skills/schema-markup-generator/README.md +114 -0
- package/skills/schema-markup-generator/SKILL.md +192 -0
- package/skills/schema-markup-generator/evals/evals.json +35 -0
- package/skills/schema-markup-generator/references/json-ld-spec.md +263 -0
- package/skills/schema-markup-generator/references/output-template.md +556 -0
- package/skills/show-hn-writer/.env.example +14 -0
- package/skills/show-hn-writer/README.md +88 -0
- package/skills/show-hn-writer/SKILL.md +303 -0
- package/skills/show-hn-writer/evals/evals.json +35 -0
- package/skills/show-hn-writer/references/hn-rules.md +74 -0
- package/skills/show-hn-writer/references/title-formulas.md +93 -0
- package/skills/stargazer/README.md +79 -0
- package/skills/stargazer/SKILL.md +7 -0
- package/skills/stargazer/stargazer-skill/SKILL.md +58 -0
- package/skills/stargazer/stargazer-skill/assets/.env.example +18 -0
- package/skills/stargazer/stargazer-skill/scripts/convert_to_csv.py +63 -0
- package/skills/stargazer/stargazer-skill/scripts/count_emails.py +52 -0
- package/skills/stargazer/stargazer-skill/scripts/stargazer_deep_extractor.py +450 -0
- package/skills/tweet-thread-from-blog/.env.example +14 -0
- package/skills/tweet-thread-from-blog/README.md +109 -0
- package/skills/tweet-thread-from-blog/SKILL.md +177 -0
- package/skills/tweet-thread-from-blog/evals/evals.json +35 -0
- package/skills/tweet-thread-from-blog/references/output-template.md +193 -0
- package/skills/tweet-thread-from-blog/references/thread-format.md +107 -0
- package/skills/twitter-GTM-find-skill/README.md +43 -0
- package/skills/twitter-GTM-find-skill/SKILL.md +7 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/SKILL.md +37 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/references/icp-checklist.md +35 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/package.json +23 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/run_pipeline.sh +8 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/debug.ts +23 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/extractor.ts +79 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/icp-filter.ts +87 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/index.ts +94 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/src/scraper.ts +41 -0
- package/skills/twitter-GTM-find-skill/twitter-GTM-find/scripts/tsconfig.json +13 -0
- package/skills/yc-intent-radar-skill/README.md +39 -0
- package/skills/yc-intent-radar-skill/SKILL.md +7 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/SKILL.md +59 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/auth.js +29 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/db.js +62 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/export_radar_candidates.js +40 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/package-lock.json +1525 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/package.json +12 -0
- package/skills/yc-intent-radar-skill/yc-jobs-scraper/scripts/scraper.js +217 -0
- package/src/e2e.test.ts +35 -0
- package/src/fs-adapters.test.ts +91 -0
- package/src/fs-adapters.ts +65 -0
- package/src/index.ts +182 -0
- package/src/transformers.ts +6 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tweet-thread-from-blog
|
|
3
|
+
description: Converts a blog post URL or article into a Twitter/X thread with a strong hook, one insight per tweet, and a CTA. Optionally posts the full thread to X via Composio using a reply chain. Use when asked to turn a blog post into a tweet thread, repurpose an article for Twitter, create a thread from a blog, write a Twitter thread about a topic, or share a blog post as a thread. Trigger when a user mentions Twitter thread, X thread, tweet thread, or wants to repurpose blog content for X/Twitter.
|
|
4
|
+
compatibility: [claude-code, gemini-cli, github-copilot]
|
|
5
|
+
author: OpenDirectory
|
|
6
|
+
version: 1.0.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Tweet Thread from Blog
|
|
10
|
+
|
|
11
|
+
Convert a blog post or article into a 7-10 tweet thread. One insight per tweet. Strong hook. CTA in the final tweet. Optionally post the thread directly to X via Composio.
|
|
12
|
+
|
|
13
|
+
## Writing Style
|
|
14
|
+
|
|
15
|
+
Apply these rules to every tweet you write:
|
|
16
|
+
|
|
17
|
+
- Active voice only
|
|
18
|
+
- Conversational, like a person typed it on their phone
|
|
19
|
+
- Contractions required: don't, it's, won't, can't, I've
|
|
20
|
+
- Short sentences, one idea per tweet
|
|
21
|
+
- No em dashes — use a period or comma instead
|
|
22
|
+
- No semicolons
|
|
23
|
+
- No markdown or asterisks
|
|
24
|
+
- No hashtags anywhere in the thread
|
|
25
|
+
|
|
26
|
+
Banned words — do not use any of these:
|
|
27
|
+
incredible, amazing, leveraging, synergize, game-changing, game changer, let's dive in, buckle up, it's worth noting, delve, harness, unlock, groundbreaking, cutting-edge, remarkable, paradigm, revolutionize, disruptive, transformative, thrilled, excited to share, powerful, innovative, comprehensive, actionable, crucial, vital, pivotal, elucidate, utilize, can, may, just, that, very, really, literally, actually, certainly, probably, basically, could, maybe
|
|
28
|
+
|
|
29
|
+
If a draft tweet contains any banned word, rewrite it before presenting.
|
|
30
|
+
|
|
31
|
+
## CRITICAL RULE
|
|
32
|
+
|
|
33
|
+
Do not invent specifics. Every claim, stat, and example in the thread must come from the blog post. Never fabricate data, quotes, or outcomes.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Step 1: Check Setup
|
|
38
|
+
|
|
39
|
+
Confirm input is present. The user must provide one of:
|
|
40
|
+
- A blog post URL
|
|
41
|
+
- Pasted article text
|
|
42
|
+
|
|
43
|
+
If no input is present, ask: "What blog post or article should I turn into a thread? Share a URL or paste the content."
|
|
44
|
+
|
|
45
|
+
COMPOSIO_API_KEY is only needed for direct posting to X. Output-only mode works without it.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Step 2: Fetch and Extract Content
|
|
50
|
+
|
|
51
|
+
**If input is a URL:**
|
|
52
|
+
Use WebFetch or Chrome DevTools MCP to fetch the page. Extract:
|
|
53
|
+
- Title
|
|
54
|
+
- Author name
|
|
55
|
+
- Publish date
|
|
56
|
+
- All body text
|
|
57
|
+
- Key statistics and data points
|
|
58
|
+
- Numbered lists or steps
|
|
59
|
+
- Subheadings
|
|
60
|
+
- Any quotes
|
|
61
|
+
|
|
62
|
+
**If input is pasted text:**
|
|
63
|
+
Read it directly.
|
|
64
|
+
|
|
65
|
+
After fetching, identify:
|
|
66
|
+
- The single most surprising or counterintuitive insight
|
|
67
|
+
- 6-9 supporting insights, data points, or steps
|
|
68
|
+
- Any specific numbers, percentages, or concrete results
|
|
69
|
+
- The core argument or main takeaway
|
|
70
|
+
|
|
71
|
+
QA checkpoint: State the core thesis and list the top insights you will use. Confirm every insight comes directly from the source. Do not proceed if you cannot verify a claim.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Step 3: Choose Thread Style
|
|
76
|
+
|
|
77
|
+
Four styles. Auto-detect from content signals. Respect explicit user override.
|
|
78
|
+
|
|
79
|
+
| Style | When to Use | Signals |
|
|
80
|
+
|-------|-------------|---------|
|
|
81
|
+
| Data/Insight | Evidence-based article with stats or research findings | Numbers, percentages, study results, data points |
|
|
82
|
+
| How-To | Tutorial, guide, or step-by-step article | Numbered lists, step headers, "how to" in title |
|
|
83
|
+
| Story/Journey | Personal experience, build log, lessons learned | First-person narrative, "I learned", "we built" |
|
|
84
|
+
| Hot Take | Opinion piece, contrarian argument | "Why X is wrong", "Stop doing X", counterintuitive claim |
|
|
85
|
+
|
|
86
|
+
Decision logic:
|
|
87
|
+
- Article has specific stats or data: Data/Insight
|
|
88
|
+
- Article is structured as steps or tips: How-To
|
|
89
|
+
- Article is first-person narrative: Story/Journey
|
|
90
|
+
- Article argues against a common belief: Hot Take
|
|
91
|
+
|
|
92
|
+
State the chosen style and reason. If ambiguous, pick one and note it.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Step 4: Read Format Rules
|
|
97
|
+
|
|
98
|
+
Read `references/thread-format.md` in full before writing any tweet. Internalize:
|
|
99
|
+
- Hook tweet rules (tweet 1 must stop the scroll)
|
|
100
|
+
- One-insight-per-tweet rule
|
|
101
|
+
- Character limit (280 per tweet, count carefully)
|
|
102
|
+
- Thread numbering format (1/8, 2/8, etc.)
|
|
103
|
+
- CTA tweet rules (final tweet only)
|
|
104
|
+
- No hashtags
|
|
105
|
+
- No em dashes
|
|
106
|
+
- Banned word list
|
|
107
|
+
|
|
108
|
+
Read `references/output-template.md` and select the template matching the chosen style.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Step 5: Generate the Thread
|
|
113
|
+
|
|
114
|
+
Produce three things:
|
|
115
|
+
|
|
116
|
+
**(A) The full thread (7-10 tweets)**
|
|
117
|
+
|
|
118
|
+
Each tweet:
|
|
119
|
+
- Under 280 characters including the tweet number ("1/8 " = 4 characters)
|
|
120
|
+
- Contains exactly one insight, step, or idea
|
|
121
|
+
- Sounds like a human typed it
|
|
122
|
+
- No URLs in tweets 1 through N-1
|
|
123
|
+
- No hashtags
|
|
124
|
+
|
|
125
|
+
**(B) The CTA tweet (final tweet)**
|
|
126
|
+
- Summarizes the key takeaway in one sentence
|
|
127
|
+
- Ends with one action: "Read the full post in the replies." or "What's your take?" or "Follow for more like this."
|
|
128
|
+
- Includes the source URL if one was provided
|
|
129
|
+
|
|
130
|
+
**(C) One alternative hook tweet**
|
|
131
|
+
- Uses a different format from the primary hook
|
|
132
|
+
- If primary used a stat, offer a question-based hook
|
|
133
|
+
- If primary used a bold claim, offer a before/after hook
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Step 6: Self-QA
|
|
138
|
+
|
|
139
|
+
Run every check before presenting. Fix violations first.
|
|
140
|
+
|
|
141
|
+
- [ ] Tweet 1 creates a curiosity gap or leads with the most surprising insight
|
|
142
|
+
- [ ] Every tweet is under 280 characters (count including tweet number)
|
|
143
|
+
- [ ] Each tweet contains exactly one idea
|
|
144
|
+
- [ ] No tweet starts with "I" (exception: Story/Journey style)
|
|
145
|
+
- [ ] No banned words in any tweet
|
|
146
|
+
- [ ] No em dashes in any tweet
|
|
147
|
+
- [ ] No hashtags in any tweet
|
|
148
|
+
- [ ] No URLs except in the final CTA tweet
|
|
149
|
+
- [ ] No invented data. Every stat and example traces to the source.
|
|
150
|
+
- [ ] Thread reads naturally in sequence
|
|
151
|
+
- [ ] Total tweet count is between 7 and 10
|
|
152
|
+
|
|
153
|
+
State total tweet count and confirm every tweet is under 280 characters before presenting.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Step 7: Post via Composio or Output
|
|
158
|
+
|
|
159
|
+
**Check for COMPOSIO_API_KEY.**
|
|
160
|
+
|
|
161
|
+
If set:
|
|
162
|
+
"Thread ready. Confirm to post to X via Composio, or say 'output only' to get the text."
|
|
163
|
+
|
|
164
|
+
On confirmation:
|
|
165
|
+
1. Post tweet 1 using action `TWITTER_CREATION_OF_A_POST` with `text` set to tweet 1 content
|
|
166
|
+
2. Capture the returned tweet ID
|
|
167
|
+
3. Post tweet 2 with `reply_in_reply_to_tweet_id` = tweet 1 ID, capture its ID
|
|
168
|
+
4. Continue for each tweet in sequence, each replying to the previous tweet's ID
|
|
169
|
+
5. Wait 1 second between posts to avoid rate limiting
|
|
170
|
+
6. After all tweets post: "Thread posted. Tweets 1-N are live."
|
|
171
|
+
|
|
172
|
+
If not set:
|
|
173
|
+
Present each tweet in a numbered list inside a code block. Add:
|
|
174
|
+
|
|
175
|
+
"To enable direct posting, add COMPOSIO_API_KEY to your .env file. See README.md for Composio setup."
|
|
176
|
+
|
|
177
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "tweet-thread-from-blog",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Turn this into a tweet thread: https://vercel.com/blog/how-we-optimized-package-imports-in-next-js",
|
|
7
|
+
"expected_output": "Agent fetches the blog post. Detects Data/Insight style (engineering post with specific performance numbers). Reads references/thread-format.md and references/output-template.md. Extracts the most surprising stat or finding as the hook. Produces 7-10 tweets, each under 280 characters including the tweet number. Every tweet contains exactly one idea. No invented data — all stats and examples trace to the source article. No hashtags in any tweet. No em dashes in any tweet. No banned words. CTA in the final tweet with source URL. Alternative hook provided. Total tweet count stated with confirmation that all tweets are under 280 chars.",
|
|
8
|
+
"files": []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": 2,
|
|
12
|
+
"prompt": "Create a Twitter thread from this tutorial: https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-20-04",
|
|
13
|
+
"expected_output": "Agent fetches the tutorial. Detects How-To style (step-by-step guide with numbered steps). Selects Template 2 (How-To) from output-template.md. Hook states the outcome or what most people miss. Each step from the guide gets its own tweet. Step tweets are concrete and actionable, not generic. Common mistake or key warning included. Result tweet explains what the reader achieves. CTA in final tweet. All tweets under 280 characters. No hashtags. No banned words. No invented steps.",
|
|
14
|
+
"files": []
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": 3,
|
|
18
|
+
"prompt": "Make a thread from this: [pasted first-person article about building a SaaS product over 4 months, including specific revenue numbers and a failed pivot]",
|
|
19
|
+
"expected_output": "Agent reads the pasted content directly — no Chrome needed. Detects Story/Journey style (first-person narrative, build log, specific outcomes). Selects Template 3. Hook captures the end result or key turning point, does not start with 'I'. Setup tweet establishes the problem. Decision tweet covers the pivot attempt. What happened tweet includes specific outcome data from the article. Lesson tweet is concrete, not generic. Advice tweet speaks directly to the reader. Takeaway tweet is for the reader, not the author. CTA in final tweet. All tweets under 280 chars. No invented revenue figures.",
|
|
20
|
+
"files": []
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": 4,
|
|
24
|
+
"prompt": "Write a thread from this opinion piece arguing that code reviews slow teams down more than they help",
|
|
25
|
+
"expected_output": "Agent reads the article. Detects Hot Take style (contrarian position, 'Why X is wrong' argument structure). Selects Template 4. Tweet 1 states the contrarian claim directly and concisely. Tweet 2 explains the common assumption. Tweet 3 presents evidence from the article. Tweet 4 states the implication. Tweet 5 steelmans the opposing view. Tweet 6 holds the position. Tweet 7 acknowledges edge cases where the claim breaks down. Final tweet CTA asks for disagreement specifically. No softening language. No hashtags. No banned words. All tweets under 280 chars.",
|
|
26
|
+
"files": []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": 5,
|
|
30
|
+
"prompt": "Turn this data-heavy performance benchmarking article into a thread but make it How-To style: [URL to article with performance statistics and methodology sections]",
|
|
31
|
+
"expected_output": "Agent fetches and reads the article. Auto-detection would select Data/Insight based on content. User explicitly requested How-To style — agent respects the override without debate. Applies Template 2 (How-To) to structure the content. Restructures the data and findings into actionable steps the reader can follow. Hook states what the reader achieves by following the steps. Body tweets are step-based, not data-based. Agent notes the style override was applied. All tweets under 280 chars. No hashtags. No invented steps beyond what the article covers.",
|
|
32
|
+
"files": []
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Output Templates
|
|
2
|
+
|
|
3
|
+
One template per thread style. Replace every [BRACKETED SLOT] with content extracted from the source. Never leave bracket text in the final output. If a step or insight is not in the source, skip that tweet rather than inventing content.
|
|
4
|
+
|
|
5
|
+
Adjust N to the actual tweet count (7-10) before numbering.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Template 1: Data/Insight
|
|
10
|
+
|
|
11
|
+
Use for evidence-based articles with stats, research findings, or data points.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
1/N [HOOK — the most surprising stat or finding from the article]
|
|
15
|
+
|
|
16
|
+
2/N [CONTEXT — what most people assume or the common approach]
|
|
17
|
+
|
|
18
|
+
3/N [FIRST DATA POINT — specific number or finding]
|
|
19
|
+
|
|
20
|
+
4/N [SECOND DATA POINT — specific number or finding]
|
|
21
|
+
|
|
22
|
+
5/N [THIRD DATA POINT OR IMPLICATION — what this means in practice]
|
|
23
|
+
|
|
24
|
+
6/N [COUNTERPOINT — the objection or nuance worth acknowledging]
|
|
25
|
+
|
|
26
|
+
7/N [TAKEAWAY — the single most useful thing to remember]
|
|
27
|
+
|
|
28
|
+
8/N [CTA — what to do next, source link if provided]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Worked example (API performance profiling article):
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
1/8 Most developers are optimising the wrong bottleneck. They profile query speed. The real problem is payload size.
|
|
35
|
+
|
|
36
|
+
2/8 Standard advice: add indexes, cache queries, tune your ORM. All fine. None of it addresses what's actually slow in 60% of cases.
|
|
37
|
+
|
|
38
|
+
3/8 We ran a trace on our most-used endpoint. 800ms response time. Query: 12ms. Serialization: 788ms. We were sending 4MB of data per request.
|
|
39
|
+
|
|
40
|
+
4/8 Switched to field selection. Users request only the fields they need. Average payload dropped from 4MB to 180KB.
|
|
41
|
+
|
|
42
|
+
5/8 Response time: 800ms to 90ms. No query changes. No cache layer. No infrastructure cost.
|
|
43
|
+
|
|
44
|
+
6/8 This doesn't apply if your queries are actually slow. Profile first. Don't assume.
|
|
45
|
+
|
|
46
|
+
7/8 The bottleneck is almost always what you're sending, not how fast you're finding it.
|
|
47
|
+
|
|
48
|
+
8/8 Full post in the replies. If this was useful, retweet tweet 1.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Template 2: How-To
|
|
54
|
+
|
|
55
|
+
Use for tutorials, guides, and step-by-step articles.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
1/N [HOOK — the result the reader achieves, or what most people miss]
|
|
59
|
+
|
|
60
|
+
2/N [WHY THIS MATTERS — the cost of not doing it, or who this is for]
|
|
61
|
+
|
|
62
|
+
3/N [STEP 1 — one action, one line]
|
|
63
|
+
|
|
64
|
+
4/N [STEP 2 — one action, one line]
|
|
65
|
+
|
|
66
|
+
5/N [STEP 3 — one action, one line]
|
|
67
|
+
|
|
68
|
+
6/N [STEP 4 OR KEY MISTAKE — common error at this stage]
|
|
69
|
+
|
|
70
|
+
7/N [RESULT — what happens when you follow the steps]
|
|
71
|
+
|
|
72
|
+
8/N [CTA]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Worked example (SSH key authentication setup):
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
1/8 You don't need a password to SSH into a server. Here's how to set it up in 10 minutes.
|
|
79
|
+
|
|
80
|
+
2/8 Password SSH leaves you open to brute force. Key auth locks that door. Most devs know this and still haven't done it.
|
|
81
|
+
|
|
82
|
+
3/8 Step 1: Generate your key pair. Run: ssh-keygen -t ed25519 -C your@email.com. Save to ~/.ssh/id_ed25519.
|
|
83
|
+
|
|
84
|
+
4/8 Step 2: Copy the public key to your server. Run: ssh-copy-id user@server-address. It adds your key to authorized_keys automatically.
|
|
85
|
+
|
|
86
|
+
5/8 Step 3: Test the connection. Run: ssh user@server-address. No password prompt means it worked.
|
|
87
|
+
|
|
88
|
+
6/8 Common mistake: forgetting to restrict permissions. Run chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys on the server.
|
|
89
|
+
|
|
90
|
+
7/8 Once this is set up, you never type that password again. Every other tool — rsync, SCP, Git over SSH — inherits the key auth.
|
|
91
|
+
|
|
92
|
+
8/8 Full step-by-step in the replies. Works on Linux, macOS, and WSL.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Template 3: Story/Journey
|
|
98
|
+
|
|
99
|
+
Use for personal experience articles, build logs, and lessons-learned posts.
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
1/N [HOOK — the end result or the key moment that changed things. Does not start with "I".]
|
|
103
|
+
|
|
104
|
+
2/N [SETUP — where you started, the problem]
|
|
105
|
+
|
|
106
|
+
3/N [DECISION — what you tried or changed]
|
|
107
|
+
|
|
108
|
+
4/N [WHAT HAPPENED — the unexpected result or outcome]
|
|
109
|
+
|
|
110
|
+
5/N [WHAT YOU LEARNED — the lesson]
|
|
111
|
+
|
|
112
|
+
6/N [WHAT YOU'D DO DIFFERENTLY — the advice for others]
|
|
113
|
+
|
|
114
|
+
7/N [TAKEAWAY — for the reader, not just you]
|
|
115
|
+
|
|
116
|
+
8/N [CTA]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Worked example (indie hacker launch story):
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
1/8 After 6 months of building in silence, we shipped. First paying customer came 4 hours later. Here's what went right and what nearly didn't.
|
|
123
|
+
|
|
124
|
+
2/8 We built a tool for devs to monitor API latency across providers. Nothing fancy. The problem was real — we had it ourselves.
|
|
125
|
+
|
|
126
|
+
3/8 3 months in, we almost pivoted. Users kept asking for Slack alerts. We said no. Stayed focused on the core latency chart.
|
|
127
|
+
|
|
128
|
+
4/8 Launch day: posted on HN Show. Got 230 upvotes. 140 signups in 24 hours. 3 converted to paid on day 1.
|
|
129
|
+
|
|
130
|
+
5/8 The Slack alerts users asked for? We shipped them in month 4. They became our top retention driver. We just needed to earn the right to build them.
|
|
131
|
+
|
|
132
|
+
6/8 Ship the dumb simple version first. Not because it's faster. Because it tells you what actually matters.
|
|
133
|
+
|
|
134
|
+
7/8 Feature requests are noise until you have users. Users tell you which noise is signal.
|
|
135
|
+
|
|
136
|
+
8/8 Full build log in the replies. What would you have done differently?
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Template 4: Hot Take
|
|
142
|
+
|
|
143
|
+
Use for opinion pieces, contrarian arguments, and counterintuitive claims.
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
1/N [THE CLAIM — the contrarian position stated directly]
|
|
147
|
+
|
|
148
|
+
2/N [THE ASSUMPTION — what most people believe and why]
|
|
149
|
+
|
|
150
|
+
3/N [THE EVIDENCE — what you actually observed or data that supports the claim]
|
|
151
|
+
|
|
152
|
+
4/N [THE IMPLICATION — what changes if the claim is true]
|
|
153
|
+
|
|
154
|
+
5/N [THE COUNTERARGUMENT — steelman the other side]
|
|
155
|
+
|
|
156
|
+
6/N [THE REBUTTAL — why you still hold the position]
|
|
157
|
+
|
|
158
|
+
7/N [THE NUANCE — when are you wrong? edge cases?]
|
|
159
|
+
|
|
160
|
+
8/N [CTA — ask for disagreement: "Tell me why I'm wrong."]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Worked example (standups are waste):
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
1/8 Daily standups don't solve coordination problems. They create them.
|
|
167
|
+
|
|
168
|
+
2/8 The logic: if everyone knows what everyone else is doing, blockers surface faster. Reasonable assumption. Wrong conclusion.
|
|
169
|
+
|
|
170
|
+
3/8 We tracked 3 months of standups. Average useful information exchanged per person: 12 seconds. Average time lost to context switching: 23 minutes per attendee.
|
|
171
|
+
|
|
172
|
+
4/8 If standups are your coordination layer, async is your alternative. But most teams treat async as standups with a time delay.
|
|
173
|
+
|
|
174
|
+
5/8 The counterargument: standups build team cohesion. True. But you can build cohesion cheaper with better rituals.
|
|
175
|
+
|
|
176
|
+
6/8 The real function of standups is making managers feel informed. That's a legitimate need. It's not a coordination mechanism.
|
|
177
|
+
|
|
178
|
+
7/8 This breaks down for teams that are genuinely blocked on each other daily. Short-cycle integration work, for instance. Know your context.
|
|
179
|
+
|
|
180
|
+
8/8 Tell me why I'm wrong. Full piece in the replies.
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Fill-in Rules
|
|
186
|
+
|
|
187
|
+
1. Replace every [BRACKETED SLOT] with content from the source material
|
|
188
|
+
2. Never leave bracket text in the output
|
|
189
|
+
3. Count characters for every tweet including the "N/N " prefix
|
|
190
|
+
4. Apply Writing Style rules: no em dashes, no semicolons, no banned words, no hashtags
|
|
191
|
+
5. If a step or point is not in the source, skip that tweet rather than inventing content
|
|
192
|
+
6. Adjust N to the actual tweet count (7-10)
|
|
193
|
+
7. The CTA tweet always goes last, always contains the source URL if one was provided
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Thread Format Reference
|
|
2
|
+
|
|
3
|
+
Rules and conventions for writing Twitter/X threads. Read this in full before generating any thread.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Section 1: Why Format Matters
|
|
8
|
+
|
|
9
|
+
Tweet 1 is all that appears in the feed. Everything depends on the hook.
|
|
10
|
+
|
|
11
|
+
Threads with 8-12 tweets outperform shorter threads by roughly 47% on engagement (Buffer/Sprout Social data). One idea per tweet makes each tweet independently shareable. Completion rate drops through the middle tweets and spikes again on the final tweet.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Section 2: Hook Tweet Rules (Tweet 1)
|
|
16
|
+
|
|
17
|
+
The hook must:
|
|
18
|
+
- Lead with the most surprising, counterintuitive, or valuable insight from the source
|
|
19
|
+
- Create a curiosity gap — the reader wants to know the rest
|
|
20
|
+
- Stand alone as a compelling statement
|
|
21
|
+
|
|
22
|
+
Hook formats that work:
|
|
23
|
+
|
|
24
|
+
| Format | Example |
|
|
25
|
+
|--------|---------|
|
|
26
|
+
| Specific stat | "Most developers waste 40% of their debugging time on the wrong layer." |
|
|
27
|
+
| Bold claim | "The advice every senior engineer gives is wrong." |
|
|
28
|
+
| Question | "What would you do if your prod DB went down and your backup was corrupt?" |
|
|
29
|
+
| Before/after | "3 months ago our API took 1.2s. Now it takes 90ms. Here's what we changed." |
|
|
30
|
+
| Counterintuitive | "Slower shipping made our team faster." |
|
|
31
|
+
|
|
32
|
+
Do NOT open with:
|
|
33
|
+
- "A thread on [topic]:"
|
|
34
|
+
- "Let me share"
|
|
35
|
+
- "Today I want to talk about"
|
|
36
|
+
- "Quick thread:"
|
|
37
|
+
- Anything that announces the thread instead of starting it
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Section 3: Body Tweet Rules (Tweets 2 to N-1)
|
|
42
|
+
|
|
43
|
+
- One idea per tweet, no more
|
|
44
|
+
- If a tweet can be split into two, split it
|
|
45
|
+
- 280 chars max including tweet number ("3/9 " = 4 characters)
|
|
46
|
+
- Use line breaks inside tweets for readability (2 lines max)
|
|
47
|
+
- Specifics beat generics ("saved 4 hours/week" beats "saved time")
|
|
48
|
+
- Numbers, examples, and quotes from the source are your best material
|
|
49
|
+
- Conversational tone: contractions, plain words, direct address ("you" not "one")
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Section 4: CTA Tweet Rules (Final Tweet)
|
|
54
|
+
|
|
55
|
+
End with exactly one action. Options:
|
|
56
|
+
|
|
57
|
+
- **Link CTA:** "Full post in the replies." (then post the URL as a reply after the thread)
|
|
58
|
+
- **Engagement CTA:** "What's your experience with this? Reply below."
|
|
59
|
+
- **Follow CTA:** "Follow [handle] for more posts like this." (only if user provides their handle)
|
|
60
|
+
- **Retweet CTA:** "If this was useful, retweet tweet 1 so others see it."
|
|
61
|
+
|
|
62
|
+
Do NOT combine multiple CTAs. Do NOT use "let me know your thoughts" — it's low signal.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Section 5: Thread Numbering
|
|
67
|
+
|
|
68
|
+
Format: "1/8" at the start of each tweet. "8/8" for the final tweet.
|
|
69
|
+
|
|
70
|
+
Example tweet 1: `1/8 Most developers are optimising the wrong bottleneck.`
|
|
71
|
+
Example tweet 8: `8/8 The bottleneck is almost always what you're sending, not how fast you're finding it. Full post in the replies.`
|
|
72
|
+
|
|
73
|
+
Always number. Readers use numbers to track how far they are in the thread.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Section 6: Banned Words
|
|
78
|
+
|
|
79
|
+
Do not use any of these in any tweet:
|
|
80
|
+
|
|
81
|
+
incredible, amazing, leveraging, synergize, game-changing, game changer, let's dive in, buckle up, it's worth noting, delve, harness, unlock, groundbreaking, cutting-edge, remarkable, paradigm, revolutionize, disruptive, transformative, thrilled, excited to share, powerful, innovative, comprehensive, actionable, crucial, vital, pivotal, elucidate, utilize, can, may, just, that, very, really, literally, actually, certainly, probably, basically, could, maybe
|
|
82
|
+
|
|
83
|
+
If a draft tweet contains any banned word, rewrite before presenting.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Section 7: No Hashtags
|
|
88
|
+
|
|
89
|
+
Do not include hashtags in any tweet. Hashtags reduce the quality signal of technical threads and are not needed for reach in reply chains.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Section 8: Validation Checklist
|
|
94
|
+
|
|
95
|
+
Run before presenting. Fix all violations first.
|
|
96
|
+
|
|
97
|
+
- [ ] Tweet 1 creates a curiosity gap or leads with most surprising insight
|
|
98
|
+
- [ ] Every tweet is under 280 characters (including tweet number)
|
|
99
|
+
- [ ] Each tweet contains exactly one idea
|
|
100
|
+
- [ ] No tweet starts with "I" (unless Story/Journey style)
|
|
101
|
+
- [ ] No banned words in any tweet
|
|
102
|
+
- [ ] No em dashes in any tweet
|
|
103
|
+
- [ ] No hashtags anywhere
|
|
104
|
+
- [ ] No URLs except in the CTA tweet
|
|
105
|
+
- [ ] No invented data
|
|
106
|
+
- [ ] Thread reads naturally in sequence
|
|
107
|
+
- [ ] Total tweet count is 7-10
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Twitter GTM Find Skill
|
|
2
|
+
|
|
3
|
+
<img width="1280" height="640" alt="Generated_chart__twitter-gtm-find-cover-bw png" src="https://github.com/user-attachments/assets/618b0abe-34fc-4c3e-a345-1a3eaeb3d20b" />
|
|
4
|
+
|
|
5
|
+
This repository contains the `twitter-GTM-find/` AI Skill.
|
|
6
|
+
|
|
7
|
+
This pipeline automates the discovery of highly-targeted, Developer-First startups hiring for Go-To-Market (GTM), Developer Relations (DevRel), and Growth roles by scraping Twitter (via Apify) and automatically verifying the startups' funding and product type using Gemini's native Google Search Grounding.
|
|
8
|
+
|
|
9
|
+
## The Skill Directory
|
|
10
|
+
|
|
11
|
+
All executable code and documentation are packaged cleanly inside the `twitter-GTM-find/` folder. This is designed to be directly imported and read by AI agents (like OpenClaw or Claude) so they understand how to use the tool.
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
twitter-GTM-find/
|
|
15
|
+
├── SKILL.md <-- The AI entry point and documentation
|
|
16
|
+
├── references/
|
|
17
|
+
│ └── icp-checklist.md <-- The strict evaluation criteria (Dev-first + $100K+ funded)
|
|
18
|
+
└── scripts/
|
|
19
|
+
├── run_pipeline.sh <-- The executable shell script
|
|
20
|
+
└── src/ <-- The TypeScript pipeline source code
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
To run the pipeline manually or via an agent:
|
|
26
|
+
|
|
27
|
+
1. Create a `.env` file at the root of the repository:
|
|
28
|
+
```env
|
|
29
|
+
APIFY_API_TOKEN=your_apify_token
|
|
30
|
+
GEMINI_API_KEY=your_gemini_api_key
|
|
31
|
+
MAX_POSTS=20
|
|
32
|
+
```
|
|
33
|
+
2. Run the shell script:
|
|
34
|
+
```bash
|
|
35
|
+
cd twitter-GTM-find/scripts
|
|
36
|
+
bash run_pipeline.sh
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
|
|
41
|
+
The pipeline generates two temporary files at the root of the repository (which are `.gitignore`d to prevent leaking data):
|
|
42
|
+
- `radar-jobs.json`: The initial raw batch of scraped tech jobs.
|
|
43
|
+
- `openclaw-icp-jobs.json`: The final, strict ICP-validated list of highly funded, developer-first startups hiring right now.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: twitter-GTM-find-Skill
|
|
3
|
+
description: End-to-end pipeline for scraping Twitter for GTM/DevRel tech startup jobs using Apify, and validating them against an Ideal Customer Profile (ICP) using Gemini's native Google Search Grounding. Use this skill when OpenClaw needs to find developer-first, funded startups actively hiring for GTM, DevRel, or Growth roles.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Twitter GTM Find Skill
|
|
7
|
+
|
|
8
|
+
This skill provides an automated pipeline to scrape Twitter for Developer-First startups hiring GTM/DevRel roles, followed by an automatic web-search verification step to validate them against our Ideal Customer Profile (ICP).
|
|
9
|
+
|
|
10
|
+
## Using the Pipeline
|
|
11
|
+
|
|
12
|
+
You can run the full pipeline using the executable Node.js project bundled in `scripts/`.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd scripts
|
|
16
|
+
npm install
|
|
17
|
+
npx ts-node src/index.ts
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Requirements:**
|
|
21
|
+
A `.env` file must be present at the workspace root with:
|
|
22
|
+
- `APIFY_API_TOKEN` (Apify account access)
|
|
23
|
+
- `GEMINI_API_KEY` (Gemini 3 Flash Preview with Search Grounding)
|
|
24
|
+
- `MAX_POSTS=20` (Optional limit)
|
|
25
|
+
|
|
26
|
+
## Outputs
|
|
27
|
+
|
|
28
|
+
The script handles two primary JSON files:
|
|
29
|
+
1. `radar-jobs.json`: The initial raw batch of tech jobs identified by the scraper.
|
|
30
|
+
2. `openclaw-icp-jobs.json`: The **final validated file** OpenClaw should ingest, containing only companies that passed the strict web-search evaluation.
|
|
31
|
+
|
|
32
|
+
## References
|
|
33
|
+
|
|
34
|
+
For deeper context on how the evaluation works or modifying the pipeline, read these files as needed:
|
|
35
|
+
|
|
36
|
+
- **ICP Checklist**: See [references/icp-checklist.md](references/icp-checklist.md) for the exact strict evaluation criteria (Developer-first + $100K minimum funding).
|
|
37
|
+
- **Gemini Search Grounding**: The pipeline (`scripts/src/icp-filter.ts`) natively uses Google Search Grounding via the `@google/generative-ai` SDK (`gemini-3-flash-preview` / `gemini-flash-latest`) to look up live funding and product data.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Ideal Customer Profile (ICP) Checklist
|
|
2
|
+
|
|
3
|
+
When evaluating whether a scraped company meets our OpenClaw ICP, follow these strict guidelines.
|
|
4
|
+
|
|
5
|
+
## 1. Developer-First Product
|
|
6
|
+
**What qualifies:**
|
|
7
|
+
* API platforms, infrastructure tools, SDKs, dev utilities
|
|
8
|
+
* AI agents/automation for technical workflows
|
|
9
|
+
* DevOps, CI/CD, monitoring, analytics
|
|
10
|
+
* Code editors, Data infrastructure, LLM deployment platforms
|
|
11
|
+
|
|
12
|
+
**Auto-skip (NOT ICP):**
|
|
13
|
+
* Consumer apps, B2C SaaS
|
|
14
|
+
* HR tools, Recruiting agencies
|
|
15
|
+
* Pure Fintech or Healthcare software
|
|
16
|
+
* Traditional physical industries (Real estate, Automotive, Clinics)
|
|
17
|
+
|
|
18
|
+
## 2. Funding Evidence
|
|
19
|
+
**Minimum requirement:**
|
|
20
|
+
* $100K+ raised (verifiable via Crunchbase, YC, press, founder posts)
|
|
21
|
+
|
|
22
|
+
**Preferred:**
|
|
23
|
+
* $500K-$5M seed/Series A in the last 18 months
|
|
24
|
+
* Backed by Y Combinator (YC), a16z, Sequoia
|
|
25
|
+
|
|
26
|
+
**Skip if (NOT ICP):**
|
|
27
|
+
* Purely bootstrapped companies with zero external capital mentioned
|
|
28
|
+
* Service agencies with no product (even if they do tech/web3 marketing)
|
|
29
|
+
* No verifiable funding evidence found online
|
|
30
|
+
|
|
31
|
+
## Evaluation Process
|
|
32
|
+
1. Research the company's official website to determine the product type.
|
|
33
|
+
2. Search "[Company Name] funding Crunchbase Y Combinator" to find capital raised.
|
|
34
|
+
3. If they are a dev-first/infrastructure/AI tool AND have funding -> `isICP` is `true`.
|
|
35
|
+
4. If they fail EITHER criteria -> `isICP` is `false`.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "twitter-gtm-jobs-radar",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"type": "commonjs",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@google/generative-ai": "^0.24.1",
|
|
15
|
+
"apify-client": "^2.22.3",
|
|
16
|
+
"dotenv": "^17.3.1"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^25.5.0",
|
|
20
|
+
"ts-node": "^10.9.2",
|
|
21
|
+
"typescript": "^5.9.3"
|
|
22
|
+
}
|
|
23
|
+
}
|