Skip to content

Commit 422a0e2

Browse files
committed
feat: add social preview, OG tags, README badges and infographic
- Generate social preview SVG + JPG (1280x640) for GitHub - Add readme infographic showing ccpkg workflow - Add shields.io badges (spec version, status, license, docs, discussions) - Configure Starlight OG/Twitter card meta tags reusing social preview - Add spec generation and freshness check scripts
1 parent 869ca14 commit 422a0e2

9 files changed

Lines changed: 836 additions & 0 deletions

.github/readme-infographic.svg

Lines changed: 115 additions & 0 deletions
Loading

.github/social-preview.jpg

72.3 KB
Loading

.github/social-preview.svg

Lines changed: 118 additions & 0 deletions
Loading

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
# ccpkg
22

3+
[![Spec Version](https://img.shields.io/badge/spec-2026--02--14-blue?style=flat-square)](https://ccpkg.dev/spec/specification.html)
4+
[![Status](https://img.shields.io/badge/status-draft-orange?style=flat-square)](#status)
5+
[![License: CC-BY-4.0](https://img.shields.io/badge/license-CC--BY--4.0-green?style=flat-square)](https://creativecommons.org/licenses/by/4.0/)
6+
[![Docs](https://img.shields.io/badge/docs-ccpkg.dev-818cf8?style=flat-square)](https://ccpkg.dev)
7+
[![GitHub Discussions](https://img.shields.io/github/discussions/zircote/ccpkg?style=flat-square&color=94a3b8)](https://github.com/zircote/ccpkg/discussions)
8+
39
> An open packaging format for AI coding assistant extensions.
410
511
ccpkg is a self-contained archive format for packaging and distributing skills, agents, commands, hooks, MCP servers, and LSP servers as a single portable unit. One file, one install, zero post-install steps.
612

13+
<picture>
14+
<source media="(prefers-color-scheme: dark)" srcset=".github/readme-infographic.svg">
15+
<img alt="How ccpkg works: Author, Pack, Distribute, Install" src=".github/readme-infographic.svg" width="800">
16+
</picture>
17+
718
## The Problem
819

920
AI coding assistants are increasingly extensible, but sharing extensions is fragmented:

astro.config.mjs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,34 @@ export default defineConfig({
88
astroMermaid(),
99
starlight({
1010
title: "ccpkg",
11+
head: [
12+
{
13+
tag: "meta",
14+
attrs: {
15+
property: "og:image",
16+
content: "https://ccpkg.dev/og-image.jpg",
17+
},
18+
},
19+
{
20+
tag: "meta",
21+
attrs: { property: "og:image:width", content: "1280" },
22+
},
23+
{
24+
tag: "meta",
25+
attrs: { property: "og:image:height", content: "640" },
26+
},
27+
{
28+
tag: "meta",
29+
attrs: { name: "twitter:card", content: "summary_large_image" },
30+
},
31+
{
32+
tag: "meta",
33+
attrs: {
34+
name: "twitter:image",
35+
content: "https://ccpkg.dev/og-image.jpg",
36+
},
37+
},
38+
],
1139
logo: {
1240
light: "./src/assets/logo-light.svg",
1341
dark: "./src/assets/logo-dark.svg",

public/og-image.jpg

72.3 KB
Loading

scripts/check-spec-freshness.mjs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env node
2+
3+
import { mkdtempSync, readFileSync, rmSync, readdirSync } from "node:fs";
4+
import { resolve, dirname, join } from "node:path";
5+
import { tmpdir } from "node:os";
6+
import { fileURLToPath } from "node:url";
7+
import { generateSpecPages } from "./generate-spec-pages.mjs";
8+
9+
const __dirname = dirname(fileURLToPath(import.meta.url));
10+
const ROOT = resolve(__dirname, "..");
11+
12+
const config = JSON.parse(
13+
readFileSync(join(__dirname, "spec-mapping.json"), "utf8"),
14+
);
15+
const committedDir = resolve(ROOT, config.outputDir);
16+
17+
// Generate to a temp directory
18+
const tempDir = mkdtempSync(join(tmpdir(), "spec-freshness-"));
19+
20+
try {
21+
generateSpecPages(tempDir);
22+
23+
const staleFiles = [];
24+
25+
for (const file of readdirSync(tempDir)) {
26+
const generated = readFileSync(join(tempDir, file), "utf8");
27+
const committedPath = join(committedDir, file);
28+
29+
let committed;
30+
try {
31+
committed = readFileSync(committedPath, "utf8");
32+
} catch {
33+
staleFiles.push(`${file} (missing from ${config.outputDir})`);
34+
continue;
35+
}
36+
37+
if (generated !== committed) {
38+
staleFiles.push(file);
39+
}
40+
}
41+
42+
if (staleFiles.length > 0) {
43+
console.error(
44+
"Spec pages are stale. Regenerate with: npm run generate:spec\n",
45+
);
46+
console.error("Stale files:");
47+
for (const f of staleFiles) {
48+
console.error(` ${f}`);
49+
}
50+
process.exit(1);
51+
}
52+
53+
console.log("All spec pages are up to date.");
54+
} finally {
55+
rmSync(tempDir, { recursive: true, force: true });
56+
}

0 commit comments

Comments
 (0)