📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user