@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,192 @@
1
+ ---
2
+ name: schema-markup-generator
3
+ description: ''
4
+ compatibility: [claude-code, gemini-cli, github-copilot]
5
+ author: OpenDirectory
6
+ version: 1.0.0
7
+ ---
8
+
9
+ # schema-markup-generator
10
+
11
+ You are an SEO engineer specialising in structured data. Your job is to read a webpage and generate valid JSON-LD schema markup that matches what is actually on the page.
12
+
13
+ DO NOT INVENT DATA. Every field in the JSON-LD must come from content that exists on the page. If a required field is not present on the page, flag it as missing rather than filling it with placeholder or guessed data.
14
+
15
+ Before starting, confirm you have a target. Accepted inputs:
16
+ - A live URL to crawl with Chrome
17
+ - A local HTML file path
18
+ - Pasted HTML content
19
+
20
+ If no input was provided, ask: "What page do you want to generate schema markup for? Give me a URL, a file path, or paste the HTML."
21
+
22
+ ---
23
+
24
+ ## Workflow
25
+
26
+ ### Step 1: Setup Check
27
+
28
+ Check the environment before doing anything else.
29
+
30
+ For live URLs: Confirm Chrome is running with remote debugging enabled. If the Chrome DevTools MCP is available, proceed. If not, try fetching the page with curl as a fallback.
31
+
32
+ For local files or pasted HTML: No Chrome needed. Read the content directly.
33
+
34
+ Check for GITHUB_TOKEN if the user wants a PR at the end. Note its presence but do not block. Output-only mode works without it.
35
+
36
+ QA: What is the input source? Is it accessible? State what crawl method you will use.
37
+
38
+ ---
39
+
40
+ ### Step 2: Crawl the Page and Extract Content
41
+
42
+ Connect to the page using the available method.
43
+
44
+ Using Chrome DevTools MCP:
45
+ - Navigate to the URL
46
+ - Wait for the page to fully load (including JavaScript-rendered content)
47
+ - Extract the full page text content and visible HTML structure
48
+ - Capture: page title, meta description, headings (h1-h6), all body text, image URLs and alt text, links, any visible prices, dates, author names, company name, address, phone numbers, FAQ sections, numbered steps, reviews and ratings
49
+
50
+ Using curl fallback:
51
+ - Fetch with a browser User-Agent
52
+ - Parse the HTML for the same content listed above
53
+
54
+ Using local file or pasted HTML:
55
+ - Read the content directly
56
+ - Parse the same fields
57
+
58
+ QA: List the key content you found. What is the page about? What structured content exists (FAQ pairs, product pricing, article byline, address, steps)?
59
+
60
+ ---
61
+
62
+ ### Step 3: Detect Schema Types Needed
63
+
64
+ Analyse the extracted content. A page often needs more than one schema type.
65
+
66
+ Detection rules:
67
+
68
+ | Page type | Required content signals | Schema type(s) to generate |
69
+ |-----------|--------------------------|---------------------------|
70
+ | FAQ page or FAQ section | 3 or more question/answer pairs | FAQPage |
71
+ | Blog post or article | Headline, author, publish date, article body | Article or BlogPosting |
72
+ | Company or about page | Company name, description, logo or social links | Organization |
73
+ | Product page | Product name, price, availability | Product |
74
+ | Homepage | Site name, search functionality | WebSite |
75
+ | How-to guide or tutorial | Numbered steps with descriptions | HowTo |
76
+ | Page with breadcrumb navigation | Breadcrumb trail visible on page | BreadcrumbList |
77
+ | Software tool or app | App name, OS, pricing, download link | SoftwareApplication |
78
+ | Local business | Physical address, phone, hours | LocalBusiness |
79
+
80
+ Apply multiple types if the page qualifies for more than one. A blog post page, for example, often needs Article and BreadcrumbList. An about page often needs Organization and WebSite (if it is the homepage).
81
+
82
+ State the schema types you will generate and why.
83
+
84
+ QA: Does the detected type match the page content? Is there enough data to populate the required fields for each type?
85
+
86
+ ---
87
+
88
+ ### Step 4: Read the Spec and Templates
89
+
90
+ Read `references/json-ld-spec.md` for the required and recommended fields for each detected schema type.
91
+
92
+ Read `references/output-template.md` for the exact JSON structure to use for each type.
93
+
94
+ For each schema type you will generate, note:
95
+ - Which required fields are present in the page content
96
+ - Which required fields are missing (you will flag these, not invent them)
97
+ - Which recommended fields are present and worth including
98
+
99
+ ---
100
+
101
+ ### Step 5: Generate the JSON-LD
102
+
103
+ Generate one `<script type="application/ld+json">` block per schema type.
104
+
105
+ Rules:
106
+ - Every value must come from the page content extracted in Step 2
107
+ - Use the templates in `references/output-template.md` as the structure
108
+ - For missing required fields: add a comment inside the JSON as `"MISSING_fieldName": "not found on page"` so the user knows what to add
109
+ - For missing recommended fields: omit them silently
110
+ - Use ISO 8601 for all dates and durations
111
+ - Use full absolute URLs for all image, page, and site references
112
+ - Nest objects correctly (author as Person object, publisher as Organization object, etc.)
113
+ - If multiple schema types apply, output each as a separate script block
114
+
115
+ Do not output generic placeholder values like "Company Name Here" or "Enter description". Either use the real value or flag it as MISSING.
116
+
117
+ QA: For each generated block, verify: Is every value traceable to the page content? Are all required fields either populated or explicitly flagged as MISSING?
118
+
119
+ ---
120
+
121
+ ### Step 6: Validate the Output
122
+
123
+ Before presenting the output, run through this checklist for each JSON-LD block:
124
+
125
+ - [ ] Valid JSON syntax (no trailing commas, balanced braces)
126
+ - [ ] @context is "https://schema.org"
127
+ - [ ] @type matches the intended schema type
128
+ - [ ] All required fields for the type are either populated or flagged as MISSING
129
+ - [ ] All URLs are absolute (start with https://)
130
+ - [ ] All dates use ISO 8601 format
131
+ - [ ] No invented data: every value traces to page content
132
+ - [ ] No placeholder strings left in the output
133
+
134
+ Fix any syntax errors before presenting. State which required fields were found and which were flagged as MISSING.
135
+
136
+ ---
137
+
138
+ ### Step 7: Output and Deploy
139
+
140
+ Present the output clearly.
141
+
142
+ For each schema block:
143
+ 1. State the schema type and which page it belongs to
144
+ 2. Show the full `<script type="application/ld+json">` block in a code block
145
+ 3. State where in the HTML to place it (inside `<head>` before `</head>`)
146
+ 4. List any MISSING fields the user needs to fill in manually
147
+
148
+ Then ask: "Should I open a GitHub PR to inject this into your codebase, or do you want to add it manually?"
149
+
150
+ If the user confirms a PR:
151
+ - Check for GITHUB_TOKEN and GITHUB_REPO in the environment
152
+ - Detect the framework (Next.js, Astro, plain HTML, etc.) to know the right injection point
153
+ - Insert the script block in the correct location for the framework
154
+ - Open a PR via the GitHub CLI or API
155
+
156
+ Framework-specific injection points:
157
+
158
+ | Framework | Where to inject |
159
+ |-----------|----------------|
160
+ | Next.js (App Router) | Add `<Script type="application/ld+json">` inside the page component, or use `next/head` for pages router |
161
+ | Astro | Add inside `<head>` in the page's layout or front matter |
162
+ | HTML | Add inside `<head>` before `</head>` |
163
+ | Jekyll | Add to `_includes/head.html` or the page's front matter with a custom head include |
164
+ | Nuxt | Add via `useHead()` composable or `<Head>` component |
165
+
166
+ QA: Was the output placed correctly? Are all MISSING fields clearly communicated to the user?
167
+
168
+ ---
169
+
170
+ ## What Good Output Looks Like
171
+
172
+ - Every JSON-LD value traces directly to visible page content
173
+ - Required fields are populated or explicitly flagged as MISSING with a clear label
174
+ - JSON syntax is valid (parseable by any JSON validator)
175
+ - URLs are absolute and correct
176
+ - Dates are in ISO 8601 format
177
+ - The placement instruction matches the user's actual framework
178
+ - The user knows exactly what to do next
179
+
180
+ ## What Bad Output Looks Like
181
+
182
+ - Invented values not present on the page ("Best Company Inc.", generic descriptions)
183
+ - Placeholder strings left in the output
184
+ - Relative URLs instead of absolute URLs
185
+ - Missing @context or @type
186
+ - Invalid JSON (trailing comma, unbalanced brackets)
187
+ - Wrong schema type for the page content
188
+ - Silent omission of required fields without flagging them
189
+
190
+
191
+
192
+
@@ -0,0 +1,35 @@
1
+ {
2
+ "skill_name": "schema-markup-generator",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "Generate schema markup for this FAQ page: https://stripe.com/docs/faq",
7
+ "expected_output": "Agent crawls the page using Chrome DevTools MCP or curl fallback. Extracts all visible question/answer pairs. Detects FAQPage schema type. Reads references/json-ld-spec.md and references/output-template.md. Generates a valid FAQPage JSON-LD block with one Question object per FAQ pair. Every question and answer text matches the visible page content. No invented Q&A pairs. Outputs a complete <script type='application/ld+json'> block. States where to place it (inside <head>). Flags any required fields that were not found on the page. Offers to open a GitHub PR.",
8
+ "files": []
9
+ },
10
+ {
11
+ "id": 2,
12
+ "prompt": "Add schema markup to this blog post: https://vercel.com/blog/how-we-optimized-package-imports-in-next-js",
13
+ "expected_output": "Agent crawls the blog post page. Detects Article or BlogPosting schema type (plus BreadcrumbList if breadcrumbs are visible). Extracts: headline from page title, author name and profile URL, publish date, article image URL, site name, site logo URL. Generates BlogPosting JSON-LD with all extracted fields. Dates in ISO 8601 format. All image URLs are absolute. If any required field (headline, image, datePublished, author) is missing from the page, flags it with MISSING_ prefix. Outputs separate script blocks for Article and BreadcrumbList if applicable. Character count not required for this skill.",
14
+ "files": []
15
+ },
16
+ {
17
+ "id": 3,
18
+ "prompt": "Generate organization schema for our about page at https://linear.app/about",
19
+ "expected_output": "Agent crawls the about page. Detects Organization schema type. Extracts: company name, website URL, company description, logo URL, social media profile links (LinkedIn, Twitter, GitHub, etc.), contact information if present. Generates Organization JSON-LD with @id set to the site URL plus /#organization. sameAs array contains only social URLs actually found on the page. contactPoint included only if contact details are visible. No invented company data. Offers to open a GitHub PR with the markup.",
20
+ "files": []
21
+ },
22
+ {
23
+ "id": 4,
24
+ "prompt": "This product page needs schema markup: https://www.notion.so/product/ai",
25
+ "expected_output": "Agent crawls the product page. Detects Product and possibly SoftwareApplication schema types (Notion AI is software). Extracts: product name, description, pricing information, availability status. If ratings are visible on the page, includes aggregateRating. If no ratings are visible, omits aggregateRating. All prices use correct priceCurrency code. availability uses the correct schema.org URL (InStock, OutOfStock, etc.). Flags as MISSING any required fields not found on the page. Outputs a Product or SoftwareApplication JSON-LD block. States validation steps the user should run (Rich Results Test URL).",
26
+ "files": []
27
+ },
28
+ {
29
+ "id": 5,
30
+ "prompt": "Generate all the schema markup needed for our homepage. Here is the HTML: <pasted HTML of a homepage with company name, tagline, search bar, social links, and contact email>",
31
+ "expected_output": "Agent reads the pasted HTML directly (no Chrome needed). Detects multiple schema types: WebSite (homepage with site name and URL), Organization (company info from the page), and WebSite with potentialAction SearchAction if a search bar is present. Generates separate JSON-LD blocks for each type. WebSite block includes potentialAction only if a search input is found in the HTML. Organization block includes only the social links and contact info actually present in the HTML. No Chrome required since HTML was pasted. No invented data. Outputs each block with clear labels. Lists MISSING fields if any required fields were absent from the HTML.",
32
+ "files": []
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,263 @@
1
+ # JSON-LD Schema Markup Spec
2
+
3
+ This document defines the required and recommended fields for each schema type this skill generates. The agent reads this before generating any markup.
4
+
5
+ ---
6
+
7
+ ## Section 1: What JSON-LD Is and Why It Matters
8
+
9
+ JSON-LD (JavaScript Object Notation for Linked Data) is Google's preferred format for structured data. You embed it as a `<script type="application/ld+json">` tag in the page `<head>`.
10
+
11
+ Why it works better than alternatives (Microdata, RDFa):
12
+ - Separate from HTML markup: you change the data without touching the visual layout
13
+ - Google parses it reliably, including on JavaScript-rendered pages
14
+ - AI crawlers (Google AI Overviews, ChatGPT, Perplexity) read JSON-LD consistently
15
+
16
+ What it does for your pages:
17
+ - Enables rich results in Google search (star ratings, FAQ dropdowns, product prices, how-to steps)
18
+ - Helps Google understand what a page is about, not just what it says
19
+ - Signals to AI systems that your content is authoritative and structured
20
+
21
+ ---
22
+
23
+ ## Section 2: Core JSON-LD Rules
24
+
25
+ Every JSON-LD block must follow these rules:
26
+
27
+ - The script tag: `<script type="application/ld+json">` placed inside `<head>`
28
+ - Every block needs `"@context": "https://schema.org"` as the first property
29
+ - Every block needs `"@type"` specifying the schema type
30
+ - All URLs must be absolute (start with `https://`)
31
+ - All dates must use ISO 8601 format: `"2026-04-10"` or `"2026-04-10T09:00:00+00:00"`
32
+ - All durations must use ISO 8601: `"PT15M"` (15 minutes), `"PT1H30M"` (1 hour 30 minutes)
33
+ - Multiple schema types on one page: one `<script>` block per type, not combined into one
34
+
35
+ ---
36
+
37
+ ## Section 3: Schema Types Reference
38
+
39
+ ### FAQPage
40
+
41
+ Use when: The page has 2 or more question/answer pairs visible to the user. FAQ sections, support pages, product FAQ tabs.
42
+
43
+ Google rich result: FAQ dropdowns appear directly under the search result.
44
+
45
+ Required fields:
46
+ - `@type`: "FAQPage"
47
+ - `mainEntity`: array of Question objects, each with:
48
+ - `@type`: "Question"
49
+ - `name`: the question text (must match text visible on page)
50
+ - `acceptedAnswer.@type`: "Answer"
51
+ - `acceptedAnswer.text`: the answer text (must match text visible on page)
52
+
53
+ Rules:
54
+ - Questions and answers must be visible on the page — do not include hidden content
55
+ - Minimum 2 questions, no maximum
56
+ - Answer text can include basic HTML tags: `<p>`, `<ul>`, `<ol>`, `<li>`, `<a>`, `<br>`, `<strong>`, `<em>`
57
+ - Do not mark up content that requires clicking "expand" to see unless that content is in the DOM
58
+
59
+ ---
60
+
61
+ ### Article and BlogPosting
62
+
63
+ Use when: The page is a blog post, news article, opinion piece, or editorial content.
64
+
65
+ Use `Article` for general editorial content. Use `BlogPosting` specifically for informal blog posts. Use `NewsArticle` for news publications.
66
+
67
+ Google rich result: Article can appear in Google Discover and News with image, title, and date.
68
+
69
+ Required fields:
70
+ - `@type`: "Article", "BlogPosting", or "NewsArticle"
71
+ - `headline`: the article title (max 110 characters for Google News)
72
+ - `image`: array of image URLs. At least one image. Recommended: provide three aspect ratios (16x9, 4x3, 1x1). Minimum 50,000 pixels total (e.g. 696x392px).
73
+ - `datePublished`: ISO 8601 publish date
74
+ - `author`: object or array with `@type` ("Person" or "Organization") and `name`
75
+
76
+ Recommended fields:
77
+ - `dateModified`: ISO 8601 last-updated date
78
+ - `publisher`: Organization object with `name`, `url`, `logo`
79
+ - `description`: article summary (from meta description or first paragraph)
80
+ - `url`: canonical URL of the article
81
+
82
+ ---
83
+
84
+ ### Organization
85
+
86
+ Use when: The page represents a company, nonprofit, or institution. Common on About, Company, or homepage pages.
87
+
88
+ Google use: Establishes entity understanding for Knowledge Panel. Helps Google connect your site to your brand.
89
+
90
+ Required fields:
91
+ - `@type`: "Organization"
92
+ - `name`: company name
93
+ - `url`: company website
94
+
95
+ Recommended fields:
96
+ - `logo`: ImageObject with `url`, `width`, `height`
97
+ - `sameAs`: array of social profile URLs (LinkedIn, Twitter/X, YouTube, GitHub, etc.)
98
+ - `description`: company description
99
+ - `contactPoint`: ContactPoint object with `contactType` and `email` or `telephone`
100
+ - `@id`: use `"https://yourdomain.com/#organization"` as a stable identifier
101
+
102
+ ---
103
+
104
+ ### Product
105
+
106
+ Use when: The page sells or describes a specific product with a price.
107
+
108
+ Google rich result: Product price, availability, and ratings appear in search results.
109
+
110
+ Required fields (at least one of these must be present to qualify for rich results):
111
+ - `review` (Review object)
112
+ - `aggregateRating` (AggregateRating object)
113
+ - `offers` (Offer object)
114
+
115
+ Core fields:
116
+ - `@type`: "Product"
117
+ - `name`: product name
118
+ - `image`: array of product image URLs
119
+ - `description`: product description
120
+
121
+ Offer fields (when pricing is on the page):
122
+ - `offers.@type`: "Offer"
123
+ - `offers.priceCurrency`: ISO 4217 code ("USD", "GBP", "EUR")
124
+ - `offers.price`: numeric price as string ("29.99")
125
+ - `offers.availability`: one of `https://schema.org/InStock`, `https://schema.org/OutOfStock`, `https://schema.org/PreOrder`
126
+ - `offers.url`: product page URL
127
+
128
+ AggregateRating fields (when ratings are on the page):
129
+ - `aggregateRating.ratingValue`: average rating (e.g. 4.5)
130
+ - `aggregateRating.reviewCount`: number of reviews
131
+ - `aggregateRating.bestRating`: maximum rating (usually 5)
132
+
133
+ ---
134
+
135
+ ### WebSite
136
+
137
+ Use when: Generating markup for the homepage or site-level schema.
138
+
139
+ Google use: Enables the Sitelinks Searchbox in search results when users search your brand name.
140
+
141
+ Required fields:
142
+ - `@type`: "WebSite"
143
+ - `name`: site name
144
+ - `url`: homepage URL
145
+
146
+ Recommended fields (for Sitelinks Searchbox):
147
+ - `potentialAction.@type`: "SearchAction"
148
+ - `potentialAction.target.urlTemplate`: search URL pattern (e.g. `"https://example.com/search?q={search_term_string}"`)
149
+ - `potentialAction.query-input`: `"required name=search_term_string"`
150
+
151
+ Only add `potentialAction` if the site has a working search feature. Do not add it for sites without search.
152
+
153
+ ---
154
+
155
+ ### HowTo
156
+
157
+ Use when: The page is a step-by-step guide or tutorial with numbered steps.
158
+
159
+ Google rich result: Steps appear directly in search results as an expandable list.
160
+
161
+ Required fields:
162
+ - `@type`: "HowTo"
163
+ - `name`: guide title
164
+ - `step`: array of HowToStep objects, each with:
165
+ - `@type`: "HowToStep"
166
+ - `name`: step title
167
+ - `text`: step description
168
+
169
+ Recommended fields:
170
+ - `image`: feature image for the guide
171
+ - `estimatedDuration`: total time as ISO 8601 duration (e.g. `"PT30M"`)
172
+ - `supply`: array of HowToSupply objects if materials are needed
173
+ - `tool`: array of HowToTool objects if tools are needed
174
+
175
+ ---
176
+
177
+ ### BreadcrumbList
178
+
179
+ Use when: The page has a visible breadcrumb navigation trail.
180
+
181
+ Google use: Displays breadcrumb path in search results instead of the full URL.
182
+
183
+ Required fields:
184
+ - `@type`: "BreadcrumbList"
185
+ - `itemListElement`: array of ListItem objects, each with:
186
+ - `@type`: "ListItem"
187
+ - `position`: integer position starting at 1
188
+ - `name`: display text for this breadcrumb
189
+ - `item`: absolute URL (required for all items except the last)
190
+
191
+ Rules:
192
+ - Positions must be sequential integers starting at 1
193
+ - The last item does not need an `item` URL (it is the current page)
194
+
195
+ ---
196
+
197
+ ### SoftwareApplication
198
+
199
+ Use when: The page describes a software tool, app, or developer product.
200
+
201
+ Google rich result: Star ratings and price can appear in search results.
202
+
203
+ Required fields:
204
+ - `@type`: "SoftwareApplication"
205
+ - `name`: app name
206
+ - `operatingSystem`: one or more of "Windows", "macOS", "Linux", "Android", "iOS", "Web"
207
+ - `applicationCategory`: one of "GameApplication", "BusinessApplication", "EducationalApplication", "DeveloperApplication", "DesignApplication", "UtilitiesApplication", "SecurityApplication", "SocialNetworkingApplication"
208
+
209
+ Recommended fields:
210
+ - `offers`: pricing (use `"price": "0"` for free apps, or actual price)
211
+ - `aggregateRating`: if ratings are on the page
212
+ - `description`: app description
213
+ - `url`: app or product page URL
214
+ - `downloadUrl`: direct download link if available
215
+
216
+ ---
217
+
218
+ ### LocalBusiness
219
+
220
+ Use when: The page represents a physical business location with an address.
221
+
222
+ Google rich result: Business details, hours, and ratings appear in local search results and maps.
223
+
224
+ Required fields:
225
+ - `@type`: "LocalBusiness" (or a more specific subtype: "Restaurant", "Store", "MedicalBusiness", etc.)
226
+ - `name`: business name
227
+ - `address`: PostalAddress object with `streetAddress`, `addressLocality`, `addressRegion`, `postalCode`, `addressCountry`
228
+
229
+ Recommended fields:
230
+ - `telephone`: phone number in international format
231
+ - `url`: website URL
232
+ - `openingHoursSpecification`: array of OpeningHoursSpecification objects with `dayOfWeek`, `opens`, `closes`
233
+ - `aggregateRating`: if reviews are on the page
234
+ - `image`: business photos
235
+ - `priceRange`: "$", "$$", "$$$", or "$$$$"
236
+
237
+ ---
238
+
239
+ ## Section 4: Common Validation Errors
240
+
241
+ These errors cause Google to reject or ignore schema markup:
242
+
243
+ | Error | What causes it | How to fix |
244
+ |-------|----------------|------------|
245
+ | Missing @context | Forgot the first line | Add `"@context": "https://schema.org"` |
246
+ | Relative URLs | Using `/path` instead of `https://domain.com/path` | Use absolute URLs everywhere |
247
+ | Wrong date format | Using "April 10, 2026" instead of ISO 8601 | Use `"2026-04-10"` format |
248
+ | Content mismatch | Schema says X, visible page says Y | Schema must reflect page content |
249
+ | Hidden content | Marking up content not visible to users | Only markup visible, on-page content |
250
+ | Invented data | Filling fields with guessed or generic values | Every value must come from the page |
251
+ | Invalid JSON | Trailing comma, unmatched bracket | Validate JSON syntax before outputting |
252
+ | Wrong @type for content | Using "Article" for a product page | Match @type to actual page purpose |
253
+
254
+ ---
255
+
256
+ ## Section 5: Validation Tools
257
+
258
+ After generating markup, the user should validate it at:
259
+
260
+ - Google Rich Results Test: https://search.google.com/test/rich-results
261
+ - Schema.org Validator: https://validator.schema.org
262
+
263
+ These tools show which rich result types the markup qualifies for and flag any errors.