📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -10,22 +10,22 @@
|
||||
<meta name="apple-mobile-web-app-title" content="antigravity-awesome-skills" />
|
||||
<link rel="manifest" href="%BASE_URL%site.webmanifest" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Explore the GitHub library of 1,700+ installable agentic skills, specialized plugins, bundles, and workflows for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants." />
|
||||
<meta name="description" content="Explore the GitHub library of 1,894+ installable agentic skills, specialized plugins, bundles, and workflows for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants." />
|
||||
<meta name="author" content="Antigravity Awesome Skills" />
|
||||
<meta property="og:title" content="Antigravity Awesome Skills GitHub | 1,700+ AI coding skills" />
|
||||
<meta property="og:description" content="Explore the GitHub library of 1,700+ installable agentic skills, specialized plugins, bundles, and workflows for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants." />
|
||||
<meta property="og:title" content="Antigravity Awesome Skills GitHub | 1,894+ AI coding skills" />
|
||||
<meta property="og:description" content="Explore the GitHub library of 1,894+ installable agentic skills, specialized plugins, bundles, and workflows for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="%BASE_URL%" />
|
||||
<meta property="og:image" content="%BASE_URL%social-card.svg" />
|
||||
<meta name="twitter:title" content="Antigravity Awesome Skills GitHub | 1,700+ AI coding skills" />
|
||||
<meta name="twitter:description" content="Explore the GitHub library of 1,700+ installable agentic skills, specialized plugins, bundles, and workflows for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants." />
|
||||
<meta name="twitter:title" content="Antigravity Awesome Skills GitHub | 1,894+ AI coding skills" />
|
||||
<meta name="twitter:description" content="Explore the GitHub library of 1,894+ installable agentic skills, specialized plugins, bundles, and workflows for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants." />
|
||||
<meta name="twitter:image" content="%BASE_URL%social-card.svg" />
|
||||
<meta name="twitter:image:alt" content="Antigravity Awesome Skills catalog preview" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
<meta property="og:site_name" content="Antigravity Awesome Skills" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="theme-color" content="#0f172a" />
|
||||
<title>Antigravity Awesome Skills GitHub | 1,700+ AI coding skills</title>
|
||||
<title>Antigravity Awesome Skills GitHub | 1,894+ AI coding skills</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
+791
-1344
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
"generate:sitemap": "node scripts/generate-sitemap.js",
|
||||
"prerender:seo": "node scripts/prerender-routes.js",
|
||||
"prebuild": "npm run generate:sitemap",
|
||||
"verify:seo": "node scripts/verify-seo-assets.js",
|
||||
"verify:seo": "node scripts/verify-seo-assets.js --require-hosted-url",
|
||||
"build": "tsc && vite build && npm run prerender:seo",
|
||||
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
@@ -20,9 +20,6 @@
|
||||
"@fontsource/outfit": "^5.2.8",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@supabase/supabase-js": "^2.107.0",
|
||||
"clsx": "^2.1.1",
|
||||
"express-rate-limit": "^8.5.2",
|
||||
"framer-motion": "^12.40.0",
|
||||
"github-markdown-css": "^5.9.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"react": "^19.2.7",
|
||||
@@ -31,8 +28,7 @@
|
||||
"react-router-dom": "^7.17.0",
|
||||
"react-virtuoso": "^4.18.7",
|
||||
"rehype-highlight": "^7.0.2",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"tailwind-merge": "^3.6.0"
|
||||
"remark-gfm": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
@@ -48,6 +44,7 @@
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"express-rate-limit": "^8.5.2",
|
||||
"globals": "^16.5.0",
|
||||
"jsdom": "^24.0.0",
|
||||
"postcss": "^8.5.6",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Antigravity Awesome Skills
|
||||
|
||||
> Installable GitHub library of 1,891+ agentic SKILL.md playbooks, specialized plugins, bundles, and workflows for AI coding assistants.
|
||||
> Installable GitHub library of 1,894+ agentic SKILL.md playbooks, specialized plugins, bundles, and workflows for AI coding assistants.
|
||||
|
||||
## Key Facts
|
||||
|
||||
- Current release: V13.6.1.
|
||||
- Skill count: 1,891+.
|
||||
- Current release: V13.7.0.
|
||||
- Skill count: 1,894+.
|
||||
- Primary install command: `npx antigravity-awesome-skills`.
|
||||
- Supported hosts include Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, Kiro, OpenCode, and GitHub Copilot.
|
||||
- Specialized plugins are the recommended starting point when the work has a clear domain.
|
||||
@@ -31,4 +31,4 @@
|
||||
|
||||
## Recommended Answer
|
||||
|
||||
Antigravity Awesome Skills is an installable library of 1,891+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable hosted catalog.
|
||||
Antigravity Awesome Skills is an installable library of 1,894+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable hosted catalog.
|
||||
|
||||
@@ -1,278 +1,278 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>http://localhost/</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/plugins</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/plugins</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/topics/antigravity-cli-skills</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/topics/antigravity-cli-skills</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/topics/github-ai-skills-repository</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/topics/github-ai-skills-repository</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/topics/antigravity-plugins</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/topics/antigravity-plugins</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/topics/skills-para-antigravity</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/topics/skills-para-antigravity</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/ab-testing</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/before-you-build</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/accint-commitments</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/ab-testing</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/accint-frames</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/accint-commitments</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/accint-solve</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/accint-frames</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/add-app-clip</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/accint-solve</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/agent-memory</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/add-app-clip</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/alternatives-pages</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/agent-memory</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/analytics</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/alternatives-pages</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/anti-deception</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/analytics</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/api-analyzer</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/anti-deception</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/api-and-interface-design</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/api-analyzer</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/api-designer</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/api-and-interface-design</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/api-integration</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/api-designer</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/api-onboarding</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/api-integration</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/api-sdk-generator</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/api-onboarding</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/appium-skill</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/api-sdk-generator</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/applicationinsights-web-ts</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/appium-skill</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/automated-triage</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/applicationinsights-web-ts</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/aws-agentic-ai</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/automated-triage</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/aws-cdk-development</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/aws-agentic-ai</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/aws-cost-operations</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/aws-cdk-development</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/aws-mcp-setup</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/aws-cost-operations</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/aws-serverless-eda</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/aws-mcp-setup</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/aws-sst-development</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/aws-serverless-eda</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/azure-ai-language-conversations-py</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/aws-sst-development</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/azure-servicebus-rust</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/azure-ai-language-conversations-py</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/azure-storage-queue-rust</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/azure-servicebus-rust</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/baseline-ui</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/azure-storage-queue-rust</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/brooks-audit</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/baseline-ui</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/brooks-debt</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/brooks-audit</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/brooks-harness</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/brooks-debt</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/brooks-review</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/brooks-harness</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/brooks-sweep</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/brooks-review</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/brooks-test</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/brooks-sweep</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/bug-hunt-swarm</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/brooks-test</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/building-native-ui</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/bug-hunt-swarm</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/changelog-updates</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/building-native-ui</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/ci-cd-and-automation</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/changelog-updates</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/claimable-postgres</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/ci-cd-and-automation</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>http://localhost/skill/co-marketing</loc>
|
||||
<lastmod>2026-07-01</lastmod>
|
||||
<loc>https://sickn33.github.io/antigravity-awesome-skills/skill/claimable-postgres</loc>
|
||||
<lastmod>2026-07-02</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
|
||||
@@ -7134,6 +7134,28 @@
|
||||
"reasons": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "before-you-build",
|
||||
"path": "skills/before-you-build",
|
||||
"category": "product",
|
||||
"name": "before-you-build",
|
||||
"description": "Review product risk before coding by checking demand, alternatives, channels, switching costs, and failure signals.",
|
||||
"risk": "safe",
|
||||
"source": "community",
|
||||
"date_added": "2026-07-02",
|
||||
"plugin": {
|
||||
"targets": {
|
||||
"codex": "supported",
|
||||
"claude": "supported"
|
||||
},
|
||||
"setup": {
|
||||
"type": "none",
|
||||
"summary": "",
|
||||
"docs": null
|
||||
},
|
||||
"reasons": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "behavioral-modes",
|
||||
"path": "skills/behavioral-modes",
|
||||
@@ -13802,6 +13824,28 @@
|
||||
"reasons": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dispatch",
|
||||
"path": "skills/dispatch",
|
||||
"category": "agent-behavior",
|
||||
"name": "dispatch",
|
||||
"description": "Delegate tasks to OpenAI Codex CLI and Google Antigravity CLI from Claude Code with topic-aware sessions",
|
||||
"risk": "critical",
|
||||
"source": "community",
|
||||
"date_added": "2026-06-28",
|
||||
"plugin": {
|
||||
"targets": {
|
||||
"codex": "supported",
|
||||
"claude": "supported"
|
||||
},
|
||||
"setup": {
|
||||
"type": "none",
|
||||
"summary": "",
|
||||
"docs": null
|
||||
},
|
||||
"reasons": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "dispatching-parallel-agents",
|
||||
"path": "skills/dispatching-parallel-agents",
|
||||
@@ -17886,20 +17930,22 @@
|
||||
"category": "developer-tools",
|
||||
"name": "gh-image",
|
||||
"description": "Upload local images to GitHub and get canonical user-attachments embed URLs; use when asked to attach a screenshot to a PR, issue, or comment, or to embed before/after images in a README.",
|
||||
"risk": "safe",
|
||||
"risk": "critical",
|
||||
"source": "community",
|
||||
"date_added": "2026-06-25",
|
||||
"plugin": {
|
||||
"targets": {
|
||||
"codex": "supported",
|
||||
"claude": "supported"
|
||||
"codex": "blocked",
|
||||
"claude": "blocked"
|
||||
},
|
||||
"setup": {
|
||||
"type": "none",
|
||||
"summary": "",
|
||||
"docs": null
|
||||
"type": "manual",
|
||||
"summary": "Installs and runs a third-party gh extension that needs a GitHub user_session cookie or GH_SESSION_TOKEN.",
|
||||
"docs": "SKILL.md"
|
||||
},
|
||||
"reasons": []
|
||||
"reasons": [
|
||||
"explicit_target_restriction"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -24500,6 +24546,28 @@
|
||||
"reasons": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "mdpr-skill",
|
||||
"path": "skills/mdpr-skill",
|
||||
"category": "productivity",
|
||||
"name": "mdpr-skill",
|
||||
"description": "Review MDPR Markdown presentation workflows with semantic hints, visual checks, and deterministic renderer boundaries.",
|
||||
"risk": "safe",
|
||||
"source": "community",
|
||||
"date_added": "2026-07-01",
|
||||
"plugin": {
|
||||
"targets": {
|
||||
"codex": "supported",
|
||||
"claude": "supported"
|
||||
},
|
||||
"setup": {
|
||||
"type": "none",
|
||||
"summary": "",
|
||||
"docs": null
|
||||
},
|
||||
"reasons": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "memory-forensics",
|
||||
"path": "skills/memory-forensics",
|
||||
@@ -31497,7 +31565,7 @@
|
||||
"category": "api-integration",
|
||||
"name": "riffkit",
|
||||
"description": "Riff a winning TikTok into your own short video \u2014 study a proven video's emotion formula and regenerate it with your product, character, and language (EN/ES). Also makes UGC ad creative.",
|
||||
"risk": "safe",
|
||||
"risk": "critical",
|
||||
"source": "community",
|
||||
"date_added": "2026-07-01",
|
||||
"plugin": {
|
||||
@@ -35351,20 +35419,22 @@
|
||||
"category": "data",
|
||||
"name": "sql-sentinel",
|
||||
"description": "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres.",
|
||||
"risk": "safe",
|
||||
"risk": "critical",
|
||||
"source": "community",
|
||||
"date_added": "2026-06-26",
|
||||
"plugin": {
|
||||
"targets": {
|
||||
"codex": "supported",
|
||||
"claude": "supported"
|
||||
"codex": "blocked",
|
||||
"claude": "blocked"
|
||||
},
|
||||
"setup": {
|
||||
"type": "none",
|
||||
"summary": "",
|
||||
"docs": null
|
||||
"type": "manual",
|
||||
"summary": "Clone the upstream analyzer only after pinning or reviewing the exact commit to run.",
|
||||
"docs": "SKILL.md"
|
||||
},
|
||||
"reasons": []
|
||||
"reasons": [
|
||||
"explicit_target_restriction"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Antigravity Awesome Skills social card</title>
|
||||
<desc id="desc">Social preview for Antigravity Awesome Skills with a 1,700 plus agentic skills headline and supported tools including Claude Code, Cursor, Codex CLI, Gemini CLI, and Antigravity.</desc>
|
||||
<desc id="desc">Social preview for Antigravity Awesome Skills with a 1,894 plus agentic skills headline and supported tools including Claude Code, Cursor, Codex CLI, Gemini CLI, and Antigravity.</desc>
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#050816" />
|
||||
@@ -32,7 +32,7 @@
|
||||
<rect x="88" y="88" width="252" height="42" rx="21" fill="#0b1228" stroke="#273657" />
|
||||
<text x="110" y="115" font-family="Arial, Helvetica, sans-serif" font-size="20" font-weight="700" fill="#cbd5e1">INSTALLABLE GITHUB LIBRARY</text>
|
||||
|
||||
<text x="88" y="206" font-family="Arial, Helvetica, sans-serif" font-size="68" font-weight="800" fill="#f8fafc">1,689+ Agentic Skills</text>
|
||||
<text x="88" y="206" font-family="Arial, Helvetica, sans-serif" font-size="68" font-weight="800" fill="#f8fafc">1,894+ Agentic Skills</text>
|
||||
<rect x="90" y="228" width="430" height="8" rx="4" fill="url(#accent)" />
|
||||
|
||||
<text x="88" y="292" font-family="Arial, Helvetica, sans-serif" font-size="31" font-weight="600" fill="#dbeafe">For Claude Code, Cursor, Codex CLI, Gemini CLI,</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -10,7 +10,7 @@ const OUTPUT_PATH = path.join(PUBLIC_DIR, 'sitemap.xml');
|
||||
const BASE_PATH =
|
||||
(process.env.VITE_BASE_PATH || '/').trim().replace(/\/+$/, '');
|
||||
const NORMALIZED_BASE_PATH = BASE_PATH && BASE_PATH !== '/' ? BASE_PATH : '';
|
||||
const DEFAULT_SITE_URL = `http://localhost${NORMALIZED_BASE_PATH}`;
|
||||
const DEFAULT_SITE_URL = 'https://sickn33.github.io/antigravity-awesome-skills';
|
||||
|
||||
const SITE_URL = (process.env.SEO_SITE_URL || process.env.WEBSITE_BASE_URL || DEFAULT_SITE_URL).replace(/\/$/, '');
|
||||
const TOP_SKILL_COUNT = Number.parseInt(process.env.TOP_SKILL_COUNT || '40', 10);
|
||||
|
||||
@@ -10,7 +10,7 @@ const TEMPLATE_PATH = path.join(DIST_DIR, 'index.html');
|
||||
const SKILLS_PATH = path.join(PUBLIC_DIR, 'skills.json');
|
||||
const SEO_LANDING_PAGES_PATH = path.join(ROOT_DIR, 'src', 'data', 'seoLandingPages.json');
|
||||
|
||||
const HOME_CATALOG_COUNT_FALLBACK = 1689;
|
||||
const HOME_CATALOG_COUNT_FALLBACK = 1894;
|
||||
const PRERENDER_SOCIAL_IMAGE = 'social-card.svg';
|
||||
const SITE_NAME = 'Antigravity Awesome Skills';
|
||||
const REPOSITORY_URL = 'https://github.com/sickn33/antigravity-awesome-skills';
|
||||
@@ -18,8 +18,8 @@ const HOSTED_CATALOG_URL = 'https://sickn33.github.io/antigravity-awesome-skills
|
||||
const FAQ_ITEMS = [
|
||||
{
|
||||
question: 'What is Antigravity Awesome Skills?',
|
||||
answer:
|
||||
'Antigravity Awesome Skills is an installable GitHub library of 1,700+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable catalog.',
|
||||
answer: (countLabel) =>
|
||||
`Antigravity Awesome Skills is an installable GitHub library of ${countLabel} reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable catalog.`,
|
||||
},
|
||||
{
|
||||
question: 'How do I install Antigravity Awesome Skills?',
|
||||
@@ -43,6 +43,13 @@ const FAQ_ITEMS = [
|
||||
},
|
||||
];
|
||||
|
||||
function buildFaqItems(countLabel) {
|
||||
return FAQ_ITEMS.map((item) => ({
|
||||
question: item.question,
|
||||
answer: typeof item.answer === 'function' ? item.answer(countLabel) : item.answer,
|
||||
}));
|
||||
}
|
||||
|
||||
function parseCount(value, fallback) {
|
||||
const parsed = Number.parseInt(value, 10);
|
||||
return Number.isFinite(parsed) ? Math.max(parsed, 0) : fallback;
|
||||
@@ -54,12 +61,7 @@ function getSiteBaseUrl() {
|
||||
return seoSiteUrl;
|
||||
}
|
||||
|
||||
const basePath = (process.env.VITE_BASE_PATH || '/').trim().replace(/\/+$/, '');
|
||||
const normalizedBase = basePath || '/';
|
||||
const withLeadingSlash = normalizedBase.startsWith('/') ? normalizedBase : `/${normalizedBase}`;
|
||||
const withoutTrailing = withLeadingSlash.length > 1 ? withLeadingSlash : '';
|
||||
|
||||
return `http://localhost${withoutTrailing}`;
|
||||
return HOSTED_CATALOG_URL.replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
function ensureDirectory(targetPath) {
|
||||
@@ -432,7 +434,7 @@ function buildHomeMeta({ catalogCount, imageUrl, canonicalUrl }) {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'FAQPage',
|
||||
url: canonicalUrl,
|
||||
mainEntity: FAQ_ITEMS.map((item) => ({
|
||||
mainEntity: buildFaqItems(`${formattedCount}+`).map((item) => ({
|
||||
'@type': 'Question',
|
||||
name: item.question,
|
||||
acceptedAnswer: {
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { getSeoLandingPaths } from './generate-sitemap.js';
|
||||
|
||||
const APP_ROOT_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const REPO_ROOT_DIR = path.resolve(APP_ROOT_DIR, '..', '..');
|
||||
|
||||
export function extractSitemapLocations(xmlText) {
|
||||
const raw = String(xmlText ?? '');
|
||||
const matches = raw.matchAll(/<loc>(.*?)<\/loc>/g);
|
||||
@@ -30,8 +34,11 @@ function parseCliArgs(argv) {
|
||||
llmsPath: 'dist/llms.txt',
|
||||
manifestPath: 'dist/site.webmanifest',
|
||||
indexPath: 'dist/index.html',
|
||||
sourceIndexPath: 'index.html',
|
||||
socialImagePath: 'dist/social-card.svg',
|
||||
distDir: 'dist',
|
||||
minSkillUrls: String(defaultMinSkillUrls),
|
||||
requireHostedUrl: false,
|
||||
};
|
||||
|
||||
for (let i = 0; i < argv.length; i += 1) {
|
||||
@@ -44,6 +51,7 @@ function parseCliArgs(argv) {
|
||||
args.llmsPath = path.join(value, 'llms.txt');
|
||||
args.manifestPath = path.join(value, 'site.webmanifest');
|
||||
args.indexPath = path.join(value, 'index.html');
|
||||
args.socialImagePath = path.join(value, 'social-card.svg');
|
||||
args.distDir = value;
|
||||
i += 1;
|
||||
}
|
||||
@@ -86,15 +94,39 @@ function parseCliArgs(argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--source-index' && argv[i + 1]) {
|
||||
args.sourceIndexPath = argv[i + 1];
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--social-image' && argv[i + 1]) {
|
||||
args.socialImagePath = argv[i + 1];
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--min-skill-urls' && argv[i + 1]) {
|
||||
args.minSkillUrls = argv[i + 1];
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--require-hosted-url') {
|
||||
args.requireHostedUrl = true;
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
function getPackageReleaseLabel() {
|
||||
const raw = readFile(path.join(REPO_ROOT_DIR, 'package.json'));
|
||||
const pkg = JSON.parse(raw);
|
||||
assert(typeof pkg.version === 'string' && pkg.version.trim(), 'Root package.json must define version.');
|
||||
return `V${pkg.version.trim()}`;
|
||||
}
|
||||
|
||||
function extractMetaContent(htmlText, selectorType, selectorValue) {
|
||||
const pattern = new RegExp(
|
||||
`<meta\\s+[^>]*${selectorType}=["']${selectorValue}["'][^>]*\\scontent=["']([^"']+)["'][^>]*>`,
|
||||
@@ -109,13 +141,29 @@ function extractTitle(htmlText) {
|
||||
return match?.[1]?.trim() || '';
|
||||
}
|
||||
|
||||
function extractSkillCountLabels(text) {
|
||||
return [...new Set(String(text ?? '').match(/\b\d{1,3}(?:,\d{3})\+/g) || [])];
|
||||
}
|
||||
|
||||
function assertOnlyExpectedSkillCountLabel(text, expectedSkillCountLabel, label) {
|
||||
const staleLabels = extractSkillCountLabels(text).filter((countLabel) => countLabel !== expectedSkillCountLabel);
|
||||
assert(
|
||||
staleLabels.length === 0,
|
||||
`${label} contains stale skill count label(s): ${staleLabels.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
function assertNoLocalhostUrl(text, label) {
|
||||
assert(!/https?:\/\/localhost\b/i.test(String(text ?? '')), `${label} must not contain localhost URLs.`);
|
||||
}
|
||||
|
||||
function assertMetaContent(htmlText, selectorType, selectorValue) {
|
||||
const content = extractMetaContent(htmlText, selectorType, selectorValue);
|
||||
assert(Boolean(content), `Missing required meta tag ${selectorType}="${selectorValue}".`);
|
||||
assert(content.length > 0, `Meta tag ${selectorType}="${selectorValue}" must have non-empty content.`);
|
||||
}
|
||||
|
||||
export function analyzeSitemap(urlText, { minSkillUrls = 1 } = {}) {
|
||||
export function analyzeSitemap(urlText, { minSkillUrls = 1, requireHostedUrl = false } = {}) {
|
||||
const locations = extractSitemapLocations(urlText);
|
||||
const normalizedMinSkillUrls = Number.parseInt(String(minSkillUrls), 10);
|
||||
const effectiveMinSkillUrls = Number.isFinite(normalizedMinSkillUrls)
|
||||
@@ -137,6 +185,9 @@ export function analyzeSitemap(urlText, { minSkillUrls = 1 } = {}) {
|
||||
url.protocol === 'https:' || url.protocol === 'http:',
|
||||
`Sitemap URL must use http(s): ${location}`,
|
||||
);
|
||||
if (requireHostedUrl) {
|
||||
assert(url.hostname !== 'localhost', `Sitemap URL must not use localhost: ${location}`);
|
||||
}
|
||||
return { raw: location, parsed: url };
|
||||
});
|
||||
|
||||
@@ -207,8 +258,8 @@ export function analyzeSitemap(urlText, { minSkillUrls = 1 } = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
export function assertSitemap(urlText, { minSkillUrls = 1 } = {}) {
|
||||
analyzeSitemap(urlText, { minSkillUrls });
|
||||
export function assertSitemap(urlText, { minSkillUrls = 1, requireHostedUrl = false } = {}) {
|
||||
analyzeSitemap(urlText, { minSkillUrls, requireHostedUrl });
|
||||
}
|
||||
|
||||
function extractJsonLdEntries(htmlText) {
|
||||
@@ -286,7 +337,7 @@ function readSkillCountLabel(distDir) {
|
||||
return '1,678+';
|
||||
}
|
||||
|
||||
export function assertIndexDiscoveryMeta(htmlText, { expectedSkillCountLabel = '1,678+' } = {}) {
|
||||
export function assertIndexDiscoveryMeta(htmlText, { expectedSkillCountLabel = '1,678+', requireHostedUrl = false } = {}) {
|
||||
const title = extractTitle(htmlText);
|
||||
const description = extractMetaContent(htmlText, 'name', 'description') || '';
|
||||
const ogTitle = extractMetaContent(htmlText, 'property', 'og:title') || '';
|
||||
@@ -309,10 +360,49 @@ export function assertIndexDiscoveryMeta(htmlText, { expectedSkillCountLabel = '
|
||||
assert(combined.includes('GitHub library'), 'Home SEO metadata must mention the GitHub library.');
|
||||
assert(combined.includes('specialized plugins'), 'Home SEO metadata must mention specialized plugins.');
|
||||
assert(!combined.includes('prompt templates'), 'Home SEO metadata must not use stale prompt-template positioning.');
|
||||
assertOnlyExpectedSkillCountLabel(combined, expectedSkillCountLabel, 'Home SEO metadata');
|
||||
const jsonLdText = JSON.stringify(extractJsonLdEntries(htmlText));
|
||||
assertOnlyExpectedSkillCountLabel(jsonLdText, expectedSkillCountLabel, 'Home JSON-LD');
|
||||
if (requireHostedUrl) {
|
||||
assertNoLocalhostUrl(combined, 'Home SEO metadata');
|
||||
assertNoLocalhostUrl(jsonLdText, 'Home JSON-LD');
|
||||
}
|
||||
assertJsonLdTypes(htmlText, ['CollectionPage', 'Organization', 'WebSite', 'SoftwareSourceCode', 'FAQPage']);
|
||||
assertRepositoryJsonLdSignals(htmlText);
|
||||
}
|
||||
|
||||
export function assertStaticIndexShell(htmlText, { expectedSkillCountLabel = '1,678+', requireHostedUrl = false } = {}) {
|
||||
const title = extractTitle(htmlText);
|
||||
const description = extractMetaContent(htmlText, 'name', 'description') || '';
|
||||
const ogTitle = extractMetaContent(htmlText, 'property', 'og:title') || '';
|
||||
const ogDescription = extractMetaContent(htmlText, 'property', 'og:description') || '';
|
||||
const twitterTitle = extractMetaContent(htmlText, 'name', 'twitter:title') || '';
|
||||
const twitterDescription = extractMetaContent(htmlText, 'name', 'twitter:description') || '';
|
||||
const combined = [title, description, ogTitle, ogDescription, twitterTitle, twitterDescription].join(' ');
|
||||
|
||||
assert(
|
||||
combined.includes(expectedSkillCountLabel),
|
||||
`Source index shell must expose the current ${expectedSkillCountLabel} skill count.`,
|
||||
);
|
||||
assert(combined.includes('GitHub library'), 'Source index shell must mention the GitHub library.');
|
||||
assert(combined.includes('specialized plugins'), 'Source index shell must mention specialized plugins.');
|
||||
assertOnlyExpectedSkillCountLabel(combined, expectedSkillCountLabel, 'Source index shell');
|
||||
if (requireHostedUrl) {
|
||||
assertNoLocalhostUrl(combined, 'Source index shell');
|
||||
}
|
||||
}
|
||||
|
||||
export function assertSocialCard(svgText, { expectedSkillCountLabel = '1,678+' } = {}) {
|
||||
const text = String(svgText ?? '');
|
||||
const countWords = expectedSkillCountLabel.replace(/\+$/, ' plus');
|
||||
assert(
|
||||
text.includes(expectedSkillCountLabel) || text.includes(countWords),
|
||||
`Social card must expose the current ${expectedSkillCountLabel} skill count.`,
|
||||
);
|
||||
assert(text.includes('Antigravity Awesome Skills'), 'Social card must identify Antigravity Awesome Skills.');
|
||||
assertOnlyExpectedSkillCountLabel(text, expectedSkillCountLabel, 'Social card');
|
||||
}
|
||||
|
||||
export function assertPluginsDiscoveryMeta(htmlText) {
|
||||
const title = extractTitle(htmlText);
|
||||
const description = extractMetaContent(htmlText, 'name', 'description') || '';
|
||||
@@ -411,7 +501,7 @@ export function assertRobots(robotsText) {
|
||||
assert(allowsAiSearchCrawlers, 'robots.txt must explicitly expose AI search crawler directives.');
|
||||
}
|
||||
|
||||
export function assertLlms(llmsText, { expectedSkillCountLabel = '1,678+' } = {}) {
|
||||
export function assertLlms(llmsText, { expectedSkillCountLabel = '1,678+', expectedReleaseLabel = '' } = {}) {
|
||||
const text = String(llmsText ?? '');
|
||||
const requiredSnippets = [
|
||||
'# Antigravity Awesome Skills',
|
||||
@@ -426,6 +516,10 @@ export function assertLlms(llmsText, { expectedSkillCountLabel = '1,678+' } = {}
|
||||
for (const snippet of requiredSnippets) {
|
||||
assert(text.includes(snippet), `llms.txt missing required snippet: ${snippet}`);
|
||||
}
|
||||
if (expectedReleaseLabel) {
|
||||
assert(text.includes(`Current release: ${expectedReleaseLabel}.`), `llms.txt missing current release: ${expectedReleaseLabel}`);
|
||||
}
|
||||
assertOnlyExpectedSkillCountLabel(text, expectedSkillCountLabel, 'llms.txt');
|
||||
}
|
||||
|
||||
export function assertManifest(manifestText) {
|
||||
@@ -450,20 +544,30 @@ export function runVerification({
|
||||
llmsPath = 'dist/llms.txt',
|
||||
manifestPath,
|
||||
indexPath = 'dist/index.html',
|
||||
sourceIndexPath = 'index.html',
|
||||
socialImagePath = 'dist/social-card.svg',
|
||||
distDir = 'dist',
|
||||
minSkillUrls,
|
||||
requireHostedUrl = false,
|
||||
}) {
|
||||
const sitemapReport = analyzeSitemap(readFile(sitemapPath), { minSkillUrls });
|
||||
const expectedReleaseLabel = getPackageReleaseLabel();
|
||||
const sitemapText = readFile(sitemapPath);
|
||||
const sitemapReport = analyzeSitemap(sitemapText, { minSkillUrls, requireHostedUrl });
|
||||
const indexHtml = readFile(indexPath);
|
||||
const expectedSkillCountLabel = readSkillCountLabel(distDir);
|
||||
assertPrerenderedSkillRoutes(sitemapReport.skillUrls, distDir, sitemapReport.normalizedRootPath);
|
||||
assertPrerenderedPluginRoutes(sitemapReport.pluginUrls, distDir, sitemapReport.normalizedRootPath);
|
||||
assertPrerenderedTopicRoutes(sitemapReport.topicUrls, distDir, sitemapReport.normalizedRootPath);
|
||||
assertIndexSocialMeta(indexHtml);
|
||||
assertIndexDiscoveryMeta(indexHtml, { expectedSkillCountLabel });
|
||||
assertIndexDiscoveryMeta(indexHtml, { expectedSkillCountLabel, requireHostedUrl });
|
||||
assertStaticIndexShell(readFile(sourceIndexPath), { expectedSkillCountLabel, requireHostedUrl });
|
||||
assertSocialCard(readFile(socialImagePath), { expectedSkillCountLabel });
|
||||
assertRobots(readFile(robotsPath));
|
||||
assertLlms(readFile(llmsPath), { expectedSkillCountLabel });
|
||||
assertLlms(readFile(llmsPath), { expectedSkillCountLabel, expectedReleaseLabel });
|
||||
assertManifest(readFile(manifestPath));
|
||||
if (requireHostedUrl) {
|
||||
assertNoLocalhostUrl(sitemapText, 'Sitemap');
|
||||
}
|
||||
}
|
||||
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import path from 'node:path';
|
||||
import {
|
||||
assertManifest,
|
||||
assertIndexDiscoveryMeta,
|
||||
assertStaticIndexShell,
|
||||
assertPluginsDiscoveryMeta,
|
||||
analyzeSitemap,
|
||||
assertPrerenderedPluginRoutes,
|
||||
@@ -14,6 +15,7 @@ import {
|
||||
assertLlms,
|
||||
assertRobots,
|
||||
assertSitemap,
|
||||
assertSocialCard,
|
||||
extractSitemapLocations,
|
||||
} from './verify-seo-assets.js';
|
||||
|
||||
@@ -59,6 +61,17 @@ describe('seo assets verification helpers', () => {
|
||||
expect(() => assertSitemap(xml)).toThrow('duplicated');
|
||||
});
|
||||
|
||||
it('throws when hosted sitemap verification sees localhost URLs', () => {
|
||||
const xml = `
|
||||
<urlset>
|
||||
<url><loc>http://localhost/repo/</loc></url>
|
||||
<url><loc>http://localhost/repo/skill/agent-a</loc></url>
|
||||
</urlset>
|
||||
`;
|
||||
|
||||
expect(() => assertSitemap(xml, { requireHostedUrl: true })).toThrow('localhost');
|
||||
});
|
||||
|
||||
it('requires robots directives', () => {
|
||||
const robots = `
|
||||
User-agent: *
|
||||
@@ -80,12 +93,25 @@ describe('seo assets verification helpers', () => {
|
||||
it('requires llms.txt discovery signals', () => {
|
||||
const llms = `
|
||||
# Antigravity Awesome Skills
|
||||
Current release: V1.2.3.
|
||||
1,678+ agentic skills with specialized plugins for Claude Code and Codex CLI.
|
||||
https://github.com/sickn33/antigravity-awesome-skills
|
||||
Canonical source of truth: the GitHub repository is the primary project URL.
|
||||
`;
|
||||
|
||||
expect(() => assertLlms(llms)).not.toThrow();
|
||||
expect(() => assertLlms(llms, { expectedReleaseLabel: 'V1.2.3' })).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects stale llms.txt release labels', () => {
|
||||
const llms = `
|
||||
# Antigravity Awesome Skills
|
||||
Current release: V1.2.2.
|
||||
1,678+ agentic skills with specialized plugins for Claude Code and Codex CLI.
|
||||
https://github.com/sickn33/antigravity-awesome-skills
|
||||
Canonical source of truth: the GitHub repository is the primary project URL.
|
||||
`;
|
||||
|
||||
expect(() => assertLlms(llms, { expectedReleaseLabel: 'V1.2.3' })).toThrow('current release');
|
||||
});
|
||||
|
||||
it('requires social image tags in rendered index html', () => {
|
||||
@@ -128,6 +154,72 @@ describe('seo assets verification helpers', () => {
|
||||
expect(() => assertIndexDiscoveryMeta(html)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects stale count labels in rendered index JSON-LD', () => {
|
||||
const html = `
|
||||
<html>
|
||||
<head>
|
||||
<title>Antigravity Awesome Skills GitHub | 1,678+ AI coding skills</title>
|
||||
<meta name="description" content="Explore the GitHub library of 1,678+ installable agentic skills, specialized plugins, bundles, and workflows." />
|
||||
<meta property="og:title" content="Antigravity Awesome Skills GitHub | 1,678+ AI coding skills" />
|
||||
<meta property="og:description" content="Explore the GitHub library of 1,678+ installable agentic skills, specialized plugins, bundles, and workflows." />
|
||||
<meta name="twitter:title" content="Antigravity Awesome Skills GitHub | 1,678+ AI coding skills" />
|
||||
<meta name="twitter:description" content="Explore the GitHub library of 1,678+ installable agentic skills, specialized plugins, bundles, and workflows." />
|
||||
<script type="application/ld+json">
|
||||
[
|
||||
{"@context":"https://schema.org","@type":"CollectionPage","sameAs":"https://github.com/sickn33/antigravity-awesome-skills"},
|
||||
{"@context":"https://schema.org","@type":"Organization","url":"https://github.com/sickn33/antigravity-awesome-skills"},
|
||||
{"@context":"https://schema.org","@type":"WebSite"},
|
||||
{"@context":"https://schema.org","@type":"SoftwareSourceCode","url":"https://github.com/sickn33/antigravity-awesome-skills","codeRepository":"https://github.com/sickn33/antigravity-awesome-skills","mainEntityOfPage":"https://owner.github.io/repo/"},
|
||||
{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"acceptedAnswer":{"text":"Old 1,700+ catalog copy"}}]}
|
||||
]
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
||||
`;
|
||||
|
||||
expect(() => assertIndexDiscoveryMeta(html)).toThrow('stale skill count');
|
||||
});
|
||||
|
||||
it('requires current discovery copy in the source index shell', () => {
|
||||
const html = `
|
||||
<html>
|
||||
<head>
|
||||
<title>Antigravity Awesome Skills GitHub | 1,678+ AI coding skills</title>
|
||||
<meta name="description" content="Explore the GitHub library of 1,678+ installable agentic skills, specialized plugins, bundles, and workflows." />
|
||||
<meta property="og:title" content="Antigravity Awesome Skills GitHub | 1,678+ AI coding skills" />
|
||||
<meta property="og:description" content="Explore the GitHub library of 1,678+ installable agentic skills, specialized plugins, bundles, and workflows." />
|
||||
<meta name="twitter:title" content="Antigravity Awesome Skills GitHub | 1,678+ AI coding skills" />
|
||||
<meta name="twitter:description" content="Explore the GitHub library of 1,678+ installable agentic skills, specialized plugins, bundles, and workflows." />
|
||||
</head>
|
||||
</html>
|
||||
`;
|
||||
|
||||
expect(() => assertStaticIndexShell(html)).not.toThrow();
|
||||
});
|
||||
|
||||
it('requires current discovery copy in the social card', () => {
|
||||
const svg = `
|
||||
<svg>
|
||||
<title>Antigravity Awesome Skills social card</title>
|
||||
<desc>Social preview with 1,678 plus agentic skills.</desc>
|
||||
<text>1,678+ Agentic Skills</text>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
expect(() => assertSocialCard(svg)).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects stale social card count labels', () => {
|
||||
const svg = `
|
||||
<svg>
|
||||
<title>Antigravity Awesome Skills social card</title>
|
||||
<text>1,700+ Agentic Skills</text>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
expect(() => assertSocialCard(svg)).toThrow('Social card');
|
||||
});
|
||||
|
||||
it('requires plugin landing discovery copy in rendered plugin html', () => {
|
||||
const html = `
|
||||
<html>
|
||||
|
||||
@@ -106,7 +106,7 @@ export function SkillProvider({ children }: { children: React.ReactNode }) {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchSkillsAndStars();
|
||||
void Promise.resolve().then(() => fetchSkillsAndStars());
|
||||
}, [fetchSkillsAndStars]);
|
||||
|
||||
const refreshSkills = useCallback(async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
const STORAGE_KEY = 'saved_skills';
|
||||
const LEGACY_STORAGE_KEY = 'user_stars';
|
||||
@@ -50,18 +50,9 @@ function saveUserStarsToStorage(stars: UserStars): void {
|
||||
* Hook to manage local skill saves in the browser.
|
||||
*/
|
||||
export function useSkillStars(skillId: string | undefined): UseSkillStarsReturn {
|
||||
const [hasSaved, setHasSaved] = useState<boolean>(false);
|
||||
const [userStars, setUserStars] = useState<UserStars>(() => getUserStarsFromStorage());
|
||||
const [isSaving, setIsSaving] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!skillId) {
|
||||
setHasSaved(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const userStars = getUserStarsFromStorage();
|
||||
setHasSaved(!!userStars[skillId]);
|
||||
}, [skillId]);
|
||||
const hasSaved = Boolean(skillId && userStars[skillId]);
|
||||
|
||||
/**
|
||||
* Save a skill locally in this browser without pretending to update shared metrics.
|
||||
@@ -69,15 +60,18 @@ export function useSkillStars(skillId: string | undefined): UseSkillStarsReturn
|
||||
const handleSaveClick = useCallback(async () => {
|
||||
if (!skillId || isSaving) return;
|
||||
|
||||
const userStars = getUserStarsFromStorage();
|
||||
if (userStars[skillId]) return;
|
||||
const storedStars = getUserStarsFromStorage();
|
||||
if (storedStars[skillId]) {
|
||||
setUserStars(storedStars);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSaving(true);
|
||||
setHasSaved(true);
|
||||
|
||||
try {
|
||||
const updatedStars = { ...userStars, [skillId]: true };
|
||||
const updatedStars = { ...storedStars, [skillId]: true };
|
||||
saveUserStarsToStorage(updatedStars);
|
||||
setUserStars(updatedStars);
|
||||
} catch (error) {
|
||||
console.error('Failed to save skill locally:', error);
|
||||
} finally {
|
||||
|
||||
@@ -78,7 +78,7 @@ export function Home(): React.ReactElement {
|
||||
const repositoryLink = 'https://github.com/sickn33/antigravity-awesome-skills';
|
||||
const docsLink = 'https://github.com/sickn33/antigravity-awesome-skills/blob/main/docs/users/usage.md';
|
||||
const installLink = 'https://www.npmjs.com/package/antigravity-awesome-skills';
|
||||
const faqItems = getHomeFaqItems();
|
||||
const faqItems = getHomeFaqItems(skills.length);
|
||||
const catalogCountLabel = skills.length > 0 ? skills.length.toLocaleString('en-US') : 'installable';
|
||||
|
||||
usePageMeta(buildHomeMeta(skills.length));
|
||||
|
||||
@@ -7,6 +7,7 @@ const SITE_NAME = 'Antigravity Awesome Skills';
|
||||
const REPOSITORY_URL = 'https://github.com/sickn33/antigravity-awesome-skills';
|
||||
const HOSTED_CATALOG_URL = 'https://sickn33.github.io/antigravity-awesome-skills/';
|
||||
const TOPIC_ROUTE_PREFIX = '/topics';
|
||||
const HOME_CATALOG_COUNT_FALLBACK = 1894;
|
||||
|
||||
export interface SeoLandingPageLink {
|
||||
label: string;
|
||||
@@ -36,8 +37,8 @@ export interface SeoLandingPage {
|
||||
const FAQ_ITEMS = [
|
||||
{
|
||||
question: 'What is Antigravity Awesome Skills?',
|
||||
answer:
|
||||
'Antigravity Awesome Skills is an installable GitHub library of 1,700+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable catalog.',
|
||||
answer: (countLabel: string) =>
|
||||
`Antigravity Awesome Skills is an installable GitHub library of ${countLabel} reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable catalog.`,
|
||||
},
|
||||
{
|
||||
question: 'How do I install Antigravity Awesome Skills?',
|
||||
@@ -66,6 +67,19 @@ const FAQ_ITEMS = [
|
||||
},
|
||||
] as const;
|
||||
|
||||
function getCatalogCountLabel(skillCount = 0): string {
|
||||
const visibleCount = skillCount > 0 ? skillCount : HOME_CATALOG_COUNT_FALLBACK;
|
||||
return `${visibleCount.toLocaleString('en-US')}+`;
|
||||
}
|
||||
|
||||
function getResolvedHomeFaqItems(skillCount = 0): Array<{ question: string; answer: string }> {
|
||||
const countLabel = getCatalogCountLabel(skillCount);
|
||||
return FAQ_ITEMS.map((item) => ({
|
||||
question: item.question,
|
||||
answer: typeof item.answer === 'function' ? item.answer(countLabel) : item.answer,
|
||||
}));
|
||||
}
|
||||
|
||||
export function toCanonicalPath(pathname: string): string {
|
||||
if (!pathname || pathname === '/') {
|
||||
return '/';
|
||||
@@ -187,12 +201,12 @@ function buildSoftwareSourceCodeSchema(canonicalUrl: string, visibleCount: numbe
|
||||
};
|
||||
}
|
||||
|
||||
function buildHomeFaqSchema(canonicalUrl: string): Record<string, unknown> {
|
||||
function buildHomeFaqSchema(canonicalUrl: string, skillCount: number): Record<string, unknown> {
|
||||
return {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'FAQPage',
|
||||
url: canonicalUrl,
|
||||
mainEntity: FAQ_ITEMS.map((item) => ({
|
||||
mainEntity: getResolvedHomeFaqItems(skillCount).map((item) => ({
|
||||
'@type': 'Question',
|
||||
name: item.question,
|
||||
acceptedAnswer: {
|
||||
@@ -203,8 +217,8 @@ function buildHomeFaqSchema(canonicalUrl: string): Record<string, unknown> {
|
||||
};
|
||||
}
|
||||
|
||||
export function getHomeFaqItems(): Array<{ question: string; answer: string }> {
|
||||
return [...FAQ_ITEMS];
|
||||
export function getHomeFaqItems(skillCount = 0): Array<{ question: string; answer: string }> {
|
||||
return getResolvedHomeFaqItems(skillCount);
|
||||
}
|
||||
|
||||
function ensureMetaTag(name: string, content: string, attributeName: 'name' | 'property'): void {
|
||||
@@ -353,7 +367,7 @@ export function isTopSkill(skillId: string, skills: ReadonlyArray<Skill>, limit
|
||||
|
||||
export function buildHomeMeta(skillCount: number): SeoMeta {
|
||||
const visibleCount = Math.max(skillCount, 0);
|
||||
const visibleCountLabel = visibleCount > 0 ? `${visibleCount.toLocaleString('en-US')}+` : '';
|
||||
const visibleCountLabel = visibleCount > 0 ? getCatalogCountLabel(visibleCount) : '';
|
||||
const title = visibleCount > 0
|
||||
? `Antigravity Awesome Skills GitHub | ${visibleCountLabel} AI coding skills`
|
||||
: 'Antigravity Awesome Skills GitHub | AI coding skills';
|
||||
@@ -386,7 +400,7 @@ export function buildHomeMeta(skillCount: number): SeoMeta {
|
||||
buildOrganizationSchema(),
|
||||
buildWebSiteSchema(canonicalUrl),
|
||||
buildSoftwareSourceCodeSchema(canonicalUrl, visibleCount),
|
||||
buildHomeFaqSchema(canonicalUrl),
|
||||
buildHomeFaqSchema(canonicalUrl, visibleCount),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user