@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,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explain-this-pr
|
|
3
|
+
description: Takes a GitHub PR URL or the current branch and writes a plain-English explanation of what it does and why, then posts it as a PR comment. Use when asked to explain a PR, summarize a pull request, write a plain-English description of a PR, add a summary comment to a PR, or understand what a PR changes. Trigger when a user says "explain this PR", "summarize this pull request", "what does this PR do", "add a comment explaining the PR", or shares a GitHub PR URL and asks what it does.
|
|
4
|
+
compatibility: [claude-code, gemini-cli, github-copilot]
|
|
5
|
+
author: OpenDirectory
|
|
6
|
+
version: 1.0.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Explain This PR
|
|
10
|
+
|
|
11
|
+
Read a GitHub pull request, understand what it changes, and write a plain-English explanation. Post it as a PR comment so reviewers have instant context.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Step 1: Check Setup
|
|
16
|
+
|
|
17
|
+
Confirm `gh` is authenticated:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
gh auth status
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If not authenticated: `gh auth login` and follow the prompts.
|
|
24
|
+
|
|
25
|
+
Confirm input. The user must provide one of:
|
|
26
|
+
- A GitHub PR URL (e.g. `https://github.com/owner/repo/pull/123`)
|
|
27
|
+
- A PR number in the current repo (e.g. `#123`)
|
|
28
|
+
- The keyword "current" to use the PR for the current branch
|
|
29
|
+
|
|
30
|
+
If no input, ask: "Which PR should I explain? Share the URL, PR number, or say 'current' for the active branch."
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 2: Fetch PR Context
|
|
35
|
+
|
|
36
|
+
**Get PR metadata:**
|
|
37
|
+
```bash
|
|
38
|
+
gh pr view PR_URL_OR_NUMBER --json number,url,title,body,author,baseRefName,headRefName,additions,deletions,changedFiles,commits,labels,state,isDraft
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `isDraft` is `true`, note this to the user: "This PR is still in draft. The explanation is based on its current state."
|
|
42
|
+
|
|
43
|
+
**Get the diff:**
|
|
44
|
+
```bash
|
|
45
|
+
gh pr diff PR_URL_OR_NUMBER
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If the diff is over 400 lines, read the `--stat` summary and the first 200 lines of the diff:
|
|
49
|
+
```bash
|
|
50
|
+
gh pr view PR_URL_OR_NUMBER --json files
|
|
51
|
+
gh pr diff PR_URL_OR_NUMBER | head -200
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Get existing comments (to avoid repeating what is already there):**
|
|
55
|
+
```bash
|
|
56
|
+
gh pr view PR_URL_OR_NUMBER --json comments --jq '.comments[].body' 2>/dev/null | head -20
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Step 3: Write the Explanation
|
|
62
|
+
|
|
63
|
+
Write two paragraphs. Read each rule before writing.
|
|
64
|
+
|
|
65
|
+
**Paragraph 1: What it does (technical)**
|
|
66
|
+
|
|
67
|
+
- One sentence per major change
|
|
68
|
+
- Name the specific files, functions, or systems that changed
|
|
69
|
+
- State the before/after if the diff makes it clear
|
|
70
|
+
- Include concrete numbers if present in the diff (lines removed, tables dropped, endpoints added)
|
|
71
|
+
- Active voice, present tense
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
```
|
|
75
|
+
Replaces the in-memory session cache in auth.middleware.ts with a Redis-backed cache (src/cache/redis.ts). Adds get, set, and invalidate methods to the new Redis module and wraps UserService.getById() with a 5-minute TTL. Removes the Map-based cache that was limited to a single process and caused session drift across multiple instances.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Paragraph 2: Why it matters (business/product impact)**
|
|
79
|
+
|
|
80
|
+
- Who benefits and how
|
|
81
|
+
- What problem this solves or what risk it reduces
|
|
82
|
+
- If the commit messages contain a "why", use that context
|
|
83
|
+
- If there is no clear "why" in the diff or commits, omit this paragraph rather than guessing
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
```
|
|
87
|
+
Users hitting the /api/me endpoint under load were getting inconsistent session data across server instances, causing intermittent 401 errors. This change makes session state consistent across all instances and reduces database load by eliminating one query per authenticated request.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Rules for both paragraphs:**
|
|
91
|
+
- No em dashes — use a comma or period
|
|
92
|
+
- No filler: "this PR", "this change", "as you can see"
|
|
93
|
+
- No invented outcomes. Only state impacts that are directly visible in the diff or commit messages
|
|
94
|
+
- If the PR is a pure refactor with no behavior change, say that explicitly: "Refactors X to Y with no change in observable behavior."
|
|
95
|
+
- Under 150 words total
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Step 4: Self-QA
|
|
100
|
+
|
|
101
|
+
Before posting, check:
|
|
102
|
+
|
|
103
|
+
- [ ] Paragraph 1 names specific files or functions from the diff
|
|
104
|
+
- [ ] No invented metrics or outcomes
|
|
105
|
+
- [ ] No em dashes
|
|
106
|
+
- [ ] No filler phrases
|
|
107
|
+
- [ ] Under 150 words total
|
|
108
|
+
- [ ] If no clear "why" exists, paragraph 2 is omitted rather than guessing
|
|
109
|
+
|
|
110
|
+
Fix any violation before posting.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Step 5: Post as PR Comment
|
|
115
|
+
|
|
116
|
+
Present the explanation to the user. Ask: "Ready to post this as a PR comment, or would you like to edit it first?"
|
|
117
|
+
|
|
118
|
+
On confirmation, pass the body via stdin to handle backticks, quotes, and newlines safely:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
gh pr comment PR_URL_OR_NUMBER --body-file - << 'EOF'
|
|
122
|
+
EXPLANATION_HERE
|
|
123
|
+
EOF
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
After posting: "Comment added. View it at: [url from Step 2]"
|
|
127
|
+
|
|
128
|
+
If the user says "output only", present the explanation in a code block for manual copy-paste without posting.
|
|
129
|
+
|
|
130
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "explain-this-pr",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Explain this PR: https://github.com/vercel/next.js/pull/12345",
|
|
7
|
+
"expected_output": "Agent runs gh pr view with the URL to get metadata (title, author, additions, deletions, changedFiles, commits). Runs gh pr diff to get the full diff. Writes two paragraphs: paragraph 1 names specific files/functions that changed (active voice, present tense, concrete details from the diff); paragraph 2 explains the business or product impact using context from the PR body or commit messages. Total under 150 words. No em dashes. No invented metrics. Asks user to confirm before posting as a comment.",
|
|
8
|
+
"files": []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": 2,
|
|
12
|
+
"prompt": "Add a plain-English summary comment to PR #42 in this repo",
|
|
13
|
+
"expected_output": "Agent resolves '#42' as a PR number in the current repo. Fetches PR metadata and diff. Writes the two-paragraph explanation. Runs gh pr comment 42 --body 'explanation'. Confirms 'Comment added. View it at: [URL]'.",
|
|
14
|
+
"files": []
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": 3,
|
|
18
|
+
"prompt": "What does this PR change? https://github.com/owner/repo/pull/99",
|
|
19
|
+
"expected_output": "Agent fetches PR metadata and diff. If the PR is a pure refactor with no behavior change, paragraph 1 says that explicitly. If there are no commit messages explaining why, paragraph 2 is omitted entirely rather than guessing at business impact. Output is under 150 words. Agent presents the explanation and asks whether to post it or output only.",
|
|
20
|
+
"files": []
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": 4,
|
|
24
|
+
"prompt": "Explain the current branch PR",
|
|
25
|
+
"expected_output": "Agent runs gh pr view without a PR number to get the PR for the current branch. If no PR exists yet for the current branch, agent informs the user and asks if they want to create one first (suggests using pr-description-writer skill). If a PR exists, proceeds normally with the two-paragraph explanation.",
|
|
26
|
+
"files": []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": 5,
|
|
30
|
+
"prompt": "Explain this large PR but just give me the text, don't post it",
|
|
31
|
+
"expected_output": "Agent fetches PR context. The diff is over 400 lines, so agent reads --stat and the first 200 lines of the diff rather than the full diff. Generates the two-paragraph explanation from the available context. Notes which parts of the diff were not read. Presents the explanation in a code block without running gh pr comment. Does not ask about posting.",
|
|
32
|
+
"files": []
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Google Trends API Skills
|
|
2
|
+
|
|
3
|
+
<img width="1280" height="640" alt="google-trends-skills-cover" src="https://github.com/user-attachments/assets/848aa1be-64af-4b4b-bf46-af3d0798b7ee" />
|
|
4
|
+
|
|
5
|
+
Agent Skills for SEO keyword research using Google Trends data via SerpApi. Built for AI agents that generate tech and developer-focused blog content.
|
|
6
|
+
|
|
7
|
+
## Skills
|
|
8
|
+
|
|
9
|
+
### 1. `google-trends-api/`
|
|
10
|
+
The API layer — knows how to query Google Trends through SerpApi, handle responses, manage rate limits, and cache results.
|
|
11
|
+
|
|
12
|
+
### 2. `seo-keyword-research/`
|
|
13
|
+
The SEO workflow — uses Google Trends data to find breakout keywords, build content structure, and generate SEO-optimized blog outlines.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 1. Get a free API key (250 searches/month)
|
|
19
|
+
# https://serpapi.com/
|
|
20
|
+
|
|
21
|
+
# 2. Set your key
|
|
22
|
+
export SERPAPI_KEY="your_key_here"
|
|
23
|
+
|
|
24
|
+
# 3. Install dependency
|
|
25
|
+
pip install requests
|
|
26
|
+
|
|
27
|
+
# 4. Run keyword research for a blog topic
|
|
28
|
+
python seo-keyword-research/scripts/blog_seo_research.py "kubernetes deployment"
|
|
29
|
+
|
|
30
|
+
# 5. Or just discover trending keywords
|
|
31
|
+
python google-trends-api/scripts/discover_keywords.py "AI developer tools"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Directory Structure
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
google-trends-api/
|
|
38
|
+
├── SKILL.md # API skill (endpoints, params, usage)
|
|
39
|
+
├── scripts/
|
|
40
|
+
│ └── discover_keywords.py # Keyword discovery script
|
|
41
|
+
└── references/
|
|
42
|
+
└── api-responses.md # Full API response structures
|
|
43
|
+
|
|
44
|
+
seo-keyword-research/
|
|
45
|
+
├── SKILL.md # SEO workflow skill (research -> outline)
|
|
46
|
+
├── scripts/
|
|
47
|
+
│ └── blog_seo_research.py # Full blog SEO research script
|
|
48
|
+
└── references/
|
|
49
|
+
├── keyword-placement-guide.md # Detailed keyword placement rules
|
|
50
|
+
└── tech-blog-examples.md # Real examples for tech/dev blogs
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## How It Works
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
User: "Write a blog about kubernetes deployment"
|
|
57
|
+
|
|
|
58
|
+
v
|
|
59
|
+
[google-trends-api] RELATED_QUERIES -> finds "kubernetes vs docker" (Breakout!)
|
|
60
|
+
[google-trends-api] RELATED_TOPICS -> finds "Helm", "CI/CD", "Container Orchestration"
|
|
61
|
+
|
|
|
62
|
+
v
|
|
63
|
+
[seo-keyword-research] Selects primary keyword, builds outline
|
|
64
|
+
|
|
|
65
|
+
v
|
|
66
|
+
Output: SEO-optimized blog outline targeting trending keywords
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Specification
|
|
70
|
+
|
|
71
|
+
These skills follow the [Agent Skills specification](https://agentskills.io/specification). Each skill has:
|
|
72
|
+
- `SKILL.md` with YAML frontmatter (name, description, compatibility, metadata)
|
|
73
|
+
- `scripts/` for executable code
|
|
74
|
+
- `references/` for detailed documentation (loaded on demand)
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: google-trends-api
|
|
3
|
+
description: Query Google Trends data via SerpApi for search trend analysis, keyword discovery, topic comparison, and geographic interest patterns. Use when users need trending keyword data, want to compare search terms, or need Google Trends insights for content planning.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Requires network access and a SerpApi API key (SERPAPI_KEY environment variable). Free tier provides 250 searches/month.
|
|
6
|
+
metadata:
|
|
7
|
+
author: farizanjum
|
|
8
|
+
version: "2.0"
|
|
9
|
+
api-provider: serpapi
|
|
10
|
+
allowed-tools: Bash(curl:*) Bash(python:*) Read
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Google Trends API Skill
|
|
14
|
+
|
|
15
|
+
Query Google Trends data through SerpApi to discover trending keywords, compare topics, and analyze search interest patterns.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- **API Key**: Set `SERPAPI_KEY` environment variable with your SerpApi key
|
|
20
|
+
- **Free Tier**: 250 searches/month (no credit card required)
|
|
21
|
+
- **Sign Up**: https://serpapi.com/
|
|
22
|
+
|
|
23
|
+
## API Basics
|
|
24
|
+
|
|
25
|
+
**Base URL**: `https://serpapi.com/search`
|
|
26
|
+
|
|
27
|
+
Every request requires these parameters:
|
|
28
|
+
- `engine=google_trends`
|
|
29
|
+
- `api_key` — your SerpApi private key
|
|
30
|
+
- `q` — 1-5 comma-separated queries (max 100 chars each)
|
|
31
|
+
- `data_type` — one of the types below
|
|
32
|
+
|
|
33
|
+
## Data Types
|
|
34
|
+
|
|
35
|
+
| Type | Max Queries | Purpose |
|
|
36
|
+
|------|-------------|---------|
|
|
37
|
+
| `RELATED_QUERIES` | 1 | Discover related search queries (rising + top) |
|
|
38
|
+
| `RELATED_TOPICS` | 1 | Discover related topics searched by same users |
|
|
39
|
+
| `TIMESERIES` | 5 | Track interest over time, compare terms |
|
|
40
|
+
| `GEO_MAP_0` | 1 | Regional interest for a single query |
|
|
41
|
+
| `GEO_MAP` | 5 | Regional comparison of multiple queries |
|
|
42
|
+
|
|
43
|
+
## Common Parameters
|
|
44
|
+
|
|
45
|
+
### Time Ranges (`date`)
|
|
46
|
+
|
|
47
|
+
| Value | Period | Best For |
|
|
48
|
+
|-------|--------|----------|
|
|
49
|
+
| `today 3-m` | Past 3 months | Current trends, SEO research |
|
|
50
|
+
| `today 12-m` | Past year | Trend validation |
|
|
51
|
+
| `today 5-y` | Past 5 years | Seasonal patterns |
|
|
52
|
+
| `now 7-d` | Last 7 days | Breaking trends |
|
|
53
|
+
| `all` | 2004-present | Historical analysis |
|
|
54
|
+
|
|
55
|
+
### Geographic (`geo`)
|
|
56
|
+
|
|
57
|
+
- `""` (empty) = Worldwide
|
|
58
|
+
- `US` = United States, `GB` = United Kingdom, `CA` = Canada
|
|
59
|
+
- `US-CA` = California (state-level)
|
|
60
|
+
|
|
61
|
+
### Region Granularity (`region`)
|
|
62
|
+
|
|
63
|
+
`COUNTRY` | `REGION` | `DMA` | `CITY`
|
|
64
|
+
|
|
65
|
+
### Platform (`gprop`)
|
|
66
|
+
|
|
67
|
+
- *(empty)* = Web Search (default)
|
|
68
|
+
- `youtube` | `news` | `images` | `froogle` (Shopping)
|
|
69
|
+
|
|
70
|
+
## Making Requests
|
|
71
|
+
|
|
72
|
+
### RELATED_QUERIES — Find related searches
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
curl -s "https://serpapi.com/search?engine=google_trends&q=kubernetes&data_type=RELATED_QUERIES&date=today+3-m&api_key=$SERPAPI_KEY"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Response structure** — see [references/api-responses.md](references/api-responses.md) for full details:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"related_queries": {
|
|
83
|
+
"rising": [
|
|
84
|
+
{"query": "kubernetes vs docker", "formatted_value": "Breakout"},
|
|
85
|
+
{"query": "kubernetes tutorial 2024", "formatted_value": "+180%"}
|
|
86
|
+
],
|
|
87
|
+
"top": [
|
|
88
|
+
{"query": "kubernetes deployment", "value": 100}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- **"Breakout"** = 5000%+ growth — highest opportunity
|
|
95
|
+
- **"+N%"** = year-over-year growth percentage
|
|
96
|
+
|
|
97
|
+
### RELATED_TOPICS — Find related topics
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
curl -s "https://serpapi.com/search?engine=google_trends&q=kubernetes&data_type=RELATED_TOPICS&date=today+3-m&api_key=$SERPAPI_KEY"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Returns rising and top topics with titles and types.
|
|
104
|
+
|
|
105
|
+
### TIMESERIES — Interest over time
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
curl -s "https://serpapi.com/search?engine=google_trends&q=react,vue,angular&data_type=TIMESERIES&date=today+12-m&api_key=$SERPAPI_KEY"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Supports up to 5 comma-separated queries for comparison. Returns timeline data with interest values (0-100 scale).
|
|
112
|
+
|
|
113
|
+
### GEO_MAP_0 — Regional interest (single query)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
curl -s "https://serpapi.com/search?engine=google_trends&q=kubernetes&data_type=GEO_MAP_0&geo=US®ion=REGION&api_key=$SERPAPI_KEY"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### GEO_MAP — Regional comparison (multi-query)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
curl -s "https://serpapi.com/search?engine=google_trends&q=react,vue&data_type=GEO_MAP&geo=US®ion=REGION&api_key=$SERPAPI_KEY"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Error Handling
|
|
126
|
+
|
|
127
|
+
Always check `search_metadata.status` in the response:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
if response.get("search_metadata", {}).get("status") != "Success":
|
|
131
|
+
error = response.get("error", "Unknown error")
|
|
132
|
+
# Handle: invalid key, rate limit, malformed query, etc.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Common errors:
|
|
136
|
+
- **"Invalid API key"** — check SERPAPI_KEY is set correctly
|
|
137
|
+
- **"No results"** — query too niche, try broader terms
|
|
138
|
+
- **"Monthly limit exceeded"** — 250 free searches used up
|
|
139
|
+
|
|
140
|
+
## Rate Limit & Budget
|
|
141
|
+
|
|
142
|
+
- **Free tier**: 250 searches/month
|
|
143
|
+
- Failed searches are automatically refunded
|
|
144
|
+
- No strict per-second rate limit, but space requests reasonably
|
|
145
|
+
- Cache results for 7-14 days (trends don't change hourly)
|
|
146
|
+
- Batch up to 5 queries in TIMESERIES/GEO_MAP calls to save credits
|
|
147
|
+
|
|
148
|
+
## Example Script
|
|
149
|
+
|
|
150
|
+
Run the discovery script for a quick keyword lookup:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
python scripts/discover_keywords.py "your topic here"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
See [scripts/discover_keywords.py](scripts/discover_keywords.py) for the full implementation.
|
|
157
|
+
|
|
158
|
+
## References
|
|
159
|
+
|
|
160
|
+
- [references/api-responses.md](references/api-responses.md) — Full response structures for all data types
|
|
161
|
+
- [SerpApi Docs](https://serpapi.com/google-trends-api) — Official API documentation
|
|
162
|
+
- [API Playground](https://serpapi.com/playground?engine=google_trends) — Test queries interactively
|
|
163
|
+
- [Dashboard](https://serpapi.com/dashboard) — Track API usage
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# API Response Structures
|
|
2
|
+
|
|
3
|
+
Full response examples for each Google Trends data type.
|
|
4
|
+
|
|
5
|
+
## RELATED_QUERIES
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"search_metadata": {
|
|
10
|
+
"status": "Success",
|
|
11
|
+
"id": "...",
|
|
12
|
+
"google_trends_url": "..."
|
|
13
|
+
},
|
|
14
|
+
"search_parameters": {
|
|
15
|
+
"engine": "google_trends",
|
|
16
|
+
"q": "sustainable fashion",
|
|
17
|
+
"data_type": "RELATED_QUERIES",
|
|
18
|
+
"date": "today 3-m"
|
|
19
|
+
},
|
|
20
|
+
"related_queries": {
|
|
21
|
+
"rising": [
|
|
22
|
+
{
|
|
23
|
+
"query": "eco friendly clothing brands",
|
|
24
|
+
"value": 345600,
|
|
25
|
+
"extracted_value": 345600,
|
|
26
|
+
"formatted_value": "Breakout"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"query": "sustainable fashion 2024",
|
|
30
|
+
"value": 18050,
|
|
31
|
+
"extracted_value": 18050,
|
|
32
|
+
"formatted_value": "+180%"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"top": [
|
|
36
|
+
{
|
|
37
|
+
"query": "sustainable fashion brands",
|
|
38
|
+
"value": 100,
|
|
39
|
+
"extracted_value": 100
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"query": "ethical fashion",
|
|
43
|
+
"value": 82,
|
|
44
|
+
"extracted_value": 82
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Key Fields
|
|
52
|
+
|
|
53
|
+
- `rising[].formatted_value`:
|
|
54
|
+
- `"Breakout"` = 5000%+ growth (highest priority)
|
|
55
|
+
- `"+N%"` = year-over-year growth percentage
|
|
56
|
+
- `top[].value`: Relative interest score (0-100 scale, 100 = most popular)
|
|
57
|
+
|
|
58
|
+
## RELATED_TOPICS
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"search_metadata": {"status": "Success"},
|
|
63
|
+
"related_topics": {
|
|
64
|
+
"rising": [
|
|
65
|
+
{
|
|
66
|
+
"topic": {
|
|
67
|
+
"mid": "/m/...",
|
|
68
|
+
"title": "Organic Cotton",
|
|
69
|
+
"type": "Topic"
|
|
70
|
+
},
|
|
71
|
+
"value": 345600,
|
|
72
|
+
"formatted_value": "Breakout",
|
|
73
|
+
"link": "/trends/explore?..."
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"top": [
|
|
77
|
+
{
|
|
78
|
+
"topic": {
|
|
79
|
+
"mid": "/m/...",
|
|
80
|
+
"title": "Ethical Fashion",
|
|
81
|
+
"type": "Topic"
|
|
82
|
+
},
|
|
83
|
+
"value": 82,
|
|
84
|
+
"extracted_value": 82,
|
|
85
|
+
"link": "/trends/explore?..."
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Key Fields
|
|
93
|
+
|
|
94
|
+
- `topic.title`: Human-readable topic name
|
|
95
|
+
- `topic.type`: Usually "Topic" or a specific category
|
|
96
|
+
- `formatted_value`: Same growth indicators as RELATED_QUERIES
|
|
97
|
+
|
|
98
|
+
## TIMESERIES
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"search_metadata": {"status": "Success"},
|
|
103
|
+
"interest_over_time": {
|
|
104
|
+
"timeline_data": [
|
|
105
|
+
{
|
|
106
|
+
"date": "Jan 1 - 7, 2024",
|
|
107
|
+
"timestamp": "1704067200",
|
|
108
|
+
"values": [
|
|
109
|
+
{
|
|
110
|
+
"query": "react",
|
|
111
|
+
"value": "85",
|
|
112
|
+
"extracted_value": 85
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"query": "vue",
|
|
116
|
+
"value": "32",
|
|
117
|
+
"extracted_value": 32
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"date": "Jan 8 - 14, 2024",
|
|
123
|
+
"timestamp": "1704672000",
|
|
124
|
+
"values": [
|
|
125
|
+
{
|
|
126
|
+
"query": "react",
|
|
127
|
+
"value": "88",
|
|
128
|
+
"extracted_value": 88
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"query": "vue",
|
|
132
|
+
"value": "30",
|
|
133
|
+
"extracted_value": 30
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Key Fields
|
|
143
|
+
|
|
144
|
+
- `timeline_data[].date`: Human-readable date range
|
|
145
|
+
- `timeline_data[].timestamp`: Unix timestamp
|
|
146
|
+
- `values[].extracted_value`: Interest score (0-100, relative to peak)
|
|
147
|
+
|
|
148
|
+
## GEO_MAP_0
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"search_metadata": {"status": "Success"},
|
|
153
|
+
"interest_by_region": [
|
|
154
|
+
{
|
|
155
|
+
"geo": "US-CA",
|
|
156
|
+
"location": "California",
|
|
157
|
+
"max_value_index": 0,
|
|
158
|
+
"value": 100,
|
|
159
|
+
"extracted_value": 100
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"geo": "US-NY",
|
|
163
|
+
"location": "New York",
|
|
164
|
+
"max_value_index": 0,
|
|
165
|
+
"value": 85,
|
|
166
|
+
"extracted_value": 85
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## GEO_MAP (multi-query)
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"search_metadata": {"status": "Success"},
|
|
177
|
+
"compared_breakdown_by_region": [
|
|
178
|
+
{
|
|
179
|
+
"geo": "US-CA",
|
|
180
|
+
"location": "California",
|
|
181
|
+
"values": [
|
|
182
|
+
{"query": "react", "value": "72%", "extracted_value": 72},
|
|
183
|
+
{"query": "vue", "value": "28%", "extracted_value": 28}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
```
|