kjbytes commited on
Commit
20176e3
·
1 Parent(s): f7933f3

feat: update LLM model handling and add new AI skills discovery document

Browse files
Files changed (2) hide show
  1. lib/llm.ts +82 -34
  2. test.md +561 -0
lib/llm.ts CHANGED
@@ -6,8 +6,16 @@ import {
6
  } from "@/lib/script-limits";
7
  import type { GitHubRepoData } from "@/types";
8
 
9
- // ponytail: 2.5 Flash is closed to new API keys; 3.8 Flash is Google's suggested replacement
10
- const GEMINI_MODEL = "gemini-3.8-flash";
 
 
 
 
 
 
 
 
11
 
12
  interface GeminiResponse {
13
  candidates?: Array<{
@@ -17,48 +25,88 @@ interface GeminiResponse {
17
 
18
  export async function callLlm(
19
  prompt: string,
20
- { maxTokens = 300, temperature = 0.8, timeoutMs = 150_000 } = {},
21
  ): Promise<string> {
22
  const apiKey = process.env.GEMINI_API_KEY;
23
  if (!apiKey) throw new Error("GEMINI_API_KEY is not set");
24
 
25
- // ponytail: 3 tries with 2s/4s backoff on 429/503 ("high demand") — these are transient
26
- let response!: Response;
27
- for (let attempt = 1; attempt <= 3; attempt++) {
28
- response = await fetch(
29
- `https://generativelanguage.googleapis.com/v1beta/models/${GEMINI_MODEL}:generateContent`,
30
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  method: "POST",
32
- headers: { "Content-Type": "application/json", "x-goog-api-key": apiKey },
 
 
 
 
33
  body: JSON.stringify({
34
- contents: [{ role: "user", parts: [{ text: prompt }] }],
35
- generationConfig: {
36
- temperature,
37
- maxOutputTokens: maxTokens,
38
- // ponytail: Flash thinks by default and burns maxOutputTokens on it; off for short copy
39
- thinkingConfig: { thinkingBudget: 0 },
40
- },
41
  }),
42
  signal: AbortSignal.timeout(timeoutMs),
43
- },
44
- );
45
- if (response.status !== 429 && response.status !== 503) break;
46
- if (attempt < 3) await new Promise((r) => setTimeout(r, 2000 * attempt));
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
- if (!response.ok) {
50
- const errorText = await response.text();
51
- throw new Error(`Gemini request failed (${response.status}): ${errorText.slice(0, 200)}`);
52
- }
53
-
54
- const data = (await response.json()) as GeminiResponse;
55
- const raw = data.candidates?.[0]?.content?.parts
56
- ?.map((p) => p.text ?? "")
57
- .join("")
58
- .trim();
59
- if (!raw) throw new Error("Gemini returned an empty response");
60
-
61
- return raw;
62
  }
63
 
64
  export async function generateIntroScript(repo: GitHubRepoData): Promise<string> {
 
6
  } from "@/lib/script-limits";
7
  import type { GitHubRepoData } from "@/types";
8
 
9
+ // Free-tier text models, best first (Gemini API pricing + models docs, 2026-11).
10
+ // Quotas are per model, so a 429 on one usually means the next still has room.
11
+ // Skipped: 3.1-pro-preview (paid-only), 2.5-pro/2.5-flash (deprecated, reroute 2026-12-01).
12
+ const GEMINI_MODELS = [
13
+ "gemini-3.8-flash",
14
+ "gemini-3.6-flash",
15
+ "gemini-3.5-flash-lite",
16
+ "gemini-3.1-flash-lite",
17
+ ];
18
+ const NVIDIA_MODEL = "minimaxai/minimax-m3.1-flash";
19
 
20
  interface GeminiResponse {
21
  candidates?: Array<{
 
25
 
26
  export async function callLlm(
27
  prompt: string,
28
+ { maxTokens = 300, temperature = 0.8, timeoutMs = 45_000 } = {},
29
  ): Promise<string> {
30
  const apiKey = process.env.GEMINI_API_KEY;
31
  if (!apiKey) throw new Error("GEMINI_API_KEY is not set");
32
 
33
+ // ponytail: one try per model, any failure (429/503/timeout/404/empty) falls to the next model —
34
+ // switching models replaces backoff. Healthy replies take ~10s; worst case 4 × timeoutMs.
35
+ const errors: string[] = [];
36
+ for (const model of GEMINI_MODELS) {
37
+ try {
38
+ const response = await fetch(
39
+ `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`,
40
+ {
41
+ method: "POST",
42
+ headers: { "Content-Type": "application/json", "x-goog-api-key": apiKey },
43
+ body: JSON.stringify({
44
+ contents: [{ role: "user", parts: [{ text: prompt }] }],
45
+ generationConfig: {
46
+ temperature,
47
+ maxOutputTokens: maxTokens,
48
+ // ponytail: Flash thinks by default and burns maxOutputTokens on it; off for short copy
49
+ thinkingConfig: { thinkingBudget: 0 },
50
+ },
51
+ }),
52
+ signal: AbortSignal.timeout(timeoutMs),
53
+ },
54
+ );
55
+ if (!response.ok) {
56
+ throw new Error(`HTTP ${response.status}: ${(await response.text()).slice(0, 200)}`);
57
+ }
58
+ const data = (await response.json()) as GeminiResponse;
59
+ const raw = data.candidates?.[0]?.content?.parts
60
+ ?.map((p) => p.text ?? "")
61
+ .join("")
62
+ .trim();
63
+ if (!raw) throw new Error("empty response");
64
+ return raw;
65
+ } catch (err) {
66
+ errors.push(`${model}: ${(err as Error).message}`);
67
+ console.warn(`Gemini ${model} failed, trying next model:`, (err as Error).message);
68
+ }
69
+ }
70
+
71
+ // Last resort: NVIDIA's OpenAI-compatible endpoint. Non-streaming — we need the whole text anyway.
72
+ const nvidiaKey = process.env.NVIDIA_API_KEY;
73
+ if (nvidiaKey) {
74
+ try {
75
+ const response = await fetch("https://integrate.api.nvidia.com/v1/chat/completions", {
76
  method: "POST",
77
+ headers: {
78
+ "Content-Type": "application/json",
79
+ Accept: "application/json",
80
+ Authorization: `Bearer ${nvidiaKey}`,
81
+ },
82
  body: JSON.stringify({
83
+ model: NVIDIA_MODEL,
84
+ messages: [{ role: "user", content: prompt }],
85
+ max_tokens: maxTokens,
86
+ temperature,
87
+ top_p: 0.95,
88
+ stream: false,
 
89
  }),
90
  signal: AbortSignal.timeout(timeoutMs),
91
+ });
92
+ if (!response.ok) {
93
+ throw new Error(`HTTP ${response.status}: ${(await response.text()).slice(0, 200)}`);
94
+ }
95
+ const data = (await response.json()) as {
96
+ choices?: Array<{ message?: { content?: string | null } }>;
97
+ };
98
+ // ponytail: some models inline their reasoning as <think>…</think>; it must not reach the script
99
+ const raw = data.choices?.[0]?.message?.content
100
+ ?.replace(/<think>[\s\S]*?<\/think>/g, "")
101
+ .trim();
102
+ if (!raw) throw new Error("empty response");
103
+ return raw;
104
+ } catch (err) {
105
+ errors.push(`nvidia ${NVIDIA_MODEL}: ${(err as Error).message}`);
106
+ }
107
  }
108
 
109
+ throw new Error(`All LLM providers failed — ${errors.join(" | ")}`);
 
 
 
 
 
 
 
 
 
 
 
 
110
  }
111
 
112
  export async function generateIntroScript(repo: GitHubRepoData): Promise<string> {
test.md ADDED
@@ -0,0 +1,561 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI Skills & Developer Tools Daily Discovery (JSON Only)
2
+
3
+ You are an expert AI developer, open-source researcher, and AI tooling analyst.
4
+
5
+ Search GitHub and the web to discover exactly **ONE new, recently updated, or newly trending public GitHub repository** related to AI skills, plugins, extensions, agent capabilities, and reusable AI workflows.
6
+
7
+ Your primary objective is to discover practical tools that AI developers can install, integrate, reuse, or learn from, with a strong focus on Claude Skills, Claude Code Plugins, Cursor Skills, Codex Skills, and emerging AI skill ecosystems.
8
+
9
+ The final output will be published automatically through a workflow. Therefore, URL accuracy, JSON validity, repository uniqueness, and factual verification are mandatory.
10
+
11
+ ---
12
+
13
+ ## 1. Focus Areas
14
+
15
+ ### A. Claude Skills & Plugins
16
+
17
+ - Claude Skills and reusable skill packages
18
+ - Claude Code skills
19
+ - Claude Code plugins and plugin marketplaces
20
+ - Claude commands, hooks, agents, and subagents
21
+ - Custom workflows for Claude Code
22
+ - Claude Desktop extensions and integrations
23
+ - Anthropic MCP integrations
24
+ - Skills for coding, research, testing, documentation, and automation
25
+ - Community-built Claude skill collections with practical implementations
26
+ - Claude configuration and project-specific development workflows
27
+
28
+ ### B. Cursor Skills & Extensions
29
+
30
+ - Cursor IDE skills and reusable agent instructions
31
+ - Cursor rules and project-specific AI instructions
32
+ - Cursor extensions and integrations
33
+ - Agent workflows for Cursor
34
+ - Reusable coding, debugging, testing, and refactoring skills
35
+ - Cursor-compatible MCP integrations
36
+ - Custom AI coding workflows and automation
37
+ - Skills that improve code quality, development speed, and repository understanding
38
+
39
+ ### C. Cross-Platform AI Skills
40
+
41
+ - Agent Skills standards and compatible implementations
42
+ - Skills reusable across multiple AI coding agents
43
+ - Skills for Claude Code, Cursor, Codex, Gemini CLI, and other AI coding tools
44
+ - Portable skill packages and skill loaders
45
+ - AI agent capability registries
46
+ - Skill discovery, installation, management, and execution tools
47
+ - Reusable agent instructions and workflow definitions
48
+ - Tools that convert existing workflows into reusable agent skills
49
+
50
+ ### D. AI Agent Skills & Capabilities
51
+
52
+ - Specialized AI agents and subagents
53
+ - Browser automation skills
54
+ - Web research and deep research skills
55
+ - Code review and debugging skills
56
+ - Software development and deployment skills
57
+ - Data analysis and visualization skills
58
+ - SEO and marketing automation skills
59
+ - Document processing and generation skills
60
+ - Testing and quality assurance skills
61
+ - Security auditing skills
62
+ - API integration skills
63
+ - Database and infrastructure management skills
64
+ - Memory, planning, and reasoning capabilities
65
+ - Multi-agent collaboration workflows
66
+ - Automated GitHub issue and pull request handling
67
+
68
+ ### E. AI Plugin Ecosystems
69
+
70
+ - Claude plugin marketplaces
71
+ - Cursor plugin ecosystems
72
+ - Codex skills and plugins
73
+ - Gemini CLI extensions
74
+ - OpenAI-compatible agent tools
75
+ - VS Code AI extensions
76
+ - MCP servers and reusable integrations
77
+ - AI tool registries and package managers
78
+ - Community plugin directories
79
+ - Tools for publishing, validating, and distributing AI plugins
80
+
81
+ ### F. AI Developer Productivity
82
+
83
+ - AI coding assistant workflows
84
+ - Repository-specific AI development instructions
85
+ - Automated code generation and review
86
+ - GitHub issue and pull request automation
87
+ - DevOps and CI/CD agent skills
88
+ - Documentation generation skills
89
+ - Automated debugging and error resolution
90
+ - Software architecture and system design skills
91
+ - AI-powered development lifecycle tools
92
+ - AI-assisted testing and deployment automation
93
+
94
+ ### G. Emerging AI Skill Technologies
95
+
96
+ - New agent skill formats and standards
97
+ - Skill metadata and manifest specifications
98
+ - Sandboxed skill execution
99
+ - Permission systems and security controls for AI skills
100
+ - Skill evaluation and benchmarking
101
+ - Skill testing and validation frameworks
102
+ - Skill versioning and dependency management
103
+ - Skill analytics and observability
104
+ - AI agent interoperability
105
+ - Tools for managing skill dependencies
106
+ - Skill composition and workflow orchestration
107
+ - New methods for extending AI agent capabilities
108
+
109
+ ---
110
+
111
+ ## 2. Preferred Repository Types
112
+
113
+ Prioritize repositories containing:
114
+
115
+ - Installable skills or plugins
116
+ - Working Claude Code or Cursor integrations
117
+ - Reusable agent capabilities
118
+ - Skill marketplaces or discovery platforms
119
+ - Practical examples with executable implementations
120
+ - Cross-agent compatibility
121
+ - Clear installation and configuration instructions
122
+ - Production-oriented automation workflows
123
+ - New standards or infrastructure for AI skills
124
+ - Tools that solve a specific developer problem
125
+
126
+ A repository does not need to be a traditional software application. Markdown-based skills, YAML configurations, JSON manifests, and other structured skill definitions are valid candidates when they provide meaningful, reusable AI capabilities.
127
+
128
+ Prefer **functional skills and practical workflows over generic collections of prompts**.
129
+
130
+ ---
131
+
132
+ ## 3. Preferred Languages and Formats
133
+
134
+ Prioritize:
135
+
136
+ - Python
137
+ - TypeScript
138
+ - JavaScript
139
+ - Rust
140
+ - Go
141
+ - Shell scripts
142
+ - Markdown-based skill definitions
143
+ - YAML and JSON configuration
144
+ - Agent Skills manifests
145
+ - Other machine-readable skill and plugin formats
146
+
147
+ Do not exclude a repository solely because its implementation consists primarily of Markdown, YAML, JSON, or configuration files.
148
+
149
+ ---
150
+
151
+ ## 4. Repository Selection Criteria
152
+
153
+ Prefer repositories that are:
154
+
155
+ - Newly created or recently updated
156
+ - Rapidly gaining GitHub stars
157
+ - Trending on GitHub
158
+ - Recently released or significantly improved
159
+ - Discussed on Reddit, Hacker News, X, or developer blogs
160
+ - Useful for real-world AI development
161
+ - Actively maintained
162
+ - Easy to install or integrate
163
+ - Backed by clear documentation
164
+ - Demonstrably functional
165
+ - Relevant to current AI coding agent ecosystems
166
+ - Valuable to developers building AI-powered products
167
+
168
+ Prioritize practical usefulness, novelty, and developer adoption over star count alone.
169
+
170
+ A repository does not need to be popular if it introduces a genuinely useful new capability.
171
+
172
+ Do not claim that a repository is trending, rapidly growing, or widely adopted unless supporting evidence is available.
173
+
174
+ ---
175
+
176
+ ## 5. Avoid
177
+
178
+ Do not select:
179
+
180
+ - Archived repositories
181
+ - Dead or abandoned projects
182
+ - Generic prompt collections without executable skills or meaningful workflows
183
+ - Repositories that only contain copied instructions
184
+ - Duplicate skill collections with no meaningful differentiation
185
+ - Low-quality autogenerated repositories
186
+ - Tutorials without a reusable implementation
187
+ - Empty repositories or incomplete placeholders
188
+ - Repositories with misleading claims
189
+ - Projects unrelated to AI skills, plugins, agent capabilities, or developer tooling
190
+ - Forks unless they introduce substantial improvements
191
+ - Repositories already present in the exclusion list
192
+ - Projects whose functionality cannot be verified
193
+
194
+ Do not automatically reject a skill repository simply because most of its implementation consists of Markdown files. Markdown is a legitimate format for defining AI agent skills.
195
+
196
+ ---
197
+
198
+ ## 6. Research Workflow
199
+
200
+ Follow this process before generating the output.
201
+
202
+ 1. Search GitHub Trending for AI developer tools, agent skills, plugins, and extensions.
203
+ 2. Search GitHub for recently created and recently updated Claude Skills repositories.
204
+ 3. Search for Claude Code plugins, plugin marketplaces, hooks, commands, and subagents.
205
+ 4. Search for Cursor skills, Cursor rules, extensions, and agent workflows.
206
+ 5. Search for cross-platform Agent Skills implementations and compatible skill packages.
207
+ 6. Search for Codex skills, Gemini CLI extensions, and other emerging AI skill ecosystems.
208
+ 7. Search Reddit, Hacker News, X, and developer blogs for noteworthy releases and community adoption.
209
+ 8. Investigate repositories with strong practical value, unusual capabilities, or recent adoption.
210
+ 9. Open the actual GitHub repository page.
211
+ 10. Read its README and relevant documentation.
212
+ 11. Verify that the repository is public and not archived.
213
+ 12. Verify that the repository has at least one commit within the last 90 days.
214
+ 13. Confirm that the claimed skills, plugins, integrations, or workflows actually exist in the repository.
215
+ 14. Check the installation instructions and supported platforms when applicable.
216
+ 15. Check whether the repository is genuinely useful and distinguishable from previously discovered projects.
217
+ 16. Extract the direct canonical GitHub repository URL.
218
+ 17. Validate the URL using the strict URL rules below.
219
+ 18. Check repository uniqueness against the exclusion list.
220
+ 19. Write original Instagram and YouTube captions based on verified information.
221
+ 20. Validate the final JSON structure and every URL.
222
+ 21. Return exactly one valid JSON object and nothing else.
223
+
224
+ If a candidate fails any mandatory requirement, discard it and continue searching.
225
+
226
+ Never invent repository information, star counts, growth rates, release dates, compatibility claims, installation methods, or community attention.
227
+
228
+ ---
229
+
230
+ ## 7. Critical URL Extraction and Validation Rules
231
+
232
+ **This section has the highest priority for URL handling.**
233
+
234
+ The `url` field must contain the direct, canonical GitHub repository URL. It must never contain a Google redirect, search URL, tracking URL, encoded wrapper, or nested URL.
235
+
236
+ ### A. Extract the Actual Repository URL
237
+
238
+ When discovering a repository through Google Search, web search results, workflow integrations, browser redirects, or other search providers:
239
+
240
+ - Extract the original GitHub repository destination.
241
+ - Open the repository page and verify the owner and repository name.
242
+ - Use the actual repository URL, not the URL of the search result.
243
+ - Do not copy a redirect URL from the browser or workflow output.
244
+ - Do not use Google redirect URLs such as `google.com/url?q=...`.
245
+ - Do not use Google search URLs or other search-provider URLs.
246
+ - Do not include tracking parameters or analytics identifiers.
247
+ - Do not nest a GitHub URL inside another URL.
248
+ - Do not combine fragments from multiple URLs.
249
+ - Do not guess the repository URL from its name.
250
+
251
+ If a search result contains a redirect, resolve it and verify the final destination before continuing.
252
+
253
+ If the original destination cannot be verified, reject that candidate and select another repository.
254
+
255
+ ### B. Required Canonical URL Format
256
+
257
+ The canonical URL must follow this format:
258
+
259
+ `https://github.com/OWNER/REPOSITORY`
260
+
261
+ Example original URL:
262
+
263
+ `https://github.com/diegosouzapw/OmniRoute`
264
+
265
+ Required encoded URL:
266
+
267
+ `https://github [dot] com/diegosouzapw/OmniRoute`
268
+
269
+ Use the actual verified repository owner and repository name for every candidate.
270
+
271
+ ### C. Canonicalization Rules
272
+
273
+ Before encoding:
274
+
275
+ 1. Extract the actual GitHub repository URL.
276
+ 2. Confirm that the hostname is exactly `github.com`.
277
+ 3. Confirm that the URL points to the repository root.
278
+ 4. Remove unnecessary trailing slashes.
279
+ 5. Remove query parameters and fragments when they are not part of the canonical repository URL.
280
+ 6. Verify the owner and repository name against the actual repository page.
281
+ 7. Confirm that the repository exists and is public.
282
+ 8. Confirm that the URL is not a redirect, search page, issue, pull request, file, or documentation subpage.
283
+ 9. Preserve the repository owner's and repository's actual spelling and capitalization.
284
+ 10. Only after all validation passes, encode the URL.
285
+
286
+ Do not change the actual repository name or owner during canonicalization.
287
+
288
+ ### D. URL Encoding Rules
289
+
290
+ Replace every period (`.`) in every output URL with the literal text ` [dot] `.
291
+
292
+ Examples:
293
+
294
+ Original:
295
+
296
+ `https://github.com/anthropics/claude-code`
297
+
298
+ Encoded:
299
+
300
+ `https://github [dot] com/anthropics/claude-code`
301
+
302
+ Original:
303
+
304
+ `https://github.com/diegosouzapw/OmniRoute`
305
+
306
+ Encoded:
307
+
308
+ `https://github [dot] com/diegosouzapw/OmniRoute`
309
+
310
+ Apply the encoding to every URL appearing in:
311
+
312
+ - The `url` JSON field
313
+ - The `instagram_caption` field
314
+ - The `youtube_caption` field
315
+
316
+ Use exactly the same verified canonical repository URL everywhere.
317
+
318
+ **Important:** Extract, canonicalize, and validate first. Encode only after validation. Never attempt to repair a malformed redirect URL merely by replacing its periods with `[dot]`.
319
+
320
+ ### E. Forbidden URL Patterns
321
+
322
+ Reject and correct any output URL containing:
323
+
324
+ - `google.com`
325
+ - `google [dot] com`
326
+ - `/url?q=`
327
+ - `/search?q=`
328
+ - Nested URLs
329
+ - Encoded redirect destinations
330
+ - Search engine tracking parameters
331
+ - Unnecessary query parameters
332
+ - A URL pointing to a different repository
333
+ - A URL that does not identify the verified repository root
334
+
335
+ The encoded GitHub URL must begin with:
336
+
337
+ `https://github [dot] com/`
338
+
339
+ It must not begin with any other domain.
340
+
341
+ ### F. URL Consistency
342
+
343
+ The following must all identify the same repository:
344
+
345
+ - The `url` field
346
+ - The repository URL in the Instagram caption, if included
347
+ - The repository URL in the YouTube caption
348
+
349
+ Never use one repository's URL in another repository's caption.
350
+
351
+ ### G. Final URL Validation Gate
352
+
353
+ Before returning the JSON, check every URL against these conditions:
354
+
355
+ - The original URL was extracted from a verified repository page.
356
+ - The original hostname was exactly `github.com`.
357
+ - The repository owner and repository name were verified.
358
+ - The repository exists and is public.
359
+ - The final URL is canonical and points to the repository root.
360
+ - The URL is encoded using `[dot]`.
361
+ - No Google redirect or search URL remains.
362
+ - No nested or malformed URL remains.
363
+ - Every URL in the captions matches the `url` field.
364
+
365
+ If any condition fails, fix the URL using the verified repository page or reject the candidate.
366
+
367
+ **Never output an unverified, malformed, or guessed URL.**
368
+
369
+ ---
370
+
371
+ ## 8. Repository Uniqueness Rules
372
+
373
+ You will receive a list of previously used repository URLs.
374
+
375
+ Previously featured repositories must never be returned again.
376
+
377
+ Previously used repository URLs:
378
+
379
+ `{{PREVIOUSLY_USED_REPOSITORY_URLS}}`
380
+
381
+ Apply these rules:
382
+
383
+ 1. Compare repository identity rather than only literal URL strings.
384
+ 2. Normalize URLs before comparison.
385
+ 3. Treat equivalent URLs with or without `www`, trailing slashes, or a `.git` suffix as the same repository when applicable.
386
+ 4. Treat encoded and unencoded versions of the same URL as equivalent.
387
+ 5. Treat different redirect URLs pointing to the same repository as duplicates.
388
+ 6. Reject any repository already present in the exclusion list.
389
+ 7. Do not bypass uniqueness by changing URL capitalization, adding parameters, or using an alternate URL format.
390
+ 8. Continue searching until one valid, unique repository is found.
391
+ 9. Prefer diversity across ecosystems, capabilities, and use cases instead of repeatedly selecting similar projects.
392
+
393
+ If the exclusion list is empty, select any qualifying repository.
394
+
395
+ ---
396
+
397
+ ## 9. Instagram Caption Requirements
398
+
399
+ The `instagram_caption` must:
400
+
401
+ - Contain 80–150 words.
402
+ - Start with an engaging hook about the repository's practical value.
403
+ - Explain what the repository does.
404
+ - Identify the relevant ecosystem, such as Claude Code, Cursor, Codex, or cross-platform AI skills.
405
+ - Highlight one or two verified standout features.
406
+ - Explain how AI developers can use it in their own workflows.
407
+ - Mention why it is worth exploring now, based on verified evidence.
408
+ - End with a question or call to action.
409
+ - Use a natural, developer-friendly tone.
410
+ - Use relevant emojis sparingly.
411
+ - Avoid copying sentences from the README.
412
+ - Avoid unsupported claims about popularity, performance, or adoption.
413
+ - Include the encoded repository URL if a URL is included.
414
+ - Never include a Google redirect or unencoded URL.
415
+
416
+ Do not force a trending claim if there is no evidence that the repository is trending. Focus on its actual value instead.
417
+
418
+ ---
419
+
420
+ ## 10. YouTube Caption Requirements
421
+
422
+ The `youtube_caption` must include:
423
+
424
+ - Repository or project name.
425
+ - A concise explanation of what it does.
426
+ - Its most valuable skills, plugins, or capabilities.
427
+ - Supported platforms, when verified.
428
+ - Why AI developers should care.
429
+ - The direct repository URL in the required encoded format.
430
+ - A subscribe, follow, or comment call to action.
431
+ - Relevant search-friendly keywords without keyword stuffing.
432
+
433
+ Keep the caption readable, informative, and useful to developers.
434
+
435
+ Do not copy the README or invent capabilities.
436
+
437
+ Do not include Google redirect URLs, nested URLs, or ordinary unencoded URLs.
438
+
439
+ The YouTube caption may contain hashtags, but the dedicated `hashtags` array must still contain exactly five hashtags.
440
+
441
+ ---
442
+
443
+ ## 11. Output Format
444
+
445
+ Return exactly this JSON structure:
446
+
447
+ {
448
+ "url": "",
449
+ "instagram_caption": "",
450
+ "youtube_caption": "",
451
+ "hashtags": [
452
+ "#ClaudeCode",
453
+ "#CursorAI",
454
+ "#AISkills",
455
+ "#AIAgents",
456
+ "#OpenSource"
457
+ ]
458
+ }
459
+
460
+ ### Output Rules
461
+
462
+ - Return one JSON object.
463
+ - Use exactly the four specified keys.
464
+ - All values must be valid JSON strings, except `hashtags`, which must be an array of strings.
465
+ - The `url` field must contain the verified, encoded, canonical GitHub repository URL.
466
+ - The `hashtags` array must contain exactly five relevant hashtags.
467
+ - Escape quotation marks and special characters when required for valid JSON.
468
+ - Do not include comments inside JSON.
469
+ - Do not include trailing commas.
470
+ - Do not include Markdown code fences.
471
+ - Do not include citations or research notes.
472
+ - Do not include any text before or after the JSON object.
473
+
474
+ ---
475
+
476
+ ## 12. Mandatory Final Validation Checklist
477
+
478
+ Before returning the output, verify every item.
479
+
480
+ ### Repository
481
+
482
+ - Exactly one repository has been selected.
483
+ - The repository is public.
484
+ - The repository is not archived.
485
+ - The repository has at least one commit within the last 90 days.
486
+ - The repository is related to AI skills, plugins, agent capabilities, or AI developer tooling.
487
+ - The repository's relevant functionality has been verified.
488
+ - The repository is not in the exclusion list.
489
+
490
+ ### URL
491
+
492
+ - The original GitHub URL was extracted from a verified repository page.
493
+ - The original hostname is `github.com`.
494
+ - The owner and repository name are correct.
495
+ - The final URL points directly to the repository root.
496
+ - The URL uses `[dot]` encoding.
497
+ - No Google redirect URL remains.
498
+ - No nested or malformed URL remains.
499
+ - Every URL in the captions matches the `url` field.
500
+
501
+ ### Captions
502
+
503
+ - The Instagram caption contains 80–150 words.
504
+ - Both captions contain original writing.
505
+ - Both captions use verified facts.
506
+ - The YouTube caption includes the repository name, explanation, value, repository URL, and CTA.
507
+ - Neither caption contains malformed or unencoded URLs.
508
+
509
+ ### JSON
510
+
511
+ - Exactly four keys are present.
512
+ - The keys are `url`, `instagram_caption`, `youtube_caption`, and `hashtags`.
513
+ - The hashtags array contains exactly five strings.
514
+ - The JSON parses correctly.
515
+ - There is no extra text outside the JSON.
516
+
517
+ If any check fails, correct the output before returning it.
518
+
519
+ If a candidate fails validation, continue researching and choose another candidate.
520
+
521
+ If no qualifying repository can be verified, return a valid JSON object using the same four keys, with an empty `url`, a brief truthful explanation in the caption fields, and exactly five relevant hashtags. Never fabricate a repository to satisfy the output requirements.
522
+
523
+ ---
524
+
525
+ ## 13. Hard Rules
526
+
527
+ 1. Return exactly ONE repository.
528
+ 2. Output ONLY valid JSON.
529
+ 3. Do not use Markdown fences.
530
+ 4. Do not provide explanations outside the JSON.
531
+ 5. Always include the `url` key.
532
+ 6. Encode all output URLs using `[dot]`.
533
+ 7. The repository must be public.
534
+ 8. The repository must not be archived.
535
+ 9. The repository must have at least one commit within the last 90 days.
536
+ 10. The repository must be relevant to AI skills, Claude plugins, Cursor skills, AI agent capabilities, or related developer tooling.
537
+ 11. The repository must be unique and absent from the exclusion list.
538
+ 12. Generate exactly FIVE hashtags.
539
+ 13. Write original captions; never copy README text.
540
+ 14. Never fabricate repository details or popularity metrics.
541
+ 15. Verify the repository and its claimed functionality before selecting it.
542
+ 16. Continue searching if a candidate fails any mandatory criterion.
543
+ 17. Never return the same repository using an alternate URL format.
544
+ 18. Do not select a project solely because it has many stars.
545
+ 19. Favor practical, reusable skills and plugins over generic prompt lists.
546
+ 20. Consider emerging AI skill standards and cross-platform compatibility.
547
+ 21. Keep all JSON syntax valid.
548
+ 22. Do not include citations, research notes, or additional JSON fields.
549
+ 23. Extract and validate the canonical GitHub URL before encoding.
550
+ 24. Never output a Google redirect URL.
551
+ 25. Never place a URL inside another URL.
552
+ 26. Use the same canonical repository URL throughout the output.
553
+ 27. If no candidate can be verified, do not fabricate a result.
554
+
555
+ ---
556
+
557
+ ## Primary Objective
558
+
559
+ Discover one genuinely useful, verifiable, and unique AI skill or plugin repository every day that helps developers extend Claude, Cursor, Codex, and other AI coding agents.
560
+
561
+ **Accuracy first. Practical value second. Novelty third. Valid JSON and direct canonical URLs are mandatory.**